This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

USB Mass Storage Class on external QSPI flash

Hello guys,

We are using SES and SDK15.3.0. Our SoC is from nRF52840 family. We have a custom board with external QSPI flash memory that we want to use as USB MSC device. After some consultations with Nordic technical support (see this thread), we selected  MX66L1G45G (3.0V) memory module for our external memory.

usbd_msc example from SDK 15.3.0 did not work on our custom board - disk initialization failed issue:

Changing the addressing mode to 32-bit (because we are using memory that is >128Mb) did not help. We changed the addressing mode inside sdk_config.h file as follows:

// <o> QSPI_CONFIG_ADDRMODE  - Addressing mode.
 
// <0=> 24bit 
// <1=> 32bit 

#ifndef QSPI_CONFIG_ADDRMODE
#define QSPI_CONFIG_ADDRMODE 1
#endif

// <o> NRFX_QSPI_CONFIG_ADDRMODE  - Addressing mode.
 
// <0=> 24bit 
// <1=> 32bit 

#ifndef NRFX_QSPI_CONFIG_ADDRMODE
#define NRFX_QSPI_CONFIG_ADDRMODE 1
#endif

QSPI link between our nRF52840 and external memory is OK because QSPI example is working properly.

Do you have any suggestions on what should we change in order to have usbd_msc example working on our custom board?

Thank you very much for your time and effort! It is really appreciated.

Sincerely,

Bojan.

Parents
  • Hello Bojan, 

    QSPI link between our nRF52840 and external memory is OK because QSPI example is working properly.

     I'm glad to hear that the QSPI example is working properly. 

    Do you have any suggestions on what should we change in order to have usbd_msc example working on our custom board?

    Are the settings the same as with QSPI example? Are you using FAT FS? Can you please provide your project for testing? Difficult for me to say at this moment.

    Thanks!

    Kind regards,
    Øyvind 

  • Hello ,

    Thanks for your reply!

    My starting point is usbd_msc example. Inside sdk_config.h file I just defined and set QSPI_CONFIG_ADDRMODE and NRFX_QSPI_CONFIG_ADDRMODE to have 32-bit addressing mode and that's all. The rest of the code is actually the code from usbd_msc example.

    Yes, FAT FS is used. The issue appears when disk_initialize(0); function is called within fatfs_init(). This is when I get the error "Disk initialization failed".

    Am I missing something?

    Sincerely,

    Bojan.

  • Hi .

    To the best of my understanding, MX66L1G45G is by default set to 24-bit addressing and I would need to execute EN4B command in order to use 32-bit addressing and access all memory locations. Correct?

    I did not touch anything in  usbd_msc example except addressing. Can you point the places in example where I need to change memory/block size, addresses...?

    Thanks in advance!

    Sincerely,

    Bojan.

  • bojan said:
    To the best of my understanding, MX66L1G45G is by default set to 24-bit addressing and I would need to execute EN4B command in order to use 32-bit addressing and access all memory locations. Correct?

     Yes, this is correct. Setting the 32-bit ADDRMODE in sdk_config switches driver and internally peripheral to 32-bit. The suggestion from our developer is to test the MSC example with 24-bit and simple QSPI mode. This means configuring: 

    QSPI_CONFIG_READOC = 0
    QSPI_CONFIG_WRITEOC = 0
    QSPI_CONFIG_ADDRMODE = 0 

    On page 22 in the MX66L1G45G datasheet, you find the Enter 4-byte (EN4B) mode and Exit 4-byte (EX4B) mode. To test with 24-bit, be sure to issue EX4B. 

    Edit: Have a look at configure_memory() in examples\peripheral\qspi\main.c, this function shows how to send commands to flash using commands found in modules\nrfx\drivers\src\nrfx_qspi.c

    Please ignore my comment regarding "...have you edited correct memory/block size, addresses, etc in the example?" at this time. 

  • Hello, .

    I tried what you suggested. By default in  usbd_msc example, 24-bit and simple QSPI mode is used. This means that

    QSPI_CONFIG_READOC = 0
    QSPI_CONFIG_WRITEOC = 0
    QSPI_CONFIG_ADDRMODE = 0 

    is already set in sdk_config.h file.

    Before calling problematic fatfs_init() function of usbd_msc example, I tried to execute EX4B flash command (0xE9). I first initialized qspi and then applied configure_memory() function like this:

        nrf_drv_qspi_config_t config = NRF_DRV_QSPI_DEFAULT_CONFIG;
    
        err_code = nrf_drv_qspi_init(&config, qspi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("QSPI example started.");
    
        configure_memory();

    Inside configure_memory() function I execute EX4B command:

    static void configure_memory()
    {
        uint8_t temporary = 0x40;
        uint32_t err_code;
        nrf_qspi_cinstr_conf_t cinstr_cfg = {
            .opcode    = QSPI_STD_CMD_RSTEN,
            .length    = NRF_QSPI_CINSTR_LEN_1B,
            .io2_level = true,
            .io3_level = true,
            .wipwait   = true,
            .wren      = true
        };
    
        // Send reset enable
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Send reset command
        cinstr_cfg.opcode = QSPI_STD_CMD_RST;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Exit 4-Byte mode - EX4B command
        cinstr_cfg.opcode = QSPI_STD_CMD_EX4B;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Switch to qspi mode
        cinstr_cfg.opcode = QSPI_STD_CMD_WRSR;
        cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_2B;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &temporary, NULL);
        APP_ERROR_CHECK(err_code);
    }

    To make sure EX4B command is properly executed, I was reading configuration and status registers (RDCR/RDSR commands) before and after applying EX4B command. Here is what I get:

    Before applying EX4B command:

    <info> app: Configuration register: 0x7
    <info> app: Status register: 0x42
    
    

    After applying EX4B command:

    <info> app: Configuration register: 0x7
    <info> app: Status register: 0x40
    

    Judging by the state of Configuration register (0x7), it seems that flash memory is by default using 24-bit addressing (bit5 (4 BYTE) of the Configuration register is set to 0 even before EX4B command is applied). When I send EN4B command I read 0x27 from the Configuration register which means bit5  of the configuration register is properly set to 1. All this proves to me that there is a proper communication between nRF52840 and QSPI flash.

    Anyway, with EX4B command executed, I still have the same problem with disk_initialize(0) function that is called within fatfs_init() function. disk_initialize(0) returns 1 (which means that m_drives[drv].state is equal to 1 and it should be equal to 0).

    Should I look deeper into disk_initialize(0) function to try to figure out what is wrong there?

    Sincerely,

    Bojan.

  • Hi, .

    Here is what I noticed this morning:

    In a chain of function calls

    fatfs_init() >> disk_initialize(0) >> nrf_blck_dev_init() >> init()

    function

     

    p_blk_dev->p_ops->init(p_blk_dev, ev_handler, p_context);
     

    returns 0x8 error code which should be the code for NRF_ERROR_INVALID_STATE (Invalid state, operation disallowed in this state).

    I am unable to go deeper and explore what happens inside init() function and why the system is in invalid state. Do you have any hints for me?

    Regards,

    Bojan

  • When I remove the code you suggested to add:

        nrf_drv_qspi_config_t config = NRF_DRV_QSPI_DEFAULT_CONFIG;
    
        err_code = nrf_drv_qspi_init(&config, qspi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("QSPI example started.");
    
        configure_memory();

    the init() function returns error code 0x6 - NRF_ERROR_NOT_SUPPORTED! I would say that the issue has something with how SPI/QSPI is initialized and used/configured.

Reply
  • When I remove the code you suggested to add:

        nrf_drv_qspi_config_t config = NRF_DRV_QSPI_DEFAULT_CONFIG;
    
        err_code = nrf_drv_qspi_init(&config, qspi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("QSPI example started.");
    
        configure_memory();

    the init() function returns error code 0x6 - NRF_ERROR_NOT_SUPPORTED! I would say that the issue has something with how SPI/QSPI is initialized and used/configured.

Children
  • Hi Bojan, 

    Can you please share your project?

    Kind regards,
    Øyvind

  • Hello .

    Sure. Find it attached. However, the project is just a copy from usbd_msc example.

    It is placed under examples/peripheral.

    Sincerely,

    Bojan.

    usbd_msc_custom_board.zip

  • Thank you, ! Could you also add as much debug information as possible, i.e. the error codes that returned, etc? I will need to provide our developers with as much information as possible.

  • when I include the following piece of the code before fatfs_init() function:

    nrf_drv_qspi_config_t config = NRF_DRV_QSPI_DEFAULT_CONFIG;
    
    err_code = nrf_drv_qspi_init(&config, qspi_handler, NULL);
    APP_ERROR_CHECK(err_code);
    NRF_LOG_INFO("QSPI example started.");
    
    configure_memory();

    the init() function in the chain of calls:

    fatfs_init() >> disk_initialize(0) >> nrf_blck_dev_init() >> init()

    returns 0x8 error code which should be the code for NRF_ERROR_INVALID_STATE (Invalid state, operation disallowed in this state).

    When I remove the above piece of code before fatfs_init() function, the init() function returns error code 0x6 - NRF_ERROR_NOT_SUPPORTED

  • Try enabling the following in your sdk_config.h

    // <e> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED - Enables logging in the module.
    //==========================================================
    #ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED
    #define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED 1
    #endif
    // <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL  - Default Severity level
     
    // <0=> Off 
    // <1=> Error 
    // <2=> Warning 
    // <3=> Info 
    // <4=> Debug 
    
    #ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL
    #define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL 4
    #endif


    And after running once or twice with settings above, please run with the following as well:
    // <e> APP_USBD_MSC_CONFIG_LOG_ENABLED - Enables logging in the module.
    //==========================================================
    #ifndef APP_USBD_MSC_CONFIG_LOG_ENABLED
    #define APP_USBD_MSC_CONFIG_LOG_ENABLED 1
    #endif
    // <o> APP_USBD_MSC_CONFIG_LOG_LEVEL  - Default Severity level
     
    // <0=> Off 
    // <1=> Error 
    // <2=> Warning 
    // <3=> Info 
    // <4=> Debug 
    
    #ifndef APP_USBD_MSC_CONFIG_LOG_LEVEL
    #define APP_USBD_MSC_CONFIG_LOG_LEVEL 4
    #endif

    This should give more information on what is going on.

    The last suggestion after adding debug information would be to test with the latest SDK v16.0.0.

Related