<?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>Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/122588/jitter-in-high-priority-thread-loop-with-irq_lock-and-k_sched_lock</link><description>I&amp;#39;ve been working on a custom device utilising the nRF52832 that needs to switch GPIOs in tightly controlled pulses. The problematic section is part of a much larger project written using nRF Connect SDK v2.6.1: 
 
 The code block is the body of an infinite</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 02 Jul 2025 14:10:19 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/122588/jitter-in-high-priority-thread-loop-with-irq_lock-and-k_sched_lock" /><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/541193?ContentTypeID=1</link><pubDate>Wed, 02 Jul 2025 14:10:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cc6741a0-3711-4f89-b7ee-1158fe74197c</guid><dc:creator>lepton-7</dc:creator><description>&lt;p&gt;Gosh that was an embarrassing oversight. Glad I took that issue as a sign to log off for the day. Appreciate all the help you both :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/541103?ContentTypeID=1</link><pubDate>Wed, 02 Jul 2025 05:10:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:74a060c7-5858-401a-857f-4f7d9faff73c</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;This code fails:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define INV(_COMP) (_COMP | 1U &amp;lt;&amp;lt; 16)
STATIC_ASSERT(0x8000 == 1U &amp;lt;&amp;lt; 16,&amp;quot;0x8000 == 1U &amp;lt;&amp;lt; 16 fails&amp;quot;);
STATIC_ASSERT(INV(7) == 0x8007,&amp;quot;INV(7) == 0x8007 fails&amp;quot;);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This code does not fail:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define INV(_COMP) (_COMP | 1U &amp;lt;&amp;lt; 15)
STATIC_ASSERT(0x8000 == 1U &amp;lt;&amp;lt; 15,&amp;quot;0x8000 == 1U &amp;lt;&amp;lt; 15 fails&amp;quot;);
STATIC_ASSERT(INV(7) == 0x8007,&amp;quot;INV(7) == 0x8007 fails&amp;quot;);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Moral: Be Assertive :-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/541100?ContentTypeID=1</link><pubDate>Wed, 02 Jul 2025 04:32:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8521ab25-401c-4ae6-b83f-25a515fe21db</guid><dc:creator>lepton-7</dc:creator><description>&lt;p&gt;I used your example and modified the&amp;nbsp;nrfx_pwm&amp;gt;grouped_mode example to get somewhat of a solution working. I&amp;#39;ve uploaded it to a github repo &lt;a href="https://github.com/lepton-7/individual_mode"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The only issue is that I&amp;#39;m unable to invert PWM polarity:&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/RigolDS1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;The CH2 and CH4 signals should have inverted polarity. This is after I tried setting the POLARITY bit (bit 15) for the COMPARE values loaded from RAM as shown here:&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1751430680010v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#define INV(_COMP) (_COMP | 1U &amp;lt;&amp;lt; 16)

static void set_biphasic_sequence(nrfx_pwm_config_t *conf, nrf_pwm_values_individual_t *arr, uint16_t pw)
{
    uint16_t comp_on = conf-&amp;gt;top_value - get_count_us(conf, pw);
    NRFX_LOG_INFO(&amp;quot;On time COMP: %d&amp;quot;, comp_on);
    NRFX_LOG_INFO(&amp;quot;On time Inverted COMP: %d&amp;quot;, INV(comp_on));
    uint16_t comp_on_dead = conf-&amp;gt;top_value - get_count_us(conf, pw + 2 * DEAD_TIME_US);
    NRFX_LOG_INFO(&amp;quot;On time COMP with deadband: %d&amp;quot;, comp_on_dead);

    uint16_t max = conf-&amp;gt;top_value;
    // arr[0] = (nrf_pwm_values_individual_t){comp_on, comp_on_dead, max, max};
    // arr[1] = (nrf_pwm_values_individual_t){max, max, comp_on, comp_on_dead};
    // arr[2] = (nrf_pwm_values_individual_t){max, max, max, max};

    arr[0] = (nrf_pwm_values_individual_t){comp_on, INV(comp_on_dead), max, INV(max)};
    arr[1] = (nrf_pwm_values_individual_t){max, INV(max), comp_on, INV(comp_on_dead)};
    arr[2] = (nrf_pwm_values_individual_t){max, INV(max), max, INV(max)};
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Any idea what I&amp;#39;m doing wrong? I&amp;#39;m using an&amp;nbsp;nrf52dk_nrf52832 board to test.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/541041?ContentTypeID=1</link><pubDate>Tue, 01 Jul 2025 13:13:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:551ef612-9d02-4e09-bf0b-77aa43e16739</guid><dc:creator>lepton-7</dc:creator><description>&lt;p&gt;If I understand correctly, the snippet you posted requires tying S1/S4 on one pin, and S2/S3 on another?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The GND phases I refer to above aren&amp;#39;t dead times, those are specifically when both low side switches (S2/S4) are turned on so that the positive and negative terminals of the output are both pulled to ground. This is a necessary part of the output terminal behaviour. Do you still think this could be solved by one PWM module?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Both other modules are spoken for: one for a 4kHz buzzer and another the control signal for a boost converter.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/541031?ContentTypeID=1</link><pubDate>Tue, 01 Jul 2025 12:23:48 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:daf75307-227d-412d-949c-cc43bc784e15</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Much simpler solution is to simply use all 4 PWM output pins and no GPIOTE would then be required; a true hardware solution. I have some code which does just this, used as a pulse driver for a pump motor. There are two sequences in the PWM peripheral allowing toggling between sequences which allows the user to change pulse width and pulse frequency without stopping or interrupting the pulse train. Usually with a fixed Dead Band (&amp;quot;Interphase Grounding&amp;quot;) only the pulse frequency is changed and the pulse widths auto-scale; in some cases the pulse frequency is kept constant and the pulse widths are changed allowing power control (think LED dimming). Both are possible with the PWM peripheral. Conceptually using 2 pins with external hardware looks like this (one table for each sequence):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;//  Full or Half H-Bridge PWM - Variable pulsewidth/pulse frequency step lengths
//
//   +----------------------------------&amp;gt; COMP0 OUT[0] Compare 0 - PIN_PWM_S1S4
//   |         +------------------------&amp;gt; COMP1 OUT[1] Compare 1 - PIN_PWM_S2S3
//   |         |         +--------------&amp;gt; COMP2 OUT[2] Compare 2 - PIN_SUPPLY_EN (3 volt power source)
//   |         |         |               (COMP3 OUT[3] Compare 3 not used)
//   |         |         |
// +---------+---------+---------+---------+
// | Compare | Compare | Compare | Top     | Cycle N
// +---------+---------+---------+---------+
// | Compare | Compare | Compare | Top     | Cycle N+1
// +---------+---------+---------+---------+
// | Compare | Compare | Compare | Top     | Cycle N+2
// +---------+---------+---------+---------+
//                                 |
//                                 +----&amp;gt; COUNTERTOP Cycle Period 4 steps, 1MHz clocks. Range 3-32767
//                                       (LOOP       Repeat Count, number of periods - no repeats)
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Using 4 pins requires other than Wave Mode or requires two PWM peripherals in synch. I&amp;#39;ll dig out my code and post later today.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/540979?ContentTypeID=1</link><pubDate>Tue, 01 Jul 2025 08:04:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:eb8d9522-d128-4a8a-8193-5c3c07b1db66</guid><dc:creator>lepton-7</dc:creator><description>&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/members/hmolesworth"&gt;hmolesworth&lt;/a&gt;&amp;nbsp;It was about time I looked deeper than what the Zephyr APIs offer and I am thoroughly impressed by how powerful the PWM, PPI, and TIMER peripherals seem to be. I have an idea that I&amp;#39;d like your opinion on.&lt;/p&gt;
&lt;p&gt;Turns out, if I slightly modify my output signal chain to positive -&amp;gt; GND -&amp;gt; negative -&amp;gt; GND, S2 = ~S1 and S4 = ~S3. Since the frequency and duty cycle is the same across all 4 (ignoring dead time for now) with S3 and S4 just being phase shifted by a known amount, I figured I could use my remaining PWM module to get the signals made. But if I understand correctly based on the &lt;a href="https://docs.nordicsemi.com/bundle/ps_nrf52832/page/pwm.html"&gt;PWM &lt;/a&gt;documentation and this &lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/48884/possible-to-create-pwm-phase-delay"&gt;discussion post&lt;/a&gt;, triggering&amp;nbsp;TASKS_SEQSTART[n] will start the wave counter for every enabled channel and so I will not be able to use PPI to generate a PWM phase delay for channels&amp;nbsp;&lt;em&gt;within&lt;/em&gt; a PWM module, only from one PWM module to the other, correct?&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/stim_5F00_timing.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;If that is indeed the case, how about I setup S1 and S2 as 2 channels of the remaining PWM module operating with an up-and-down wave counter and have S3 and S4 as GPIOTE pins? This way I could set the S2 duty cycle to be slightly larger so I get deadtimes on either side of the S1 enable region.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;EVENTS_SEQSTARTED[0] can then be used to start a TIMER that is already configured with the appropriately calculated CC[n] registers such they can trigger the 4 GPIOTE SET and CLR tasks that are required to form the negative phase and transition into the GND phase for the rest of the PWM period.&lt;/p&gt;
&lt;p&gt;The only other issue I can think of is that&amp;nbsp;EVENTS_SEQSTARTED[0] is only raised at the very start of the PWM module being started, but this can be solved by another TIMER that lasts exactly as long as the PWM period to restart the S3/S4 GPIOTE triggering TIMER.&lt;/p&gt;
&lt;p&gt;Would this then in-fact be an exclusively hardware implementation to drive the H-bridge? Of course every time the user changes the pulse width/pulse frequency I should be able to stop the PWM and clear, reset all the timers, and reconfigure PWM and TIMER registers for the new settings.&lt;/p&gt;
&lt;p&gt;Also, &lt;a href="https://devzone.nordicsemi.com/members/vibe"&gt;Vidar Berg&lt;/a&gt;&amp;nbsp;thanks for linking that example, it helped me understand how I should approach writing this up.&lt;/p&gt;
&lt;p&gt;Please let me know whether this vague plan seems feasible to either of you or if I have a critical misunderstanding of the peripherals.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/540957?ContentTypeID=1</link><pubDate>Tue, 01 Jul 2025 05:53:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2a11bdad-70e8-44b9-9952-e5c3786f0c85</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;I posted an example showing how you can use the nrfx pwm driver in the nRF Connect SDK here:&amp;nbsp;&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/104487/softblink-in-ncs-zephyr/449543"&gt;RE: Softblink in NCS/Zephyr&lt;/a&gt;&amp;nbsp;.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/540934?ContentTypeID=1</link><pubDate>Mon, 30 Jun 2025 20:09:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5df426ee-00d4-4e48-8bb8-c7477d49fcd5</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Only 2 pins are required to drive the H-bridge (1 for S1,4 and 1 for S2,3) if using external logic though 4 pins are preferred for hardware simplicity, and the most important issue is usually to ensure that there is a way to control the dead band (non-overlap) as the drive voltages are not square waves as shown on (say) a logic analyser but instead exponential or linear ramps on both rising and falling edges. Overlap due to thresholds and sloping signals crossing can be catastrophic (shorted motor drivers exploding) or simply a nuisance (unwanted battery power loss). Here are some examples I provided for H-Bridge PWM with dead-bands; might be helpful:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/96200/pwm-interrupts-interrupt-priority-levels/447693"&gt;pwm-interrupts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/55568/how-to-set-up-pwm-dead-time-at-the-end-of-period/225233"&gt;how-to-set-up-pwm-dead-time-at-the-end-of-period&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/540929?ContentTypeID=1</link><pubDate>Mon, 30 Jun 2025 18:13:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6be90f10-80c1-4d9e-8308-6c85f2bd8973</guid><dc:creator>lepton-7</dc:creator><description>&lt;p&gt;Hi Vidar,&lt;/p&gt;
&lt;p&gt;Yes I am using the bluetooth stack in other parts of the code. I did not know that it used zero latency interrupts, thanks for the information!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/540928?ContentTypeID=1</link><pubDate>Mon, 30 Jun 2025 18:10:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fb9c5e5c-65e2-472f-a573-113641b45f7d</guid><dc:creator>lepton-7</dc:creator><description>&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1751303883240v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;The driving circuit is an H-bridge (I&amp;#39;ve pasted a dummy setup I found online; my circuit does not connect to a motor). I have 4 GPIOs going to the 4 switch inputs on the H-bridge arms. These signals have line buffers to avoid overloading the GPIOs.&lt;/p&gt;
&lt;p&gt;So when I call positive_electrodes(), S1 and S4 turn on. Similarly, when I call ground_electrodes(), S2 and S4 are turned on. I used 50us and 10ms times as examples in the code excerpt but I actually need to configure pulse widths between 50us - 500us delivered at 10Hz - 200Hz at runtime based on user input.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;My initial idea when developing this system was to use PWM, but two channels are spoken for already. Plus, I needed the positive and negative pulses to be delivered successively with no overlap. As far as I know there aren&amp;#39;t ways to implement a phase delay between two pins on the same PWM channel (at least in the NCS Zephyr APIs that I&amp;#39;ve checked).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thanks for linking those threads, I took a look and they definitely are interesting. I haven&amp;#39;t interacted with the PPI or EGU so I&amp;#39;ll do some homework to see if those could imply a solution. Thanks!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/540836?ContentTypeID=1</link><pubDate>Mon, 30 Jun 2025 10:46:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4bbbc918-cde2-469c-8553-e45ebf755619</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;I would also recommend checking&amp;nbsp;if it&amp;#39;s possible to handle this in hardware without CPU involvement as &lt;a href="https://devzone.nordicsemi.com/members/hmolesworth"&gt;hmolesworth&lt;/a&gt;&amp;nbsp; suggested. Since you&amp;#39;re&amp;nbsp;seeing this issue with IRQ locking, I assume you&amp;#39;re using one of our wireless protocol stacks, which use &lt;a href="https://docs.nordicsemi.com/bundle/ncs-3.0.1/page/zephyr/kernel/services/interrupts.html#zero_latency_interrupts"&gt;zero latency interrupts&lt;/a&gt; (not disabled by IRQ locks) to ensure that timing critical protocol events are processed on time. These will preempt any running application thread.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/540798?ContentTypeID=1</link><pubDate>Mon, 30 Jun 2025 01:29:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e1320fc7-f922-41e4-84b7-4d454a0e4bce</guid><dc:creator>LatoyaJGreiner</dc:creator><description>&lt;p&gt;What a great explanation! I really appreciate you updating this thread&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#ffffff;"&gt;&lt;a style="color:#ffffff;" href="https://blockyblast.io"&gt;block blast&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Jitter in high priority thread loop with irq_lock and k_sched_lock</title><link>https://devzone.nordicsemi.com/thread/540783?ContentTypeID=1</link><pubDate>Fri, 27 Jun 2025 23:55:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:668227ca-2cac-4768-b89e-34cf5ad116d6</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Was there a reason to not just use hardware PWM to drive the GPIO? The pulses would then have no jitter; if code is required for each part of the pulse or some parts of the pulse the EGU could be used to generate interrupts which would handle any semaphores and the like; no need for thread interaction for the actual pulse timing.&lt;/p&gt;
&lt;p&gt;Maybe share the driving circuit for the electrodes; a 4-output PWM can control the &lt;em&gt;Pos-Float-neg-ground&lt;/em&gt; phases by selectively setting each of the 4 outputs to (say) H1D0, D1D0, H0D1, H1D0 but need to see how the outputs are driven to confirm. It is possible to use more than one PWM synchronously with 0nSec phase delay as well as no jitter. I provide an example here; the nRF52832 is simple but the changed PWM implementation on the nRF52833 required slightly different code:&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/108397/pwm-anomaly-nrf52832-vs-nrf52833"&gt;pwm-anomaly-nrf52832-vs-nrf52833&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/108184/start-pwms-synchronous"&gt;start-pwms-synchronous&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>