<?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>GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/83280/gpio-toggling-frequency</link><description>Hi, 
 I am toggling a GPIO using the below code and trying to find out the relation of the frequency and the code statements. I know that GPIO peripheral is running at 16MHz and I have added the &amp;#39;nop&amp;#39; instructions to make sure that the changes take effect</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 03 Jan 2022 21:58:14 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/83280/gpio-toggling-frequency" /><item><title>RE: GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/thread/345763?ContentTypeID=1</link><pubDate>Mon, 03 Jan 2022 21:58:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:933d1c27-38eb-43f8-a0ab-d1791211884b</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Yes avoiding &lt;em&gt;while(1)&lt;/em&gt; delay works; cache also speeds up to 8MHz&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;    // Enable cache and hit/miss tracking
    while(NRF_NVMC-&amp;gt;READY == 0) ;
    NRF_NVMC-&amp;gt;ICACHECNF = 0x101;
    while(1)
    {
        NRF_P0-&amp;gt;OUTSET = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTCLR = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTSET = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTCLR = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTSET = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTCLR = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTSET = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTCLR = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTSET = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
        NRF_P0-&amp;gt;OUTCLR = 1UL &amp;lt;&amp;lt; SCOPE_PROBE_2;
    }&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/thread/345761?ContentTypeID=1</link><pubDate>Mon, 03 Jan 2022 21:46:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:45ef5885-4f71-40cb-95f5-9b59ec485c81</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;__DSB() causes the MPU to wait until the port write high instruction completes, which although the port pin 16MHz clock is synchronous to the instruction 64MHz clock the two may be out-of-phase with the port action depending on previous instructions, and the state of the instruction pipeline. Let&amp;#39;s say that takes 62.5nSec + n = 72 nSecs where 62.5 nSec is a single cycle at 16MHz. Same for the port write low. What next? A jump instruction, as&amp;nbsp; you are using a &lt;em&gt;while(1)&lt;/em&gt; loop. That may be taking (122-72) - 60 nSecs to complete.&lt;/p&gt;
&lt;p&gt;Prove this by a series of port set high / reset low instructions and then see what timing you get. 100 such high/low pairs in the while(1) loop might be closer to (72+72)x100 nSecs or perhaps slightly better.&lt;/p&gt;
&lt;p&gt;Finally results assume the crystal-derived HFCLK is enabled. Enabling instruction cache will change from 2 wait states to 0 wait states in the instruction timing, though in this loop that may not change timing, I&amp;#39;d have to check in the ARM Cortex-M4 manual.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you really want 8MHz use the hardware PWM peripheral which can give 8MHz max rate, no timing issues&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/thread/345747?ContentTypeID=1</link><pubDate>Mon, 03 Jan 2022 16:59:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:670509a5-8db0-4411-8a37-de4e29e1a980</guid><dc:creator>kizhimon</dc:creator><description>&lt;p&gt;I have changed it to DSB and the timing now is as given below. Could you please explain me how to derive 72 ns and 50 ns from the code ? How many CPU cycles does DSB take ?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1641228954946v1.png" alt=" " /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/thread/345734?ContentTypeID=1</link><pubDate>Mon, 03 Jan 2022 16:17:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bd347e12-1c44-4d23-8473-404c9216a910</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;I would recommend &lt;em&gt;__DSB()&lt;/em&gt; instead of &lt;em&gt;__ISB()&lt;/em&gt;; don&amp;#39;t care about the instruction cache just peripheral memory access fully completing&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/**
  \brief   Data Synchronization Barrier
  \details Acts as a special kind of Data Memory Barrier.
           It completes when all explicit memory accesses before this instruction complete.
 */
// Ensure all explicit memory accesses before this instruction complete - avoid inline definition as a function
#define __DSB() __ASM volatile (&amp;quot;dsb 0xF&amp;quot;:::&amp;quot;memory&amp;quot;)&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/thread/345698?ContentTypeID=1</link><pubDate>Mon, 03 Jan 2022 14:20:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:83cde668-c369-4000-97b4-9f324b5a7ff5</guid><dc:creator>kizhimon</dc:creator><description>&lt;p&gt;Here is it:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;while(1)&lt;/code&gt;&lt;br /&gt;&lt;code&gt;{&lt;/code&gt;&lt;br /&gt;&lt;code&gt;NRF_P0-&amp;gt;OUTSET = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F8C32508 str.w r2, [r3, #0x0508]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F3BF8F6F isb&lt;/code&gt;&lt;br /&gt;&lt;code&gt;NRF_P0-&amp;gt;OUTCLR = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F8C3250C str.w r2, [r3, #0x050C]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F3BF8F6F isb&lt;/code&gt;&lt;br /&gt;&lt;code&gt;NRF_P0-&amp;gt;OUTSET = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F8C32508 str.w r2, [r3, #0x0508]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F3BF8F6F isb&lt;/code&gt;&lt;br /&gt;&lt;code&gt;NRF_P0-&amp;gt;OUTCLR = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F8C3250C str.w r2, [r3, #0x050C]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F3BF8F6F isb&lt;/code&gt;&lt;br /&gt;&lt;code&gt;NRF_P0-&amp;gt;OUTSET = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F8C32508 str.w r2, [r3, #0x0508]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F3BF8F6F isb&lt;/code&gt;&lt;br /&gt;&lt;code&gt;NRF_P0-&amp;gt;OUTCLR = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F8C3250C str.w r2, [r3, #0x050C]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F3BF8F6F isb&lt;/code&gt;&lt;br /&gt;&lt;code&gt;NRF_P0-&amp;gt;OUTSET = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F8C32508 str.w r2, [r3, #0x0508]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F3BF8F6F isb&lt;/code&gt;&lt;br /&gt;&lt;code&gt;NRF_P0-&amp;gt;OUTCLR = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F8C3250C str.w r2, [r3, #0x050C]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; F3BF8F6F isb&lt;/code&gt;&lt;br /&gt;&lt;code&gt; E7DE b 0x0001A142&lt;/code&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/thread/345696?ContentTypeID=1</link><pubDate>Mon, 03 Jan 2022 14:16:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0397dec9-2a96-4183-92d0-758377ba670b</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Can you post the generated assembly code for this code you made with the __ISB?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/thread/345681?ContentTypeID=1</link><pubDate>Mon, 03 Jan 2022 13:28:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:14414ff6-a90e-4608-8c04-877ae33a949a</guid><dc:creator>kizhimon</dc:creator><description>&lt;p&gt;thank you for your reply.&lt;/p&gt;
&lt;p&gt;I have replaced NOP by ISB as given below.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; NRF_P0-&amp;gt;OUTSET = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; NRF_P0-&amp;gt;OUTCLR = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; NRF_P0-&amp;gt;OUTSET = 0x04000000;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;__ISB();&lt;/code&gt;&lt;br /&gt;&lt;code&gt; NRF_P0-&amp;gt;OUTCLR = 0x04000000;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This is what I see in analyser now.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1641215641933v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;It is taking ~178ns to change the state from high to low.&lt;/p&gt;
&lt;p&gt;__ISB() takes four processor cycles = (1/(64 * 10^6)) * 4 =&amp;nbsp; 62.5 ns&lt;/p&gt;
&lt;p&gt;str.w r2, [r3, #0x050C] --&amp;gt; This is the instruction to change the pin state to low. Does this instruction consume the remaining time of&amp;nbsp;115.5&amp;nbsp;ns (178 - 62.5) ?&lt;/p&gt;
&lt;p&gt;Is this how it works or am I missing anything ?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: GPIO toggling frequency</title><link>https://devzone.nordicsemi.com/thread/345663?ContentTypeID=1</link><pubDate>Mon, 03 Jan 2022 12:45:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cbdefad2-7701-4a16-9ed5-4042517dcf4b</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;&lt;a href="https://developer.arm.com/documentation/dui0497/a/the-cortex-m0-instruction-set/miscellaneous-instructions/nop?lang=en"&gt;NOP is not guaranteed to be time consuming&lt;/a&gt;&amp;nbsp;and also discussed &lt;a href="https://stackoverflow.com/questions/41790296/isb-instruction-in-arm-cortex-m"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have seen what you see many times and the lesson I learnt is NOT to rely on NOP for very time sensitive delays.&lt;/p&gt;
&lt;p&gt;You can for example use ISB to create 4 processor cycles of delay to fill the pipeline or you can actually write some ASM code using other dummy arithmetic operation for a very predictable halt of logic in your code, but do not rely on NOP alone as that wont give you predictable delays.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>