ADC 1KHz over NUS with ADC Zephyr API - Crash

Hi everybody

I'm trying to implement a reading on a nRF5340 an ADC to sample a sensor every 1ms, pack datas and send them over NUS to a central.

I'm using NCS 2.1.0 and Zephyr ADC API

The problem is how to implement a reading of ADC in a faster way... What I implement until now is this:

An init function, to setup ADC (channels are defined into devTree, this code has been taken from an example)
and set up timers........

struct adc_sequence sequence = {
	/* individual channels will be added below */
	.channels = 0,
	.buffer	  = &sample_buffer,
	/* buffer size in bytes, not number of samples */
	.buffer_size = sizeof(sample_buffer),
	.resolution	 = ADC_RESOLUTION,
	.calibrate	 = true,
	.options	 = &adcOptions,
};

/****************************************************************/


static void AppFuncInput_AnalogIn(void)
{
	m_pAdcDevice = DEVICE_DT_GET(ADC_NODE);

	if (!device_is_ready(m_pAdcDevice))
	{
		LOG_ERROR("ADC device not found\n");
		return ERR_INVALID_PARAM;
	}
	
	/*
	 * Configure channels individually prior to sampling
	 */
	for (uint8_t i = 0; i < ADC_NUM_CHANNELS; i++)
	{
		channel_cfg.channel_id = channel_ids[i];
		LOG_INFO("Configured ADC%d", channel_ids[i]);

#ifdef CONFIG_ADC_NRFX_SAADC
		channel_cfg.input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + channel_ids[i];
#endif

		adc_channel_setup(m_pAdcDevice, &channel_cfg);

		sequence.channels |= BIT(channel_ids[i]);
	}

	m_adcVref = adc_ref_internal(m_pAdcDevice);


    /* Initialize a Timer to run the first time after 10s and then every 1ms */
    k_timer_init(&sFunctionTimer, AppFuncInput_AnalogIn, NULL);
    k_timer_start(&sFunctionTimer, K_MSEC(10000), K_MSEC(1));

/*
.....
*/

}

Then, the callback function to read the ADC is this:

static void AppFuncInput_AnalogIn(void)
{
	int16_t err = NO_ERROR;  ///< return code for the function

	/* Read sequence of channels (fails if not supported by MCU) */
	err = adc_read(m_pAdcDevice, &sequence);
	if (err != 0)
	{
		LOG_ERROR("ADC reading failed with error %d.\n", err);
		return err;
	}

	/* if there's an extra sample number please insert these values into filter calculation */
	for (uint8_t jj = 0; jj <= ADC_EXTRASAMPLE_NUMBER; jj += ADC_NUM_CHANNELS)
	{
		for (uint8_t i = 0; i < ADC_NUM_CHANNELS; i++)
		{
			calculateMean(&m_analogInputFlt[i], sample_buffer[i + jj]);
		/* 
		....
		*/
		}
	};

	AppFuncInput_HandleBleSendingData();
};

Now, if I use the 

AppFuncInput_AnalogIn( ) 
in the normal execution, calling the function in a separate thread, it works properly but I was not able to say: "Hey, sample every 1ms".
I put a k_msleep(1) but it depends on execution timing of the function...... That's why I introduced the K_Timer element.
BUT it fails to work.
When the timer ends, and launch callback, reached the adc_read( ), it says
ASSERTION FAIL [((arch_is_in_isr() == 0) || ((timeout).ticks == (((k_timeout_t) {0})).ticks))] @ WEST_TOPDIR/zephyr/kernel/sem.c:121
This could be due to interaction between BLE stack and ADC ?

Is there a more simple method to get data every 1ms from an ADC and then send it to BLE Nus central?

Thank you !
Parents Reply Children
No Data
Related