Folks,
we are using a K20N512VLL100 (Datecode 1N30D) and are trying to tame the RTC and its interrupts.
We want to use an Alarm IRQ (periodically generated every second) to have a substitute for the seconds interrupt (which we think is not implemented, because we did not find any "dedicated interrupt vector" as mentioned in the manual).
Here is our (rather simple) init code for the RTC:
...
/*enable the clock to SRTC module register space*/
SIM_SCGC6 |= SIM_SCGC6_RTC_MASK;
/* Only VBAT_POR has an effect on the SRTC, RESET to the part does not,
so you must manually reset the SRTC to make sure everything is in a known state */
/*clear the software reset bit*/
RTC_CR = RTC_CR_SWR_MASK;
RTC_CR &= ~RTC_CR_SWR_MASK;
/* Enable RTC interrupt in NCVIC */
NVICICPR2 |= 0x4; //Clear RTC pending interrupts in NVIC
NVICISER2 |= 0x4; //Enable RTC interrupts in NVIC
/*Enable the oscillator*/
RTC_CR |= RTC_CR_OSCE_MASK;
/*Wait to all the 32 kHz to stabilize, refer to the crystal startup time
in the crystal datasheet*/
for(i=0;i<0x600000;i++);
RTC_CCR = 0x00;
RTC_TSR = 0; // Initialize Time ....later only if VBat was lost
RTC_TAR = RTC_TSR + 10; // First RTC alarm should come up in 10 seconds
/* Enable the counter */
RTC_SR |= RTC_SR_TCE_MASK;
...
Now we expect all is done....here is our RTC-ISR:
...
if ((RTC_SR & RTC_SR_TIF_MASK)== 0x01)
{ RTC_SR &= 0x07; //clear TCE, or RTC_TSR can not be written
RTC_TSR = 0x00000000; //clear TIF
}
else if ((RTC_SR & RTC_SR_TOF_MASK) == 0x02)
{ RTC_SR &= 0x07; //clear TCE, or RTC_TSR can not be written
RTC_TSR = 0x00000000; //clear TOF
}
else if ((RTC_SR & RTC_SR_TAF_MASK) == 0x04)
{ RTC_TAR += 1; // Write new alarm value, to generate an alarm every second add 1
}
Now, we get a strange behavior:
After this init we got a interrupt with Bit 0 (TIF) of RTC_SR set. This is handled by the ISR properly. But never we get an Alarm Interrupt TAF (RTC_SR Bit 2) set. But the Alarm flag TAF is set, we checked this by polling it in our main loop.
When we disable all RTC interrupt sources in RTC_IER, of course no ISR call is done. But independent which interrupt we enable (even if we only enable only the alarm interrupt) we always get the TIF interrupt, but never an TAF alarm interrupt...
What is our mistake ?
Thanks, Ulf
Solved! Go to Solution.
Thanks, Folks,
your hints made us solve the problem. In future we will have to read the manuals carefullier to understand the details of this complex device.
Regards, Ulf
Hi Ulf
I don't see where you enable the RTC interrupt (RTC_IER = RTC_IER_TAIE).
TIF means that the timer is invalid and it won't actually count in this state. To clear it, write RTC_SR = 0; and then RTC_SR = RTC_SR_TCE; This will reset that flag and allow the counter to run.
To generate a seconds interrupt you need to set
RTC_TAR = RTC_TSR;
and not +1 ("TAF is set whenever TAR equals the TSR and the TSR increments". This is a bit strange, but, if it is read carefully, it means that the interrupt is not generated when the count value increments to match the alarm value but when the increment takes place after the match).
The uTasker project includes RTC support (tested on K40 and K60 and assumed the same on K20), including full Gregorian time/calendar support - see http://www.utasker.com/forum/index.php?topic=1656.0
The interface was in fact made equivalent to the M522xx RTC interface so it retains compatibility with Coldfire RTC projects by also supporting the features of that RTC - like minutes interrupts, hours interrupts, day interrupts, stop-watch and an alarm at a specified date and time (realised in SW though since the Kinetis RTC is simpler).
Regards
Mark
Note of course that RTC_IER is a new register, available only in later documentation & chips.
--ERGII
Hi
My K60 board arrived in Dec. 2010 and the chip (1M42M) has the RTC_IEC register.
I think that the K20s are much newer so should be equivalent.
Regards
Mark
Hi Mark,
thank you for your hints, but unfortunately they do not make the thing work.
HW-Reset will automatically enable the Alarm interrupt and all the other ones (RTC_IER is set to 0x07 by reset). That is the reason why we don not enable the Alarm interrupt.
We changed the interrupt behavior to clear TIIF as well to clear TOIF, ok.
We also changed the setting of TAR in the way you told: Set it to TSR to get the interrupt generated every second AFTER comparison is true.
If you look at our ISR you can see that we catch the contents of RTC_SR in the beginning. We get many RTC interrupts with RTC_SR = 0x20. Our documentation says: Bit 5 is not used and always reads 0....what is going on here?
Unfortunately the seconds interrupt does not work anyway. Any other ideas?
Regards
Ulf
Hi Ulf
Below is the code from the uTasker project. It should be possible to use this more or less directly to verify that your HW is operating correctly:
Initialisation code:
POWER_UP(6, SIM_SCGC6_RTC); // ensure the RTC is powered if (RTC_SR & RTC_SR_TIF) { // if timer invalid RTC_SR = 0; // ensure stopped RTC_TSR = 0; // write to clear RTC_SR_TIF in status register when not yet enabled RTC_CR = (RTC_CR_OSCE | RTC_CR_CLKO); // enable oscillator but don't supply clock to other peripherals return WAIT_STABILISING_DELAY; // the oscillator requires some time to stabilise so the user should call again after this time has expired } rtc_interrupt_handler[iIRQ] = ((INTERRUPT_SETUP *)ptrSettings)->int_handler; // enter the handling interrupt RTC_SR = 0; // temporarily disable RTC to avoid potentially missed seconds count fnConvertSecondsTime(RTC_TSR); // take the present seconds count value and convert to time and date RTC_TAR = (RTC_TSR); // set timer alarm interrupt at next second fnEnterInterrupt(irq_RTC_ID, PRIORITY_RTC, _rtc_handler); rtc_interrupts |= (0x01 << iIRQ); // flag interrupt(s) enabled RTC_IER = RTC_IER_TAIE; // enable alarm interrupt RTC_SR = RTC_SR_TCE; // enable couter
fnConvertSeconds() can be comment out since it converts the present count value to a data/time only.
rtc_interrupts is not needed since it is used by the ISR to simulate a number of Coldfire RTC interrupts.
The details about entering interrupts can be changed to suit the framework. you use.
Note that the full initialisation is only performed once (when the RTC is invalid) and subsequent starts leave the RTC and its oscillator alone.
In the case of return WAIT_STABILISING_DELAY the user recalls the initialisation after a pause of 1s in order to allow the 32kHz oscillator to stabilise (when debugging and stepping the code this is not necessary since one just needs to step slowly). Also make sure that you have the power input to the RTC connected to a battery or the appropriate voltage since the RTC will otherwise not run.
The interrupt handler just does:
static __interrupt void _rtc_handler(void){ RTC_TAR = (RTC_TSR); // reset interrupt flag and set timer alarm interrupt to next second .... plus some extra stuff to simulate Coldfire RTC operation}
Regards
Mark
Thanks, Folks,
your hints made us solve the problem. In future we will have to read the manuals carefullier to understand the details of this complex device.
Regards, Ulf