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

PPI usage white paper?

Does there exist a white paper describing some typical PPI use cases with coding examples? The only one I've found is the peripheral/gpiote example and it is severely lacking any explanatory comments. Looking at the relevant functions in the info-center is not much help since they also have terse 7 or 8 word descriptions. Looking at the PPI section of the chip spec is also nearly useless, since it does not mention any of the nrf_drv_ppi functions.

My use-case is pretty simple and almost the same as the gpiote example. I want to configure a GPIO to output a continuous 1MHz signal to be used as a clock by an external device. This configuration should use as little power as possible and allow my application to stop and start the 1MHz signal as required. And finally, the signal should continue uninterrupted when I call sd_app_evt_wait to manage power.

Parents
  • Hi,

    I wrote some code for this earlier, for 4 MHz output on pin 18 set NRF_TIMER1->CC[0] = 8;.

    int main(void)
    {
        // Set up GPIO as output
        nrf_gpio_range_cfg_output(17, 18);
        nrf_gpio_pin_clear(17); // Light LED 1 to indicate that the code is running
        
        // Start high frequency clock without SoftDevice
        NRF_CLOCK->TASKS_HFCLKSTART = 1;
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        {
            // Wait for clock to start
        }
    
        // Start high frequency clock with SoftDevice
        uint32_t running;
        sd_clock_hfclk_request();
        sd_clock_hfclk_is_running(&running);
        while(!running)
        {
            sd_clock_hfclk_is_running(&running);
            //Wait for clock to start
        }
    
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        
        // Configure GPIOTE to toggle pin 18 
        NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos |
                                GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos |
                                18 << GPIOTE_CONFIG_PSEL_Pos | 
                                GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos;
                                
        // Set up timer
        NRF_TIMER1->PRESCALER = 0;
        NRF_TIMER1->CC[0] = 2; // Adjust the output frequency by adjusting the CC.
        NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
        NRF_TIMER1->TASKS_START = 1;
            
        // Set up PPI to connect the timer compare event with the GPIOTE toggle task
        NRF_PPI->CH[0].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[0];
        NRF_PPI->CH[0].TEP = (uint32_t) &NRF_GPIOTE->TASKS_OUT[0];
        
        NRF_PPI->CHENSET = PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos;
        
        while (true)
        {
           
        }
    }
    

    You can also see this post.

    Best regards,

    Øyvind

  • Øyvind,

    Won't the direct use of TIMER1 in the way you show above cause a conflict with the SoftDevice? I'm under the impression that timer control needs to go through the SD APIs when the SD is running.

    Bret

Reply Children
No Data
Related