I. Overview of the Content
Using STM32 internal USB controller outside the larger page NAND FLASH k9f1g08u0a implementation of a 128M u disk.
1, STM32 USB controller
stm32f103of theMCUcomes withUSBfrom the controller, in accordance withUSBspecification of communication connections;PCThe data transfer between the host and the microcontroller is accomplished by sharing a dedicated data buffer that can beUSBdirect access to peripherals. The size of this dedicated data buffer is determined by the number of endpoints used and the maximum data grouping size for each endpoint, with the maximum available per endpoint +byte buffers, which can be used up to -One- way or8two-way endpoints. USBmodules withPChost communication, based onUSBspecification implementation of token grouping detection, data transmission/Processing of received, and handshake grouping. The format of the entire transmission is done by hardware, which includesCRCgeneration and validation of the. Each endpoint has a buffer description block that describes the buffer address used by the endpoint, the size, and the number of bytes that need to be transferred.
When the USB module identifies a valid function / endpoint of the token grouping,( if the data needs to be transferred and the endpoint is configured ) The associated data transfer occurs. The USB module implements the data exchange between the port and the dedicated buffer via an internal, single-bit register. After all data transfer is complete, if necessary, send or receive the appropriate handshake grouping according to the direction of transmission.
At the end of the data transfer, theUSB module will trigger the interrupt associated with the endpoint, read the status register and / or use a different interrupt to process. USB Interrupt Mapping Unit: Maps a potentially disruptive USB event to three different NVIC request lines:
(1) USB Low-priority interrupt (channel 20): Can be triggered by all USB events (correct transmission, USB reset, etc.). The firmware should first determine the interrupt source before processing interrupts.
(2) USB high priority interrupt (channel 19): Can only be triggered by the correct transmission of synchronous and double-buffered batch transmission, the purpose is to ensure maximum transmission rate.
(3) USB wakeup interrupt (Channel 42): Triggered by a wake-up event in USB suspend mode.
Figure 1, USB device block diagram
2. Large-page NAND k9f1g08
Nand FlashData is read and written in pages, and data is erased in blocks. UnderNANDThe capacity level will alsoNandflashDivided into large pagesNANDand small pagesNAND;k9f1g08is the big pageNAND, it has a page size of(2k+64) Byte,Block size is (128K+4K)Byte。k9f1208u0mFor small pagesNAND, it has a page size of(512+16) Byte,Block size is (16K+ +)Byte。 Since writing data toFLASH, you can only change the specified bit to0, and the specified bit cannot be modified1。 So before you can write data for a page, you must erase it (all the bits are placed1), otherwise the write data will fail.in the preparationFLASHRead and write programs, you need to pass three parameters, the address to operate, the data cache to manipulate, the length of the data to be manipulated, and the write operation, there should be erase and bad block management.
3, USB Mass storage Bulk only
The Mass storage class supports two transport protocols:
1. Bulk-only Transmission (BOT)
2. Control/bulk/interrupt Transmission (CBI)
The Mass Storage class specification defines two classes of requests: Get_max_lun and Mass Storage Reset, and all Mass Storage class devices must support both requests.
Bulk-only Mass Storage Reset (bmrequesttype=00100001b and brequest= 11111111b) is used to reset the Mass Storage device and its associated interface.
Get_max_lun (bmrequesttype= 10100001b and brequest= 11111110b) is used to confirm the number of logical units supported by the device. The value of the Max LUN must be 0~15. Note: LUNs are starting from 0. The host cannot send CBW to a LUN that does not exist.
The mass storage device interface descriptor that supports bot transmission is as follows:
Interface Class Code binterfaceclass=08h, expressed as mass storage device;
Interface Class sub-code binterfacesubclass=06h, indicating that the device supports SCSI Primary Command-2 (SPC-2);
Protocol code BINTERFACEPROTOCOL There are 3 kinds: 0x00, 0x01, 0x50, the first two need to use interrupt transmission, the last one only use bulk transfer (BOT).
Bot-enabled devices must support a minimum of 3 Endpoint:control, bulk-in, and Bulk-out. The USB2.0 specification defines the control endpoint 0. The bulk-in endpoint is used to transfer data from the device to the host. The bulk-out endpoint is used to transfer data from the host to the device.
Bulk-only transmission (BOT) like control transmission, Bot is also composed of the command stage, optional data stage and state stage. All command requests may have or have no data phase. The command transmission, data-in,data-out transmission and status transmission of bot are described.
Figure 2, Bulk-only transmission
CBW is a short packet consisting of 31 bytes. CBW and subsequent data, as well as CSW, start with the new package. It is important to note that all CBW transmissions are Little-endian mode.
In CBW, dcbwsignature must be "43425355h", which means that it is a CBW packet. Dcbwtag is the CB label, which will be returned through the corresponding CSW tag feedback.
In CSW, dcswsignature must be "53425355h", which means it is a CSW package.
Second, the initialization of the system
1, initialize the system clock, set the USB clock to 48MHz;
2, USB interrupt configuration, Select channel, set priority, enable interrupt.
3, USB initialization: Connect USB, USB hardware reset, prepare CNTR register enable and shield interrupt, clear 0 interrupt status register.
4, Flash initialization.
Third, the enumeration of USB
when USB is connected, enter the USB low-priority interrupt. First get interrupt status (read ISTR register), there is USB reset interrupt, USB suspend interrupt and correct data transmission interruption in mass storage.
Note: in the void usb_istr (void) function of usb_istr.c.
1, USB bus Reset:
Sets the start address of the packet buffer description table;
Initialize endpoint: Endpoint 0 for control endpoint, endpoint 1, 2 for batch endpoint, set send and receive status, set send and receive buffer address.
Set CBW signature, cbw.dsignature=0x43425355;
Initializes the bot state machine.
Note: in the void Mass_reset () function of usb_prop.c.
2. USB bus hangs: No data transmission on XMS bus, USB bus hangs, enter low power mode.
Note: in the void Suspend () function of usb_pwr.c.
3, the correct data transmission interruption (usb_int.c CTR_LP ();)
Clear the interrupt flag;
Gets the endpoint identifier;
Control endpoint Processing: Read the endpoint register, which is used to determine whether the data is input, output, or build the package.
Non-control endpoint processing: The next section describes.
See the software flowchart.
Figure 3, USB enumeration software flowchart
Iv. non-control endpoint processing (USB_ENDP.C-usb.bot.c)
Endpoint 2 output interrupt: USB host transmitting data or command packet to MCU.
Endpoint 1 input Interrupt: MCU transmit data or descriptor to USB host.
1, endpoint 2 output interrupt
(1) Copy the data transmitted from the host computer from the USB endpoint buffer to the MCU memory;
(2) To determine the bot status, according to the bot state to make the corresponding treatment: when the bot status is 0 o'clock, CBW packet parsing, and processing SCSI command; When the bot state is 1 o'clock, it represents the data output and executes the WRITE10 command processing.
2. Endpoint 1 input Interrupt
Determine bot status, if bot status is 2, indicate data input, execute READ10 command processing; if the bot status is 4, the data entry is completed, then CSW is returned to the command state.
3, bot state machine software flowchart
(1) Endpoint 2 output interrupt flowchart (Usb_bot.c-mass_storage_out ())
Figure 4, Endpoint 2 output interrupt
(2) CBW package parsing software flowchart (Usb_bot.c-Cbw_decode ())
Figure 5, CBW packet parsing
(3) READ10 command Software flowchart (USB_SCSI.C-Scsi_read10_cmd (LUN, LBA, BLOCKNBR))
Figure 6, READ10 command
(4) WRITE10 command software flowchart (USB_SCSI.C-Scsi_write10_cmd (LUN, LBA, BLOCKNBR))
Figure 7, WRITE10 command
(5) Endpoint 1 input interrupt flowchart (USB_BOT.C-mass_storage_in ())
Figure 8, Endpoint 1 input interrupt
4, USB to memory operation
In mass storage, the USB memory operation is based on the sector (in fat, a sector of 512 bytes), and the maximum packet length of the USB endpoint is 64 bytes, so the data to be sent or received is first put into memory, assuming that the CPU writes data to Endpoint 1, First, read one sector of the data from the Flash or SD card and send it to the USB endpoint 8 times by the maximum packet length. If it is the endpoint 2 output data, then the CPU will receive the data first put into memory, and accumulate, when it is 512 bytes of integer times, then write the data to Flash or SD, the software operation process is as follows:
Figure 9, Read_memory flowchart
In the Flash or SD card read and write operation, the function requires three entry parameters, the first is a logical unit number, to tell the CPU host is which disk operation (assuming that there are multiple disks), the second is the logical block address, here refers to the number of sectors, and the memory address is a byte address, so this address needs to be converted The third is the length of the data, the number of sectors that can be, or how many bytes, which can be obtained in the CBW package.
When the data is sent, the bot's state value is set to 4, which goes into the state phase.
V. Flash Read and write
USB to the operation of the Flash is arbitrary, in sector units, because it is not the continuous address to write data, so flash write function to have the erasure management. Here I am directly porting the flash read-write function of the circle, so here is a reference to his description:
(The following text is from the Circle blog)
because NAND flash erase, you can only press block erase, so in the write sector, the first to erase a block. Before erasing the block, the other data in the block must be copied out, because a block is larger (128KB), it is impossible to open such a large buffer within the MCU. The original block is temporarily copied into a swap block with the help of the page Copy command in the NAND flash. But if only one block is exchanged, it will be frequently erased and the lifespan will be greatly reduced. So in this system, 10 blocks are reserved for use as swap areas, in turn. In addition, the continuous write of the sector is optimized, and when the sector is continuously written, it is not necessary to repeat the above operation each time, only need to re-erase when the address spans the block. The implementation of the continuous write sector is as follows: when the sector address is detected across the block, the original whole piece of data is copied into the swap block, then the previous part of the current address in the block is copied to the original block, and then the current sector address from the Swap block page (using the page copy-random write command), Then write the data of one sector and then write to the other sectors, and when the sector address spreads, write the page to the original block until the sector is written (of course, if the process spans the block, the previous block erase and the copy process must be repeated). The remaining pages in the swap block are then copied back into the original block, so that a continuous write process is completed.
because NAND flash generates bad blocks during production and use, bad block management must be added. In this system, 50 blocks are reserved for bad block management. In the process of wiping and writing, if a bad block is found, then the address of the block is re-mapped to a reserved block. Each subsequent action on the Bad block address is relocated to the new block address. Use a two-dimensional array to hold the mapping relationship. The first half of the two-dimensional array is the bad block address, and the second part is the block address after the re-mapping. Whenever a bad block is found, it is necessary to reconstruct the table (mainly by adding new mappings and sorting, to facilitate the re-mapping of the two-table method), and write the same three copies to the three blocks reserved for this purpose. The reason to use three backups is to take into account the importance of these data, because once this mapping is broken, the consequences will be catastrophic. When the table is saved, special handling is done, first marking them ready to erase, then erasing and writing the data sequentially, so that even if the power is suddenly lost during the operation, at least two blocks of backup data can be used, which can be recovered when the system is initialized. The data uses a special flag (0X0055AAFF) and a summation and checksum to determine whether it is valid. For a new factory falsh, when the bad block table is loaded, the checksum fails, and the program assumes that there is no bad block and that the array is initialized and saved. Each alternate block is also used by another array to flag its state (unused, corrupted, used, etc.). When a new spare block is needed, it is found unused from the array and marked as used. If the spare block itself is bad, then it is flagged as corrupted. The array is saved with the bad block re-mapping table. In addition, the current number of bad blocks is saved.
The re-mapping process for addresses: when reading and writing an address, the first thing to do is to re-insinuate it. First of all to determine whether there is a bad block, when the number of bad blocks is 0 o'clock, the original address can be directly returned. When the number of bad blocks is not 0 o'clock, first determine whether the last access and the address of this visit belong to the same page, if it belongs to, then directly alluded to the last mapped block address. If not, then you need to check the bad block mapping table. If only a bad block, as long as the direct comparison can not look at the table. If the number of bad blocks is greater than 2, then you need to look up the table. Since the address in the table is arranged in order from small to large, it can be judged first and last, and if it is not in that range, then it is not necessary to re-allude and return the original address. If within that range, use a binary lookup table to find out if it is in a bad block table. If so, re-insinuate the address and save the address for the next re-allusion when the address is not used directly across the block. The maximum support 50 bad blocks, in the worst case, the two-point table method needs to be judged 6 times.
Six,USB file Description
1. USB Firmware library file
Usb_conf.h USB library file configuration;
Usb_type.h USB library file type declaration, so that the USB library file is independent;
Usb_def.h the common macro definition of USB library files;
USB_REGS.H USB Controller Register description;
USB_REGS.C USB controller registers the underlying operation function;
USB_INIT.C USB controller initialization;
USB_INT.C USB High-priority interrupts and low-priority interrupt handling functions, which are not used in this example for high-priority intermediate, are removed;
USB_MEM.C This function is used to transfer data from the USB endpoint to the host and host to the USB endpoint;
USB_CROE.C USB2.0 Protocol processing;
The above file has a strong independence, in addition to special circumstances, do not need to modify the user, directly call the internal function.
2, USB Mass Storage Bulk only implementation
The following documents are also from the official STM32, but should be modified according to the actual application.
USB_PWR.C the power management function of the USB controller;
USB_ISTR.C USB Low priority interrupt-in;
USB_ENDP.C non-control endpoint processing (high-capacity data storage input and output functions);
USB_PROP.C Mass Storage Related properties: Mass initialization, reset and so on;
USB_BOT.C bot state Machine, CBW parsing and invoking SCSI processing (batch data input and output state transition through the bot state machine Implementation), this program is responsible for receiving the host's CBW package, and parsing, calling the SCSI command handler function, return CSW;
USB_SCSI.C SCSI command processing;
USB_DESC.C USB descriptor;
Vii. Conclusion
The first time with 32-bit ARM microcontroller, the first time to play USB, can spend two weeks to achieve this U disk, the mood is quite excited, of course, I refer to a lot of netizens and the official code, in the STM32 Development Board in English, there are mass storage routines, is the SD read and write, Cannot operate on NAND, each time the PC endpoint NAND disk is prompted to format the disk, but always formatting is unsuccessful. Later found in the program to write NAND, no erase management, resulting in every data write failed, and then I transplanted a circle of NAND erase management function, changed the large page of NAND FLASH, finally debugging success. In the process of debugging, understand the STM32 USB controller, understand the USB MASS STORAGE Bulk Transfer Protocol, learn to use NAND FLASH, now two weeks from the learning results to summarize, I hope to communicate with you. In this two weeks, has been a lot of netizens support, especially to thank the circle, help me to answer a lot of difficult problems, corrected my many wrong concepts, so that I can smooth the idea of clarity, but also to thank 21ICBBS netizens, and perfume city, to me to answer a lot about STM32 technical issues, There are many unknown netizens, thank you for your selfless contribution to the information.
As a beginner, the above will inevitably have the wrong place, but also ask the heroes to criticize correct.
PDF document and source code download Http://space.ednchina.com/Upload/2009/6/3/9a5a45dc-5c4b-4307-80dd-1018dc2e0d9b.rar
USB Mass Storage Learn note-stm32+flash implement USB flash drive