And arguably it should work, given that the 32F4 supports unaligned 32 bit loads and stores.Well yes, if unaligned traps are not enabled, it would work. The only thing to keep in mind is that ldrd/strd do not support unaligned access, but that's generally not a problem.
All Cortex-M3/M4/M7 devices should support unaligned access. I don't think there is even an option in IP to disable that.
I posted the question on th ST forum (where usually there are no replies)
What is actually wrong with the existing (ST) code assuming the buffers are explicitly 4-aligned?
QuoteJust because you do 16 stores, does not mean you have to do exactly 16 loads, too.I think it does.
struct u32pair {
uint32_t lo;
uint32_t hi;
};
static inline u32pair u32pair_shift_left(struct u32pair p, uint_fast8_t n)
{
return (struct u32pair){ .hi = (p.hi << n) | (p.lo >> (32 - n)), .lo = p.lo << n);
}
Of your 39 questions there, 3 went with no replies.
That USB FIFO works explicitly in 32-bit units, so feeding it a byte array and a byte length (which is silently rounded up to a multiple of four), is just the wrong approach.

Or the compiler will actually generate code to access unaligned data by bytes and reassemble?

QuoteThat USB FIFO works explicitly in 32-bit units, so feeding it a byte array and a byte length (which is silently rounded up to a multiple of four), is just the wrong approach.Do we actually know this?
Putting the data in a buffer and specifying the size are two separate operations. It is not an actual FIFO. It is cleared after each frame is sent, so you can write in multiples of 4, the remaining 1-3 bytes will be discarded.
HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, const uint32_t *src, uint_fast8_t ch_ep_num, uint_fast16_t bytes, uint_fast8_t dma)
{
const uintptr_t USBx_BASE = (uintptr_t)USBx;
if (dma == 0U) {
const uint32_t *p = src;
const uint32_t *const q = src + (bytes + 3) / 4;
while (p < q) {
USBx_DFIFO((uint32_t)ch_ep_num) = *(p++);
}
}
return HAL_OK;
}
uint32_t *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint32_t *dst, uint_fast16_t bytes)
{
const uintptr_t USBx_BASE = (uintptr_t)USBx;
uint32_t *p = dst;
uint32_t *const q = dst + (bytes + 3) / 4;
while (p < q) {
*(p++) = USBx_DFIFO(0U);
}
return dst;
}
QuoteOf your 39 questions there, 3 went with no replies.
Did you count the
- replies with little or no information content
- replies weeks later
- replies by "Piranha" telling one that they are a useless idiot, can't read, and providing info which is deliberately incomplete so "Piranha" gets multiple chances to tell the person that they are a useless idiot who can't read (many others have been on the receiving end of this; not just me)
That USB FIFO works explicitly in 32-bit units, so feeding it a byte array and a byte length (which is silently rounded up to a multiple of four), is just the wrong approach.
the code has already changed.
who provide genuine information and don't have time to custom-tailor them to your very particular setup, so the burden of understanding and implementing it is upon you.
QuoteThat USB FIFO works explicitly in 32-bit units, so feeding it a byte array and a byte length (which is silently rounded up to a multiple of four), is just the wrong approach.This is true, but irrelevant. The __packed attribute is placed on the user buffer, not the USB hardware FIFO.
I've designed hardware FIFOs in the past (FPGA & FPGA -> ASIC) and they were always bytewide, if you want to end up with bytes at the output (which, with USB, you do).
QuoteThat USB FIFO works explicitly in 32-bit units, so feeding it a byte array and a byte length (which is silently rounded up to a multiple of four), is just the wrong approach.This is true, but irrelevant. The __packed attribute is placed on the user buffer, not the USB hardware FIFO.My comment was about the C interface, so it most definitely is relevant.
Instead of simply marking the buffer unaligned, so the compiler will deal with any alignment issues, I claim that it is better to use the data type native to the interface (32-bit words) instead, since it also ensures the buffers are aligned, and reminds the programmers that this interface really prefers the buffers to be aligned. It does not preclude using the buffers in a byte-wise manner, since casting the buffer to an unsigned char pointer does exactly that. Path of Least Surprise and all.
the burden of packing/unpacking/realigning/whatever the naturally byte-natured data is upon the programmer, but at the moment somebody starts to write a "library", it is expected by the users of "library" that it's that "library" which takes upon itself that burden.
All Cortex-M3/M4/M7 devices should support unaligned access
in others accessed strictly-16-bit

QuoteAll Cortex-M3/M4/M7 devices should support unaligned access
Yup, indeed! ARM is usually tolerant, other architectures are not.
This includes 0.
for (i = 0U; i < count32b; i++)but at the moment somebody starts to write a "library", it is expected by the users of "library" that it's that "library" which takes upon itself that burden.
And I counted also the information provided by unpaid volunteers

This is in the "data" stage of transfer; in case of ZLP (zero-length packet), the OTG machine won't proceed to that. The Operational model subchapter of OTG chapter(s) in RM0090 describe that.
Would a "dummy" write to DFIFO fix that? (As in, trigger the transfer but discard all four bytes?)
Would a "dummy" write to DFIFO fix that? (As in, trigger the transfer but discard all four bytes?)Fix what exactly? The trigger for a transfer is not a FIFO write, but the count write. You can write 0 and ZLP would be sent. No need to write FIFO in that case.

QuoteAll Cortex-M3/M4/M7 devices should support unaligned access
Yup, indeed! ARM is usually tolerant, other architectures are not.Not in my experience. Even application processors may have ARM CPUs that don't allow unaligned access and I have come across systems that don't even throw a bus error but corrupt data silently.

I did wonder why ZLPs were needed... What a weird protocol.
In the early days of USB, the standard comment was that the spec was written by a bunch of kids
I guess larger industrial firms buy in commercial products for USB, ETH, etc, with paid support.