cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple GPIO interrupts firing when only one is triggered

DSabo
Associate III

I am using the STM32 Nucleo F411RE, and have 5 GPIO pins set up as inputs, each set to trigger an interrupt on the rising and falling edge, configured to use the internal pull down.

However, what I am finding is that causing a level change on one of the pins is triggering an interrupt for all of them.

At first I thought it might be cross talk between the pins, but I added external pull down resistors of 10k to ground and the issue is still there.

So I'm assuming either my configuration is wrong, or my interrupt handlers are, but I don't see any issue..

#define PEDAL_CLAMP_Pin GPIO_PIN_2
#define PEDAL_CLAMP_GPIO_Port GPIOC
#define PEDAL_FORWARD_Pin GPIO_PIN_3
#define PEDAL_FORWARD_GPIO_Port GPIOC
#define PEDAL_REVERSE_Pin GPIO_PIN_6
#define PEDAL_REVERSE_GPIO_Port GPIOC
#define PEDAL_UNCLAMP_Pin GPIO_PIN_8
#define PEDAL_UNCLAMP_GPIO_Port GPIOC
#define SWITCH_PRESSURE_Pin GPIO_PIN_10
#define SWITCH_PRESSURE_GPIO_Port GPIOC
 
void MX_PedalSwitches_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	BaseType_t createStatus = pdFAIL; // Init to fail to be safe
 
	/* GPIO Ports Clock Enable */
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOH_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
 
	GPIO_InitStruct.Pin = PEDAL_CLAMP_Pin|PEDAL_UNCLAMP_Pin|PEDAL_FORWARD_Pin|PEDAL_REVERSE_Pin
						  |SWITCH_PRESSURE_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
	GPIO_InitStruct.Pull = GPIO_PULLDOWN;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
	HAL_NVIC_SetPriority(EXTI15_10_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
	HAL_NVIC_SetPriority(EXTI3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
	HAL_NVIC_SetPriority(EXTI2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
	HAL_NVIC_SetPriority(EXTI9_5_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
 
	HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
	HAL_NVIC_EnableIRQ(EXTI3_IRQn);
	HAL_NVIC_EnableIRQ(EXTI2_IRQn);
	HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
 
	createStatus = xTaskCreate(SwitchDebounceTask, "Pedal Switch task", configMINIMAL_STACK_SIZE,(void*) NULL,1, &switchTaskHandle);
	configASSERT(createStatus == pdPASS);
}
 
void EXTI2_IRQHandler(void)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
 
	uint32_t notifyValue = 0;
 
	if(__HAL_GPIO_EXTI_GET_IT(PEDAL_CLAMP_Pin) != RESET)
	{
		notifyValue = 1 << PEDAL_CLAMP_PRESSED;
 
		xTaskNotifyFromISR(switchTaskHandle, notifyValue, eSetBits, &xHigherPriorityTaskWoken);
	}
 
	__HAL_GPIO_EXTI_CLEAR_IT(PEDAL_CLAMP_Pin);
 
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
 
void EXTI3_IRQHandler(void)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
	uint32_t notifyValue = 0;
 
	if(__HAL_GPIO_EXTI_GET_IT(PEDAL_FORWARD_Pin) != RESET)
	{
		notifyValue = 1 << PEDAL_FORWARD_PRESSED;
		xTaskNotifyFromISR(switchTaskHandle, notifyValue, eSetBits, &xHigherPriorityTaskWoken);
 
    }
 
	__HAL_GPIO_EXTI_CLEAR_IT(PEDAL_FORWARD_Pin);
 
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
 
void EXTI9_5_IRQHandler(void)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
	uint32_t notifyValue = 0;
 
	if(__HAL_GPIO_EXTI_GET_IT(PEDAL_REVERSE_Pin) != RESET)
	{
		notifyValue = 1 << PEDAL_REVERSE_PRESSED;
 
		xTaskNotifyFromISR(switchTaskHandle, notifyValue, eSetBits, &xHigherPriorityTaskWoken);
 
		__HAL_GPIO_EXTI_CLEAR_IT(PEDAL_REVERSE_Pin);
    }
 
	if(__HAL_GPIO_EXTI_GET_IT(PEDAL_UNCLAMP_Pin) != RESET)
	{
		notifyValue = 1 << PEDAL_UNCLAMP_PRESSED;
 
		xTaskNotifyFromISR(switchTaskHandle, notifyValue, eSetBits, &xHigherPriorityTaskWoken);
 
		__HAL_GPIO_EXTI_CLEAR_IT(PEDAL_UNCLAMP_Pin);
    }
 
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
 
void EXTI15_10_IRQHandler(void)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
 
	uint32_t notifyValue = 0;
 
	HAL_EXTI_IRQHandler(&H_EXTI_13);
 
	if(__HAL_GPIO_EXTI_GET_IT(SWITCH_PRESSURE_Pin) != RESET)
	{
		notifyValue = 1 << SWITCH_PRESSURE_PRESSED;
 
		xTaskNotifyFromISR(switchTaskHandle, notifyValue, eSetBits, &xHigherPriorityTaskWoken);
 
		__HAL_GPIO_EXTI_CLEAR_IT(SWITCH_PRESSURE_Pin);
    }
 
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

9 REPLIES 9

Can you replicate this behaviour in a simple/minimal, non-RTOS, implementation?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
turboscrew
Senior III

Does it still do that, if you add clearing of interrupts before enabling them? Rather before setting priorities.

DSabo
Associate III

After clearing interrupts before setting priorities it still does it... I'm working on putting a simple example together to try it, but it may be a few days before I can get to it

Piranha
Chief II
HAL_EXTI_IRQHandler(&H_EXTI_13);

If you process interrupt with your code, why to you need this?

> However, what I am finding is that causing a level change on one of the pins is triggering an interrupt for all of them.

How exactly do you determine that?

I'll have to look at that.. I think it was auto generated.

I have different tasks running that process each interrupt, when the interrupt occurs I send a flag to the task, which then unblocks and does something... I can see all the tasks unblocking

DSabo
Associate III

Are some of the GPIO pins only 3.3V tolerant as inputs? As I've been looking into this more I've seen some references to that, but I didn't see anything in the data sheet...I didn't realize this and have been using 5V signals.

DSabo
Associate III

I reproduced the behavior without freertos, I did everything in main... I hooked up a scope on one of the lines and there is tons of noise, with spikes over 2.5 volts.

For now I've transitioned to polling instead of using interrupts until I can sort this out more.

I added external pull down resistors without changing the behavior

RafaelSTM32
Associate III

Same problem, I tried this to debug and both ent1 and ent2 are loaded with 1 at same time

 

void EXTI0_IRQHandler(void)

{

/* USER CODE BEGIN EXTI0_IRQn 0 */

ent1 = 1;

/* USER CODE END EXTI0_IRQn 0 */

HAL_GPIO_EXTI_IRQHandler(IN_1_Pin);

/* USER CODE BEGIN EXTI0_IRQn 1 */

 

/* USER CODE END EXTI0_IRQn 1 */

}

 

/**

* @brief This function handles EXTI line1 interrupt.

*/

void EXTI1_IRQHandler(void)

{

/* USER CODE BEGIN EXTI1_IRQn 0 */

ent2 = 1;

/* USER CODE END EXTI1_IRQn 0 */

HAL_GPIO_EXTI_IRQHandler(IN_2_Pin);

/* USER CODE BEGIN EXTI1_IRQn 1 */

 

/* USER CODE END EXTI1_IRQn 1 */

}

I have 16 exti's but I only programmed 2, exti0 and exti1 to start the develop, when I trigger the first the second is triggered also and viceversa

I tried with irq0 for all and after that I tried with irq0 for exti0, irq1 for exti1 and so on