2019-07-04 10:17 PM
The below paragraph to me is almost incoherient. I don't have a usb protocol analyser so its important I get this right (From page 684 of the RM0350 user guide):
OUT and SETUP packets (data reception)
"These two tokens are handled by the USB peripheral more or less in the same way; the
differences in the handling of SETUP packets are detailed in the following paragraph about
control transfers. When receiving an OUT/SETUP PID, if the address matches a valid
endpoint, the USB peripheral accesses the contents of the ADDRn_RX and COUNTn_RX
locations inside the buffer descriptor table entry related to the addressed endpoint. The
content of the ADDRn_RX is stored directly in its internal register ADDR. While COUNT is
now reset and the values of BL_SIZE and NUM_BLOCK bit fields, which are read within
COUNTn_RX content are used to initialize BUF_COUNT, an internal 16 bit counter, which is
used to check the buffer overrun condition (all these internal registers are not accessible by
software). Data bytes subsequently received by the USB peripheral are packed in half-
words (the first byte received is stored as least significant byte) and then transferred to the
packet buffer starting from the address contained in the internal ADDR register while
BUF_COUNT is decremented and COUNT is incremented at each byte transfer. When the
end of DATA packet is detected, the correctness of the received CRC is tested and only if no
errors occurred during the reception, an ACK handshake packet is sent back to the
transmitting host."
-
For definitions I'm defining:
Packet Memory Area (PMA)
This term is defined in the user guide but then not used everywhere that is relevant.
Allocated Endpoint Buffer Memory Region (AEBMR)
The contents of the receive buffer in the region defined by ADDRn_RX and COUNTn_RX.
-
My interpretation of the paragraph
"When receiving an OUT/SETUP PID, if the address matches a valid endpoint, the USB
peripheral accesses the contents of the ADDRn_RX and COUNTn_RX locations inside the
buffer descriptor table entry related to the addressed endpoint."
When the device receives a Packet ID (PID) that refers to a valid endpoint, the USB peripheral hardware accesses the contents of the PMA (in the region defined by ADDRn_RX and COUNTn_RX).
"The content of the ADDRn_RX is stored directly in its internal register ADDR. While COUNT is
now reset and the values of BL_SIZE and NUM_BLOCK bit fields, which are read within
COUNTn_RX content are used to initialize BUF_COUNT, an internal 16 bit counter, which is
used to check the buffer overrun condition (all these internal registers are not accessible by
software)."
The inaccessible internal buffer is copied into AEBMR automatically.
COUNT, BL_SIZE and NUM_BLOCK fields are reset.
COUNTn_RX is used to initialise an internal counter (BUF_COUNT) to prevent buffer overrun conditions.
"Data bytes subsequently received by the USB peripheral are packed in half-words
(the first byte received is stored as least significant byte) and then transferred to the
packet buffer starting from the address contained in the internal ADDR register while
BUF_COUNT is decremented and COUNT is incremented at each byte transfer."
Data is stored inside the AEBMR. Data is packed in half-words (16 bits):
For example if four bytes 0x01 to 0x04 were received in ascending order:
Address Data
0x0000 0x0201
0x0002 0x0403
And in memory starting at address 0x0000:
0x02010403
This requires reordering of the half words before processing data in a byte stream:
0x01020304.
"When the end of DATA packet is detected, the correctness of the received CRC is tested
and only if no errors occurred during the reception, an ACK handshake packet is sent back to the transmitting host."
CRC is sent at the end of the data packet.
If there are no errors, ACK is sent back to the transmitting host.
2019-07-05 12:41 AM
> This requires reordering of the half words
No, they are stored LSB first, the same endiannes the Cortex-M0 is fixed into.
Don't get too fixed on the exact wording, mind, the manual probably hasn't been written by a native english speaker; and it wasn't written by a well-trained technical writer, rather, it may have been written by the author of the IP module, who may not have much experience from the application side of the trade.
What I want to say is, stop reading and start writing your code and play, and if you stumble upon problems, call back.
JW
PS. There are relatively cheap USB analyzers around, or logic analyzers or oscilloscopes capable of decoding USB; at least for Full Speed they are. I for example use https://www.asix.net/dbg_sigma.htm - the USB module was extra, and it has its quirks, but it was well worth the money. I have also heard praise on https://www.totalphase.com/protocols/usb/ . Not affiliated etc.
2019-07-05 01:41 AM
I'm still confused as to why they mentioned the packing if half words with byte order.
The least significant byte of a uint16 is (v & 0xff), so it implies its written first, then (v & 0xff00) is written.
I have little endian machine, I believe M0 is little endian too. So I setup byte packing in the compiler and did maybe a stupid example, so be warned...
union HalfWord
{
uint16_t data;
uint8_t bytes[2];
};
union Memory
{
HalfWord words[4u];
uint8_t bytes[ sizeof(words) ];
};
Then I print the Memory::bytes:
Memory test { 0x0102, 0x0304, 0x0506, 0x0708 };
for (size_t i = 0; i < sizeof(test.bytes); ++i)
{
std::cout << "byte[" << i << "] = " << (unsigned)test.bytes[i] << "\n";
}
The result is:
byte[0] = 2
byte[1] = 1
byte[2] = 4
byte[3] = 3
byte[4] = 6
byte[5] = 5
byte[6] = 8
byte[7] = 7
Thats sort of what where my thinking was at. Still sort of confused.
All my questions refer to blocks of code that I have :
#warning "Implementation ambiguity"
Or something similar :).
Its just unlikely I'll be able to convince people that I need a hardware analyser.
2019-07-05 01:04 PM
> I'm still confused as to why they mentioned the packing if half words with byte order.
Because the memory used for the USB controller (PMA) is organized by 16-bit words and is accessed by 16-bit
(see stm32f0xx_hal_pcd.c )
It is a separate memory, distinct from the main STM32F0 RAM.
> Its just unlikely I'll be able to convince people that I need a hardware analyser.
Perhaps you don't need it. But any serious project that involves USB does.
-- pa
2019-07-06 04:06 AM
> Still sort of confused.
The description of the USB machine effectively says, "halfwords in the packet memory are stored little endian". The Cortex-M0 is little endian. There's nothing to be confused about, everything matches.
> Its just unlikely I'll be able to convince people that I need a hardware analyser.
Do those people understand the notion of money? You seem to be from the 1st world, it's unlikely that the cost of your time is less than a couple tens of dollars per hour. The options I've pointed you at are few hundreds of dollars (I repeat, for Full Speed USB only). So if you spend 10 hours or so (1-2 days) on a problem which could've been solved by using the tool, those people are even.
This said, the analyzer is not a panacea. No gadget is. Debugger is not the box or software, it's the person who sits on your chair.
JW