Hi,
I am running a firmware on MCF52254. Basically, I am collecting data which the microcontroller computes through USB. I am sending the data through bulk endpoint without any problem. I am collecting the data in the micro controller at 5 MHz and sending it through the bulk endpoint to the host. I noticed that sometimes I get an error DMA error (DMA_ERR) and bus turnaround timeout error (BTO_ERR) on usb. When I cleared it, it starts sending the data again.
What could be cause of the problem. Is clearing the data fine as I need to send the data in real time to the host.
Regards.
Solved! Go to Solution.
> I am not using ethernet (FEC) and there is no DMA activity.
So it is surprising that the USB can't get enough bus bandwidth to send packets "sometimes".
So the only thing that can be locking the USB out is the CPU. And it SHOULD be at a lower priority than the USB on the Arbiter and (separately) on the SRAM.
Have you checked this? Has MPARK been changed from the default?
Another possibility is that you might have misaligned USB buffers. Are all your USB buffers (and the data in them) aligned to 4 bytes or 16 bytes? You probably don't want to hand the USB DMA controller odd addresses as it might make it run slower.
Another possibility is that the CPU is performing one or more MOVEM.L instructions, and they may block the SRAM until finished. The way to avoid this is to note that "The SRAM is partitioned into two physical memory arrays to allow simultaneous access to arrays by the processor core and another bus master.". That isn't made clear, but it seems to mean the upper and lower 32k blocks can be accessed simultaneously. That means you should put all your USB buffers in one half and the CPU memory (and most importantly the stack) in the other half. The RAMBAR should be programmed so that the USB has the highest priority in both halves.
It is also possible but unlikely that you are using an efficient "memcpy()" implementation. Most of the ones I've seen are pretty poor. The ones I write use MOVEM.L and might cause the problems you're seeing. So you should check the assembly output of the memcpy() function to make sure it isn't "too good".
Tom
Have you read "20.3.5 USB Transaction" in the Reference Manual where it mentions DMA_ERR, and lists two conditions that cause it to be set? You're getting BTO_ERR as well, so you've got the first condition.
The description of DMA_ERR says what to do.
Try changing the MPARK register settings. Do you have other DMA Controller activity? Is the Ethernet running? Both of them default to higher priority than USB.
Do you have RAMBAR[PRIU:PRIL;SPV] and (the other) RAMBAR[BDE] bits set properly?
MCF52254, so 64k SRAM and no mini-flexbus, so you can't be using external storage.
> I am collecting the data in the micro controller at 5 MHz
This is only an 80MHz CPU. That means you only have 16 clock cycles per sample ( 8 bit, 16 bit, 32 bit?) transferred. That includes reading the data, transferring to memory, transferring in and out of the CPU for processing, copying to the USB buffers and final USB DMA transfer. You may need to make your code more efficient and minimise the number of data copies. The highest efficiency would be to DMA the samples from the ADC (or whatever) directly into the USB data buffers for instance.
Tom
"The description of DMA_ERR says what to do."
This is the description from the documentation: -
"In device mode, the BDT is not written back nor is the TOK_DNE interrupt triggered because it is assumed that a second attempt is queued and succeed in the future."
So, it means I should own the buffer descriptors and resend the data.
Will clearing the token suspend from the control register starts sending the data again.
MCF_USB_OTG_CTL &= ~MCF_USB_OTG_CTL_TXSUSPEND_TOKENBUSY;
Thanks for the help.
Regards.
> "The description of DMA_ERR says what to do."
> This is the description from the documentation: -
I meant the bit in the previous paragraph:
First, the memory latency on the BVCI initiator
interface may be too high and cause the receive FIFO to overflow. This is predominantly a hardware
performance issue, usually caused by transient memory access issues.
So you should be finding and fixing the memory problem. That you do by reprogramming MPARK, or by making the other DMA less aggressive.
You didn't answer my question, which was "Are you using DMA and/or the FEC"?
Tom
Hi Tom,
Thanks for the clarification.
I am not using ethernet (FEC) and there is no DMA activity. Apart from DMA timers which I used them periodically for some timing operations only, no DMA activity.
Regards.
> I am not using ethernet (FEC) and there is no DMA activity.
So it is surprising that the USB can't get enough bus bandwidth to send packets "sometimes".
So the only thing that can be locking the USB out is the CPU. And it SHOULD be at a lower priority than the USB on the Arbiter and (separately) on the SRAM.
Have you checked this? Has MPARK been changed from the default?
Another possibility is that you might have misaligned USB buffers. Are all your USB buffers (and the data in them) aligned to 4 bytes or 16 bytes? You probably don't want to hand the USB DMA controller odd addresses as it might make it run slower.
Another possibility is that the CPU is performing one or more MOVEM.L instructions, and they may block the SRAM until finished. The way to avoid this is to note that "The SRAM is partitioned into two physical memory arrays to allow simultaneous access to arrays by the processor core and another bus master.". That isn't made clear, but it seems to mean the upper and lower 32k blocks can be accessed simultaneously. That means you should put all your USB buffers in one half and the CPU memory (and most importantly the stack) in the other half. The RAMBAR should be programmed so that the USB has the highest priority in both halves.
It is also possible but unlikely that you are using an efficient "memcpy()" implementation. Most of the ones I've seen are pretty poor. The ones I write use MOVEM.L and might cause the problems you're seeing. So you should check the assembly output of the memcpy() function to make sure it isn't "too good".
Tom
Hi Tom,
Thanks for the useful information.
One last question, is it possible to send both even and odd usb buffer descriptors simultaneously means as I send the even BD, then immediately after can I send odd BD without waiting for TOKEN_DONE.
Regards.
> is it possible to send both even and odd usb buffer descriptors simultaneously
I have no idea. I only read the manuals to answer these questions. I would recommend "doing it by the book" though.
Tom