2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ What's the configuration of the "group priority"? why 15 for RTC's priority? that would be better if you would add more descriptions. I don't know what do you want to do!? your first sentence isn't clear to me. \$\endgroup\$ – Roh Sep 10 '14 at 15:59
  • \$\begingroup\$ I'll edit the question to explain the issue better. I haven't configured the group priority, I have read somewhere that the default scheme is having a byte for the preemption priority and a byte for the sub priority. Am I wrong ? \$\endgroup\$ – Mike Sep 10 '14 at 16:03
  • \$\begingroup\$ Do you have any debugger? if so, What do you see in the registers? can you add all codes? What's your IDE? \$\endgroup\$ – Roh Sep 10 '14 at 16:16
  • \$\begingroup\$ I'm using CooCox IDE, and I do have a debugger. Which registers are of interest ? USART_SR - only has TC and TXE bits set = 0xc00c0 USART_CR1 - RXNEIE, TE, RE and UE bits are set = 0x202c USART_CR2 and CR3 are = 0x0000 I don't think posting all of the code will be useful, I'll see what's relevant and see if I can edit the question. \$\endgroup\$ – Mike Sep 10 '14 at 16:47
  • \$\begingroup\$ Did you set NVIC priority group? \$\endgroup\$ – Ashton H. Sep 10 '14 at 17:37
4
\$\begingroup\$

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:

enter image description here

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.

\$\endgroup\$
  • \$\begingroup\$ I have set the priority group to group 4, but I still can't seem to nest them. I have edited the question and added some code. \$\endgroup\$ – Mike Sep 12 '14 at 12:42
2
\$\begingroup\$

Ok, So apparently the STM32 Standard Peripheral Library is totally broken. I have used NVIC_SetPriority to set the priority and it finally worked.

Here is the NVIC code:

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);

    NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(4,0,0));
    NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(4,1,0));
    NVIC_SetPriority(RTCAlarm_IRQn, NVIC_EncodePriority(4,15,0));

}
\$\endgroup\$
  • \$\begingroup\$ Actually, according to this article it is the correct way of assigning priority to some interrupts. I didn't have time to take a look at the reference manual to confirm it thought. \$\endgroup\$ – Ashton H. Sep 12 '14 at 19:04
  • \$\begingroup\$ As for the ST library - I always suggest that people use libopencm3 instead :) \$\endgroup\$ – Ashton H. Sep 12 '14 at 19:05
  • \$\begingroup\$ Or use ChibiOS/RT -- it has a fantastic and clean hardware abstraction layer (HAL), and allows you to actually code portable to other MCUs. \$\endgroup\$ – Colin D Bennett Sep 12 '14 at 19:13
  • \$\begingroup\$ Maybe I'll use one of those on my next project, Thanks though. \$\endgroup\$ – Mike Sep 12 '14 at 20:03
  • \$\begingroup\$ I also think the problem here could've been the fact that the library sets the SysTick interrupt to the lowest priority (15) in SystemInit(), directly opposite what you want (highest priority) and also clashing with your RTCAlarm which has the same priority. \$\endgroup\$ – TisteAndii Aug 27 '18 at 0:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.