Hardfault when using both UART and GPIOTE, how can I solve this problem?

Hello,

I feel like this question has an answer similar to this question, but I can't seem to get it working devzone.nordicsemi.com/.../

I am using the nrf51422 chip on a board I designed myself and I'm using a UART and GPIO interrupt. The UART interrupt works fine on it's own, but as soon as I generate an interrupt on the GPIO, the software goes into hardfault and thus everything stops working. Without UART the GPIO interrupt was working fine.

I'm using the nrf51 DK with the PCA10028 chip on it to program my PCB.

I'm initializing the UART like this:

void init_uart()
{
	uint32_t err_code;
	
	const app_uart_comm_params_t comm_params =
	{
		RX_PIN_NUMBER,
		TX_PIN_NUMBER,
		RTS_PIN_NUMBER,
		CTS_PIN_NUMBER,
		APP_UART_FLOW_CONTROL_DISABLED,
		false,
		0x004EBF00 //just about 19230 baud
	};
		
	APP_UART_FIFO_INIT(&comm_params,
									 UART_RX_BUF_SIZE,
									 UART_TX_BUF_SIZE,
									 uart_error_handle,
									 APP_IRQ_PRIORITY_LOW,
									 err_code);

	APP_ERROR_CHECK(err_code);

and the GPIO interrupt is intitialized like this:

void gpio_init(void)
{
	ret_code_t err_code;
	
	err_code = nrf_drv_gpiote_init();
	APP_ERROR_CHECK(err_code);
		
	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
	nrf_drv_gpiote_in_config_t in_config2 = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
	in_config.pull = NRF_GPIO_PIN_NOPULL;
	in_config2.pull = NRF_GPIO_PIN_NOPULL;
	
	err_code = nrf_drv_gpiote_in_init(encoder_a, &in_config, encoder_a_handler);
	APP_ERROR_CHECK(err_code);
	
	err_code = nrf_drv_gpiote_in_init(encoder_b, &in_config2, encoder_b_handler);
	APP_ERROR_CHECK(err_code);
	
	nrf_drv_gpiote_in_event_enable(encoder_a, true);
	nrf_drv_gpiote_in_event_enable(encoder_b, true);

An interrupt on the UART module is generated like this:

void uart_error_handle(app_uart_evt_t * p_event)
{
		if(p_event->evt_type == APP_UART_DATA_READY)
		{
                                //function to call when data arrives on Rx
				parse();
		}
}

And the interrupt handlers for the gpio look like this (the other handler is similair):

void encoder_b_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t NRF_GPIOTE_POLARITY_TOGGLE)
{
	if(bToggle == false){
		bToggle = true;
	}
	else{
		bToggle = false;
	}
	
	if(aToggle == true)
	{
		encoderCounter--;
		transfer_completed = true;
		printNumber();
		aToggle = false;
		bToggle = false;
	}	
}

As I've said: the answer to this question is probably similair to the one linked above. However, I have checked the interrupt priority in the nrf_drv_gpiote.h, but it was already on a low priority and does not seem to do much when I change it from low to high.

I'm really stumped as to what might cause this problem. Could it the speed at which the UART interrupt is caused? I receive about 33 bytes of data in 17 ms after which I do not receive data for about 58 ms.

  • It seems to be that the problem was in my main.c.

    I called the gpio_init(); function first and the init_uart(); function second. By switching this around the problem seems to be solved.

    I don't know exactly why this is. Does anyone know why this happens? I call both these functions only once, so how does this impact my code?