[SPIM + NUS] conflict between the SPIM and BLE thread.

I am programming with the nRF52840DKs. [Toolchain Manager: v1.3.0, IDE: Visual Studio Code (VSCode), SDK: ncs v2.6.0, window11 pro]

I am currently working on integrating 'NUS_peripheral' and 'SPIM'.

My goal: communicate with the ADC via SPIM and transmit the collected data via Bluetooth.

To briefly explain my code, the SPIM turns on and off at regular intervals using a timer. The NUS (peripheral) sends data through a while loop.

However, it seems that there's a conflict between the SPIM and the while loop in the BLE thread.

Below are the main code:

#define MTU_SIZE 244
#define PRIORITY 7

nrfx_spim_t spim1_inst = NRFX_SPIM_INSTANCE(SPIM_INST_IDX);
nrfx_timer_t timer1_inst = NRFX_TIMER_INSTANCE(TIMER_INST_IDX);
nrfx_gpiote_t gpiote_inst = NRFX_GPIOTE_INSTANCE(GPIOTE_INST_IDX);
nrf_ppi_channel_t ppi_channel_spi_start;
nrf_ppi_channel_t ppi_channel_spi_end;

volatile uint16_t initialization_counter = 0;
volatile uint16_t repeat_counter = 0;
volatile uint16_t NUS_send_counter = 0;
volatile bool initialization_stop = false;

#define TIME_TO_WAIT_US 50

uint8_t spim_tx_buf_initial[30][2];
uint8_t spim_tx_buf_repeat[18][2];

#define rx_data_size 4096
uint8_t spim_rx_buf_A[rx_data_size][2];
uint8_t spim_rx_buf_B[rx_data_size][2];
uint8_t (*spim_buffer)[2];
uint8_t (*nus_buffer)[2];
uint8_t out_channel;

void spim1_handler(nrfx_spim_evt_t const * p_event, void * p_context) {   
   NUS_send_counter++;
    
   if(!initialization_stop){
         initialization_counter++;
         if(initialization_counter == 30){
            initialization_stop = true;
            spim1_inst.p_reg->TXD.PTR = (uint32_t)spim_tx_buf_repeat[0];
         }
      return ;
   }
   repeat_counter++;
   if ( repeat_counter % 18 == 0 ) {
      spim1_inst.p_reg->TXD.PTR = (uint32_t)spim_tx_buf_repeat[0];
   } 
}

void timer0_handler(nrf_timer_event_t event_type, void * p_context){   

} 

void peripheral_setup(void){
    nrfx_err_t error;
    (void)error;
    
    /*  GPIOTE Setting */
    static const nrfx_gpiote_output_config_t output_config = {
        .drive = NRF_GPIO_PIN_S0S1,
        .input_connect = NRF_GPIO_PIN_INPUT_DISCONNECT,
        .pull = NRF_GPIO_PIN_NOPULL,
    };
    const nrfx_gpiote_task_config_t task_config = {
        .task_ch = out_channel,
        .polarity = NRF_GPIOTE_POLARITY_TOGGLE,
        .init_val = NRF_GPIOTE_INITIAL_VALUE_HIGH,
    };

    error = nrfx_gpiote_output_configure(&gpiote_inst, SS_PIN_MASTER, &output_config, &task_config);
    nrfx_gpiote_out_task_enable(&gpiote_inst, SS_PIN_MASTER);

    /*  SPIM 1 Setting */
    nrfx_spim_config_t spim1_config = NRFX_SPIM_DEFAULT_CONFIG(SCK_PIN_MASTER,
                                                            MOSI_PIN_MASTER,
                                                            MISO_PIN_MASTER,
                                                            NRF_SPIM_PIN_NOT_CONNECTED);
    spim1_config.frequency      = NRFX_MHZ_TO_HZ(8);
    error = nrfx_spim_init(&spim1_inst, &spim1_config, spim1_handler,0);

    nrfx_spim_xfer_desc_t spim1_xfer_desc = NRFX_SPIM_XFER_TRX((uint8_t*)spim_tx_buf_initial, 2, (uint8_t*)spim_rx_buf_A, 2);
    uint32_t spim1_flags = NRFX_SPIM_FLAG_HOLD_XFER | NRFX_SPIM_FLAG_REPEATED_XFER; 
    error = nrfx_spim_xfer(&spim1_inst, &spim1_xfer_desc, spim1_flags);
    spim1_inst.p_reg->TXD.PTR = (uint32_t)spim_tx_buf_initial[0];
    spim1_inst.p_reg->TXD.MAXCNT = 2;
    spim1_inst.p_reg->TXD.LIST =SPIM_TXD_LIST_LIST_ArrayList << SPIM_TXD_LIST_LIST_Pos;
    spim1_inst.p_reg->RXD.PTR = (uint32_t)spim_rx_buf_A[0];
    spim1_inst.p_reg->RXD.MAXCNT = 2;
    spim1_inst.p_reg->RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList << SPIM_RXD_LIST_LIST_Pos;

    /*  TIMER 0 Setting */
    nrfx_timer_config_t timer0_config = NRFX_TIMER_DEFAULT_CONFIG(16000000);
    timer0_config.bit_width          = NRF_TIMER_BIT_WIDTH_32,
    error = nrfx_timer_init(&timer1_inst, &timer0_config, timer0_handler);
    //error = nrfx_timer_init(&timer1_inst, &timer0_config, NULL);
    nrfx_timer_clear(&timer1_inst);
    k_sleep(K_MSEC(2000));


    uint32_t desired_ticks = nrfx_timer_us_to_ticks(&timer1_inst, TIME_TO_WAIT_US);
    nrfx_timer_extended_compare(&timer1_inst, NRF_TIMER_CC_CHANNEL0, desired_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

    /*   PPI  Setting  */
    uint32_t gpiote_task_addr = nrfx_gpiote_out_task_address_get(&gpiote_inst ,SS_PIN_MASTER);    
    uint32_t timer_start_compare_event_addr = nrfx_timer_compare_event_address_get(&timer1_inst, NRF_TIMER_CC_CHANNEL0);
    uint32_t spi_start_task_addr   = nrfx_spim_start_task_address_get(&spim1_inst);
    uint32_t spi_end_evt_addr = nrfx_spim_end_event_address_get(&spim1_inst);

    // Timer reaches the desired tick -> GPIOTE toggle(off), SPI start
    error = nrfx_gppi_channel_alloc(&ppi_channel_spi_start);
    nrfx_gppi_channel_endpoints_setup(ppi_channel_spi_start, timer_start_compare_event_addr, gpiote_task_addr);
    nrfx_gppi_fork_endpoint_setup(ppi_channel_spi_start, spi_start_task_addr);
    // SPI tx-rx transmission ends -> GPIOTE toggle(on)
    error = nrfx_gppi_channel_alloc(&ppi_channel_spi_end);
    nrfx_gppi_channel_endpoints_setup(ppi_channel_spi_end, spi_end_evt_addr, gpiote_task_addr);

}

void ble_write_thread(void){
   int ret;
   uint16_t temp;
   uint8_t (*temp_buffer)[2];
    
   k_sem_take(&nus_start, K_FOREVER);
   LOG_INF("Starting BLE Write Thread");

   while (1) {

      temp = NUS_send_counter;
      NUS_send_counter = 0;
      
      temp_buffer = spim_buffer;  
      spim_buffer = nus_buffer;
      nus_buffer = temp_buffer;

      spim1_inst.p_reg->RXD.PTR = (uint32_t)spim_buffer;

      while(temp > 0){
         if(temp < MTU_SIZE){
            ret = bt_nus_send(current_conn, (uint8_t *)nus_buffer, temp);
            temp = 0;
            break;
         }else{
            ret = bt_nus_send(current_conn, (uint8_t *)nus_buffer, MTU_SIZE);
            temp -= MTU_SIZE;
         }
      }
      if (k_sem_take(&disconnect_sem, K_NO_WAIT) == 0){
         LOG_INF("Disconnected, exiting BLE Write Thread");
         return;
      }
   }
}

K_THREAD_DEFINE(ble_write_thread_id, 8192, ble_write_thread, NULL, NULL, NULL, PRIORITY, 0, 0);

Related