STM32F411 RTC Second Interrupt

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

STM32F411 RTC Second Interrupt

Post by Tabulous »

Having trouble getting this working

So i init the wakeup like this

Code: Select all

void clkInit( void )
{
    rtcGetTime( &RTCD1, &ts );
    rtcGetDtStructTm( &ts, &t );

    clk.sec = t.tm_sec;
    clk.min = t.tm_min;
    clk.hrs = t.tm_hour;
    clk.day = t.tm_mday;
    clk.mon = t.tm_mon + 1;
    clk.year = ( t.tm_year - 100 );

    /* set wakeup */
    wakeupspec.wutr = (( uint32_t )4) << 16;      /* select 1 Hz clock source */
    wakeupspec.wutr |= ( 1 );                       /* Period in seconds */
    rtcSTM32SetPeriodicWakeup( &RTCD1,
                               &wakeupspec );
}


then setup the exti to capture the interrupt.

Code: Select all

static const EXTConfig extio = {
  {
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_DISABLED, NULL},
    {EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART, extcb2}  // RTC_WAKEUP EVENT
  }
};

void extioInit( void )
{

    /*
     * Activates the EXT driver.
     */
    extStart( &EXTD1, &extio );
}

static RTCWakeup wakeupspec;

static void extcb2(EXTDriver *extp, expchannel_t channel)
{

    (void)extp;
    (void)channel;

    palTogglePad(GPIOE, GPIOE_GRN_LED);

    /* re-setup wakeup */
//    wakeupspec.wutr = (( uint32_t )4) << 16;      /* select 1 Hz clock source */
 //   wakeupspec.wutr |= ( 1 );                       /* Period in seconds */
 //   rtcSTM32SetPeriodicWakeup( &RTCD1,
  //                             &wakeupspec );
}


Does one need to reset any interrupt ? as all that is happening is the callback is firing very fast, and not at 1Hz as expected ?
Last edited by Tabulous on Thu Feb 09, 2017 12:59 pm, edited 1 time in total.
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: STM32F411 RTC Second Interrupt

Post by Giovanni »

EXT driver resets the EXTI bits, I am not sure if there is something to reset in the RTC.

Is it "very fast" or continuously? if just fast maybe there is a wrong RTC setup.

Giovanni
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Re: STM32F411 RTC Second Interrupt

Post by Tabulous »

found answer here

http://www.chibios.com/forum/viewtopic.php?f=16&t=3381

one needs to do this.....

RTC->ISR &= ~RTC_ISR_WUTF; // Clear Wakeup Flag
EXTI->PR &= ~(1 << 22); // Clear the pending flag
Tabulous
Posts: 518
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 18 times

Re: STM32F411 RTC Second Interrupt

Post by Tabulous »

Also worth nothing

wakeupspec.wutr = (( uint32_t )4) << 16; /* select 1 Hz clock source */
wakeupspec.wutr |= ( 1 ); /* Period in seconds */


the above will result in 2 second tick......... you need to minus one from the timer period.

Might be worth doing that in rtcSTM32SetPeriodicWakeup ?

i.e.

void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) {
syssts_t sts;

/* Entering a reentrant critical zone.*/
sts = osalSysGetStatusAndLockX();

if (wakeupspec != NULL) {
osalDbgCheck((wakeupspec->wutr & 0xFFFF) > 0);
osalDbgCheck(wakeupspec->wutr != 0x30000);

rtcp->rtc->CR &= ~RTC_CR_WUTE;
while (!(rtcp->rtc->ISR & RTC_ISR_WUTWF))
;
rtcp->rtc->WUTR = (wakeupspec->wutr & 0xFFFF) - 1;
rtcp->rtc->CR = (wakeupspec->wutr >> 16) & 0x7;
rtcp->rtc->CR |= RTC_CR_WUTIE;
rtcp->rtc->CR |= RTC_CR_WUTE;
}
else {
rtcp->rtc->CR &= ~RTC_CR_WUTIE;
rtcp->rtc->CR &= ~RTC_CR_WUTE;
}

/* Leaving a reentrant critical zone.*/
osalSysRestoreStatusX(sts);
}
Post Reply