Repeatitive Timer and Edge Counter in nRF5340

I need repetitive Timer and Edge Counter in my application. There is is a single Timer Peripheral that can be used either as a Timer or Counter.  As well, further in counter mode, it is required to count both edges pe second. SO, how can all these be achieved ?

Parents
  • I copied some code from the link of example given by you as in attached text file. When, build the error shown in image occurs.

    Gulzar Singh

       

    //*******
    #include <nrfx_timer.h>
    #include <nrfx_gpiote.h>
    #include <helpers/nrfx_gppi.h>
    #if defined(DPPI_PRESENT)
    #include <nrfx_dppi.h>
    #else
    #include <nrfx_ppi.h>
    #endif
    //***********
    #define INPUT_PIN 26
    #define COUNT_READ_INTERVAL 2000
    static const nrfx_timer_t m_timer_count = NRFX_TIMER_INSTANCE(0);
    
    static const nrfx_timer_t m_timer_read  = NRFX_TIMER_INSTANCE(1);
    //******************************************************************************************
    void timer_handler_count(nrf_timer_event_t event_type, void * p_context)
    {
    
    }
    
    void timer_handler_read(nrf_timer_event_t event_type, void * p_context)
    {
        uint32_t count = nrfx_timer_capture_get(&m_timer_count, NRF_TIMER_CC_CHANNEL0);
    	uint32_t avg_freq = 0;
        if(count > 0)
        {
    	   avg_freq = (1000*count)/COUNT_READ_INTERVAL;
    	   printk("Average freq: %d [Hz]\n",avg_freq);
        }
    	printk("C: %d\n",count);
    }
    /**
     * @brief Function for configuring: INPUT_PIN pin for input sensing
     */
    static void gpiote_init(void)
    {
        nrfx_err_t err;
    	
    	/* Connect GPIOTE_0 IRQ to nrfx_gpiote_irq_handler */
    	//IRQ_CONNECT(DT_IRQN(DT_NODELABEL(gpiote)),
    	//	    DT_IRQ(DT_NODELABEL(gpiote), priority),
    	//	    nrfx_isr, nrfx_gpiote_irq_handler, 0);
    			
    	/* Initialize GPIOTE (the interrupt priority passed as the parameter
    	 * here is ignored, see nrfx_glue.h).
    	 */
    	err = nrfx_gpiote_init(0);
    	if (err != NRFX_SUCCESS) {
    		printk("nrfx_gpiote_init error: %08x", err);
    		return;
    	}
    	
    	nrfx_gpiote_in_config_t const in_config = {
    		.sense = NRF_GPIOTE_POLARITY_LOTOHI,
    		.pull = NRF_GPIO_PIN_NOPULL,
    		.is_watcher = false,
    		.hi_accuracy = true,
    		.skip_gpio_setup = false,
    	};
    
    	err = nrfx_gpiote_in_init(INPUT_PIN, &in_config, NULL);
    	if (err != NRFX_SUCCESS) {
    		printk("nrfx_gpiote_in_init error: %08x", err);
    		return;
    	}
    	
    	nrfx_gpiote_in_event_enable(INPUT_PIN, false);
    	
    
    }
    static void timer_init(void)
    {
    	// Configure m_timer_count for counting of low to high events on GPIO
    	nrfx_err_t          err;
    	nrfx_timer_config_t timer_cfg = {
    		.mode      = NRF_TIMER_MODE_LOW_POWER_COUNTER,
    		.bit_width = NRF_TIMER_BIT_WIDTH_32,
    		.p_context = NULL,
    	};
    
    	err = nrfx_timer_init(&m_timer_count, &timer_cfg, timer_handler_count);
    	if (err != NRFX_SUCCESS) {
    		printk("nrfx_timer_init failed with: %d\n", err);
    	}
    	// Configure m_timer_read for reading the counter timer at a given interval COUNT_READ_INTERVAL
        timer_cfg.mode = NRF_TIMER_MODE_TIMER;
        err = nrfx_timer_init(&m_timer_read, &timer_cfg, timer_handler_read);
        if (err != NRFX_SUCCESS) {
    		printk("nrfx_timer_init failed with: %d\n", err);
    	}
    		
    	nrfx_timer_extended_compare(&m_timer_read,
    		NRF_TIMER_CC_CHANNEL0,
    		nrfx_timer_ms_to_ticks(&m_timer_read, COUNT_READ_INTERVAL),
    		NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
    		true);
    	
    	
    	IRQ_CONNECT(TIMER1_IRQn, NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
    		nrfx_timer_1_irq_handler, NULL, 0);
    	IRQ_CONNECT(TIMER2_IRQn, NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
    		nrfx_timer_2_irq_handler, NULL, 0);
    	
    	nrfx_timer_clear(&m_timer_count);
    	nrfx_timer_clear(&m_timer_read);
    	
    	nrfx_timer_enable(&m_timer_count);
    	nrfx_timer_enable(&m_timer_read);
    		
    }
    void ppi_init()
    {
        nrfx_err_t err;
    	
    	/* Allocate a (D)PPI channel. */
    #if defined(DPPI_PRESENT)
    	uint8_t ppi_channel_1;
    	uint8_t ppi_channel_2;
    	
    	err = nrfx_dppi_channel_alloc(&ppi_channel_1);
    	err = nrfx_dppi_channel_alloc(&ppi_channel_2);
    #else
    	nrf_ppi_channel_t ppi_channel_1;
        nrf_ppi_channel_t ppi_channel_2;
    	
    	err = nrfx_ppi_channel_alloc(&ppi_channel_1);
    	err = nrfx_ppi_channel_alloc(&ppi_channel_2);
    #endif
    	if (err != NRFX_SUCCESS) {
    		printk("(D)PPI channel allocation error: %08x", err);
    		return;
    	}
    
    	
    	nrfx_gppi_channel_endpoints_setup(ppi_channel_1,
    		nrf_gpiote_event_address_get(NRF_GPIOTE,
    			nrfx_gpiote_in_event_get(INPUT_PIN)),
    		nrf_timer_task_address_get(m_timer_count.p_reg,
    			NRF_TIMER_TASK_COUNT));
    			
    
    	nrfx_gppi_channel_endpoints_setup(ppi_channel_2,
    		nrf_timer_event_address_get(m_timer_read.p_reg,
    			NRF_TIMER_EVENT_COMPARE0),
            nrf_timer_task_address_get(m_timer_count.p_reg, 
    			NRF_TIMER_TASK_CAPTURE0));
    	
    	
        nrfx_gppi_fork_endpoint_setup(ppi_channel_2, nrf_timer_task_address_get(m_timer_count.p_reg,NRF_TIMER_TASK_CLEAR)); // Clear counter timer using (D)PPI.
     
    	/* Enable (D)PPI channel. */
    #if defined(DPPI_PRESENT)
    	err = nrfx_dppi_channel_enable(ppi_channel_1);
    	err = nrfx_dppi_channel_enable(ppi_channel_2);
    #else
    	err = nrfx_ppi_channel_enable(ppi_channel_1);
    	err = nrfx_ppi_channel_enable(ppi_channel_2);
    #endif
    	if (err != NRFX_SUCCESS) {
    		printk("Failed to enable (D)PPI channel, error: %08x", err);
    		return;
    	}
    }
    //************
    void main()
    {
    	 gpiote_init();
    	
            timer_init();
    	
            ppi_init();
    }

Reply
  • I copied some code from the link of example given by you as in attached text file. When, build the error shown in image occurs.

    Gulzar Singh

       

    //*******
    #include <nrfx_timer.h>
    #include <nrfx_gpiote.h>
    #include <helpers/nrfx_gppi.h>
    #if defined(DPPI_PRESENT)
    #include <nrfx_dppi.h>
    #else
    #include <nrfx_ppi.h>
    #endif
    //***********
    #define INPUT_PIN 26
    #define COUNT_READ_INTERVAL 2000
    static const nrfx_timer_t m_timer_count = NRFX_TIMER_INSTANCE(0);
    
    static const nrfx_timer_t m_timer_read  = NRFX_TIMER_INSTANCE(1);
    //******************************************************************************************
    void timer_handler_count(nrf_timer_event_t event_type, void * p_context)
    {
    
    }
    
    void timer_handler_read(nrf_timer_event_t event_type, void * p_context)
    {
        uint32_t count = nrfx_timer_capture_get(&m_timer_count, NRF_TIMER_CC_CHANNEL0);
    	uint32_t avg_freq = 0;
        if(count > 0)
        {
    	   avg_freq = (1000*count)/COUNT_READ_INTERVAL;
    	   printk("Average freq: %d [Hz]\n",avg_freq);
        }
    	printk("C: %d\n",count);
    }
    /**
     * @brief Function for configuring: INPUT_PIN pin for input sensing
     */
    static void gpiote_init(void)
    {
        nrfx_err_t err;
    	
    	/* Connect GPIOTE_0 IRQ to nrfx_gpiote_irq_handler */
    	//IRQ_CONNECT(DT_IRQN(DT_NODELABEL(gpiote)),
    	//	    DT_IRQ(DT_NODELABEL(gpiote), priority),
    	//	    nrfx_isr, nrfx_gpiote_irq_handler, 0);
    			
    	/* Initialize GPIOTE (the interrupt priority passed as the parameter
    	 * here is ignored, see nrfx_glue.h).
    	 */
    	err = nrfx_gpiote_init(0);
    	if (err != NRFX_SUCCESS) {
    		printk("nrfx_gpiote_init error: %08x", err);
    		return;
    	}
    	
    	nrfx_gpiote_in_config_t const in_config = {
    		.sense = NRF_GPIOTE_POLARITY_LOTOHI,
    		.pull = NRF_GPIO_PIN_NOPULL,
    		.is_watcher = false,
    		.hi_accuracy = true,
    		.skip_gpio_setup = false,
    	};
    
    	err = nrfx_gpiote_in_init(INPUT_PIN, &in_config, NULL);
    	if (err != NRFX_SUCCESS) {
    		printk("nrfx_gpiote_in_init error: %08x", err);
    		return;
    	}
    	
    	nrfx_gpiote_in_event_enable(INPUT_PIN, false);
    	
    
    }
    static void timer_init(void)
    {
    	// Configure m_timer_count for counting of low to high events on GPIO
    	nrfx_err_t          err;
    	nrfx_timer_config_t timer_cfg = {
    		.mode      = NRF_TIMER_MODE_LOW_POWER_COUNTER,
    		.bit_width = NRF_TIMER_BIT_WIDTH_32,
    		.p_context = NULL,
    	};
    
    	err = nrfx_timer_init(&m_timer_count, &timer_cfg, timer_handler_count);
    	if (err != NRFX_SUCCESS) {
    		printk("nrfx_timer_init failed with: %d\n", err);
    	}
    	// Configure m_timer_read for reading the counter timer at a given interval COUNT_READ_INTERVAL
        timer_cfg.mode = NRF_TIMER_MODE_TIMER;
        err = nrfx_timer_init(&m_timer_read, &timer_cfg, timer_handler_read);
        if (err != NRFX_SUCCESS) {
    		printk("nrfx_timer_init failed with: %d\n", err);
    	}
    		
    	nrfx_timer_extended_compare(&m_timer_read,
    		NRF_TIMER_CC_CHANNEL0,
    		nrfx_timer_ms_to_ticks(&m_timer_read, COUNT_READ_INTERVAL),
    		NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
    		true);
    	
    	
    	IRQ_CONNECT(TIMER1_IRQn, NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
    		nrfx_timer_1_irq_handler, NULL, 0);
    	IRQ_CONNECT(TIMER2_IRQn, NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
    		nrfx_timer_2_irq_handler, NULL, 0);
    	
    	nrfx_timer_clear(&m_timer_count);
    	nrfx_timer_clear(&m_timer_read);
    	
    	nrfx_timer_enable(&m_timer_count);
    	nrfx_timer_enable(&m_timer_read);
    		
    }
    void ppi_init()
    {
        nrfx_err_t err;
    	
    	/* Allocate a (D)PPI channel. */
    #if defined(DPPI_PRESENT)
    	uint8_t ppi_channel_1;
    	uint8_t ppi_channel_2;
    	
    	err = nrfx_dppi_channel_alloc(&ppi_channel_1);
    	err = nrfx_dppi_channel_alloc(&ppi_channel_2);
    #else
    	nrf_ppi_channel_t ppi_channel_1;
        nrf_ppi_channel_t ppi_channel_2;
    	
    	err = nrfx_ppi_channel_alloc(&ppi_channel_1);
    	err = nrfx_ppi_channel_alloc(&ppi_channel_2);
    #endif
    	if (err != NRFX_SUCCESS) {
    		printk("(D)PPI channel allocation error: %08x", err);
    		return;
    	}
    
    	
    	nrfx_gppi_channel_endpoints_setup(ppi_channel_1,
    		nrf_gpiote_event_address_get(NRF_GPIOTE,
    			nrfx_gpiote_in_event_get(INPUT_PIN)),
    		nrf_timer_task_address_get(m_timer_count.p_reg,
    			NRF_TIMER_TASK_COUNT));
    			
    
    	nrfx_gppi_channel_endpoints_setup(ppi_channel_2,
    		nrf_timer_event_address_get(m_timer_read.p_reg,
    			NRF_TIMER_EVENT_COMPARE0),
            nrf_timer_task_address_get(m_timer_count.p_reg, 
    			NRF_TIMER_TASK_CAPTURE0));
    	
    	
        nrfx_gppi_fork_endpoint_setup(ppi_channel_2, nrf_timer_task_address_get(m_timer_count.p_reg,NRF_TIMER_TASK_CLEAR)); // Clear counter timer using (D)PPI.
     
    	/* Enable (D)PPI channel. */
    #if defined(DPPI_PRESENT)
    	err = nrfx_dppi_channel_enable(ppi_channel_1);
    	err = nrfx_dppi_channel_enable(ppi_channel_2);
    #else
    	err = nrfx_ppi_channel_enable(ppi_channel_1);
    	err = nrfx_ppi_channel_enable(ppi_channel_2);
    #endif
    	if (err != NRFX_SUCCESS) {
    		printk("Failed to enable (D)PPI channel, error: %08x", err);
    		return;
    	}
    }
    //************
    void main()
    {
    	 gpiote_init();
    	
            timer_init();
    	
            ppi_init();
    }

Children
Related