fix for endpoint bitfield problem in big endian mode#1114
Conversation
|
Thank you @Wini-Buh for detail breakout, I think I understand the issue, indeed the bitfield doesn't work well when swapping the endian. USB descriptors are always in endian --> need swap, which will cause incorrect mapping of bitfield. I think the best solution is just drop the bitfield within multi-byte field such as wMaxPacketSize entirely. The highspeed mult isn't used much anyway, in case of usage, it could be done simply by bitwise operation. I will make any PR to rename/change it, although it is used across drivers, it is very straight forward change. |
|
@hathach Ok, I agree with you to replace the bitfield |
will do it after PRs adding video and cdc-ncm, since it can complicate those on-going PR. |
In arm-gnu-toolchain-12.2 we see this warning, that's not relevant to pico. Disable it. warning: blink.elf has a LOAD segment with RWX permissions Fixes hathach#1029
I could track down the problem with the bitfield "wMaxPacketSize" in the file "usb_types.h"
tinyusb/src/common/tusb_types.h
Lines 352 to 361 in 32bdf3b
and the CCRX toolchain building in big endian mode. The problem does not occurs if the CCRX toolchain is building in little endian mode.
The bitfield "wMaxPacketSize" is a member of the "tusb_desc_endpoint_t" struct definition, which is used to make the access to the USB descriptor easier. The USB descriptor is a constant and it's descriptor fields must be always in little endian and the bitfield order must be always lower-bit (or right). An access with a controller working in big endian is possible as long as the endian change on an access to the descriptor fields is possible.
It is not possible to tell the CCRX that the constant USB descriptor (which is an array of bytes) is defined in little endian and the struct definition that is mapped over it must force the access in little endian.
Have we look at the situation how it looks in the memory (only the bitfield "wMaxPacketSize") on a little endian configuration:
Allocation of the bitfields in "right" (or lower-bit) :
The U16_TO_U8S_LE macro (which is used in the TUD_CDC_DESCRIPTOR macro) creates the the following content in the memory at "Adr" if a value of 0x40 (01000000b) is used
Loading this content as a 16 bit word into a register of the RX controller gives the value of 0x40 (01000000b) because of the little endian configuration of the RX CPU.
Mapping the struct "wMaxPacketSize" over it looks like this
Doing the same in big endian configuration
Loading this content as a 16 bit word into a register of the RX controller gives the value of 0x4000 (01000000 00000000b) because of the big endian configuration of the RX CPU.
Mapping the struct "wMaxPacketSize" over it looks like this
Conclusion
This PR solves this issue with the use of a helper struct, which is used to change the endian if required and then access the bitfields correctly.