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

GPIO reading doesn't work (reading 0 all the time) after a certain amount of time.

Hi.

I have NRF52840 with softdevice and GPIO0.7 and 0.27 connected to DALI CLICK and set up and 0.7 - IN, 0.27 OUT.
I'm also using TIMER2 for running callback every 104us , each call to the callback i'm either sampling or setting a gpio (DALI protocol is half duplex by def.)
The problem is that every several minutes the GPIO0.7 stops reading and i need to reset the board (reset using J-link doesn't work, i need to turn it of and on, i'm pulling the usb cable out). for the GPIO to work again.

Yes i'm sure it's the board and not the DALI CLICK cause i disconnected the CLICK's leg off and connected a logic analyzer and could clearly see the data flowing, then connected the click again and restarted using j-link (like isaid before the issue still happens after j-link reset). i could not see any data on the logic analyzer, as if the 0.7 is suddenly connected to ground all the time.

In my setup i have another DALI CLICK connected to the logic analyzer and not connected to any dev board (as a niffer) and in every case i can see that the data is sent AND sent back, so i know it's the GPIO that doesn't receives it.

Here is the GPIO start code:

ret_code_t err_code;
err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);

nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
nrf_drv_gpiote_in_init(NRF_GPIO_PIN_MAP(0,7), &config, NULL);

when i need to read:

uint8_t data = nrf_gpio_pin_read(NRF_GPIO_PIN_MAP(0,7));

setting up the timer:

void Timer_DALI_Init() 
{
    NRF_TIMER2->MODE = 0UL;
	NRF_TIMER2->BITMODE = 3UL;
	NRF_TIMER2->PRESCALER = 4UL; // 1000000 times / sec  => f=16MHZ/(2^PRESCALAR)
	NRF_TIMER2->CC[0] = 104UL; // (104us)
	NRF_TIMER2->INTENSET = (unsigned long) (1 << 16); // Compare with 0
	NRF_TIMER2->SHORTS = 1;  // Clear the timer when COMPARE0 event is triggered

	__sd_nvic_irq_enable();
	sd_nvic_SetPriority(TIMER2_IRQn, 3);

}

void Timer_Stop(void) {	
    sd_nvic_DisableIRQ(TIMER2_IRQn);
}

void Timer_Start(void) {
   //reset tick and bit counters
	tick_count = 0;
	bit_count = 0;
	sd_nvic_EnableIRQ(TIMER2_IRQn);
	NRF_TIMER2->TASKS_CLEAR = 1;               // clear the task first to be usable for later
	NRF_TIMER2->TASKS_START = 1UL;
}


void TIMER2_IRQHandler(void)
{
	volatile uint32_t dummy;
	if (DALI_NRF_TIMER->EVENTS_COMPARE[0] == 1)
	{
		DALI_ISR_Callback();
		NRF_TIMER2->EVENTS_COMPARE[0] = 0;
		// Read back event register so ensure we have cleared it before exiting IRQ handler.
		dummy = NRF_TIMER2->EVENTS_COMPARE[0];
		dummy; // to get rid of set bt not used warning
	}
}

DALI_ISR_Callback is the function that runs every 104us and calls nrf_gpio_pin_write and nrf_gpio_pin_read when needed.

Any hints ?

Related