/** * @copyright 2017 Indie Semiconductor. * * This file is proprietary to Indie Semiconductor. * All rights reserved. Reproduction or distribution, in whole * or in part, is forbidden except by express written permission * of Indie Semiconductor. * * @file pmu_device.c * @Author: Jack.Pan * @E-mail:jack.pan@indiemicro.com * @Date: 2020/09/10 */ #include #include #include #include #include #include #include #include #include static __INLINE void WDTA_Start(void); void BOR_Handler(void) { } void PMU_BORInit(Bor1V5Thres_t lowThreshold, Bor3V3Thres_t highThreshold) { TRIMHV_SFRS->PMUTRIM.TRIM_VREF_BUF = HWCFG_GetBGBUFFCalibValue(); TRIMHV_SFRS->PMUTRIM.VDD3V3_LDO_TRIM = HWCFG_Get3V3CalibValue(); TRIMHV_SFRS->PMUTRIM.OCP_CTRL_3V3 = HWCFG_Get3V3_OCPValue(); TRIMHV_SFRS->PMUTRIM.VDD1V5_LDO_TRIM = HWCFG_Get1V5_CalibValue(); TRIMHV_SFRS->PMUTRIM.OCP_CTRL_1V5 = HWCFG_Get1V5_OCPValue(); TRIMHV_SFRS->BORCONFIG.S_BOR_1P5V = (uint8_t)lowThreshold; TRIMHV_SFRS->BORCONFIG.S_BOR_3P3V = (uint8_t)highThreshold; TRIMHV_SFRS->BORACTION.VDD1V5 = (uint8_t)PMU_BROWNOUT_RESET; TRIMHV_SFRS->BORACTION.VDD3V3 = (uint8_t)PMU_BROWNOUT_RESET; TRIMHV_SFRS->BORACTION.BOR_1V5_LOCK = 1U; TRIMHV_SFRS->BORACTION.BOR_3V3_LOCK = 1U; TRIMHV_SFRS->OVTEMPCONFIG.TEMPSENSE_EN = 1U; /* enable temperature sensor */ EVTHOLD_SFRS->HOLD = 0U; /* clear Lullaby_Handler after wake up */ } void PMU_WakeTimerInit(PMU_WAKEUP_TIMEER_MODE_t mode, PMU_WAKEUP_TIMEER_Interval_t interval) { if (mode == WAKEUP_TIMEER_DISABLE){ WICA_SFRS->CTRL.TIMER_ENA = 0U; }else{ WICA_SFRS->CTRL.TIMER_TAPSEL = (uint8_t)interval; WICA_SFRS->CTRL.TIMER_ENA = 1U; } } void PMU_EnterDeepSleepMode(void) { CRGA_SFRS->MODULERSTREQ |= MODUE_SOFT_RESET_PWM; /* Add GPIO function here for low power mode*/ /* set gpios to input with power up resistor */ // for (uint8_t i = (uint8_t)GPIO_INIT_PORT_1; i<= (uint8_t)GPIO_INIT_PORT_4; i++ ){ // GPIO_Init((GpioInitPort_t)i,GPIO_MUX_GPIO,GPIO_DIR_INPUT,GPIO_PULL_UP); // } /* end of GPIO settigns */ TRIMHV_SFRS->OVTEMPCONFIG.TEMPSENSE_EN = 0U; /* disbale temperature sensor when sleep */ CRGA_SFRS->OVTEMPACTION.OVERTEMP_EN = 0U; TRIMHV_SFRS->VBATTRIM.BAT_UV_EN = 0U; TRIMHV_SFRS->VBATTRIM.BAT_OV_EN = 0U; // SYSCTRLA_REG_PMU_ACCESS_KEY.PMU_ACCESS_KEY = 0x0A; // PMUA_SFRS->CTRL.PD1V5_ENA_HIBERNATE = 1U; /*IOCTRLA_SFRS->LINSGFCONF.LINSRXGF3RD_ENA = 0U;*/ /* clear all of wake up flags */ /* Enable wakeup detect and IRQ when LINS is in sleep mode(LINS_REG_CTRL.SLEEP = 1U;) */ WICA_SFRS->CTRL.LINS_IRQCLR = 1U; WICA_SFRS->CTRL.LINS_IRQENA = 1U; WICA_SFRS->CTRL.LINS_ENA = 1U; WICA_SFRS->CTRL.LINS_IRQENA = 1U; NVIC_EnableIRQ(WULIN_IRQn); NVIC_EnableIRQ(Lullaby_IRQn); /* Enable Lullaby interrupt*/ EVTHOLD_SFRS->HOLD = 1U; /* Trigger ISR then entering sleep in ISR */ /* Waiting to enter sleep mode */ for(;;){ } } /* Please make sure here and don't delete these functions!!!! or it would cause severe error*/ /* hibernate wake up interrupt ISR */ void Lullaby_Handler(void) { /* Set lin to sleep mode */ if (TRIMHV_SFRS->LINS.LINS_SLEEP == 1U){ TRIMHV_SFRS->LINS.LINS_SLEEP = 0U; } TRIMHV_SFRS->LINS.LINS_SLEEP = 1U; /* Enter sleep mode */ PMUA_SFRS->CTRL.HIBERNATE = 1U; } #pragma optimize=none static __INLINE void WDTA_Start(void) { CRGA_SFRS->WDTACTION.WDTBARKCNTCLR = 1U; WDTA_SFRS->CTRL.TIMEOUTSEL = (uint8_t)WDTA_INTERVAL_9216MS; WDTA_SFRS->CLEAR = 0x3c574ad6U; WDTA_SFRS->STOPR.STOP = 0U;/* start wdt*/ } void NMI_Handler(void) { uint32_t temp = FLASH_SFRS->FLSECCR.ADDRECC; FLASH_SFRS->FLSECCR.ECCD = 1; FLASH_SFRS->FLSECCR.ECCC = 1; SYSCFG_SFRS->SRAMCFGR.SRAMECCD = 1; SYSCFG_SFRS->SRAMCFGR.SRAMECCC = 1; for(;;){} } void HardFault_Handler(void) { WDTA_Start(); for(;;){} } void SVC_Handler(void) { WDTA_Start(); for(;;){} } void PendSV_Handler(void) { WDTA_Start(); for(;;){} } void MemManage_Handler(void) { } void BusFault_Handler(void) { } void UsageFault_Handler(void) { } void Divider_Handler(void) { } void FlashEcc_Handler(void) { } void RamEcc_Handler(void) { } void CR_Handler(void) { } void CSA_OCP_Handler(void) { } void error(void) { }