I want to use SPI and SAADC at the same time with Murata MBN52832 (WSM-BL241-ADA-008DK) module, but it doesn't work.

My purpose is to create a beacon that communicates acceleration and heart rate values ​​using BLE.

First of all, I tried to merge the nrf52832 SPI and SAADC sample programs, but debugging did not work properly.

The development environment is below.
・SEGGER Embedded Studio for ARM V5.70a
・Acceleration sensor (IIM-42652)
・Heart rate sensor

Here's what I noticed:
- Everything after the saadc_sampling_event_init() function is not working.
・If only one of SPI or SAADC is used, each sample program will work.
・Merge moved each SAADC file based on the SPI sample program.

please help me. Thank you.
//SPI
#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"

//standerd
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <stdint.h>

//SAADC
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nrf.h"
#include "nrf_drv_saadc.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "boards.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "app_util_platform.h"
#include "nrf_pwr_mgmt.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

//SPI setting
#define SPI_SCK_PIN 4  //SCK
#define SPI_MISO_PIN 29  //SDO
#define SPI_MOSI_PIN 17  //SDI
#define SPI_SS_PIN 3  //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. */
static  uint8_t whoami;

//SAADC
#define SAMPLES_IN_BUFFER 5
volatile uint8_t state = 1;

static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(0);
static nrf_saadc_value_t     m_buffer_pool[2][SAMPLES_IN_BUFFER];
static nrf_ppi_channel_t     m_ppi_channel;
static uint32_t              m_adc_evt_counter;



//SAADC function
void timer_handler(nrf_timer_event_t event_type, void * p_context)
{

}


void saadc_sampling_event_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
    APP_ERROR_CHECK(err_code);

    /* setup m_timer for compare event every 400ms */
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 400);
    nrf_drv_timer_extended_compare(&m_timer,
                                   NRF_TIMER_CC_CHANNEL0,
                                   ticks,
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                   false);
    nrf_drv_timer_enable(&m_timer);

    uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                NRF_TIMER_CC_CHANNEL0);
    uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();

    /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
                                          timer_compare_event_addr,
                                          saadc_sample_task_addr);
    APP_ERROR_CHECK(err_code);
}


void saadc_sampling_event_enable(void)
{
    ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);

    APP_ERROR_CHECK(err_code);
}


void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        ret_code_t err_code;

        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

        int i;
        printf("ADC event number: %d\n", (int)m_adc_evt_counter);

        for (i = 0; i < SAMPLES_IN_BUFFER; i++)
        {
            printf("%d\n", p_event->data.done.p_buffer[i]);
        }
        m_adc_evt_counter++;
    }
}


void saadc_init(void)
{
    ret_code_t err_code;
    nrf_saadc_channel_config_t channel_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);

    err_code = nrf_drv_saadc_init(NULL, saadc_callback);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(0, &channel_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);

}


/**
 * @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, 2, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;
        whoami  = m_rx_buf[1];
        printf(" whoami:0x%02X\n", whoami);
        if( whoami != 0x6F ){
          printf(" whoami:0x%02X (expected:0x6F)  ...exit\n", whoami);
          exit(0);
        }

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        nrf_delay_ms(50); 

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

        /* 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, m_rx_buf, 2));
        while (!spi_xfer_done){ __WFE(); }; spi_xfer_done=false;

}


void SPI_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_4M;
  spi_config.mode = NRF_DRV_SPI_MODE_0;
  APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));

  nrf_gpio_cfg(SPI_SCK_PIN,
  NRF_GPIO_PIN_DIR_OUTPUT,
  NRF_GPIO_PIN_INPUT_CONNECT,
  NRF_GPIO_PIN_NOPULL,
  NRF_GPIO_PIN_H0H1,
  NRF_GPIO_PIN_NOSENSE);
}


int main(void)
{
bsp_board_init(BSP_INIT_LEDS);

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


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

    ret_code_t ret_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(ret_code);

    saadc_sampling_event_init();
    saadc_sampling_event_enable();
    printf("SAADC HAL simple example started.");

    while (1)
    {

      memset(m_rx_buf, 0, m_length);
      spi_xfer_done = false;
      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("[IIM42652] X:%02X,Y:%02X,Z:%02X \n", m_rx_buf[1],m_rx_buf[3],m_rx_buf[5]);

      nrf_pwr_mgmt_run();
      NRF_LOG_FLUSH();
      
      nrf_delay_ms(100);
    }
    
}

Related