0
\$\begingroup\$

I am using a BMD-340 module based on the nRF52840 Microcontroller.

I am interfacing with AT25SF041 flash memory.

I am writing a byte to a specific address in Flash.

But when I try to read the memory location, On the debug window I only see "00".

Even when I erase a sector, I still see "00", when I should probably be seeing "FF".

I don't see any error messages on the debug window.

I can read the status registers and Device ID completely fine, so I suppose SPI read function is working.

Below is flash_mem.c

#include "flash_mem.h"
#include "nrf_drv_spi.h"
#include "nrf_gpio.h"

static const nrf_drv_spi_t m_spi_at = NRF_DRV_SPI_INSTANCE(0);

static uint32_t spi_config(void)
{
    uint32_t err_code;
    nrf_drv_spi_config_t config = NRF_DRV_SPI_DEFAULT_CONFIG;
    config.frequency = NRF_DRV_SPI_FREQ_1M;
    config.mode      = NRF_DRV_SPI_MODE_3;
    config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
    config.mosi_pin  = AT_PIN_MOSI;
    config.miso_pin  = AT_PIN_MISO;
    config.sck_pin   = AT_PIN_SCK;
    config.ss_pin    = AT_PIN_CS; 
    err_code = nrf_drv_spi_init(&m_spi_at, &config, NULL, NULL);
    if (err_code != NRF_SUCCESS)
    {
        // Initialization failed. Take recovery action.
    }   
    nrf_gpio_cfg_output(AT_PIN_CS);
    nrf_gpio_pin_set(AT_PIN_CS);
    return err_code;
}


uint32_t at_init(void)
{
    return spi_config();
}

void at_read_rems(uint8_t * manufacturer_id, uint8_t * device_id)
{
    uint8_t spi_tx_cmd[] = {0x9F};
    uint8_t spi_rx_response[3];
    nrf_gpio_pin_clear(AT_PIN_CS);
    nrf_drv_spi_transfer(&m_spi_at, spi_tx_cmd, sizeof(spi_tx_cmd), spi_rx_response, sizeof(spi_rx_response));
    nrf_gpio_pin_set(AT_PIN_CS);
    *manufacturer_id = spi_rx_response[1]; 
    *device_id = spi_rx_response[2];
}


void at_write_enable(void)
{
    static uint8_t spi_tx_cmd[] = {CMD_WREN};
    nrf_gpio_pin_clear(AT_PIN_CS);
    nrf_drv_spi_transfer(&m_spi_at, spi_tx_cmd, sizeof(spi_tx_cmd), 0, 0);
    nrf_gpio_pin_set(AT_PIN_CS);
}

void at_program(uint32_t address, uint8_t * data_ptr, uint32_t data_length)
{
    uint8_t spi_tx_cmd[] = {CMD_PROGRAM, (address >> 16) & 0xFF, (address >> 8) & 0xFF, (address >> 0) & 0xFF};
    nrf_gpio_pin_clear(AT_PIN_CS);
    nrf_drv_spi_transfer(&m_spi_at, spi_tx_cmd, sizeof(spi_tx_cmd),NULL, NULL);
    while(data_length > 255)
    {
        nrf_drv_spi_transfer(&m_spi_at, data_ptr, 255, NULL, NULL);
        data_ptr += 255;
        data_length -= 255;
    }
    nrf_drv_spi_transfer(&m_spi_at, data_ptr, data_length, NULL, NULL);
    nrf_gpio_pin_set(AT_PIN_CS);
}


void at_read(uint32_t address, uint8_t * data_ptr, uint32_t data_length)
{
    uint8_t spi_tx_cmd[] = {CMD_READ, (address >> 16) & 0xFF, (address >> 8) & 0xFF, (address >> 0) & 0xFF};
    nrf_gpio_pin_clear(AT_PIN_CS);
    nrf_drv_spi_transfer(&m_spi_at, spi_tx_cmd, sizeof(spi_tx_cmd), NULL, NULL);
    while(data_length > 255)
    {
        nrf_drv_spi_transfer(&m_spi_at, 0, 0, data_ptr, 255);
        data_ptr += 255;
        data_length -= 255;
    }
    nrf_drv_spi_transfer(&m_spi_at, NULL, NULL , data_ptr, data_length);
    nrf_gpio_pin_set(AT_PIN_CS);
}

Below is part of main.c

int main(void)
{

    uint8_t status_register, man_id, dev_id;
    uint8_t data_buf = 0x23;
    uint32_t address = 0x01A8FF;
    uint8_t read_buf;
    at_init();
    at_write_enable();
    at_sector_erase(address);
     nrf_delay_ms(500);

     at_read(address, &read_buf, 1);
       NRF_LOG_INFO("Reading address %.8x: ", address);
       NRF_LOG_INFO("%.2X-" ,(int)read_buf);


       at_program(address, &data_buf, 1);

       at_read(address, &read_buf, 1);
       NRF_LOG_INFO("Reading address %.8x: ", address);
       NRF_LOG_INFO("%.2X-" ,(int)read_buf);
}

I don't have a logic analyzer to scope the signals yet.

Can someone help? Thanks,

\$\endgroup\$
2
  • 2
    \$\begingroup\$ I don't know anything about the library code. And I'd normally go find working code samples to be sure I'm not missing something (not sure why you aren't, or haven't shown us what you found.) But I notice you are both informing the library of the SS line and your are also manually operating it. That doesn't make sense. If they need knowledge of that line, then the so because they use it. If so, there will be a function API for that which I don't see you using. But I'm ignorant of the library. So I'll let others help. \$\endgroup\$ – jonk Feb 6 '20 at 17:02
  • 1
    \$\begingroup\$ For anyone interested in this topic here, the OP's same question on Nordic Semiconductor's DevZone is also active - see "Cannot write/read a byte from external Flash via SPI" - so answers / suggestions / further details / etc. might appear there. \$\endgroup\$ – SamGibson Feb 6 '20 at 18:08
1
\$\begingroup\$

You don't show the erase function, but depending on which size of erase you send, it may take more than 2000ms to complete. Full chip erase can take 10 seconds. You should check the flash status register if it says it's busy or not. Therefore it may not be ready for the first read command. And you don't enable write latch before byte write, so it will not write anything. Even if it did, page write takes about 3ms, so it would not be immediately ready for another read. Please also note that your write function won't work, as the chip works in 256 byte pages, so you can write up to 256 bytes, and if a write gets split between two 256-byte pages, you need a wrapper to handle it. Reading works from any address with any amount of bytes.

\$\endgroup\$
3
  • \$\begingroup\$ I'm erasing 4Kb, so that takes a maximum of 300ms according to the datasheet. I added the Write_enable command before the byte write. I still see only "00" when I read. Also I am trying to write/read only 1 byte here, so I haven't written a loop to handle >256 bytes. Thanks \$\endgroup\$ – Rohit Garg Feb 6 '20 at 18:53
  • \$\begingroup\$ So did you put a 3ms delay after write so chip is ready for read? \$\endgroup\$ – Justme Feb 6 '20 at 19:34
  • \$\begingroup\$ Yes I added a 10ms delay after write, I only read back zeros.. \$\endgroup\$ – Rohit Garg Feb 6 '20 at 19:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.