USB Host enumeration fails

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

USB Host enumeration fails

Contributor III

I am having trouble trying to get an application to run an application on the imxrt1052 using USB host. It fails the enumeration. There are other topics that talk about this and it appears to be linked with using cacheable memory such as external SDRAM or OCRAM etc.

I have followed this post: using non-cached memory that shows how to partition the internal OCRAM so that data for USB uses non-cacheable memory but it assumes the rest of the application uses the cached part of the OCRAM.

The SDK examples (such as evkbimxrt1050_host_msd_fatfs_freertos) are not actually that helpful because they are all quite small and configured to run entirely in internal memory which is never going to be the case for a real-world application of any decent size. I have modified the one I just mentioned to run XIP from QSPI flash and it's fine because all data is inside TCM memory.

I have a debug configuration that runs entirely from external SDRAM and that works fine.

I'm posting the output of the linker below that shows how the memory is used with about 5KB in SRAM_OC_NCACHE all for USB data buffers.

Is there anything else that needs to be done to get the USB Host code to enumerate? i.e. does the code for usb have to run from RAM? I have tried modifying my link scripts to put any *_usb_*.o modules into TCM SRAM (.text, .rodata) but that doesn't seem to help either.

Is there a simple way I can temporarily disable data caching so that I can at least test that this is why things are not working?

Memory region Used Size Region Size %age Used
BOARD_FLASH: 1009808 B 4 MB 24.08%
BOARD_FLASH_FS: 0 GB 16 MB 0.00%
BOARD_SDRAM: 12430852 B 14 MB 84.68%
SRAM_DTC: 0 GB 128 KB 0.00%
SRAM_ITC: 45296 B 128 KB 34.56%
SRAM_OC: 0 GB 128 KB 0.00%
SRAM_OC_NCACHE: 5792 B 127 KB 4.45%
SRAM_OC_SSBL: 4 B 1 KB 0.39%

Labels (1)
3 Replies

Contributor III

I did get this working eventually...

Here's some things I learned along the way that may help if someone else has similar trouble.

Don't worry about forcing actual code to run from internal RAM, I don't think it makes any difference. I modified the usb host MSD FreeRTOS SDK sample to run XIP from external QSPI flash and it was fine as is my own app which is considerably larger.

If using FreeRTOS then ensure configAPPLICATION_ALLOCATED_HEAP is set to 1 and configured appropriately. i.e. you have pick one of the heapx.c options and then declare the ucHeap static array in your app code thus:

/* Allocate the memory for the heap. */

Note that the USB_DMA_NONINIT_DATA_ALIGN define will expand to a section you chose as per the notes in the article I mentioned in the original post. For me this was non-cached external SDRAM because I used an generous 1MB for the FreeRTOS heap which was too big to fit inside internal memory. Having the FreeRTOS heap allocated to non-cacheable memory is critical and this feature was disabled in my application because I didn't intend to use the heap in this way.

Using the tightly coupled internal memory (SRAM_ITC, SRAM_DTC) is better as there will never be cache issues (but there will if using SRAM_OC). I had assumed part of the problem was that internal memory had to be used for performance reasons, for code as well as data, but it seems that it's data coherency that is mostly the issue that needs sorting. This is why you can get away with using say external SDRAM for all data as long as it's in a non-cacheable region.

I guess that was probably enough to get things working, but I did additionally modify my linker scripts to put all .data for *_usb_*.o modules into SRAM_DTC just because I thought it was a good idea. I'm not sure this is needed however.

Another problem I had that I think is a C/C++ interop issue (and I didn't resolve it but worked around it) is that I tried putting my USBHost FreeRTOS task into a C++ class (actually a singleton) but I had lots of weird linker errors along the lines of:

"relocation truncated to fit: R_ARM_PREL31 for .text bla bla"

I think this was related to jumping code between different areas of memory greater than 31-bits. I worked around this by just making the code plain 'C' instead of 'C++'. The only consequence for me was that I wasn't able to use my fancy debug logging functionality that is C++ based.

Contributor I

I'm working with RT1176 and I had the same issue with usb, what worked for me was:


2) enabling the cache invalidation code in usb/host/usb_host_hci.c:

     if (transfer->transferLength > 0)
         DCACHE_CleanByRange((uint32_t)transfer->transferBuffer, transfer->transferLength);

The above code can be enabled setting USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE=1, but such setting is not supported for cortex M7:

#if defined __CORTEX_M && (__CORTEX_M == 7U)

so I forced the compilation putting "if 1" only in those areas where the cache invalidation was disabled (in total only 3 places).

In this way the usb seems to be working, but:

1) I don't understand why USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE=1 is not compatible with cortex M7

2) I'd like someone from NXP validates the patch or give me some hints how to get usb host working with transfer buffers dinamically allocated in cacheable ram. I could place the heap in a noncacheable ram  (this works), but this slows down the system, am I right? 


thank you

Tags (2)

Contributor II

hi, gianlucacornacchia.

My test case shows that you can not do that.

In addition to your guidance( 1) setting DATA_SECTION_IS_CACHEABLE=1, 2) enabling the cache invalidation code in usb/host/usb_host_hci.c, 3) place ucHeap in cachable space), I turn on the LCD controller with frame buffer not in TCM, the write-read-verify testing round for flash disk is sure to be fail after several hundreds testing rounds.

Testing round seems OK if LCD controller is turned off.

I use RT1052 EVKB, most probaly you can get the same result for RT1176.