<?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>Making 4 regular PWM signal.</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/76430/making-4-regular-pwm-signal</link><description>Hello, guys. I&amp;#39;m using the PCA10040 and the SDK 16.0&amp;#39;s BLE UART peripheral example. I am trying to make PWM signal below. 
 
 When PWM0 stops, PWM2 works, and when PWM2 stops, then PWM3, and in the same way, PWM4 works. And this signal is constantly repeated</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 21 Jun 2021 15:34:03 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/76430/making-4-regular-pwm-signal" /><item><title>RE: Making 4 regular PWM signal.</title><link>https://devzone.nordicsemi.com/thread/316326?ContentTypeID=1</link><pubDate>Mon, 21 Jun 2021 15:34:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a81f1d74-f603-47ff-a4bd-4ff66a244c90</guid><dc:creator>JWY</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;As you said, I&amp;#39;ve studied how to directly controf the PWM. Then i found out app_pwm_library is composed of PPI and GPIOTE, so i made the code while waiting for your reply.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;The code works the way i want it to. But i have a feeling that my code is forcing something to work. After running out of my code and looking at your answer, your code looks very convenient to extend and control like nRF_SDK.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;I attach my code below. And thank you so much for your help.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;
#define MAX_SAMPLE_LEVEL     800
#define SIXTY_SAMPLE_LEVEL   600
#define HALF_SAMPLE_LEVEL    400
#define QUARTER_SAMPLE_LEVEL 200

void TIMER1_IRQHandler(void)
{  
    if ((NRF_TIMER1-&amp;gt;EVENTS_COMPARE[3] != 0) &amp;amp;&amp;amp; ((NRF_TIMER1-&amp;gt;INTENSET &amp;amp; TIMER_INTENSET_COMPARE3_Msk) != 0)) //TIMER_INTENSET_COMPARE1_Msk
    {
        //counter++;
        NRF_TIMER1-&amp;gt;EVENTS_COMPARE[3] = 0;
        NRF_TIMER1-&amp;gt;CC[0]             = (NRF_TIMER1-&amp;gt;CC[0] + MAX_SAMPLE_LEVEL);
        NRF_TIMER1-&amp;gt;CC[1]             = (NRF_TIMER1-&amp;gt;CC[0] + QUARTER_SAMPLE_LEVEL);
        NRF_TIMER1-&amp;gt;CC[2]             = (NRF_TIMER1-&amp;gt;CC[0] + HALF_SAMPLE_LEVEL);  
        NRF_TIMER1-&amp;gt;CC[3]             = (NRF_TIMER1-&amp;gt;CC[0] + SIXTY_SAMPLE_LEVEL);
    }
}

void timer_INT_init(void)
{
    //NRF_CLOCK-&amp;gt;EVENTS_HFCLKSTARTED = 0;
    //NRF_CLOCK-&amp;gt;TASKS_HFCLKSTART    = 1;
 
    //while (NRF_CLOCK-&amp;gt;EVENTS_HFCLKSTARTED == 0)
    //{
    //    // Do nothing.
    //}

    NRF_TIMER1-&amp;gt;MODE                    = TIMER_MODE_MODE_Timer &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;
    NRF_TIMER1-&amp;gt;BITMODE                 = TIMER_BITMODE_BITMODE_16Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER1-&amp;gt;PRESCALER               = 4;

    NRF_TIMER1-&amp;gt;TASKS_CLEAR = 1;    

    NRF_TIMER1-&amp;gt;CC[0]                   = MAX_SAMPLE_LEVEL;      //800
    NRF_TIMER1-&amp;gt;CC[1]                   = QUARTER_SAMPLE_LEVEL;  //200
    NRF_TIMER1-&amp;gt;CC[2]                   = HALF_SAMPLE_LEVEL;     //400   
    NRF_TIMER1-&amp;gt;CC[3]                   = SIXTY_SAMPLE_LEVEL;    //600


    NRF_TIMER1-&amp;gt;INTENSET = (TIMER_INTENSET_COMPARE3_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE3_Pos);

    NRF_POWER-&amp;gt;TASKS_CONSTLAT = 1;
    NVIC_EnableIRQ(TIMER1_IRQn);
    __enable_irq();
    NRF_TIMER1-&amp;gt;TASKS_START = 1;

}

void ppi_init(void)
{
      nrf_gpio_cfg_output(PWM_A1);
      nrf_gpio_cfg_output(PWM_A2);
      nrf_gpio_cfg_output(PWM_B1);
      nrf_gpio_cfg_output(PWM_B2);

      nrf_gpiote_task_config( 0, PWM_A1, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);      //NRF_GPIOTE_INITIAL_VALUE_LOW
      nrf_gpiote_task_config( 1, PWM_A2, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);      //NRF_GPIOTE_INITIAL_VALUE_LOW
      nrf_gpiote_task_config( 2, PWM_B_PADL, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);  //NRF_GPIOTE_INITIAL_VALUE_LOW
      nrf_gpiote_task_config( 3, PWM_B1, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);     //NRF_GPIOTE_INITIAL_VALUE_LOW


      NRF_PPI-&amp;gt;CH[0].EEP  = (uint32_t)&amp;amp;NRF_TIMER1-&amp;gt;EVENTS_COMPARE[0];  //800us Cycle
      NRF_PPI-&amp;gt;CH[0].TEP  = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[0];                                        // Que&amp;gt;  SET SIGNAL  PWM_A1(22)  
      NRF_PPI-&amp;gt;FORK[0].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[3];                                       // Que&amp;gt;  OFF SIGNAL  PWM_B2(25)  

      NRF_PPI-&amp;gt;CH[1].EEP  = (uint32_t)&amp;amp;NRF_TIMER1-&amp;gt;EVENTS_COMPARE[1]; // 200us Cycle
      NRF_PPI-&amp;gt;CH[1].TEP  = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[0];                                        // Que&amp;gt; OFF SIGNAL   PWM_A1(22)                                           
      NRF_PPI-&amp;gt;FORK[1].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[1];                                       // Que&amp;gt; SET SIGNAL   PWM_A2(23)                                        

      NRF_PPI-&amp;gt;CH[2].EEP  = (uint32_t)&amp;amp;NRF_TIMER1-&amp;gt;EVENTS_COMPARE[2]; // 400us Cycle
      NRF_PPI-&amp;gt;CH[2].TEP  = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[1];                                        // Que&amp;gt; OFF SIGNAL   PWM_A2(23) 
      NRF_PPI-&amp;gt;FORK[2].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[2];                                       // Que&amp;gt; SET SIGNAL   PWM_B1(24)   

      NRF_PPI-&amp;gt;CH[3].EEP  = (uint32_t)&amp;amp;NRF_TIMER1-&amp;gt;EVENTS_COMPARE[3]; // 600us Cycle
      NRF_PPI-&amp;gt;CH[3].TEP  = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[2];                                        // Que&amp;gt; OFF SIGNAL   PWM_B1(24) 
      NRF_PPI-&amp;gt;FORK[3].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[3];                                       // Que&amp;gt; SET SIGNAL   PWM_B2(25)  


      NRF_PPI-&amp;gt;CHEN       = (PPI_CHEN_CH0_Enabled &amp;lt;&amp;lt; PPI_CHEN_CH0_Pos) |
                            (PPI_CHEN_CH1_Enabled &amp;lt;&amp;lt; PPI_CHEN_CH1_Pos) |
                            (PPI_CHEN_CH2_Enabled &amp;lt;&amp;lt; PPI_CHEN_CH2_Pos) |
                            (PPI_CHEN_CH2_Enabled &amp;lt;&amp;lt; PPI_CHEN_CH3_Pos) ;

}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Making 4 regular PWM signal.</title><link>https://devzone.nordicsemi.com/thread/316292?ContentTypeID=1</link><pubDate>Mon, 21 Jun 2021 13:54:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e1824d26-1f63-4028-b51c-b283c12d40d7</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;app_pwm is based on a timer and GPIOTE+PPI, it is limited with two channels per instance. Take a look at &lt;a href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.2.0/group__nrfx__pwm.html?cp=8_5_2_6_9_0_13_1"&gt;PWM driver&lt;/a&gt;, it uses hardware PWM peripheral that can drive four channels at once.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here is a draft example how to configure pwm for 4 channels:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static const nrfx_pwm_t pwm = NRFX_PWM_INSTANCE(0);

static const nrfx_pwm_config_t pwm_config = {
    .output_pins = { 13,14,15,16 },
    .irq_priority = 3,
    .base_clock = NRF_PWM_CLK_1MHz,
    .count_mode = NRF_PWM_MODE_UP,
    .top_value = 200,
    .load_mode = NRF_PWM_LOAD_INDIVIDUAL,
    .step_mode = NRF_PWM_STEP_AUTO,
};

static uint16_t pwm_data[16] = { 0x8000,0,0,0,  0,0x8000,0,0,  0,0,0x8000,0,  0,0,0,0x8000 };

static const nrf_pwm_sequence_t pwm_seq = {
    .values.p_raw = pwm_data,
    .length = NRF_PWM_VALUES_LENGTH(pwm_data),
    .repeats = 0,
    .end_delay = 0,
};

nrfx_pwm_init(&amp;amp;pwm, &amp;amp;pwm_config, NULL);
nrfx_pwm_simple_playback(&amp;amp;pwm, &amp;amp;pwm_seq, 1, NRFX_PWM_FLAG_LOOP);
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Making 4 regular PWM signal.</title><link>https://devzone.nordicsemi.com/thread/316131?ContentTypeID=1</link><pubDate>Sat, 19 Jun 2021 18:28:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:886c32d8-dec7-45dd-97a9-133cdb2c2c7d</guid><dc:creator>JWY</dc:creator><description>&lt;p&gt;Hello Dmitry.&lt;/p&gt;
&lt;p&gt;First, thant you for answer.&lt;/p&gt;
&lt;p&gt;Do you mean creating an instance that controls 4 channels at oner?&lt;/p&gt;
&lt;p&gt;I only know the way that APP_PWM_DEFAULT_CONFIG_2CH(800L, 22, 23); So, please let me know how to do that?&lt;/p&gt;
&lt;p&gt;And i also can&amp;#39;t find&amp;nbsp;&amp;nbsp;&lt;span&gt;DECODER.LOAD=Single.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thank you&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre class="tw-data-text tw-text-large XcVN5d tw-ta" id="tw-target-text" dir="ltr"&gt;&lt;span class="Y2IQFc" lang="en"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Making 4 regular PWM signal.</title><link>https://devzone.nordicsemi.com/thread/315973?ContentTypeID=1</link><pubDate>Thu, 17 Jun 2021 19:09:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:31973dbf-b123-4942-b9cc-6c1ea0734e4f</guid><dc:creator>Dmitry</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I believe you can do this with four channels of a single PWM instance. Configure PWM with DECODER.LOAD=Single and create a four-step sequence, each step has zero compare value and POLARITY set for an active output:&lt;/p&gt;
&lt;p&gt;uint16_t pwmseq[16] = { 0x8000,0,0,0,&amp;nbsp; 0,0x8000,0,0,&amp;nbsp; 0,0,0x8000,0,&amp;nbsp; 0,0,0,0x8000 };&lt;/p&gt;
&lt;p&gt;(I&amp;#39;m working with PWM peripheral directly rather than via app_pwm library, so I can&amp;#39;t show a code sample with app_pwm)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Making 4 regular PWM signal.</title><link>https://devzone.nordicsemi.com/thread/315946?ContentTypeID=1</link><pubDate>Thu, 17 Jun 2021 15:31:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d8f0911f-9193-4cb7-966c-3088a1cbc533</guid><dc:creator>JWY</dc:creator><description>&lt;pre class="tw-data-text tw-text-large XcVN5d tw-ta" dir="ltr"&gt;&lt;span class="Y2IQFc" lang="en"&gt;Thank you for answer.
Is nRF52832 impossible to do that?&lt;br /&gt;&lt;br /&gt;Here my code is&lt;br /&gt;&lt;br /&gt;app_pwm_config_t PWM_1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(800L, 22, 23); // 0.8ms &lt;br /&gt;app_pwm_config_t PWM_2_cfg = APP_PWM_DEFAULT_CONFIG_2CH(800L, 24, 25); // 0.8ms&lt;br /&gt;&lt;br /&gt; g_s_bReadyFlag = false;&lt;br /&gt; while (app_pwm_channel_duty_set(&amp;amp;PWM_1, 0, 25) == NRF_ERROR_BUSY);&lt;br /&gt; while (!g_s_bReadyFlag);&lt;br /&gt;&lt;br /&gt; nrf_delay_us(200);&lt;br /&gt; g_s_bReadyFlag = false;&lt;br /&gt; while (app_pwm_channel_duty_set(&amp;amp;PWM_1, 1, 25) == NRF_ERROR_BUSY);&lt;br /&gt; while (!g_s_bReadyFlag);&lt;br /&gt;&lt;/span&gt; nrf_delay_us(200);&lt;br /&gt;&lt;br /&gt; g_s_bReadyFlag_2 = false;&lt;br /&gt; while (app_pwm_channel_duty_set(&amp;amp;PWM_2, 0, 25) == NRF_ERROR_BUSY);&lt;br /&gt; while (!g_s_bReadyFlag_2);&lt;br /&gt; nrf_delay_us(200);&lt;/pre&gt;
&lt;pre class="tw-data-text tw-text-large XcVN5d tw-ta" dir="ltr"&gt;&lt;br /&gt; g_s_bReadyFlag_2 = false;&lt;br /&gt; while (app_pwm_channel_duty_set(&amp;amp;PWM_2, 1, 25) == NRF_ERROR_BUSY);&lt;br /&gt; while (!g_s_bReadyFlag_2);&lt;br /&gt; nrf_delay_us(200);&lt;/pre&gt;
&lt;pre class="tw-data-text tw-text-large XcVN5d tw-ta" id="tw-target-text" dir="ltr"&gt;&lt;span class="Y2IQFc" lang="en"&gt;If irun this code and check the scope, i can see that the 200 microsecond delay is not applied and almost the same output.&lt;br /&gt;&lt;/span&gt;The results were similar even when outputting separately one by one without controlling the two channels as a bundle.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;pre class="tw-data-text tw-text-large XcVN5d tw-ta" id="tw-target-text" dir="ltr"&gt;&lt;span class="Y2IQFc" lang="en"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="tw-data-text tw-text-large XcVN5d tw-ta" id="tw-target-text" dir="ltr"&gt;&lt;span class="Y2IQFc" lang="en"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Making 4 regular PWM signal.</title><link>https://devzone.nordicsemi.com/thread/315884?ContentTypeID=1</link><pubDate>Thu, 17 Jun 2021 12:52:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8d3e2b36-ed11-4176-b24f-314daeb09daa</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;The simplest may be to use the nRF52833 and nRF52840 which have 4 PWM peripherals. You would need to configure all 4 PWM, and then delay the START for each of them with 200us, then they should produce the signal you show. That should be pretty straight forward I believe.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Please also see:&lt;br /&gt;&lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf52833/pwm.html"&gt;https://infocenter.nordicsemi.com/topic/ps_nrf52833/pwm.html&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Kenneth&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>