This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

regarding the SPI code for sending hex arrays

I am trying to make the LSM9DS1 connected with the nrf52840, 

1. Now I am trying to send the hex array to the lsm9ds1, seems always failed. 

any suggestion how to make the hex array send to the LSM9DS1 sensor and how to make the receiving hex array correctly received?

Here is my code attached.

#include "lsm9ds1_reg.h"
#include "nrf_drv_spi.h"


#include "nrf_drv_spi.h"
#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "sdk_config.h"

/**
  * @defgroup    LSM9DS1
  * @brief       This file provides a set of functions needed to drive the
  *              lsm9ds1 enhanced inertial module.
  * @{
  *
  */

/**
  * @defgroup    LSM9DS1_Interfaces_Functions
  * @brief       This section provide a set of functions used to read and
  *              write a generic register of the device.
  *              MANDATORY: return 0 -> no Error.
  * @{
  *
  */



#define SPI_INSTANCE  0 
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); 
static volatile bool spi_xfer_done;  
#define TEST_STRING "Nordic"
static uint8_t       m_tx_buf[] = TEST_STRING;           
static uint8_t       m_rx_buf[sizeof(TEST_STRING) + 1];   
static const uint8_t m_length = sizeof(m_tx_buf);        //m_length = 0;//
 

void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *                    p_context)
{
    spi_xfer_done = true;
    /*
	printf("Transfer completed.");
	printf(" Received:");
    printf("frx_buff=%x,len is %d",m_rx_buf, strlen((const char *)m_rx_buf));
		*/
		
		
    if (m_rx_buf[0] != 0)
    {
        printf(" Received:");
		//printf("mrx_buff=%s,len is %d",m_rx_buf, strlen((const char *)m_rx_buf));
        printf("frx_buff=%x,len is %d",m_rx_buf, strlen((const char *)m_rx_buf));
    }
}
/*
*/
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
void lsm9ds1_SPI_init()
{
    
    spi_config.ss_pin   = NRF_DRV_SPI_PIN_NOT_USED;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin  = SPI_SCK_PIN;
    spi_config.frequency    = NRF_SPI_FREQ_125K;//NRF_DRV_SPI_FREQ_4M;
    spi_config.mode         = NRF_DRV_SPI_MODE_0;
    spi_config.bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL));
	nrf_gpio_pin_set(IMU_CS_M_PIN); 
    nrf_gpio_pin_set(IMU_CS_AG_PIN);
	nrf_delay_ms(2);
	
}

void lsm9ds1_SPI_self_test_init()
{
    spi_config.ss_pin   = NRF_DRV_SPI_PIN_NOT_USED;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin  = SPI_SCK_PIN;
    spi_config.frequency    = NRF_SPI_FREQ_125K;//NRF_DRV_SPI_FREQ_4M;
    spi_config.mode         = NRF_DRV_SPI_MODE_0;
    spi_config.bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
	//APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL));
    nrf_gpio_pin_set(IMU_CS_M_PIN); 
    nrf_gpio_pin_set(IMU_CS_AG_PIN);
	nrf_delay_ms(2);
}

//niklas
void lsm9ds1_SPI_self_test()
{
   //self test, production need to be removed
   //nrf_gpio_pin_set(IMU_CS_M_PIN); 
   nrf_gpio_pin_clear(IMU_CS_AG_PIN);
   /*
   printf("m_tx_buf is %s, %s\n",m_tx_buf[0],m_tx_buf[1]);
   printf("m_tx_buf is %s, %s\n",&m_tx_buf[0],&m_tx_buf[1]);
   uint8_t f_tx_buf[]="SK";
   printf("f_tx_buf is %s, %s\n",f_tx_buf[0],f_tx_buf[1]);
   printf("f_tx_buf is %s, %s\n",&f_tx_buf[0],&f_tx_buf[1]);
   */
   uint8_t f_rx_buf[5];
   uint8_t len;
   //m_tx_buf[0]="P";//(LSM9DS1_WHO_AM_I | 0x80);
   //APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, f_tx_buf,2, m_rx_buf, m_length));
   //reference https://devzone.nordicsemi.com/f/nordic-q-a/21828/how-to-send-1-byte-via-spi-from-master-to-slave
   uint8_t tx[3] = {0x11, 0x20 , 0x00};
   printf("f_tx_buf is %x,  %x,%x\n",tx[0],tx[1],tx[2]);
   //uint8_t f_tx_buf[]=tx[];
   //APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, 0x11, 1, NULL, 1));
   //APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, 0x20 | 0x00, 1, NULL, 1));
   //APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, 0x00, 1, m_rx_buf, m_length));
   APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, tx, 3, m_rx_buf, m_length));
   //APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf,sizeof(m_tx_buf), m_rx_buf, m_length));
   //printf("srx_buff=%x,len is %d",f_rx_buf, len);
   //nrf_gpio_pin_set(IMU_CS_M_PIN); 
   nrf_gpio_pin_set(IMU_CS_AG_PIN);
   //APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL));
		
}

static int32_t platform_write_imu(void *handle, uint8_t reg,
                                  uint8_t *bufp,
                                  uint16_t len);
static int32_t platform_read_imu(void *handle, uint8_t reg,
                                 uint8_t *bufp,
                                 uint16_t len);
static int32_t platform_write_mag(void *handle, uint8_t reg,
                                  uint8_t *bufp,
                                  uint16_t len);
static int32_t platform_read_mag(void *handle, uint8_t reg,
                                 uint8_t *bufp,
                                 uint16_t len);
static void tx_com( uint8_t *tx_buffer, uint16_t len );
static void platform_delay(uint32_t ms);
static void platform_init(void);

/*

typedef struct {
  void   *hbus;
  uint8_t cs_pin;
} sensbus_t;
static sensbus_t imu_bus = {&spi,
                            4
                           };
static sensbus_t mag_bus = {&spi,
                            27
                           };
*/

void lis9ds1_self_test(void)
{
  //stmdev_ctx_t dev_ctx_imu;
  //stmdev_ctx_t dev_ctx_mag;
  uint8_t tx_buffer[1000];
  //axis3bit16_t data_raw;
  lsm9ds1_status_t reg;
  lsm9ds1_id_t whoamI;
  /*
  float val_st_off[3];
  float val_st_on[3];
  float test_val[3];
  uint8_t st_result;
  uint8_t rst;
  uint8_t i;
  uint8_t j;
  */
  /* Initialize inertial sensors (IMU) driver interface */
  //dev_ctx_imu.lsm9ds1_write_reg_private = platform_write_imu;
  //dev_ctx_imu.lsm9ds1_read_reg_private = platform_read_imu;
  //dev_ctx_imu.handle = (void *)&imu_bus;
  /* Initialize magnetic sensors driver interface */
  //dev_ctx_mag.write_reg = platform_write_mag;
  //dev_ctx_mag.read_reg = platform_read_mag;
  //dev_ctx_mag.handle = (void *)&mag_bus;
  /* Init test platform */
  //platform_init();
  /* Wait sensor boot time */
  //platform_delay(BOOT_TIME);
  /* Check device ID */
  lsm9ds1_dev_id_get(&whoamI);
  printf("imu I am is %X\n",whoamI.imu );
  printf("mag I am is %X\n",whoamI.mag );

  if (whoamI.imu != LSM9DS1_IMU_ID || whoamI.mag != LSM9DS1_MAG_ID) {
    while (1) {
      /* manage here device not found */
    }

  }
}
		
//_niklas
//int32_t lsm9ds1_read_reg_private(uint8_t typess, uint8_t reg, uint8_t *data, uint16_t len)
int32_t lsm9ds1_read_reg(uint8_t typess, uint8_t reg, uint8_t *data, uint16_t len)
{
   if(typess==2){nrf_gpio_pin_clear(IMU_CS_M_PIN); }
   if(typess==1){nrf_gpio_pin_clear(IMU_CS_AG_PIN); }
   uint8_t temp_tx_buf[10];
   memset(temp_tx_buf,0x00,sizeof(temp_tx_buf));
   temp_tx_buf[0]=(reg | 0x80);
   for (uint8_t i = 0; i < len; i++) {
      temp_tx_buf[i+1] = 0x00;
    }
   
   int32_t ret;
   ret=nrf_drv_spi_transfer(&spi, temp_tx_buf, len+1, data, len);
   APP_ERROR_CHECK(ret);
   if(typess==2){nrf_gpio_pin_set(IMU_CS_M_PIN); }
   if(typess==1){nrf_gpio_pin_set(IMU_CS_AG_PIN); }
   return  ret;

}
//niklas
//int32_t lsm9ds1_write_reg_private(uint8_t typess, uint8_t reg, uint8_t *data, uint16_t len)
int32_t lsm9ds1_write_reg(uint8_t typess, uint8_t reg, uint8_t *data, uint16_t len)
{
   if(typess==2){nrf_gpio_pin_clear(IMU_CS_M_PIN); }
   if(typess==1){nrf_gpio_pin_clear(IMU_CS_AG_PIN);}
   uint8_t temp_tx_buf[10];
   memset(temp_tx_buf,0x00,sizeof(temp_tx_buf));
   temp_tx_buf[0]=(reg & 0x7F);
   for (uint8_t i = 0; i < len; i++) {
      temp_tx_buf[i+1] = 0x00;
    }
   
   int32_t ret;
   ret=nrf_drv_spi_transfer(&spi, temp_tx_buf, len+1, data, len);
   APP_ERROR_CHECK(ret);
   if(typess==2){nrf_gpio_pin_set(IMU_CS_M_PIN); }
   if(typess==1){nrf_gpio_pin_set(IMU_CS_AG_PIN); }
   return  ret;
}

2. also I made some self testing by connect the MISO to the MOSI for the hex array sending with the function lsm9ds1_SPI_self_test_init() and lsm9ds1_SPI_self_test() in the code above, but not receiving the same data I send out, any issues and suggestions?

Thank you in advance

BR,

Niklas

Parents
  • Hi,

    I do not have that SPI slave with me. It is difficult to answer why a specific slave does not respond well to the SPI peripheral in the nRF5X. In general the SPI peripheral is very mature and know to work, the issue here could be a misinterpretation of the pin driving strength on either side.

    I have seen that the LSM9DS1 works well with TWI and tested here, but i have never used or tested this with SPI.

    I can do a loop test like you did by connecting the MISO and MOSI. Can you please give your main.c file and tell me which version of SDK you are using, so that i can see if there is any misconfiguration that i missed to see in your code snippet.

  • Thank you. I did the loop testing this morning. Now I find the issue was the cs pins for M and A/G I forget to do the output before the write, now should be fine. 

Reply Children
Related