[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);

Parents Reply Children
  • Please show the full code. I don't see how spim_buffer assigned. 


    I don't see where you assign the SPI buffer spim_rx_buf_A to. 

  • MOSI: command, MISO: result

    First of all, the data received from the sensor is the result (MISO) of the SPIM.

    While debugging the data received via BLE, there is an issue where the pattern of data received from the sensor is not being output as expected.

    After the result of the initial transmission (spim_tx_buf_initial) is successfully sent via BLE, only the result of the repeated transmission (spim_tx_buf_repeat) should be transmitted. However, even after the initial transmission is complete, some of the 'result of spim_tx_buf_initial' continues to be output. As a result, only the 'result of spim_tx_buf_repeat' should be repeated, but this is not happening as expected.

Related