External Flash W25Q64 with USBD_MSC example on NRF52840

Hi All,

        I have an external flash W25Q64 on which I have to mount a file system. I am using USBD_MSC example of NRF52840. My main goal is to create a file inside the flash memory chip. And when USB is plugged into the device it should be seen as a drive on laptop/desktop and I should be able to access the file which was created in the flash chip.I have made the connections on the NRF52840 using the pin configurations below:-


#define SDC_SCK_PIN     (25) 
#define SDC_MOSI_PIN   (23) 
#define SDC_MISO_PIN   (24) 
#define SDC_CS_PIN       (15) 

I have also configured the details in nrf_serial_flash_params.c file. 

static const nrf_serial_flash_params_t m_sflash_params[] = {
    {    
        .read_id = { 0xEF,0x40,0x17 },
        .capabilities = 0x00,
        .size = 8 * 1024 * 1024,
        .erase_size = 2 * 1024,
        .program_size = 256,
    }
};

nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_id)
{
    size_t i;

    for (i = 0; i < ARRAY_SIZE(m_sflash_params); ++i)
    {
        if (memcmp(m_sflash_params[i].read_id, p_read_id, sizeof(m_sflash_params[i].read_id)) == 0)
        {
            return &m_sflash_params[i];
        }
    }

    return NULL;
}

When I run the example , i get the following error:-

<info> app: Initializing disk 0 (QSPI)...

 <error> app: Disk initialization failed.

1) Will this example run for W25Q64 IC??

2) This example also includes FATfs files. Will it automatically create a file system on the external SPI W25Q64 flash memory??

3) Why am I getting "Disk initialization failed." error?

4) Inside sdk_config.h do I also need to enable pin configurations for Qspi??

5) How to test this application? Currently I am using NRF52840 DK and then connecting external spi flash to it. But for USB detection how will it work?

I have attached few files here to check for the configurations

04162.sdk_config.h

5287.W25Q64BV.PDF

Please help me to solve this issue. I need to solve this issue on an urgent basis. Your help will be appreciated. I have also attached W25Q64 datasheet for your reference.

Thanks & Regards,

Snehal

Parents Reply
  • I dont think so you are wishing to help me in any ways. Before going on to logic analyzer I wanted to verify my code from you. Sorry to be rude but this is really frustrating. We wait for days and this is what we get !!

    I dont even think you have seen my comments or read my code. I am really disappointed by this. This is support forum and I am not getting any help regarding the issues. Its been a month now and my patience is getting finished now.

Children
  • Hi,

    I have reviewed the code, but it's difficult to say what's wrong without having the SPI flash device you are using to debug it.

    You mentioned the code was stuck:

    sne_333 said:
    The code is actually getting stuck in function nrf_drv_spi_read.

     I answered:

    Sigurd said:
    Could you check what nrf_drv_spi_read() is waiting for?

    Did you debug and check this? 

  • Yes I debugged and modified my code but still it gets stuck at nrf_drv_spi_transfer function. My updated functions are as follows:-

    void at_write_enable(void)
    {
        ret_code_t err_code;
       static uint8_t spi_tx_cmd[] = {0x06};
       nrf_gpio_pin_clear(SPI_SS_PIN);
        nrf_drv_spi_transfer(&m_spi, spi_tx_cmd, 1, 0, 0);
        vTaskDelay(1000);
        nrf_gpio_pin_set(SPI_SS_PIN);
    }
    
    
    void at_write_disable(void)
    {
        ret_code_t err_code;
       spi_tx_buf[0] = 0x04;
       nrf_gpio_pin_clear(SPI_SS_PIN);
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi, spi_tx_buf, 1, 0, 0));
        vTaskDelay(1000);
        nrf_gpio_pin_set(SPI_SS_PIN);
         vTaskDelay(1000);
    
    }
    
    
    
    ret_code_t nrf_drv_spi_read(void *   p_rx_buffer,
                              size_t   rx_buffer_length,
                              uint32_t src_address)
    {
       at_write_disable();
    
        uint8_t spi_tx_cmd[] = {0x0b, (src_address >> 16) & 0xFF, (src_address >> 8) & 0xFF, (src_address >> 0) & 0xFF};
       nrf_gpio_pin_clear(SPI_SS_PIN);
        nrf_drv_spi_transfer(&m_spi,spi_tx_cmd,sizeof(spi_tx_cmd),NULL,NULL);
        vTaskDelay(1000);
        while(rx_buffer_length > 255)
        {
            nrf_drv_spi_transfer(&m_spi, 0, 0, p_rx_buffer, 255);
            p_rx_buffer += 255;
            rx_buffer_length -= 255;
        }
        nrf_drv_spi_transfer(&m_spi, NULL, NULL , p_rx_buffer, rx_buffer_length);
       nrf_gpio_pin_set(SPI_SS_PIN);
       return NRFX_SUCCESS;
    }
    
    
     
    ret_code_t nrf_drv_spi_write(uint8_t * data_ptr,uint32_t data_length,uint32_t address)
    {
    
        at_write_enable();
        vTaskDelay(1000);
        uint8_t spi_tx_cmd[] = {0x02, (address >> 16) & 0xFF, (address >> 8) & 0xFF, (address >> 0) & 0xFF};
        nrf_gpio_pin_clear(SPI_SS_PIN);
        nrf_drv_spi_transfer(&m_spi, spi_tx_cmd, sizeof(spi_tx_cmd),NULL, NULL);
        while(data_length > 255)
        {
            nrf_drv_spi_transfer(&m_spi, data_ptr, 255, NULL, NULL);
            data_ptr += 255;
            data_length -= 255;
        }
        nrf_drv_spi_transfer(&m_spi, data_ptr, data_length, NULL, NULL);
        nrf_gpio_pin_set(SPI_SS_PIN);
           return NRFX_SUCCESS;
    
    }
    
    uint8_t SFlash_Erase(nrf_spi_erase_len_t length,uint32_t start_address)
    {
    	int i;
    	uint8_t tx_data[4];
    
    
    	// enable write
    	tx_data[0] = 0x02;
        nrf_gpio_pin_clear(SPI_SS_PIN);
        nrf_drv_spi_transfer(&m_spi,tx_data,1,spi_rx_buf,4);
            vTaskDelay(1000);
        nrf_gpio_pin_set(SPI_SS_PIN);
    
    	// wait until the operation is completed
    
    	// erase chip
    	tx_data[0] = length;
            tx_data[1] = (start_address >> 16);
            tx_data[2] = (start_address >> 8);
            tx_data[3] = (start_address);
    
        nrf_drv_spi_transfer(&m_spi,tx_data,4,spi_rx_buf,4);
            vTaskDelay(1000);
        nrf_gpio_pin_set(SPI_SS_PIN);
    
    	vTaskDelay(2000);
    
            return NRF_SUCCESS;
    }

    Currently the code is getting stuck sometimes at "at_write_enable" as well as "nrf_drv_spi_read" and "nrf_drv_spi_write" i dont understand why?

  • Hi,

    Since you did not provide an event handler to nrf_drv_spi_init(), the call to nrf_drv_spi_transfer() is performed in blocking mode, which means that this function returns when the transfer is finished.
    I would assume you are stuck in spi_xfer(), waiting for NRF_SPI_EVENT_READY event. But you should debug, and confirm this,
    As mentioned by Kenneth in e.g. this similar post, make sure that CLK toggle as expected (and is not forced low externally by some electrical issues)

Related