AnsweredAssumed Answered

STM32F050G4 RTC Alarm Problems

Question asked by Mack.Ben.001 on Oct 31, 2013
Latest reply on Nov 13, 2013 by Mack.Ben.001
Hi All, a couple of questions about the RTC Alarm. I have got the RTC Alarm working (using LSI), and raising an interrupt (RTC_IRQHandler()) successfully, but I'm stuck on the following:-

1) I would like an alarm once a second, so I can put the core in stop mode, and have it wake up once a second. The reference manual implies that if I set the ALRMASSR MASKSS to zero, and set all the ALRMAR MSK bits, then I should get an interrupt once a second, but I don't. I used
RTC->ALRMAR = 0x80808080;
RTC->ALRMASSR = 0x00000000;

2) Whilst I can set RTC->ALRMAR in the first place, I cannot modify it within RTC_IRQHandler() for the next alarm. I'm disabling WPR.

I have attached my test code below. You'll notice the debug vars ben1, ben2, ben3 - if I pause a few seconds after the first alarm interrupt, ben2 (ALRMAR) is still 0x80808005. You'll notice from commented code that I also tried the library functions for setting the alarm, and even tried RTC_EnterInitMode(), same problem. Any suggestions?

#include "stm32f0xx.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_pwr.h"
#include "stm32f0xx_rtc.h"
#include "stm32f0xx_exti.h"
#include "stm32f0xx_misc.h"
 
#define PORT_LED              GPIOB
#define PIN_LED_G             GPIO_Pin_6
#define PIN_LED_R             GPIO_Pin_7
#define LED_G_ON              GPIOB->BSRR=PIN_LED_G
#define LED_G_OFF             GPIOB->BRR=PIN_LED_G
#define LED_G_TOGGLE          GPIOB->ODR ^= PIN_LED_G
#define LED_R_ON              GPIOB->BSRR=PIN_LED_R
#define LED_R_OFF             GPIOB->BRR=PIN_LED_R
#define LED_R_TOGGLE          GPIOB->ODR ^= PIN_LED_R
 
uint32_t ben1, ben2, ben3;
 
int main(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RTC_InitTypeDef RTC_InitStructure;
    //RTC_TimeTypeDef RTC_TimeStructure;
    //RTC_TimeTypeDef bentemp_rtc;
    //ErrorStatus benerrorstatus;
    //uint32_t benui32;
 
    // Outputs Port B
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    GPIO_InitStructure.GPIO_Pin = PIN_LED_G | PIN_LED_R;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 
    // Init RTC Clock
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);   // Enable the PWR clock
    PWR_BackupAccessCmd(ENABLE);            // Enable access to the Backup domain registers (PWR->CR |= PWR_CR_DBP;)
    RCC_LSICmd(ENABLE);                     // Enable the LSI OSC
    while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); // and wait until ready
    RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Set RTC clock source to LSI (RCC->BDCR |= RCC_RTCCLKSource_LSI;) must set PWR_CR_DBP first
    RCC_RTCCLKCmd(ENABLE);                  // Enable RTC Clock (RCC->BDCR |= RCC_BDCR_RTCEN;)
    RTC_WaitForSynchro();                   // Wait for RTC APB registers synchronisation
 
    // Set RTC prescaler register RTC_PRER
    RTC_InitStructure.RTC_AsynchPrediv = 99;
    RTC_InitStructure.RTC_SynchPrediv =  399; /* (40KHz / 100) - 1 = 399*/
    RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
    RTC_Init(&RTC_InitStructure);
 
    // Init RTC time register
    // ben note the RTC_SetTime() function doesn't appear to work...
    RTC->WPR = 0xCA;                        // Disable the write protection for RTC registers
    RTC->WPR = 0x53;                        // ditto
    RTC_EnterInitMode();                    // Enter initialisation mode
    RTC->TR = (uint32_t)0x00000000;     // Set the RTC_TR register
    RTC->ISR &= ~RTC_ISR_INIT;              // Exit initialisation mode
    RTC->WPR = 0xFF;                        // Enable the write protection for RTC registers
 
    // Init EXTI line 17
    EXTI->RTSR |= EXTI_IMR_MR17;    // set rising edge bit
    EXTI->IMR |= EXTI_IMR_MR17;     // set interrupt mask bit
 
    // Enable the RTC Interrupt
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    // Set RTC alarm
    RTC->WPR = 0xCA;
    RTC->WPR = 0x53;
    RTC->ALRMAR = 0x80808005;   // MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=0 ST=0 SU=5 secs
    //RTC->ALRMAR = 0x80808080;   // MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=1(ignore seconds)
    //RTC->ALRMASSR = 0x00000000;   // MASKSS=0 so the alarm is set when the seconds unit is incremented
    RTC->CR |= RTC_CR_ALRAIE;   // enable alarm interrupt ben was RTC_ITConfig(RTC_IT_ALRA, ENABLE);
    RTC->CR |= RTC_CR_ALRAE;    // enable alarm
    RTC->WPR = 0xFF;
 
    // and finally clear any pending interrupts
    RTC_ClearITPendingBit(RTC_IT_ALRA);
    EXTI_ClearITPendingBit(EXTI_Line17);
 
 
    while(1)
    {
        ben1 = RTC->TR;
        ben2 = RTC->ALRMAR;
    }
}
 
void RTC_IRQHandler(void)
{
   LED_G_TOGGLE;
 
/*
   // set next alarm
   RTC_WaitForSynchro(); //ben only if we read TR -
   //uint32_t fred = RTC->ALRMAR & 0x0000007F;
   uint32_t fred = RTC->TR & 0x0000007F;
   fred += 5;
   if (fred > 59)
      fred = 0;
 
    ben3 = fred;
 */
 
   RTC->WPR = 0xCA;
   RTC->WPR = 0x53;
   //RTC->ALRMAR = 0x80808000 | fred;   // MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=0 ST/U = fred secs
   RTC->ALRMAR = 0x80808009;   // MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=0 ST/U = fred secs
   RTC->WPR = 0xFF;
 
/*   RTC_WriteProtectionCmd(DISABLE);
   RTC_EnterInitMode();
   //RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &alarm);
   RTC->ALRMAR = 0x80808009;   // MSK4=1(ignore day/date), MSK3=1(ignore hours), MSK2=1(ignore minutes), MSK1=0 ST/U = fred secs
   RTC_WriteProtectionCmd(ENABLE);
   RTC_ExitInitMode();
*/
 
   RTC_ClearITPendingBit(RTC_IT_ALRA);
   EXTI_ClearITPendingBit(EXTI_Line17);
}

Outcomes