Zephyr GPIOTE + SPIM + BLE packet missing

Nordic DevZone
Nordic DevZone

Hello,

I'm currently working with ISP2053 which is the nRF5340-based module.

The system, as the specific GPIO pin detects a low-to-high event, gets data from another device via SPI (ISP becomes a master) and sends the SPI received data via BLE.

But I think the BLE parts malfunction and the data are missed.

When I check the CS pin of the SPI, the SPI transmissions are established for every GPIO event, so the problem may occur after the SPI.

Following is my code for the initiation of GPIOTE, SPIM, and BLE. Please let me know if I used the functions in an inappropriate way or missed setting.

void gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	nrfx_err_t err_code = nrfx_spim_xfer(&spim_adc, &spim_adc_desc, 0);
	if (err_code != NRFX_SUCCESS)
	{
		// printk("SPI error: %x\n", err_code);
	}
}

void gpiote_init(void)
{
	nrfx_err_t err_code;
	
	// GPIOTE init
    err_code = nrfx_gpiote_init(NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);
	
	nrfx_gpiote_in_config_t gpiote_cfg = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);

	err_code = nrfx_gpiote_in_init(pin_spim_fpga_ind, &gpiote_cfg, gpiote_handler);
	if (NRFX_SUCCESS != err_code)
	{
		printk("GPIOTE init error\n");
	}
	nrfx_gpiote_in_event_enable(pin_spim_fpga_ind, true);
}

void spim_adc_event_handler(nrfx_spim_evt_t const *p_event, void *p_context)
{
	if (p_event->type == NRFX_SPIM_EVENT_DONE)
	{
		spim_adc_xfer_done = true;
		// k_sem_give(&ble_buffer_ok);
	}
}

void spi_init(void)
{
	// spim_stim init
	nrfx_spim_config_t spim_stim_config = NRFX_SPIM_DEFAULT_CONFIG(pin_spim_stim_CLK, pin_spim_stim_MOSI, pin_spim_stim_MISO, pin_spim_stim_CS);
	spim_stim_config.frequency = NRF_SPIM_FREQ_8M;
	spim_stim_config.mode = NRF_SPIM_MODE_3;
	// nrfx_spim_init(&spim_stim, &spim_stim_config, spim_stim_event_handler, NULL);
	if (NRFX_SUCCESS != nrfx_spim_init(&spim_stim, &spim_stim_config, spim_stim_event_handler, NULL))
	{
		printk("SPIM_STIM init error\n");
	}
	IRQ_DIRECT_CONNECT(SPIM1_SPIS1_TWIM1_TWIS1_UARTE1_IRQn, 6, nrfx_spim_1_irq_handler, 0);
	irq_enable(SPIM1_SPIS1_TWIM1_TWIS1_UARTE1_IRQn);

	// spim_adc init
	nrfx_spim_config_t spim_adc_config = NRFX_SPIM_DEFAULT_CONFIG(pin_spim_adc_CLK, pin_spim_adc_MOSI, pin_spim_adc_MISO, pin_spim_adc_CS);
	spim_adc_config.frequency = NRF_SPIM_FREQ_8M;
	spim_adc_config.mode = NRF_SPIM_MODE_3;
	// nrfx_spim_init(&spim_adc, &spim_adc_config, spim_adc_event_handler, NULL);
	if (NRFX_SUCCESS != nrfx_spim_init(&spim_adc, &spim_adc_config, spim_adc_event_handler, NULL))
	{
		printk("SPIM_ADC init error\n");
	}
	IRQ_DIRECT_CONNECT(SPIM2_SPIS2_TWIM2_TWIS2_UARTE2_IRQn, 6, nrfx_spim_2_irq_handler, 0);
	irq_enable(SPIM2_SPIS2_TWIM2_TWIS2_UARTE2_IRQn);
}

void ble_send_thread(void)
{
	int ble_err_code = 0;
	while(1)
	{
		if (spim_adc_xfer_done)
		{
			if (is_ble_snd)
			{
				uint16_t length = spim_adc_m_length;
				ble_err_code = bt_nus_send(NULL, spim_adc_rx_buf, length);
			}
			spim_adc_xfer_done = false;
		}
		k_yield();
	}
}

K_THREAD_DEFINE(ble_send_thread_id, 1024, ble_send_thread, NULL, NULL, NULL, 7, 0, 0);

  • Hi,

    Where does the "is_ble_snd" flag set? Have you verified that your code enters this part of the loop, either by logging or debugging?

    Can you provide some more details about what you mean by "But I think the BLE parts malfunction and the data are missed."?

    Best regards,
    Jørgen

  • Where does the "is_ble_snd" flag set? Have you verified that your code enters this part of the loop, either by logging or debugging?

     Sorry for missing that part. When I send a certain Bluetooth message from another device, that flag becomes true. I verified the code above enters the loop via debugging.

    Can you provide some more details about what you mean by "But I think the BLE parts malfunction and the data are missed."?

     I mean, in the case of my debugging setup, the SPI slave device gives "0123456789..." and "9876543210..." in turn for every SPI transaction (each message has 240 bytes long). The slave device is nRF52840-DK with SPIS example from the nRF5 SDK 17.0.2 loaded.

     If everything works well, the resultant Bluetooth message from the SPIM should be the same as the SPIS message but it irregularly becomes like

     "0123456789" "9876543210"  "0123456789" (missing) "0123456789" "9876543210"

     Also, as I trigger the SPI transaction every 6ms and the message is 240 bytes long, the data throughput should be 40 kB/s, but it takes more than 3 seconds to take 40 kB data via Bluetooth.

  • DL_November said:

     I mean, in the case of my debugging setup, the SPI slave device gives "0123456789..." and "9876543210..." in turn for every SPI transaction (each message has 240 bytes long). The slave device is nRF52840-DK with SPIS example from the nRF5 SDK 17.0.2 loaded.

     If everything works well, the resultant Bluetooth message from the SPIM should be the same as the SPIS message but it irregularly becomes like

     "0123456789" "9876543210"  "0123456789" (missing) "0123456789" "9876543210"

    Have you checked the SPI lines with a logic analyzer, to see if the packets are being lost between the SPI devices, or when sending over BLE?

    DL_November said:
     Also, as I trigger the SPI transaction every 6ms and the message is 240 bytes long, the data throughput should be 40 kB/s, but it takes more than 3 seconds to take 40 kB data via Bluetooth.

    You should check the return code (ble_err_code) from your call to bt_nus_send(). If you call the function more often than you are able to send over BLE, the function may return an error when the buffers are full. If the throughput on BLE is too low, you may have to change the connection interval, data length, ATT MTU, PHY, connection event extension, etc. to allow more data to be sent over BLE. Please have a look at the Bluetooth: Throughput sample.

Related