SPI connection to ADXL345 with Nrf52840

Hi,

I'm trying to test a simple SPI communication between nrf52840 dev board and adxl345. I'm following this guy's youtube tutorial on segger embedded studio. Here's the code to read the device ID and also the hardware setup. I'm getting 242 instead of correct value of 0xe5 or 229. I'm not sure where it's wrong. I tested on an arduino uno and it works. Please help.

Thanks

#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"

#define ADD_REG_WHO_AM_I 0x00
#define UC_WHO_AM_I_DEFAULT_VALUE 0xE5


#define SPI_BUFSIZE 8     // SPI communication buffer size
#define SPI_INSTANCE 0    // SPI instance to be used
#define SET_READ_SINGLE_CMD(x) (x | 0x80)   // local macro - set read single command (DEPENDS ON SENSOR)

uint8_t spi_tx_buf[SPI_BUFSIZE];    // spi tx buffer
uint8_t spi_rx_buf[SPI_BUFSIZE];    // spi rx buffer

static volatile bool spi_xfer_done; // flag to signal that the SPI instance has completed the transfer

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

/* SPI Event handler function, on every tranfer this callback function is triggered */
void spi_event_handler(nrf_drv_spi_evt_t const *p_event, void *p_context){
  spi_xfer_done = true;
}

/* Initialize the spi instance */
void spi_init(void){
  // Create a sturct to hold the configurations and set these values to default */
  nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
  
  // Assign pins to SPI instance 
  spi_config.ss_pin = 47;
  spi_config.miso_pin = 46;
  spi_config.mosi_pin = 45;
  spi_config.sck_pin = 44;
  // Configure the transfer speed by setting the clock for data transmission
  spi_config.frequency = NRF_DRV_SPI_FREQ_4M;

  /* Call the SPI initialization function within APP_ERROR_CHECK function so that if any error
   occurs during initialization then we can get the response on debug window */
  APP_ERROR_CHECK(nrf_drv_spi_init(&m_spi, &spi_config, spi_event_handler, NULL));

}

int read_reg(int reg){
  spi_tx_buf[0] = SET_READ_SINGLE_CMD(reg); // set the read command for reading a single byte 
  
  spi_xfer_done = false;                    // reset the flag

  APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi, spi_tx_buf, 2, spi_rx_buf, 2));    // call the spi transfer function

  while(spi_xfer_done == false){};  // wait till the transfer is done

  return spi_rx_buf[1];                // return the data
  
}

int main(void)
{
    int intRegValue;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); // initialize the logger module and check if any error occurred during initialization
    NRF_LOG_DEFAULT_BACKENDS_INIT();      // initialize the default backends for nrf logger

    spi_init();                           // call the SPI initialization function
    NRF_LOG_INFO("APP STARTED");    

    intRegValue = read_reg(ADD_REG_WHO_AM_I);   // get the returned value
    NRF_LOG_INFO("this came up = %d", intRegValue);
    if(intRegValue == UC_WHO_AM_I_DEFAULT_VALUE){
      NRF_LOG_INFO("Correct data!");
    }else{
      NRF_LOG_INFO("INCORRECT");
    }


    while (1)
    {
        
    }
}

  • Hi,

    Can you try to increase the GPIO drive strength of the SPI pins by calling nrf_gpio_cfg() with drive parameter set to (NRF_GPIO_PIN_H0H1) after spi_init()? I have seen this solve similar issues in the past.

    Best regards,
    Jørgen

  • I added the following after spi_init() after reading some other posts in the forum but i'm still getting "242". On the side, I tried to read deviceID on an arduino UNO, i got "229" correctly. So, I'm assuming it's firmware or the board?

    nrf_gpio_cfg(SPI_SS,       NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
      nrf_gpio_cfg(SPI_MOSI_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
      nrf_gpio_cfg(SPI_SCK_PIN,  NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);

  • Please try configuring the MISO pin as high drive as well. If that does not work, please check if lowering the SPI frequency will affect the results.

    Can you provide a logic trace/scope image of the communication on the SPI bus? Do the output and input look as expected?

  • Same result with MISO pin as high drive. I'm assuming we have to set it as INPUT? I don't have a logic trace/scope with me, It'll take me a while to get it sorted out. In the meantime, what are your thoughts on the problem?

     nrf_gpio_cfg(SPI_MISO_PIN,  NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);

  • I just tried out with SPI_MODE_3 and it seems be working. I don't know why it wouldn't work with SPI_MODE_0. Any thoughts?

      

    #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"
    
    #define ADD_REG_WHO_AM_I 0x00
    #define UC_WHO_AM_I_DEFAULT_VALUE 0xE5
    
    
    #define SPI_BUFSIZE 8     // SPI communication buffer size
    #define SPI_INSTANCE 0    // SPI instance to be used
    #define SET_READ_SINGLE_CMD(x) (x | 0x80)   // local macro - set read single command (DEPENDS ON SENSOR)
    
    uint8_t spi_tx_buf[SPI_BUFSIZE];    // spi tx buffer
    uint8_t spi_rx_buf[SPI_BUFSIZE];    // spi rx buffer
    
    static volatile bool spi_xfer_done; // flag to signal that the SPI instance has completed the transfer
    
    static const nrf_drv_spi_t m_spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);      // create SPI instance
    
    /* SPI Event handler function, on every tranfer this callback function is triggered */
    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 (spi_rx_buf[0] != 0)
      {
          NRF_LOG_INFO(" Received:");
          NRF_LOG_HEXDUMP_INFO(spi_rx_buf, strlen((const char *)spi_rx_buf));
      }
    }
    
    /* Initialize the spi instance */
    void spi_init(void){
      // Create a sturct to hold the configurations and set these values to default */
      nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
      
      // Assign pins to SPI instance 
      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.mode     = NRF_DRV_SPI_MODE_3;
      // Configure the transfer speed by setting the clock for data transmission
      spi_config.frequency =  NRF_DRV_SPI_FREQ_4M;
    
      /* Call the SPI initialization function within APP_ERROR_CHECK function so that if any error
       occurs during initialization then we can get the response on debug window */
      APP_ERROR_CHECK(nrf_drv_spi_init(&m_spi, &spi_config, spi_event_handler, NULL));
    
    }
    
    int read_reg(int reg){
      spi_tx_buf[0] = SET_READ_SINGLE_CMD(reg); // set the read command for reading a single byte 
      
      spi_xfer_done = false;                    // reset the flag
    
      APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi, spi_tx_buf, 2, spi_rx_buf, 2));    // call the spi transfer function
    
      while(spi_xfer_done == false){};  // wait till the transfer is done
    
      return spi_rx_buf[1];                // return the data
      
    }
    
    int main(void)
    {
        int intRegValue;
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); // initialize the logger module and check if any error occurred during initialization
        NRF_LOG_DEFAULT_BACKENDS_INIT();      // initialize the default backends for nrf logger
    
        spi_init();                           // call the SPI initialization function
    
        NRF_LOG_INFO("APP STARTED");    
        nrf_gpio_cfg(SPI_SS_PIN,  NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
        nrf_gpio_cfg(SPI_MISO_PIN,  NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
        nrf_gpio_cfg(SPI_MOSI_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
        nrf_gpio_cfg(SPI_SCK_PIN,  NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
    
        intRegValue = read_reg(ADD_REG_WHO_AM_I);   // get the returned value
        NRF_LOG_INFO("this came up = %d", intRegValue);
        if(intRegValue == UC_WHO_AM_I_DEFAULT_VALUE){
          NRF_LOG_INFO("Correct data!");
        }else{
          NRF_LOG_INFO("INCORRECT");
        }
    
    
        while (1)
        {
            
        }
    }

Related