cancel
Showing results for 
Search instead for 
Did you mean: 

Help with RTC, HSE and Interrupt

Palacios.Bruno
Associate III
Posted on September 10, 2014 at 22:43

Hello guys, I am having some problems with the following code:

void RTC_Configuration(void)

{

RTC_InitTypeDef RTC_InitStructure;

RTC_TimeTypeDef RTC_TimeStructure;

RTC_DateTypeDef RTC_DateStructure;

NVIC_InitTypeDef NVIC_InitStructure;

EXTI_InitTypeDef EXTI_InitStructure;

/* Enable the PWR clock */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

/* Allow access to RTC */

PWR_BackupAccessCmd(ENABLE);

// Reset the backup domain, clear RTC

RCC_BackupResetCmd(ENABLE);

RCC_BackupResetCmd(DISABLE);

if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) /* HSE Already running? */

{

/* Enable the LSI OSC */

RCC_HSEConfig(RCC_HSE_ON);

/* Wait till LSI is ready */

while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

}

/* Select the RTC Clock Source */

RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div8);

/* Enable the RTC Clock */

RCC_RTCCLKCmd(ENABLE);

/* Wait for RTC APB registers synchronisation */

RTC_WaitForSynchro(); /* Espero la suncronizacion de los registros APB RTC */

RTC_InitStructure.RTC_AsynchPrediv = 123 - 1; /* Condiguracion del calendario para HSE/8 = 1 MHz */

RTC_InitStructure.RTC_SynchPrediv = 8146 - 1;

RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;

RTC_Init(&RTC_InitStructure);

RTC_DateStructure.RTC_Year = 14; /* Seteo la fecha al 1/1/14 */

RTC_DateStructure.RTC_Month = RTC_Month_January;

RTC_DateStructure.RTC_Date = 0x01;

RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Wednesday;

RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure);

RTC_TimeStructure.RTC_H12 = RTC_H12_AM;

RTC_TimeStructure.RTC_Hours = 0;

RTC_TimeStructure.RTC_Minutes = 0;

RTC_TimeStructure.RTC_Seconds = 0;

RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);

/* Configuro las interrupciones */

EXTI_ClearITPendingBit(EXTI_Line22);

EXTI_InitStructure.EXTI_Line = EXTI_Line22;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

RTC_WakeUpCmd(DISABLE);

//

RTC_WriteProtectionCmd(DISABLE);

/* Configure the RTC WakeUp Clock source: CK_SPRE (1Hz) */

RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);

RTC_SetWakeUpCounter(1);

/* Enable the RTC Wakeup Interrupt */

RTC_ITConfig(RTC_IT_WUT, ENABLE);

RTC_ITConfig(RTC_IT_TS, DISABLE);

RTC_ITConfig(RTC_IT_ALRA, DISABLE);

RTC_ITConfig(RTC_IT_ALRB, DISABLE);

RTC_ITConfig(RTC_IT_TAMP, DISABLE);

RTC_ITConfig(RTC_IT_TAMP1, DISABLE);

RTC_ClearFlag(RTC_FLAG_WUTF);

RTC_ClearITPendingBit(RTC_IT_WUT);

EXTI_ClearITPendingBit(EXTI_Line22);

//

RTC_AlarmCmd(RTC_Alarm_A, DISABLE);

//

RTC_AlarmCmd(RTC_Alarm_B, DISABLE);

//

RTC_TimeStampCmd(RTC_TimeStampEdge_Rising, DISABLE);

//

RTC_TimeStampCmd(RTC_TimeStampEdge_Falling, DISABLE);

//

RTC_TamperFilterConfig(RTC_TamperFilter_Disable);

//

RTC_TamperCmd(RTC_Tamper_1, DISABLE);

//

RTC_TamperPullUpCmd(DISABLE);

//

RTC_BypassShadowCmd(DISABLE);

//

RTC_CoarseCalibCmd(DISABLE);

//

RTC_WriteProtectionCmd(ENABLE);

/* Enable Wakeup Counter */

RTC_WakeUpCmd(ENABLE);

}

void RTC_WKUP_IRQHandler(void){

if(RTC_GetITStatus(RTC_IT_WUT) != RESET){

Aux++;

RTC_WriteProtectionCmd(DISABLE);

EXTI_ClearITPendingBit(EXTI_Line22);

RTC_ClearITPendingBit(RTC_IT_WUT);

RTC_ClearFlag(RTC_FLAG_WUTF);

RTC_ClearFlag(RTC_FLAG_RECALPF);

RTC_ClearFlag(RTC_FLAG_TAMP1F);

RTC_ClearFlag(RTC_FLAG_TSOVF);

RTC_ClearFlag(RTC_FLAG_TSF);

RTC_ClearFlag(RTC_FLAG_WUTF);

RTC_ClearFlag(RTC_FLAG_ALRBF);

RTC_ClearFlag(RTC_FLAG_ALRAF);

RTC_ClearFlag(RTC_FLAG_WUTF);

RTC_ClearFlag(RTC_FLAG_INITF);

RTC_ClearFlag(RTC_FLAG_RSF);

RTC_ClearFlag(RTC_FLAG_SHPF);

RTC_ClearFlag(RTC_FLAG_WUTWF);

RTC_ClearFlag(RTC_FLAG_ALRBWF);

RTC_ClearFlag(RTC_FLAG_ALRAWF);

RTC_WriteProtectionCmd(ENABLE);

}

}

The idea is to have an interrupt every second but when the first interrupt is fired then constantly enters in the interrupt, some times because of the RTC_IT_WUTF and some others because of others flags.

I have been trying a lot of things but without success.

I don't know what I am doing wrong. Can you help me?

Thanks a lot.

Best regards,

Bruno

#discovery #stm32f4 #wait-for-you--clive1-!-!-!

4 REPLIES 4
Posted on September 11, 2014 at 01:22

Which STM32 part, an F2 or F4 at a guess? Never mind saw the tags...

I don't have time right now to dig through this, but I think you need to explicitly test/clear the EXTI source, rather than make it dependent on other sources. If you fail to clear it, the interrupt will keep reentering.

You should also be able to test/set/clear multiple status bits in a single operation. Interrupt flags can assert separately from whether they are enabled. The enabling just means the flag is gated through to the interrupt controller.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Palacios.Bruno
Associate III
Posted on September 11, 2014 at 02:15

Dear clive1,

As always thank you for your answer. 

I am sorry to tell you I did not understand what do you meant with ''You should also be able to test/set/clear multiple status bits in a single operation. Interrupt flags can assert separately from whether they are enabled. The enabling just means the flag is gated through to the interrupt controller.''

I do not why but I cannot understand it. As you probably noticed, my english is not good at all.

Regarding to the EXTI source, I have cleared the pending bit in the interrupt when a valid RTC_IT_WUT interrupt arrives, which seems to be the first one fired but then there are some invalid fires until another WUF and so. I do not know if I am clear enough.

Al the RTC_ClearFlag() in the ISR are the result of my tests. I tried with a single if sentence for each flag and the result was that the undesired fires of the ISR was not because of any of the IT sources (WUT, TS, ALRA, ALRB, TAMP, TAMP1).

All the flags were in RESET state but some of the RTC_Flags were in SET state. What I remember is that RTC_FLAG_WUTF, RTC_FLAG_RSF, RTC_FLAG_ALRAWF, RTC_FLAG_ALRBWF and probably another one were set.

Could you give me some clue of what I should review?

Thank you again!

Best regards,

Bruno

PD: I am using an STM32F407VGT6

Posted on September 11, 2014 at 04:59

RTC_ITConfig(RTC_IT_WUT, ENABLE); // Enable singular source
RTC_ITConfig(RTC_IT_TS | RTC_IT_ALRA | RTC_IT_ALRB, DISABLE); // Disable multiple sources
RTC_ClearFlag(RTC_FLAG_TAMP1F | RTC_FLAG_TSOVF | RTC_FLAG_TSF |
RTC_FLAG_WUTF | RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_RSF); // Clear multiple flags
if (EXTI_GetITStatus(EXTI_Line22) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line22); 
// ...
}

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Palacios.Bruno
Associate III
Posted on September 11, 2014 at 13:48

Great, thank you so much.

Now it almost work. The interrupt is triggered correctly a couple of times and then it does not trigger again but well, I will figure it out. The single ClearFlag() calls was because I was testing, lol. ** EDIT ** Let me share the final configuration that worked:

void RTC_Configuration(void)
{
RTC_InitTypeDef RTC_InitStructure;
RTC_TimeTypeDef RTC_TimeStructure;
RTC_DateTypeDef RTC_DateStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); /* Habilito el PWR clock */
PWR_BackupAccessCmd(ENABLE); /* Permito Acceso al RTC */
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET){ /* HSE activado? */
RCC_HSEConfig(RCC_HSE_ON); /* Sino activo HSE */
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
}
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div8); /* 8015674 Hz / 8 = 1001959,25 Hz*/
RCC_RTCCLKCmd(ENABLE); /* Habilito el clock */
RTC_WaitForSynchro(); /* Espero la suncronizacion de los registros APB RTC */
RTC_InitStructure.RTC_AsynchPrediv = 123 - 1; /* 1001959 / 123 = 8146 / */
RTC_InitStructure.RTC_SynchPrediv = 8146 - 1;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
RTC_DateStructure.RTC_Year = 14; /* Seteo la fecha al 1/1/14 */
RTC_DateStructure.RTC_Month = RTC_Month_January;
RTC_DateStructure.RTC_Date = 0x01;
RTC_DateStructure.RTC_WeekDay = RTC_Weekday_Wednesday;
RTC_SetDate(RTC_Format_BCD, &RTC_DateStructure);
RTC_TimeStructure.RTC_H12 = RTC_H12_AM;
RTC_TimeStructure.RTC_Hours = 0;
RTC_TimeStructure.RTC_Minutes = 0;
RTC_TimeStructure.RTC_Seconds = 0;
RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);
/* Configuro las interrupciones */
EXTI_ClearITPendingBit(EXTI_Line22);
EXTI_InitStructure.EXTI_Line = EXTI_Line22;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RTC_WakeUpCmd(DISABLE);
RTC_WriteProtectionCmd(DISABLE);
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
RTC_SetWakeUpCounter(0x01); /* Interrupcion cada 1 segundo */
RTC_ITConfig(RTC_IT_WUT, ENABLE); /* Enable the RTC Wakeup Interrupt */
RTC_ITConfig(RTC_IT_TAMP | RTC_IT_TAMP1 | RTC_IT_TS |
RTC_IT_ALRA | RTC_IT_ALRB, DISABLE); /* Disable multiple sources */
RTC_ClearFlag(RTC_FLAG_WUTF);
RTC_ClearITPendingBit(RTC_IT_WUT);
EXTI_ClearITPendingBit(EXTI_Line22);
RTC_WriteProtectionCmd(ENABLE);
RTC_WakeUpCmd(ENABLE); /* Habilito contador Wake UP */
}
void RTC_WKUP_IRQHandler(void){
if (EXTI_GetITStatus(EXTI_Line22) != RESET){
Aux++;
RTC_WriteProtectionCmd(DISABLE);
EXTI_ClearITPendingBit(EXTI_Line22);
RTC_ClearITPendingBit(RTC_IT_WUT);
RTC_ClearFlag(RTC_FLAG_WUTF);
RTC_ClearFlag(RTC_FLAG_TAMP1F | RTC_FLAG_TSOVF | RTC_FLAG_TSF |
RTC_FLAG_WUTF | RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_RSF); /* Clear multiple flags */
RTC_WriteProtectionCmd(ENABLE);
}
}