/*FUNCTION********************************************************************** * * Function Name : POWER_SYS_GetCurrentMode * Description : Returns currently running power mode. * *END**************************************************************************/ power_manager_modes_t POWER_SYS_GetCurrentMode(void) { power_manager_modes_t retVal; switch (SMC_HAL_GetStat(SMC)) { #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE /* High speed run mode */ case kStatHsrun: retVal = kPowerManagerHsrun; break; #endif /* Run mode */ case kStatRun: retVal = kPowerManagerRun; break; /* Very low power run mode */ case kStatVlpr: retVal = kPowerManagerVlpr; break; /* This should never happen - core has to be in some run mode to execute code */ default: retVal = kPowerManagerMax; break; } return retVal; }
/*FUNCTION********************************************************************** * * Function Name : POWER_SYS_GetVeryLowPowerModeStatus * Description : Returns whether very low power mode is running. * *END**************************************************************************/ bool POWER_SYS_GetVeryLowPowerModeStatus(void) { /* Get current power mode and return true if it is very low power mode */ uint8_t status = SMC_HAL_GetStat(SMC); if (status == kStatVlpr) { return true; } else { return false; } }
/*FUNCTION********************************************************************** * Function Name : POWER_SYS_WaitForVlprStatus * Description :Internal function used by POWER_SYS_SetMode function *END**************************************************************************/ static power_manager_error_code_t POWER_SYS_WaitForVlprStatus(void) { uint32_t i; for (i=0; SMC_HAL_GetStat(SMC) != kStatVlpr; i++) { if(i > POWER_SET_MODE_TIMEOUT) { return kPowerManagerErrorSwitch; } } return kPowerManagerSuccess; }
void displayPowerMode(void) { uint32_t smcMode = SMC_HAL_GetStat(SMC_BASE_PTR); switch (smcMode) { case kStatRun: PRINTF(" SMC mode = kPowerModeRun\n\r"); break; case kStatVlpr: PRINTF(" SMC mode = kPowerModeVlpr\n\r"); break; default: PRINTF(" SMC mode = Unknown!\n\r"); break; } }
void displayPowerMode(void) { uint32_t smcMode = SMC_HAL_GetStat(SMC_BASE_PTR); switch (smcMode) { case kStatRun: PRINTF(" SMC mode = kStatRun\r\n"); break; case kStatVlpr: PRINTF(" SMC mode = kPowerModeVlpr\r\n"); break; case kStatHsrun: PRINTF(" SMC mode = kPowerModeHsrun\r\n"); break; default: PRINTF(" SMC mode = Invalid mode\r\n"); break; } }
/*FUNCTION********************************************************************** * * Function Name : SMC_HAL_SetMode * Description : Config the power mode * This function will configure the power mode control for any run, stop and * stop submode if needed. It will also configure the power options for specific * power mode. Application should follow the proper procedure to configure and * switch power mode between the different run and stop mode. Refer to reference * manual for the proper procedure and supported power mode that can be configured * and switch between each other. Refert to smc_power_mode_config_t for required * parameters to configure the power mode and the supported options. Other options * may need to configure through the hal driver individaully. Refer to hal driver * header for details. * *END**************************************************************************/ smc_hal_error_code_t SMC_HAL_SetMode(uint32_t baseAddr, const smc_power_mode_config_t *powerModeConfig) { smc_hal_error_code_t retCode = kSmcHalSuccess; uint8_t currentStat; volatile unsigned int dummyread; smc_stop_mode_t stopMode; smc_run_mode_t runMode; power_mode_stat_t modeStat; power_modes_t powerModeName = powerModeConfig->powerModeName; /* verify the power mode name*/ assert(powerModeName < kPowerModeMax); #if FSL_FEATURE_SMC_HAS_LPWUI /* check lpwui option*/ if (powerModeConfig->lpwuiOption) { /* check current stat*/ currentStat = SMC_HAL_GetStat(baseAddr); /* if not in VLPR stat, could not set to RUN*/ if (currentStat == kStatRun) { SMC_HAL_SetLpwuiMode(baseAddr, powerModeConfig->lpwuiOptionValue); } } #endif /* branch based on power mode name*/ switch (powerModeName) { case kPowerModeRun: case kPowerModeVlpr: if (powerModeName == kPowerModeRun) { /* mode setting for normal RUN*/ runMode = kSmcRun; modeStat = kStatVlpr; } else { /* mode setting for VLPR*/ runMode = kSmcVlpr; modeStat = kStatRun; } /* check current stat*/ currentStat = SMC_HAL_GetStat(baseAddr); /* if not in VLPR stat, could not set to RUN*/ if (currentStat != modeStat) { retCode = kSmcHalFailed; } else { /* set power mode to normal RUN or VLPR*/ SMC_HAL_SetRunMode(baseAddr, runMode); } break; #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE case kPowerModeHsrun: /* mode setting for HSRUN (high speed run) */ runMode = kSmcHsrun; modeStat = kStatRun; /* check current stat*/ currentStat = SMC_HAL_GetStat(baseAddr); if (currentStat != modeStat) { /* if not in the mode, return error*/ retCode = kSmcHalFailed; } else { /* set power mode to normal RUN or VLPR mode first*/ SMC_HAL_SetRunMode(baseAddr, runMode); } break; #endif case kPowerModeWait: case kPowerModeVlpw: if (powerModeName == kPowerModeWait) { /* mode setting for normal RUN*/ runMode = kSmcRun; modeStat = kStatRun; } else { /* mode setting for VLPR*/ runMode = kSmcVlpr; modeStat = kStatVlpr; } /* check current stat*/ currentStat = SMC_HAL_GetStat(baseAddr); if (currentStat != modeStat) { /* if not in the mode, return error*/ retCode = kSmcHalFailed; } else { /* set power mode to normal RUN or VLPR mode first*/ SMC_HAL_SetRunMode(baseAddr, runMode); } if (retCode == kSmcHalSuccess) { /* Clear the SLEEPDEEP bit to disable deep sleep mode - enter wait mode*/ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; __WFI(); } break; case kPowerModeStop: case kPowerModeVlps: case kPowerModeLls: if (powerModeName == kPowerModeStop) { #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE /* check current stat*/ currentStat = SMC_HAL_GetStat(baseAddr); if ((currentStat == kStatHsrun) || (SMC_HAL_GetRunMode(baseAddr) == kSmcHsrun)) { retCode = kSmcHalFailed; break; } #endif stopMode = kSmcStop; #if FSL_FEATURE_SMC_HAS_PSTOPO if (powerModeConfig->pstopOption) { SMC_HAL_SetPstopMode(baseAddr, powerModeConfig->pstopOptionValue); } #endif } else if (powerModeName == kPowerModeVlps) { stopMode = kSmcVlps; } else { stopMode = kSmcLls; } /* set power mode to specified STOP mode*/ SMC_HAL_SetStopMode(baseAddr, stopMode); #if FSL_FEATURE_SMC_HAS_LLS_SUBMODE if (powerModeName == kPowerModeLls) { /* further set the stop sub mode configuration*/ SMC_HAL_SetStopSubMode(baseAddr, powerModeConfig->stopSubMode); } #endif /* wait for write to complete to SMC before stopping core */ dummyread = SMC_HAL_GetStat(baseAddr); dummyread = dummyread + 1; /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP)*/ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; __WFI(); break; case kPowerModeVlls: /* set power mode to specified STOP mode*/ SMC_HAL_SetStopMode(baseAddr, kSmcVlls); /* further set the stop sub mode configuration*/ SMC_HAL_SetStopSubMode(baseAddr, powerModeConfig->stopSubMode); /* check if Vlls0 option needs configuration*/ if (powerModeConfig->stopSubMode == kSmcStopSub0) { #if FSL_FEATURE_SMC_HAS_PORPO if (powerModeConfig->porOption) { SMC_HAL_SetPorMode(baseAddr, powerModeConfig->porOptionValue); } #endif } /* wait for write to complete to SMC before stopping core */ dummyread = SMC_HAL_GetStat(baseAddr); dummyread = dummyread + 1; /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP)*/ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; __WFI(); break; default: retCode = kSmcHalNoSuchModeName; break; } return retCode; }
/*! * @brief main function */ int main(void) { i2c_slave_state_t slave; i2cData_t i2cData = { .subAddress = Invalid_Subaddress_Index, .data = 0, .state = CMD_MODE }; i2c_slave_user_config_t userConfig = { .address = 0x3A, .slaveListening = true, .slaveCallback = i2c_slave_event_callback_passive, .callbackParam = &i2cData, #if FSL_FEATURE_I2C_HAS_START_STOP_DETECT .startStopDetect = false, #endif #if FSL_FEATURE_I2C_HAS_STOP_DETECT .stopDetect = false, #endif }; // Low Power Configuration smc_power_mode_config_t smcConfig; // Init struct memset(&smcConfig, 0, sizeof(smcConfig)); hardware_init(); OSA_Init(); GPIO_DRV_Init(0, ledPins); // Initiate I2C instance module I2C_DRV_SlaveInit(BOARD_I2C_INSTANCE, &userConfig, &slave); PRINTF("\r\n====== I2C Slave ======\r\n\r\n"); // turn LED_slave on to indicate I2C slave status is waiting for date receiving LED_turnon_slave(); LED_turnoff_master(); OSA_TimeDelay(50); PRINTF("\r\n I2C slave enters low power mode...\r\n"); // set to allow entering specific modes SMC_HAL_SetProtection(SMC, kAllowPowerModeVlp); // set power mode to specific Run mode #if FSL_FEATURE_SMC_HAS_LPWUI smcConfig.lpwuiOptionValue = kSmcLpwuiEnabled; #endif #if FSL_FEATURE_SMC_HAS_PORPO smcConfig.porOptionValue = kSmcPorEnabled; #endif #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE smcConfig.powerModeName = kPowerModeRun; // If current status is HSRUN mode, change to RUN mode first. if (kStatHsrun == SMC_HAL_GetStat(SMC_BASE_PTR)) { SMC_HAL_SetMode(SMC_BASE_PTR, &smcConfig); } #endif smcConfig.powerModeName = kPowerModeWait; // Entry to Low Power Mode SMC_HAL_SetMode(SMC_BASE_PTR, &smcConfig); // LED_slave is still on during low power mode until I2C master send data to slave. // Turn off LED_slave to indicate MCU wake up by I2C address matching interrupt LED_turnoff_slave(); PRINTF("\r\n I2C slave wakes up from low power mode by I2C address matching.\r\n"); while(1); }