IMXRT1050 USB DEVICE examples fail to run from OCRAM

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

IMXRT1050 USB DEVICE examples fail to run from OCRAM

Jump to solution
5,131 Views
jackking
Senior Contributor I

Similar to other issues I have had with other SDK samples (FatFS/SDcard), it seems that caching causes problems with USB device samples.

If I switch one of the samples (such as: dev_hid_mouse_bm) to use SRAM_OC as location of global vars, then USB will fail to enumerate.

I have also tried setting the config buffer to be cacheable in usb_device_config.h, but that causes USB device initialization to fail completely.

How can I use the USB stack when running from OCRAM?

Banners_and_Alerts_and_Properties_for_evkmimxrt1060_dev_hid_mouse_bm.jpg

workspace_-_evkmimxrt1060_dev_hid_mouse_bm_source_usb_device_config_h_-_MCUXpresso_IDE.jpg

Tags (2)
1 Solution
4,349 Views
Carlos_Mendoza
NXP Employee
NXP Employee

Hello guys,

In cases when a cacheable RAM region is being used as main RAM for the application it will be necessary to relocate the USB descriptors and data to a non cacheable memory. The following changes in the project will take care of this relocation:

  • In the usb_misc.h file update these definitions to the following, changes in bold:

#else
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
#define USB_BDT USB_LINK_USB_BDT_BSS
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#endif

  • In the project properties, inside the managed linker script configurations add the following Extra linker script input sections:

pastedImage_2.png

With the above configuration, the USB descriptors and data will be placed in the SRAM_DTC region, the same changes apply if you want to use the Non cacheable SDRAM region, you just need to change the region you want to use in the configuration above.

Hope this helps.

Regards,

Carlos Mendoza

View solution in original post

9 Replies
4,349 Views
jackking
Senior Contributor I

I tried defining sections to match what is in the USB macros of usb_misc.h, but it still didn't fix the issue.

workspace_-_evkmimxrt1060_dev_hid_mouse_bm_usb_include_usb_misc_h_-_MCUXpresso_IDE.jpg

Properties_for_evkmimxrt1060_dev_hid_mouse_bm.jpg

0 Kudos
4,349 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi Jack,

In fact, not only USB, but also ENET has this phenomenon. This is because these bus masters put their control and data exchange blocks in RAM, for example, USB Periodic Frame List. Since TCM do not need cache, anything written by USB/ENET peripheral can be read by MCU directly. But if you put these blocks in OCRAM, MCU will not know if the data is changed by other master. MCU will still read data from cache but not refresh it. So, if you hope to make full use of OCRAM, you should keep these control and data exchange blocks in DTCM, or close cache function.

Regards,

Jing

0 Kudos
4,349 Views
dmarks_ls
Senior Contributor I

Jing,

My biggest issue with the RT1050 SDK software right now is that this software has been provided in a state where much of the middleware (USB, lwIP, FatFS) does not function correctly on a platform where any memory other than (non-cacheable) SRAM_DTC is used for global data.  For a chip where the official eval board has 32 MB of SDRAM, forcing all global data into 128 KB is incredibly constraining and for many use cases impossible.  It is frustrating to NXP's customers to provide them this RT1050 software as-is, then only provide general advice when those customers inevitably incur multiple hours of development cost while discovering, reporting, and mitigating these issues.  SDK examples need to function correctly regardless of what memory region is used for global data.

Hui_Ma‌ / Mike has done a great job investigating these issues and fielding my concerns; it is my hope you will work closely with him and the rest of the SDK team to resolve these deficiencies in the SDK software, rather than leaving these issues as an exercise for the reader.  Thanks.

David R.

4,350 Views
Carlos_Mendoza
NXP Employee
NXP Employee

Hello guys,

In cases when a cacheable RAM region is being used as main RAM for the application it will be necessary to relocate the USB descriptors and data to a non cacheable memory. The following changes in the project will take care of this relocation:

  • In the usb_misc.h file update these definitions to the following, changes in bold:

#else
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
#define USB_BDT USB_LINK_USB_BDT_BSS
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA
#endif

  • In the project properties, inside the managed linker script configurations add the following Extra linker script input sections:

pastedImage_2.png

With the above configuration, the USB descriptors and data will be placed in the SRAM_DTC region, the same changes apply if you want to use the Non cacheable SDRAM region, you just need to change the region you want to use in the configuration above.

Hope this helps.

Regards,

Carlos Mendoza

4,349 Views
mark_byrnes1
Contributor I

Carlos - that answer was super helpful for me to get stated. I just would like another option. The NonCacheable section could also assigned to the OCRAM memory region. 

  • Set up another region of OCRAM (note - 0x10000 is really much more than is needed)

Memoryedit.png

  • Like Carlos, use the "NonCacheable" description on the new region

NonCacheable Region.png

  • Setup the MPU to block cache access to a MPU region in board.c

    /* Region 5 setting */
    MPU->RBAR = ARM_MPU_RBAR(5, 0x20210000);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 0, 1, 0, ARM_MPU_REGION_SIZE_64KB);

  • Then follow Carlos' first step and add USB_LINK_NONCACHE_NONINIT_DATA in usb_misc.h

This example kind of fragments the memory, but it should work well enough to get started running the USB demo completely in OCRAM.

3,111 Views
slimSHA
Contributor III

were you able to run the USB code on SRAM_OC with the above changes?. 
i have been trying the above changes, but the USB enumeration is failing.

this is my board.c changes 

/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
    MPU->RBAR = ARM_MPU_RBAR(5, 0x00000000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);

    /* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */
    MPU->RBAR = ARM_MPU_RBAR(6, 0x20000000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);

    /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
    MPU->RBAR = ARM_MPU_RBAR(7, 0x20200000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256B-ARM_MPU_REGION_SIZE_32KB);

    /*Region 11 for sram oc non cache area */
    MPU->RBAR = ARM_MPU_RBAR(11, 0x20238000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 0, 1, 0, ARM_MPU_REGION_SIZE_32KB);


    /* Region 8 setting: Memory with Normal type, not shareable, outer/inner write back */
    MPU->RBAR = ARM_MPU_RBAR(8, 0x80000000U);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);

    while ((size >> i) > 0x1U)
    {
        i++;
    }

    if (i != 0)
    {
        /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */
        assert(!(nonCacheStart % size));
        assert(size == (uint32_t)(1 << i));
        assert(i >= 5);

        /* Region 9 setting: Memory with Normal type, not shareable, non-cacheable */
        MPU->RBAR = ARM_MPU_RBAR(9, nonCacheStart);
        MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, i - 1);
    }

    /* Region 10 setting: Memory with Device type, not shareable, non-cacheable */
    MPU->RBAR = ARM_MPU_RBAR(10, 0x40000000);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4MB);

    /* Enable MPU */
    ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);

 

my usb_misc.h changes

#define USB_CONTROLLER_DATA      USB_LINK_NONCACHE_NONINIT_DATA
#else
#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS
#define USB_BDT    USB_LINK_USB_BDT_BSS
#define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA
#define USB_DMA_DATA_INIT_SUB
#define USB_CONTROLLER_DATA	USB_LINK_NONCACHE_NONINIT_DATA
#endif

 

my linker setttings

slimSHA_0-1641555736991.png

my mcu settings

slimSHA_1-1641555885335.png

am I missing anything?

 

 

0 Kudos
4,348 Views
jackking
Senior Contributor I

carlosmendoza‌ It looks like this change only works for the USB device examples.   Do you know the corresponding change that is necessary for the USB host examples?

0 Kudos
4,349 Views
dmarks_ls
Senior Contributor I

Thanks, Carlos.  I appreciate the clarification regarding .bss and .data for non-cacheable data (I was missing the .init section definition).

Will these source code modifications and linker script changes be incorporated into future SDK revisions and example projects, for USB and all other peripherals and middleware that are affected by RT1050 cache issues?

EDIT: I missed Jing's reply above.  I'm glad that NXP acknowledges that there is considerable work to be done, and I look forward to seeing this platform working at its full potential.

David R.

4,349 Views
jackking
Senior Contributor I

Jing,

Is there documentation on how to do this?  I don't know what the control and data exchange blocks are.  Is the developer expected to make changes to the MCUXpresso SDK code directly?

In the dev_hid_mouse_bm example, the buffer is already defined to use non-cached memory:

mouse.c

/*******************************************************************************
 * Variables
 ******************************************************************************/
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_MouseBuffer[USB_HID_MOUSE_REPORT_LENGTH];

In the thread: MCUX on RT1050 - MMC stack won't initialize  drodgers had a similar issue with ENET which seems to require a change to the SDK code, although the USB stack config and comments seem to suggest that caching should be taken care of automatically when configured correctly.

There is already cache handling code around the USB config buffer in usb_device_dci.c, are you suggesting that this is not sufficient to allow using cached memory for USB?

usb_device_dci.c:

#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
            if (length)
            {
                DCACHE_CleanByRange((uint32_t)buffer, length);
            }
#endif
            /* Call the controller send interface, the callbackFn is initialized in
            USB_DeviceGetControllerInterface */
            error = deviceHandle->controllerInterface->deviceSend(deviceHandle->controllerHandle, endpointAddress,
                                                                  buffer, length);
        }
        else
        {
#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
            if (length)
            {
                DCACHE_CleanInvalidateByRange((uint32_t)buffer, length);
            }
#endif