2010-09-13 02:47 PM
External Interrupt Problem (EXTI) - EXTI_Line4
2011-05-17 05:06 AM
I am having a problem with EXTI_Line4. There is an external chip that is driving this signal. At the time I configure this chip (via Init() routine ) I turn off the interrupt until I finish initialization. However, this chip generates an interrupt just before I enable this pin.
Why is it that as soon as I enable this pin to generate an interrupt it does not do so. I would figure the edge detection circuitry found this wild the interrupt was disabled and should report it instantly when the interrupt is enabled to fire the interrupt.
Your English is a little tortured, I'm having a hard time deciphering it. You have a race condition? You need to enable the interrupt earlier? The external chip generates a pulse, while you are initializing the STM32 and/or the External chip, and the STM32 does not react/interrupt because it missed the signal from your external chip? Does it react subsequently when another pulse comes in and it is enabled? Why would you expect the STM32 to detect/store/act-on a external input that occurs BEFORE you enable the STM32 to do so? The pin is almost certainly synchronized, and then a change observed between states stored between two adjacent clock periods. The fact it transitioned sometime in the distant past will be lost. You clearly need to enable the interrupt before the device is going to generate it, not after the fact. You might also be able to check the state of you external chip after you have enabled interrupts to see if one is already pending, and that has been missed.
2011-05-17 05:06 AM
This has to do with the order of operation in which the subsystems in the microcontroller (STM32F103). The basic steps can be broken down into:
1) Configure Interrupt initialization 2) Enable Interrupt 3) Disable Interrupt 4) Clear Interrupts 5) ISR function The key is to configure the hardware before interrupt occurs (initialization). This will ensure that if the interrupt is disabled and the interrupt occurs, the ISR will fire after the enable interrupt function is called. The sample code is below: void InterruptConfigure(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; // Enable interrupt pin Clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); // Configure interrupt pin as input floating GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_Init(GPIOC, &GPIO_InitStructure); // Connect EXTI Line to Pin GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4); // Configure EXTI line EXTI_InitStructure.EXTI_Line = EXTI_Line4; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); } /* End of InterruptConfigure() */ void InterruptDisable(void) { NVIC_InitTypeDef NVIC_InitStructure; // Enable and set EXTI Interrupt to the lowest priority NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&NVIC_InitStructure); } /* End of InterruptDisable() */ void InterruptEnable(void) { NVIC_InitTypeDef NVIC_InitStructure; // Enable and set Button EXTI Interrupt to the lowest priority NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /* End of InterruptEnable() */ void InterruptClear(void) { EXTI_ClearITPendingBit(EXTI_Line4); } /* End of InterruptClear() */ void EXTI4_IRQHandler(void) { // Check the Port C pin 4 first if(EXTI_GetITStatus(EXTI_Line4) != RESET) { // TODO: Add Code here for Application } } /* End of EXTI4_IRQHandler() */2011-05-17 05:06 AM
Sorry about the English. I was trying to get this post in before a meeting.
The reason for this question is because I have two pieces of firmware. In one of them the Interrupt Line (Port C pin 4) is driven low when the interrupt is disabled. When the interrupt is enabled, the processor call the ISR immediately. This is why in most processors the interrupt flag is cleared before enabling the interrupt. In the second firmware project the same thing is happening but the ISR is not being called. It almost seems like another hardware component is not configured before this one. For instance, the pending request register. This seems to be the prevailing procedure for processors: interrupt flag and interrupt enable. If the flag is not cleared, but the interrupt is enabled the ISR will get called as soon as the enable becomes asserted.