This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to check for pending interrupts before calling sd_app_evt_wait?

Hi. I am having trouble getting the sd_app_evt_wait() call to work correctly in my code. My main program works like this:

<inits>
for(;;)
{
   <read saadc>
   <sd_app_evt_wait> // app_timer should make this return in 10 seconds
}

I have an app_timer that causes sd_app_evt_wait to return by firing every 10 seconds. The problem is, after sampling the ADCs, the call to sd_app_evt_wait returns immediately, running the loop forever. It doesn't sleep and wait for the timer. If I put a second call to sd_app_evt_wait directly after the first, the first call returns, and the second call sleeps until the timer wakes it (desired operation, but with two calls). From what I have learned of the sd_app_evt_wait function, if there are pending interrupts, it will immediately return. However, if I read the NVIC->ISPR at any time, it is 0. No interrupts pending, but sd_app_evt_wait returns once, then sleeps properly, on the Second call. I read about the FPU interrupts, so I added the following:

 uint32_t FPU_EXCEPTION_MASK = 0x0000009F;
pending = __get_FPSCR();
if (pending)
{
	NRF_LOG_DEBUG("FPU Exceptions: %d\r\n", pending);
	/* Clear exceptions and PendingIRQ from the FPU unit */
	__set_FPSCR(__get_FPSCR() & ~(FPU_EXCEPTION_MASK));
	(void) __get_FPSCR();
	NVIC_ClearPendingIRQ(FPU_IRQn);
}

but they don't help. The variable "pending" is always 0, and the ISPR is always 0. Adding

NVIC_ClearPendingIRQ(SAADC_IRQn);
NVIC_ClearPendingIRQ(FPU_IRQn);

before the first call to sd_app_evt_wait doesn't help either. What am I missing?

Parents
  • Thanks for finding that PAN, I hadn't seen that before. I put printouts in my ADC callback, and I only get one callback on init. My init runs nrf_drv_saadc_init(), then if that succeeds, calls nrf_drv_saadc_calibrate_offset(), which calls back to the ADC callback once with calibration completed. I measure channels one at a time by calling nrf_drv_saadc_channel_init(channel[i]) nrf_drv_saadc_sample_convert(channel[i]) nrf_drv_saadc_channel_uninit(channel[i] I don't use any DMAs or interrupts on conversion complete, just the blocking calls for each channel. I only run calibration once, on init, and I only get one callback to the ADC callback, but I still get the wake from sleep right after going to sleep...

Reply
  • Thanks for finding that PAN, I hadn't seen that before. I put printouts in my ADC callback, and I only get one callback on init. My init runs nrf_drv_saadc_init(), then if that succeeds, calls nrf_drv_saadc_calibrate_offset(), which calls back to the ADC callback once with calibration completed. I measure channels one at a time by calling nrf_drv_saadc_channel_init(channel[i]) nrf_drv_saadc_sample_convert(channel[i]) nrf_drv_saadc_channel_uninit(channel[i] I don't use any DMAs or interrupts on conversion complete, just the blocking calls for each channel. I only run calibration once, on init, and I only get one callback to the ADC callback, but I still get the wake from sleep right after going to sleep...

Children
No Data
Related