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

2 Timers as counter with external input capture pin

Hi. I have to make mesuring impulses quantity of two external low freq signals without interrupts.

I tried to use GPIOTE EVENTS_IN[0] and 1 with PPI ch 0 and 1 to timer 2 and 3 TASKS_COUNT generate. it works, but when the event on pins polarity change occure simultaneously one of the timers counts twice. 

How to make it write to be timers counted independently of each other?

Parents
  • Hi,

     

    Could you share a piece of the code where you tie everything together, so I can look at the logic?

    Are the signals occurring within a very short period of time? If yes, then it might be that you are running into this errata: http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.Rev1.errata/anomaly_832_155.html?cp=2_1_1_1_1_44

     

    Best regards,

    Håkon

     

  • Delay between signals 1 - 1.5 ms/

    Code (next i remake without ppi)

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)

    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    
    		if( pin == 4 )
    		{	
    			counter1++;
    			SEGGER_RTT_WriteString(0,"CNT1\r\n");
    		}
    		else if( pin == 5 )
    		{			
    			counter2++;
    			SEGGER_RTT_WriteString(0,"CNT2\r\n");
    		}
    }
    
    static void buttons_leds_init(bool * p_erase_bonds)
    {
    	nrf_gpio_cfg_output(17);
    	nrf_gpio_cfg_output(18);
    	nrf_gpio_cfg_output(19);
    	nrf_gpio_cfg_output(20);
    	nrf_gpio_pin_set(17);
    	nrf_gpio_pin_set(18);
    	nrf_gpio_pin_set(19);
    	nrf_gpio_pin_set(20);
    
    	err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    	
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
        in_config.pull = NRF_GPIO_PIN_PULLUP;
        nrf_drv_gpiote_in_init(4, &in_config, in_pin_handler);
        nrf_drv_gpiote_in_event_enable(4, true);
        nrf_drv_gpiote_in_init(5, &in_config, in_pin_handler);
        nrf_drv_gpiote_in_event_enable(5, true);
        
        NVIC_SetPriority(2, GPIOTE_IRQn);
        NVIC_DisableIRQ(GPIOTE_IRQn);
    }
    

    cnt2 sets twice

  • It is not the pin used, but the GPIOTE->IN[] instance used. If there are no other IN channels in use, then this is 0 and 1.

  • Ok.I took an experiment using nrf51 pca10001 board. i had the same problem on nrf51, but when i had used errata code ,  nrf51 code starts to work well! no double events.

    void GPIOTE_IRQHandler(void)
    {
    		if(NRF_GPIOTE->EVENTS_IN[0] == 1)
    		{	
    			NRF_GPIOTE->EVENTS_IN[0] = 0;
    			counter1++;
    
    		}
    		if(NRF_GPIOTE->EVENTS_IN[1] == 1)
    		{			
    			NRF_GPIOTE->EVENTS_IN[1] = 0;
    			counter2++;
    		}
    }
    ...
    ...
    ...
    nrf_gpio_cfg_input(0, GPIO_PIN_CNF_PULL_Pullup);
    nrf_gpio_cfg_input(1, GPIO_PIN_CNF_PULL_Pullup);
    
    *(volatile uint32_t *)(NRF_GPIOTE_BASE + 0x600 + (4 * 0)) = 1;
    *(volatile uint32_t *)(NRF_GPIOTE_BASE + 0x600 + (4 * 1)) = 1;
    
    NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
    												0 << GPIOTE_CONFIG_PSEL_Pos												 |	
    												GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos;
    
    NRF_GPIOTE->CONFIG[1] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
    												1 << GPIOTE_CONFIG_PSEL_Pos												 |	
    												GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos;	
    
    NRF_GPIOTE->EVENTS_IN[0] = 0;
    NRF_GPIOTE->EVENTS_IN[1] = 0;
    
    NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Enabled << GPIOTE_INTENSET_IN0_Pos | 
    											 GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos ; 
    
    NRF_GPIOTE->POWER = 	GPIOTE_POWER_POWER_Enabled << GPIOTE_POWER_POWER_Pos;
    NVIC_EnableIRQ(GPIOTE_IRQn);

    Then i remake code for nrf 52

    void GPIOTE_IRQHandler(void)
    {
    		if(NRF_GPIOTE->EVENTS_IN[0] == 1)
    		{	
    			NRF_GPIOTE->EVENTS_IN[0] = 0;
    			counter1++;
    		}
    		if(NRF_GPIOTE->EVENTS_IN[1] == 1)
    		{			
    			NRF_GPIOTE->EVENTS_IN[1] = 0;
    			counter2++;
    		}
    }
    ...
    ...
    ...
    nrf_gpio_cfg_input(3, GPIO_PIN_CNF_PULL_Pullup);
    nrf_gpio_cfg_input(4, GPIO_PIN_CNF_PULL_Pullup);
    
    *(volatile uint32_t *)(NRF_GPIOTE_BASE + 0x600 + (4 * 0)) = 1;
    *(volatile uint32_t *)(NRF_GPIOTE_BASE + 0x600 + (4 * 1)) = 1;
    
    NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
    						3 << GPIOTE_CONFIG_PSEL_Pos												 |	
    						GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos;
    
    NRF_GPIOTE->CONFIG[1] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
    						4 << GPIOTE_CONFIG_PSEL_Pos												 |	
    						GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos;	
    
    NRF_GPIOTE->EVENTS_IN[0] = 0;
    NRF_GPIOTE->EVENTS_IN[1] = 0;
    
    NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Enabled << GPIOTE_INTENSET_IN0_Pos | 
    					   GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos ; 
    
    NVIC_SetPriority(2, GPIOTE_IRQn);
    NVIC_DisableIRQ(GPIOTE_IRQn);

    But for nrf52 it doesnt works, it always has double event for EVENTS_IN[1]

  • oh, i find, one of my relay time-to-time works incorrect.

  • Just to confirm; the source of the issue has been found?

     

    Best regards,

    Håkon

Reply Children
No Data
Related