Reading magnetometer LIS2MDL via SPI

Hi,

using segger v5.66, SDK 17.1

My hardware has 4 wire SPI lines running to magnetometer, Initially I was unable to read the WHO_AM_I(4F)  register. After going through the datasheet I came across this

so I was suspecting this was actual problem because of which I was unable to read register

The information given in datasheet I don't understand completely what to be done, Here is my current code

#define ADD_REG_WHO_AM_I          0x4F
#define WHO_AM_I_DEFAULTvalue     0x40  //reserved register

#define SPI_BUFFER    8
#define SPI_INSTANCE  0

#define SET_READ_SINGLE_CMD(x)  (x | 0x80)

uint8_t spi_tx_buf[SPI_BUFFER];
uint8_t spi_rx_buf[SPI_BUFFER];

static volatile bool spi_xfer_done;

//create an instance
static const nrf_drv_spi_t m_spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);

void spi_event_handler(nrf_drv_spi_evt_t const * p_event, void * p_context)
{
    spi_xfer_done = true;
}

void spi_init(void)
{
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;

    spi_config.ss_pin     = 27;
    spi_config.miso_pin   = 05;
    spi_config.mosi_pin   = 17;
    spi_config.sck_pin    = 26;
    spi_config.frequency  = NRF_DRV_SPI_FREQ_4M;

    APP_ERROR_CHECK(nrf_drv_spi_init(&m_spi, &spi_config, spi_event_handler, NULL));

}

int lsm2_read_reg(char reg)
{
    spi_tx_buf[0] = SET_READ_SINGLE_CMD(reg); //creat read comd
    spi_xfer_done = false;

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi, spi_tx_buf, 2, spi_rx_buf, 2));

    while(spi_xfer_done == false){}

    return spi_rx_buf[1];
}



int main(void)
{

    int interRegValue;
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    spi_init();

    NRF_LOG_INFO("Spi application started");

    interRegValue = lsm2_read_reg(ADD_REG_WHO_AM_I);

    if(interRegValue == WHO_AM_I_DEFAULTvalue)
    {
        NRF_LOG_INFO("WHO AM I value is correct");
    }

    while (1)
    {
     
    }
}

So now, I dont understand how do we interface this
this is what I though initially

1. initialize, config, read the register

btw, any help from community shall help, Thanks

Parents
  • Hi,

    That is correct, the nRF52 series chips does not support 3-wire SPI.

    If I understand the documentation of your device correctly, you need to write the value "1" to register 0x62 before you can read the WHO_AM_I register using 4 wires. Have you written a "lsm2_write_reg" function?

    Best regards,
    Jørgen

  • Hi jorgen, thanks for inputs
    here is my write function

    #define SET_WRITE_SINGLE_CMD(x) (x & (~(0xC0))) //masking
    
    static void lsm2_write_reg(char reg, int data)
    {
        SPIWriteLength = 2;
        SPIReadLength = 0;
    
        spi_tx_buf[0] = SET_WRITE_SINGLE_CMD(reg);
        spi_tx_buf[1] = 0;
    
        spi_xfer_done = false;
    
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi, spi_tx_buf, SPIWriteLength, spi_rx_buf, SPIReadLength));
    
        while(!spi_xfer_done);
    }

    my main()

    #define TO_WRITE_THIS 0x62
    
    int main(void)
    {
    
        int interRegValue;
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        spi_init();
    
        //init_LIS();
    
        NRF_LOG_INFO("Spi application started");
    
        lsm2_write_reg(TO_WRITE_THIS , 1);
    
        interRegValue = lsm2_read_reg(ADD_REG_WHO_AM_I);
    
        if(interRegValue == WHO_AM_I_DEFAULTvalue)
        {
            NRF_LOG_INFO("WHO AM I value is correct");
        }
    
        while (1)
        {
         
        }
    }

    Im still unable to read the register

Reply
  • Hi jorgen, thanks for inputs
    here is my write function

    #define SET_WRITE_SINGLE_CMD(x) (x & (~(0xC0))) //masking
    
    static void lsm2_write_reg(char reg, int data)
    {
        SPIWriteLength = 2;
        SPIReadLength = 0;
    
        spi_tx_buf[0] = SET_WRITE_SINGLE_CMD(reg);
        spi_tx_buf[1] = 0;
    
        spi_xfer_done = false;
    
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi, spi_tx_buf, SPIWriteLength, spi_rx_buf, SPIReadLength));
    
        while(!spi_xfer_done);
    }

    my main()

    #define TO_WRITE_THIS 0x62
    
    int main(void)
    {
    
        int interRegValue;
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        spi_init();
    
        //init_LIS();
    
        NRF_LOG_INFO("Spi application started");
    
        lsm2_write_reg(TO_WRITE_THIS , 1);
    
        interRegValue = lsm2_read_reg(ADD_REG_WHO_AM_I);
    
        if(interRegValue == WHO_AM_I_DEFAULTvalue)
        {
            NRF_LOG_INFO("WHO AM I value is correct");
        }
    
        while (1)
        {
         
        }
    }

    Im still unable to read the register

Children
No Data
Related