I want to acquire data from the murata MBN52832 (WSM-BL241-ADA-008DK) module and acceleration sensor (IIM-42652) via SPI communication, but the MISO pin does not respond.

I am trying to read acceleration values ​​from an acceleration sensor (IIM-42652) via SPI with nrf52832 as the SPI master. I created it based on the spi_pca10040 example, but the reading displayed in the terminal remains 0. 

The development environment is SEGGER Embedded Studio for ARM V5.70a.
https://product.tdk.com/system/files/dam/doc/product/sensor/mortion-inertial/imu/data_sheet/ds-000440-iim-42652-typ-v1.1.pdf
https://www.murata.com/products/productdata/8813650903070/mbn52832.pdf?1659967311000

#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 SPI_SCK_PIN 3  //SCK
#define SPI_MISO_PIN 4  //SDO
#define SPI_MOSI_PIN 29  //SDI
#define SPI_SS_PIN 2  //SS

#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[] = TEST_STRING;           /**< TX buffer. */
static uint8_t       m_rx_buf[sizeof(TEST_STRING) + 1];    /**< 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;
    printf("Transfer completed.\n");
    if (m_rx_buf[0] != 0)
    {
        printf(" Received:\n");
        NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
    }
}

void imu_setup_IIM42652(){

        memset(m_rx_buf, 0, m_length);
        memset(m_tx_buf, 0, m_length);
        spi_xfer_done = false;

        /* WHO_AM_I = 0x6F */
        m_tx_buf[0]=0x80|0x75;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
        whoami  = m_rx_buf[0];
        printf(" whoami:%02X\n", whoami);

        /* DEVICE_CONFIG
         * SOFT_RESET_CONFIG[0] = 1(Enable Reset. wait 1ms)
         */
        m_tx_buf[0] = 0x11;
        m_tx_buf[1] = 0x01;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        nrf_delay_ms(10);

        /* ACCEL_CONFIG0
         * ACCEL_FS_SEL[7:5] = 2(±4g)
         * ACCEL_ODR[3:0]    = 9(50Hz:LN mode (default))
         */
        m_tx_buf[0] = 0x50;
        m_tx_buf[1] = 0x49;// 010(2) 0 1001(9) = 73(0x49)
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        /* PWR_MGMT0
         * ACCEL_MODE[1:0] = 2(Low Power Mode)
         */
        m_tx_buf[0] = 0x4E;
        m_tx_buf[1] = 0x02;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        /* APEX_CONFIG0
         * DMP_ODR[1:0] = 2(50Hz)
         */
        m_tx_buf[0] = 0x56;
        m_tx_buf[1] = 0x02;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        /* SIGNAL_PATH_RESET
         * DMP_INIT_EN[6] = 0
         * DMP_MEM_RESET_EN[5] = 1
         */
        m_tx_buf[0] = 0x4B;
        m_tx_buf[1] = 0x20;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        nrf_delay_ms(50); // 1msでよいはずだか、安定して動かすために50msとする。

        /* SIGNAL_PATH_RESET
         * DMP_INIT_EN[6] = 1
         * DMP_MEM_RESET_EN[5] = 0
         */
        m_tx_buf[0] = 0x4B;
        m_tx_buf[1] = 0x40;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        /* REG_BANK_SEL
         * BANK_SEL[2:0] = 4(BANK4)
         */
        m_tx_buf[0] = 0x76;
        m_tx_buf[1] = 0x04;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        /* INT_SOURCE6
         * STEP_DET_INT1_EN[5] = 1
         */
        m_tx_buf[0] = 0x4D;
        m_tx_buf[1] = 0x20;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        /* REG_BANK_SEL
         * BANK_SEL[2:0] = 0(BANK0)
         */
        m_tx_buf[0] = 0x76;
        m_tx_buf[1] = 0x00;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        /* APEX_CONFIG0
         * PED_ENABLE[5] = 1
         * DMP_ODR[1:0] = 2(50Hz)
         */
        m_tx_buf[0] = 0x56;
        m_tx_buf[1] = 0x22;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

        /* TMST_CONFIG0
         * TMST_TO_REGS_EN[4] = 1
         */
        m_tx_buf[0] = 0x54;
        m_tx_buf[1] = 0x33;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

}

int main(void)
{
    bsp_board_init(BSP_INIT_LEDS);

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    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_0;
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));

    printf("SPI example started.\n");
    imu_setup_IIM42652();

    while (1)
    {
        // Reset rx buffer and transfer done flag
        memset(m_rx_buf, 0, m_length);
        spi_xfer_done = false;
        m_tx_buf[0]=0x80|0x1F;

        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
        printf("Read Accelerometer:%02X%02X-%02X%02X-%02X%02X\n", m_rx_buf[0],m_rx_buf[1], m_rx_buf[2],m_rx_buf[3], m_rx_buf[4],m_rx_buf[5]);
        while (!spi_xfer_done)
        {
            __WFE();
        }

        NRF_LOG_FLUSH();

        bsp_board_led_invert(BSP_BOARD_LED_0);
        nrf_delay_ms(200);
    }
}

I have tried the following for possible causes:

・Assign pin connections with reference to the data sheet. Shuffling didn't solve the problem
・When I checked the SPI communication waveform with an oscilloscope with the MBN52832 (WSM-BL241-ADA-008DK) module and sensor connected, I found that the CS, SCLK, and MOSI pins were normal, but the MISO pin was not normal.
With the MBN52832 (WSM-BL241-ADA-008DK) module and sensor connected, the MISO pin was left unconnected, and the MISO of the acceleration sensor was used as the measurement point. When checking the SPI communication waveform with an oscilloscope, it was found that the , SCLK, and MOSI pins all appear to be working properly.
please help me. Thank you.






  • Hi,

     

    Given that the SPI pins from the nRF are behaving as they should, and it is the MISO (master in / slave out) signal that isn't shifting data back, it sounds like a configuration issue on the sensor side. Are you certain that you have setup the sensor in SPI mode?

     

    Kind regards,

    Håkon

  • Thanks for your comment Håkon

    I'm following the default settings from the sensor's datasheet. The relevant code is this.

    /* DEVICE_CONFIG
             * SOFT_RESET_CONFIG[0] = 1(Enable Reset. wait 1ms)
             */
            m_tx_buf[0] = 0x11;
            m_tx_buf[1] = 0x01;
            APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, NULL, 0));

  • Hi,

     

    Try to reduce the SPI speed to 500 kHz, and could you share a logic trace of the whole init-operation, including SCK/MOSI/MISO/CSN?

     

    Kind regards,

    Håkon

  • Sorry for the late reply.

    I tried changing the SPI speed from 500K to 4M, but debugging stopped and it did not work properly.

    The following error message appears.
    void app_error_handler(unsigned int error_code=0x00004001, unsigned int line_num=0x00002029, const uint8_t* p_file_name=0x00004001)
    void app_error_fault_handler(unsigned int id=0x00004001, unsigned int pc=0x00002029, unsigned int info=0x2000ff70)


    ・To make it easier to understand, the code has been changed to read the sensor ID instead of the acceleration value.

    memset(m_rx_buf, 0, m_length);
            spi_xfer_done = false;
            m_tx_buf[0]=0xF5;
            //m_tx_buf[0]=0x9F;
    
            APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
            
            while (!spi_xfer_done)
            {
                __WFE();
            }
    
            printf("Read Accelerometer:%02X%02X-%02X%02X-%02X%02X\n", m_rx_buf[0],m_rx_buf[1], m_rx_buf[2],m_rx_buf[3], m_rx_buf[4],m_rx_buf[5]);

    If the SPI speed is 8M, you can debug without problems. The waveform measured with an oscilloscope is below.

    CLK (light blue), MISO (yellow), MOSI (pink),CS(green)
     

    F5 (11110101) can be transmitted from the MOSI waveform, but what is returned from MISO is not the correct 6F (01110011) but 5C (01011100).

    Thank you
     
  • Hi,

     

    When reducing the SPI speed, the firmware should not assert.

    Enter debug mode and see in the call stack where the function failed, and try to handle this accordingly.

     

    If you still receive the incorrect value for WHO_AM_I register; have you tried asking the sensor vendor for reasons this could happen?

     

    Kind regards,

    Håkon

Related