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?

  • 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

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

Children
Related