//[[ Most of the system-timer functionality is part of the hal-library // This functionality is kept public because it depends on configuration // options defined in the BOARD_HEADER. Only for the full HAL, though. In // the minimal HAL if the user has to supply the two ifdefs they do so // in whatever manner they choose. //]] uint16_t halInternalStartSystemTimer(void) { //Since the SleepTMR is the only timer maintained during deep sleep, it is //used as the System Timer (RTC). We maintain a 32 bit hardware timer //configured for a tick value time of 1024 ticks/second (0.9765625 ms/tick) //using either the 10 kHz internal SlowRC clock divided and calibrated to //1024 Hz or the external 32.768 kHz crystal divided to 1024 Hz. //With a tick time of ~1ms, this 32bit timer will wrap after ~48.5 days. //disable top-level interrupt while configuring INT_CFGCLR = INT_SLEEPTMR; if (useOsc32k > OSC32K_DISABLE) { if (useOsc32k == OSC32K_DIGITAL) { //Disable both OSC32K and SLOWRC if using external digital clock input SLEEPTMR_CLKEN = 0; } else { // OSC32K_CRYSTAL || OSC32K_SINE_1V //Enable the 32kHz XTAL (and disable SlowRC since it is not needed) SLEEPTMR_CLKEN = SLEEPTMR_CLK32KEN; } //Sleep timer configuration is the same for crystal and external clock SLEEPTMR_CFG = (SLEEPTMR_ENABLE | //enable TMR (0 << SLEEPTMR_DBGPAUSE_BIT)| //TMR not paused when halted (5 << SLEEPTMR_CLKDIV_BIT) | //divide down to 1024Hz (1 << SLEEPTMR_CLKSEL_BIT)) ; //select CLK32K external clock halCommonDelayMilliseconds(OSC32K_STARTUP_DELAY_MS); } else { //Enable the SlowRC (and disable 32kHz XTAL since it is not needed) SLEEPTMR_CLKEN = SLEEPTMR_CLK10KEN; SLEEPTMR_CFG = (SLEEPTMR_ENABLE | //enable TMR (0 << SLEEPTMR_DBGPAUSE_BIT)| //TMR not paused when halted (0 << SLEEPTMR_CLKDIV_BIT) | //already 1024Hz (0 << SLEEPTMR_CLKSEL_BIT)) ; //select CLK1K internal SlowRC #ifndef DISABLE_RC_CALIBRATION halInternalCalibrateSlowRc(); //calibrate SlowRC to 1024Hz #endif//DISABLE_RC_CALIBRATION } //clear out any stale interrupts INT_SLEEPTMRFLAG = (INT_SLEEPTMRWRAP | INT_SLEEPTMRCMPA | INT_SLEEPTMRCMPB); //turn off second level interrupts. they will be enabled elsewhere as needed INT_SLEEPTMRCFG = INT_SLEEPTMRCFG_RESET; //enable top-level interrupt INT_CFGSET = INT_SLEEPTMR; return 0; }
/** * @brief Starts system timer * @param None * @retval Return unsigned value */ uint16_t halInternalStartSystemTimer(void) { /* Since the SleepTMR is the only timer maintained during deep sleep, it is * used as the System Timer (RTC). We maintain a 32 bit hardware timer * configured for a tick value time of 1024 ticks/second (0.9765625 ms/tick) * using either the 10 kHz internal SlowRC clock divided and calibrated to * 1024 Hz or the external 32.768 kHz crystal divided to 1024 Hz. * With a tick time of ~1ms, this 32bit timer will wrap after ~48.5 days. */ /* disable top-level interrupt while configuring */ NVIC->ICER[0] = NVIC_IxxR_SLEEPTMR; #ifdef ENABLE_OSC32K #ifdef DIGITAL_OSC32_EXT /* Disable both OSC32K and SLOWRC if using external digital clock input */ CLK->SLEEPCR = 0; #else /*!DIGITAL_OSC32_EXT */ /* Enable the 32kHz XTAL (and disable SlowRC since it is not needed) */ CLK->SLEEPCR = CLK_SLEEPCR_LSEEN; #endif /* Sleep timer configuration is the same for crystal and external clock */ SLPTMR->CR = (SLPTMR_CR_EN | /* enable TMR */ (0 << 10)| /* TMR not paused when halted */ (5 << 4) | /* divide down to 1024Hz */ (1 << 0)) ; /* select XTAL */ #else /* !ENABLE_OSC32K */ /* Enable the SlowRC (and disable 32kHz XTAL since it is not needed) */ CLK->SLEEPCR = CLK_SLEEPCR_LSI10KEN; SLPTMR->CR = (SLPTMR_CR_EN | /* enable TMR */ (0 << 10)| /* TMR not paused when halted */ (0 << 4) | /* already 1024Hz */ (0 << 0)) ; /* select SlowRC */ #ifndef DISABLE_RC_CALIBRATION halInternalCalibrateSlowRc(); /* calibrate SlowRC to 1024Hz */ #endif /* DISABLE_RC_CALIBRATION */ #endif /*ENABLE_OSC32K */ /* clear out any stale interrupts */ SLPTMR->ISR = (SLPTMR_IER_WRAP | SLPTMR_IER_CMPA | SLPTMR_IER_CMPB); /* turn off second level interrupts. they will be enabled elsewhere as needed */ SLPTMR->IER = 0x00; /* enable top-level interrupt */ NVIC->ISER[0] = NVIC_IxxR_SLEEPTMR; return 0; }