USB bulk application (again...)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USB bulk application (again...)

1,817 Views
carstengroen
Senior Contributor II

I know this has been brought up before (from myself and others).

I'm standing at the foot of a mountain where I need to implement bulk USB communication on RT1064 (and possibly RT117x). So far we have managed to get along using CDC, but now we finally NEED Bulk communication (1 OUT and 3 IN endpoints).

Is there any of you "out there" that has done this, and perhaps even better, has something to share ? I have been looking into the various examples in the SDK, but it seems like a large "house of code" to get this taken apart to make something simple.

Anything that can help me get going would be received with great joy

 

0 Kudos
Reply
9 Replies

1,802 Views
carstengroen
Senior Contributor II

I should add that I have the config phase working (as far as I can tell), the device gets enumerated and is seen by the PC as it should, the descriptors are ok, endpoint size gets set correctly in HS mode etc. Its the actual "data transfer" that puzzles me, how to get to a point where I can read/write the different endpoints (1 OUT and 3 IN endpoints).

 

carstengroen_0-1617696532249.png

 

0 Kudos
Reply

1,786 Views
mjbcswitzerland
Specialist V

Hi

In a device with 1 OUT and 3 IN you will find that the Host is polling the 3 INs as fast as possible (depending on USB bandwidth available to them) and, because there is (presently) nothing ready in their output buffers, the HS USB device is NAKing each request.


This means that in order to send something to the host on the 3 INs you just need to prepare the appropriate output buffer content and set its endpoint's prime bit in the EPPRIME register. You will receive an interrupt when the transmission has terminated successfully.

Whenever the host sends something to you on the OUT endpoint you will receive an interrupt with the endpoint's flag set in the EPCOMPLETE set. Then the endpoint's Rx buffer content can be processed (and the endpoint freed again by re-priming its rx flag in the EPPRIME register).

If you can identify the location of code doing this in examples you can presumably copy it for your purposes.

Regards

Mark
[uTasker project FS/HSUSB device/host developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements

For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/iMX/RT1064.html

0 Kudos
Reply

1,777 Views
carstengroen
Senior Contributor II

Thanks Mark,

I'm not sure that's the way forward for me (but maybe), I would like to make it so that it plugs in with the way the USB stuff from NXP is already made, I might need to include MTP support at some point. I'm currently fighting with the code to get something working, I think I have a gap in my understanding of how its all connected together. There is not exactly an abundance of information in the code/documentation about how its done.

I will keep fighting and keep hoping that someone has some input/code snippets that will give me some breakthrough in this

If I at some point succeed with this, I will make something that can be shared, I have a feeling that quite a few people out there needs to do bulk transfers/custom drivers....

 

0 Kudos
Reply

1,769 Views
mjbcswitzerland
Specialist V

Hi Carsten

I have described the lowest level operation, which is the only way that the HSUSB device operates and so needs to be done whatever overall library is used. The central actions should be identifiable in the code so that you can see how they are accessed/controlled in certain example cases and then so can do about the same for new cases (there will presumably be some encapsulation allowing some generic reuse).

In the uTasker project each bulk channel is opened as and IN, OUT or IN/OUT pair based on the buffer descriptor configuration and the low level handling then performed generically so that the user doesn't need to understand and maintain such operation (the class level is the same for FS and HS controllers and thus works on i.MX RT, Coldfire and also Kinetis parts - as well as some LPC ones). In the case of one OUT and three IN bulk endpoints and assuming no IN/OUT endpoints are virtually paired to a duplex channel (which makes them look like a duplex UART type of interface to the higher level) each will have its own communication handle when enumerated. Eg. hIn0, hIn1, hIn2 and hOut0
Then the user reads and writes with something like
dataLength = fnRead(hIn2, buffer, length);
and writes with fnWrite(hOut0, buffer, dataLength);
which would echo IN2 receptions back to the OUT endpoint.
This interface is again generic and so can be used identically for any class operations.

The uTasker project has been serving the (originally) Freescale community since 2008 and maintains compatibility over parts and time and so is an alternative choice for professionals who require proven and immediate reliable operations in USB projects that is stable over time (in comparison during this period there have been a number of versions of SDK USB stacks that each have been dropped after a couple of years and replaced by new ones that are not compatible).
Regards

Mark

 

0 Kudos
Reply

1,760 Views
carstengroen
Senior Contributor II

Thanks Mark,

I have been thru the low level stuff before (LPC2148) on USB (although its been almost 20 years ago).

On the RT106x I would rather try and make something that plugs into the way NXP has planned, as I wrote I hope to be able to combine it with MTP at some point (and MTP is NOT something I want to do from the bottom!). 

I'm still working on the code, so far I managed to get a couple of messages from the PC to the RT, for some reason it stops after 2 messages. Still investigating...

I took one of the CDC samples from the NXP SDK and stripped that for code, maybe I removed too much....

Anyway, glad for all and any pointers!

Regards,

Carsten

0 Kudos
Reply

1,751 Views
mjbcswitzerland
Specialist V

Hi Carsten

The uTasker USB stack also works compatibly on LPC2xxx but the USB controllers are very different - whilst the Coldfire/Kinetis/i.MX RT ones are driven by buffer descriptors and DMA the LPC2xxx ones are FIFO driven.

Regards

Mark

 

0 Kudos
Reply

1,755 Views
carstengroen
Senior Contributor II

Slowly things are starting to light up

I now have data back and forth between the RT1064 and a PC. The RT1064 sends data every 2 seconds, when the PC receives this, it replies with a short message back. 

I still have some stuff to do with the fact that I have 3 IN endpoints and 1 OUT endpoint (as I'm working from the CDC sample), but I think and hope that will be somewhat ok to fix....

Anyway, I know this is more of a "USB question", but I need to know if I'm doing something wrong as I see "NYET" status on the OUT packets the RT1064 receives, or if this is "normal" behavior ? I have so far only worked on FS devices so the NYET on HS devices is new to me...

I checked the CDC sample from the SDK, and that one also shows "NYET" packets on each "OUT" packet, so I guess this is "just how it is" ?

carstengroen_3-1617887083078.png

 

Again, once I have something that works and tested, I will make a separate post with the code and an explanation. 

A couple of screenshots from my Beagle 480 analyzer with the "NYET" situation (which might turn out to be perfectly normal): 

 

carstengroen_0-1617886742628.png

 

carstengroen_1-1617886775982.png

 

carstengroen_2-1617886786150.png

 

 

0 Kudos
Reply

1,747 Views
mjbcswitzerland
Specialist V

Hi Carsen

NYET means that the device has indeed received the last data frame but is presently not capable of receiving further data. If you look in your recordings you will see that the host is also sending PINGs which is because it first questions whether the device can now receive data or not.

In comparison to FS USB, FS USB always ACKs successful data and the host doesn't know whether subsequent data will be accepted (ACKed) or not (NAKed). NAKs are very bad for bus bandwidth since the host has to transfer a complete frame of data for nothing and repeat it later. FS USB can therefore be bandwidth inefficient.

HS USB improves this with ACK (data was accepted and more can be sent) and NYET (data was accepted but please don't send more yet since I am not yet ready for it). After a NYET the host will use PING tokens (rather than data frames) to see whether the device is ready again or not, thus not wasting data bandwidth when it isn't.

Since you are seeing NYETs in low bandwidth cases it means that the stack is not utilising the HS USB controller's capabilities of multi-buffer descriptors. The HS USB can accept up to 16kByte of burst 480Mb/s data with no NYETs/PINGs and more if the receiver is handling the data on-the-fly and preparing more buffer space.

Therefore NYETs are normal for flow control in high data rate cases. They are also fine in low data rate cases when performance is not an issue. If they are seen in simple cases it means that the HS USB driver is not optimised for high data rate use and so may require improvements in cases where this could be of importance.

Regards

Mark

 

1,744 Views
carstengroen
Senior Contributor II

Thanks a lot Mark!

I got some of that explanation also on the net, but you explained it so I actually understood it immediately (as always when you explains something here on the forum!). Makes perfect sense. I will not need too much bandwidth anyway, so I can easily live with this "limitation", but its nice to know for the future, you never know

I will keep poking my keyboard here and see if something sensible comes out of it

Regards,
Carsten 

0 Kudos
Reply