Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Not applicable
Hi,

I am developing an appliance that needs to do some reasonable time-keeping and have been experimenting with the various timers available on the XMC4500.

While debugging very weird behaviour (that I've fixed now; turns out I was doing too much work in an interrupt) of a CCU-based timer I happened upon something unrelated: I have an interrupt tied to the CCU Timer and increment a ccu_ticks variable in the interrupt. In the main loop, I calculate the time passed based on the ccu_ticks and from the RTC.

If I enable the CCU clock in sleep state and call __WFI in the main loop to make the CPU go to sleep, the CCU and RTC clock very visibly drift against each other. When I don't call __WFI, they seem to keep step very well. Is there any explanation for this? Does it take the CPU too long to wake up from sleep when the CCU interrupt is hit?

Here is the main code:


uint32_t ccu_ticks = 0;
void CCU_Timer()
{
ccu_ticks++;
}

int main(void)
{
/* DAVE init cut out */

// Enable CCU clock in sleep
SCU_CLK->SLEEPCR |= SCU_CLK_SLEEPCR_CCUCR_Msk;

uint8_t is_initial = 1;
int32_t initial_offset = 0x1337;

while(1U)
{
XMC_RTC_TIME_t rtc_timeval;
uint32_t ccu_time;
uint32_t rtc_time;

RTC_GetTime(&rtc_timeval);

// ccu_tick increments every 100ms, so divide by ten to get seconds
ccu_time = (ccu_ticks / 10);
// get high number of rtc seconds
rtc_time = rtc_timeval.hours * 60 * 60 + rtc_timeval.minutes * 60 + rtc_timeval.seconds;

int32_t diff = ((int32_t)rtc_time - (int32_t)ccu_time);

if (is_initial) {
initial_offset = diff;
is_initial = 0;
} else {
//this should not be hit for a long time
if ((diff - initial_offset) < -2 || (diff - initial_offset) > 2) {
while (1U)
{

}
}
}

__WFI();

}
}



I attached the project. It includes Apps and code for displaying CCU time, RTC time, and the drift on a standard 16x2 character display. That code can be cut out if you don't have a test board with a character lcd handy.
0 Likes
2 Replies
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi,

during Hibernate mode, the RTC crystal (32.768Mhz) is providing the standby clock and RTC. Hence RTC clock timing should not be affected (Can you confirm on this?). However if you are using CCU and systick, then there might be some issue as their clock source had been switched to a different frequency.

1970.attach
0 Likes
Not applicable
I set SCU_CLK->SLEEPCR |= SCU_CLK_SLEEPCR_CCUCR_Msk; to make sure CCU is still clocked from f_PLL via the high precision main clock. I don't think the CCU should be switched to a different clock source. I'm not sending the system into hibernation, just sending the CPU into sleep state.
0 Likes