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

nRF52840: 16 MHz Clock-Out on GPIO Pin

Can we get a 16MHz clock out over a GPIO pin? We could use this to clock some downstream devices.

Parents
  • Hello,

    The GPIO module runs on 16M so the theoretical max. frequency is limited to 8Mhz, unfortunately. 

  • Thanks for the quick response. Would it be possible then to get an 8MHz clock out over a GPIO pin? Could you provide some example code?

  • Yes, it should be possible. I made the code below that you can use to test this.

    #include <stdbool.h>
    #include <stdint.h>
    #include "boards.h"
    
    
    void gpio_clock_8m(uint32_t pin_number)
    {
        
        NRF_TIMER1->PRESCALER = 0; // 16MHz
        NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
        NRF_TIMER1->CC[0] = 1;
    
        NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Task | (pin_number << GPIOTE_CONFIG_PSEL_Pos) |
                                (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
    
        /*Connect TIMER event to GPIOTE out 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   = 1;
    
        /*Starts clock signal*/
        NRF_TIMER1->TASKS_START = 1;
    }
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        
        /*Start HF crystal for improved clock tolerance*/
        NRF_CLOCK->TASKS_HFCLKSTART = 1;
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    
    
        gpio_clock_8m(27);
    
    
        for (;;)
        {
            __WFE();
        }
         
    }

    Also, in case you haven't noticed, some pins are not recommended for high-frequency I/O operation (may interfere with RADIO). See the "Pin assignments" section of the PS to see which pins this applies to.

Reply
  • Yes, it should be possible. I made the code below that you can use to test this.

    #include <stdbool.h>
    #include <stdint.h>
    #include "boards.h"
    
    
    void gpio_clock_8m(uint32_t pin_number)
    {
        
        NRF_TIMER1->PRESCALER = 0; // 16MHz
        NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
        NRF_TIMER1->CC[0] = 1;
    
        NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Task | (pin_number << GPIOTE_CONFIG_PSEL_Pos) |
                                (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
    
        /*Connect TIMER event to GPIOTE out 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   = 1;
    
        /*Starts clock signal*/
        NRF_TIMER1->TASKS_START = 1;
    }
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        
        /*Start HF crystal for improved clock tolerance*/
        NRF_CLOCK->TASKS_HFCLKSTART = 1;
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    
    
        gpio_clock_8m(27);
    
    
        for (;;)
        {
            __WFE();
        }
         
    }

    Also, in case you haven't noticed, some pins are not recommended for high-frequency I/O operation (may interfere with RADIO). See the "Pin assignments" section of the PS to see which pins this applies to.

Children
Related