Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Unable to interface nrf51822 with LIS3DH (accelerometer) using SPI being nrf as master

Hi, 

I tried interfacing LIS3Dh using SPI, I used the SPI example to start with, when I didn't get the desired result, I look numerous question on the forum and tried to modify the code but it does not seem to be working.

I am simply trying to read WHO_AM_I register/or any other register, I am getting FF always, 

the sensor is embedded on PCB with following configurations: 

Configurations:

LIS3DH nrf 51822 pin  sdk_config.h 
SCK 9 SPI_SCK_PIN 9
SDI 10 SPI_MOSI_PIN 10
CS 12 SPI_SS_PIN 12
SDO 7 SPI_MISO_PIN 11

Below code is trying to read who_am_i ( 0x0F) 

#define SPI_INSTANCE  0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */

#define TEST_STRING "Nordic"
static uint8_t       m_tx_buf[]={0x0F};           /**< TX buffer. */
static uint8_t       m_rx_buf[]={0x00, 0x00,0x00, 0x00,0x00};    /**< RX buffer. */
//static const uint8_t m_length = sizeof(m_rx_buf);        /**< Transfer length. */

/**
 * @brief SPI user event handler.
 * @param event
 */
void spi_event_handler(nrf_drv_spi_evt_t const * p_event)
{
    spi_xfer_done = true;
    SEGGER_RTT_printf(0,"Transfer completed.\r\n");
    if (1 != 0)
    {
        SEGGER_RTT_printf(0," Received: \r\n");
        NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
        SEGGER_RTT_printf(0, "value: %u \r\n", *m_rx_buf);
        bsp_board_led_invert(BSP_BOARD_LED_1);
    }
}

int main(void)
{
    bsp_board_leds_init();

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    SEGGER_RTT_printf(0,"SPI example\r\n");

   nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
	spi_config.ss_pin   = SPI_SS_PIN;
	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_DRV_SPI_FREQ_8M;
	spi_config.mode= NRF_DRV_SPI_MODE_2;
        
	APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler));
        
       
        uint8_t sizerx = 2;
        spi_xfer_done = false;
        
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 1, m_rx_buf, sizerx));
        while (!spi_xfer_done){
	  __WFE();
        }

        if(sizerx!=0)
        {
            SEGGER_RTT_printf(0,"Received[0]: %x %x %x %x %x \n\r",m_rx_buf[0],m_rx_buf[1],m_rx_buf[2],m_rx_buf[3],m_rx_buf[4]);
        }else{
            SEGGER_RTT_printf(0,"no value return from \r\n");
        }
      
      SEGGER_RTT_printf(0,"miso-> %u \r\n", nrf_gpio_pin_out_read(11));
      SEGGER_RTT_printf(0,"mosi-> %u \r\n", nrf_gpio_pin_out_read(10));
      SEGGER_RTT_printf(0,"ss-> %u \r\n", nrf_gpio_pin_out_read(12));
                     
}

log output ( in every case I am getting FF value in rx_buff ) 

SDK Used: 12.2

using JLink to transfer the via SWO

I have tried with different modes and frequencies also but no luck. 

Please help.

Parents
  • The LIS3DH clocks data in on the rising clock edge; hence last 'scope screenshot shows a transmitted command value of 0x87 not 0x8F. The traces would be easier to read if they were vertically separated slightly .. while still overlapping. Perhaps post the function you are using to generate this trace, in case we see something there ..

  • It is weird, but I used the example from the sdk 14.2. I just modified the buffer to the register I wanted.

    #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 "nrf_gpio.h"
    
    #define SPI_INSTANCE  0 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
    
    //sck//scl 03
    //miso//sdo 28
    //mosi//sda 4
    //ss/cs 29 
    
    //#define TEST_STRING "Nordic"
    static uint8_t       m_tx_buf[] = {0x87,0x00};           /**< TX buffer. */
    static uint8_t       m_rx_buf[] = {0x00,0x00};    /**< RX buffer. */
    static const uint8_t m_length = sizeof(m_tx_buf);        /**< Transfer length. */
    
    /**
     * @brief SPI user event handler.
     * @param event
     */
    void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                           void *                    p_context)
    {
        spi_xfer_done = true;
        NRF_LOG_INFO("Transfer completed.");
        if (m_rx_buf[0] != 0)
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
        }
    }
    
    int main(void)
      {
        bsp_board_leds_init();
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        
        NRF_LOG_INFO("SPI example.");
    
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin    = SPI_SS_PIN;
        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;
        spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
        spi_config.mode      = NRF_DRV_SPI_MODE_3;           
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
        while (1)
        {
            // Reset rx buffer and transfer done flag
            memset(m_rx_buf, 0, m_length);
            spi_xfer_done = false;
    
            bsp_board_led_invert(BSP_BOARD_LED_0);
            
            APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
    
            while (!spi_xfer_done)
            {
                __WFE();
            }
    
            NRF_LOG_FLUSH();
    
            bsp_board_led_invert(BSP_BOARD_LED_0);
            nrf_delay_ms(1000);
        }
    }

Reply
  • It is weird, but I used the example from the sdk 14.2. I just modified the buffer to the register I wanted.

    #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 "nrf_gpio.h"
    
    #define SPI_INSTANCE  0 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
    
    //sck//scl 03
    //miso//sdo 28
    //mosi//sda 4
    //ss/cs 29 
    
    //#define TEST_STRING "Nordic"
    static uint8_t       m_tx_buf[] = {0x87,0x00};           /**< TX buffer. */
    static uint8_t       m_rx_buf[] = {0x00,0x00};    /**< RX buffer. */
    static const uint8_t m_length = sizeof(m_tx_buf);        /**< Transfer length. */
    
    /**
     * @brief SPI user event handler.
     * @param event
     */
    void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                           void *                    p_context)
    {
        spi_xfer_done = true;
        NRF_LOG_INFO("Transfer completed.");
        if (m_rx_buf[0] != 0)
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
        }
    }
    
    int main(void)
      {
        bsp_board_leds_init();
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        
        NRF_LOG_INFO("SPI example.");
    
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin    = SPI_SS_PIN;
        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;
        spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
        spi_config.mode      = NRF_DRV_SPI_MODE_3;           
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
        while (1)
        {
            // Reset rx buffer and transfer done flag
            memset(m_rx_buf, 0, m_length);
            spi_xfer_done = false;
    
            bsp_board_led_invert(BSP_BOARD_LED_0);
            
            APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
    
            while (!spi_xfer_done)
            {
                __WFE();
            }
    
            NRF_LOG_FLUSH();
    
            bsp_board_led_invert(BSP_BOARD_LED_0);
            nrf_delay_ms(1000);
        }
    }

Children
Related