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

ADXL345 SPI setting mismatch

Hello, I am using spi_master example to get a sensor output from ADXL345. Currently, it seems my code can read output data, but there is error showing for settings mismatch and I can't really find where it comes from. Current setting is Msb first, CPOL (1, activelow), CPHA (1, Trailing) and datasheet of ADXL345 also says it should be like that. I am attaching logic analyzer plot and my code. Please help me out!

image descriptionimage descriptionimage description

    #include "nrf_delay.h"
    #include "nrf_gpio.h"
    #include "common.h"
    #include "app_error.h"
    #include "app_util_platform.h"
    #include "spi_master.h"
    #include "example_config.h"

#define DELAY_MS    100     /**< Timer Delay in milli-seconds. */

#define SPI_MASTER_0_ENABLE 1

static uint8_t m_tx_data_spi[TX_RX_MSG_LENGTH]; /**< SPI master TX buffer. */
static uint8_t m_rx_data_spi[TX_RX_MSG_LENGTH]; /**< SPI master RX buffer. */

static volatile bool m_transfer_completed = true;

static uint8_t power[2] = {0x2D, 0x08};
static uint8_t mode[2]  = {0x31, 0x01};
static uint8_t rate[2] = {0x2C, 0x0F};
static uint8_t reg_x0 = {0x80 | 0x40 | 0x32};
static uint8_t reg_x1 = {0x80 | 0x33};
static uint8_t reg_y0 = {0x80 | 0x34};
static uint8_t reg_y1 = {0x80 | 0x35};
static uint8_t reg_z0 = {0x80 | 0x36};


static uint32_t err_code;

/**@brief Function for error handling, which is called when an error has occurred. 
 *
 * @param[in] error_code  Error code supplied to the handler.
 * @param[in] line_num    Line number where the handler is called.
 * @param[in] p_file_name Pointer to the file name. 
 */
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
{
    for (;;)
    {
        //No implementation needed.
    }
}

/**@brief Handler for SPI0 master events.
 *
 * @param[in] spi_master_evt    SPI master event.
 */
void spi_master_0_event_handler(spi_master_evt_t spi_master_evt)
{
    bool result = false;
    switch (spi_master_evt.evt_type)
    {
        case SPI_MASTER_EVT_TRANSFER_COMPLETED:

            //Close SPI master.
            spi_master_close(SPI_MASTER_0);
        
            m_transfer_completed = true;
            break;
        
        default:
            //No implementation needed.
            break;
    }
}

/**@brief Function for initializing a SPI master driver.
 *
 * @param[in] spi_master_instance       An instance of SPI master module.
 * @param[in] spi_master_event_handler  An event handler for SPI master events.
 * @param[in] lsb                       Bits order LSB if true, MSB if false.
 */
static void spi_master_init(spi_master_hw_instance_t spi_master_instance, 
                            spi_master_event_handler_t spi_master_event_handler,
                            const bool lsb)
{
    uint32_t err_code = NRF_SUCCESS;

    //Configure SPI master.
    spi_master_config_t spi_config = SPI_MASTER_INIT_DEFAULT;
    
            spi_config.SPI_Pin_SCK = SPIM0_SCK_PIN;
            spi_config.SPI_Pin_MISO = SPIM0_MISO_PIN;
            spi_config.SPI_Pin_MOSI = SPIM0_MOSI_PIN;
            spi_config.SPI_Pin_SS = SPIM0_SS_PIN;

    spi_config.SPI_CONFIG_ORDER = (lsb ? SPI_CONFIG_ORDER_LsbFirst : SPI_CONFIG_ORDER_MsbFirst);
    
    err_code = spi_master_open(spi_master_instance, &spi_config);
    APP_ERROR_CHECK(err_code);
    
    //Register event handler for SPI master.
    spi_master_evt_handler_reg(spi_master_instance, spi_master_event_handler);
}


/** @brief Function for main application entry.
 */
int main(void)
{
  
		
			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
      spi_master_send_recv(SPI_MASTER_0, power, 2, m_rx_data_spi, 2); 
    	spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
	    spi_master_send_recv(SPI_MASTER_0, mode, 2, m_rx_data_spi, 2); 
    	spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
	    spi_master_send_recv(SPI_MASTER_0, rate, 2, m_rx_data_spi, 2); 				
	
    for (;;)
    {
        if (m_transfer_completed)
        {
            m_transfer_completed = false;

		
			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
      spi_master_send_recv(SPI_MASTER_0, power, 2, m_rx_data_spi, 2); 
    	spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
	    spi_master_send_recv(SPI_MASTER_0, rate, 2, m_rx_data_spi, 2); 				
	    spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);				
	    spi_master_send_recv(SPI_MASTER_0, mode, 2, m_rx_data_spi, 2); 
			spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
      spi_master_send_recv(SPI_MASTER_0, &reg_x0, 1, m_rx_data_spi, 7);   
      nrf_delay_ms(10);				
	
        }
    }

}
  • Hey I messed with the ADXL345 a little bit and started a library. All I got to was reading the deviceID (register 0x00) and verifying that what I was reading was correct. Here is the library I put together based off the SDK example in the most recent nRF52 SDK. It might help you. Very simple and based off what Nordic provides in their most recent SDK example - just stripped down to the basics.

    github.com/.../warthog_library github.com/.../warthog_spi.c

    note: I used easydma.

    and in main.c, something like:

    #include "warthog_spi.h"

    uint8_t tx_data_spi[TX_RX_MSG_LENGTH];

    uint8_t rx_data_spi[TX_RX_MSG_LENGTH];

    int main() {

    const nrf_drv_spi_t spi_master_0 = NRF_DRV_SPI_INSTANCE(0);

    spi_master_init(&spi_master_0);

    tx_data_spi[0] = (0UL);

    spi_send_recv(&spi_master_0, tx_data_spi, rx_data_spi, TX_RX_MSG_LENGTH);

    for (;;) }

    note that easydma means that the data read in spi will be stored in a buffer in RAM directly, without CPU intervention.

Related