I'm trying to interrupt into a USART handler from inside an RTC_Alarm handler, but it doesn't work.
I have set the NVIC:
void NVIC_Configuration() {
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_SetPriorityGrouping(NVIC_PriorityGroup_4);
/* Configure UART IRQ */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Configure RTC Alarm IRQ */
NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
I have also noticed that my SysTick handler also isn't running while executing code inside the RTC_Alarm handlers.
How do I get the interrupt to nest ?
Here is some of the rest of the code:
So I have this loop waiting for an interrupt from a UART to set the CurrentMode, but the interrupt never occurs. The same interrupt works in the rest of the code.
void RTCAlarm_IRQHandler() {
/* Reset the Alarm in 24 Hours */
RTC_Set_Alarm(FALSE, (Get_Alarm_Time() + 3600*24));
RTC_ClearITPendingBit(RTC_IT_ALR);
EXTI_ClearITPendingBit(EXTI_Line17);
RTC_WaitForLastTask();
Op_Mode_Type SwapTemp = CurrentMode;
CurrentMode = ModeOnAlarm;
Alarm_Mode(SwapTemp);
}
void Alarm_Mode(Op_Mode_Type Initial_Mode) {
/* Enable USART Interrupt */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_EnableIRQ(USART1_IRQn);
switch (ModeOnAlarm)
{
case Op_Mode_Single_Color:
Set_Color(&Alarm_Color);
while(CurrentMode == Op_Mode_Single_Color); //TODO - Add Timeout + UART Isn't interrupting here
break;
//Some more cases here....
}
CurrentMode = Initial_Mode;
}
void USART1_IRQHandler() {
uint8_t data;
if (USART_GetITStatus(USART1,USART_IT_RXNE)) {
data = USART_ReceiveData(USART1);
CurrentMode = (Op_Mode_Type)(data);
USART_ClearITPendingBit(USART1, USART_IT_RXNE); // Clear interrupt flag
/* Disable USART Interrupt */
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
NVIC_DisableIRQ(USART1_IRQn);
}
}
Functionally I don't really need to use the interrupt in this code, but I want to understand why doesn't it work.
Best Answer
Since you have not assigned NVIC priority group, it is left with a default value of 2. This means that you have 2 bits for preemption priority and 2 bits for sub-priority. That allows you to use priority levels from 0 to 3 (2^n). Allowed priority levels for each group are illustrated in the following table:
As you can see, Group 4 has to be used in order to set preemption priority levels 0-15.
You may leave the group unassigned for UART interrupt (since it will be assigned to group 2 by default).
For more information and examples you can refer to this article.