This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SPIM place transfer buffer in data RAM region

Hello,

I am interfacing a nRF52 based module with external flash memory. 

When I try to program/read a single byte, I get the "NRF_ERROR_INVALID_ADDR" error.

This relates to placing the transfer buffer in the data RAM region as mentioned in the SPIM documentation.

What exactly does that mean and how should I place the transfer buffer in the data RAM region?

Please help,

Thanks

Parents
  • Hi,

    If you have a normal buffer (static or not) which is not constant, it will be in the data RAM region. You can refer to Memory for details.

    If this does not help, can you specify which function returns NRF_ERROR_INVALID_ADDR, which chip you use, which SPIM instance you use and which SDK you use?

Reply
  • Hi,

    If you have a normal buffer (static or not) which is not constant, it will be in the data RAM region. You can refer to Memory for details.

    If this does not help, can you specify which function returns NRF_ERROR_INVALID_ADDR, which chip you use, which SPIM instance you use and which SDK you use?

Children
  • I am using a BMD 349 module based on nRF52840. 

    I am interfacing with AT25SF041 flash memory.

    I am using SDK 14.2.

    I am using SPIM instance 0.

    I have attached the relevant parts of the code:

    Below is slash_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;
        uint8_t read_buf;
        at_init();
        at_write_enable();
    
        uint32_t address = 0x01A8FF;
                //for(int i = 0; i < READ_WRITE_LENGTH; i++) data_buf[i] = i;
                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);
    }

    When I build the code on SES I get a yellow alert sign on the at_program line in main.c .

    The nrf_drv_spi_transfer function in at_program() gives the  NRF_ERROR_INVALID_ADDR error.

    Please help,

    thanks

  • Hi,

    RO said:
    When I build the code on SES I get a yellow alert sign on the at_program line in main.c .

    The yellow alert sign indicates a compiler warning. What does it say? Is it in at_program() NRF_ERROR_INVALID_ADDR is returned from the call to nrf_drv_spi_transfer()?

    Looking at your code, I see an easy to do a mistake, which I assume triggers the warning. read_buf is a variable, but you pass it as a pointer. You should have used &read_buf to the call to at_read. Since you are using an uninitialized variable as a pointer, this will point to whatever happened to be in RAM, so this is most likely the issue.

    (It is a good idea to always take warnings serious as that will save you a lot of time in the long run.)

  • Thanks, that removed the alert sign.

    And I don't seem to get the invalid address error. 

    But I still can't read the byte. I still see "00" in the debug window.

    I also created a new ticket: https://devzone.nordicsemi.com/f/nordic-q-a/57395/cannot-write-read-a-byte-from-external-flash-via-spi

    Any idea what I am doing wrong?

    Thanks

  • Hi,

    I see you have already got feedback on the new issue on the other thread, so I suggest we close this.

Related