1 //*****************************************************************************
2 //
3 //! @file am_hal_pwrctrl.c
4 //!
5 //! @brief Functions for enabling and disabling power domains.
6 //!
7 //! @addtogroup pwrctrl3p Pwrctrl - Power Control
8 //! @ingroup apollo3p_hal
9 //! @{
10 //
11 //*****************************************************************************
12
13 //*****************************************************************************
14 //
15 // Copyright (c) 2024, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_3_2_0-dd5f40c14b of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47
48 #include <stdint.h>
49 #include <stdbool.h>
50 #include "am_mcu_apollo.h"
51
52 //*****************************************************************************
53 //
54 // Defines
55 //
56 //*****************************************************************************
57 //
58 //! Maximum number of checks to memory power status before declaring error.
59 //
60 #define AM_HAL_PWRCTRL_MAX_WAIT 20
61
62 //*****************************************************************************
63 //
64 // Globals
65 //
66 //*****************************************************************************
67 bool g_bSimobuckTrimsDone = false;
68
69 #ifdef AM_HAL_PWRCTRL_VDDF_BOOST_WA
70 bool g_bVddfTrimsDone = false;
71 #endif
72
73 //
74 //! Mask of HCPA Enables from the PWRCTRL->DEVPWRSTATUS register mapped to the
75 //! PWRCTRL->DEVPWREN register
76 //
77 #define HCPA_MASK ( \
78 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOS, PWRCTRL_DEVPWREN_PWRIOS_EN) | \
79 _VAL2FLD(PWRCTRL_DEVPWREN_PWRUART0, PWRCTRL_DEVPWREN_PWRUART0_EN) | \
80 _VAL2FLD(PWRCTRL_DEVPWREN_PWRUART1, PWRCTRL_DEVPWREN_PWRUART1_EN) | \
81 _VAL2FLD(PWRCTRL_DEVPWREN_PWRSCARD, PWRCTRL_DEVPWREN_PWRSCARD_EN))
82
83 //
84 //! Mask of HCPB Enables from the PWRCTRL->DEVPWRSTATUS register mapped to the
85 //! PWRCTRL->DEVPWREN register
86 //
87 #define HCPB_MASK ( \
88 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM0, PWRCTRL_DEVPWREN_PWRIOM0_EN) | \
89 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM1, PWRCTRL_DEVPWREN_PWRIOM1_EN) | \
90 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM2, PWRCTRL_DEVPWREN_PWRIOM2_EN))
91
92 //
93 //! Mask of HCPC Enables from the PWRCTRL->DEVPWRSTATUS register mapped to the
94 //! PWRCTRL->DEVPWREN register
95 //
96 #define HCPC_MASK ( \
97 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM3, PWRCTRL_DEVPWREN_PWRIOM3_EN) | \
98 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM4, PWRCTRL_DEVPWREN_PWRIOM4_EN) | \
99 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM5, PWRCTRL_DEVPWREN_PWRIOM5_EN))
100
101 //
102 //! Mask of MSPI Enables from the PWRCTRL->DEVPWRSTATUS register mapped to the
103 //! PWRCTRL->DEVPWREN register
104 //
105 #define MSPI_MASK ( \
106 _VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI0, PWRCTRL_DEVPWREN_PWRMSPI0_EN) | \
107 _VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI1, PWRCTRL_DEVPWREN_PWRMSPI1_EN) | \
108 _VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI2, PWRCTRL_DEVPWREN_PWRMSPI2_EN))
109
110 //
111 //! Define the peripheral control structure.
112 //
113 const struct
114 {
115 uint32_t ui32PeriphEnable;
116 uint32_t ui32PeriphStatus;
117 uint32_t ui32PeriphEvent;
118 }
119 am_hal_pwrctrl_peripheral_control[AM_HAL_PWRCTRL_PERIPH_MAX] =
120 {
121 {0, 0, 0}, // AM_HAL_PWRCTRL_PERIPH_NONE
122 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOS, PWRCTRL_DEVPWREN_PWRIOS_EN),
123 PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
124 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOS
125 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM0, PWRCTRL_DEVPWREN_PWRIOM0_EN),
126 PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
127 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM0
128 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM1, PWRCTRL_DEVPWREN_PWRIOM1_EN),
129 PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
130 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM1
131 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM2, PWRCTRL_DEVPWREN_PWRIOM2_EN),
132 PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
133 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM2
134 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM3, PWRCTRL_DEVPWREN_PWRIOM3_EN),
135 PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
136 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM3
137 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM4, PWRCTRL_DEVPWREN_PWRIOM4_EN),
138 PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
139 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM4
140 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM5, PWRCTRL_DEVPWREN_PWRIOM5_EN),
141 PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
142 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM5
143 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRUART0, PWRCTRL_DEVPWREN_PWRUART0_EN),
144 PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
145 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_UART0
146 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRUART1, PWRCTRL_DEVPWREN_PWRUART1_EN),
147 PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
148 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_UART1
149 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRADC, PWRCTRL_DEVPWREN_PWRADC_EN),
150 PWRCTRL_DEVPWRSTATUS_PWRADC_Msk,
151 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_ADCEVEN, PWRCTRL_DEVPWREVENTEN_ADCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_ADC
152 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRSCARD, PWRCTRL_DEVPWREN_PWRSCARD_EN),
153 PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
154 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_SCARD
155 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI0, PWRCTRL_DEVPWREN_PWRMSPI0_EN),
156 PWRCTRL_DEVPWRSTATUS_PWRMSPI_Msk,
157 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_MSPIEVEN, PWRCTRL_DEVPWREVENTEN_MSPIEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_MSPI0
158 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI1, PWRCTRL_DEVPWREN_PWRMSPI1_EN),
159 PWRCTRL_DEVPWRSTATUS_PWRMSPI_Msk,
160 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_MSPIEVEN, PWRCTRL_DEVPWREVENTEN_MSPIEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_MSPI1
161 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI2, PWRCTRL_DEVPWREN_PWRMSPI2_EN),
162 PWRCTRL_DEVPWRSTATUS_PWRMSPI_Msk,
163 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_MSPIEVEN, PWRCTRL_DEVPWREVENTEN_MSPIEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_MSPI2
164 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRPDM, PWRCTRL_DEVPWREN_PWRPDM_EN),
165 PWRCTRL_DEVPWRSTATUS_PWRPDM_Msk,
166 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_PDMEVEN, PWRCTRL_DEVPWREVENTEN_PDMEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_PDM
167 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRBLEL, PWRCTRL_DEVPWREN_PWRBLEL_EN),
168 PWRCTRL_DEVPWRSTATUS_BLEL_Msk,
169 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_BLELEVEN, PWRCTRL_DEVPWREVENTEN_BLELEVEN_EN)} // AM_HAL_PWRCTRL_PERIPH_BLEL
170 };
171
172 //
173 //! Define the memory control structure.
174 //
175 const struct
176 {
177 uint32_t ui32MemoryEnable;
178 uint32_t ui32MemoryStatus;
179 uint32_t ui32MemoryEvent;
180 uint32_t ui32MemoryMask;
181 uint32_t ui32StatusMask;
182 uint32_t ui32PwdSlpEnable;
183 }
184 am_hal_pwrctrl_memory_control[AM_HAL_PWRCTRL_MEM_MAX] =
185 {
186 {0, 0, 0, 0, 0, 0},
187 {AM_HAL_PWRCTRL_MEMEN_SRAM_8K_DTCM,
188 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_8K_DTCM,
189 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_8K_DTCM,
190 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
191 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
192 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_8K_DTCM},
193 {AM_HAL_PWRCTRL_MEMEN_SRAM_32K_DTCM,
194 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_32K_DTCM,
195 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_32K_DTCM,
196 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
197 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
198 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_32K_DTCM},
199 {AM_HAL_PWRCTRL_MEMEN_SRAM_64K_DTCM,
200 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_64K_DTCM,
201 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_64K_DTCM,
202 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
203 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
204 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_64K_DTCM},
205 {AM_HAL_PWRCTRL_MEMEN_SRAM_128K,
206 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_128K,
207 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_128K,
208 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
209 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
210 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_128K},
211 {AM_HAL_PWRCTRL_MEMEN_SRAM_192K,
212 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_192K,
213 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_192K,
214 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
215 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
216 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_192K},
217 {AM_HAL_PWRCTRL_MEMEN_SRAM_256K,
218 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K,
219 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_256K,
220 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
221 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
222 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_256K},
223 {AM_HAL_PWRCTRL_MEMEN_SRAM_320K,
224 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_320K,
225 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_320K,
226 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
227 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
228 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_320K},
229 {AM_HAL_PWRCTRL_MEMEN_SRAM_384K,
230 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_384K,
231 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_384K,
232 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
233 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
234 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_384K},
235 {AM_HAL_PWRCTRL_MEMEN_SRAM_448K,
236 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_448K,
237 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_448K,
238 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
239 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
240 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_448K},
241 {AM_HAL_PWRCTRL_MEMEN_SRAM_512K,
242 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_512K,
243 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_512K,
244 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
245 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
246 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_512K},
247 {AM_HAL_PWRCTRL_MEMEN_SRAM_576K,
248 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_576K,
249 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_576K,
250 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
251 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
252 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_576K},
253 {AM_HAL_PWRCTRL_MEMEN_SRAM_672K,
254 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_672K,
255 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_672K,
256 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
257 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
258 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_672K},
259 {AM_HAL_PWRCTRL_MEMEN_SRAM_768K,
260 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_768K,
261 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_768K,
262 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
263 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
264 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_768K},
265 {AM_HAL_PWRCTRL_MEMEN_FLASH_1M,
266 AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_1M,
267 AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_1M,
268 AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
269 AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
270 AM_HAL_PWRCTRL_MEMPWDINSLEEP_FLASH_1M},
271 {AM_HAL_PWRCTRL_MEMEN_FLASH_2M,
272 AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_2M,
273 AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_2M,
274 AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
275 AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
276 AM_HAL_PWRCTRL_MEMPWDINSLEEP_FLASH_2M},
277 {AM_HAL_PWRCTRL_MEMEN_CACHE,
278 0,
279 AM_HAL_PWRCTRL_MEMPWREVENTEN_CACHE,
280 AM_HAL_PWRCTRL_MEM_REGION_CACHE_MASK,
281 0,
282 AM_HAL_PWRCTRL_MEMPWDINSLEEP_CACHE},
283 {AM_HAL_PWRCTRL_MEMEN_ALL,
284 AM_HAL_PWRCTRL_PWRONSTATUS_ALL,
285 AM_HAL_PWRCTRL_MEMPWREVENTEN_ALL,
286 AM_HAL_PWRCTRL_MEM_REGION_ALL_MASK,
287 AM_HAL_PWRCTRL_MEM_REGION_ALT_ALL_MASK,
288 AM_HAL_PWRCTRL_MEMPWDINSLEEP_ALL}
289 };
290
291 // ****************************************************************************
292 //
293 // Enable power for a peripheral.
294 //
295 // ****************************************************************************
296 uint32_t
am_hal_pwrctrl_periph_enable(am_hal_pwrctrl_periph_e ePeripheral)297 am_hal_pwrctrl_periph_enable(am_hal_pwrctrl_periph_e ePeripheral)
298 {
299 //
300 // Enable power control for the given device.
301 //
302 AM_CRITICAL_BEGIN
303 PWRCTRL->DEVPWREN |= am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable;
304 AM_CRITICAL_END
305
306 for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WAIT; wait_usecs += 10)
307 {
308 am_hal_flash_delay(FLASH_CYCLES_US(10));
309
310 if ((PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) > 0)
311 {
312 break;
313 }
314 }
315
316 //
317 // Check the device status.
318 //
319 if ((PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) > 0)
320 {
321 return AM_HAL_STATUS_SUCCESS;
322 }
323 else
324 {
325 //
326 // If the Power Enable fails, make sure the DEVPWREN is Low
327 //
328 AM_CRITICAL_BEGIN
329 PWRCTRL->DEVPWREN &= ~am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable;
330 AM_CRITICAL_END
331
332 return AM_HAL_STATUS_FAIL;
333 }
334 } // am_hal_pwrctrl_periph_enable()
335
336 // ****************************************************************************
337 //
338 // Function checks the PWRCTRL->DEVPWREN since the PWRCTRL->DEVPWRSTATUS
339 // register alone cannot tell the user if a peripheral is enabled when
340 // and HCPx register is being used.
341 //
342 // ****************************************************************************
343 static uint32_t
pwrctrl_periph_disable_msk_check(am_hal_pwrctrl_periph_e ePeripheral)344 pwrctrl_periph_disable_msk_check(am_hal_pwrctrl_periph_e ePeripheral)
345 {
346 uint32_t retVal = AM_HAL_STATUS_FAIL;
347 uint32_t HCPxMSPIxMask = PWRCTRL->DEVPWREN;
348
349 switch (am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus)
350 {
351 case (PWRCTRL_DEVPWRSTATUS_HCPA_Msk):
352 if (((HCPxMSPIxMask & HCPA_MASK) > 0) && ((HCPxMSPIxMask & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable) == 0))
353 {
354 retVal = AM_HAL_STATUS_SUCCESS;
355 }
356 break;
357
358 case (PWRCTRL_DEVPWRSTATUS_HCPB_Msk):
359 if (((HCPxMSPIxMask & HCPB_MASK) > 0) && ((HCPxMSPIxMask & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable) == 0))
360 {
361 retVal = AM_HAL_STATUS_SUCCESS;
362 }
363 break;
364
365 case (PWRCTRL_DEVPWRSTATUS_HCPC_Msk):
366 if (((HCPxMSPIxMask & HCPC_MASK) > 0) && ((HCPxMSPIxMask & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable) == 0))
367 {
368 retVal = AM_HAL_STATUS_SUCCESS;
369 }
370 break;
371
372 case (PWRCTRL_DEVPWRSTATUS_PWRMSPI_Msk):
373 if (((HCPxMSPIxMask & MSPI_MASK) > 0) && ((HCPxMSPIxMask & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable) == 0))
374 {
375 retVal = AM_HAL_STATUS_SUCCESS;
376 }
377 break;
378
379 default:
380 break;
381 }
382
383 return retVal;
384 }
385
386 // ****************************************************************************
387 //
388 // Disable power for a peripheral.
389 //
390 // ****************************************************************************
391 uint32_t
am_hal_pwrctrl_periph_disable(am_hal_pwrctrl_periph_e ePeripheral)392 am_hal_pwrctrl_periph_disable(am_hal_pwrctrl_periph_e ePeripheral)
393 {
394 //
395 // Disable power domain for the given device.
396 //
397 AM_CRITICAL_BEGIN
398 PWRCTRL->DEVPWREN &= ~am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable;
399 AM_CRITICAL_END
400
401 for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WAIT; wait_usecs += 10)
402 {
403 am_hal_flash_delay(FLASH_CYCLES_US(10));
404
405 if ((PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) == 0)
406 {
407 break;
408 }
409 }
410
411 //
412 // Check the device status.
413 //
414 if ((PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) == 0)
415 {
416 return AM_HAL_STATUS_SUCCESS;
417 }
418 else
419 {
420 return pwrctrl_periph_disable_msk_check(ePeripheral);
421 }
422
423 } // am_hal_pwrctrl_periph_disable()
424
425 //*****************************************************************************
426 //
427 // This function determines to the caller whether a given peripheral is
428 // currently enabled or disabled.
429 //
430 //*****************************************************************************
431 uint32_t
am_hal_pwrctrl_periph_enabled(am_hal_pwrctrl_periph_e ePeripheral,uint32_t * pui32Enabled)432 am_hal_pwrctrl_periph_enabled(am_hal_pwrctrl_periph_e ePeripheral,
433 uint32_t *pui32Enabled)
434 {
435 uint32_t ui32Mask = am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus;
436 uint32_t ui32Enabled = 0;
437
438 if (pui32Enabled == NULL)
439 {
440 return AM_HAL_STATUS_INVALID_ARG;
441 }
442
443 if (ui32Mask != 0)
444 {
445 ui32Enabled = PWRCTRL->DEVPWRSTATUS & ui32Mask ? 1 : 0;
446 ui32Enabled = ui32Enabled && (PWRCTRL->DEVPWREN & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable);
447 }
448
449 *pui32Enabled = ui32Enabled;
450
451 return AM_HAL_STATUS_SUCCESS;
452
453 } // am_hal_pwrctrl_periph_enabled()
454
455 // ****************************************************************************
456 //
457 // Enable a configuration of memory.
458 //
459 // ****************************************************************************
460 uint32_t
am_hal_pwrctrl_memory_enable(am_hal_pwrctrl_mem_e eMemConfig)461 am_hal_pwrctrl_memory_enable(am_hal_pwrctrl_mem_e eMemConfig)
462 {
463 uint32_t ui32MemEnMask, ui32MemDisMask, ui32MemRegionMask, ui32MemStatusMask;
464
465 ui32MemEnMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryEnable;
466 ui32MemDisMask = ~am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryEnable;
467 ui32MemRegionMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryMask;
468 ui32MemStatusMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32StatusMask;
469
470 //
471 // Disable unneeded memory. If nothing to be disabled, skip to save time.
472 //
473 // Note that a deliberate disable step using a disable mask is taken here
474 // for 2 reasons: 1) To only affect the specified type of memory, and 2)
475 // To avoid inadvertently disabling any memory currently being depended on.
476 //
477 if ( ui32MemDisMask != 0 )
478 {
479 PWRCTRL->MEMPWREN &=
480 ~(ui32MemDisMask & ui32MemRegionMask) |
481 (_VAL2FLD(PWRCTRL_MEMPWREN_DTCM, PWRCTRL_MEMPWREN_DTCM_GROUP0DTCM0) |
482 _VAL2FLD(PWRCTRL_MEMPWREN_FLASH0, PWRCTRL_MEMPWREN_FLASH0_EN));
483 am_hal_flash_delay(FLASH_CYCLES_US(1));
484 }
485
486 //
487 // Enable the required memory.
488 //
489 if ( ui32MemEnMask != 0 )
490 {
491 PWRCTRL->MEMPWREN |= ui32MemEnMask;
492
493 for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WAIT; wait_usecs += 10)
494 {
495 am_hal_flash_delay(FLASH_CYCLES_US(10));
496
497 if ( (PWRCTRL->MEMPWRSTATUS & ui32MemStatusMask) ==
498 am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryStatus )
499 {
500 break;
501 }
502 }
503 }
504
505 //
506 // Return status based on whether the power control memory status has reached the desired state.
507 //
508 if ( ( PWRCTRL->MEMPWRSTATUS & ui32MemStatusMask) ==
509 am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryStatus )
510 {
511 return AM_HAL_STATUS_SUCCESS;
512 }
513 else
514 {
515 return AM_HAL_STATUS_FAIL;
516 }
517
518 } // am_hal_pwrctrl_memory_enable()
519
520 // ****************************************************************************
521 //
522 // Power down respective memory.
523 //
524 // ****************************************************************************
525 uint32_t
am_hal_pwrctrl_memory_deepsleep_powerdown(am_hal_pwrctrl_mem_e eMemConfig)526 am_hal_pwrctrl_memory_deepsleep_powerdown(am_hal_pwrctrl_mem_e eMemConfig)
527 {
528 if ( eMemConfig >= AM_HAL_PWRCTRL_MEM_MAX )
529 {
530 return AM_HAL_STATUS_FAIL;
531 }
532
533 //
534 // Power down the required memory.
535 //
536 PWRCTRL->MEMPWDINSLEEP |= am_hal_pwrctrl_memory_control[eMemConfig].ui32PwdSlpEnable;
537
538 return AM_HAL_STATUS_SUCCESS;
539
540 } // am_hal_pwrctrl_memory_deepsleep_powerdown()
541
542 // ****************************************************************************
543 //
544 // Apply retention voltage to respective memory.
545 //
546 // ****************************************************************************
547 uint32_t
am_hal_pwrctrl_memory_deepsleep_retain(am_hal_pwrctrl_mem_e eMemConfig)548 am_hal_pwrctrl_memory_deepsleep_retain(am_hal_pwrctrl_mem_e eMemConfig)
549 {
550 if ( eMemConfig >= AM_HAL_PWRCTRL_MEM_MAX )
551 {
552 return AM_HAL_STATUS_FAIL;
553 }
554
555 //
556 // Retain the required memory.
557 //
558 PWRCTRL->MEMPWDINSLEEP &= ~am_hal_pwrctrl_memory_control[eMemConfig].ui32PwdSlpEnable;
559
560 return AM_HAL_STATUS_SUCCESS;
561
562 } // am_hal_pwrctrl_memory_deepsleep_retain()
563
564
565 #ifdef AM_HAL_PWRCTRL_VDDF_BOOST_WA
566 //****************************************************************************
567 //
568 // simobuck_memldo_patch_check()
569 //
570 //****************************************************************************
571 #define AM_REG_INFO1_PATCHVER6_ADDR 0x50023838
572 #define AM_REG_INFO1_TRIM22_ADDR 0x5002386C
573 #define AM_REG_INFO1_TRIM28_ADDR 0x50023870
574
575 #define TRIM22_MEMLDOACTIVETRIM_Msk 0x0000003F
576 #define TRIM22_MEMLDOACTIVETRIM_Pos 0
577 #define TRIM28_MEMACTIVETRIM_Msk 0x003F0000
578 #define TRIM28_MEMACTIVETRIM_Pos 16
579
580 static bool
simobuck_memldo_patch_check(void)581 simobuck_memldo_patch_check(void)
582 {
583 //
584 // patch checker bit3 for CV patch
585 //
586 return (AM_REGVAL(AM_REG_INFO1_PATCHVER6_ADDR) & (1 << 3)) ? false : true;
587 } // simobuck_memldo_patch_check
588
589 //****************************************************************************
590 //
591 // Apply VDDF boost of +30mV on SIMOBUCK and MEMLDO Active Trim
592 //
593 //****************************************************************************
594 void
am_hal_pwrctrl_bleif_workaround(void)595 am_hal_pwrctrl_bleif_workaround(void)
596 {
597 uint32_t ui32RegBackupVal;
598 uint32_t ui32TrimVal;
599 //
600 // If patch is not applied, use current values for boost.
601 //
602 if (!simobuck_memldo_patch_check())
603 {
604 //
605 // Apply boost based on original values in
606 // MCUCTRL->SIMOBUCK1 (for simobuck)
607 // MCUCTRL->LDOREG2 (for MEMLDO)
608 //
609
610 //
611 // increase VDDF (LDOREG2_MEMLDOACTIVETRIM) by 3 counts
612 //
613 ui32RegBackupVal = MCUCTRL->LDOREG2;
614
615 ui32TrimVal = _FLD2VAL(MCUCTRL_LDOREG2_MEMLDOACTIVETRIM, ui32RegBackupVal);
616
617 //
618 // increase VDDF by ui32TrimVal counts
619 //
620 ui32TrimVal += 3;
621
622 //
623 // check for overflow and limit
624 //
625 ui32TrimVal = ui32TrimVal > ( MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Msk >> MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Pos ) ? ( MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Msk >> MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Pos ) : ui32TrimVal;
626
627 //
628 // Put boosted value back.
629 //
630 MCUCTRL->LDOREG2 &= ~MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Msk;
631 MCUCTRL->LDOREG2 |= _VAL2FLD(MCUCTRL_LDOREG2_MEMLDOACTIVETRIM, ui32TrimVal);
632
633 //
634 // increase VDDF (SIMOBUCK1_MEMACTIVETRIM) by 5 counts
635 //
636 ui32RegBackupVal = MCUCTRL->SIMOBUCK1;
637
638 ui32TrimVal = _FLD2VAL(MCUCTRL_SIMOBUCK1_MEMACTIVETRIM, ui32RegBackupVal);
639
640 //
641 // increase VDDF by ui32TrimVal counts
642 //
643 ui32TrimVal += 5;
644
645 //
646 // check for overflow and limit
647 //
648 ui32TrimVal = ui32TrimVal > ( MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Pos ) ? ( MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Pos ) : ui32TrimVal;
649
650 //
651 // Put boosted value back.
652 //
653 MCUCTRL->SIMOBUCK1 &= ~MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Msk;
654 MCUCTRL->SIMOBUCK1 |= _VAL2FLD(MCUCTRL_SIMOBUCK1_MEMACTIVETRIM, ui32TrimVal);
655 }
656 else
657 {
658 //
659 // Apply boost based on memldo and simobuck_mem_active trims
660 // AM_REG_INFO1_TRIM28_ADDR & TRIM28_MEMACTIVETRIM_Msk (for simobuck)
661 // AM_REG_INFO1_TRIM22_ADDR & TRIM22_MEMLDOACTIVETRIM_Msk (for MEMLDO)
662 //
663
664 //
665 // increase VDDF (MEMLDO) by 3 counts
666 //
667 ui32RegBackupVal = AM_REGVAL(AM_REG_INFO1_TRIM22_ADDR);
668
669 ui32TrimVal = _FLD2VAL(TRIM22_MEMLDOACTIVETRIM, ui32RegBackupVal);
670
671 //
672 // increase VDDF by ui32TrimVal counts
673 //
674 ui32TrimVal += 3;
675
676 //
677 // check for overflow and limit
678 //
679 ui32TrimVal = ui32TrimVal > (TRIM22_MEMLDOACTIVETRIM_Msk >> TRIM22_MEMLDOACTIVETRIM_Pos) ? (TRIM22_MEMLDOACTIVETRIM_Msk >> TRIM22_MEMLDOACTIVETRIM_Pos) : ui32TrimVal;
680
681 //
682 // Put boosted value back.
683 //
684 MCUCTRL->LDOREG2 &= ~TRIM22_MEMLDOACTIVETRIM_Msk;
685 MCUCTRL->LDOREG2 |= _VAL2FLD(TRIM22_MEMLDOACTIVETRIM, ui32TrimVal);
686
687 //
688 // increase VDDF (SIMOBUCK MEM) by 5 counts
689 //
690 ui32RegBackupVal = AM_REGVAL(AM_REG_INFO1_TRIM28_ADDR);
691
692 ui32TrimVal = _FLD2VAL(TRIM28_MEMACTIVETRIM, ui32RegBackupVal);
693
694 //
695 // increase VDDF by ui32TrimVal counts
696 //
697 ui32TrimVal += 5;
698
699 //
700 // check for overflow and limit
701 //
702 ui32TrimVal = ui32TrimVal > ( TRIM28_MEMACTIVETRIM_Msk >> TRIM28_MEMACTIVETRIM_Pos ) ? ( TRIM28_MEMACTIVETRIM_Msk >> TRIM28_MEMACTIVETRIM_Pos ) : ui32TrimVal;
703
704 //
705 // Put boosted value back.
706 //
707 MCUCTRL->SIMOBUCK1 &= ~TRIM28_MEMACTIVETRIM_Msk;
708 MCUCTRL->SIMOBUCK1 |= _VAL2FLD(TRIM28_MEMACTIVETRIM, ui32TrimVal);
709 }
710 } //am_hal_pwrctrl_bleif_workaround
711
712 #endif //#ifdef AM_HAL_PWRCTRL_VDDF_BOOST_WA
713
714 // ****************************************************************************
715 //
716 // Updates to the SIMOBUCK Trims
717 //
718 // ****************************************************************************
719 static void
simobuck_updates(void)720 simobuck_updates(void)
721 {
722 //
723 // Adjust the SIMOBUCK LP settings.
724 //
725 if ( APOLLO3_GE_B0 )
726 {
727 if ( !g_bSimobuckTrimsDone )
728 {
729 uint32_t ui32LPTRIM;
730 g_bSimobuckTrimsDone = true;
731
732 //
733 // Update SIMOBUCK MEM LP TRIM 12 codes ~ -37mV
734 //
735 ui32LPTRIM = MCUCTRL->SIMOBUCK1_b.SIMOBUCKMEMLPTRIM;
736 ui32LPTRIM = ui32LPTRIM > 12 ? ui32LPTRIM - 12 : 0;
737 MCUCTRL->SIMOBUCK1_b.SIMOBUCKMEMLPTRIM = ui32LPTRIM;
738
739 //
740 // Update SIMOBUCK CORE LP TRIM 13 codes ~ -40mV
741 //
742 ui32LPTRIM = MCUCTRL->SIMOBUCK1_b.SIMOBUCKCORELPTRIM;
743 ui32LPTRIM = ui32LPTRIM > 13 ? ui32LPTRIM - 13 : 0;
744 MCUCTRL->SIMOBUCK1_b.SIMOBUCKCORELPTRIM = ui32LPTRIM;
745
746 MCUCTRL->SIMOBUCK2_b.SIMOBUCKCORELPLOWTONTRIM = 8;
747 MCUCTRL->SIMOBUCK2_b.SIMOBUCKCORELPHIGHTONTRIM = 5;
748 MCUCTRL->SIMOBUCK4_b.SIMOBUCKMEMLPLOWTONTRIM = 8;
749 MCUCTRL->SIMOBUCK3_b.SIMOBUCKMEMLPHIGHTONTRIM = 6;
750 MCUCTRL->SIMOBUCK4_b.SIMOBUCKCOMP2LPEN = 1;
751 MCUCTRL->SIMOBUCK4_b.SIMOBUCKCOMP2TIMEOUTEN = 0;
752 MCUCTRL->SIMOBUCK2_b.SIMOBUCKCORELEAKAGETRIM = 3;
753 MCUCTRL->SIMOBUCK2_b.SIMOBUCKTONGENTRIM = 31;
754 }
755
756 #ifdef AM_HAL_PWRCTRL_VDDF_BOOST_WA
757 //
758 // Increase VDDF voltage by +30mV for both mem simobuck and ldo
759 //
760 if ( !g_bVddfTrimsDone )
761 {
762 g_bVddfTrimsDone = true;
763
764 //
765 // Perform boost of vddf by +30mV
766 //
767 am_hal_pwrctrl_bleif_workaround();
768 }
769 #endif //#ifdef AM_HAL_PWRCTRL_VDDF_BOOST_WA
770 }
771
772 //
773 // Adjust the SIMOBUCK Timeout settings.
774 //
775 if ( APOLLO3_GE_A1 )
776 {
777 MCUCTRL->SIMOBUCK4_b.SIMOBUCKCOMP2TIMEOUTEN = 0;
778 }
779 } // simobuck_updates()
780
781 // ****************************************************************************
782 //
783 // am_hal_pwrctrl_low_power_init()
784 // Initialize system for low power configuration.
785 //
786 // ****************************************************************************
787 uint32_t
am_hal_pwrctrl_low_power_init(void)788 am_hal_pwrctrl_low_power_init(void)
789 {
790 uint32_t ui32Status;
791
792 //
793 // Take a snapshot of the reset status, if not done already
794 //
795 if ( !gAmHalResetStatus )
796 {
797 gAmHalResetStatus = RSTGEN->STAT;
798 }
799
800 //
801 // Adjust the SIMOBUCK LP settings.
802 //
803 simobuck_updates();
804
805 //
806 // Configure cache for low power and performance.
807 //
808 am_hal_cachectrl_control(AM_HAL_CACHECTRL_CONTROL_LPMMODE_RECOMMENDED, 0);
809
810 //
811 // Check if the BLE is already enabled.
812 //
813 if ( PWRCTRL->DEVPWRSTATUS_b.BLEL == 0)
814 {
815 am_hal_pwrctrl_blebuck_trim();
816
817 //
818 // First request the BLE feature and check that it was available and acknowledged.
819 //
820 MCUCTRL->FEATUREENABLE_b.BLEREQ = 1;
821 ui32Status = am_hal_flash_delay_status_check(10000,
822 (uint32_t)&MCUCTRL->FEATUREENABLE,
823 (MCUCTRL_FEATUREENABLE_BLEAVAIL_Msk |
824 MCUCTRL_FEATUREENABLE_BLEACK_Msk |
825 MCUCTRL_FEATUREENABLE_BLEREQ_Msk),
826 (MCUCTRL_FEATUREENABLE_BLEAVAIL_Msk |
827 MCUCTRL_FEATUREENABLE_BLEACK_Msk |
828 MCUCTRL_FEATUREENABLE_BLEREQ_Msk),
829 true);
830
831 if (AM_HAL_STATUS_SUCCESS != ui32Status)
832 {
833 return AM_HAL_STATUS_TIMEOUT;
834 }
835
836 //
837 // Next, enable the BLE Buck.
838 //
839 PWRCTRL->SUPPLYSRC |= _VAL2FLD(PWRCTRL_SUPPLYSRC_BLEBUCKEN,
840 PWRCTRL_SUPPLYSRC_BLEBUCKEN_EN);
841
842 //
843 // Allow the buck to go to low power mode in BLE sleep.
844 //
845 PWRCTRL->MISC |= _VAL2FLD(PWRCTRL_MISC_MEMVRLPBLE,
846 PWRCTRL_MISC_MEMVRLPBLE_EN);
847 }
848
849 #if AM_HAL_BURST_LDO_WORKAROUND
850 //
851 // This is to charge the capacitor
852 //
853 am_hal_burst_ldo_charge();
854 #endif
855
856 return AM_HAL_STATUS_SUCCESS;
857 } // am_hal_pwrctrl_low_power_init()
858
859 // ****************************************************************************
860 //
861 // am_hal_pwrctrl_blebuck_trim()
862 //
863 // ****************************************************************************
864 void
am_hal_pwrctrl_blebuck_trim(void)865 am_hal_pwrctrl_blebuck_trim(void)
866 {
867 //
868 // Enable the BLE buck trim values
869 //
870 if ( APOLLO3_GE_A1 )
871 {
872 AM_CRITICAL_BEGIN
873 MCUCTRL->BLEBUCK2_b.BLEBUCKTONHITRIM = 0x19;
874 MCUCTRL->BLEBUCK2_b.BLEBUCKTONLOWTRIM = 0xC;
875 CLKGEN->BLEBUCKTONADJ_b.TONADJUSTEN = CLKGEN_BLEBUCKTONADJ_TONADJUSTEN_DIS;
876 AM_CRITICAL_END
877 }
878 } // am_hal_pwrctrl_blebuck_trim()
879
880 #if AM_HAL_BURST_LDO_WORKAROUND
881
882 #if 0
883 //****************************************************************************
884 //
885 // Get the simobuck vddc/vddf active trim value with saturation.
886 // Based on current register setting
887 //
888 //****************************************************************************
889 static uint32_t
890 simobuck_vddx_active_trim_get(am_hal_burst_voltage_wa_e vddx)
891 {
892 if (vddx == AM_HAL_BURST_VDDC)
893 {
894 return MCUCTRL->SIMOBUCK1_b.COREACTIVETRIM;
895 }
896 else if (vddx == AM_HAL_BURST_VDDF)
897 {
898 return MCUCTRL->SIMOBUCK1_b.MEMACTIVETRIM;
899 }
900
901 return 0;
902 }
903 #endif
904
905 //****************************************************************************
906 //
907 // Get the simobuck vddc/vddf default trim value with saturation.
908 // Based on current register setting
909 //
910 //****************************************************************************
911 static uint32_t
simobuck_vddx_default_trim_get(am_hal_burst_voltage_wa_e vddx)912 simobuck_vddx_default_trim_get(am_hal_burst_voltage_wa_e vddx)
913 {
914 if (am_hal_burst_ldo_patch_check())
915 {
916 if (vddx == AM_HAL_BURST_VDDC)
917 {
918 return (AM_REGVAL(0x50023870) & 0x3FF);
919 }
920 else if (vddx == AM_HAL_BURST_VDDF)
921 {
922 return ((AM_REGVAL(0x50023870) >> 16) & 0x3F);
923 }
924 }
925
926 return 0;
927 }
928
929 #if 0
930 //****************************************************************************
931 //
932 // Get the LDO vddc/vddf active trim value with saturation.
933 // Based on current register setting
934 //
935 //****************************************************************************
936 static uint32_t
937 ldo_vddx_active_trim_get(am_hal_burst_voltage_wa_e vddx)
938 {
939 if (vddx == AM_HAL_BURST_VDDC)
940 {
941 return MCUCTRL->LDOREG1_b.CORELDOACTIVETRIM;
942 }
943 else if (vddx == AM_HAL_BURST_VDDF)
944 {
945 return MCUCTRL->LDOREG2_b.MEMLDOACTIVETRIM;
946 }
947
948 return 0;
949 }
950 #endif
951
952 //****************************************************************************
953 //
954 // Get the LDO vddc/vddf default trim value with saturation.
955 // Based on current register setting
956 //
957 //****************************************************************************
958 static uint32_t
ldo_vddx_default_trim_get(am_hal_burst_voltage_wa_e vddx)959 ldo_vddx_default_trim_get(am_hal_burst_voltage_wa_e vddx)
960 {
961 if (am_hal_burst_ldo_patch_check())
962 {
963 if (vddx == AM_HAL_BURST_VDDC)
964 {
965 return (AM_REGVAL(0x50023868) & 0x3FF);
966 }
967 else if (vddx == AM_HAL_BURST_VDDF)
968 {
969 return (AM_REGVAL(0x5002386C) & 0x3F);
970 }
971 }
972
973 return 0;
974 }
975
976 //****************************************************************************
977 //
978 // Adjust the simobuck vddc/vddf active trim values with saturation.
979 // Based on current register setting
980 // Returns actual adjusted amount of trim code
981 //
982 //****************************************************************************
983 int32_t
am_hal_pwrctrl_simobuck_vddx_active_trim_adj(am_hal_burst_voltage_wa_e vddx,int32_t vddx_code)984 am_hal_pwrctrl_simobuck_vddx_active_trim_adj(am_hal_burst_voltage_wa_e vddx, int32_t vddx_code)
985 {
986 //
987 // save original SIMOBUCK1 value, it will be restored
988 //
989 int32_t i32ActualCode = 0;
990
991 AM_CRITICAL_BEGIN;
992 if (vddx == AM_HAL_BURST_VDDC)
993 {
994 int32_t i32Vddc = MCUCTRL->SIMOBUCK1_b.COREACTIVETRIM;
995 i32ActualCode = i32Vddc;
996 i32Vddc += vddx_code;
997
998 //
999 // check for overflow and limit
1000 //
1001 if (i32Vddc < 0)
1002 {
1003 i32Vddc = 0;
1004 }
1005 else if (i32Vddc > (MCUCTRL_SIMOBUCK1_COREACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_COREACTIVETRIM_Pos))
1006 {
1007 i32Vddc = (MCUCTRL_SIMOBUCK1_COREACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_COREACTIVETRIM_Pos);
1008 }
1009
1010 i32ActualCode = i32Vddc - i32ActualCode;
1011 MCUCTRL->SIMOBUCK1_b.COREACTIVETRIM = i32Vddc;
1012 }
1013 else if (vddx == AM_HAL_BURST_VDDF)
1014 {
1015 int32_t i32Vddf = MCUCTRL->SIMOBUCK1_b.MEMACTIVETRIM;
1016 i32ActualCode = i32Vddf;
1017 i32Vddf += vddx_code;
1018
1019 //
1020 // check for overflow and limit
1021 //
1022 if (i32Vddf < 0)
1023 {
1024 i32Vddf = 0;
1025 }
1026 else if (i32Vddf > (MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Pos))
1027 {
1028 i32Vddf = (MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Pos);
1029 }
1030
1031 i32ActualCode = i32Vddf - i32ActualCode;
1032 MCUCTRL->SIMOBUCK1_b.MEMACTIVETRIM = i32Vddf;
1033 }
1034
1035 am_hal_flash_delay( FLASH_CYCLES_US(20) );
1036 AM_CRITICAL_END;
1037 return i32ActualCode;
1038 }
1039
1040 //****************************************************************************
1041 //
1042 // Adjust the LDO vddc/vddf active trim values with saturation.
1043 // Based on current register setting
1044 // Returns actual adjusted amount of trim code
1045 //
1046 //****************************************************************************
1047 int32_t
am_hal_pwrctrl_ldo_vddx_active_trim_adj(am_hal_burst_voltage_wa_e vddx,int32_t vddx_code)1048 am_hal_pwrctrl_ldo_vddx_active_trim_adj(am_hal_burst_voltage_wa_e vddx, int32_t vddx_code)
1049 {
1050 //
1051 // save original LDO value, it will be restored
1052 //
1053 int32_t i32ActualCode = 0;
1054
1055 AM_CRITICAL_BEGIN;
1056 if (vddx == AM_HAL_BURST_VDDC)
1057 {
1058 int32_t i32Vddc = MCUCTRL->LDOREG1_b.CORELDOACTIVETRIM;
1059 i32ActualCode = i32Vddc;
1060 i32Vddc += vddx_code;
1061
1062 //
1063 // check for overflow and limit
1064 //
1065 if (i32Vddc < 0)
1066 {
1067 i32Vddc = 0;
1068 }
1069 else if (i32Vddc > (MCUCTRL_LDOREG1_CORELDOACTIVETRIM_Msk >> MCUCTRL_LDOREG1_CORELDOACTIVETRIM_Pos))
1070 {
1071 i32Vddc = (MCUCTRL_LDOREG1_CORELDOACTIVETRIM_Msk >> MCUCTRL_LDOREG1_CORELDOACTIVETRIM_Pos);
1072 }
1073
1074 i32ActualCode = i32Vddc - i32ActualCode;
1075 MCUCTRL->LDOREG1_b.CORELDOACTIVETRIM = i32Vddc;
1076 }
1077 else if (vddx == AM_HAL_BURST_VDDF)
1078 {
1079 int32_t i32Vddf = MCUCTRL->LDOREG2_b.MEMLDOACTIVETRIM;
1080 i32ActualCode = i32Vddf;
1081 i32Vddf += vddx_code;
1082
1083 //
1084 // check for overflow and limit
1085 //
1086 if (i32Vddf < 0)
1087 {
1088 i32Vddf = 0;
1089 }
1090 else if (i32Vddf > (MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Msk >> MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Pos))
1091 {
1092 i32Vddf = (MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Msk >> MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Pos);
1093 }
1094
1095 i32ActualCode = i32Vddf - i32ActualCode;
1096 MCUCTRL->LDOREG2_b.MEMLDOACTIVETRIM = i32Vddf;
1097 }
1098
1099 am_hal_flash_delay( FLASH_CYCLES_US(20) );
1100 AM_CRITICAL_END;
1101 return i32ActualCode;
1102 }
1103
1104 //****************************************************************************
1105 //
1106 // Adjust the simobuck vddc/vddf active trim values with saturation.
1107 // Based on default trim setting
1108 // Returns actual adjusted amount of trim code
1109 // (Requires Info1 patch5)
1110 //
1111 //****************************************************************************
1112 int32_t
am_hal_pwrctrl_simobuck_vddx_active_trim_adj_default(am_hal_burst_voltage_wa_e vddx,int32_t vddx_code)1113 am_hal_pwrctrl_simobuck_vddx_active_trim_adj_default(am_hal_burst_voltage_wa_e vddx, int32_t vddx_code)
1114 {
1115 //
1116 // save original SIMOBUCK1 value, it will be restored
1117 //
1118 int32_t i32ActualCode = 0;
1119
1120 //
1121 // check if info1 patch5 is present
1122 //
1123 if (!am_hal_burst_ldo_patch_check())
1124 {
1125 return 0;
1126 }
1127
1128 AM_CRITICAL_BEGIN;
1129 if (vddx == AM_HAL_BURST_VDDC)
1130 {
1131 int32_t i32Vddc = simobuck_vddx_default_trim_get(AM_HAL_BURST_VDDC);
1132 i32ActualCode = i32Vddc;
1133 i32Vddc += vddx_code;
1134
1135 //
1136 // check for overflow and limit
1137 //
1138 if (i32Vddc < 0)
1139 {
1140 i32Vddc = 0;
1141 }
1142 else if (i32Vddc > (MCUCTRL_SIMOBUCK1_COREACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_COREACTIVETRIM_Pos))
1143 {
1144 i32Vddc = (MCUCTRL_SIMOBUCK1_COREACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_COREACTIVETRIM_Pos);
1145 }
1146
1147 i32ActualCode = i32Vddc - i32ActualCode;
1148 MCUCTRL->SIMOBUCK1_b.COREACTIVETRIM = i32Vddc;
1149 }
1150 else if (vddx == AM_HAL_BURST_VDDF)
1151 {
1152 int32_t i32Vddf = simobuck_vddx_default_trim_get(AM_HAL_BURST_VDDF);
1153 i32ActualCode = i32Vddf;
1154 i32Vddf += vddx_code;
1155
1156 //
1157 // check for overflow and limit
1158 //
1159 if (i32Vddf < 0)
1160 {
1161 i32Vddf = 0;
1162 }
1163 else if (i32Vddf > (MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Pos))
1164 {
1165 i32Vddf = (MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Msk >> MCUCTRL_SIMOBUCK1_MEMACTIVETRIM_Pos);
1166 }
1167
1168 i32ActualCode = i32Vddf - i32ActualCode;
1169 MCUCTRL->SIMOBUCK1_b.MEMACTIVETRIM = i32Vddf;
1170 }
1171
1172 am_hal_flash_delay( FLASH_CYCLES_US(20) );
1173 AM_CRITICAL_END;
1174 return i32ActualCode;
1175 }
1176
1177 //****************************************************************************
1178 //
1179 // Adjust the LDO vddc/vddf active trim values with saturation.
1180 // Based on default trim setting
1181 // (Requires Info1 patch5)
1182 // Returns actual adjusted amount of trim code
1183 //
1184 //****************************************************************************
1185 int32_t
am_hal_pwrctrl_ldo_vddx_active_trim_adj_default(am_hal_burst_voltage_wa_e vddx,int32_t vddx_code)1186 am_hal_pwrctrl_ldo_vddx_active_trim_adj_default(am_hal_burst_voltage_wa_e vddx, int32_t vddx_code)
1187 {
1188 //
1189 // save original LDO value, it will be restored
1190 //
1191 int32_t i32ActualCode = 0;
1192
1193 //
1194 // check if info1 patch5 is present
1195 //
1196 if (!am_hal_burst_ldo_patch_check())
1197 {
1198 return 0;
1199 }
1200
1201 AM_CRITICAL_BEGIN;
1202 if (vddx == AM_HAL_BURST_VDDC)
1203 {
1204 int32_t i32Vddc = ldo_vddx_default_trim_get(AM_HAL_BURST_VDDC);
1205 i32ActualCode = i32Vddc;
1206 i32Vddc += vddx_code;
1207
1208 //
1209 // check for overflow and limit
1210 //
1211 if (i32Vddc < 0)
1212 {
1213 i32Vddc = 0;
1214 }
1215 else if (i32Vddc > (MCUCTRL_LDOREG1_CORELDOACTIVETRIM_Msk >> MCUCTRL_LDOREG1_CORELDOACTIVETRIM_Pos))
1216 {
1217 i32Vddc = (MCUCTRL_LDOREG1_CORELDOACTIVETRIM_Msk >> MCUCTRL_LDOREG1_CORELDOACTIVETRIM_Pos);
1218 }
1219
1220 i32ActualCode = i32Vddc - i32ActualCode;
1221 MCUCTRL->LDOREG1_b.CORELDOACTIVETRIM = i32Vddc;
1222 }
1223 else if (vddx == AM_HAL_BURST_VDDF)
1224 {
1225 int32_t i32Vddf = ldo_vddx_default_trim_get(AM_HAL_BURST_VDDF);
1226 i32ActualCode = i32Vddf;
1227 i32Vddf += vddx_code;
1228
1229 //
1230 // check for overflow and limit
1231 //
1232 if (i32Vddf < 0)
1233 {
1234 i32Vddf = 0;
1235 }
1236 else if (i32Vddf > (MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Msk >> MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Pos))
1237 {
1238 i32Vddf = (MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Msk >> MCUCTRL_LDOREG2_MEMLDOACTIVETRIM_Pos);
1239 }
1240
1241 i32ActualCode = i32Vddf - i32ActualCode;
1242 MCUCTRL->LDOREG2_b.MEMLDOACTIVETRIM = i32Vddf;
1243 }
1244
1245 am_hal_flash_delay( FLASH_CYCLES_US(20) );
1246 AM_CRITICAL_END;
1247 return i32ActualCode;
1248 }
1249
1250 //****************************************************************************
1251 //
1252 // Boost VDDF if CV Patch applied
1253 //
1254 //****************************************************************************
1255 void
am_hal_pwrctrl_wa_vddf_boost(void)1256 am_hal_pwrctrl_wa_vddf_boost(void)
1257 {
1258 //
1259 // Boost VDDF value
1260 //
1261 AM_CRITICAL_BEGIN
1262 if (PWRCTRL->MISC_b.SIMOBUCKEN == 1)
1263 {
1264 am_hal_pwrctrl_simobuck_vddx_active_trim_adj_default(AM_HAL_BURST_VDDF, AM_HAL_BURST_BUCK_VDDF_ADJ_CODE_30MV);
1265 }
1266 else
1267 {
1268 am_hal_pwrctrl_ldo_vddx_active_trim_adj_default(AM_HAL_BURST_VDDF, AM_HAL_BURST_LDO_VDDF_ADJ_CODE_30MV);
1269 }
1270 am_hal_flash_delay( FLASH_CYCLES_US(20) );
1271 AM_CRITICAL_END
1272 }
1273
1274 //****************************************************************************
1275 //
1276 // Restore VDDF if CV Patch applied
1277 //
1278 //****************************************************************************
1279 void
am_hal_pwrctrl_wa_vddf_restore(void)1280 am_hal_pwrctrl_wa_vddf_restore(void)
1281 {
1282 //
1283 // Restore VDDF value
1284 //
1285 AM_CRITICAL_BEGIN
1286 if (PWRCTRL->MISC_b.SIMOBUCKEN == 1)
1287 {
1288 am_hal_pwrctrl_simobuck_vddx_active_trim_adj_default(AM_HAL_BURST_VDDF, 0);
1289 }
1290 else
1291 {
1292 am_hal_pwrctrl_ldo_vddx_active_trim_adj_default(AM_HAL_BURST_VDDF, 0);
1293 }
1294 am_hal_flash_delay( FLASH_CYCLES_US(20) );
1295 AM_CRITICAL_END
1296 }
1297
1298 #endif // AM_HAL_BURST_LDO_WORKAROUND
1299
1300 //*****************************************************************************
1301 //
1302 // End Doxygen group.
1303 //! @}
1304 //
1305 //*****************************************************************************
1306