<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/46064/saadc-irq-handler-not-working</link><description>Hi 
 I am working on a project that has two timers, TIMER3 and TIMER4 (TIMER3 as timer and theTIMER4 as a counter). TIMER3 resets after counting up to 4. I am using PPI to increment TIMER4 every time TIMER3 resets. TIMER4 also resets after counting up</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 06 May 2019 05:52:47 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/46064/saadc-irq-handler-not-working" /><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/185325?ContentTypeID=1</link><pubDate>Mon, 06 May 2019 05:52:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:081aa126-9a78-4999-a281-6cb8cc4d8615</guid><dc:creator>t_m</dc:creator><description>&lt;p&gt;Thank you so much. It worked that way.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/185205?ContentTypeID=1</link><pubDate>Fri, 03 May 2019 13:28:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:64918662-413c-4490-a4d3-9cbab2450861</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;You need to encase your state machine in a while(1), otherwise the CPU will halt after the first execution:&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;int main(void)
{
   //Empty adc_buffer
    for(int n = 0; n &amp;lt; sizeof(adc_buffer)/sizeof(adc_buffer[0]); n++)
	{
		adc_buffer[n] = 0;
	}
	
	// init adc
    adc_init();
    
    // init timers
    timers_init();
    
    // start ppi
    timer4_adc_ppi();
    
    // start timers
    timers_start();
    
    while(1)
    {
        while(adc_counter &amp;lt; SAMPLES_IN_BUFFER)
        {
            //do nothing until all adc samples are collected
        }
        
        // calculate the average of the samples in the buffer
        float sample_sum =0;
    	float sample_avg=0;
    	
    	for (int j = 0; j &amp;lt; sizeof(adc_buffer)/sizeof(adc_buffer[0]); j++)
    	{
    	    sample_sum += adc_buffer[j];
    	}
    	sample_avg = sample_sum/sizeof(adc_buffer)/sizeof(adc_buffer[0]);
    	sample_avg = (uint16_t)sample_avg;
    	// UART print sample_avg (to be implemented!)
    	
    	//Empty adc_buffer for next measurement
        for(int n = 0; n &amp;lt; sizeof(adc_buffer)/sizeof(adc_buffer[0]); n++)
    	{
    		adc_buffer[n] = 0;
    	}
    }    
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/185029?ContentTypeID=1</link><pubDate>Fri, 03 May 2019 05:55:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c079d2e5-c53a-4ca8-b60f-6b8b5afa45c9</guid><dc:creator>t_m</dc:creator><description>&lt;p&gt;&amp;quot;&lt;span&gt;&amp;nbsp;Does you SAADS IRQ not fire at the end of the 32 samples? &amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;MY SAADC_IRQ does not fire at the end of the 32 samples. After the the 32th sample, the mcu exits the&amp;nbsp;&amp;nbsp;&lt;em&gt;while(adc_counter &amp;lt; SAMPLES_IN_BUFFER)&lt;/em&gt;&amp;nbsp;loop in the main function, continue executing the remaining lines of the main function. At the end of the main function, the IRQ_SAADC fires again. And when it leaves the IRQ, the MCU jumps back to line 164 in my code above (nrf_saadc_disable()) and continues executing the remaining lines of the main function before it finally halts.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/184957?ContentTypeID=1</link><pubDate>Thu, 02 May 2019 14:45:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:44b98b73-1f4c-4a7c-9186-92429a44918a</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;From earlier:&lt;br /&gt;&amp;quot;&lt;span&gt;I checked the&amp;nbsp;SAADC registers while debugging. I just noticed that TASKs_SAMPLE in PPI enables (sets to 1) EVENTS_DONE, EVENTS_END and EVENTS_RESULTDONE&amp;nbsp;&amp;nbsp;registers. I tried to disable them in my IRQ handler, but only EVENTS_END was able to clear to zero. &amp;quot;&lt;br /&gt;&lt;br /&gt;You only need EVENTS_END to be cleared, it&amp;#39;s the only interrupt that we care about. Does you SAADS IRQ not fire at the end of the 32 samples?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/184251?ContentTypeID=1</link><pubDate>Mon, 29 Apr 2019 09:17:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b6c33d28-60da-48f7-adfb-006b1ce0d489</guid><dc:creator>t_m</dc:creator><description>&lt;p&gt;I used that, but had the same effect. Now I just modified the while loop in main function in the following way to start the ADC task for every sample. It seems to work with some bugs:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;quot;nrf.h&amp;quot;
#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
//#include &amp;quot;bsp.h&amp;quot;
#include &amp;quot;nrf_gpio.h&amp;quot;
#include &amp;quot;nrf_delay.h&amp;quot;
#include &amp;quot;math.h&amp;quot;

//==================================
//PPI channels
#define TIMER4_PPI_CH_A						0 // TIMER3 reloads and TIMER4 increments
#define TIMER4_PPI_CH_B						1 // TIMER4 reloads, one ADC sample is taken
//===================================

//===================================
// TIMER CC registers
#define TIMER3_RELOAD_CC_NUM				5
#define TIMER4_RELOAD_CC_NUM 				5
//===================================

// TIMER3 reload value. The PWM frequency equals &amp;#39;16000000 / TIMER_RELOAD_VALUE&amp;#39;
#define TIMER3_RELOAD                   4 		
#define TIMER4_RELOAD					128		// TIMER4 counts upto 128. Count is incremented every timer TIMER3 RELOADs
#define SAMPLES_IN_BUFFER				32 	// Total number of ADC samples

static int adc_counter = 0; // counter for the ADC samples
volatile int16_t adc_value = 0;
volatile bool adc_flag = false;
volatile float adc_exact_value = 0;
static uint32_t adc_buffer[SAMPLES_IN_BUFFER];

//timer init
void timers_init(void)
{
    NRF_TIMER3-&amp;gt;BITMODE                 		= TIMER_BITMODE_BITMODE_08Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER3-&amp;gt;PRESCALER               		= 0;
    NRF_TIMER3-&amp;gt;SHORTS                  		= TIMER_SHORTS_COMPARE0_CLEAR_Msk &amp;lt;&amp;lt; TIMER3_RELOAD_CC_NUM;
    NRF_TIMER3-&amp;gt;MODE                    		= TIMER_MODE_MODE_Timer &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;
    NRF_TIMER3-&amp;gt;CC[TIMER3_RELOAD_CC_NUM] 		= TIMER3_RELOAD;
	
	NRF_TIMER4-&amp;gt;BITMODE                     	= TIMER_BITMODE_BITMODE_08Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER4-&amp;gt;PRESCALER               		= 0;
    NRF_TIMER4-&amp;gt;SHORTS                  		= TIMER_SHORTS_COMPARE0_CLEAR_Msk &amp;lt;&amp;lt; TIMER4_RELOAD_CC_NUM;
    NRF_TIMER4-&amp;gt;MODE                    		= TIMER_MODE_MODE_Counter &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;
    NRF_TIMER4-&amp;gt;CC[TIMER4_RELOAD_CC_NUM] 		= TIMER4_RELOAD;
}

void timers_start(void)
{
    NRF_TIMER3-&amp;gt;TASKS_START = 1;		
	NRF_TIMER4-&amp;gt;TASKS_START = 1;
}
void SAADC_IRQHandler(void)
{
      adc_flag = true;
      nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
}

void adc_init(void)

	// Enable interrupt on ADC sample ready
	NRF_SAADC-&amp;gt;INTENSET = SAADC_INTENSET_END_Msk;
	NVIC_EnableIRQ(SAADC_IRQn); 
	
	// configure ADC
	NRF_SAADC-&amp;gt;CH[0].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6    &amp;lt;&amp;lt; SAADC_CH_CONFIG_GAIN_Pos) |
                            (SAADC_CH_CONFIG_MODE_SE         &amp;lt;&amp;lt; SAADC_CH_CONFIG_MODE_Pos) |
                            (SAADC_CH_CONFIG_REFSEL_Internal &amp;lt;&amp;lt; SAADC_CH_CONFIG_REFSEL_Pos) |
                            (SAADC_CH_CONFIG_RESN_Bypass     &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESN_Pos) |
                            (SAADC_CH_CONFIG_RESP_Bypass     &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESP_Pos) |
                            (SAADC_CH_CONFIG_TACQ_3us        &amp;lt;&amp;lt; SAADC_CH_CONFIG_TACQ_Pos);

  // Configure the SAADC channel with AIN2 as positive input, no negative input(single ended). // change it to AIN5 in the final version
  NRF_SAADC-&amp;gt;CH[0].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput2 &amp;lt;&amp;lt; SAADC_CH_PSELP_PSELP_Pos;
  NRF_SAADC-&amp;gt;CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC &amp;lt;&amp;lt; SAADC_CH_PSELN_PSELN_Pos; // Will be ignored if MODE is SE
	
  // Configure the SAADC resolution.
  NRF_SAADC-&amp;gt;RESOLUTION = SAADC_RESOLUTION_VAL_12bit &amp;lt;&amp;lt; SAADC_RESOLUTION_VAL_Pos;
	
  // Configure result to be put in RAM at the location of &amp;quot;adc_value&amp;quot; variable.
  // Number of sample counts
  NRF_SAADC-&amp;gt;RESULT.MAXCNT = 1;
  NRF_SAADC-&amp;gt;RESULT.PTR = (uint32_t)&amp;amp;adc_value;
	
  // Enable ADC
  NRF_SAADC-&amp;gt;ENABLE = SAADC_ENABLE_ENABLE_Enabled &amp;lt;&amp;lt; SAADC_ENABLE_ENABLE_Pos;
	
  //Start the ADC 
  NRF_SAADC-&amp;gt;TASKS_START = 1;
  while(NRF_SAADC-&amp;gt;EVENTS_STARTED ==0);
  NRF_SAADC-&amp;gt;EVENTS_STARTED = 0;
  
}

void timer4_adc_ppi(void)
{
	// Create PPI event when TIMER3 reloads that triggers an increment counting task in TIMER4
	NRF_PPI-&amp;gt;CH[TIMER4_PPI_CH_A].EEP 		= (uint32_t)&amp;amp;NRF_TIMER3-&amp;gt;EVENTS_COMPARE[TIMER3_RELOAD_CC_NUM];
	NRF_PPI-&amp;gt;CH[TIMER4_PPI_CH_A].TEP 		= (uint32_t)&amp;amp;NRF_TIMER4-&amp;gt;TASKS_COUNT;
	
	
	// Create PPI event on TIMER4 when it reaches TIMER4_RELOAD, that triggers ADC sampling task
	NRF_PPI-&amp;gt;CH[TIMER4_PPI_CH_B].EEP 		= (uint32_t)&amp;amp;NRF_TIMER4-&amp;gt;EVENTS_COMPARE[TIMER4_RELOAD_CC_NUM];
	NRF_PPI-&amp;gt;CH[TIMER4_PPI_CH_B].TEP 		= (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;TASKS_SAMPLE;	
	
	NRF_PPI-&amp;gt;CHENSET 							= ( 1 &amp;lt;&amp;lt; TIMER4_PPI_CH_A) | ( 1 &amp;lt;&amp;lt; TIMER4_PPI_CH_B);
}

int main(void)
{
   //Empty adc_buffer
    memset(&amp;amp;adc_buffer,0, sizeof(adc_buffer));	
	
	// init adc
    adc_init();
    
    // init timers
    timers_init();
    
    // start ppi
    timer4_adc_ppi();
    
    // start timers
    timers_start();
    
    
    while(adc_counter &amp;lt; SAMPLES_IN_BUFFER)
    {
        if(adc_flag )
			{
				adc_flag = false;
				adc_exact_value =(((float)adc_value/4096)*3.6f*1000)*5.545f;
				adc_buffer[sample_count] = adc_exact_value;
				NRF_SAADC-&amp;gt;TASKS_START = 0x01UL;
				while (!NRF_SAADC-&amp;gt;EVENTS_STARTED); 
				NRF_SAADC-&amp;gt;EVENTS_STARTED = 0x00UL;
				adc_counter++;
			}	
	
    }
    
    // calculate the average of the samples in the buffer
    float sample_sum =0;
	float sample_avg=0;
	
	for (int j = 0; j &amp;lt; sizeof(adc_buffer)/sizeof(adc_buffer[0]); j++)
	{
	    sample_sum += adc_buffer[j];
	}
	sample_avg = sample_sum/sizeof(adc_buffer)/sizeof(adc_buffer[0]);
	sample_avg = (uint16_t)sample_avg;
	// UART print sample_avg (to be implemented!)
	
	nrf_drv_common_irq_disable(SAADC_IRQn);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
				
				// Wait for ADC being stopped.
    uint32_t timeout = 3; // tried different values

    while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0 &amp;amp;&amp;amp; timeout &amp;gt; 0)
    {
        --timeout;
    }
    nrf_saadc_disable();
				
	//Empty adc_buffer for next measurement
     memset(&amp;amp;adc_buffer,0, sizeof(adc_buffer));
    
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The bug I have right now is the IRQ handler function is called once&amp;nbsp;again after it reaches the last line of code in the main function. I don&amp;#39;t know what triggers it, but it just gets triggered ones. I tried to put different timeout values for the NRF_SAADC_TASK_STOP, but didn&amp;#39;t fix the issue. Any idea on this?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/183354?ContentTypeID=1</link><pubDate>Wed, 24 Apr 2019 08:44:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f5776fbc-9938-4b3a-819f-36f950b61e20</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;You need to clear those events in your SAADC IRQ with &lt;span&gt;nrf_saadc_event_clear&lt;/span&gt;&lt;span&gt;(NRF_SAADC_EVENT_END) etc&lt;/span&gt;, and they should remain enabled.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/182404?ContentTypeID=1</link><pubDate>Tue, 16 Apr 2019 13:26:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f7806c8c-568f-4cc2-9e12-394329f1a59c</guid><dc:creator>t_m</dc:creator><description>&lt;p&gt;If I start from the last tip:&lt;/p&gt;
&lt;p&gt;&amp;quot;&lt;span&gt;I also also suggest that you verify your PPI triggering separately from the SAADC operation, that way you can be sure that the PPI system gets the signal from TIMER 4 when it&amp;#39;s supposed to. &amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Yes, I used a GPIOTE channel to toggle a PIN when TIMER 4 resets. Toggling of the PIN happens precisely as it is defined by the PPI.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I checked the&amp;nbsp;SAADC registers while debugging. I just noticed that TASKs_SAMPLE in PPI enables (sets to 1) EVENTS_DONE, EVENTS_END and EVENTS_RESULTDONE&amp;nbsp;&amp;nbsp;registers. I tried to disable them in my IRQ handler, but only EVENTS_END was able to clear to zero.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/182112?ContentTypeID=1</link><pubDate>Mon, 15 Apr 2019 12:44:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a38d192a-6c3e-4a5c-ace7-a4467b06827d</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;&lt;em&gt;NRF_SAADC_TASK_SAMPLE is the address offset from the SAADC address base, you need to use&amp;nbsp;NRF_SAADC-&amp;gt;TASKS_SAMPLE when operating on absolute addresses.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;NRF_SAADC_TASK_SAMPLE&lt;span&gt;&amp;nbsp;uses address offset because that&amp;#39;s the API style of the low level drivers in the SDK.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;I suggest you run the SAADC example as is, monitor the state of the registers, and compare those states with your own project.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/em&gt;I also suggest you take a look at the SAADC driver and see how it sets up the SAADC and how its ISR handles the SAADC events.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;I also also suggest that you verify your PPI triggering separately from the SAADC operation, that way you can be sure that the PPI system gets the signal from TIMER 4 when it&amp;#39;s supposed to.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/182049?ContentTypeID=1</link><pubDate>Mon, 15 Apr 2019 09:47:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4007df32-8624-44a1-a95a-135f824e0c7d</guid><dc:creator>t_m</dc:creator><description>&lt;p&gt;Sorry, I am still not able to move forward with this problem. I am not sure what goes wrong, but it seems the MCU gets jammed after the IRQ Handler is triggered once. I tried to clear the flags, tried to do it in different ways but didn&amp;#39;t succeed.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I am planning to go with the second option, i.e using the nrf_saadc_buffer_convert() with the ppi. I just read in the documentation on SAADC (if I understand correctly), that I should use&amp;nbsp;&lt;em&gt;NRF_SAADC_TASK_SAMPLE&lt;/em&gt;&lt;span&gt;&amp;nbsp;to trigger one sample task. Is it so that I can replace line 106 of my code above with&amp;nbsp;&lt;em&gt;NRF_PPI-&amp;gt;CH[TIMER4_PPI_CH_B].TEP = (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;NRF_SAADC_TASK_SAMPLE; ? &lt;/em&gt;If that is the case, how should I write my call back function?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/181638?ContentTypeID=1</link><pubDate>Thu, 11 Apr 2019 13:40:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4629d333-483a-430b-adb5-945bade69b4b</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;&amp;quot;&lt;span&gt;Through debugging I can see that the IRQ handler is called once, and the adc_counter gets incremented only once. &amp;quot;&amp;nbsp;&lt;br /&gt;- You probably need to clear the interrupt flag in NVIC. You can do this by calling&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span&gt;nrf_saadc_event_clear&lt;/span&gt;&lt;span&gt;(NRF_SAADC_EVENT_END);&lt;br /&gt;This is usually done in the saadc driver&amp;#39;s interrupt handler.&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;&amp;quot;Can I check those in kiel, debug mode?&amp;quot;&lt;br /&gt;- Yes, they should appear as the INTEN, INTSET, and INTCLR registers along the other SAADC registers, this is true for all the other peripherals as well.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;quot;Can I use nrf_drv_saadc_buffer_convert()&amp;nbsp;with PPI?&amp;quot;&lt;br /&gt;-Yes, they are intended to be used together.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/181589?ContentTypeID=1</link><pubDate>Thu, 11 Apr 2019 12:27:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:df1ac458-df14-4bdd-9f7c-97f2cd61dd7e</guid><dc:creator>t_m</dc:creator><description>&lt;p&gt;Through debugging I can see that the IRQ handler is called once, and the adc_counter gets incremented only once.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;quot;&lt;span&gt;You need to check the NVIC registers to see if the SAADC&amp;#39;s END event interrupt is actually enabled.&amp;quot; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Can I check those in kiel, debug mode?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Can I use nrf_drv_saadc_buffer_convert()&amp;nbsp;with PPI?&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/181567?ContentTypeID=1</link><pubDate>Thu, 11 Apr 2019 11:50:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:72025409-f6de-4533-b9dc-0daaeebf7028</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;You need to check the NVIC registers to see if the SAADC&amp;#39;s END event interrupt is actually enabled.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;quot;&lt;span&gt;TIMER3 is used to generate two phase shifted PWM signals using PPI, based on the example&amp;nbsp;&lt;/span&gt;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/30198/what-is-the-maximum-and-minimum-frequency-of-the-pwm-signal-which-can-be-measured/120517#120517"&gt;here&lt;/a&gt;&lt;span&gt;. The timer of the PWM signals resets faster than the ADC sampling rate =&amp;gt; requirement for TIMER4.&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;- Alright your TIMERs looks good then :)&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;quot;&lt;span&gt;If I understood correctly, to set RESULT.MAXCNT=32, I should also specify the sampling frequency using&amp;nbsp;NRF_SAADC-&amp;gt;SAMPLERATE.&amp;quot;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;- Not correct. You should not use the SAMPLERATE register unless you&amp;#39;re also using the SAADC&amp;#39;s internal timer (poorly documented). If SAMPLERATE.MODE is set to 0x0 the SAMPLE task will trigger individual samples. &lt;br /&gt;In this mode one sample will be taken for each enabled SAADC channel every time a SAMPLE task is triggered until the number of samples taken&amp;nbsp;across all channels equals RUSULT.MAXCNT. &lt;br /&gt;In your case you&amp;#39;ve only got one channel enabled and therefore you will reach MAXCNT after MAXCNT amount of SAMPLE tasks has been triggered. If you&amp;#39;ve had enabled two channels then you would reach MAXCNT after MAXCNT/2 SAMPLE tasks have been triggered, etc.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;If you want continuous sampling with a buffer size of 32 samples, then you should update RESULT.PTR after you&amp;#39;ve triggered the START task and received the STARTED event. The RESULT register is double buffered, this means that when you trigger the START task the content of this register is copied into an internal SAADC register. The reason why this is done is that you can then immediately prepare the next sample buffer and write its address and size into the RESULT register, and then use PPI to connect the END event to the START task, thereby creating an endless loop of TIMER synchronized adc sampling.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;nrf_drv_saadc_buffer_convert() does this with a set of two buffers that is swapped for each cycle of&amp;nbsp;(32) samples. You can use any amount of buffers you like.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/181539?ContentTypeID=1</link><pubDate>Thu, 11 Apr 2019 10:48:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:91b18bbf-fdbb-49f7-b93d-90b86ef0a336</guid><dc:creator>t_m</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;Thanks for the tips.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The Interrupt handler is not executed at all. That&amp;#39;s what worries me. The reason why I am using two timers, instead of one, is because TIMER3 is used to generate two phase shifted PWM signals using PPI, based on the example &lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/30198/what-is-the-maximum-and-minimum-frequency-of-the-pwm-signal-which-can-be-measured/120517#120517"&gt;here&lt;/a&gt;. The timer of the PWM signals resets faster than the ADC sampling rate =&amp;gt; requirement for TIMER4.&lt;/p&gt;
&lt;p&gt;The ADC sampling is done at a lower frequency than the PWM. However, it is required that the&amp;nbsp;ADC sampling should be synchronized with the PWM signals, which make it difficult to use RESULT.MAXCNT = 32. If I understood correctly, to set RESULT.MAXCNT=32, I should also specify the sampling frequency using&amp;nbsp;NRF_SAADC-&amp;gt;SAMPLERATE. This will make the synchronization between the two times difficult.The two timers are synchronized using PPI. So, my question is how should the SAADC IRQ handler be written so that it counts the number of ADC samples and appends that to the buffer. The main function will take care of the rest when the buffer is full.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC IRQ Handler not working</title><link>https://devzone.nordicsemi.com/thread/181503?ContentTypeID=1</link><pubDate>Thu, 11 Apr 2019 09:07:22 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3b12c828-1eda-4093-ae8d-aeb4752f9e3f</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;Does the interrupt handler execute at all? Place a breakpoint in the interrupt handler to verify.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are a few things that you can change to greatly reduce the complexity of your application.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;The first thing you should do is to set RESULT.MAXCNT to 32, then you wont have to service the interrupt until you&amp;#39;ve got all 32 samples. You will also not have to keep track of the sample number with a global variable.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;The second thing is to only use TIMER3, there&amp;#39;s no need to use another timer as each TIMER has six compare match registers. You can set TIMER3&amp;#39;s CC0 register to (128*4), trigger the SAADC SAMPLE task from&amp;nbsp;&lt;span&gt;EVENTS_COMPARE[0]&amp;nbsp;and enable the SHORTS to clear TIMER3.&amp;nbsp;&lt;br /&gt;What I believe you&amp;#39;re trying to do is to implement a prescaler in order to get the correct frequency&amp;nbsp;for your SAADC sampling. The TIMERs already have this functionality&amp;nbsp;with the PRESCALER register. From&amp;nbsp;&lt;a href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/timer.html?cp=2_1_0_23#concept_xbd_hqp_sr"&gt;TIMER — Timer/counter&lt;/a&gt;:&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt; f&lt;sub&gt;TIMER&lt;/sub&gt; = 16 MHz / (2&lt;sup&gt;PRESCALER&lt;/sup&gt;)&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;br /&gt;The third thing is using memset to erase a buffer instead of a for loop, f.ex:&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;//Empty adc_buffer

memset(&amp;amp;adc_buffer,0, sizeof(adc_buffer)); 
&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;See &lt;a href="https://www.tutorialspoint.com/c_standard_library/c_function_memset.htm"&gt;https://www.tutorialspoint.com/c_standard_library/c_function_memset.htm&amp;nbsp;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Cheers!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>