1 //*****************************************************************************
2 //
3 //! @file am_hal_pwrctrl.c
4 //!
5 //! @brief Functions for enabling and disabling power domains.
6 //!
7 //! @addtogroup pwrctrl3 Pwrctrl - Power Control
8 //! @ingroup apollo3_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 //
70 // Mask of HCPA Enables from the PWRCTRL->DEVPWRSTATUS register mapped to the
71 // PWRCTRL->DEVPWREN register
72 //
73 #define HCPA_MASK ( \
74 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOS, PWRCTRL_DEVPWREN_PWRIOS_EN) | \
75 _VAL2FLD(PWRCTRL_DEVPWREN_PWRUART0, PWRCTRL_DEVPWREN_PWRUART0_EN) | \
76 _VAL2FLD(PWRCTRL_DEVPWREN_PWRUART1, PWRCTRL_DEVPWREN_PWRUART1_EN) | \
77 _VAL2FLD(PWRCTRL_DEVPWREN_PWRSCARD, PWRCTRL_DEVPWREN_PWRSCARD_EN))
78
79 //
80 // Mask of HCPB Enables from the PWRCTRL->DEVPWRSTATUS register mapped to the
81 // PWRCTRL->DEVPWREN register
82 //
83 #define HCPB_MASK ( \
84 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM0, PWRCTRL_DEVPWREN_PWRIOM0_EN) | \
85 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM1, PWRCTRL_DEVPWREN_PWRIOM1_EN) | \
86 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM2, PWRCTRL_DEVPWREN_PWRIOM2_EN))
87
88 //
89 // Mask of HCPC Enables from the PWRCTRL->DEVPWRSTATUS register mapped to the
90 // PWRCTRL->DEVPWREN register
91 //
92 #define HCPC_MASK ( \
93 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM3, PWRCTRL_DEVPWREN_PWRIOM3_EN) | \
94 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM4, PWRCTRL_DEVPWREN_PWRIOM4_EN) | \
95 _VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM5, PWRCTRL_DEVPWREN_PWRIOM5_EN))
96
97 //
98 // Define the peripheral control structure.
99 //
100 const struct
101 {
102 uint32_t ui32PeriphEnable;
103 uint32_t ui32PeriphStatus;
104 uint32_t ui32PeriphEvent;
105 }
106
107 am_hal_pwrctrl_peripheral_control[AM_HAL_PWRCTRL_PERIPH_MAX] =
108 {
109 {0, 0, 0}, // AM_HAL_PWRCTRL_PERIPH_NONE
110 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOS, PWRCTRL_DEVPWREN_PWRIOS_EN),
111 PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
112 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOS
113 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM0, PWRCTRL_DEVPWREN_PWRIOM0_EN),
114 PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
115 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM0
116 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM1, PWRCTRL_DEVPWREN_PWRIOM1_EN),
117 PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
118 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM1
119 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM2, PWRCTRL_DEVPWREN_PWRIOM2_EN),
120 PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
121 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM2
122 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM3, PWRCTRL_DEVPWREN_PWRIOM3_EN),
123 PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
124 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM3
125 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM4, PWRCTRL_DEVPWREN_PWRIOM4_EN),
126 PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
127 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM4
128 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM5, PWRCTRL_DEVPWREN_PWRIOM5_EN),
129 PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
130 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM5
131 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRUART0, PWRCTRL_DEVPWREN_PWRUART0_EN),
132 PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
133 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_UART0
134 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRUART1, PWRCTRL_DEVPWREN_PWRUART1_EN),
135 PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
136 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_UART1
137 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRADC, PWRCTRL_DEVPWREN_PWRADC_EN),
138 PWRCTRL_DEVPWRSTATUS_PWRADC_Msk,
139 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_ADCEVEN, PWRCTRL_DEVPWREVENTEN_ADCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_ADC
140 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRSCARD, PWRCTRL_DEVPWREN_PWRSCARD_EN),
141 PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
142 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_SCARD
143 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI, PWRCTRL_DEVPWREN_PWRMSPI_EN),
144 PWRCTRL_DEVPWRSTATUS_PWRMSPI_Msk,
145 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_MSPIEVEN, PWRCTRL_DEVPWREVENTEN_MSPIEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_MSPI
146 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRPDM, PWRCTRL_DEVPWREN_PWRPDM_EN),
147 PWRCTRL_DEVPWRSTATUS_PWRPDM_Msk,
148 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_PDMEVEN, PWRCTRL_DEVPWREVENTEN_PDMEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_PDM
149 {_VAL2FLD(PWRCTRL_DEVPWREN_PWRBLEL, PWRCTRL_DEVPWREN_PWRBLEL_EN),
150 PWRCTRL_DEVPWRSTATUS_BLEL_Msk,
151 _VAL2FLD(PWRCTRL_DEVPWREVENTEN_BLELEVEN, PWRCTRL_DEVPWREVENTEN_BLELEVEN_EN)} // AM_HAL_PWRCTRL_PERIPH_BLEL
152 };
153
154 //
155 // Define the memory control structure.
156 //
157 const struct
158 {
159 uint32_t ui32MemoryEnable;
160 uint32_t ui32MemoryStatus;
161 uint32_t ui32MemoryEvent;
162 uint32_t ui32MemoryMask;
163 uint32_t ui32StatusMask;
164 uint32_t ui32PwdSlpEnable;
165 }
166
167 am_hal_pwrctrl_memory_control[AM_HAL_PWRCTRL_MEM_MAX] =
168 {
169 {0, 0, 0, 0, 0, 0},
170 {AM_HAL_PWRCTRL_MEMEN_SRAM_8K_DTCM,
171 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_8K_DTCM,
172 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_8K_DTCM,
173 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
174 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
175 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_8K_DTCM},
176 {AM_HAL_PWRCTRL_MEMEN_SRAM_32K_DTCM,
177 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_32K_DTCM,
178 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_32K_DTCM,
179 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
180 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
181 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_32K_DTCM},
182 {AM_HAL_PWRCTRL_MEMEN_SRAM_64K_DTCM,
183 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_64K_DTCM,
184 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_64K_DTCM,
185 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
186 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
187 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_64K_DTCM},
188 {AM_HAL_PWRCTRL_MEMEN_SRAM_96K,
189 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_96K,
190 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_96K,
191 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
192 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
193 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_96K},
194 {AM_HAL_PWRCTRL_MEMEN_SRAM_128K,
195 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_128K,
196 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_128K,
197 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
198 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
199 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_128K},
200 {AM_HAL_PWRCTRL_MEMEN_SRAM_160K,
201 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_160K,
202 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_160K,
203 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
204 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
205 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_160K},
206 {AM_HAL_PWRCTRL_MEMEN_SRAM_192K,
207 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_192K,
208 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_192K,
209 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
210 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
211 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_192K},
212 {AM_HAL_PWRCTRL_MEMEN_SRAM_224K,
213 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_224K,
214 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_224K,
215 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
216 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
217 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_224K},
218 {AM_HAL_PWRCTRL_MEMEN_SRAM_256K,
219 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K,
220 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_256K,
221 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
222 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
223 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_256K},
224 {AM_HAL_PWRCTRL_MEMEN_SRAM_288K,
225 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_288K,
226 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_288K,
227 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
228 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
229 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_288K},
230 {AM_HAL_PWRCTRL_MEMEN_SRAM_320K,
231 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_320K,
232 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_320K,
233 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
234 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
235 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_320K},
236 {AM_HAL_PWRCTRL_MEMEN_SRAM_352K,
237 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_352K,
238 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_352K,
239 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
240 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
241 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_352K},
242 {AM_HAL_PWRCTRL_MEMEN_SRAM_384K,
243 AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_384K,
244 AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_384K,
245 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
246 AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
247 AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_384K},
248 {AM_HAL_PWRCTRL_MEMEN_FLASH_512K,
249 AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_512K,
250 AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_512K,
251 AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
252 AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
253 AM_HAL_PWRCTRL_MEMPWDINSLEEP_FLASH_512K},
254 {AM_HAL_PWRCTRL_MEMEN_FLASH_1M,
255 AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_1M,
256 AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_1M,
257 AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
258 AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
259 AM_HAL_PWRCTRL_MEMPWDINSLEEP_FLASH_1M},
260 {AM_HAL_PWRCTRL_MEMEN_CACHE,
261 0,
262 AM_HAL_PWRCTRL_MEMPWREVENTEN_CACHE,
263 AM_HAL_PWRCTRL_MEM_REGION_CACHE_MASK,
264 0,
265 AM_HAL_PWRCTRL_MEMPWDINSLEEP_CACHE},
266 {AM_HAL_PWRCTRL_MEMEN_ALL,
267 AM_HAL_PWRCTRL_PWRONSTATUS_ALL,
268 AM_HAL_PWRCTRL_MEMPWREVENTEN_ALL,
269 AM_HAL_PWRCTRL_MEM_REGION_ALL_MASK,
270 AM_HAL_PWRCTRL_MEM_REGION_ALT_ALL_MASK,
271 AM_HAL_PWRCTRL_MEMPWDINSLEEP_ALL}
272 };
273
274 // ****************************************************************************
275 //
276 // am_hal_pwrctrl_periph_enable()
277 // Enable power for a peripheral.
278 //
279 // ****************************************************************************
280 uint32_t
am_hal_pwrctrl_periph_enable(am_hal_pwrctrl_periph_e ePeripheral)281 am_hal_pwrctrl_periph_enable(am_hal_pwrctrl_periph_e ePeripheral)
282 {
283 //
284 // Enable power control for the given device.
285 //
286 AM_CRITICAL_BEGIN
287 PWRCTRL->DEVPWREN |= am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable;
288 AM_CRITICAL_END
289
290 for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WAIT; wait_usecs += 10)
291 {
292 am_hal_flash_delay(FLASH_CYCLES_US(10));
293
294 if ((PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) > 0)
295 {
296 break;
297 }
298 }
299
300 //
301 // Check the device status.
302 //
303 if ((PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) > 0)
304 {
305 return AM_HAL_STATUS_SUCCESS;
306 }
307 else
308 {
309 //
310 // IF the Power Enable fails, make sure the DEVPWREN is Low
311 //
312 AM_CRITICAL_BEGIN
313 PWRCTRL->DEVPWREN &= ~am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable;
314 AM_CRITICAL_END
315
316 return AM_HAL_STATUS_FAIL;
317 }
318 } // am_hal_pwrctrl_periph_enable()
319
320 // ****************************************************************************
321 //
322 // am_hal_pwrctrl_periph_disable_msk_check()
323 // Function checks the PWRCTRL->DEVPWREN since the PWRCTRL->DEVPWRSTATUS
324 // register alone cannot tell the user if a peripheral is enabled when
325 // and HCPx register is being used.
326 //
327 // ****************************************************************************
328 static uint32_t
pwrctrl_periph_disable_msk_check(am_hal_pwrctrl_periph_e ePeripheral)329 pwrctrl_periph_disable_msk_check(am_hal_pwrctrl_periph_e ePeripheral)
330 {
331 uint32_t retVal = AM_HAL_STATUS_FAIL;
332 uint32_t HCPxMask = PWRCTRL->DEVPWREN;
333
334 switch (am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus)
335 {
336 case (PWRCTRL_DEVPWRSTATUS_HCPA_Msk):
337 if (((HCPxMask & HCPA_MASK) > 0) && ((HCPxMask & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable) == 0))
338 {
339 retVal = AM_HAL_STATUS_SUCCESS;
340 }
341 break;
342
343 case (PWRCTRL_DEVPWRSTATUS_HCPB_Msk):
344 if (((HCPxMask & HCPB_MASK) > 0) && ((HCPxMask & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable) == 0))
345 {
346 retVal = AM_HAL_STATUS_SUCCESS;
347 }
348 break;
349
350 case (PWRCTRL_DEVPWRSTATUS_HCPC_Msk):
351 if (((HCPxMask & HCPC_MASK) > 0) && ((HCPxMask & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable) == 0))
352 {
353 retVal = AM_HAL_STATUS_SUCCESS;
354 }
355 break;
356
357 default:
358 break;
359 }
360
361 return retVal;
362 }
363
364 // ****************************************************************************
365 //
366 // am_hal_pwrctrl_periph_disable()
367 // Disable power for a peripheral.
368 //
369 // ****************************************************************************
370 uint32_t
am_hal_pwrctrl_periph_disable(am_hal_pwrctrl_periph_e ePeripheral)371 am_hal_pwrctrl_periph_disable(am_hal_pwrctrl_periph_e ePeripheral)
372 {
373 //
374 // Disable power domain for the given device.
375 //
376 AM_CRITICAL_BEGIN
377 PWRCTRL->DEVPWREN &= ~am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable;
378 AM_CRITICAL_END
379
380 for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WAIT; wait_usecs += 10)
381 {
382 am_hal_flash_delay(FLASH_CYCLES_US(10));
383
384 if ((PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) == 0)
385 {
386 break;
387 }
388 }
389
390 //
391 // Check the device status.
392 //
393 if ((PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) == 0)
394 {
395 return AM_HAL_STATUS_SUCCESS;
396 }
397 else
398 {
399 return pwrctrl_periph_disable_msk_check(ePeripheral);
400 }
401
402 } // am_hal_pwrctrl_periph_disable()
403
404 //*****************************************************************************
405 //
406 // am_hal_pwrctrl_periph_enabled()
407 // This function determines to the caller whether a given peripheral is
408 // currently enabled or disabled.
409 //
410 //*****************************************************************************
411 uint32_t
am_hal_pwrctrl_periph_enabled(am_hal_pwrctrl_periph_e ePeripheral,uint32_t * pui32Enabled)412 am_hal_pwrctrl_periph_enabled(am_hal_pwrctrl_periph_e ePeripheral,
413 uint32_t *pui32Enabled)
414 {
415 uint32_t ui32Mask = am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus;
416 uint32_t ui32Enabled = 0;
417
418 if (pui32Enabled == NULL)
419 {
420 return AM_HAL_STATUS_INVALID_ARG;
421 }
422
423 if (ui32Mask != 0)
424 {
425 ui32Enabled = PWRCTRL->DEVPWRSTATUS & ui32Mask ? 1 : 0;
426 ui32Enabled = ui32Enabled && (PWRCTRL->DEVPWREN & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable);
427 }
428
429 *pui32Enabled = ui32Enabled;
430
431 return AM_HAL_STATUS_SUCCESS;
432
433 } // am_hal_pwrctrl_periph_enabled()
434
435 // ****************************************************************************
436 //
437 // am_hal_pwrctrl_memory_enable()
438 // Enable a configuration of memory.
439 //
440 // ****************************************************************************
441 uint32_t
am_hal_pwrctrl_memory_enable(am_hal_pwrctrl_mem_e eMemConfig)442 am_hal_pwrctrl_memory_enable(am_hal_pwrctrl_mem_e eMemConfig)
443 {
444 uint32_t ui32MemEnMask, ui32MemDisMask, ui32MemRegionMask, ui32MemStatusMask;
445
446 ui32MemEnMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryEnable;
447 ui32MemDisMask = ~am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryEnable;
448 ui32MemRegionMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryMask;
449 ui32MemStatusMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32StatusMask;
450
451 //
452 // Disable unneeded memory. If nothing to be disabled, skip to save time.
453 //
454 // Note that a deliberate disable step using a disable mask is taken here
455 // for 2 reasons: 1) To only affect the specified type of memory, and 2)
456 // To avoid inadvertently disabling any memory currently being depended on.
457 //
458 if ( ui32MemDisMask != 0 )
459 {
460 PWRCTRL->MEMPWREN &=
461 ~(ui32MemDisMask & ui32MemRegionMask) |
462 (_VAL2FLD(PWRCTRL_MEMPWREN_DTCM, PWRCTRL_MEMPWREN_DTCM_GROUP0DTCM0) |
463 _VAL2FLD(PWRCTRL_MEMPWREN_FLASH0, PWRCTRL_MEMPWREN_FLASH0_EN));
464 am_hal_flash_delay(FLASH_CYCLES_US(1));
465 }
466
467 //
468 // Enable the required memory.
469 //
470 if ( ui32MemEnMask != 0 )
471 {
472 PWRCTRL->MEMPWREN |= ui32MemEnMask;
473
474 for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WAIT; wait_usecs += 10)
475 {
476 am_hal_flash_delay(FLASH_CYCLES_US(10));
477
478 if ( (PWRCTRL->MEMPWRSTATUS & ui32MemStatusMask) ==
479 am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryStatus )
480 {
481 break;
482 }
483 }
484 }
485
486 //
487 // Return status based on whether the power control memory status has reached the desired state.
488 //
489 if ( ( PWRCTRL->MEMPWRSTATUS & ui32MemStatusMask) ==
490 am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryStatus )
491 {
492 return AM_HAL_STATUS_SUCCESS;
493 }
494 else
495 {
496 return AM_HAL_STATUS_FAIL;
497 }
498
499 } // am_hal_pwrctrl_memory_enable()
500
501 // ****************************************************************************
502 //
503 // am_hal_pwrctrl_memory_deepsleep_powerdown()
504 // Power down respective memory.
505 //
506 // ****************************************************************************
507 uint32_t
am_hal_pwrctrl_memory_deepsleep_powerdown(am_hal_pwrctrl_mem_e eMemConfig)508 am_hal_pwrctrl_memory_deepsleep_powerdown(am_hal_pwrctrl_mem_e eMemConfig)
509 {
510 if ( eMemConfig >= AM_HAL_PWRCTRL_MEM_MAX )
511 {
512 return AM_HAL_STATUS_FAIL;
513 }
514
515 //
516 // Power down the required memory.
517 //
518 PWRCTRL->MEMPWDINSLEEP |= am_hal_pwrctrl_memory_control[eMemConfig].ui32PwdSlpEnable;
519
520 return AM_HAL_STATUS_SUCCESS;
521
522 } // am_hal_pwrctrl_memory_deepsleep_powerdown()
523
524 // ****************************************************************************
525 //
526 // am_hal_pwrctrl_memory_deepsleep_retain()
527 // Apply retention voltage to respective memory.
528 //
529 // ****************************************************************************
530 uint32_t
am_hal_pwrctrl_memory_deepsleep_retain(am_hal_pwrctrl_mem_e eMemConfig)531 am_hal_pwrctrl_memory_deepsleep_retain(am_hal_pwrctrl_mem_e eMemConfig)
532 {
533 if ( eMemConfig >= AM_HAL_PWRCTRL_MEM_MAX )
534 {
535 return AM_HAL_STATUS_FAIL;
536 }
537
538 //
539 // Retain the required memory.
540 //
541 PWRCTRL->MEMPWDINSLEEP &= ~am_hal_pwrctrl_memory_control[eMemConfig].ui32PwdSlpEnable;
542
543 return AM_HAL_STATUS_SUCCESS;
544
545 } // am_hal_pwrctrl_memory_deepsleep_retain()
546
547 // ****************************************************************************
548 // simobuck_updates()
549 // ****************************************************************************
550 static void
simobuck_updates(void)551 simobuck_updates(void)
552 {
553 //
554 // Adjust the SIMOBUCK LP settings.
555 //
556 if ( APOLLO3_GE_B0 )
557 {
558 MCUCTRL->SIMOBUCK2_b.SIMOBUCKCORELPHIGHTONTRIM = 2;
559 MCUCTRL->SIMOBUCK2_b.SIMOBUCKCORELPLOWTONTRIM = 3;
560 MCUCTRL->SIMOBUCK3_b.SIMOBUCKCORELPHIGHTOFFTRIM = 5;
561 MCUCTRL->SIMOBUCK3_b.SIMOBUCKCORELPLOWTOFFTRIM = 2;
562 MCUCTRL->SIMOBUCK3_b.SIMOBUCKMEMLPHIGHTOFFTRIM = 6;
563 MCUCTRL->SIMOBUCK3_b.SIMOBUCKMEMLPLOWTOFFTRIM = 1;
564 MCUCTRL->SIMOBUCK3_b.SIMOBUCKMEMLPHIGHTONTRIM = 3;
565 MCUCTRL->SIMOBUCK4_b.SIMOBUCKMEMLPLOWTONTRIM = 3;
566 }
567
568 //
569 // Adjust the SIMOBUCK Timeout settings.
570 //
571 if ( APOLLO3_GE_A1 )
572 {
573 MCUCTRL->SIMOBUCK4_b.SIMOBUCKCOMP2TIMEOUTEN = 0;
574 }
575
576 } // simobuck_updates()
577
578 // ****************************************************************************
579 //
580 // am_hal_pwrctrl_low_power_init()
581 // Initialize system for low power configuration.
582 //
583 // ****************************************************************************
584 uint32_t
am_hal_pwrctrl_low_power_init(void)585 am_hal_pwrctrl_low_power_init(void)
586 {
587 uint32_t ui32Status;
588
589 //
590 // Take a snapshot of the reset status, if not done already
591 //
592 if ( !gAmHalResetStatus )
593 {
594 gAmHalResetStatus = RSTGEN->STAT;
595 }
596
597 //
598 // Software workaround for Errata ERR019.
599 //
600 if ((APOLLO3_A1) && (1 == PWRCTRL->SUPPLYSTATUS_b.SIMOBUCKON))
601 {
602 ui32Status = am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_PDM);
603 if (AM_HAL_STATUS_SUCCESS != ui32Status)
604 {
605 return ui32Status;
606 }
607 }
608
609 //
610 // Adjust the SIMOBUCK LP settings.
611 //
612 simobuck_updates();
613
614 //
615 // Configure cache for low power and performance.
616 //
617 am_hal_cachectrl_control(AM_HAL_CACHECTRL_CONTROL_LPMMODE_RECOMMENDED, 0);
618
619 //
620 // Check if the BLE is already enabled.
621 //
622 if ( PWRCTRL->DEVPWRSTATUS_b.BLEL == 0)
623 {
624 am_hal_pwrctrl_blebuck_trim();
625
626 //
627 // First request the BLE feature and check that it was available and acknowledged.
628 //
629 MCUCTRL->FEATUREENABLE_b.BLEREQ = 1;
630 ui32Status = am_hal_flash_delay_status_check(10000,
631 (uint32_t)&MCUCTRL->FEATUREENABLE,
632 (MCUCTRL_FEATUREENABLE_BLEAVAIL_Msk |
633 MCUCTRL_FEATUREENABLE_BLEACK_Msk |
634 MCUCTRL_FEATUREENABLE_BLEREQ_Msk),
635 (MCUCTRL_FEATUREENABLE_BLEAVAIL_Msk |
636 MCUCTRL_FEATUREENABLE_BLEACK_Msk |
637 MCUCTRL_FEATUREENABLE_BLEREQ_Msk),
638 true);
639
640 if (AM_HAL_STATUS_SUCCESS != ui32Status)
641 {
642 return AM_HAL_STATUS_TIMEOUT;
643 }
644
645 //
646 // Next, enable the BLE Buck.
647 //
648 PWRCTRL->SUPPLYSRC |= _VAL2FLD(PWRCTRL_SUPPLYSRC_BLEBUCKEN,
649 PWRCTRL_SUPPLYSRC_BLEBUCKEN_EN);
650
651 //
652 // Allow the buck to go to low power mode in BLE sleep.
653 //
654 PWRCTRL->MISC |= _VAL2FLD(PWRCTRL_MISC_MEMVRLPBLE,
655 PWRCTRL_MISC_MEMVRLPBLE_EN);
656
657 //
658 // Check for Apollo3 A0 Silicon.
659 //
660 if ( APOLLO3_A0 )
661 {
662 // Disable SIMO Buck clkdiv because if ble is out of reset then the same bit divides the simobuck clk too aggressively.
663 MCUCTRL->SIMOBUCK4_b.SIMOBUCKCLKDIVSEL = 0x0;
664 MCUCTRL->BLEBUCK2_b.BLEBUCKTONHITRIM = 0xF;
665 MCUCTRL->BLEBUCK2_b.BLEBUCKTONLOWTRIM = 0xF;
666 }
667 }
668
669 return AM_HAL_STATUS_SUCCESS;
670 } // am_hal_pwrctrl_low_power_init()
671
672 // ****************************************************************************
673 //
674 // am_hal_pwrctrl_blebuck_trim()
675 //
676 // ****************************************************************************
am_hal_pwrctrl_blebuck_trim(void)677 void am_hal_pwrctrl_blebuck_trim(void)
678 {
679 //
680 // Enable the BLE buck trim values
681 //
682 if ( APOLLO3_GE_A1 )
683 {
684 AM_CRITICAL_BEGIN
685 MCUCTRL->BLEBUCK2_b.BLEBUCKTONHITRIM = 0x19;
686 MCUCTRL->BLEBUCK2_b.BLEBUCKTONLOWTRIM = 0xC;
687 CLKGEN->BLEBUCKTONADJ_b.TONADJUSTEN = CLKGEN_BLEBUCKTONADJ_TONADJUSTEN_DIS;
688 AM_CRITICAL_END
689 }
690 } // am_hal_pwrctrl_blebuck_trim()
691
692 //*****************************************************************************
693 //
694 // End Doxygen group.
695 //! @}
696 //
697 //*****************************************************************************
698