/*! * \file hal_sleep.c * * \brief Target xc6xxx hal spi implementation * * \copyright Revised BSD License, see section \ref LICENSE. * * \code * * _ __ _ ________ _ * | |/ /(_)___ / ____/ /_ (_)___ * | // / __ \/ / / __ \/ / __ \ * / |/ / / / / /___/ / / / / /_/ / * /_/|_/_/_/ /_/\____/_/ /_/_/ .___/ * /_/ * (C) 2022-2025 XinChip * * \endcode * * \author ( XinChip ) Alex-J * * \author ( XinChip ) */ /* ------------------------------------------------------------------------------------------------ * Includes * ------------------------------------------------------------------------------------------------ */ #include "hal_types.h" #include "hal_mcu.h" #include "hal_board.h" #include "hal_sleep.h" #include "OSAL.h" #include "OSAL_Timers.h" #include "OSAL_Tasks.h" #include "OSAL_PwrMgr.h" #include "OnBoard.h" #include "hal_drivers.h" #include "hal_assert.h" #include "hal_timer.h" #include "xc_drv_pwr.h" #include "xc_drv_clock.h" #include "xc6xxx.h" #define WAKEUP_TIMER (TIMER0_IDX) #define OSASL_MIN_SLEEP_TIME (5) /* ------------------------------------------------------------------------------------------------ * Global Variables * ------------------------------------------------------------------------------------------------ */ volatile uint8 halSleepPconValue; uint32 rtc_time_mod = 0; /* ------------------------------------------------------------------------------------------------ * Function Prototypes * ------------------------------------------------------------------------------------------------ */ #if (0) __RAM_CODE static uint32_t wakeup_timer_set(uint32_t ms) { uint32_t ticks; cprao_aon_reg1__timer_ao_sleep_clksw__setf(0); /* aotimer0 init */ if (cprao_aon_clken_grctl__timer_ao_pclk_en__getf() != ENABLE) { cprao_aon_clken_grctl__timer_ao_pclk_en__setf(ENABLE); } cprao_aon_clken_grctl__timer0_ao_pclk_en__setf(ENABLE); cprao_aon_clken_grctl__timer1_ao_pclk_en__setf(ENABLE); cpr_lp_ctl__timer_sysclk_sel__setf(ENABLE); aotimer_tcr__tes__setf(WAKEUP_TIMER, DISABLE); aotimer_tcr__tms__setf(WAKEUP_TIMER, (uint8_t)AOTIMER_MODE_SINGLE); (void)aotimer_tic__tic__getf(WAKEUP_TIMER); /* aotimer0 set value */ if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32768) { ticks = 32 * ms + (768 * ms) / 1000;} else if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32K) { ticks = 32 * ms;} ticks = ticks < AOTIMER_MIN_TLC_VAL ? AOTIMER_MIN_TLC_VAL : ticks; aotimer_tcr__tes__setf(WAKEUP_TIMER, AOTIMER_TCR_TES_DISABLE); aotimer_tlc_set(WAKEUP_TIMER, ticks); /* aotimer0 start */ NVIC_EnableIRQ(TIMER_AO0_IRQn); aotimer_tcr__tim__setf(WAKEUP_TIMER, DISABLE); aotimer_tcr__tes__setf(WAKEUP_TIMER, ENABLE); // Wait for timer enable while (aotimer_tcr__tes__getf(WAKEUP_TIMER) != ENABLE) { __nop(); } return ticks; } #endif __RAM_CODE static uint32_t wakeup_timer_set(uint32_t ms) { uint32_t ticks; /* wakeup timer init */ if (cpr_ctlapbclken_grctl__timer_pclk_en__getf() != ENABLE) { cpr_ctlapbclken_grctl__timer_pclk_en__setf(ENABLE);} cpr_timer0_clk_ctl__timer_clksel__setf((uint8_t)TIMER_CLK_SRC_32K); cpr_timer0_clk_ctl__timer_clk0_div__setf((uint8_t)TIMER_DIV_CLK_32000Hz); cpr_timer0_clk_ctl__timer_clk1_div__setf((uint8_t)TIMER_DIV_CLK_32000Hz); if (cpr_lp_ctl__timer_sysclk_sel__getf() != ENABLE) { cpr_lp_ctl__timer_sysclk_sel__setf(ENABLE);} timer_tcr__tes__setf(WAKEUP_TIMER, TIMER_TCR_TES_DISABLE); timer_tcr__tms__setf(WAKEUP_TIMER, (uint8_t)TIMER_MODE_SINGLE); #if !defined(NO_SUPPORT_LFCLK_XTAL_32768) /* wakeup timer set value */ if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32768) { ticks = 32 * ms + (768 * ms) / 1000;} else if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32K) { ticks = 32 * ms;} #else ticks = 32 * ms; #endif ticks = ticks < TIMER_MIN_TLC_VAL ? TIMER_MIN_TLC_VAL : ticks; // timer_tcr__tes__setf(WAKEUP_TIMER, TIMER_TCR_TES_DISABLE); timer_tlc_set(WAKEUP_TIMER, ticks); /* wakeup timer start */ NVIC_EnableIRQ(TIMER0_IRQn); timer_tcr__tim__setf(WAKEUP_TIMER, TIMER_TCR_TIM_DISABLE); timer_tcr__tes__setf(WAKEUP_TIMER, TIMER_TCR_TES_ENABLE); // Wait for timer enable while (timer_tcr__tes__getf(WAKEUP_TIMER) != ENABLE) { __nop(); } return ticks; } static void bor_init(void) { cprao_aon_bor_ctr_reg0__bor_ctrl__setf(0x0); cprao_aon_bor_ctr_reg0__bor_rstn_mask__setf(1); cprao_aon_bor_ctr_reg0__bor_intr_mask__setf(0); NVIC_EnableIRQ(MPU_IRQn); } static void system_lightsleep_cfg(void) { #if (USE_XIP != 1) cprao_aon_puctrl1_set(0x4); /* puctrl1= 0x4 , SSI0RX must pulldown*/ #endif cprao_aon_sys_time_set((RST_READY_TIME << 12) | (OSC32_STABLE_TIME)); xc_pwr_pd_lightsleep_set(); xc_pwr_sleepsrc_mask_set(0x1e001e); xc_pwr_osc_off(); } void system_sleep_init(void) { uint32_t wake_it_src; bor_init(); #if (0) #if !defined(NO_SUPPORT_ROM_FMC_SPI) #if (USE_XIP == 1) xc_fmc_spi_init_oprt(); #endif #else #if (USE_XIP == 1) SPI_InitCfg_t spi_cfg = {0}; spi_cfg.Mode = SPI_MODE_MASTER; spi_cfg.DataSize = SSI_CTRL0_DFS_LEN_8BIT; spi_cfg.Direction = SSI_CTRL0_TMOD_WR; spi_cfg.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; spi_cfg.CLKPolarity = SSI_CTRL0_SCPOL_LOW; spi_cfg.CLKPhase = SPI_CPHA_LEAD; spi_cfg.FirstBit = SPI_FirstBit_MSB; xc_spi_init(XC_SPI0, &spi_cfg); #endif #endif #endif xc_pwr_gpio_sleep_config(); wake_it_src = GPIO_IRQn_WAKE | RTC_IRQn_WAKE | TIMER_AO0_IRQn_WAKE | TIMER0_IRQn_WAKE; xc_pwr_wake_it_set(wake_it_src); system_lightsleep_cfg(); } __RAM_CODE void halSleep(uint32 osal_timeout) { uint32 before_sleep_tick, wakeup_timer_set_tick, wakeup_timer_current_tick, wakeup_timer_dlt_tick, wakeup_timer_dlt_us, temp_tick; if (osal_timeout <= OSASL_MIN_SLEEP_TIME) return; NVIC_DisableIRQ(TIMER1_IRQn); HAL_DISABLE_INTERRUPTS(); /* stop OSAL timer */ timer_tcr__tes__setf(OSAL_TIMER, TIMER_TCR_TES_DISABLE); /* get before sleep tick */ before_sleep_tick = getMcuPrecisionCount(); /* set sleep time:ms */ wakeup_timer_set_tick = wakeup_timer_set(osal_timeout); delay_us(100); /* sleep */ xc_sleep(); xc_rc32k_soft_calib_enable(); wakeup_timer_current_tick = timer_tcv_get(WAKEUP_TIMER); /* stop wakeup timer */ timer_tcr__tes__setf(WAKEUP_TIMER, TIMER_TCR_TES_DISABLE); if (wakeup_timer_current_tick < wakeup_timer_set_tick) { wakeup_timer_dlt_tick = wakeup_timer_set_tick - wakeup_timer_current_tick;} else { wakeup_timer_dlt_tick = 0xffffffff - wakeup_timer_current_tick + wakeup_timer_set_tick;} #if !defined(NO_SUPPORT_LFCLK_XTAL_32768) if (clock_cb.lfclk_in == CLOCK_LFCLK_IN_32768) { wakeup_timer_dlt_us = (((wakeup_timer_dlt_tick << 7) - (wakeup_timer_dlt_tick << 2) - (wakeup_timer_dlt_tick << 1)) >> 2) + (((wakeup_timer_dlt_tick << 3) + wakeup_timer_dlt_tick) >> 9);} else { wakeup_timer_dlt_us = (wakeup_timer_dlt_tick * 125) >> 2;} #else wakeup_timer_dlt_us = (wakeup_timer_dlt_tick * 125) >> 2; #endif temp_tick = before_sleep_tick + wakeup_timer_dlt_us / 625; rtc_time_mod += wakeup_timer_dlt_us % 625; if (rtc_time_mod > 625) { temp_tick++; rtc_time_mod = rtc_time_mod % 625; } /* update system tick */ osal_timer_tick_set(temp_tick); osal_timer_start(); HAL_ENABLE_INTERRUPTS(); xc_rc32k_soft_calib_disable(); } __RAM_CODE void MPU_Handler(void) { cprao_aon_slp_pd_mask_set(0x001); #if XTAL_32K #if !defined(NO_SUPPORT_LFCLK_XTAL_32768) cprao_aon_ctl_clk32k_set(0x109); #endif #endif printf("MPU_Handler\n"); WDT_InitCfg_t wdt_cfg; wdt_cfg.WorkMode = WDT_WORK_MODE0; wdt_cfg.ReloadValue = WDT_CLK_32M_RESET_MODE0_4096US; wdt_cfg.PclkSel = WDT_WORK_32M; xc_wdt_init(&wdt_cfg); xc_wdt_start(); while (1); } /************************************************************************************************** * @fn TimerElapsed * * @brief Determine the number of OSAL timer ticks elapsed during sleep. * Deprecated for CC2538 and CC2430 SoC. * * input parameters * * @param None. * * output parameters * * None. * * @return Number of timer ticks elapsed during sleep. ************************************************************************************************** */ uint32 TimerElapsed( void ) { /* Stubs */ return (0); } /************************************************************************************************** * @fn halRestoreSleepLevel * * @brief Restore the deepest timer sleep level. * * input parameters * * @param None * * output parameters * * None. * * @return None. ************************************************************************************************** */ void halRestoreSleepLevel( void ) { /* Stubs */ }