This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nrf5340dk 8hmz clock output to gpio pin example via gpiote/ppi/timer

Hello Nordic Devzone,

I am currently attempting to generate 8mhz clock output to a gpio pin on the nrf5340dk. I have found previous posts about utilizing the gpiote, timer, and ppi channels to generate such clock output to a gpio pin, but have not found any example suitable for the nrf5340dk.

This GPIO option would be convenient but seems to be deprecated: https://docs.zephyrproject.org/1.9.0/api/io_interfaces.html#c.GPIO_INT_CLOCK_SYNC

I attempted to port a deprecated example of utilizing gpiote, timer, ppi for the nrf51 referenced here: https://github.com/NordicPlayground/nrf51-8-mhz-gpio-clock/blob/master/main.c

The attempt to port the clock generation code for the nrf5340 utilizing nrfx is below:

/*

* Copyright (c) 2012-2014 Wind River Systems, Inc.

*

* SPDX-License-Identifier: Apache-2.0

*/

#include <zephyr.h>
#include <sys/printk.h>
#include <drivers/spi.h>
#include <nrfx.h>
#include <nrfx_uarte.h>

#include <nrfx_dppi.h>
#include <helpers/nrfx_gppi.h>
#include <nrfx_gpiote.h>
#include <nrfx_timer.h>

// #include "nrf_gpio.h"
// #include "boards.h"
// #include "nrf_drv_ppi.h"
// #include "nrf_drv_timer.h"
// #include "nrf_drv_gpiote.h"
// #include "app_error.h"

// < ... omit spi code .. >

#define GPIOTE_INTERRUPT_PRIORITY 0
#define GPIOTE_MCLK_SYNC_PIN_OUT 0
#define DIVIDER_COUNT 20
#define ERROR_STATUS_CHECK(error) if(error != NRFX_SUCCESS){ printk("error code not 0! IS = %d", error);}


#define PIN 26

nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(0);
void main(void)
{


	nrfx_gpiote_init(GPIOTE_INTERRUPT_PRIORITY);



	nrfx_err_t err;
	nrfx_gpiote_out_config_t out_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
	err = nrfx_gpiote_out_init(PIN, &out_config);
	if( err != NRFX_SUCCESS )
	{
      printk("err_code not 0 for nrf_drv_gpiote_in_init");
    }



	nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
	timer_cfg.mode = NRF_TIMER_MODE_COUNTER;
	err = nrfx_timer_init(&m_timer, &timer_cfg, NULL);
	ERROR_STATUS_CHECK(err)

    nrfx_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, DIVIDER_COUNT, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
    nrfx_timer_enable(&m_timer);

    uint8_t channel;
    err =  nrfx_dppi_channel_alloc(&channel);
    nrfx_gpiote_pin_t gpiote_mclk_sync_pin_out = PIN;

 	uint32_t gpiote_mclk_toggle_task_addr = nrfx_gpiote_out_task_addr_get(gpiote_mclk_sync_pin_out); 
	uint32_t timer_event_address = nrfx_timer_event_address_get(&m_timer, NRF_TIMER_EVENT_COMPARE0);


	nrfx_gppi_channel_endpoints_setup(channel, timer_event_address, gpiote_mclk_toggle_task_addr );

	//printk("SPIM Example\n");
	//spi_init();

	// while (1) {
	// 	spi_test_send();
	// 	k_sleep(K_SECONDS(0));
	// }
}

I have connected an oscilloscope to the GPIO PIN 0.26 and do not see any clock hi/lo output. If NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true) is set, the GPIO 0.26 reads hi initially. My suspicion is the timer is not set correctly, and possibly the ppi channel's timer event/gpiote out task connection.

Is anyone able to point out the incorrect setup in the code to achieve the clock output to gpio?
Is there any reference or example code for the nrf5340dk and latest nrfx to generate 8hmz clock output to the gpio pin ?


Thank you for your support,

0n3

  • Hi,

     

    There was a couple of enable and the timer mode was incorrect. Here's a patched version of your sample:

    void main(void)
    {
    	nrfx_gpiote_init(GPIOTE_INTERRUPT_PRIORITY);
    
    
    
    	nrfx_err_t err;
    	nrfx_gpiote_out_config_t out_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
    	err = nrfx_gpiote_out_init(PIN, &out_config);
    	if( err != NRFX_SUCCESS )
    	{
          printk("err_code not 0 for nrf_drv_gpiote_in_init");
        }
    
    
    
    	nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
    	timer_cfg.mode = NRF_TIMER_MODE_TIMER;
    	timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    	err = nrfx_timer_init(&m_timer, &timer_cfg, NULL);
    	ERROR_STATUS_CHECK(err)
    
        nrfx_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, DIVIDER_COUNT, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);    
    
        uint8_t channel;
        err =  nrfx_dppi_channel_alloc(&channel);
        nrfx_gpiote_pin_t gpiote_mclk_sync_pin_out = PIN;
    
     	uint32_t gpiote_mclk_toggle_task_addr = nrfx_gpiote_out_task_addr_get(gpiote_mclk_sync_pin_out); 
    	uint32_t timer_event_address = nrfx_timer_event_address_get(&m_timer, NRF_TIMER_EVENT_COMPARE0);
    	printk("%x %x\n", gpiote_mclk_sync_pin_out, timer_event_address);
    
    	nrfx_gppi_channel_endpoints_setup(channel, timer_event_address, gpiote_mclk_toggle_task_addr );
    	nrfx_gppi_channels_enable(BIT(channel));
    	nrfx_gpiote_out_task_enable(PIN);
    	nrfx_timer_enable(&m_timer);
    }

     

    Kind regards,

    Håkon

Related