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

ADC_IRQHandler not called when using RTC

I've modified the button press example from nAN-36 using the ADC examples from the git repository.

What I'm trying to do is send the data sampled via the ADC using the real time clock via a notify as is used on the button in the application note. I've added the notify (using the on_button_change function in the ADC_IRQHandler.

I've also copied over the timing functions from the rtc example.

I've added breakpoints on the IRQHandler but it is never called. Am I wrong in assuming that the ppi will not trigger the interrupt via channel 0? It seems that outputting the result is also handled the same way in the example. Or will I need to make some modifications to the on_button_change function

    static void ppi_init(void)
{
  // Configure PPI channel 0 to start ADC task
  NRF_PPI->CH[0].EEP = (uint32_t)&NRF_RTC0->EVENTS_TICK;
  NRF_PPI->CH[0].TEP = (uint32_t)&NRF_ADC->TASKS_START;

  // Enable PPI channel 0
  NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos);
}



    void ADC_IRQHandler(void)
{
	 uint8_t     adc_result;	    
	 uint32_t err_code;
	
	/* Clear dataready event */
  NRF_ADC->EVENTS_END = 0;	
	
	adc_result              = NRF_ADC->RESULT;
	
	//Use the STOP task to save current. Workaround for PAN_028 rev1.5 anomaly 1.
  NRF_ADC->TASKS_STOP = 1;
	
	//Release the external crystal
	sd_clock_hfclk_release();
	

// Notify ADC property    
            err_code = ble_lbs_on_button_change(&m_lbs, adc_result);
            if (err_code != NRF_SUCCESS &&
                err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
                err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
   
}	
  • Hi

    Have you enabled the ADC interrupt yet? You can see how that is done with the softdevice in the adc-example-with-softdevice example.

    If it is still not working, you may want to check first if the RTC tick is surely working, by enabling the RTC inerrupt and setting a breakpoint in the RTC interrupt handler.

    If you are configuring the ppi channels after you initialize the softdeivce with ble_stack_init(), it is safer to use the sd_ppi_* functions instead.

    The PPI does not directly trigger the ADC interrupt. It triggers the ADC START task which will initiate the ADC sampling. Some microseconds later the ADC will be finished with sampling and will output it's result in the ADC->RESULT register which will trigger the ADC interrupt.

    Calling the ble_lbs_on_button_change from the ADC interrupt handler should be fine if you explicitly set the priority of the interrupt to NRF_APP_PRIORITY_LOW, like done in the adc-example-with-softdevice example.

  • I'm not seeing the RTC0 interrupt trigger.

    I think I have the RTC setup right. RTC0_IRQHandler is just an __asm{nop} command to give the debugger something to break on.

     /** Configures and starts RTC0
    */
    static void rtc_config(void)
    {
    	NRF_RTC0->INTENSET = RTC_INTENSET_TICK_Enabled;  
    	sd_nvic_SetPriority(RTC0_IRQn, NRF_APP_PRIORITY_LOW);  
    	sd_nvic_EnableIRQ(RTC0_IRQn);
    	
    
      NRF_RTC0->PRESCALER = COUNTER_PRESCALER;                   // Set prescaler to a TICK of RTC_FREQUENCY
      NRF_RTC0->EVTENSET = RTC_EVTENSET_TICK_Msk;                // Enable TICK event	
    	NRF_RTC0->TASKS_START = 1;                                 // Start RTC0
    }
    
  • Hi Anton

    One very important thing I forgot to mention, the RTC0 peripheral is used by the S110 softdevice, so the peripheral is blocked when the softdevice is enabled. In the example I pointed you to earlier, application timer is used to trigger the ADC sampling. The application timers use the RTC1 in the background. When you use the application timers, you do not configure the RTC interrupt directly, instead you configure and start an application timer.

Related