cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to initialise interrupts || Nucleo - F746ZG

MShar.7
Associate II

Hi everyone,

I am new to the world of STM32 MCU's so please bear with me.

I am following a tutorial on Udemy and trying to write a GPIO interrupt code from scratch. I have done all register configurations and config is working fine as seen through SFR view in debug mode but when I run the code it seems like the interrupt is not enabled. The code never comes in the handler function.

#include <string.h>
#include "stm32f746xx.h"
#include "stm32f746xx_gpio_driver.h"
 
void delay(void){
	for(uint32_t i=0; i<100000; i++);
}
 
int main(){
 
	GPIO_PeriClockControl(GPIOC,ENABLE);
	GPIO_PeriClockControl(GPIOB,ENABLE);
 
	GPIO_Handle_t LED, BTN;
	memset(&LED, 0, sizeof(LED));
	memset(&BTN, 0, sizeof(BTN));
 
	LED.pGPIOx = GPIOB;
	LED.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_14;
	LED.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_OUT;
	LED.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_PP;
	LED.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
	LED.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_NO_PUPD;
 
	GPIO_Init(&LED);
 
	LED.pGPIOx = GPIOB;
	LED.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_7;
	LED.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_OUT;
	LED.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_PP;
	LED.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
	LED.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_NO_PUPD;
 
	GPIO_Init(&LED);
 
	BTN.pGPIOx = GPIOC;
	BTN.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_13;
	BTN.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_IT_FT;
	BTN.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
	BTN.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_PIN_PU;
 
	GPIO_Init(&BTN);
 
	//IRQ interrupt and priority configuration
	GPIO_IRQPriorityConfig(IRQ_NO_EXTI10_15,NVIC_IRQ_PRIO_15);
	GPIO_IRQIntConfig(IRQ_NO_EXTI10_15,ENABLE);
 
	while(1);
}
 
void EXTI15_10_IRQHandle(void){
	delay();
	GPIO_IRQHandling(GPIO_PIN_NO_13);
	GPIO_ToggleOutputPin(GPIOB,GPIO_PIN_NO_14);
	GPIO_ToggleOutputPin(GPIOB,GPIO_PIN_NO_7);
}
/*
 * stm32f746xx_gpio_driver.c
 */
 
#include "stm32f746xx_gpio_driver.h"
 
/*
 * peripheral clock setup
 */
void GPIO_PeriClockControl(GPIO_RegDef_t *pGPIOx, uint8_t EnOrDis){
	if(EnOrDis == ENABLE){
		if(pGPIOx == GPIOA){
			GPIOA_PCLK_EN();
		}else if(pGPIOx == GPIOB){
			GPIOB_PCLK_EN();
		}else if(pGPIOx == GPIOC){
			GPIOC_PCLK_EN();
		}else if(pGPIOx == GPIOD){
			GPIOD_PCLK_EN();
		}else if(pGPIOx == GPIOE){
			GPIOE_PCLK_EN();
		}else if(pGPIOx == GPIOF){
			GPIOF_PCLK_EN();
		}else if(pGPIOx == GPIOG){
			GPIOG_PCLK_EN();
		}else if(pGPIOx == GPIOH){
			GPIOH_PCLK_EN();
		}else if(pGPIOx == GPIOI){
			GPIOI_PCLK_EN();
		}else if(pGPIOx == GPIOJ){
			GPIOJ_PCLK_EN();
		}else if(pGPIOx == GPIOK){
			GPIOK_PCLK_EN();
		}
	} else {
		if(pGPIOx == GPIOA){
			GPIOA_PCLK_DIS();
		}else if(pGPIOx == GPIOB){
			GPIOB_PCLK_DIS();
		}else if(pGPIOx == GPIOC){
			GPIOC_PCLK_DIS();
		}else if(pGPIOx == GPIOD){
			GPIOD_PCLK_DIS();
		}else if(pGPIOx == GPIOE){
			GPIOE_PCLK_DIS();
		}else if(pGPIOx == GPIOF){
			GPIOF_PCLK_DIS();
		}else if(pGPIOx == GPIOG){
			GPIOG_PCLK_DIS();
		}else if(pGPIOx == GPIOH){
			GPIOH_PCLK_DIS();
		}else if(pGPIOx == GPIOI){
			GPIOI_PCLK_DIS();
		}else if(pGPIOx == GPIOJ){
			GPIOJ_PCLK_DIS();
		}else if(pGPIOx == GPIOK){
			GPIOK_PCLK_DIS();
		}
	}
}
 
/*
 * init and deInit
 */
void GPIO_Init(GPIO_Handle_t *pGPIOHandle){
	uint32_t temp = 0;
	if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode <= GPIO_MODE_ANALOG){
		temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
		pGPIOHandle->pGPIOx->MODER &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing ; always clear before setting
		pGPIOHandle->pGPIOx->MODER |= temp; // setting
	} else {
 
		// 1. configure RTSR / FTSR
		if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_FT){
			(*EXTI).FTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
			(*EXTI).RTSR &= ~(1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // coz we only want FT, clear the corresponding RTSR bit; just to be safe if it is not already cleared for some reason
		} else if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RT){
			(*EXTI).RTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
			(*EXTI).FTSR &= ~(1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
		} else if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RFT){
			(*EXTI).RTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
			(*EXTI).FTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
		}
 
		// 2. config the gpio port selection in SYSCFG_EXTICR
		uint8_t temp1 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 4;
		uint8_t temp2 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 4;
		uint8_t portcode = GPIO_BASEADDR_TO_CODE(pGPIOHandle->pGPIOx);
		SYSCFG_PCLK_EN();
		(*SYSCFG).EXTICR[temp1] = portcode << (temp2 * 4);
 
		// 3. enable the exti interrupt delivery using IMR
		(*EXTI).IMR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
	}
	temp = 0;
 
	temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinSpeed << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
	pGPIOHandle->pGPIOx->OSPEEDR &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
	pGPIOHandle->pGPIOx->OSPEEDR |= temp; // setting
	temp = 0;
 
	temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinPuPdControl << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
	pGPIOHandle->pGPIOx->PUPDR &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
	pGPIOHandle->pGPIOx->PUPDR |= temp; // setting
	temp = 0;
 
	temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinOPType << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
	pGPIOHandle->pGPIOx->OTYPER &= ~(0x01 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
	pGPIOHandle->pGPIOx->OTYPER |= temp; // setting
	temp = 0;
 
	if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_ALTFN){
		uint8_t temp1 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 8;
		uint8_t temp2 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 8;
		pGPIOHandle->pGPIOx->AFR[temp1] &= ~(0x0f << (4* temp2)); // clearing
		pGPIOHandle->pGPIOx->AFR[temp1] |= pGPIOHandle->GPIO_PinConfig.GPIO_PinAltFunMode << (4* temp2); // setting
	}
}
 
void GPIO_DeInit (GPIO_RegDef_t *pGPIOx){
	if(pGPIOx == GPIOA){
		GPIOA_REG_RESET();
	}else if(pGPIOx == GPIOB){
		GPIOB_REG_RESET();
	}else if(pGPIOx == GPIOC){
		GPIOC_REG_RESET();
	}else if(pGPIOx == GPIOD){
		GPIOD_REG_RESET();
	}else if(pGPIOx == GPIOE){
		GPIOE_REG_RESET();
	}else if(pGPIOx == GPIOF){
		GPIOF_REG_RESET();
	}else if(pGPIOx == GPIOG){
		GPIOG_REG_RESET();
	}else if(pGPIOx == GPIOH){
		GPIOH_REG_RESET();
	}else if(pGPIOx == GPIOI){
		GPIOI_REG_RESET();
	}else if(pGPIOx == GPIOJ){
		GPIOJ_REG_RESET();
	}else if(pGPIOx == GPIOK){
		GPIOK_REG_RESET();
	}
}
 
 
/*
 * data read and write
 */
uint8_t GPIO_ReadFromInputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber){
	uint8_t value;
	value = (uint8_t)((pGPIOx->IDR >> PinNumber) & 0x00000001);
	return value;
}
 
uint16_t GPIO_ReadFromInputPort(GPIO_RegDef_t *pGPIOx){
	uint16_t value;
	value = pGPIOx->IDR;
	return value;
}
 
void GPIO_WriteToOutputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber, uint8_t value){
	if(value == GPIO_PIN_SET){
		pGPIOx->ODR |= (1 << PinNumber);
	} else if(value == GPIO_PIN_CLEAR || value == GPIO_PIN_RESET){
		pGPIOx->ODR &= ~(1 << PinNumber);
	}
}
 
void GPIO_WriteToOutputPort(GPIO_RegDef_t *pGPIOx, uint16_t value){
	pGPIOx->ODR = value;
}
 
void GPIO_ToggleOutputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber){
	pGPIOx->ODR ^= (1 << PinNumber);
}
 
/*
 * IRQ configuration and ISR handling
 */
 
// IRQConfig is for config in processor side
void GPIO_IRQIntConfig(uint16_t IRQNumber, uint8_t EnOrDis){
	if(EnOrDis == ENABLE){
//		*(NVIC_ISER0 + (((uint32_t)(int32_t)IRQNumber) >> 5UL)) = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQNumber) & 0x1FUL));
		if(IRQNumber <= 31){
			(*NVIC_ISER0) |= (1<<IRQNumber);
		} else if((IRQNumber > 31) && (IRQNumber <= 63)){
			 (*NVIC_ISER1) |= (1<<(IRQNumber%32));
		} else if((IRQNumber > 63) && (IRQNumber <= 95)){
			(*NVIC_ISER2) |= (1<<(IRQNumber%64));
		} else if(IRQNumber > 95){
			(*NVIC_ISER3) |= (1<<(IRQNumber%96));
		}
	} else if (EnOrDis == DISABLE){
		if(IRQNumber <= 31){
			(*NVIC_ICER0) |= (1<<IRQNumber);
		} else if((IRQNumber > 31) && (IRQNumber <= 63)){
			(*NVIC_ICER1) |= (1<<(IRQNumber%32));
		} else if((IRQNumber > 63) && (IRQNumber <= 95)){
			(*NVIC_ICER2) |= (1<<(IRQNumber%64));
		} else if(IRQNumber > 95){
			(*NVIC_ICER3) |= (1<<(IRQNumber%96));
		}
	}
}
 
void GPIO_IRQPriorityConfig(uint16_t IRQNumber, uint16_t IRQPriority){
	// 1. find the ipr register and section
	uint32_t iprx = IRQNumber / 4;
	uint32_t iprx_section = IRQNumber % 4;
 
	// 2. store the value
	uint8_t shift_value = (8*iprx_section) + (8-NO_IPR_BITS_IMPLEMENTED); // need to move more by (8-NO_IPR_BITS_IMPLEMENTED) bits, since not all of 8 bits are used..
	uint16_t temp = (IRQPriority << shift_value);
	*(NVIC_IPR_BASEADDR + iprx) |= temp; // iprx is multiplied by 4 because each address jump is of 4 bytes..
}
 
void GPIO_IRQHandling(uint8_t PinNumber){
	// clear the exti pr register bit corresponding to the pin number
	if((*EXTI).PR & (1<<PinNumber)){
		(*EXTI).PR |= ( 1 << PinNumber );
	}
}

Please help me find the issue.

Thanks!

4 REPLIES 4

void EXTI15_10_IRQHandle(void)

IRQHandler not IRQHandle

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
MShar.7
Associate II

Thanks a lot Tesla!

This i have changed now and the breakpoint inside the handler is now getting that tick mark which earlier it was not showing.

But still, on pressing the button it is not entering the handler.

Andrew Neil
Evangelist III

"I am following a tutorial on Udemy"

Don't Udemy have tutors to help their students?

"pressing the button"

What button?

MShar.7
Associate II

"Don't Udemy have tutors to help their students?"

Courses there are usually old and most teachers are generally not that active. Nevertheless i will definitely post my queries there as well but my expectation of a reply is pretty low.

"What button?"

The blue button on nucleo-F746ZG.. it is connected to PORTC pin 13 as can see in the code.

normal GPIO functionality is working fine. its just the interrupt part that's giving problems.