2024-12-13 05:37 AM - edited 2024-12-13 05:38 AM
Hello,
STM32CubedIDE, STM407G DISC1 BOARD
I am trying to trigger an external interrupt by using a button connected to PA1 pin.
My configurations are below;
1-) I enabled 7.bit in NVIC_ISER register. IRQN_EXTI0 is enabled
2-) I enabled GPIOAEN in RCC register. GPIOA clock is enabled.
3-) I wrote '1' into the TR1 in EXTI> RTRS register for RISING EDGE.
4-) I enabled SYSCFG clock.
5-) Although the reset value is already '0'(which is corresponding to A Port)
for SYSCFG_EXTICR1> EXTI1, I wrote '0' again for Port A and pin 1(EXTI1)
6-) I set EXTI>IMR> MR1 bit in the register for not masking the line 1( due to being 1.pin )
7-) Other pin configurations are, Pull-Down, High-Speed and Push-Pull for OTYPE
I succeed in making it work for PA0 and PB0 external interrupts individually.I debugged each step and it seems everything is fine. I suspect due to I use first pin, I am missing something here.I haven't figured it out yet. However, PA0 and PA1 share most register common.Only difference could be the MR bits but I have checked them several times.
For better understanding, I tried to capture the high logic with a single LED using PA1 button, after I configurated it identically as in the above.Result is positive, I can capture it is able to be high but cannot trigger interrupt. What am I missing? I am looking forward to handle the issue. Thank you for your assistance.
Respects Khansokhua
Solved! Go to Solution.
2024-12-13 07:38 AM - edited 2024-12-13 07:48 AM
The 0..15 relate to the pin# in ONE bank, PA13 would dump into EXTI15_10_IRQHandler
Perhaps review the diagram/illustration in the Reference Manual (RM0090) describing HOW things work.
DCD EXTI0_IRQHandler ; EXTI Line0
DCD EXTI1_IRQHandler ; EXTI Line1
DCD EXTI2_IRQHandler ; EXTI Line2
DCD EXTI3_IRQHandler ; EXTI Line3
DCD EXTI4_IRQHandler ; EXTI Line4
...
DCD EXTI9_5_IRQHandler ; External Line[9:5]s
...
DCD EXTI15_10_IRQHandler ; External Line[15:10]s
You'd generally put the higher priority ones on lower pin#, but it's a bit of a wash, especially with the layers of inefficiency HAL/CUBE add.
Avoid doing too much in IRQ / Callback context, do what you need quickly and leave.
2024-12-13 05:47 AM
Hello @Khansokhua and welcome to the community,
I suggest you starting by programming with HAL and especially inspiring from this example:
If it does work you can move forward and go with programming doing direct access to the registers inspiring from the HAL implementation.
2024-12-13 05:54 AM
Thank you! @SofLit I am also planning to use HAL. However, I need some clarification for my current position right now. What do you think the problem is here?
2024-12-13 06:10 AM - edited 2024-12-13 06:17 AM
Bit 0 is 0x01
Bit 1 is 0x02
EXTI1_IRQHandler ; EXTI Line1
void EXTILine1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
/* Enable GPIOA clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure PA1 pin as input floating */
GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Pin = GPIO_PIN_1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable and set EXTI Line1 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI1_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
}
void EXTI1_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}
2024-12-13 06:44 AM
You just tell by text what you did and this is not efficient. You need to share your code.
And again, please inspire from the HAL implementation to know how to implement a correct sequence of the direct access to the register.
@Tesla DeLorean gave you an example of using HAL.
2024-12-13 07:17 AM
Thank you for your answer @Tesla DeLorean . I use EXTI0_IRQHandler, for PA1.
I thought, 0-3 pins EXTI0, 4-7 EXTI1 8-11 EXTI2, 12-15 EXTI3.
Here my question, if I need to use EXTI1_IRQHandler for PA1 external interrupt.
Then which handler do I need to use for (let's say) PA13 external interrupt? What is the rule here?
and If I have to use EXTI1_IRQHandler for PA1. I guess I also need to enable IRQN_EXTI1. Then from starting previous example how do I need to enable corresponding bit in ISER?
It seems I mixed some terms up.I will send the code for better clarity.You are absolutely right @SofLit
So you can assist me more efficiently.
2024-12-13 07:24 AM - edited 2024-12-13 07:25 AM
void EXTI0_IRQHandler(void)
{
if(EXTI->PR & (1u << 0))
{
GPIOD->ODR |= (1u << 13);
EXTI_SET_PR_0();
}
else if(EXTI->PR & (1u << 1))
{
GPIOD->ODR |= (1u << 13);
EXTI_SET_PR_1();
}
}
int main(void)
{
GPIO_Handle_t EXTI_A0 = { .PORTNAME = GPIOA,
.PINCONF.PIN = GPIO_PIN_0,
.PINCONF.MODE = GPIO_MODE_INT_RISING,
.PINCONF.OTYPE = GPIO_OTYPE_PP,
.PINCONF.OSPEED = GPIO_OSPEED_HIGH,
.PINCONF.PUPD = GPIO_PUPD_PD,
.PINCONF.AF = GPIO_AF_NO
};
GPIO_Handle_t EXTI_A1 = { .PORTNAME = GPIOA,
.PINCONF.PIN = GPIO_PIN_1,
.PINCONF.MODE = GPIO_MODE_INT_RISING,
.PINCONF.OTYPE = GPIO_OTYPE_PP,
.PINCONF.OSPEED = GPIO_OSPEED_HIGH,
.PINCONF.PUPD = GPIO_PUPD_NO,
.PINCONF.AF = GPIO_AF_NO
};
GPIO_Handle_t orange_LED = { .PORTNAME = GPIOD,
.PINCONF.PIN = LED_ORANGE,
.PINCONF.MODE = GPIO_MODE_OUTPUT,
.PINCONF.OTYPE = GPIO_OTYPE_PP,
.PINCONF.OSPEED = GPIO_OSPEED_HIGH,
.PINCONF.PUPD = GPIO_PUPD_PD ,
.PINCONF.AF = GPIO_AF_NO
};
gpioInit(&orange_LED);
nvicInterruptEnable(IRQN_EXTI0);
gpioInit(&EXTI_A1); // gpioInit includes SYSCFG, IMR etc configuration
gpioInit(&EXTI_A0); // A0 works fine
while(1)
{
}
}
2024-12-13 07:26 AM - edited 2024-12-13 07:28 AM
@Khansokhua wrote:
Here my question, if I need to use EXTI1_IRQHandler for PA1 external interrupt.
Then which handler do I need to use for (let's say) PA13 external interrupt? What is the rule here?.
It depend on the product:
but the rule for PYn and EXTIm_IRQHandler: where Y is the port and n is the pin number, m the available EXTI line number or range.
So n needs to be = m if m is a value or at least n needs to be in the range of m.
Example for STM32F405 product:
If you need to use PA7 as source of EXTI interrupt you need to use
EXTI9_5_IRQHandler(): 7 is in the range of [5..9]
2024-12-13 07:38 AM
I can only see five handler in start-up file for STM407.
.word EXTI0_IRQHandler /* EXTI Line0 interrupt */
.word EXTI1_IRQHandler /* EXTI Line1 interrupt */
.word EXTI2_IRQHandler /* EXTI Line2 interrupt */
.word EXTI3_IRQHandler /* EXTI Line3 interrupt */
.word EXTI4_IRQHandler /* EXTI Line4 interrupt */
2024-12-13 07:38 AM - edited 2024-12-13 07:48 AM
The 0..15 relate to the pin# in ONE bank, PA13 would dump into EXTI15_10_IRQHandler
Perhaps review the diagram/illustration in the Reference Manual (RM0090) describing HOW things work.
DCD EXTI0_IRQHandler ; EXTI Line0
DCD EXTI1_IRQHandler ; EXTI Line1
DCD EXTI2_IRQHandler ; EXTI Line2
DCD EXTI3_IRQHandler ; EXTI Line3
DCD EXTI4_IRQHandler ; EXTI Line4
...
DCD EXTI9_5_IRQHandler ; External Line[9:5]s
...
DCD EXTI15_10_IRQHandler ; External Line[15:10]s
You'd generally put the higher priority ones on lower pin#, but it's a bit of a wash, especially with the layers of inefficiency HAL/CUBE add.
Avoid doing too much in IRQ / Callback context, do what you need quickly and leave.