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

  • The code which I wrote for nrf_drv_spi_read is not correct. The nrf_drv_qspi_read is different. I need help to convert that fucntion. 

  • sne_333 said:
    The code which I wrote for nrf_drv_spi_read is not correct

    Maybe check with an Logic analyzer, e.g. Saleae logic or similar, that what is sent is as expected. 

  • 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.

  • 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?

Related