STM32 USBv1 large copy in interrupt context

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

STM32 USBv1 large copy in interrupt context

Postby iggarpe » Sat Oct 31, 2015 3:43 pm

Please see the following functions in os/hal/STM32/LLD/USBv1/usb_lld.c:

usb_packet_read_to_buffer
usb_packet_read_to_queue
usb_packet_write_from_buffer
usb_packet_write_from_queue

Those functions iterate through the entire chunk of data to copy it from/to the USB FIFO, and they are called in interrupt context. Isn't this a huge no-no in real time systems?

User avatar
Giovanni
Site Admin
Posts: 14462
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1078 times
Been thanked: 922 times
Contact:

Re: STM32 USBv1 large copy in interrupt context

Postby Giovanni » Sat Oct 31, 2015 4:16 pm

It is but the HW lacks a dedicated DMA. The loop goes through the packet buffer, 64 bytes usually, it is not too slow.

It should be verified if one of the standard DMA channels could do the transfer but the buffer organization is strange.

Giovanni

iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

Re: STM32 USBv1 large copy in interrupt context

Postby iggarpe » Sat Oct 31, 2015 5:33 pm

Yeah, I know you can't use DMA with USB (except maybe as you suggest afterwards to move the data from memory to memory).

As I see it the problem with this driver is that first you prepare reception saying where you want the data, and then you're notified when the data is there. This works great with peripherals which can use DMA, but in cases like this where no DMA is possible and the peripheral has its own dedicated memory, it would make more sense to first prepare reception (no specific buffer supplied) and then you're notified when the data has been received and where it has been stored.

Can you think of an elegant way to unify both schemes?

User avatar
Giovanni
Site Admin
Posts: 14462
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1078 times
Been thanked: 922 times
Contact:

Re: STM32 USBv1 large copy in interrupt context

Postby Giovanni » Sat Oct 31, 2015 6:37 pm

It is a tradeoff I made initially, not all devices have a PMA, some have queues.

The choice is between simulating a PMA on devices with queues (possible but very inefficient) or the current approach.

A pump thread is not possible in USBv1 because the final callback is supposed to be called from ISR context.

Giovanni

iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

Re: STM32 USBv1 large copy in interrupt context

Postby iggarpe » Sun Nov 01, 2015 11:16 pm

Giovanni wrote:A pump thread is not possible in USBv1 because the final callback is supposed to be called from ISR context.


Sorry, don't understand this. Why can't you signal an event for a pump thread to react to? The data will be sitting in the buffer until it is read, worst can happen is it being overwritten by the next packet.

BTW, iscochronous endpoints are broken in current USBv1. Just a couple of things I've noticed:

1- Setting EPR_STAT_TX_NAK / EPR_STAT_RX_NAK is wrong with isochronous endpoints (only "disabled" and "valid" are legal according to RM).

2- Double buffering is always used in isochronous endpoints, which also implies you can't have bidirectional isochronous enpoints because both RX/TX ADDRESS/COUNT stm32 descriptor fields are used for either RX or TX.

User avatar
Giovanni
Site Admin
Posts: 14462
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1078 times
Been thanked: 922 times
Contact:

Re: STM32 USBv1 large copy in interrupt context

Postby Giovanni » Mon Nov 02, 2015 12:24 am

Hi,

The transfer is terminated by a callback from ISR in current driver, if the transfer is performed by a thread then it is not possible to call the callback from proper context, it would be called by the thread. That would make the driver not compatible with other implementations.

Isochronous endpoints are not implemented at all in USBv1 currently, not broken.

Giovanni

iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

Re: STM32 USBv1 large copy in interrupt context

Postby iggarpe » Mon Nov 02, 2015 8:29 pm

Giovanni wrote:The transfer is terminated by a callback from ISR in current driver, if the transfer is performed by a thread then it is not possible to call the callback from proper context, it would be called by the thread. That would make the driver not compatible with other implementations.


Oh, I see, it's not that it can't be done but that it would require a significant change in the API requiring rewritting of other implementations too. No can do.

Giovanni wrote:Isochronous endpoints are not implemented at all in USBv1 currently, not broken.


Ummm... the isochronous type was accounted for in the endpoint initialization, so I assumed they were implemented. In fact, they sort of worked (probably because USBv1 is not as f*cked up as OTGv1). I went ahead and made the necessary changes to make it work, see bug #661.

User avatar
Giovanni
Site Admin
Posts: 14462
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1078 times
Been thanked: 922 times
Contact:

Re: STM32 USBv1 large copy in interrupt context

Postby Giovanni » Mon Nov 02, 2015 8:38 pm

Yes, I also think that the USBv1 peripheral is actually nice and well done. Few registers and it does everything, they should add a link to the DMA engine and it would be perfect.

Giovanni


Return to “ChibiOS/HAL”

Who is online

Users browsing this forum: No registered users and 1 guest