S32 SDK
smc_hal.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 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 
20 
51 #include "smc_hal.h"
52 #include <stddef.h>
53 
54 /*******************************************************************************
55  * Definitions
56  ******************************************************************************/
57 
58 
59 /*******************************************************************************
60  * PROTOTYPES
61  ******************************************************************************/
62 
63 static bool SMC_HAL_WaitForStatChange(const SMC_Type* const baseAddr, const power_mode_stat_t mode, const uint32_t timeout);
64 
66 #define SMC_TIMEOUT 1000U
67 
68 
69 /*******************************************************************************
70  * Code
71  ******************************************************************************/
72 
73 /*FUNCTION**********************************************************************
74  *
75  * Function Name : SMC_HAL_GetVersion
76  * Description : Get the version of the SMC module
77  * This function will get the version of the SMC module.
78  * function for more details.
79  *
80  * Implements SMC_HAL_GetVersion_Activity
81  *END**************************************************************************/
82 void SMC_HAL_GetVersion(const SMC_Type* const baseAddr, smc_version_info_t* const versionInfo)
83 {
84  uint32_t regValue;
85 
86  regValue = baseAddr->VERID;
87  regValue = (regValue & SMC_VERID_MAJOR_MASK) >> SMC_VERID_MAJOR_SHIFT;
88  versionInfo->majorNumber = regValue;
89 
90  regValue = baseAddr->VERID;
91  regValue = (regValue & SMC_VERID_MINOR_MASK) >> SMC_VERID_MINOR_SHIFT;
92  versionInfo->minorNumber = regValue;
93 
94  regValue = baseAddr->VERID;
95  regValue = (regValue & SMC_VERID_FEATURE_MASK) >> SMC_VERID_FEATURE_SHIFT;
96  versionInfo->featureNumber = regValue;
97 }
98 
99 /*FUNCTION**********************************************************************
100  *
101  * Function Name : SMC_HAL_SetPowerMode
102  * Description : Config the power mode
103  * This function will configure the power mode control for any run, stop and
104  * stop submode if needed. It will also configure the power options for specific
105  * power mode. Application should follow the proper procedure to configure and
106  * switch power mode between the different run and stop mode. Refer to reference
107  * manual for the proper procedure and supported power mode that can be configured
108  * and switch between each other. Refer to smc_power_mode_config_t for required
109  * parameters to configure the power mode and the supported options. Other options
110  * may need to configure through the hal driver individaully. Refer to hal driver
111  * header for details.
112  *
113  * Implements SMC_HAL_SetPowerMode_Activity
114  *END**************************************************************************/
116  const smc_power_mode_config_t* const powerModeConfig)
117 {
118  status_t retCode;
119  smc_stop_mode_t stopMode;
120  power_manager_modes_t powerModeName = powerModeConfig->powerModeName;
121 
125  static const uint16_t transitionTable[] =
126  {
127  (uint16_t)STAT_RUN, /* Next mode POWER_MANAGER_HSRUN */
128  (((uint16_t)STAT_VLPR) | ((uint16_t)STAT_HSRUN)), /* Next mode POWER_MANAGER_RUN */
129  (uint16_t)STAT_RUN, /* Next mode POWER_MANAGER_VLPR */
130  (uint16_t)STAT_RUN, /* Next mode POWER_MANAGER_WAIT */
131  (uint16_t)STAT_VLPR, /* Next mode POWER_MANAGER_VLPW */
132  (uint16_t)STAT_RUN, /* Next mode POWER_MANAGER_STOP */
133  (((uint16_t)STAT_RUN) | ((uint16_t)STAT_VLPR)), /* Next mode POWER_MANAGER_VLPS */
134  };
135  (void) transitionTable;
136 
137 
138  /* Verify the power mode name*/
139  DEV_ASSERT((size_t)powerModeName < (sizeof(transitionTable) / sizeof(transitionTable[0])));
140  /* Check the current and the next power mode in the transitioning table */
141  DEV_ASSERT((((uint16_t)SMC_HAL_GetPowerModeStatus(baseAddr)) & transitionTable[powerModeName]) != 0U);
142 
143  /* Branch based on power mode name*/
144  switch (powerModeName)
145  {
146  case POWER_MANAGER_RUN:
147  /* Set to RUN mode. */
149  /* Wait for stat change */
151  {
152  /* Timeout for power mode change expired. */
153  retCode = STATUS_TIMEOUT;
154  break;
155  }
156  retCode = STATUS_SUCCESS;
157  break;
158 
159  case POWER_MANAGER_VLPR:
160  /* "Very-Low-Power Modes" is allowed? */
162 
163  /* Set power mode to VLPR*/
165  /* Wait for stat change */
167  {
168  /* Timeout for power mode change expired. */
169  retCode = STATUS_TIMEOUT;
170  break;
171  }
172  retCode = STATUS_SUCCESS;
173  break;
174 
175 #if FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
176  case POWER_MANAGER_HSRUN:
177  /* "High Speed Mode" is allowed? */
179 
180  /* Set power mode to HSRUN */
182  /* Wait for stat change */
184  {
185  /* Timeout for power mode change expired. */
186  retCode = STATUS_TIMEOUT;
187  break;
188  }
189  retCode = STATUS_SUCCESS;
190  break;
191 #endif
192 #if FEATURE_SMC_HAS_WAIT_VLPW
193  case POWER_MANAGER_WAIT:
194  /* Fall-through */
195  case POWER_MANAGER_VLPW:
196  /* "Very-Low-Power Modes" is allowed? */
197  if (powerModeName == POWER_MODE_VLPW)
198  {
200  }
201 
202  /* Clear the SLEEPDEEP bit to disable deep sleep mode - WAIT */
204 
205  /* Cpu is going into sleep state */
206  STANDBY();
207 
208  retCode = STATUS_SUCCESS;
209  break;
210 #endif
211  case POWER_MANAGER_STOP:
212  /* Fall-through */
213  case POWER_MANAGER_VLPS:
214  if (powerModeName == POWER_MANAGER_STOP)
215  {
216  stopMode = SMC_STOP;
217 
218 #if FEATURE_SMC_HAS_STOPO
219  if (powerModeConfig->stopOption)
220  {
221 
222  SMC_HAL_SetStopOption(baseAddr, powerModeConfig->stopOptionValue);
223  }
224 #endif
225 #if FEATURE_SMC_HAS_PSTOPO
226  if (powerModeConfig->pStopOption)
227  {
228  SMC_HAL_SetPStopOption(baseAddr, powerModeConfig->pStopOptionValue);
229  }
230 #endif
231  }
232  else
233  {
234  stopMode = SMC_VLPS;
235 
236  /* "Very-Low-Power Modes" is allowed? */
238  }
239 
240  /* Set power mode to specified STOP mode*/
241  SMC_HAL_SetStopModeControl(baseAddr, stopMode);
242 
243  /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP)*/
245 
246  /* Cpu is going into deep sleep state */
247  STANDBY();
248 
249  retCode = STATUS_SUCCESS;
250  break;
251  default:
252  retCode = STATUS_UNSUPPORTED;
253  break;
254  }
255  return retCode;
256 }
257 
258 /*FUNCTION**********************************************************************
259  *
260  * Function Name : SMC_HAL_SetProtectionMode
261  * Description : Config all power mode protection settings
262  * This function will configure the power mode protection settings for
263  * supported power mode on the specified chip family. The availabe power modes
264  * are defined in smc_power_mode_protection_config_t. Application should provide
265  * the protect settings for all supported power mode on the chip and aslo this
266  * should be done at early system level init stage. Refer to reference manual
267  * for details. This register can only write once after power reset. So either
268  * use this function or use the individual set function if you only have single
269  * option to set.
270  *
271  * Implements SMC_HAL_SetProtectionMode_Activity
272  *END**************************************************************************/
273 void SMC_HAL_SetProtectionMode(SMC_Type* const baseAddr,
274  const smc_power_mode_protection_config_t* const protectConfig)
275 {
276  /* Initialize the setting */
277  uint32_t regValue = 0U;
278 
279  /* Check configurations for each mode and combine the setting together */
280  if (protectConfig->vlpProt)
281  {
282  regValue |= SMC_PMPROT_AVLP(1);
283  }
284 
285 #if FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
286  if (protectConfig->hsrunProt)
287  {
288  regValue |= SMC_PMPROT_AHSRUN(1);
289  }
290 #endif
291 
292  /* Write once into PMPROT register*/
293  baseAddr->PMPROT = regValue;
294 }
295 
296 /*FUNCTION**********************************************************************
297  *
298  * Function Name : SMC_HAL_GetProtectionMode
299  * Description : Get the current power mode protection setting
300  * This function will get the current power mode protection settings for
301  * a specified power mode.
302  *
303  * Implements SMC_HAL_GetProtectionMode_Activity
304  *END**************************************************************************/
305 bool SMC_HAL_GetProtectionMode(const SMC_Type* const baseAddr, const power_modes_protect_t protect)
306 {
307  bool retValue;
308  uint32_t regValue = (uint32_t)baseAddr->PMPROT;
309 
310  /* Check the mode range */
311  DEV_ASSERT(protect < ALLOW_MAX);
312 
313  /* Branch according to the mode and read the setting */
314  switch (protect)
315  {
316  case ALLOW_VLP:
317  regValue = (regValue & SMC_PMPROT_AVLP_MASK) >> SMC_PMPROT_AVLP_SHIFT;
318  break;
319 #if FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
320  case ALLOW_HSRUN:
321  regValue = (regValue & SMC_PMPROT_AHSRUN_MASK) >> SMC_PMPROT_AHSRUN_SHIFT;
322  break;
323 #endif
324  default:
325  /* Invalid command */
326  regValue = 0UL;
327  break;
328  }
329  retValue = (regValue == 0UL) ? false : true;
330  return retValue;
331 }
332 
333 
334 /*FUNCTION**********************************************************************
335  * Function Name : SMC_HAL_WaitForStatChange
336  * Description : Internal function used by SMC_HAL_SetPowerMode function
337  * to wait until the state is changed or timeout expires
338  *
339  * return power mode status change
340  * - true: power mode has been changed successfully
341  * - false: timeout expired, power mode has not been changed
342  *END**************************************************************************/
343 static bool SMC_HAL_WaitForStatChange(const SMC_Type* const baseAddr, const power_mode_stat_t mode, const uint32_t timeout)
344 {
345  uint32_t i;
346  bool retValue;
347 
348  for (i = 0U; i < timeout; i++)
349  {
350  if (mode == SMC_HAL_GetPowerModeStatus(baseAddr))
351  {
352  /* Power mode has been changed successfully */
353  break;
354  }
355  }
356 
357  /* If i greater or equal to timeout, then timeout expired (the power mode has not been changed)*/
358  retValue = (i < timeout);
359 
360  return retValue;
361 }
362 
363 
364 
365 /*******************************************************************************
366  * EOF
367  ******************************************************************************/
368 
#define SMC_VERID_FEATURE_MASK
Definition: S32K144.h:11082
#define S32_SCB_SCR_SLEEPDEEP_MASK
Definition: S32K144.h:9924
__I uint32_t VERID
Definition: S32K144.h:11050
#define SMC_PMPROT_AHSRUN(x)
Definition: S32K144.h:11119
bool SMC_HAL_GetProtectionMode(const SMC_Type *const baseAddr, const power_modes_protect_t protect)
Gets the the current power mode protection setting.
Definition: smc_hal.c:305
static power_mode_stat_t SMC_HAL_GetPowerModeStatus(const SMC_Type *const baseAddr)
Gets the current power mode stat.
Definition: smc_hal.h:510
#define SMC_PMPROT_AVLP_SHIFT
Definition: S32K144.h:11113
Power mode protection configuration Implements smc_power_mode_protection_config_t_Class.
Definition: smc_hal.h:186
#define SMC_PMPROT_AHSRUN_SHIFT
Definition: S32K144.h:11117
power_manager_modes_t powerModeName
Definition: smc_hal.h:199
#define DEV_ASSERT(x)
Definition: devassert.h:78
uint32_t minorNumber
Definition: smc_hal.h:217
#define SMC_VERID_FEATURE_SHIFT
Definition: S32K144.h:11083
__IO uint32_t PMPROT
Definition: S32K144.h:11052
SMC module version number Implements smc_version_info_t_Class.
Definition: smc_hal.h:214
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 S32_SCB
Definition: S32K144.h:9795
static void SMC_HAL_SetStopModeControl(SMC_Type *const baseAddr, const smc_stop_mode_t stopMode)
Configures the STOP mode control setting.
Definition: smc_hal.h:362
#define STANDBY()
Enter low-power standby state WFI (Wait For Interrupt) makes the processor suspend execution (Clock i...
Definition: s32_core_cm4.h:103
#define SMC_PMPROT_AVLP_MASK
Definition: S32K144.h:11112
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:31
#define SMC_PMPROT_AVLP(x)
Definition: S32K144.h:11115
static bool SMC_HAL_WaitForStatChange(const SMC_Type *const baseAddr, const power_mode_stat_t mode, const uint32_t timeout)
Definition: smc_hal.c:343
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
void SMC_HAL_GetVersion(const SMC_Type *const baseAddr, smc_version_info_t *const versionInfo)
Get the version of the SMC module.
Definition: smc_hal.c:82
#define SMC_VERID_MAJOR_MASK
Definition: S32K144.h:11090
Power mode control configuration used for calling the SMC_SYS_SetPowerMode API Implements smc_power_m...
Definition: smc_hal.h:198
static void SMC_HAL_SetStopOption(SMC_Type *const baseAddr, const smc_stop_option_t option)
Configures the STOPO (Stop Option).
Definition: smc_hal.h:447
power_modes_protect_t
Power Modes Protection Implements power_modes_protect_t_Class.
Definition: smc_hal.h:140
uint32_t featureNumber
Definition: smc_hal.h:218
uint32_t majorNumber
Definition: smc_hal.h:216
#define SMC_TIMEOUT
Definition: smc_hal.c:66
#define SMC_VERID_MAJOR_SHIFT
Definition: S32K144.h:11091
power_mode_stat_t
Power Modes in PMSTAT Implements power_mode_stat_t_Class.
Definition: smc_hal.h:125
#define SMC_VERID_MINOR_MASK
Definition: S32K144.h:11086
smc_stop_mode_t
Stop mode definition Implements smc_stop_mode_t_Class.
Definition: smc_hal.h:163
smc_stop_option_t stopOptionValue
Definition: smc_hal.h:202
#define SMC_PMPROT_AHSRUN_MASK
Definition: S32K144.h:11116
#define SMC_VERID_MINOR_SHIFT
Definition: S32K144.h:11087