This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Making 4 regular PWM signal.

Hello, guys. I'm using the PCA10040 and the SDK 16.0'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.

I tried to implement it only with the PWM SDK example, but I thought I needed other things to make it works, so I asked a question. please give me an advise.

 

Thank you for reding my issue.

  • Hello,

     As you said, I'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.

     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.

     I attach my code below. And thank you so much for your help.

    #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->EVENTS_COMPARE[3] != 0) && ((NRF_TIMER1->INTENSET & TIMER_INTENSET_COMPARE3_Msk) != 0)) //TIMER_INTENSET_COMPARE1_Msk
        {
            //counter++;
            NRF_TIMER1->EVENTS_COMPARE[3] = 0;
            NRF_TIMER1->CC[0]             = (NRF_TIMER1->CC[0] + MAX_SAMPLE_LEVEL);
            NRF_TIMER1->CC[1]             = (NRF_TIMER1->CC[0] + QUARTER_SAMPLE_LEVEL);
            NRF_TIMER1->CC[2]             = (NRF_TIMER1->CC[0] + HALF_SAMPLE_LEVEL);  
            NRF_TIMER1->CC[3]             = (NRF_TIMER1->CC[0] + SIXTY_SAMPLE_LEVEL);
        }
    }
    
    void timer_INT_init(void)
    {
        //NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        //NRF_CLOCK->TASKS_HFCLKSTART    = 1;
     
        //while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        //{
        //    // Do nothing.
        //}
    
        NRF_TIMER1->MODE                    = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
        NRF_TIMER1->BITMODE                 = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
        NRF_TIMER1->PRESCALER               = 4;
    
        NRF_TIMER1->TASKS_CLEAR = 1;    
    
        NRF_TIMER1->CC[0]                   = MAX_SAMPLE_LEVEL;      //800
        NRF_TIMER1->CC[1]                   = QUARTER_SAMPLE_LEVEL;  //200
        NRF_TIMER1->CC[2]                   = HALF_SAMPLE_LEVEL;     //400   
        NRF_TIMER1->CC[3]                   = SIXTY_SAMPLE_LEVEL;    //600
    
    
        NRF_TIMER1->INTENSET = (TIMER_INTENSET_COMPARE3_Enabled << TIMER_INTENSET_COMPARE3_Pos);
    
        NRF_POWER->TASKS_CONSTLAT = 1;
        NVIC_EnableIRQ(TIMER1_IRQn);
        __enable_irq();
        NRF_TIMER1->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->CH[0].EEP  = (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[0];  //800us Cycle
          NRF_PPI->CH[0].TEP  = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];                                        // Que>  SET SIGNAL  PWM_A1(22)  
          NRF_PPI->FORK[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[3];                                       // Que>  OFF SIGNAL  PWM_B2(25)  
    
          NRF_PPI->CH[1].EEP  = (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[1]; // 200us Cycle
          NRF_PPI->CH[1].TEP  = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];                                        // Que> OFF SIGNAL   PWM_A1(22)                                           
          NRF_PPI->FORK[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1];                                       // Que> SET SIGNAL   PWM_A2(23)                                        
    
          NRF_PPI->CH[2].EEP  = (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[2]; // 400us Cycle
          NRF_PPI->CH[2].TEP  = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1];                                        // Que> OFF SIGNAL   PWM_A2(23) 
          NRF_PPI->FORK[2].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[2];                                       // Que> SET SIGNAL   PWM_B1(24)   
    
          NRF_PPI->CH[3].EEP  = (uint32_t)&NRF_TIMER1->EVENTS_COMPARE[3]; // 600us Cycle
          NRF_PPI->CH[3].TEP  = (uint32_t)&NRF_GPIOTE->TASKS_OUT[2];                                        // Que> OFF SIGNAL   PWM_B1(24) 
          NRF_PPI->FORK[3].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[3];                                       // Que> SET SIGNAL   PWM_B2(25)  
    
    
          NRF_PPI->CHEN       = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos) |
                                (PPI_CHEN_CH1_Enabled << PPI_CHEN_CH1_Pos) |
                                (PPI_CHEN_CH2_Enabled << PPI_CHEN_CH2_Pos) |
                                (PPI_CHEN_CH2_Enabled << PPI_CHEN_CH3_Pos) ;
    
    }

Related