<?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 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/67998/nrf52-pulse-duration-counter---going-from-1-micro-second-resolution-to-nano-seconds</link><description>I used the Adafruit Bluefruit NRF52840 LE and added some simple code to this existing timer/counter for pulses: https://devzone.nordicsemi.com/f/nordic-q-a/62633/nrf52-timer-as-counter-adafruit-feather It counts the number of LOW pulses within a certain</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 06 Nov 2020 16:37:08 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/67998/nrf52-pulse-duration-counter---going-from-1-micro-second-resolution-to-nano-seconds" /><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278845?ContentTypeID=1</link><pubDate>Fri, 06 Nov 2020 16:37:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a839982f-91f8-4453-8768-26a7b9131a07</guid><dc:creator>fe7565</dc:creator><description>&lt;p&gt;Thank you, Jorgen.&amp;nbsp; I am happy with that resolution.&amp;nbsp; &amp;nbsp; One more question:&amp;nbsp; this may be for a new thread, but can the systemtick (64 Mhz) used as a Timer base at 15,625 nano seconds ticks?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278835?ContentTypeID=1</link><pubDate>Fri, 06 Nov 2020 16:07:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:838a73f3-4543-47c5-9163-8adfe1b09df5</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>[quote user="fe7565"]So the maximum resolution of the NRF52840 is 62.5 nano sec tick (16 Mhz MCU clock)?[/quote]
&lt;p&gt;Yes, that is correct. The TIMERs runs off the 16 MHz peripheral clock.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278826?ContentTypeID=1</link><pubDate>Fri, 06 Nov 2020 15:13:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cacb81aa-ab7d-449d-88ff-b74bab2b0c0c</guid><dc:creator>fe7565</dc:creator><description>&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;&lt;strong&gt;YES!!! YES!!!!! Works!!!&amp;nbsp;&lt;/strong&gt; &lt;/span&gt;&amp;nbsp;I added the Extern &amp;quot;C&amp;quot;&amp;nbsp; {}&amp;nbsp; &amp;nbsp; &amp;nbsp; Now I get readings of two pulses&amp;#39; timestamps.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I subtracted the first timestamp from the second timestamp and getting 12682 and 12876 values (my input pulses are not super steady).&amp;nbsp; Which seems to translate based on your 1/16 micro sec resolution to 792.625 and 804.75 us.&amp;nbsp; &amp;nbsp;Which is exactly what I was expecting!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So the maximum resolution of the NRF52840 is 62.5 nano sec tick (16 Mhz MCU clock)?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;extern &amp;quot;C&amp;quot;
{
void GPIOTE_IRQHandler(void)
{
  if (NRF_GPIOTE-&amp;gt;EVENTS_IN[GPIOTE_CHANNEL] == 1)    //if an input pulse is detected on pin 6 then...
  {
    NRF_GPIOTE-&amp;gt;EVENTS_IN[GPIOTE_CHANNEL] = 0;     //  reset event detection to zero to ready for next event detection? 
    counts = NRF_TIMER2-&amp;gt;CC[0];                     // save Timer value at same time when signal was read on pin 6
    Serial.println(counts);
  }
}
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278823?ContentTypeID=1</link><pubDate>Fri, 06 Nov 2020 14:54:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6d1072e5-c999-430a-8398-b33f9793fea3</guid><dc:creator>fe7565</dc:creator><description>&lt;p&gt;Jorgen, just noticed your suggestion.&amp;nbsp; Thank you.&amp;nbsp; I will try another pin and see if the use of Pin 6 (being the&amp;nbsp; UART TX pin) maybe the source of the conflict.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278819?ContentTypeID=1</link><pubDate>Fri, 06 Nov 2020 14:44:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a537d36d-440f-444e-b1f6-5cc47836c996</guid><dc:creator>fe7565</dc:creator><description>&lt;p&gt;Thank you for the quick reply. The code compiles without a problem on Arduino IDE, but when I open the Serial COM port, it either does nothing , or freezes the port.&amp;nbsp; &amp;nbsp; I think interrupt issues in the code may not necessarily prompt an error during compiling.&amp;nbsp; &amp;nbsp;I will add in the code:&amp;nbsp; &amp;nbsp;extern &amp;quot;C&amp;quot; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;I am checking into it...&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278807?ContentTypeID=1</link><pubDate>Fri, 06 Nov 2020 14:18:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ad12b655-612f-45fc-8785-41dcb2b8529b</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Not sure how that works in Arduino, or if you are building for a specific board, but by default GPIO P0.06 is used for the UART TX pin on our DKs. If&amp;nbsp;the UART is not configured to use a different pin in your build, the &amp;quot;Serial.begin(115200);&amp;quot; line may interfere with the GPIOTE channel configuration which is set later. Have you tried removing this line, or used a different GPIO for the&amp;nbsp;FREQ_MEASURE_PIN?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278779?ContentTypeID=1</link><pubDate>Fri, 06 Nov 2020 12:54:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2d4406a2-4ac6-48dd-a630-3c1865a96db2</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;I didn&amp;#39;t check the code on hardware, but I don&amp;#39;t see anything missing, of course maybe I forgot something.. What are your results? If you&amp;#39;re using Arduino IDE, there may be issues with interrupt handlers that are already defined in the IDE. I have no experience with&amp;nbsp;Arduino IDE with nRF52, sorry.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278718?ContentTypeID=1</link><pubDate>Fri, 06 Nov 2020 07:36:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b4a55fdd-a77e-4666-aa2b-898bb62289b9</guid><dc:creator>fe7565</dc:creator><description>&lt;p&gt;Sorry for the slow reply.&amp;nbsp; Took me a while with my limited knowledge to digest the information.&amp;nbsp; Thank you very much for the suggestions and the sample code.&amp;nbsp; I incorporated the code above into the original.&amp;nbsp; And&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt; I added comments in the code&amp;nbsp;&lt;/span&gt;&lt;/strong&gt;the best I could understand it.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I suspect that I either missed something or&lt;strong&gt; I did not define the GPIOTE_CHANNEL (number?) correctly.&amp;nbsp;&lt;/strong&gt; I do not have any readings on the Arduino IDE serial port, and it also locks up the port, requiring a manual reset.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I suspect that its very close to correct, but after reading the SDK I was not able to figure what setup or step I missed with the GPIOTE_CHANNEL.&amp;nbsp; Is there a missing link between GPIOTE_EVENT and the TIMER signal detection?&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Just to refresh:&amp;nbsp;&lt;/span&gt; Only two HIGH pulses are coming in about every 3-10 seconds on pin 6.&amp;nbsp; The two pulses are around 800 us (micro sec) apart from each other peak-to-peak.&amp;nbsp; &amp;nbsp;I am hoping to capture the RISING or HIGH level of Pulse 1, and the same with Pulse 2. Then determine the gap between the two pulse tops (the period/interval between the two pulses).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#define FREQ_MEASURE_PIN 6u  // actual PIN 11 on Adafruit Feather Express nRFf52840 LE
#define PPI_CHANNEL 1u
#define GPIOTE_CHANNEL 1   // I just picked channel # as a guess...  Tried 0, 1 , 2, 6

volatile unsigned long counts; //volatile because inside IRQ

void setup() {
  Serial.begin(115200);
  pinMode(LED_RED, OUTPUT);
  initCounter();
}

void loop() 
{  
 //nothing here because IRQHandler does all the work and only when singal is detected
 
}


void GPIOTE_IRQHandler(void)
{
  if (NRF_GPIOTE-&amp;gt;EVENTS_IN[GPIOTE_CHANNEL] == 1)    //if an input pulse is detected on pin 6 then...
  {
    NRF_GPIOTE-&amp;gt;EVENTS_IN[GPIOTE_CHANNEL] = 0;     //  reset event detection to zero to ready for next event detection? 
    counts = NRF_TIMER2-&amp;gt;CC[0];                     // save Timer value at same time when signal was read on pin 6
    Serial.println(counts);
  }
}


void initCounter()
{    
  NRF_P0-&amp;gt;PIN_CNF[FREQ_MEASURE_PIN] = GPIO_PIN_CNF_DIR_Input &amp;lt;&amp;lt; GPIO_PIN_CNF_DIR_Pos |        //sets up PIN 6 for event read
                                      GPIO_PIN_CNF_INPUT_Connect &amp;lt;&amp;lt; GPIO_PIN_CNF_INPUT_Pos |  //pos going signal
                                      GPIO_PIN_CNF_PULL_Pulldown &amp;lt;&amp;lt; GPIO_PIN_CNF_PULL_Pos |   //pulldown LOW so no floating of pin voltage
                                      GPIO_PIN_CNF_SENSE_High &amp;lt;&amp;lt; GPIO_PIN_CNF_SENSE_Pos;      //a HIGH POS signal is the trigger
                                      
  NRF_PPI-&amp;gt;CHEN |= 1 &amp;lt;&amp;lt; PPI_CHANNEL;
  NRF_PPI-&amp;gt;CH[PPI_CHANNEL].EEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;EVENTS_IN[GPIOTE_CHANNEL];
  NRF_PPI-&amp;gt;CH[PPI_CHANNEL].TEP = (uint32_t)&amp;amp;NRF_TIMER2-&amp;gt;TASKS_CAPTURE[0];   //sets up Timer channel

  NRF_GPIOTE-&amp;gt;CONFIG[GPIOTE_CHANNEL] = GPIOTE_CONFIG_MODE_Event &amp;lt;&amp;lt; GPIOTE_CONFIG_MODE_Pos |         //sets up pin for event capture 
                                    FREQ_MEASURE_PIN &amp;lt;&amp;lt; GPIOTE_CONFIG_PSEL_Pos |                   //sets up event capture on pin 6
                                    GPIOTE_CONFIG_POLARITY_LoToHi &amp;lt;&amp;lt; GPIOTE_CONFIG_POLARITY_Pos;   //sets event capture signal trigger type 
                                    
  NRF_GPIOTE-&amp;gt;INTENSET = (1 &amp;lt;&amp;lt; GPIOTE_CHANNEL);    //  Interrupt routine setup on a pin
  NVIC_EnableIRQ(GPIOTE_IRQn);                     //  Interrupt routine setup if signal detected on pin 6

  NRF_TIMER2-&amp;gt;TASKS_STOP = 1;    //stops timer
  NRF_TIMER2-&amp;gt;TASKS_CLEAR = 1;    //clear timer to zero
  NRF_TIMER2-&amp;gt;MODE = TIMER_MODE_MODE_Timer &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;   //sets up TIMEr mode as &amp;quot;Timer&amp;quot;
  NRF_TIMER2-&amp;gt;BITMODE = TIMER_BITMODE_BITMODE_32Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;    // sets values for Timer input
  NRF_TIMER2-&amp;gt;PRESCALER = 0;       //read at max resolution (at MCU speed)
  NRF_TIMER2-&amp;gt;TASKS_START = 1;      // starts the Timer
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52 Pulse Duration Counter - going from 1 micro-second resolution to nano-seconds</title><link>https://devzone.nordicsemi.com/thread/278554?ContentTypeID=1</link><pubDate>Thu, 05 Nov 2020 09:12:22 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:097326eb-54b2-4502-8442-3f8156a2ff0b</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;the best resolution you can achieve is 1/16us. For the maximum accuracy, use the hardware path (GPIOTE-PPI-CAPTURE) instead of software loop. Also don&amp;#39;t confuse GPIOTE and PPI channels - though you can use channels with the same index for both, these are different things.&lt;/p&gt;
&lt;p&gt;The code will look like this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void GPIOTE_IRQHandler(void)
{
  if (NRF_GPIOTE-&amp;gt;EVENTS_IN[GPIOTE_CHANNEL] == 1)
  {
    NRF_GPIOTE-&amp;gt;EVENTS_IN[GPIOTE_CHANNEL] = 0;
    counts = NRF_TIMER2-&amp;gt;CC[0];
    ...
  }
}

void initCounter()
{    
  NRF_P0-&amp;gt;PIN_CNF[FREQ_MEASURE_PIN] = GPIO_PIN_CNF_DIR_Input &amp;lt;&amp;lt; GPIO_PIN_CNF_DIR_Pos |
                                      GPIO_PIN_CNF_INPUT_Connect &amp;lt;&amp;lt; GPIO_PIN_CNF_INPUT_Pos |
                                      GPIO_PIN_CNF_PULL_Pulldown &amp;lt;&amp;lt; GPIO_PIN_CNF_PULL_Pos |
                                      GPIO_PIN_CNF_SENSE_High &amp;lt;&amp;lt; GPIO_PIN_CNF_SENSE_Pos;

  NRF_PPI-&amp;gt;CHEN |= 1 &amp;lt;&amp;lt; PPI_CHANNEL;
  NRF_PPI-&amp;gt;CH[PPI_CHANNEL].EEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;EVENTS_IN[GPIOTE_CHANNEL];
  NRF_PPI-&amp;gt;CH[PPI_CHANNEL].TEP = (uint32_t)&amp;amp;NRF_TIMER2-&amp;gt;TASKS_CAPTURE[0];

  NRF_GPIOTE-&amp;gt;CONFIG[GPIOTE_CHANNEL] = GPIOTE_CONFIG_MODE_Event &amp;lt;&amp;lt; GPIOTE_CONFIG_MODE_Pos |
                                    FREQ_MEASURE_PIN &amp;lt;&amp;lt; GPIOTE_CONFIG_PSEL_Pos |
                                    GPIOTE_CONFIG_POLARITY_LoToHi &amp;lt;&amp;lt; GPIOTE_CONFIG_POLARITY_Pos; 
  NRF_GPIOTE-&amp;gt;INTENSET = (1 &amp;lt;&amp;lt; GPIOTE_CHANNEL);
  NVIC_EnableIRQ(GPIOTE_IRQn);

  NRF_TIMER2-&amp;gt;TASKS_STOP = 1;   
  NRF_TIMER2-&amp;gt;TASKS_CLEAR = 1;
  NRF_TIMER2-&amp;gt;MODE = TIMER_MODE_MODE_Timer &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;
  NRF_TIMER2-&amp;gt;BITMODE = TIMER_BITMODE_BITMODE_32Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;
  NRF_TIMER2-&amp;gt;PRESCALER = 0;
  NRF_TIMER2-&amp;gt;TASKS_START = 1;
}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>