<?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>nordic NRF51822 + PWM + PPI + TIMER1</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/45182/nordic-nrf51822-pwm-ppi-timer1</link><description>Hello, 
 I want to make a PWM signal that fires an interrupt at the end of the PWM period. I want to use two CC registers - one for the pulse width and one for the period width. On compare event I want to trigger one task that sets and another that clears</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 22 Mar 2019 11:11:55 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/45182/nordic-nrf51822-pwm-ppi-timer1" /><item><title>RE: nordic NRF51822 + PWM + PPI + TIMER1</title><link>https://devzone.nordicsemi.com/thread/177803?ContentTypeID=1</link><pubDate>Fri, 22 Mar 2019 11:11:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:27815c0c-beb4-4a11-b299-44e2ec1a8d67</guid><dc:creator>L.B.</dc:creator><description>&lt;p&gt;Hello! This solved my answer! And the code you suggested works as expected. Thank you!&lt;/p&gt;
&lt;p&gt;Indeed in the datasheet I saw this line:&lt;/p&gt;
&lt;p&gt;Only one GPIOTE channel can be assigned to one physical pin. Failing to do so may result in unpredictable&lt;br /&gt;behavior.&lt;/p&gt;
&lt;p&gt;but I was unable to quite get it at that time. Now makes sense ...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nordic NRF51822 + PWM + PPI + TIMER1</title><link>https://devzone.nordicsemi.com/thread/177605?ContentTypeID=1</link><pubDate>Thu, 21 Mar 2019 14:02:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e8b951df-a31d-4a9c-8f99-26fdadb48256</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;It&amp;#39;s not possible to assign the same pin to two GPIOTE channels, so that&amp;#39;s probably why it&amp;#39;s not working. But it should be possible to use the toggle task instead with one channel. Here&amp;#39;s a slightly modified version of your code:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void TIMER1_IRQHandler(){
    //NVIC_ClearPendingIRQ(TIMER1_IRQn);
   // NRF_TIMER1-&amp;gt;EVENTS_COMPARE[0] = 0;
    //if(NRF_TIMER1-&amp;gt;EVENTS_COMPARE[1]){ // No other compare events enabled
        //One PWM period has elapsed
        NRF_TIMER1-&amp;gt;EVENTS_COMPARE[1] = 0;
        //NRF_TIMER1-&amp;gt;TASKS_CLEAR = 1;
        pwm_triggers++;
    //}
}

void pwm_init(void){
    NRF_GPIOTE-&amp;gt;CONFIG[0] = (0x03 | (25 &amp;lt;&amp;lt; 8) | (0x3 /*toggle*/ &amp;lt;&amp;lt; 16) | (0x01 &amp;lt;&amp;lt; 20)); //Make GPIO a task, use pin 25, task sets pin high, init as pin high, 0x111903
//    NRF_GPIOTE-&amp;gt;CONFIG[1] = (0x03 | (27 &amp;lt;&amp;lt;8)  | (0x02 &amp;lt;&amp;lt; 16) | (0x01  &amp;lt;&amp;lt; 20)); //Make GPIO a task, use pin 25, task sets pin low, init as pin low, 0x21903
    
    //NRF_PPI-&amp;gt;CHG[0] |= 0x03; // Grouping was not used
    NRF_PPI-&amp;gt;CH[0].EEP = (uint32_t)&amp;amp;NRF_TIMER1-&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;CH[1].EEP = (uint32_t)&amp;amp;NRF_TIMER1-&amp;gt;EVENTS_COMPARE[1];
    NRF_PPI-&amp;gt;CH[1].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[0];
    NRF_PPI-&amp;gt;CHEN |= 0x03;

    //NRF_TIMER1-&amp;gt;POWER = 0x01;
    NRF_TIMER1-&amp;gt;TASKS_CLEAR = 1;
    NRF_TIMER1-&amp;gt;MODE = 0; //Timer mode
    NRF_TIMER1-&amp;gt;BITMODE = 0x01; //8-bit
    NRF_TIMER1-&amp;gt;PRESCALER = 0; //Prescaler = /1
    NRF_TIMER1-&amp;gt;SHORTS = 2; //	Enable COMPARE1_CLEAR to clear timer on CC[1] match 
    NRF_TIMER1-&amp;gt;CC[0] = 1; 
    NRF_TIMER1-&amp;gt;CC[1] = 20;

    while(NRF_TIMER1-&amp;gt;CC[0] != 1){ }
    while(NRF_TIMER1-&amp;gt;CC[1] != 20){ }

    NRF_TIMER1-&amp;gt;INTENSET = 1 &amp;lt;&amp;lt; 17; //Enable interrupt on compare register  1. Event 0 appears to be ignored anyway
    NVIC_SetPriority(TIMER1_IRQn, 3);
    NVIC_ClearPendingIRQ(TIMER1_IRQn);
    NVIC_EnableIRQ(TIMER1_IRQn);
    NRF_TIMER1-&amp;gt;TASKS_START = 1;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Can you try and see if works?&lt;/p&gt;
[quote userid="77810" url="~/f/nordic-q-a/45182/nordic-nrf51822-pwm-ppi-timer1"]With the debugger I see that the interrupt never exits because the COMPARE_EVENT[1] is set whenever COMPARE_EVENT[0] is set, which is not expected.[/quote]
&lt;p&gt;The debugger only halts the CPU while the timers are kept running. So it is impossible to read out compare event 0 before compare event 1 manually.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Just a warning, it starts to become complicated as soon as you want to update the duty cycle on the fly. If that&amp;#39;s something you intend to do, you should consider modifying the existing PWM library instead.&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>