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 Reply Children
  • 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);
        }
    }

  • Isn't that the answer? The 'scope shows you are sensing 0x87 which agrees with the code above; Whoami requires 0x8F ..

  • Yep, you got it right. I was mistakenly sending, for the scopeshots, 0x87 instead of 0x8F (I even tried to delete the comment, but I couldn't)

    Now I got it working but had to reduce the speed (as you pointed above) and to modify the loop back example to check for the second byte in the answer.

    Really had to use the scope for this (8MHz was inserting harmonics in my clock signal and the reverse analysis from an old code got me to try the mode 3, the one that worked).

    TL;DR I used mode 0 and 3 to make it work

    Here I share my happiness with you, thansk so much 

    MOSI

    MISO

  • I faced the same problem.
    there is a difference, only 0x00 is entered in MISO.
    Have you solved this problem?

Related