Recently in the use of STM32 USB module to develop a project, it is very simple, the result of a fast two days to the USB packet buffer access to do a little summary here.
The STM32 USB module packet buffer has 512B, but in the STM32 reference manual memory image shows that 0x40006000-0x400063ff, a whole lot of 512B, how can this, but also in the attempt to programming encountered a problem:
In the setup0_process (void) function of the usb_core.c file, there is a paragraph:
uint16_t offset = 1;
if (pinformation->controlstate! = PAUSE)
{
Pinform Ation->usbbmrequesttype = *pbuf.b++; /* Bmrequesttype */
pinformation->usbbrequest = *pbuf.b++;/* brequest */
PBUF.W + = offset; /* Word not accessed because of addressing */
Pinformation->usbwvalue = B Yteswap (*pbuf.w++); /* Wvalue */
PBUF.W + = offset; /* Word not accessed because of all bits addressing */
&nbs P pinformation->usbwindex = Byteswap (*pbuf.w++); /* Windex */
PBUF.W + = offset; /* Word not accessed because of all bits addressing */
&nbs P Pinformation->usbwlength = *PBUF.W; /* wlength */
}
This does not quite understand why PBUF.W + = offset is required, and the explanation behind it is not very understanding * * Word not accessed because of the addressing */
, I then added debugging before this paragraph to show what was received Number
#ifdef DEBUG
uartsend_string ("*** endpoint 0 received Setu P Data ***\r\n ");
for (offset=0;offset<16;offset++)
{
& nbsp Uartsend_hex (*pbuf.b++);
}
#endif
Results serial debugging is displayed as follows:
*** usb bus reset ***
*** USB Bus Ctr Set ***
*** Enter endpoint 0 ***
*** endpoint 0 received setup package ***
*** Endpoint 0 received setup Data ***
0x80 0x06 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x40 0x00 0x00 0x00
should have shown 0x80 0x06 0x00 0x01 0x00 0x000x40 0x00 only right, not quite understand how 0x80 0x06 and 0x00 0x01 after two 0x00, is the USB module will also be received data jumped it.
Later read the reference manual, asked some people, only to know that the original STM32 USB buffer is a two-port ram,cpu end needs to use 32-bit way access, but the USB module one end using 16-bit mode access. This means that the address in each USB module will correspond to the actual address in the controller, so that the two-byte address space after every four bytes of address space is empty. So the above serial debugging shows the data each correct two bytes will be more than two bytes of 0x00.
Here is also a description of the operation function of the buffer in the STM32 USB library function:
There is such a function in the Usb_men.c file
void Pmatouserbuffercopy (uint8_t *pbusrbuf, uint16_t wpmabufaddr, uint16_t wnbytes)
uint32_t n = (wnbytes + 1) >> 1;/*/2*/
uint32_t i;
uint32_t *pdwval;
Pdwval = (uint32_t *) (WPMABUFADDR * 2 + pmaaddr);
for (i = n; I! = 0; i--)
{
* (uint16_t*) pbusrbuf++ = *pdwval++;
pbusrbuf++;
}
Its role is to copy the data in the buffer to the uint8_t receive_buffer[] you define; Other places are good to understand, here to talk about
Pdwval = (uint32_t *) (WPMABUFADDR * 2 + pmaaddr);
for (i = n; I! = 0; i--)
{
* (uint16_t*) pbusrbuf++ = *pdwval++;
pbusrbuf++;
}
The first is Pdwval = (uint32_t *) (WPMABUFADDR * 2 + pmaaddr); here Wpmabufaddr * 2 is the address in the USB module mentioned above to correspond to the actual address in the controller, After obtaining the first address of the buffer for the corresponding endpoint, force it (uint32_t*) to point to the uint32_t type, so that each *pdwval++,pdwval address increases by 4 bytes, and each time there is four bytes of data read out.
In the For Loop, * (uint16_t*) pbusrbuf++ = *pdwval++; This sentence emphasizes that + + is the same priority as the pointer *, combined in order to right-to-left combination, so the equivalent of * ((uint16_t*) pbusrbuf++), First * (uint16 _t*) Pbusrbuf assigns only the first 16 bits of the *pdwval++ 32-bit data, and then adds the Pbusrbuf to 1 bytes. Here, the previously defined uint8_treceive_buffer[]; Two array variables in the array are assigned, but at this point the address also refers to the addition of one byte, so you also need to pbusrbuf++; Let it point to receive_buffer[]; the lower number group variable. One cycle, knowing that all the data is read out.
Transfer from http://blog.csdn.net/ringstart/article/details/6822377