S32 SDK
power_manager_smc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
3  * Copyright 2016 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
19 
103 #include "power_manager.h"
104 #include "smc_hal.h"
105 
107 #define POWER_SET_MODE_TIMEOUT 1000U
108 
111 
112 /*******************************************************************************
113  * PROTOTYPES
114  ******************************************************************************/
115 
119 
123 
124 /*******************************************************************************
125  * Code
126  ******************************************************************************/
127 
128 /*******************************************************************************
129  *
130  * It is expected that prior to the POWER_SYS_Init() call the write-once protection
131  * register was configured appropriately allowing entry to all required low power
132  * modes.
133  * The following is an example of how to set up two power modes and one
134  * callback, and initialize the Power manager with structures containing their settings.
135  * The example shows two possible ways the configuration structures can be stored
136  * (ROM or RAM), although it is expected that they will be placed in the read-only
137  * memory to save the RAM space. (Note: In the example it is assumed that the programmed chip
138  * doesn't support any optional power options described in the power_manager_user_config_t)
139  * :
140  * @code
141 
142  power_manager_user_config_t vlprConfig = { vlprConfig power mode configuration
143  .powerMode = POWER_MANAGER_VLPR,
144  .sleepOnExitOption = false,
145  .sleepOnExitValue = false,
146  };
147 
148  power_manager_user_config_t stopConfig = { stopConfig power mode configuration
149  .powerMode = POWER_MANAGER_STOP,
150  .sleepOnExitOption = false,
151  .sleepOnExitValue = false,
152  };
153 
154  power_manager_user_config_t const * powerConfigsArr[] = { Power mode configurations array
155  &vlprConfig,
156  &stopConfig
157  };
158 
159  power_manager_callback_user_config_t callbackCfg0 = { Callback configuration structure callbackCfg0
160  .callbackFunction = &callback0,
161  .callbackType = POWER_MANAGER_CALLBACK_BEFORE_AFTER,
162  .callbackData = (void *)0,
163  };
164 
165  power_manager_callback_user_config_t const * callbacksConfigsArr[] = { Callback configuration structures array
166  &callbackCfg0
167  };
168 
169  status_t callback0(power_manager_notify_struct_t * notify, Definition of power manager callback
170  power_manager_callback_data_t * dataPtr)
171  {
172  status_t ret = STATUS_SUCCESS;
173  ...
174  return ret;
175  }
176 
177  int main(void) Main function
178  {
179  status_t ret = STATUS_SUCCESS;
180 
181  Calling of init method
182  POWER_SYS_Init(&powerConfigsArr, 2U, &powerStaticCallbacksConfigsArr, 1U);
183 
184  Switch to VLPR mode
185  ret = POWER_SYS_SetMode(MODE_VLPR,POWER_MANAGER_POLICY_AGREEMENT);
186 
187  if (ret != STATUS_SUCCESS)
188  {
189  return -1;
190  }
191  return 0;
192  }
193 
194  * @endcode
195  *
196  *END**************************************************************************/
197 
199 {
200  smc_power_mode_protection_config_t powerModeProtConfig =
201  {
202  .vlpProt = true, /* Very low power mode is allowed. */
203  .hsrunProt = true /* High speed mode is allowed. */
204  };
205 
206  /* Very low power modes and high speed mode are not protected. */
207  SMC_HAL_SetProtectionMode(SMC, &powerModeProtConfig);
208 
209  return STATUS_SUCCESS;
210 }
211 
213 {
214  return STATUS_SUCCESS;
215 }
216 
217 /*FUNCTION**********************************************************************
218  *
219  * Function Name : POWER_SYS_DoSetMode
220  * Description : Configures the power mode.
221  *
222  * This function performs the actual implementation-specific logic to switch to one of the defined power modes.
223  *END**************************************************************************/
225 {
226  status_t returnCode; /* Function return */
227 
228  /* Check whether the power mode is a sleeping or a running power mode */
229  if (configPtr->powerMode <= POWER_MANAGER_VLPR)
230  {
231  /* Switch to a running power mode */
232  returnCode = POWER_SYS_SwitchToRunningPowerMode(configPtr);
233  }
234  else
235  {
236  /* Switch to a sleeping power mode */
237  returnCode = POWER_SYS_SwitchToSleepingPowerMode(configPtr);
238  }
239 
240  return returnCode;
241 }
242 
243 /*FUNCTION**********************************************************************
244  *
245  * Function Name : POWER_SYS_GetCurrentMode
246  * Description : Returns currently running power mode.
247  *
248  * Implements POWER_SYS_GetCurrentMode_Activity
249  *END**************************************************************************/
251 {
252  power_manager_modes_t retVal;
254  {
255 #if FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
256  /* High speed run mode */
257  case STAT_HSRUN:
258  retVal = POWER_MANAGER_HSRUN;
259  break;
260 #endif
261  /* Run mode */
262  case STAT_RUN:
263  retVal = POWER_MANAGER_RUN;
264  break;
265  /* Very low power run mode */
266  case STAT_VLPR:
267  retVal = POWER_MANAGER_VLPR;
268  break;
269  /* This should never happen - core has to be in some run mode to execute code */
270  default:
271  retVal = POWER_MANAGER_MAX;
272  break;
273  }
274  return retVal;
275 }
276 
277 /*FUNCTION**************************************************************************
278  * Function Name : POWER_SYS_WaitForRunStatus
279  * Description :Internal function used by POWER_SYS_SwitchToSleepingPowerMode and
280  * POWER_SYS_SwitchToRunningPowerMode functions
281  * mode The expected running mode
282  *
283  *END*******************************************************************************/
285 {
286  status_t retCode;
287  power_mode_stat_t modeStat;
288  uint32_t i = 0U;
289 
290  switch(mode)
291  {
292  case SMC_RUN:
293  modeStat = STAT_RUN;
294  retCode = STATUS_SUCCESS;
295  break;
296  case SMC_VLPR:
297  modeStat = STAT_VLPR;
298  retCode = STATUS_SUCCESS;
299  break;
300 #if FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
301  case SMC_HSRUN:
302  modeStat = STAT_HSRUN;
303  retCode = STATUS_SUCCESS;
304  break;
305 #endif
306  default:
307  /* invalid parameter */
308  modeStat = STAT_INVALID;
309  retCode = STATUS_UNSUPPORTED;
310  break;
311  }
312  if (STATUS_SUCCESS == retCode)
313  {
314  for (; i < POWER_SET_MODE_TIMEOUT ; i++)
315  {
316  if(SMC_HAL_GetPowerModeStatus(SMC) == modeStat)
317  {
318  break;
319  }
320  }
321  }
322  if (i >= POWER_SET_MODE_TIMEOUT)
323  {
325  }
326  return retCode;
327 }
328 
329 
330 /*FUNCTION**********************************************************************************************
331  * Function Name : POWER_SYS_SwitchToRunningPowerMode
332  * Description :Internal function used by POWER_SYS_SetMode function to switch to a running power mode
333  * configPtr pointer to the requested user-defined power mode configuration
334  *
335  *END***************************************************************************************************/
337 {
338  smc_power_mode_config_t halModeConfig; /* SMC HAL layer configuration structure */
339  status_t returnCode;
340 
341  /* Configure the HAL layer */
342  switch (configPtr->powerMode) {
343 #if FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
344  /* High speed run mode */
345  case POWER_MANAGER_HSRUN:
346  /* High speed run mode can be entered only from Run mode */
348  {
350  returnCode = POWER_SYS_WaitForModeStatus(SMC_RUN);
351  }
352  else
353  {
354  returnCode = STATUS_SUCCESS;
355  }
356  if (STATUS_SUCCESS == returnCode)
357  {
358  halModeConfig.powerModeName = POWER_MANAGER_HSRUN;
359 
360  /* Switch the mode */
361  if (SMC_HAL_SetPowerMode(SMC, &halModeConfig) == STATUS_SUCCESS)
362  {
364  }
365  else
366  {
367  returnCode = STATUS_MCU_TRANSITION_FAILED;
368  }
369  }
370  break;
371 #endif
372  /* Run mode */
373  case POWER_MANAGER_RUN:
374  halModeConfig.powerModeName = POWER_MANAGER_RUN;
375  returnCode = STATUS_SUCCESS;
376  /* Switch the mode */
377  if (SMC_HAL_SetPowerMode(SMC, &halModeConfig) == STATUS_SUCCESS)
378  {
379  returnCode = POWER_SYS_WaitForModeStatus(SMC_RUN);
380  }
381  else
382  {
383  returnCode = STATUS_MCU_TRANSITION_FAILED;
384  }
385  break;
386  /* Very low power run mode */
387  case POWER_MANAGER_VLPR:
388  /* Very low power run mode can be entered only from Run mode */
390  {
392  returnCode = POWER_SYS_WaitForModeStatus(SMC_RUN);
393  }
394  else
395  {
396  returnCode = STATUS_SUCCESS;
397  }
398 
399  if (STATUS_SUCCESS == returnCode)
400  {
401  halModeConfig.powerModeName = POWER_MANAGER_VLPR;
402 
403  /* Switch the mode */
404  if (SMC_HAL_SetPowerMode(SMC, &halModeConfig) == STATUS_SUCCESS)
405  {
407  }
408  else
409  {
410  returnCode = STATUS_MCU_TRANSITION_FAILED;
411  }
412  }
413  break;
414  /* Wait mode */
415  default:
416  /* invalid power mode */
417  returnCode = STATUS_UNSUPPORTED;
418  halModeConfig.powerModeName = POWER_MANAGER_MAX;
419  break;
420  }
421 
422  return returnCode;
423 }
424 
425 
426 /*FUNCTION**********************************************************************************************
427  * Function Name : POWER_SYS_SwitchToSleepingPowerMode
428  * Description :Internal function used by POWER_SYS_SetMode function to switch to a sleeping power mode
429  * configPtr pointer to the requested user-defined power mode configuration
430  *
431  *END***************************************************************************************************/
433 {
434  smc_power_mode_config_t halModeConfig; /* SMC HAL layer configuration structure */
435  status_t returnCode; /* return value */
436  power_mode_stat_t pwrModeStat; /* power mode stat */
437 
438  /* Configure the HAL layer */
439  switch (configPtr->powerMode) {
440 #if FEATURE_SMC_HAS_WAIT_VLPW
441  /* Wait mode */
442  case POWER_MANAGER_WAIT:
443  /* Wait mode can be entered only from Run mode */
445  {
447  returnCode = POWER_SYS_WaitForModeStatus(SMC_RUN);
448  }
449  else
450  {
451  returnCode = STATUS_SUCCESS;
452  }
453  halModeConfig.powerModeName = POWER_MANAGER_WAIT;
454  break;
455  /* Very low power wait mode */
456  case POWER_MANAGER_VLPW:
457  /* Very low power wait mode can be netered only from Very low power run mode */
459  {
462  }
463  else
464  {
465  returnCode = STATUS_SUCCESS;
466  }
467  halModeConfig.powerModeName = POWER_MANAGER_VLPW;
468  break;
469 #endif
470 #if FEATURE_SMC_HAS_PSTOPO
471  /* Partial stop modes */
472  case POWER_MANAGER_PSTOP1:
473  /* fall-through */
474  case POWER_MANAGER_PSTOP2:
475  /* fall-through */
476 #endif
477 #if FEATURE_SMC_HAS_STOPO
478  /* Stop modes */
479  case POWER_MANAGER_STOP1:
480  /* fall-through */
481  case POWER_MANAGER_STOP2:
482  /* fall-through */
483 #endif
484  /* Stop mode */
485  case POWER_MANAGER_STOP:
486  /* Stop mode can be entered only from Run mode */
488  {
490  returnCode = POWER_SYS_WaitForModeStatus(SMC_RUN);
491  }
492  else
493  {
494  returnCode = STATUS_SUCCESS;
495  }
496  halModeConfig.powerModeName = POWER_MANAGER_STOP;
497 #if FEATURE_SMC_HAS_PSTOPO
498  halModeConfig.pstopOption = true;
499  /* Set the partial stop option value */
500  if (POWER_MANAGER_PSTOP1 == configPtr->powerMode)
501  {
502  halModeConfig.pstopOptionValue = SMC_PSTOP_STOP1;
503  }
504  else if(POWER_MANAGER_PSTOP2 == configPtr->powerMode)
505  {
506  halModeConfig.pstopOptionValue = SMC_PSTOP_STOP2;
507  }
508  else
509  {
510  halModeConfig.pstopOptionValue = SMC_PSTOP_STOP;
511  }
512 #endif
513 #if FEATURE_SMC_HAS_STOPO
514  /* Set the stop option value */
515  if (POWER_MANAGER_STOP1 == configPtr->powerMode)
516  {
517  halModeConfig.stopOption = true;
518  halModeConfig.stopOptionValue = SMC_STOP1;
519  }
520  else if(POWER_MANAGER_STOP2 == configPtr->powerMode)
521  {
522  halModeConfig.stopOption = true;
523  halModeConfig.stopOptionValue = SMC_STOP2;
524  }
525  else
526  {
527  halModeConfig.stopOption = false;
528  }
529 #endif
530  break;
531  /* Very low power stop mode */
532  case POWER_MANAGER_VLPS:
533  pwrModeStat = SMC_HAL_GetPowerModeStatus(SMC);
534  /* Very low power stop mode can be entered only from Run mode or Very low power run mode*/
535  if ((pwrModeStat != STAT_RUN) && (pwrModeStat != STAT_VLPR))
536  {
538  returnCode = POWER_SYS_WaitForModeStatus(SMC_RUN);
539  }
540  else
541  {
542  returnCode = STATUS_SUCCESS;
543  }
544  halModeConfig.powerModeName = POWER_MANAGER_VLPS;
545  break;
546  default:
547  /* invalid power mode */
548  returnCode = STATUS_UNSUPPORTED;
549  halModeConfig.powerModeName = POWER_MANAGER_MAX;
550  break;
551  }
552 
553  if (STATUS_SUCCESS == returnCode)
554  {
555  /* Configure ARM core what to do after interrupt invoked in (deep) sleep state */
556  if (configPtr->sleepOnExitOption)
557  {
558  if (configPtr->sleepOnExitValue)
559  {
560  /* Go back to (deep) sleep state on ISR exit */
562  }
563  else
564  {
565  /* Do not re-enter (deep) sleep state on ISR exit */
567  }
568  }
569 
570  /* Switch the mode */
571  if (SMC_HAL_SetPowerMode(SMC, &halModeConfig) != STATUS_SUCCESS)
572  {
573  returnCode = STATUS_MCU_TRANSITION_FAILED;
574  }
575  }
576  return returnCode;
577 }
578 
579 /*******************************************************************************
580  * EOF
581  ******************************************************************************/
582 
#define SMC
Definition: S32K144.h:11066
static status_t POWER_SYS_SwitchToRunningPowerMode(const power_manager_user_config_t *const configPtr)
status_t POWER_SYS_DoSetMode(const power_manager_user_config_t *const configPtr)
static status_t POWER_SYS_SwitchToSleepingPowerMode(const power_manager_user_config_t *const configPtr)
static power_mode_stat_t SMC_HAL_GetPowerModeStatus(const SMC_Type *const baseAddr)
Gets the current power mode stat.
Definition: smc_hal.h:510
Power mode protection configuration Implements smc_power_mode_protection_config_t_Class.
Definition: smc_hal.h:186
power_manager_modes_t powerModeName
Definition: smc_hal.h:199
status_t POWER_SYS_DoInit(void)
void SMC_HAL_SetProtectionMode(SMC_Type *const baseAddr, const smc_power_mode_protection_config_t *const protectConfig)
Configures all power mode protection settings.
Definition: smc_hal.c:273
#define POWER_SET_MODE_TIMEOUT
#define S32_SCB
Definition: S32K144.h:9795
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:31
power_manager_state_t gPowerManagerState
Power manager internal structure.
#define S32_SCB_SCR_SLEEPONEXIT_MASK
Definition: S32K144.h:9920
status_t POWER_SYS_DoDeinit(void)
power_manager_modes_t POWER_SYS_GetCurrentMode(void)
This function returns currently running power mode.
power_manager_modes_t
Power modes enumeration.
Definition: smc_hal.h:76
static void SMC_HAL_SetRunModeControl(SMC_Type *const baseAddr, const smc_run_mode_t runMode)
Configures the the RUN mode control setting.
Definition: smc_hal.h:307
status_t SMC_HAL_SetPowerMode(SMC_Type *const baseAddr, const smc_power_mode_config_t *const powerModeConfig)
Configures the power mode.
Definition: smc_hal.c:115
smc_run_mode_t
Run mode definition Implements smc_run_mode_t_Class.
Definition: smc_hal.h:151
Power mode control configuration used for calling the SMC_SYS_SetPowerMode API Implements smc_power_m...
Definition: smc_hal.h:198
Power mode user configuration structure.
Definition: smc_hal.h:114
Power manager internal state structure.
power_manager_modes_t powerMode
Definition: smc_hal.h:116
power_mode_stat_t
Power Modes in PMSTAT Implements power_mode_stat_t_Class.
Definition: smc_hal.h:125
static status_t POWER_SYS_WaitForModeStatus(smc_run_mode_t mode)
smc_stop_option_t stopOptionValue
Definition: smc_hal.h:202