<?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>Safely updating duty cycle values during playback</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/85408/safely-updating-duty-cycle-values-during-playback</link><description>The NRF documentation for nrf_pwm_sequence_t says: 
 When the sequence is set (by a call to nrf_pwm_sequence_set), the provided duty cycle values are not copied. The values pointer is stored in the internal register of the peripheral, and the values are</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 08 Mar 2022 15:17:50 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/85408/safely-updating-duty-cycle-values-during-playback" /><item><title>RE: Safely updating duty cycle values during playback</title><link>https://devzone.nordicsemi.com/thread/356954?ContentTypeID=1</link><pubDate>Tue, 08 Mar 2022 15:17:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f6f107e7-e243-45de-b84c-2dab2d658747</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello again,&amp;nbsp;&lt;/p&gt;
[quote user="Andy Gould"]Thanks for the update.[/quote]
&lt;p&gt;No problem at all, I am happy to help!&lt;/p&gt;
[quote user="Andy Gould"]Is the only way to do this using NRFX, to cache the new values until that&amp;nbsp;NRFX_PWM_EVT_END_SEQ0/1 occurs, and then update then?&amp;nbsp;[/quote]
&lt;p&gt;Yes, this is how you should do this, update the sequence as part of the END_SEQ event handling. The&amp;nbsp;&lt;em&gt;NRFX_PWM_EVT_FINISHED&lt;/em&gt;&lt;span&gt;&amp;nbsp;event will only be generated once a sequence playback has completed the specified number of times - generated when the LOOPSDONE event has been generated - while the SEQEND events are generated for each sequence end.&lt;/span&gt;&lt;/p&gt;
[quote user="Andy Gould"]I presume that the safe window is defined as between SEQSTARTED and SEQEND?[/quote]
&lt;p&gt;No, that would be the unsafe window - the values should not be changed between SEQSTARTED and SEQEND, instead it should be between SEQEND and SEQSTARTED.&lt;/p&gt;
[quote user="Andy Gould"]&lt;p&gt;But these events are not available in NRFX?&lt;/p&gt;
&lt;p&gt;Is there a reason why some of these events are not exposed at the NRFX layer?&lt;/p&gt;[/quote]
&lt;p&gt;These events are not exposed to the application layer, no - they are used by the driver directly, and then the driver will forward relevant NRFX events to the application layer event handler based on these. These&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Safely updating duty cycle values during playback</title><link>https://devzone.nordicsemi.com/thread/356840?ContentTypeID=1</link><pubDate>Tue, 08 Mar 2022 10:40:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:561d73bc-8e11-415e-8e69-e9128be93f6f</guid><dc:creator>Andy Gould</dc:creator><description>&lt;p&gt;Thanks for the update. What I am not clear on, is at what point it becomes unsafe to change the values.... So. If I have an external trigger ( for example, an ADC read), that provides values for the PWM duty cycle, and when it completes, I want to update the PWM duty cycles. I know that the &lt;em&gt;NRFX_PWM_EVT_END_SEQ0&lt;/em&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;or&amp;nbsp;&lt;em&gt;NRFX_PWM_EVT_END_SEQ1&lt;/em&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;Indicates that it is safe to update the values, but I&amp;#39;m not clear what event I should subscribe to that indicates that it is unsafe.&amp;nbsp;&lt;a title="nrfx_pwm_evt_type_t" href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.0.0/group__nrfx__pwm.html?cp=8_5_4_6_9_0_12_1_8#ga3bd252a13f482085e89e23516b8a422a"&gt;nrfx_pwm_evt_type_t&lt;/a&gt;&amp;nbsp; only contains&amp;nbsp;&lt;/p&gt;
&lt;table class="fieldtable"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="2" rowspan="1"&gt;Enumerator&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga3bd252a13f482085e89e23516b8a422aa087e425c2519f35f5db0b0a85222406f"&gt;&lt;/a&gt;NRFX_PWM_EVT_FINISHED&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;Sequence playback finished.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga3bd252a13f482085e89e23516b8a422aa9548867c6bb75600cd7fb219b868fe30"&gt;&lt;/a&gt;NRFX_PWM_EVT_END_SEQ0&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;End of sequence 0 reached. Its data can be safely modified now.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga3bd252a13f482085e89e23516b8a422aaa9dc1447d439ba09dedc954f66768957"&gt;&lt;/a&gt;NRFX_PWM_EVT_END_SEQ1&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;End of sequence 1 reached. Its data can be safely modified now.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga3bd252a13f482085e89e23516b8a422aa38d857ec1e12fe4a6091734678a3869a"&gt;&lt;/a&gt;NRFX_PWM_EVT_STOPPED&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;The PWM peripheral has been stopped.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And &lt;em&gt;NRFX_PWM_EVT_FINISHED&lt;/em&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;appears to occur at the same time as &lt;em&gt;NRFX_PWM_EVT_END_SEQ0/1.&amp;nbsp;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Is the only way to do this using NRFX, to cache the new values until that&amp;nbsp;NRFX_PWM_EVT_END_SEQ0/1 occurs, and then update then?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt;&lt;/span&gt;&lt;/em&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I notice that NRF has a more compete set of events:&lt;/p&gt;
&lt;table class="fieldtable"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th colspan="2" rowspan="1"&gt;Enumerator&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga4a8ceac653433e4ac8ee8682bdef45bfadf20e481b3105e4ef6e6f80423c8192b"&gt;&lt;/a&gt;NRF_PWM_EVENT_STOPPED&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;Response to STOP task, emitted when PWM pulses are no longer generated.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga4a8ceac653433e4ac8ee8682bdef45bfaa5bb09f0669ce66b58053dd382a3bcbf"&gt;&lt;/a&gt;NRF_PWM_EVENT_SEQSTARTED0&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;First PWM period started on sequence 0.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga4a8ceac653433e4ac8ee8682bdef45bfa79aea4fc8f7e536c180a1b5b4c9a2596"&gt;&lt;/a&gt;NRF_PWM_EVENT_SEQSTARTED1&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;First PWM period started on sequence 1.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga4a8ceac653433e4ac8ee8682bdef45bfa60bc770e86e8c3e1987b7828c5527e3b"&gt;&lt;/a&gt;NRF_PWM_EVENT_SEQEND0&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;Emitted at the end of every sequence 0 when its last value has been read from RAM.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga4a8ceac653433e4ac8ee8682bdef45bfa250b4184e07ce53864c00aa17f142c3e"&gt;&lt;/a&gt;NRF_PWM_EVENT_SEQEND1&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;Emitted at the end of every sequence 1 when its last value has been read from RAM.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga4a8ceac653433e4ac8ee8682bdef45bfa2340304c4d850deee64456310c272d13"&gt;&lt;/a&gt;NRF_PWM_EVENT_PWMPERIODEND&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;Emitted at the end of each PWM period.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="fieldname" colspan="1" rowspan="1"&gt;&lt;em&gt;&lt;a class="anchor" id="gga4a8ceac653433e4ac8ee8682bdef45bfa904f95da3dc44a8e147623f4ae32a268"&gt;&lt;/a&gt;NRF_PWM_EVENT_LOOPSDONE&lt;/em&gt;&amp;nbsp;&lt;/td&gt;
&lt;td class="fielddoc" colspan="1" rowspan="1"&gt;
&lt;p&gt;Concatenated sequences have been played the requested number of times.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I presume that the safe window is defined as between SEQSTARTED and SEQEND? But these events are not available in NRFX?&lt;/p&gt;
&lt;p&gt;Is there a reason why some of these events are not exposed at the NRFX layer?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Safely updating duty cycle values during playback</title><link>https://devzone.nordicsemi.com/thread/356821?ContentTypeID=1</link><pubDate>Tue, 08 Mar 2022 10:10:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:22db21a7-6835-4a5c-b5e4-95f1ffdf5e56</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello,&lt;br /&gt;&lt;br /&gt;Thank you for your patience with this.&lt;/p&gt;
[quote user=""]When the sequence is set (by a call to nrf_pwm_sequence_set), the provided duty cycle values are not copied. The values pointer is stored in the internal register of the peripheral, and the values are loaded from RAM during the sequence playback. Therefore, you must ensure that the values do not change before and during the sequence playback (for example, the values cannot be placed in a local variable that is allocated on stack).[/quote]
&lt;p&gt;To clarify this, this means that you must ensure that the pointer you provide actually points to the values for the playback &lt;em&gt;at the time of the playback&lt;/em&gt; - for example, if the values only persist through the scope of an &amp;#39;update_pwm&amp;#39; function, they may be overwritten by the time the playback actually happens, which is not a valid way to operate the PWM peripheral.&lt;br /&gt;On the other hand, if your playback sequence values are persistent throughout the duration of your PWM peripheral&amp;#39;s operation - such as in the case of global variables - it will ensure that the pointer you provide to the PWM peripheral always points to the valid playback sequence values.&lt;/p&gt;
[quote user=""]Does this mean that the user can update duty cycles using this function at any time, without worrying about a safe window?[/quote]
&lt;p&gt;No, because this function only update&amp;#39;s the PWM&amp;#39;s pointer - it does not perform any check to see if the location of the values will persist until the playback occurs.&lt;br /&gt;The issue arises if you supply a pointer that points to non-persistent playback sequence values. The &amp;#39;safe window&amp;#39; in this case would therefor be the time in which you can guarantee that the sequence playback values that you have provided the pointer for does not change / are actually stored at the location.&lt;br /&gt;&lt;br /&gt;Please do not hesitate to let me know if any part of this still should be unclear! :)&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>