<?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>nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/62058/nrf52-timer-code-help</link><description>Hi 
 I&amp;#39;m working on a project in which I use a timer to generate two signals that I need to phase shift each other, but at the beginning and at the end it cuts, can anyone advise me how to solve this problem ?. I&amp;#39;m attaching my code and a video to see</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 03 Jun 2020 09:04:06 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/62058/nrf52-timer-code-help" /><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252928?ContentTypeID=1</link><pubDate>Wed, 03 Jun 2020 09:04:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e5f8ba69-0331-4967-bdea-37b781fcc04b</guid><dc:creator>Folny</dc:creator><description>&lt;p&gt;Thanks for your advice, I set up the code this way and it looks like it&amp;#39;s working properly.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;lt;stdbool.h&amp;gt;
#include &amp;quot;nrf.h&amp;quot;
#include &amp;quot;nrf_gpio.h&amp;quot;
#include &amp;quot;boards.h&amp;quot;
#include &amp;quot;nrf_delay.h&amp;quot;

#define GPIOTE_TASK(ch, pin, initstate) do { NRF_GPIOTE-&amp;gt;CONFIG[ch] = ((3UL &amp;lt;&amp;lt; 0) | ((pin) &amp;lt;&amp;lt; 8) | (3UL &amp;lt;&amp;lt; 16) | ((initstate) &amp;lt;&amp;lt; 20)); } while (0)
	
int Frequency = 400;
int Phase_Set = 0; //set phase 0-100

//int Phase[4] = {1, 1, 0, 0};

//int cnt = 0;

#define GPIO_OUT_1         NRF_GPIO_PIN_MAP(0,6)
#define GPIO_OUT_2         NRF_GPIO_PIN_MAP(0,8)

void timer_init(int frequency, int phase){	

    NRF_TIMER2-&amp;gt;BITMODE                 = TIMER_BITMODE_BITMODE_24Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER2-&amp;gt;PRESCALER               = 0;
    NRF_TIMER2-&amp;gt;SHORTS                  = TIMER_SHORTS_COMPARE0_CLEAR_Msk &amp;lt;&amp;lt; 0;
    NRF_TIMER2-&amp;gt;MODE                    = TIMER_MODE_MODE_Timer &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;
	NRF_TIMER2-&amp;gt;CC[0] = frequency;
	NRF_TIMER2-&amp;gt;CC[1] = phase+1;
    NRF_TIMER2-&amp;gt;CC[2] = ((phase+1) + frequency/2) % frequency;  
 	
  	//NRF_TIMER2-&amp;gt;INTENSET = (TIMER_INTENSET_COMPARE0_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE0_Pos) | (TIMER_INTENSET_COMPARE1_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE1_Pos);
	
    //NVIC_EnableIRQ(TIMER2_IRQn);		
    NRF_TIMER2-&amp;gt;TASKS_START = 1;               
}

/*
void TIMER2_IRQHandler(void){

	if(NRF_TIMER2-&amp;gt;EVENTS_COMPARE[0]){
	nrf_gpio_pin_toggle(GPIO_OUT_1);           
    NRF_TIMER2-&amp;gt;EVENTS_COMPARE[0] = 0;           
  }
	
	if(NRF_TIMER2-&amp;gt;EVENTS_COMPARE[1]){
	cnt++;
    nrf_gpio_pin_write(GPIO_OUT_2,Phase[cnt]);
	if(cnt == 4)
    cnt = 0;
	NRF_TIMER2-&amp;gt;EVENTS_COMPARE[1] = 0;           
  }
}
*/

int main(void){

  NRF_CLOCK-&amp;gt;TASKS_HFCLKSTART = 1;
  nrf_gpio_cfg_output(GPIO_OUT_1);       
  nrf_gpio_cfg_output(GPIO_OUT_2);
	
  GPIOTE_TASK(0, GPIO_OUT_1, 0);
  GPIOTE_TASK(1, GPIO_OUT_2, 0);
	
  NRF_PPI-&amp;gt;CH[0].EEP = (uint32_t)&amp;amp;NRF_TIMER2-&amp;gt;EVENTS_COMPARE[0];
  NRF_PPI-&amp;gt;CH[0].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[0];
  NRF_PPI-&amp;gt;CHENSET = (1UL &amp;lt;&amp;lt; 0);
	
  NRF_PPI-&amp;gt;CH[1].EEP =(uint32_t)&amp;amp; NRF_TIMER2-&amp;gt;EVENTS_COMPARE[1];
  NRF_PPI-&amp;gt;CH[1].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_SET[1];
  NRF_PPI-&amp;gt;CHENSET = (1UL &amp;lt;&amp;lt; 1);
  NRF_PPI-&amp;gt;CH[2].EEP = (uint32_t)&amp;amp;NRF_TIMER2-&amp;gt;EVENTS_COMPARE[2];
  NRF_PPI-&amp;gt;CH[2].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_CLR[1];
  NRF_PPI-&amp;gt;CHENSET = (1UL &amp;lt;&amp;lt; 2);
	
  timer_init(Frequency,Phase_Set*2);                              
	
	while(1){
 	Phase_Set++;
  if(Phase_Set == Frequency){
	 Phase_Set = 1;
  }
  NRF_TIMER2-&amp;gt;CC[1] = Phase_Set+1;
  NRF_TIMER2-&amp;gt;CC[2] = ((Phase_Set+1) + Frequency/2) % Frequency;
  nrf_delay_ms(50); 
  }
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252843?ContentTypeID=1</link><pubDate>Tue, 02 Jun 2020 19:47:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:411d6d72-9467-4d90-b8fd-909cccf98ad9</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;Please read &lt;a href="https://natersoz.net/2019/04/07/nordic-tasks-and-events/"&gt;this&lt;/a&gt;&amp;nbsp;article about tasks, events and PPI.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t see a reason to run lower curve in IRQ - you will loose all advantages of GPIOTE and your channels will not be synchronized. Here are &amp;quot;a few lines of code&amp;quot; to start with (maybe it&amp;#39;s not exactly what you need, but hope you will understand what to do next).&lt;/p&gt;
&lt;p&gt;First, configure your pins to be controlled by GPIOTE:&lt;/p&gt;
&lt;p&gt;#define GPIOTE_TASK(ch, pin, initstate) do { NRF_GPIOTE-&amp;gt;CONFIG[ch] = ((3UL &amp;lt;&amp;lt; 0) | ((pin) &amp;lt;&amp;lt; 8) | (3UL &amp;lt;&amp;lt; 16) | ((initstate) &amp;lt;&amp;lt; 20)); } while (0)&lt;/p&gt;
&lt;p&gt;GPIOTE_TASK(0, GPIO_OUT_1, 0);&lt;br /&gt;GPIOTE_TASK(1, GPIO_OUT_2, 0);&lt;/p&gt;
&lt;p&gt;For upper curve, configure GPIOTE channel 0 to toggle on CC[0] event:&lt;/p&gt;
&lt;p&gt;NRF_PPI-&amp;gt;CH[0].EEP = &amp;amp;NRF_TIMER2-&amp;gt;EVENTS_COMPARE[0];&lt;br /&gt;NRF_PPI-&amp;gt;CH[0].TEP = &amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[0];&lt;br /&gt;NRF_PPI-&amp;gt;CHENSET = (1UL &amp;lt;&amp;lt; 0);&lt;/p&gt;
&lt;p&gt;For lower curve, configure GPIOTE channel 1 to rise on CC[1] and fall on CC[2]:&lt;/p&gt;
&lt;p&gt;NRF_PPI-&amp;gt;CH[1].EEP = &amp;amp;NRF_TIMER2-&amp;gt;EVENTS_COMPARE[1];&lt;br /&gt;NRF_PPI-&amp;gt;CH[1].TEP = &amp;amp;NRF_GPIOTE-&amp;gt;TASKS_SET[1];&lt;br /&gt;NRF_PPI-&amp;gt;CHENSET = (1UL &amp;lt;&amp;lt; 1);&lt;br /&gt;NRF_PPI-&amp;gt;CH[2].EEP = &amp;amp;NRF_TIMER2-&amp;gt;EVENTS_COMPARE[2];&lt;br /&gt;NRF_PPI-&amp;gt;CH[2].TEP = &amp;amp;NRF_GPIOTE-&amp;gt;TASKS_CLR[1];&lt;br /&gt;NRF_PPI-&amp;gt;CHENSET = (1UL &amp;lt;&amp;lt; 2);&lt;/p&gt;
&lt;p&gt;Now you can adjust phase shift of lower curve by changing CC[1] and CC[2] in your loop:&lt;/p&gt;
&lt;p&gt;NRF_TIMER2-&amp;gt;CC[1] = phase;&lt;br /&gt;NRF_TIMER2-&amp;gt;CC[2] = (phase + frequency/2) % frequency;&lt;/p&gt;
&lt;p&gt;If you need to sample ADC value at some point, you can configure channel 3 to start a SAMPLE task:&lt;/p&gt;
&lt;p&gt;NRF_PPI-&amp;gt;CH[3].EEP = &amp;amp;NRF_TIMER2-&amp;gt;EVENTS_COMPARE[3];&lt;br /&gt;NRF_PPI-&amp;gt;CH[3].TEP = &amp;amp;NRF_SAADC-&amp;gt;TASKS_SAMPLE;&lt;br /&gt;NRF_PPI-&amp;gt;CHENSET = (1UL &amp;lt;&amp;lt; 3);&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252786?ContentTypeID=1</link><pubDate>Tue, 02 Jun 2020 14:22:31 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c294bb9b-cfcd-4bef-90de-399639015d0a</guid><dc:creator>Folny</dc:creator><description>&lt;p&gt;Basically, I just need what you see in my video, the upper curve on the oscilloscope can be generated using GPIOTE and the lower curve runs in IRQ and only needs a full phase shift.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252783?ContentTypeID=1</link><pubDate>Tue, 02 Jun 2020 14:15:34 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4eb7865f-4cf2-400b-bb8c-cf424ab8f9d4</guid><dc:creator>Folny</dc:creator><description>&lt;p&gt;I have no experience with PPI and GPIOTE, I&amp;#39;m new and I started programming nRF just a few months ago, it would be great if you could help me with that and write at least a few lines of code.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252781?ContentTypeID=1</link><pubDate>Tue, 02 Jun 2020 14:03:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9411f8e2-7a1e-4217-b5be-30973057c1b7</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;I didn&amp;#39;t look deeply into an algorithm - as I understood, you need to generate two phase-shifted signals and sample a value with ADC at some point of time. You can leave processing of&amp;nbsp; the result in IRQ routine, but anything hardware-related (wave generation, start of ADC sampling) can be done better with PPI and GPIOTE.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252761?ContentTypeID=1</link><pubDate>Tue, 02 Jun 2020 13:13:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e8c247af-b4d9-492a-b931-15e718cf5125</guid><dc:creator>Folny</dc:creator><description>&lt;p&gt;Yes I would need to use the IRQ because it will run part of the program I am working on something&amp;nbsp; similar &lt;a href="https://github.com/dc42/arduino/blob/master/MetalDetector/MetalDetector.ino"&gt;https://github.com/dc42/arduino/blob/master/MetalDetector/MetalDetector.ino&lt;/a&gt; if you have any idea how to omit the IRQ write it to me there.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252753?ContentTypeID=1</link><pubDate>Tue, 02 Jun 2020 12:58:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b2a359f6-76d8-4fc0-adcd-c5ecadb25459</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;Do you need some other tasks in IRQ handler? If no, GPIOTE will give you exactly the same result as your interrupt routine but with much higher precision.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252748?ContentTypeID=1</link><pubDate>Tue, 02 Jun 2020 12:53:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4c61036b-d77e-4774-ba75-717eb71becb0</guid><dc:creator>Folny</dc:creator><description>&lt;p&gt;Thank you for your answer, I&amp;#39;m not entirely sure how to do this because the main program must run in TIMER2_IRQHandler nrf_gpio_pin_toggle(GPIO_OUT_1); must remain phase preserved via GPIOTE I only want to scroll GPIO_OUT_2.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Timer Code Help</title><link>https://devzone.nordicsemi.com/thread/252722?ContentTypeID=1</link><pubDate>Tue, 02 Jun 2020 12:17:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ac94da78-c904-41e3-aa0a-0d275eff4eae</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;seems CPU can&amp;#39;t get in time to handle your interrupts. For such a high frequencies, it&amp;#39;s better to use GPIOTE controlled by timer.&amp;nbsp;You can allocate two GPIOTE channels with MODE=Task, POLARITY=Toggle, then configure their toggling from TIMER events via PPI:&lt;/p&gt;
&lt;p&gt;&lt;span&gt;COMPARE[0] --&amp;gt; GPIOTE-&amp;gt;TASKS_OUT[0] and TIMER2-&amp;gt;EVENTS_CLEAR,&amp;nbsp; where CC[0]=frequency&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;COMPARE[1] --&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;GPIOTE-&amp;gt;TASKS_SET[1],&amp;nbsp; where CC[1]=phase&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;COMPARE[2] --&amp;gt;&amp;nbsp;GPIOTE-&amp;gt;TASKS_CLR[1],&amp;nbsp; where CC[2]=(phase+frequency/2)%frequency&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>