<?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>PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/63091/ppi-auto-reset-timer-in-counter-mode</link><description>The only way I can see to do it is by two separate PPI calls. So Timer1 &amp;quot;tasker&amp;quot; is firing both the capture and clear... but will they execute sequentially?</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 06 Jul 2020 12:11:24 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/63091/ppi-auto-reset-timer-in-counter-mode" /><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/258597?ContentTypeID=1</link><pubDate>Mon, 06 Jul 2020 12:11:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1665fc32-860d-4d29-99f1-e8a4396fdabb</guid><dc:creator>snoopy20</dc:creator><description>&lt;p&gt;yes, and iirc, app_timer is needed for using the softdevice...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/258581?ContentTypeID=1</link><pubDate>Mon, 06 Jul 2020 11:38:38 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b774161a-6040-4f23-ba60-efef18fa72ed</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;RTC 1 is by default used by the app_timer. Perhaps that is what you mean.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/258577?ContentTypeID=1</link><pubDate>Mon, 06 Jul 2020 11:09:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cd6f7129-27a2-4488-bf07-437dc5b88aaa</guid><dc:creator>snoopy20</dc:creator><description>&lt;p&gt;Off the top of my head an application uses nrf52sdk which uses rtc1 to time calls to SoftDevice so although it&amp;#39;s not used per-say it is as good as.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/258559?ContentTypeID=1</link><pubDate>Mon, 06 Jul 2020 09:53:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e30fbecd-d3a0-492b-9dd5-502c79a03a11</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;I don&amp;#39;t know what Softdevice you are using, so I&amp;#39;ll do an educated guess. For the S112, you can check the requirements &lt;a href="https://infocenter.nordicsemi.com/topic/sds_s112/SDS/s1xx/sd_resource_reqs/hw_block_interrupt_vector.html?cp=4_7_0_0_6_0"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;BR,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/258531?ContentTypeID=1</link><pubDate>Mon, 06 Jul 2020 07:53:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c2a99a32-6227-43a4-b3bc-65c860a98279</guid><dc:creator>snoopy20</dc:creator><description>&lt;p&gt;I&amp;#39;m pretty sure the softdevice also uses RTC1 although I can&amp;#39;t recall what for off the top of my head.&lt;br /&gt;&lt;br /&gt;I haven&amp;#39;t tested the approach yet but see no reason why it won&amp;#39;t work. All I&amp;#39;m doing is running a timer at 2Hz and a timer that clocks of an external pulse, so I know how many pulses have occurred every 0.5s.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/257602?ContentTypeID=1</link><pubDate>Tue, 30 Jun 2020 13:20:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4899055f-1377-4721-a346-f9ceb56721d4</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;I don&amp;#39;t think I am able to follow the logic behind the counter mode and the way you are measuring, but is this working?&lt;/p&gt;
&lt;p&gt;If you are using the softdevice, just don&amp;#39;t use the TIMER0 and RTC0 for anything else. The softdevice will use them as well, but you may already know this.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;BR,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/257530?ContentTypeID=1</link><pubDate>Tue, 30 Jun 2020 10:19:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e9b1de3d-0c4b-4a9b-8dbd-573b475ec3ff</guid><dc:creator>snoopy20</dc:creator><description>&lt;p&gt;Here&amp;#39;s my &amp;#39;final&amp;#39; approach (hopefully).&lt;br /&gt;&lt;br /&gt;The tasker timer uses 6 compare points at 0.25s each with a short on 6.&lt;br /&gt;&lt;br /&gt;Compare points 0,2,4 trigger the pulse capture. It has 0.25s to complete in hardware. Plenty I&amp;#39;m sure.&lt;br /&gt;&lt;br /&gt;The tasker timer fires an interrupt on all compares. The compare point is stored, a %2 check determines if the frequency calculation should run (I also use the tasker for other matters).&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;  compareAt++;

  // 0.25s tasks
  // TODO: led patterns

  // 0.5s tasks
  if (compareAt % 2) {
    // TODO: TASKS HERE
    if (compareAt == 6) {
      compareAt = 0;
    }
  }&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;So the capture is always used 0.25s after it&amp;#39;s been fired and the interrupt has 0.25s to fire and complete.&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;  status.motion.frequency = CFG_MOTION_PIF_TIMER-&amp;gt;CC[0] - lastPulseCount; // (frequency is Hz/2)
  lastPulseCount = CFG_MOTION_PIF_TIMER-&amp;gt;CC[0];&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I&amp;#39;ve probably reinvented what the softdevice is already doing with RTC0 or RTC1 but I prefer separation of concerns and I have the timer spare.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/257507?ContentTypeID=1</link><pubDate>Tue, 30 Jun 2020 08:39:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:25c4b961-7d4a-47ae-969d-142917051ece</guid><dc:creator>snoopy20</dc:creator><description>&lt;p&gt;I should be careful with the wording - I&amp;#39;m not doing pulse measurement as the source is inductive/noisy and quite slow (10-200Hz). Instead I have one timer running at 2Hz and another timer counting the amount of pulses resulting in simple division to calculate the frequency. The 2Hz timer triggers the capture on the count timer.&lt;br /&gt;&lt;br /&gt;But your approach will work - set the timer in manual count mode to 32 bit and minus the previous value. I&amp;#39;ll go with this!&lt;br /&gt;&lt;br /&gt;A related question, what&amp;#39;s the difference between TIMER_MODE_LowPowerCounterMode? It says the other (non low power?) mode is depreciated but no details are given.&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;CFG_MOTION_PIF_TIMER-&amp;gt;MODE = TIMER_MODE_MODE_LowPowerCounter &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So my code now with the 32 bit setting is now...&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;inline void MOTION_Init (void) {

  // motion count config; 32 bit, manual clock
  CFG_MOTION_PIF_TIMER-&amp;gt;MODE = TIMER_MODE_MODE_LowPowerCounter &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;
  CFG_MOTION_PIF_TIMER-&amp;gt;BITMODE = TIMER_BITMODE_BITMODE_32Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;

  // motion frequency capture
  NRF_PPI-&amp;gt;CH[CFG_PPI_TASKER_CHANNEL_MOTION_CAPTURE].EEP = CFG_TASKER_PIF_TIMER-&amp;gt;EVENTS_COMPARE[1]; // wire tasker timer compare
  NRF_PPI-&amp;gt;CH[CFG_PPI_TASKER_CHANNEL_MOTION_CAPTURE].TEP = CFG_MOTION_PIF_TIMER-&amp;gt;TASKS_CAPTURE[1]; // wire ppi to timer capture
  NRF_PPI-&amp;gt;CHENSET = 1 &amp;lt;&amp;lt; CFG_PPI_TASKER_CHANNEL_MOTION_CAPTURE_POS;  // enable ppi channel

  // motion pin trigger motion timer count
  NRF_GPIOTE-&amp;gt;CONFIG[CFG_GPIOTE_MOTION_CHANNEL] = (CFG_PIN_MOTION_ZEROCROSS &amp;lt;&amp;lt; GPIOTE_CONFIG_PSEL_Pos) | (GPIOTE_CONFIG_POLARITY_HiToLo &amp;lt;&amp;lt; GPIOTE_CONFIG_POLARITY_Pos) | (GPIOTE_CONFIG_MODE_Event &amp;lt;&amp;lt; GPIOTE_CONFIG_MODE_Pos);
  NRF_PPI-&amp;gt;CH[CFG_PPI_MOTION_CHANNEL_COUNT].EEP = NRF_GPIOTE-&amp;gt;EVENTS_IN[CFG_GPIOTE_MOTION_CHANNEL]; // wire gpio event to ppi
  NRF_PPI-&amp;gt;CH[CFG_PPI_MOTION_CHANNEL_COUNT].TEP = CFG_MOTION_PIF_TIMER-&amp;gt;TASKS_COUNT; // wire ppi to timer count
  NRF_PPI-&amp;gt;CHENSET = 1 &amp;lt;&amp;lt; CFG_PPI_MOTION_CHANNEL_COUNT_POS;  // enable ppi channel
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Note the default timer mode is 16 bit not 24 bit ;)&lt;/p&gt;
&lt;p&gt;The final issue I may have is the 2Hz tasker timer fires the capture of the counter so that it&amp;#39;s ready to be used in the interrupt, but I&amp;#39;m seeing potential for a race between the capture completing and the tasker interrupt executing. I haven&amp;#39;t tested it yet but might need a second compare on the tasker slightly after the first to give the capture time to complete.&lt;br /&gt;&lt;br /&gt;Perhaps in NRF54 there&amp;#39;d be an EVENT_CAPTURE to complement the EVENT_COMPARE. Task/event sequencing would be a nice to have as well.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/257490?ContentTypeID=1</link><pubDate>Tue, 30 Jun 2020 07:15:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:58365846-b613-47ac-937f-7d9276a7b697</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;I see. Yes. For pulse length measurement I would suggest to subtract the previous measurement. If you set the timer in 32bit mode (instead of default 24 bit), you don&amp;#39;t really need to worry about wraparound at all.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;uint32_t a = 0x0000 0001
uint32_t b = 0xFFFF FFFF

uint32_t c = a-b; // c = 0x0000 0002&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;In C programming this operation will automatically wrap around, so as long as the pulse is not longer than one full clock cycle (which is unlikely), you don&amp;#39;t need to worry about the wrap around.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;So you can remove the fork: CFG_MOTION_PIF_TIMER-&amp;gt;TASKS_CLEAR;&lt;/p&gt;
&lt;p&gt;I am a bit confused about your counter mode timer, and how that works in your application, but it may be working. I am just used to seeing a timer being used directly, and capturing the CC of a timer mode timer on a hitolo/lotohi. However, when you read out the capture value, compare it to the previous capture compare value, and this should give the difference. Something like this (pseudo):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;volatile uint32_t prev_capture = 0x00;
volatile uint32_t curr_capture = 0x00;

void timer_interrupt_handler(void)
{
    curr_capture = TIMERX-&amp;gt;CC[1];
    uint32_t diff_capture = curr_capture - prev_capture;
    NRF_LOG_INFO(&amp;quot;diff_capture %08x&amp;quot;, diff_capture);
    prev_capture = curr_capture;
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/257395?ContentTypeID=1</link><pubDate>Mon, 29 Jun 2020 13:03:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dc6c9373-ccd7-42e8-9068-2325472f25b2</guid><dc:creator>snoopy20</dc:creator><description>&lt;p&gt;No, I&amp;#39;m capturing pulses for frequency measurement.&amp;nbsp; The code below may explain better.&lt;br /&gt;&lt;br /&gt;It sounds like PPI or FORK can&amp;#39;t guarantee the logic, so I&amp;#39;ll have to have code to subtract the previous value plus manage a wrap around condition. Best approach?&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;  // tasker fires every 500ms
  
  // motion frequency capture
  NRF_PPI-&amp;gt;CH[CFG_PPI_TASKER_CHANNEL_MOTION_CAPTURE].EEP = CFG_TASKER_PIF_TIMER-&amp;gt;EVENTS_COMPARE[1]; // wire timer compare
  NRF_PPI-&amp;gt;CH[CFG_PPI_TASKER_CHANNEL_MOTION_CAPTURE].TEP = CFG_MOTION_PIF_TIMER-&amp;gt;TASKS_CAPTURE[1]; // wire ppi to timer capture
  NRF_PPI-&amp;gt;FORK[CFG_PPI_TASKER_CHANNEL_MOTION_CAPTURE].TEP = CFG_MOTION_PIF_TIMER-&amp;gt;TASKS_CLEAR; // wire ppi to reset count
  NRF_PPI-&amp;gt;CHENSET = 1 &amp;lt;&amp;lt; CFG_PPI_TASKER_CHANNEL_MOTION_CAPTURE_POS;  // enable ppi channel

  // motion pin
  NRF_GPIOTE-&amp;gt;CONFIG[CFG_GPIOTE_MOTION_CHANNEL] = (CFG_PIN_MOTION_ZEROCROSS &amp;lt;&amp;lt; GPIOTE_CONFIG_PSEL_Pos) | (GPIOTE_CONFIG_POLARITY_HiToLo &amp;lt;&amp;lt; GPIOTE_CONFIG_POLARITY_Pos) | (GPIOTE_CONFIG_MODE_Event &amp;lt;&amp;lt; GPIOTE_CONFIG_MODE_Pos);
  NRF_PPI-&amp;gt;CH[CFG_PPI_MOTION_CHANNEL_COUNT].EEP = NRF_GPIOTE-&amp;gt;EVENTS_IN[CFG_GPIOTE_MOTION_CHANNEL]; // wire gpio event to ppi
  NRF_PPI-&amp;gt;CH[CFG_PPI_MOTION_CHANNEL_COUNT].TEP = CFG_MOTION_PIF_TIMER-&amp;gt;TASKS_COUNT; // wire ppi to timer count
  NRF_PPI-&amp;gt;CHENSET = 1 &amp;lt;&amp;lt; CFG_PPI_MOTION_CHANNEL_COUNT_POS;  // enable ppi channel&lt;/pre&gt;&lt;br /&gt;&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: PPI Auto Reset Timer In Counter Mode</title><link>https://devzone.nordicsemi.com/thread/257373?ContentTypeID=1</link><pubDate>Mon, 29 Jun 2020 12:27:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1d6b42f4-cbc4-4c01-aa94-e941d278f01c</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;If you capture and clear at the same time, then you have a chance of capturing 0. PPI tasks are done by HW directly, so it will not wait for the capture to finish before clearing.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I am not sure exactly what your timer is doing, but often when this question comes up it usually turns out that the clearing of the timer is not strictly necessary. And why do you need to capture when you know the value of the timer? (It clears when it reaches the set value, right?)&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>