Пример #1
0
/*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;
}
Пример #2
0
/*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;
    }
}
Пример #3
0
/*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;
}
Пример #4
0
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;
    }
}
Пример #5
0
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;
    }
}
Пример #6
0
/*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);
}