<?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>SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/41481/saadc-fails-to-sync-with-pwm-via-ppi</link><description>I&amp;#39;m looking to sync an ADC reading with the PWM output. I&amp;#39;m using PPI for this but fails to make it synchronise properly with the PWM. 
 I&amp;#39;m getting interrupts and sampled values, indicating something is sampled. But if I toggle a pin when starting the</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 14 Dec 2018 13:15:18 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/41481/saadc-fails-to-sync-with-pwm-via-ppi" /><item><title>RE: SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/thread/161866?ContentTypeID=1</link><pubDate>Fri, 14 Dec 2018 13:15:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:041d71a4-adfe-4a07-b2fc-7bdb8401b322</guid><dc:creator>obbe</dc:creator><description>&lt;p&gt;Of course!&amp;nbsp;&lt;span class="emoticon" data-url="https://devzone.nordicsemi.com/cfs-file/__key/system/emoji/1f926.svg" title="Face palm"&gt;&amp;#x1f926;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/thread/161863?ContentTypeID=1</link><pubDate>Fri, 14 Dec 2018 13:11:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:eb8e14ea-6934-4d68-8354-f285564b826c</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;Yes. But then it will be synchronized with a pin interrupt, either going HiToLo or LoToHi.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void pin_init(uint32_t pinselect)
{  
    NRF_GPIOTE-&amp;gt;CONFIG[CHANNEL_NUMBER] = GPIOTE_CONFIG_MODE_Task &amp;lt;&amp;lt; GPIOTE_CONFIG_MODE_Pos | 
                                         GPIOTE_CONFIG_POLARITY_Toggle &amp;lt;&amp;lt; GPIOTE_CONFIG_POLARITY_Pos | 
                                         pinselect &amp;lt;&amp;lt; GPIOTE_CONFIG_PSEL_Pos | 
                                         GPIOTE_CONFIG_OUTINIT_High &amp;lt;&amp;lt; GPIOTE_CONFIG_OUTINIT_Pos; // no effect when in event mode.

    NRF_PPI-&amp;gt;CH[PIN_PPI_CH_A].EEP   = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;EVENTS_IN[CHANNEL_NUMBER];
    NRF_PPI-&amp;gt;CH[PIN_PPI_CH_A].TEP   = (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;TASKS_SAMPLE;
    
    NRF_PPI-&amp;gt;CHENSET                = (1 &amp;lt;&amp;lt; PIN_PPI_CH_A);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;What you really are looking for is just the state change of the pin, and not the PWM events, right?&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: SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/thread/161730?ContentTypeID=1</link><pubDate>Thu, 13 Dec 2018 15:42:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9f5ac6f0-9b65-4295-b704-0084a0d3e4c4</guid><dc:creator>obbe</dc:creator><description>&lt;p&gt;Ok, so I guess it all boils down to this question: Is it possible to generate an event that is synchronised with the start of a PWM period?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/thread/161653?ContentTypeID=1</link><pubDate>Thu, 13 Dec 2018 12:20:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ab0cd7b9-1038-4290-9f93-5208d9684531</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;The point of the peripherals on the nRF is that they should do as much as possible without having to interrupt or wait for the CPU. Especially with the PWM driver. If you generate a PWM signal to control an LED or an electric motor, you certainly don&amp;#39;t want to get an application interrupt every 2ms to toggle the pin. So after you start the PWM, it will not generate an event on every PWM period.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I still don&amp;#39;t understand whether you generate the PWM on the nRF to trigger samples, or if you ultimately want it to trigger on a PWM signal that is generated externally.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
[quote user="obbe"]I basically want an interrupt every T seconds[/quote]
&lt;p&gt;&amp;nbsp;Sounds like a timer, and not PWM is the way to go.&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: SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/thread/161610?ContentTypeID=1</link><pubDate>Thu, 13 Dec 2018 08:55:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2bf1aba3-33cd-46fb-bc07-e6665bf4dfc4</guid><dc:creator>obbe</dc:creator><description>&lt;p&gt;Thanks for the thorough reply.&lt;/p&gt;
&lt;p&gt;I set the pin when I want to start the ADC conversion, and then clear it in the event handler. The issue is not that I&amp;#39;m not getting samples or that the event handler is called. I get a DONE event.&lt;/p&gt;
&lt;p&gt;The issue is that the sequence doesn&amp;#39;t sync with the PWM. What I want is that if I want to acquire a sample, the ADC shall wait until the beginning of the next PWM cycle. Assuming the the acquisition time is t_acq and the PWM period is T, I would expect an interrupt at T+t_acq, but using the oscilloscope, I can see that these are not at all related.&lt;/p&gt;
&lt;p&gt;So I&amp;#39;m thinking that I have misinterpreted when PWM events are generated. I basically want an interrupt every T seconds, regardless if I&amp;#39;m changing the PWM duty cycles or not.&lt;/p&gt;
&lt;p&gt;If this is not clear I can write a sample program that explains the use case better?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/thread/161592?ContentTypeID=1</link><pubDate>Thu, 13 Dec 2018 07:56:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ca2d3fc8-c131-4130-bd0e-6a5e60ac02e2</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;I see. You set the pin in the saadc_evt_handler, right? And you try to trigger the SAADC from the PWM started event, correct?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I have not used the SAADC on register level before, so I can&amp;#39;t say without testing whether your SAADC setup is correct or not, but I guess the SAADC needs more samples before it will trigger the event. It fills up the entire buffer, which I guess is the one you have set to 3:&lt;/p&gt;
&lt;p&gt;NRF_SAADC-&amp;gt;RESULT.MAXCNT = 3U;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Hence, even if the EEP triggers:&lt;/p&gt;
&lt;p&gt;NRF_PPI-&amp;gt;CH[0].EEP = (uint32_t)(&amp;amp;(NRF_PWM0-&amp;gt;EVENTS_SEQSTARTED[kIndicatorPwmSequence]));&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;And the TEP triggers:&lt;/p&gt;
&lt;p&gt;NRF_PPI-&amp;gt;CH[0].TEP = (uint32_t)(&amp;amp;NRF_SAADC-&amp;gt;TASKS_SAMPLE);&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;It will not trigger the saadc_evt_handler; because the SAADC doesn&amp;#39;t get a callback until it has finished reading n samples, where n is the number of elements in the buffer.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Check this log from the saadc example in the SDK:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;lt;info&amp;gt; SAADC: Function: nrfx_saadc_init, error code: NRF_SUCCESS.
&amp;lt;info&amp;gt; SAADC: Channel initialized: 0.
&amp;lt;info&amp;gt; SAADC: Function: nrfx_saadc_channel_init, error code: NRF_SUCCESS.
&amp;lt;info&amp;gt; SAADC: Function: nrfx_saadc_buffer_convert, buffer length: 5, active channels: 1.
&amp;lt;info&amp;gt; SAADC: Function: nrfx_saadc_buffer_convert, error code: NRF_SUCCESS.
&amp;lt;warning&amp;gt; SAADC: Function: nrfx_saadc_buffer_convert, error code: NRF_SUCCESS.
&amp;lt;info&amp;gt; app: SAADC HAL simple example started.
&amp;lt;debug&amp;gt; SAADC: Event: 
&amp;lt;debug&amp;gt; SAADC: Event: NRF_SAADC_EVENT_END.
&amp;lt;warning&amp;gt; SAADC: Function: nrfx_saadc_buffer_convert, error code: NRF_SUCCESS.
&amp;lt;info&amp;gt; app: ADC event number: 0
&amp;lt;info&amp;gt; app: 12
&amp;lt;info&amp;gt; app: 11
&amp;lt;info&amp;gt; app: 12
&amp;lt;info&amp;gt; app: 9
&amp;lt;info&amp;gt; app: 9
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Only the logs starting with &amp;lt;debug&amp;gt; are from the SAADC_IRQHandler, the rest is from main.c.&lt;/p&gt;
&lt;p&gt;I modified this function by adding the NRFX_LOG_DEBUG(&amp;quot;Event:&amp;quot;); in the start of this function:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void nrfx_saadc_irq_handler(void)
{
    NRFX_LOG_DEBUG(&amp;quot;Event: &amp;quot;);
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_END))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
        NRFX_LOG_DEBUG(&amp;quot;Event: %s.&amp;quot;, EVT_TO_STR(NRF_SAADC_EVENT_END));
    ...&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;As you can see, the first event in the irq handler is the NRF_SAADC_EVENT_END, which is after the first 5 samples are sampled (there are 5 samples in the buffer in this example).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You should check out this example. It sets up a timer, starts it, and uses PPI to trigger sample events from the timeout events. You can see in the example that the timeout handler is empty, so it is only used to trigger the samples via PPI.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When doing PPI implementations like the one you have posted, it is a good idea to start with a simple check, such as starting with the PWM, but as an TEP, just toggle a pin. To set up an GPIOTE in ppi, you can try the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void pin_init(uint32_t pinselect)
{  
    NRF_GPIOTE-&amp;gt;CONFIG[CHANNEL_NUMBER] = GPIOTE_CONFIG_MODE_Task &amp;lt;&amp;lt; GPIOTE_CONFIG_MODE_Pos | 
                                         GPIOTE_CONFIG_POLARITY_Toggle &amp;lt;&amp;lt; GPIOTE_CONFIG_POLARITY_Pos | 
                                         pinselect &amp;lt;&amp;lt; GPIOTE_CONFIG_PSEL_Pos | 
                                         GPIOTE_CONFIG_OUTINIT_High &amp;lt;&amp;lt; GPIOTE_CONFIG_OUTINIT_Pos;

    NRF_PPI-&amp;gt;CH[PIN_PPI_CH_A].EEP = (uint32_t)(&amp;amp;(NRF_PWM0-&amp;gt;EVENTS_SEQSTARTED[kIndicatorPwmSequence]));
    NRF_PPI-&amp;gt;CH[PIN_PPI_CH_A].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_CLR[PWM0_GPIOTE_CH];
    
    NRF_PPI-&amp;gt;CHENSET               = (1 &amp;lt;&amp;lt; PIN_PPI_CH_A);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I suggest you check out the saadc example, which triggers the samples via ppi, and sets up all this using the SDK API, together with starting checking whether the PWM is set up correctly by toggling the pin on the PWM event end points (EEP).&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: SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/thread/161477?ContentTypeID=1</link><pubDate>Wed, 12 Dec 2018 14:23:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ef0e6d23-66d9-4d15-a0a8-0402898c99c4</guid><dc:creator>obbe</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Pin 3 is not connected to anything. I&amp;#39;m just using it to verify that the ADC is synced with the PWM properly. I.e. I sample the PWM output and pin 3 output with the oscilloscope to see that the ADC sampling occurs when the PWM signal is high.&lt;/p&gt;
&lt;p&gt;Yeah, a little background info would probably be in place. But the short answer is: &lt;span&gt;using the PWM signal as a timer to trigger the SAADC readings.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The PWM is controlling an RGB LED (sinking it through transistors). To detect that the LED is working properly, we want to&amp;nbsp;measure the voltage drop over the diodes, using the SAADC.&lt;/p&gt;
&lt;p&gt;For example, assume that the LED&amp;#39;s are powered with 5V and have a voltage drop of 3V. A normally functioning diode, when on, would have a voltage of 5V-3V = 2V at its cathode. A diode that has short-circuited would have 5V and one that has open-circuited would have 0V (because we are sinking it to GND).&amp;nbsp;If it is not on, the voltage would be &amp;gt;3.3V, even when it&amp;#39;s working. (We are not really sure of this, but its a theory anyway)&lt;/p&gt;
&lt;p&gt;So, in order to reliably determine if the diode is working, we need to sync the SAADC reading with when the LED is ON, thus with the PWM.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC fails to sync with PWM via PPI</title><link>https://devzone.nordicsemi.com/thread/161468?ContentTypeID=1</link><pubDate>Wed, 12 Dec 2018 13:59:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:657eda2d-0a0e-4b3e-bd08-23dbba71abbb</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;What is your pin 3 connected to? Is it RED GREEN or BLUE pin of yours, or something else?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;To be honest, I am having a little trouble understanding exactly what you want to do. Are you trying to create a feedback loop to measure the average on the PWM pin, or are you using the PWM signal as a timer to trigger the SAADC readings?&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></channel></rss>