Skip to main content
Graduate
December 13, 2024
Solved

PA1 EXTERNAL INTERRUPT ISSUE

  • December 13, 2024
  • 4 replies
  • 2137 views

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

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    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.

    4 replies

    Technical Moderator
    December 13, 2024

    Hello @Khansokhua and welcome to the community,

    I suggest you starting by programming with HAL and especially inspiring from this example:

    https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM32F4-Discovery/Examples/GPIO/GPIO_EXTI

    If it does work you can move forward and go with programming doing direct access to the registers inspiring from the HAL implementation.

    Graduate
    December 13, 2024

    Thank you! @mƎALLEm 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?

    Technical Moderator
    December 13, 2024

    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.

     

    Graduate II
    December 13, 2024

    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);
    }
    Graduate
    December 13, 2024

    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 @mƎALLEm 

    So you can assist me more efficiently.

    Technical Moderator
    December 13, 2024

    @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]

     

     

    Graduate
    December 13, 2024

     

    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)
     {
     }
    }