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

How to use lis2dh12 with latest SDK 15.3 (SPI)

Hi I would like to use sdk15.3 with the \nRF5_SDK_15.3.0_59ac345\components\drivers_ext\lis2dh12 but I need to have it with SPI. Is this possible?

  • Yes of course, but you'll have to port from TWI to SPI yourself. 

  • Take one of the 15.3.0 SPI examples and use the code I show here for initialisation, which works with the LIS2DH12. Since you already have i2c functional, that should get you most of the way there. SPI is much cleaner to use than i2c.

    // Description
    // ===========
    // The LIS2DH12 is an ultra-low-power highperformance three-axis linear accelerometer
    // belonging to the femto family with digital I2C/SPI serial interface standard output.
    // The LIS2DH12 has user-selectable full scales of +-2g/4g/8g/16g and is capable of measuring
    // accelerations with output data rates from 1 Hz to 5.3 kHz.
    // The self-test capability allows the user to check the functionality of the sensor in the final
    // application.
    // The device may be configured to generate interrupt signals by detecting two independent
    // inertial wake-up/free-fall events as well as by the position of the device itself.
    //
    // SPI Interface
    // =============
    // bit 0: RW bit. When 0, the data DI(7:0) is written into the device. When 1, the data DO(7:0)
    //                from the device is read. In the latter case, the chip will drive SDO at the start of bit 8.
    // bit 1: MS bit. When 0, the address will remain unchanged in multiple read/write commands.
    //                When 1, the address is auto incremented in multiple read/write commands.
    // bit 2-7:  address AD(5:0). This is the address field of the indexed register.
    // bit 8-15: data DI(7:0) (write mode). This is the data that is written into the device (MSb first).
    // bit 8-15: data DO(7:0) (read mode). This is the data that is read from the device (MSb first).
    //                In multiple read/write commands further blocks of 8 clock periods will be added. When the
    //                MS bit is 0, the address used to read/write data remains the same for every block. When
    //                the MS bit is 1, the address used to read/write data is increased at every block.
    
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        ret_code_t err_code;
    
        spi_config.ss_pin    = LIS2DH12_CS_PIN;
        spi_config.miso_pin  = LIS2DH12_MISO_PIN;
        spi_config.mosi_pin  = LIS2DH12_MOSI_PIN;
        spi_config.sck_pin   = LIS2DH12_SCK_PIN;
        spi_config.frequency = NRF_DRV_SPI_FREQ_8M;  // LIS2DH12 works up to 10MHz on SPI
        spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
        spi_config.mode      = NRF_DRV_SPI_MODE_0;
        APP_ERROR_CHECK(nrf_drv_spi_init(&mLis2dh12SpiInstance, &spi_config, Lis2dh12_spi_event_handler, NULL));

    The event handler should be kept ultra-simple:

    // Interrupt-driven events related to ADC sampling
    static volatile bool mLisPacketTransferComplete = false;
    
    /**
     * @brief SPI event handler indicating SPI transfer has completed
     * @param event
     */
    static void lis2dh12_spi_event_handler(nrf_drv_spi_evt_t const * p_event, void *p_context)
    {
        mLisPacketTransferComplete = true;
    }

    Choose an SPI not used elsewhere:

    #define SPI_INSTANCE  2   // SPI instance index
    static const nrf_drv_spi_t mLisSpiInstance = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);

    Transmit and wait for a result (simplistic example):

     // Send a command
     APP_ERROR_CHECK(nrf_drv_spi_transfer(&mLisSpiInstance, tx_buf, length, rx_buf, length));
     // Check for successful transfer
     while (!mLisPacketTransferComplete) ;
     // Completed ok

    If you have issues with nrfx instead of nrf, this might be helpful

    #if defined(NRFX_SPI2_ENABLED)
    #warning NRFX_SPI2_ENABLED
    #endif
    #if defined(NRFX_SPIM2_ENABLED)
    #warning NRFX_SPIM2_ENABLED
    #endif
    #if defined(NRF_SPI2_ENABLED)
    #warning NRF_SPI2_ENABLED
    #endif
    #if defined(NRF_SPIM2_ENABLED)
    #warning NRF_SPIM2_ENABLED
    #endif

    Good luck, it works well. If you are going off-board via leads longer than an inch/25mm or so then boost the drive level on CLK.

  • Hi hmolesworth,

    Can you please show a clearer example that I can use for this application? I am not sure which example I can apply so that this is working fine.

    Thanks and have a nice day!

  • I have tried with ble_app_uart but the lis2dh12 doesn't works fine, btw I didnt get the twi working for lis2dh12 as I only have the nordic with lis2dh12 with SPI instead of i2C.

    thanks!

  • Use the sdk/examples/peripheral/SPIM example.

Related