1/*
2 * Copyright 2017-2021, NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#include "fsl_dcdc.h"
10
11/* Component ID definition, used by tools. */
12#ifndef FSL_COMPONENT_ID
13#define FSL_COMPONENT_ID "platform.drivers.dcdc_1"
14#endif
15
16/*******************************************************************************
17 * Prototypes
18 ******************************************************************************/
19/*!
20 * @brief Get instance number for DCDC module.
21 *
22 * @param base DCDC peripheral base address
23 */
24static uint32_t DCDC_GetInstance(DCDC_Type *base);
25
26#if (defined(DCDC_REG4_ENABLE_SP_MASK) && DCDC_REG4_ENABLE_SP_MASK)
27/*!
28 * @brief Convert the byte array to word.
29 *
30 * @param ptrArray Pointer to the byte array.
31 * @return The converted result.
32 */
33static uint32_t DCDC_ConvertByteArrayToWord(uint8_t *ptrArray);
34#endif /* DCDC_REG4_ENABLE_SP_MASK */
35
36/*******************************************************************************
37 * Variables
38 ******************************************************************************/
39/*! @brief Pointers to DCDC bases for each instance. */
40static DCDC_Type *const s_dcdcBases[] = DCDC_BASE_PTRS;
41
42#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
43/*! @brief Pointers to DCDC clocks for each instance. */
44static const clock_ip_name_t s_dcdcClocks[] = DCDC_CLOCKS;
45#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
46
47/*******************************************************************************
48 * Code
49 ******************************************************************************/
50static uint32_t DCDC_GetInstance(DCDC_Type *base)
51{
52 uint32_t instance;
53
54 /* Find the instance index from base address mappings. */
55 for (instance = 0; instance < ARRAY_SIZE(s_dcdcBases); instance++)
56 {
57 if (s_dcdcBases[instance] == base)
58 {
59 break;
60 }
61 }
62
63 assert(instance < ARRAY_SIZE(s_dcdcBases));
64
65 return instance;
66}
67
68#if (defined(DCDC_REG4_ENABLE_SP_MASK) && DCDC_REG4_ENABLE_SP_MASK)
69static uint32_t DCDC_ConvertByteArrayToWord(uint8_t *ptrArray)
70{
71 assert(ptrArray != NULL);
72
73 uint32_t temp32 = 0UL;
74 uint8_t index;
75
76 for (index = 0U; index < 4U; index++)
77 {
78 temp32 |= ptrArray[index] << ((index % 4U) * 8U);
79 }
80
81 return temp32;
82}
83#endif /* DCDC_REG4_ENABLE_SP_MASK */
84
85#if defined(FSL_FEATURE_DCDC_HAS_CTRL_REG) && FSL_FEATURE_DCDC_HAS_CTRL_REG
86/*!
87 * brief Enable the access to DCDC registers.
88 *
89 * param base DCDC peripheral base address.
90 * param config Pointer to the configuration structure.
91 */
92void DCDC_Init(DCDC_Type *base, dcdc_config_t *config)
93{
94#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
95 /* Enable the clock. */
96 CLOCK_EnableClock(s_dcdcClocks[DCDC_GetInstance(base)]);
97#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
98 uint32_t tmp32 = base->CTRL0;
99
100 tmp32 |= DCDC_CTRL0_CONTROL_MODE(config->controlMode) | DCDC_CTRL0_TRIM_HOLD(config->trimInputMode);
101
102 if (config->enableDcdcTimeout)
103 {
104 tmp32 |= DCDC_CTRL0_ENABLE_DCDC_CNT_MASK;
105 }
106 if (config->enableSwitchingConverterOutput)
107 {
108 tmp32 |= DCDC_CTRL0_DIG_EN_MASK;
109 }
110 base->CTRL0 |= DCDC_CTRL0_ENABLE_MASK;
111 base->CTRL0 = tmp32;
112}
113#else
114/*!
115 * brief Enable the access to DCDC registers.
116 *
117 * param base DCDC peripheral base address.
118 */
119void DCDC_Init(DCDC_Type *base)
120{
121#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
122 /* Enable the clock. */
123 CLOCK_EnableClock(s_dcdcClocks[DCDC_GetInstance(base)]);
124#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
125}
126#endif /* FSL_FEATURE_DCDC_HAS_CTRL_REG */
127
128/*!
129 * brief Disable the access to DCDC registers.
130 *
131 * param base DCDC peripheral base address.
132 */
133void DCDC_Deinit(DCDC_Type *base)
134{
135#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
136 /* Disable the clock. */
137 CLOCK_DisableClock(s_dcdcClocks[DCDC_GetInstance(base)]);
138#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
139}
140
141#if defined(FSL_FEATURE_DCDC_HAS_CTRL_REG) && FSL_FEATURE_DCDC_HAS_CTRL_REG
142/*!
143 * brief Get the default setting for DCDC user configuration structure.
144 *
145 * This function initializes the user configuration structure to a default value. The default values are:
146 * code
147 * config->controlMode = kDCDC_StaticControl;
148 * config->trimInputMode = kDCDC_SampleTrimInput;
149 * config->enableDcdcTimeout = false;
150 * config->enableSwitchingConverterOutput = false;
151 * endcode
152 *
153 * param config Pointer to configuration structure. See to "dcdc_config_t"
154 */
155void DCDC_GetDefaultConfig(DCDC_Type *base, dcdc_config_t *config)
156{
157 assert(NULL != config);
158
159 /* Initializes the configure structure to zero. */
160 (void)memset(config, 0, sizeof(*config));
161
162 config->controlMode = kDCDC_StaticControl;
163 config->trimInputMode = kDCDC_SampleTrimInput;
164 config->enableDcdcTimeout = false;
165 config->enableSwitchingConverterOutput = false;
166}
167
168/*!
169 * @brief Make DCDC enter into low power modes.
170 *
171 * @param base DCDC peripheral base address.
172 * @param mode DCDC low power mode selection. See to "_dcdc_low_power_mode"
173 */
174void DCDC_EnterLowPowerMode(DCDC_Type *base, dcdc_low_power_mode_t mode)
175{
176 switch (mode)
177 {
178 case kDCDC_StandbyMode:
179 base->CTRL0 |= DCDC_CTRL0_STBY_EN_MASK;
180 break;
181 case kDCDC_LowPowerMode:
182 base->CTRL0 |= DCDC_CTRL0_LP_MODE_EN_MASK;
183 break;
184 case kDCDC_GpcStandbyLowPowerMode:
185 base->CTRL0 |= DCDC_CTRL0_STBY_LP_MODE_EN_MASK;
186 break;
187 default:
188 assert(false);
189 break;
190 }
191}
192#endif /* FSL_FEATURE_DCDC_HAS_CTRL_REG */
193
194/*!
195 * brief Configure the DCDC clock source.
196 *
197 * param base DCDC peripheral base address.
198 * param clockSource Clock source for DCDC. See to "dcdc_clock_source_t".
199 */
200void DCDC_SetClockSource(DCDC_Type *base, dcdc_clock_source_t clockSource)
201{
202 uint32_t tmp32;
203
204 /* Configure the DCDC_REG0 register. */
205 tmp32 = base->REG0 & ~(DCDC_REG0_XTAL_24M_OK_MASK | DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK |
206 DCDC_REG0_SEL_CLK_MASK | DCDC_REG0_PWD_OSC_INT_MASK);
207 switch (clockSource)
208 {
209 case kDCDC_ClockInternalOsc:
210 tmp32 |= DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK;
211 break;
212 case kDCDC_ClockExternalOsc:
213 /* Choose the external clock and disable the internal clock. */
214 tmp32 |= DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK | DCDC_REG0_SEL_CLK_MASK | DCDC_REG0_PWD_OSC_INT_MASK;
215 break;
216 case kDCDC_ClockAutoSwitch:
217 /* Set to switch from internal ring osc to xtal 24M if auto mode is enabled. */
218 tmp32 |= DCDC_REG0_XTAL_24M_OK_MASK;
219 break;
220 default:
221 assert(false);
222 break;
223 }
224 base->REG0 = tmp32;
225}
226
227/*!
228 * brief Get the default setting for detection configuration.
229 *
230 * The default configuration are set according to responding registers' setting when powered on.
231 * They are:
232 * code
233 * config->enableXtalokDetection = false;
234 * config->powerDownOverVoltageDetection = true;
235 * config->powerDownLowVlotageDetection = false;
236 * config->powerDownOverCurrentDetection = true;
237 * config->powerDownPeakCurrentDetection = true;
238 * config->powerDownZeroCrossDetection = true;
239 * config->OverCurrentThreshold = kDCDC_OverCurrentThresholdAlt0;
240 * config->PeakCurrentThreshold = kDCDC_PeakCurrentThresholdAlt0;
241 * endcode
242 *
243 * param config Pointer to configuration structure. See to "dcdc_detection_config_t"
244 */
245void DCDC_GetDefaultDetectionConfig(dcdc_detection_config_t *config)
246{
247 assert(NULL != config);
248
249 /* Initializes the configure structure to zero. */
250 (void)memset(config, 0, sizeof(*config));
251
252 config->enableXtalokDetection = false;
253#if (defined(FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT) && (FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT == 2))
254 config->powerDownOverVoltageVdd1P8Detection = true;
255 config->powerDownOverVoltageVdd1P0Detection = true;
256#else
257 config->powerDownOverVoltageDetection = true;
258#endif /* FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT */
259 config->powerDownLowVlotageDetection = false;
260 config->powerDownOverCurrentDetection = true;
261 config->powerDownPeakCurrentDetection = true;
262 config->powerDownZeroCrossDetection = true;
263 config->OverCurrentThreshold = kDCDC_OverCurrentThresholdAlt0;
264 config->PeakCurrentThreshold = kDCDC_PeakCurrentThresholdAlt0;
265}
266
267/*!
268 * breif Configure the DCDC detection.
269 *
270 * param base DCDC peripheral base address.
271 * param config Pointer to configuration structure. See to "dcdc_detection_config_t"
272 */
273void DCDC_SetDetectionConfig(DCDC_Type *base, const dcdc_detection_config_t *config)
274{
275 assert(NULL != config);
276
277 uint32_t tmp32;
278 /* Configure the DCDC_REG0 register. */
279 tmp32 = base->REG0 & ~(DCDC_REG0_XTALOK_DISABLE_MASK
280#if (defined(FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT) && (FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT == 2))
281 | DCDC_REG0_PWD_HIGH_VDD1P8_DET_MASK | DCDC_REG0_PWD_HIGH_VDD1P0_DET_MASK
282#else
283 | DCDC_REG0_PWD_HIGH_VOLT_DET_MASK
284#endif /* FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT */
285#if defined(FSL_FEATURE_DCDC_HAS_REG0_DCDC_IN_DET) && FSL_FEATURE_DCDC_HAS_REG0_DCDC_IN_DET
286 | DCDC_REG0_PWD_CMP_DCDC_IN_DET_MASK
287#else
288 | DCDC_REG0_PWD_CMP_BATT_DET_MASK
289#endif /* FSL_FEATURE_DCDC_HAS_REG0_DCDC_IN_DET */
290 | DCDC_REG0_PWD_OVERCUR_DET_MASK | DCDC_REG0_PWD_CUR_SNS_CMP_MASK | DCDC_REG0_PWD_ZCD_MASK |
291 DCDC_REG0_CUR_SNS_THRSH_MASK | DCDC_REG0_OVERCUR_TRIG_ADJ_MASK);
292
293 tmp32 |= DCDC_REG0_CUR_SNS_THRSH(config->PeakCurrentThreshold) |
294 DCDC_REG0_OVERCUR_TRIG_ADJ(config->OverCurrentThreshold);
295 if (false == config->enableXtalokDetection)
296 {
297 tmp32 |= DCDC_REG0_XTALOK_DISABLE_MASK;
298 }
299#if (defined(FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT) && (FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT == 2))
300 if (config->powerDownOverVoltageVdd1P8Detection)
301 {
302 tmp32 |= DCDC_REG0_PWD_HIGH_VDD1P8_DET_MASK;
303 }
304 if (config->powerDownOverVoltageVdd1P0Detection)
305 {
306 tmp32 |= DCDC_REG0_PWD_HIGH_VDD1P0_DET_MASK;
307 }
308#else
309 if (config->powerDownOverVoltageDetection)
310 {
311 tmp32 |= DCDC_REG0_PWD_HIGH_VOLT_DET_MASK;
312 }
313#endif /* FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT */
314 if (config->powerDownLowVlotageDetection)
315 {
316#if defined(FSL_FEATURE_DCDC_HAS_REG0_DCDC_IN_DET) && FSL_FEATURE_DCDC_HAS_REG0_DCDC_IN_DET
317 tmp32 |= DCDC_REG0_PWD_CMP_DCDC_IN_DET_MASK;
318#else
319 tmp32 |= DCDC_REG0_PWD_CMP_BATT_DET_MASK;
320#endif /* FSL_FEATURE_DCDC_HAS_REG0_DCDC_IN_DET */
321 }
322 if (config->powerDownOverCurrentDetection)
323 {
324 tmp32 |= DCDC_REG0_PWD_OVERCUR_DET_MASK;
325 }
326 if (config->powerDownPeakCurrentDetection)
327 {
328 tmp32 |= DCDC_REG0_PWD_CUR_SNS_CMP_MASK;
329 }
330 if (config->powerDownZeroCrossDetection)
331 {
332 tmp32 |= DCDC_REG0_PWD_ZCD_MASK;
333 }
334 base->REG0 = tmp32;
335}
336
337/*!
338 * brief Get the default setting for low power configuration.
339 *
340 * The default configuration are set according to responding registers' setting when powered on.
341 * They are:
342 * code
343 * config->enableOverloadDetection = true;
344 * config->enableAdjustHystereticValue = false;
345 * config->countChargingTimePeriod = kDCDC_CountChargingTimePeriod8Cycle;
346 * config->countChargingTimeThreshold = kDCDC_CountChargingTimeThreshold32;
347 * endcode
348 *
349 * param config Pointer to configuration structure. See to "dcdc_low_power_config_t"
350 */
351void DCDC_GetDefaultLowPowerConfig(dcdc_low_power_config_t *config)
352{
353 assert(NULL != config);
354
355 /* Initializes the configure structure to zero. */
356 (void)memset(config, 0, sizeof(*config));
357#if !(defined(FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS) && FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS)
358 config->enableOverloadDetection = true;
359#endif /* FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS */
360 config->enableAdjustHystereticValue = false;
361 config->countChargingTimePeriod = kDCDC_CountChargingTimePeriod8Cycle;
362 config->countChargingTimeThreshold = kDCDC_CountChargingTimeThreshold32;
363}
364
365/*!
366 * brief Configure the DCDC low power.
367 *
368 * param base DCDC peripheral base address.
369 * param config Pointer to configuration structure. See to "dcdc_low_power_config_t".
370 */
371void DCDC_SetLowPowerConfig(DCDC_Type *base, const dcdc_low_power_config_t *config)
372{
373 assert(NULL != config);
374
375 uint32_t tmp32;
376 /* Configure the DCDC_REG0 register. */
377 tmp32 = base->REG0 &
378 ~(DCDC_REG0_LP_HIGH_HYS_MASK | DCDC_REG0_LP_OVERLOAD_FREQ_SEL_MASK | DCDC_REG0_LP_OVERLOAD_THRSH_MASK
379#if !(defined(FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS) && FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS)
380 | DCDC_REG0_EN_LP_OVERLOAD_SNS_MASK
381#endif /* FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS */
382 );
383 tmp32 |= DCDC_REG0_LP_OVERLOAD_FREQ_SEL(config->countChargingTimePeriod) |
384 DCDC_REG0_LP_OVERLOAD_THRSH(config->countChargingTimeThreshold);
385#if !(defined(FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS) && FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS)
386 if (config->enableOverloadDetection)
387 {
388 tmp32 |= DCDC_REG0_EN_LP_OVERLOAD_SNS_MASK;
389 }
390#endif /* FSL_FEATURE_DCDC_HAS_NO_REG0_EN_LP_OVERLOAD_SNS */
391 if (config->enableAdjustHystereticValue)
392 {
393 tmp32 |= DCDC_REG0_LP_HIGH_HYS_MASK;
394 }
395 base->REG0 = tmp32;
396}
397
398/*!
399 * brief Get DCDC status flags.
400 *
401 * param base peripheral base address.
402 * return Mask of asserted status flags. See to "_dcdc_status_flags_t".
403 */
404uint32_t DCDC_GetstatusFlags(DCDC_Type *base)
405{
406 uint32_t tmp32 = 0U;
407
408 if (DCDC_REG0_STS_DC_OK_MASK == (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
409 {
410 tmp32 |= (uint32_t)kDCDC_LockedOKStatus;
411 }
412
413 return tmp32;
414}
415
416#if !(defined(FSL_FEATURE_DCDC_HAS_NO_CURRENT_ALERT_FUNC) && FSL_FEATURE_DCDC_HAS_NO_CURRENT_ALERT_FUNC)
417/*!
418 * brief Reset current alert signal. Alert signal is generate by peak current detection.
419 *
420 * param base DCDC peripheral base address.
421 * param enable Switcher to reset signal. True means reset signal. False means don't reset signal.
422 */
423void DCDC_ResetCurrentAlertSignal(DCDC_Type *base, bool enable)
424{
425 if (enable)
426 {
427 base->REG0 |= DCDC_REG0_CURRENT_ALERT_RESET_MASK;
428 }
429 else
430 {
431 base->REG0 &= ~DCDC_REG0_CURRENT_ALERT_RESET_MASK;
432 }
433}
434#endif /* FSL_FEATURE_DCDC_HAS_NO_CURRENT_ALERT_FUNC */
435
436/*!
437 * brief Get the default setting for loop control configuration.
438 *
439 * The default configuration are set according to responding registers' setting when powered on.
440 * They are:
441 * code
442 * config->enableCommonHysteresis = false;
443 * config->enableCommonThresholdDetection = false;
444 * config->enableInvertHysteresisSign = false;
445 * config->enableRCThresholdDetection = false;
446 * config->enableRCScaleCircuit = 0U;
447 * config->complementFeedForwardStep = 0U;
448 * endcode
449 *
450 * param config Pointer to configuration structure. See to "dcdc_loop_control_config_t"
451 */
452void DCDC_GetDefaultLoopControlConfig(dcdc_loop_control_config_t *config)
453{
454 assert(NULL != config);
455
456 /* Initializes the configure structure to zero. */
457 (void)memset(config, 0, sizeof(*config));
458
459 config->enableCommonHysteresis = false;
460 config->enableCommonThresholdDetection = false;
461 config->enableInvertHysteresisSign = false;
462 config->enableRCThresholdDetection = false;
463 config->enableRCScaleCircuit = 0U;
464 config->complementFeedForwardStep = 0U;
465}
466
467/*!
468 * brief Configure the DCDC loop control.
469 *
470 * param base DCDC peripheral base address.
471 * param config Pointer to configuration structure. See to "dcdc_loop_control_config_t".
472 */
473void DCDC_SetLoopControlConfig(DCDC_Type *base, const dcdc_loop_control_config_t *config)
474{
475 assert(NULL != config);
476
477 uint32_t tmp32;
478
479 /* Configure the DCDC_REG1 register. */
480#if defined(FSL_FEATURE_DCDC_HAS_SWITCHING_CONVERTER_DIFFERENTIAL_MODE) && \
481 FSL_FEATURE_DCDC_HAS_SWITCHING_CONVERTER_DIFFERENTIAL_MODE
482 tmp32 = base->REG1 & ~(DCDC_REG1_LOOPCTRL_EN_DF_HYST_MASK | DCDC_REG1_LOOPCTRL_EN_CM_HYST_MASK |
483 DCDC_REG1_LOOPCTRL_DF_HST_THRESH_MASK | DCDC_REG1_LOOPCTRL_CM_HST_THRESH_MASK);
484 if (config->enableCommonHysteresis)
485 {
486 tmp32 |= DCDC_REG1_LOOPCTRL_EN_CM_HYST_MASK;
487 }
488 if (config->enableCommonThresholdDetection)
489 {
490 tmp32 |= DCDC_REG1_LOOPCTRL_CM_HST_THRESH_MASK;
491 }
492 if (config->enableDifferentialHysteresis)
493 {
494 tmp32 |= DCDC_REG1_LOOPCTRL_EN_DF_HYST_MASK;
495 }
496 if (config->enableDifferentialThresholdDetection)
497 {
498 tmp32 |= DCDC_REG1_LOOPCTRL_DF_HST_THRESH_MASK;
499 }
500#else
501 tmp32 = base->REG1 & ~(DCDC_REG1_LOOPCTRL_EN_HYST_MASK | DCDC_REG1_LOOPCTRL_HST_THRESH_MASK);
502 if (config->enableCommonHysteresis)
503 {
504 tmp32 |= DCDC_REG1_LOOPCTRL_EN_HYST_MASK;
505 }
506 if (config->enableCommonThresholdDetection)
507 {
508 tmp32 |= DCDC_REG1_LOOPCTRL_HST_THRESH_MASK;
509 }
510#endif /* FSL_FEATURE_DCDC_HAS_SWITCHING_CONVERTER_DIFFERENTIAL_MODE */
511 base->REG1 = tmp32;
512
513 /* configure the DCDC_REG2 register. */
514 tmp32 = base->REG2 & ~(DCDC_REG2_LOOPCTRL_HYST_SIGN_MASK | DCDC_REG2_LOOPCTRL_RCSCALE_THRSH_MASK |
515 DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK | DCDC_REG2_LOOPCTRL_DC_FF_MASK);
516 tmp32 |= DCDC_REG2_LOOPCTRL_DC_FF(config->complementFeedForwardStep) |
517 DCDC_REG2_LOOPCTRL_EN_RCSCALE(config->enableRCScaleCircuit);
518 if (config->enableInvertHysteresisSign)
519 {
520 tmp32 |= DCDC_REG2_LOOPCTRL_HYST_SIGN_MASK;
521 }
522 if (config->enableRCThresholdDetection)
523 {
524 tmp32 |= DCDC_REG2_LOOPCTRL_RCSCALE_THRSH_MASK;
525 }
526 base->REG2 = tmp32;
527}
528
529/*!
530 * brief Configure for the min power.
531 *
532 * param base DCDC peripheral base address.
533 * param config Pointer to configuration structure. See to "dcdc_min_power_config_t".
534 */
535void DCDC_SetMinPowerConfig(DCDC_Type *base, const dcdc_min_power_config_t *config)
536{
537 assert(NULL != config);
538
539 uint32_t tmp32;
540
541 tmp32 = base->REG3 & ~DCDC_REG3_MINPWR_DC_HALFCLK_MASK;
542 if (config->enableUseHalfFreqForContinuous)
543 {
544 tmp32 |= DCDC_REG3_MINPWR_DC_HALFCLK_MASK;
545 }
546 base->REG3 = tmp32;
547}
548
549#if (defined(FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT) && (FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT == 2))
550/*!
551 * brief Adjust the target voltage of VDD_SOC in run mode and low power mode.
552 * Do not use this function. It has been superceded by DCDC_AdjustRunTargetVoltage
553 * and DCDC_AdjustLowPowerTargetVoltage.
554 *
555 * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
556 * stabled.
557 * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
558 * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
559 *
560 * param base DCDC peripheral base address.
561 * param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V.
562 * param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V.
563 * param sel sel DCDC target voltage output selection. See to "_dcdc_voltage_output_sel".
564 */
565void DCDC_AdjustTargetVoltage(DCDC_Type *base, uint32_t VDDRun, uint32_t VDDStandby, dcdc_voltage_output_sel_t sel)
566{
567 uint32_t tmp32;
568
569 if (sel == kDCDC_VoltageOutput1P8)
570 {
571 /* Unlock the step for the VDD 1P8. */
572 base->REG3 &= ~DCDC_REG3_VDD1P8CTRL_DISABLE_STEP_MASK;
573
574 /* Configure the DCDC_CTRL1 register. */
575 tmp32 = base->CTRL1 & ~(DCDC_CTRL1_VDD1P8CTRL_STBY_TRG_MASK | DCDC_CTRL1_VDD1P8CTRL_TRG_MASK);
576
577 tmp32 |= DCDC_CTRL1_VDD1P8CTRL_STBY_TRG(VDDStandby) | DCDC_CTRL1_VDD1P8CTRL_TRG(VDDRun);
578 base->CTRL1 = tmp32;
579 }
580 else if (sel == kDCDC_VoltageOutput1P0)
581 {
582 /* Unlock the step for the VDD 1P0. */
583 base->REG3 &= ~DCDC_REG3_VDD1P0CTRL_DISABLE_STEP_MASK;
584
585 /* Configure the DCDC_CTRL1 register. */
586 tmp32 = base->CTRL1 & ~(DCDC_CTRL1_VDD1P0CTRL_STBY_TRG_MASK | DCDC_CTRL1_VDD1P0CTRL_TRG_MASK);
587
588 tmp32 |= DCDC_CTRL1_VDD1P0CTRL_STBY_TRG(VDDStandby) | DCDC_CTRL1_VDD1P0CTRL_TRG(VDDRun);
589 base->CTRL1 = tmp32;
590 }
591 else
592 {
593 ; /* Intentional empty */
594 }
595
596 /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage is set to new
597 * target value, DCDC_STS_DC_OK will be asserted. */
598 while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
599 {
600 }
601}
602
603/*!
604 * brief Adjust the target voltage of VDD_SOC in run mode.
605 *
606 * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
607 * stabled.
608 * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
609 * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
610 *
611 * param base DCDC peripheral base address.
612 * param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V.
613 * param sel sel DCDC target voltage output selection. See to "_dcdc_voltage_output_sel".
614 */
615void DCDC_AdjustRunTargetVoltage(DCDC_Type *base, uint32_t VDDRun, dcdc_voltage_output_sel_t sel)
616{
617 uint32_t tmp32;
618
619 if (sel == kDCDC_VoltageOutput1P8)
620 {
621 /* Unlock the step for the VDD 1P8. */
622 base->REG3 &= ~DCDC_REG3_VDD1P8CTRL_DISABLE_STEP_MASK;
623
624 /* Configure the DCDC_CTRL1 register. */
625 tmp32 = base->CTRL1 & ~DCDC_CTRL1_VDD1P8CTRL_TRG_MASK;
626
627 tmp32 |= DCDC_CTRL1_VDD1P8CTRL_TRG(VDDRun);
628 base->CTRL1 = tmp32;
629 }
630 else if (sel == kDCDC_VoltageOutput1P0)
631 {
632 /* Unlock the step for the VDD 1P0. */
633 base->REG3 &= ~DCDC_REG3_VDD1P0CTRL_DISABLE_STEP_MASK;
634
635 /* Configure the DCDC_CTRL1 register. */
636 tmp32 = base->CTRL1 & ~DCDC_CTRL1_VDD1P0CTRL_TRG_MASK;
637
638 tmp32 |= DCDC_CTRL1_VDD1P0CTRL_TRG(VDDRun);
639 base->CTRL1 = tmp32;
640 }
641 else
642 {
643 ; /* Intentional empty */
644 }
645
646 /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage is set to new
647 * target value, DCDC_STS_DC_OK will be asserted. */
648 while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
649 {
650 }
651}
652
653/*!
654 * brief Adjust the target voltage of VDD_SOC in low power mode.
655 *
656 * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
657 * stabled.
658 * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
659 * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
660 *
661 * param base DCDC peripheral base address.
662 * param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V.
663 * param sel sel DCDC target voltage output selection. See to "_dcdc_voltage_output_sel".
664 */
665void DCDC_AdjustLowPowerTargetVoltage(DCDC_Type *base, uint32_t VDDStandby, dcdc_voltage_output_sel_t sel)
666{
667 uint32_t tmp32;
668
669 if (sel == kDCDC_VoltageOutput1P8)
670 {
671 /* Unlock the step for the VDD 1P8. */
672 base->REG3 &= ~DCDC_REG3_VDD1P8CTRL_DISABLE_STEP_MASK;
673
674 /* Configure the DCDC_CTRL1 register. */
675 tmp32 = base->CTRL1 & ~(DCDC_CTRL1_VDD1P8CTRL_STBY_TRG_MASK);
676
677 tmp32 |= DCDC_CTRL1_VDD1P8CTRL_STBY_TRG(VDDStandby);
678 base->CTRL1 = tmp32;
679 }
680 else if (sel == kDCDC_VoltageOutput1P0)
681 {
682 /* Unlock the step for the VDD 1P0. */
683 base->REG3 &= ~DCDC_REG3_VDD1P0CTRL_DISABLE_STEP_MASK;
684
685 /* Configure the DCDC_CTRL1 register. */
686 tmp32 = base->CTRL1 & ~(DCDC_CTRL1_VDD1P0CTRL_STBY_TRG_MASK);
687
688 tmp32 |= DCDC_CTRL1_VDD1P0CTRL_STBY_TRG(VDDStandby);
689 base->CTRL1 = tmp32;
690 }
691 else
692 {
693 ; /* Intentional empty */
694 }
695
696 /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage is set to new
697 * target value, DCDC_STS_DC_OK will be asserted. */
698 while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
699 {
700 }
701}
702#else
703
704/*!
705 * brief Adjust the target voltage of VDD_SOC in run mode and low power mode.
706 * Do not use this function. It has been superceded by DCDC_AdjustRunTargetVoltage
707 * and DCDC_AdjustLowPowerTargetVoltage
708 *
709 * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
710 * stabled.
711 * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
712 * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
713 *
714 * param base DCDC peripheral base address.
715 * param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V.
716 * param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V.
717 */
718void DCDC_AdjustTargetVoltage(DCDC_Type *base, uint32_t VDDRun, uint32_t VDDStandby)
719{
720 uint32_t tmp32;
721
722 /* Unlock the step for the output. */
723 base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK;
724
725 /* Configure the DCDC_REG3 register. */
726 tmp32 = base->REG3 & ~(DCDC_REG3_TARGET_LP_MASK | DCDC_REG3_TRG_MASK);
727
728 tmp32 |= DCDC_REG3_TARGET_LP(VDDStandby) | DCDC_REG3_TRG(VDDRun);
729 base->REG3 = tmp32;
730
731 /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage is set to new
732 * target value, DCDC_STS_DC_OK will be asserted. */
733 while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
734 {
735 }
736}
737
738/*!
739 * brief Adjust the target voltage of VDD_SOC in run mode.
740 *
741 * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
742 * stabled.
743 * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
744 * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
745 *
746 * param base DCDC peripheral base address.
747 * param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V.
748 */
749void DCDC_AdjustRunTargetVoltage(DCDC_Type *base, uint32_t VDDRun)
750{
751 uint32_t tmp32;
752
753 /* Unlock the step for the output. */
754 base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK;
755
756 /* Configure the DCDC_REG3 register. */
757 tmp32 = base->REG3 & ~DCDC_REG3_TRG_MASK;
758
759 tmp32 |= DCDC_REG3_TRG(VDDRun);
760 base->REG3 = tmp32;
761
762 /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage is set to new
763 * target value, DCDC_STS_DC_OK will be asserted. */
764 while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
765 {
766 }
767}
768
769/*!
770 * brief Adjust the target voltage of VDD_SOC in low power mode.
771 *
772 * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
773 * stabled.
774 * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
775 * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
776 *
777 * param base DCDC peripheral base address.
778 * param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V.
779 */
780void DCDC_AdjustLowPowerTargetVoltage(DCDC_Type *base, uint32_t VDDStandby)
781{
782 uint32_t tmp32;
783
784 /* Unlock the step for the output. */
785 base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK;
786
787 /* Configure the DCDC_REG3 register. */
788 tmp32 = base->REG3 & ~DCDC_REG3_TARGET_LP_MASK;
789
790 tmp32 |= DCDC_REG3_TARGET_LP(VDDStandby);
791 base->REG3 = tmp32;
792
793 /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage is set to new
794 * target value, DCDC_STS_DC_OK will be asserted. */
795 while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
796 {
797 }
798}
799#endif /* FSL_FEATURE_DCDC_VDD_OUTPUT_COUNT == 2 */
800
801/*!
802 * brief Configure the DCDC internal regulator.
803 *
804 * param base DCDC peripheral base address.
805 * param config Pointer to configuration structure. See to "dcdc_internal_regulator_config_t".
806 */
807void DCDC_SetInternalRegulatorConfig(DCDC_Type *base, const dcdc_internal_regulator_config_t *config)
808{
809 assert(NULL != config);
810
811 uint32_t tmp32;
812
813#if (defined(FSL_FEATURE_DCDC_HAS_REG3_FBK_SEL) && FSL_FEATURE_DCDC_HAS_REG3_FBK_SEL)
814 tmp32 = base->REG3 & ~DCDC_REG3_REG_FBK_SEL_MASK;
815 tmp32 |= DCDC_REG3_REG_FBK_SEL(config->feedbackPoint);
816 base->REG3 = tmp32;
817
818 tmp32 = base->REG1 & ~DCDC_REG1_REG_RLOAD_SW_MASK;
819#else
820 /* Configure the DCDC_REG1 register. */
821 tmp32 = base->REG1 & ~(DCDC_REG1_REG_FBK_SEL_MASK | DCDC_REG1_REG_RLOAD_SW_MASK);
822 tmp32 |= DCDC_REG1_REG_FBK_SEL(config->feedbackPoint);
823#endif /* FSL_FEATURE_DCDC_HAS_REG3_FBK_SEL */
824
825 if (config->enableLoadResistor)
826 {
827 tmp32 |= DCDC_REG1_REG_RLOAD_SW_MASK;
828 }
829 base->REG1 = tmp32;
830}
831
832#if (defined(DCDC_REG4_ENABLE_SP_MASK) && DCDC_REG4_ENABLE_SP_MASK)
833/*!
834 * brief Init DCDC module when the control mode selected as setpoint mode.
835 *
836 * note The function should be invoked in the initial step to config the
837 * DCDC via setpoint control mode.
838 *
839 * param base DCDC peripheral base address.
840 * param config The pointer to the structure @ref dcdc_setpoint_config_t.
841 */
842void DCDC_SetPointInit(DCDC_Type *base, const dcdc_setpoint_config_t *config)
843{
844 assert(config != NULL);
845
846 /* Enable DCDC Dig Logic. */
847 base->REG5 = config->enableDigLogicMap;
848
849 /* Set DCDC power mode. */
850 base->REG6 = config->lowpowerMap;
851 base->REG7 = config->standbyMap;
852 base->REG7P = config->standbyLowpowerMap;
853
854 /* Set target voltage of VDD1P8 in buck mode. */
855 base->REG8 = DCDC_ConvertByteArrayToWord(config->buckVDD1P8TargetVoltage);
856 base->REG9 = DCDC_ConvertByteArrayToWord(config->buckVDD1P8TargetVoltage + 4U);
857 base->REG10 = DCDC_ConvertByteArrayToWord(config->buckVDD1P8TargetVoltage + 8U);
858 base->REG11 = DCDC_ConvertByteArrayToWord(config->buckVDD1P8TargetVoltage + 12U);
859
860 /* Set target voltage of VDD1P0 in buck mode. */
861 base->REG12 = DCDC_ConvertByteArrayToWord(config->buckVDD1P0TargetVoltage);
862 base->REG13 = DCDC_ConvertByteArrayToWord(config->buckVDD1P0TargetVoltage + 4U);
863 base->REG14 = DCDC_ConvertByteArrayToWord(config->buckVDD1P0TargetVoltage + 8U);
864 base->REG15 = DCDC_ConvertByteArrayToWord(config->buckVDD1P0TargetVoltage + 12U);
865
866 /* Set target voltage of VDD1P8 in low power mode. */
867 base->REG16 = DCDC_ConvertByteArrayToWord(config->standbyVDD1P8TargetVoltage);
868 base->REG17 = DCDC_ConvertByteArrayToWord(config->standbyVDD1P8TargetVoltage + 4U);
869 base->REG18 = DCDC_ConvertByteArrayToWord(config->standbyVDD1P8TargetVoltage + 8U);
870 base->REG19 = DCDC_ConvertByteArrayToWord(config->standbyVDD1P8TargetVoltage + 12U);
871
872 /* Set target voltage of VDD1P0 in low power mode. */
873 base->REG20 = DCDC_ConvertByteArrayToWord(config->standbyVDD1P0TargetVoltage);
874 base->REG21 = DCDC_ConvertByteArrayToWord(config->standbyVDD1P0TargetVoltage + 4U);
875 base->REG22 = DCDC_ConvertByteArrayToWord(config->standbyVDD1P0TargetVoltage + 8U);
876 base->REG23 = DCDC_ConvertByteArrayToWord(config->standbyVDD1P0TargetVoltage + 12U);
877
878 /* Enable DCDC module. */
879 base->REG4 = config->enableDCDCMap;
880}
881#endif /* DCDC_REG4_ENABLE_SP_MASK */
882
883/*!
884 * brief Boot DCDC into DCM(discontinous conduction mode).
885 *
886 * pwd_zcd=0x0;
887 * pwd_cmp_offset=0x0;
888 * dcdc_loopctrl_en_rcscale= 0x5;
889 * DCM_set_ctrl=1'b1;
890 *
891 * param base DCDC peripheral base address.
892 */
893void DCDC_BootIntoDCM(DCDC_Type *base)
894{
895 base->REG0 &= ~(DCDC_REG0_PWD_ZCD_MASK | DCDC_REG0_PWD_CMP_OFFSET_MASK);
896 base->REG2 = (~DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK & base->REG2) | DCDC_REG2_LOOPCTRL_EN_RCSCALE(0x5U) |
897 DCDC_REG2_DCM_SET_CTRL_MASK;
898}
899
900/*!
901 * brief Boot DCDC into CCM(continous conduction mode).
902 *
903 * pwd_zcd=0x1;
904 * pwd_cmp_offset=0x0;
905 * dcdc_loopctrl_en_rcscale=0x3;
906 *
907 * param base DCDC peripheral base address.
908 */
909void DCDC_BootIntoCCM(DCDC_Type *base)
910{
911 base->REG0 = (~DCDC_REG0_PWD_CMP_OFFSET_MASK & base->REG0) | DCDC_REG0_PWD_ZCD_MASK;
912 base->REG2 = (~DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK & base->REG2) | DCDC_REG2_LOOPCTRL_EN_RCSCALE(0x3U);
913}
914