<?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>TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/6687/timer1-with-ppi-to-gpiote</link><description>I&amp;#39;m trying to repeatedly toggle a GPIOTE on every CC[0] compare within the time period set by CC[1]. CC[1] runs multiple times. Every time CC[1] is reached I want to stop the CC[0] compare, check if I&amp;#39;ve sent a certain number of toggles and if so, stop</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 27 Apr 2015 18:49:54 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/6687/timer1-with-ppi-to-gpiote" /><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23459?ContentTypeID=1</link><pubDate>Mon, 27 Apr 2015 18:49:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5800f028-38aa-4106-b078-780f30ceeb2c</guid><dc:creator>LS</dc:creator><description>&lt;p&gt;Found this in the release notes for S110 version 8.0, &amp;quot;The default behaviour is now that the application can use the CPU while the radio is active. In previous versions of the S110, the CPU execution was blocked by the SoftDevice during radio activity.&amp;quot; I was using S110 V7.1, so I&amp;#39;m updating to 8.0.&lt;/p&gt;
&lt;p&gt;I believe your third method is the correct approach. I can&amp;#39;t implement it with my project, because TIMER2 is being used to time other events that start before TIMER1 and end after TIMER1 is stopped. So I&amp;#39;m going to implement method 2 and relax the smallest timing constraints to see if that works.&lt;/p&gt;
&lt;p&gt;In case it helps anyone, I received another suggestion to connect an SPI channel to my GPIOTE pin and send the bit toggling pattern as bytes through SPI. This would allow me to set the speed fast enough, and control the on/off time with 1s and 0s. We may experiment with this approach in the future.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23455?ContentTypeID=1</link><pubDate>Fri, 24 Apr 2015 07:15:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a098a58c-aa55-4bdf-86b8-edbb4fbaf520</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;you said&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Every time CC[1] is reached I want to stop the CC[0] compare, check if I&amp;#39;ve sent a certain number of toggles and if so, stop TIMER1, else I&amp;#39;ll re-enable the CC[0] compare and continue running
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;but you are not stopping CC[0] compare, you are just disabling its interrupt, the event will be generated anyways and through PPI and GPIOTE it will toggle the pin. Instead of just disabling the interrupt at this time, you need to also disable that compare event.
you are doing things in few microseconds, yes you are very close to check its limits.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23458?ContentTypeID=1</link><pubDate>Fri, 24 Apr 2015 01:47:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:33bdddfb-6975-48cb-8f7f-1494e449143f</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;25/5 = 5microseconds = 80 clock cycles. That is probably right on the limit, it&amp;#39;s what I guessed above. 50 for the softdevice overhead, 16 for the cortex interrupt. If you absolutely can guarantee there&amp;#39;s nothing else will interrupt you then making your IRQ handler more efficient (no debug compile, remove the unecessary sets of the compare events to zero) you may get away with it .. or try the second method where you schedule the extra PPI to turn off the counter on the last cycle, that buys you 20 microseconds.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23457?ContentTypeID=1</link><pubDate>Fri, 24 Apr 2015 01:36:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1e8418cb-4f74-400a-bf1e-92bd3b84dc8f</guid><dc:creator>LS</dc:creator><description>&lt;p&gt;Thank you for the very detailed response! I&amp;#39;m using a period of 25 microseconds, and sub_period is equal to the period divided by a value from 1 to 5. I think I&amp;#39;m pushing the limits with such small timer increments. The softdevice broadcaster is only called after this cycle is complete, but it may still be affecting the timing. Let me discuss your recommendations with my team and see what we can do!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23454?ContentTypeID=1</link><pubDate>Fri, 24 Apr 2015 01:27:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8b4616b1-038b-4019-b097-a53aed38628f</guid><dc:creator>LS</dc:creator><description>&lt;p&gt;The period I have to use is fixed at 25 microseconds. The sub_period varies and is equal to period divided by a number from 1 to 5. I&amp;#39;m thinking I might be pushing the limits of the microcontroller since I only have a 16MHz clock.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23456?ContentTypeID=1</link><pubDate>Fri, 24 Apr 2015 00:27:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0b97e9fa-ac93-4979-9a2b-ac30039490d6</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;I&amp;#39;m assuming that sub_period &amp;lt; period.&lt;/p&gt;
&lt;p&gt;As soon as CC[1] triggers, that clears the timer (via PPI) and you have only subperiod ticks until the CC[0] compare is going to trigger the next toggle. I would assume you see this issue mostly when subperiod is small, close to zero, what kind of numbers are you using for subperiod and period?&lt;/p&gt;
&lt;p&gt;What&amp;#39;s likely is that indeed TIMER1_IRQ doesn&amp;#39;t get run before the timer hits CC[0] again and you get the extra toggle. The softdevice performs regular interrupts and blocks other things happening for up to milliseconds at a time. The more the softdevice is doing, the longer it blocks things for (eg doing nothing does very little, advertising does something, sending data in a connection you can get some very long blocks). Even just having the softdevice loaded and disabled adds 50 cycles to the interrupt start time. I would estimate that in the code above with a softdevice on the chip, the interrupt + the softdevice overhead + the code before you disable the timer is around 80 cycles. That&amp;#39;s the best case if the SD isn&amp;#39;t servicing its own high priority interrupt when TIMER1 is raised, the worst case is milliseconds.&lt;/p&gt;
&lt;p&gt;You gave TIMER1 an interrupt priority of 3, you could raise that to 1, but if you&amp;#39;re talking the kind of microsecond timings you mention, as soon as you start doing things with the softdevice even at priority 1 on the interrupt you&amp;#39;re going to have that interrupt delayed, quite possibly by enough to get several toggles of the pin before you turn it off.&lt;/p&gt;
&lt;p&gt;Relying on interrupts for any kind of precise timing when the softdevice is running really doesn&amp;#39;t work, not unless you&amp;#39;re talking times of the order of 10s of milliseconds or more. Basically assume that TIMER1 interrupt can be delayed by up to 4ms in the worst cases.&lt;/p&gt;
&lt;p&gt;Things you could try:&lt;/p&gt;
&lt;p&gt;Raise the TIMER1 interrupt priority to 1 - but that&amp;#39;s not going to work&lt;/p&gt;
&lt;p&gt;Add another PPI channel to stop the timer on CC[1] compare which you only enable in the TIMER1 interrupt one cycle &lt;em&gt;before&lt;/em&gt; remainingToggles is 0.  So the final toggle also turns off the timer. That will work better, especially if the period value is close to 0xffff, but will still glitch in the worst case. The lower &amp;#39;period&amp;#39; is, the worse it will glitch.&lt;/p&gt;
&lt;p&gt;Use TIMER2 in count up mode triggered by CC[1] compare using another PPI, clear it, load its compare with the number of toggles you want and set up yet another PPI to stop TIMER1 when you get the compare. Now you have a solution entirely within PPI which should be immune to interrupts, at the cost of 2 timers and 4 PPIs.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23453?ContentTypeID=1</link><pubDate>Fri, 24 Apr 2015 00:15:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2678824f-71a7-45b8-a5e9-26c69c4741e3</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;What are the values of your period and sub_period?&lt;/p&gt;
&lt;p&gt;in your timer_check(), the first thing I would do inside the if statement would be to disable the timer, I think shutdown takes longer than disable. after this i would disable PPI and GPIOTE.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23452?ContentTypeID=1</link><pubDate>Thu, 23 Apr 2015 22:42:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c3f90a80-8002-4cd7-b591-75f902b4fbc8</guid><dc:creator>Nick Pelis</dc:creator><description>&lt;p&gt;But you&amp;#39;ve already incurred that overhead just by having TIMER1_IRQHandler() exist.  To set a bit in NRF_GPIO-&amp;gt;OUTSET is probably only a few instructions--an LDR to contain the new bit pattern, another LDR to contain the base address of NRF_GPIO, and an STR to store the new bit pattern at the offset in NRF_GPIO where the OUTSET field is.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23451?ContentTypeID=1</link><pubDate>Thu, 23 Apr 2015 22:24:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:233b885a-651d-4741-9a17-844aad6f4035</guid><dc:creator>LS</dc:creator><description>&lt;p&gt;My timer period is in microseconds and the time between toggles could be in nanoseconds. So ideally I&amp;#39;d like to avoid the overhead of toggling the pin in software, to get the most precise timing possible. If it&amp;#39;s not possible to prevent the extra toggle I&amp;#39;m seeing, I may do it through software to guarantee the proper sequence.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TIMER1 with PPI to GPIOTE</title><link>https://devzone.nordicsemi.com/thread/23450?ContentTypeID=1</link><pubDate>Thu, 23 Apr 2015 22:14:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:323a1acc-8c88-4db7-a46e-bd7b7c25fca9</guid><dc:creator>Nick Pelis</dc:creator><description>&lt;p&gt;What&amp;#39;s the reasoning behind having hardware toggle the pin, instead of software?  You could insert code into the else clause of your if() statement in timer_check() which toggles the pin instead.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>