1 //*****************************************************************************
2 //
3 // am_hal_mcuctrl.c
4 //! @file
5 //!
6 //! @brief Functions for interfacing with the MCUCTRL.
7 //!
8 //! @addtogroup mcuctrl2 MCU Control (MCUCTRL)
9 //! @ingroup apollo2hal
10 //! @{
11 //
12 //*****************************************************************************
13
14 //*****************************************************************************
15 //
16 // Copyright (c) 2017, Ambiq Micro
17 // All rights reserved.
18 //
19 // Redistribution and use in source and binary forms, with or without
20 // modification, are permitted provided that the following conditions are met:
21 //
22 // 1. Redistributions of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // 3. Neither the name of the copyright holder nor the names of its
30 // contributors may be used to endorse or promote products derived from this
31 // software without specific prior written permission.
32 //
33 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
37 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 // POSSIBILITY OF SUCH DAMAGE.
44 //
45 // This is part of revision 1.2.11 of the AmbiqSuite Development Package.
46 //
47 //*****************************************************************************
48
49 #include <stdint.h>
50 #include <stdbool.h>
51 #include "am_mcu_apollo.h"
52
53 #define LDO_TRIM_REG_ADDR (0x50023004)
54 #define BUCK_TRIM_REG_ADDR (0x50023000)
55
56 //*****************************************************************************
57 //
58 // Global Variables.
59 //
60 //*****************************************************************************
61 //
62 // Define the flash sizes from CHIP_INFO.
63 //
64 const uint32_t g_am_hal_mcuctrl_flash_size[16] =
65 {
66 16 * 1024, /* 0x0 0x00004000 16 KB */
67 32 * 1024, /* 0x1 0x00008000 32 KB */
68 64 * 1024, /* 0x2 0x00010000 64 KB */
69 128 * 1024, /* 0x3 0x00020000 128 KB */
70 256 * 1024, /* 0x4 0x00040000 256 KB */
71 512 * 1024, /* 0x5 0x00080000 512 KB */
72 1 * 1024 * 1024, /* 0x6 0x00100000 1 MB */
73 2 * 1024 * 1024, /* 0x7 0x00200000 2 MB */
74 4 * 1024 * 1024, /* 0x8 0x00400000 4 MB */
75 8 * 1024 * 1024, /* 0x9 0x00800000 8 MB */
76 16 * 1024 * 1024, /* 0xA 0x01000000 16 MB */
77 32 * 1024 * 1024, /* 0xB 0x02000000 32 MB */
78 64 * 1024 * 1024, /* 0xC 0x04000000 64 MB */
79 128 * 1024 * 1024, /* 0xD 0x08000000 128 MB */
80 256 * 1024 * 1024, /* 0xE 0x10000000 256 MB */
81 512 * 1024 * 1024 /* 0xF 0x20000000 512 MB */
82 };
83
84 //
85 // Define the SRAM sizes from CHIP_INFO.
86 // For Apollo2, the SRAM sizes are defined exactly the same as the flash sizes.
87 //
88 #define g_am_hal_mcuctrl_sram_size g_am_hal_mcuctrl_flash_size
89
90 //*****************************************************************************
91 //
92 //! @brief Gets all relevant device information.
93 //!
94 //! @param psDevice is a pointer to a structure that will be used to store all
95 //! device info.
96 //!
97 //! This function gets the device part number, chip IDs, and revision and
98 //! stores them in the passed structure.
99 //!
100 //! @return None
101 //
102 //*****************************************************************************
103 void
am_hal_mcuctrl_device_info_get(am_hal_mcuctrl_device_t * psDevice)104 am_hal_mcuctrl_device_info_get(am_hal_mcuctrl_device_t *psDevice)
105 {
106 //
107 // Read the Part Number.
108 //
109 psDevice->ui32ChipPN = AM_REG(MCUCTRL, CHIP_INFO);
110
111 //
112 // Read the Chip ID0.
113 //
114 psDevice->ui32ChipID0 = AM_REG(MCUCTRL, CHIPID0);
115
116 //
117 // Read the Chip ID1.
118 //
119 psDevice->ui32ChipID1 = AM_REG(MCUCTRL, CHIPID1);
120
121 //
122 // Read the Chip Revision.
123 //
124 psDevice->ui32ChipRev = AM_REG(MCUCTRL, CHIPREV);
125
126 //
127 // Read the Part Number.
128 //
129 psDevice->ui32ChipPN = AM_REG(MCUCTRL, CHIP_INFO);
130
131 //
132 // Read the Chip ID0.
133 //
134 psDevice->ui32ChipID0 = AM_REG(MCUCTRL, CHIPID0);
135
136 //
137 // Read the Chip ID1.
138 //
139 psDevice->ui32ChipID1 = AM_REG(MCUCTRL, CHIPID1);
140
141 //
142 // Read the Chip Revision.
143 //
144 psDevice->ui32ChipRev = AM_REG(MCUCTRL, CHIPREV);
145
146 //
147 // Read the Chip VENDOR ID.
148 //
149 psDevice->ui32VendorID = AM_REG(MCUCTRL, VENDORID);
150
151 //
152 // Qualified from Part Number.
153 //
154 psDevice->ui32Qualified =
155 (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_QUAL_M) >>
156 AM_HAL_MCUCTRL_CHIP_INFO_QUAL_S;
157
158 //
159 // Flash size from Part Number.
160 //
161 psDevice->ui32FlashSize =
162 g_am_hal_mcuctrl_flash_size[
163 (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_FLASH_SIZE_M) >>
164 AM_HAL_MCUCTRL_CHIP_INFO_FLASH_SIZE_S];
165
166 //
167 // SRAM size from Part Number.
168 //
169 psDevice->ui32SRAMSize =
170 g_am_hal_mcuctrl_flash_size[
171 (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_SRAM_SIZE_M) >>
172 AM_HAL_MCUCTRL_CHIP_INFO_SRAM_SIZE_S];
173
174 //
175 // Now, let's look at the JEDEC info.
176 // The full partnumber is 12 bits total, but is scattered across 2 registers.
177 // Bits [11:8] are 0xE.
178 // Bits [7:4] are 0xE for Apollo, 0xD for Apollo2.
179 // Bits [3:0] are defined differently for Apollo and Apollo2.
180 // For Apollo, the low nibble is 0x0.
181 // For Apollo2, the low nibble indicates flash and SRAM size.
182 //
183 psDevice->ui32JedecPN = (AM_BFR(JEDEC, PID0, PNL8) << 0);
184 psDevice->ui32JedecPN |= (AM_BFR(JEDEC, PID1, PNH4) << 8);
185
186 //
187 // JEPID is the JEP-106 Manufacturer ID Code, which is assigned to Ambiq as
188 // 0x1B, with parity bit is 0x9B. It is 8 bits located across 2 registers.
189 //
190 psDevice->ui32JedecJEPID = (AM_BFR(JEDEC, PID1, JEPIDL) << 0);
191 psDevice->ui32JedecJEPID |= (AM_BFR(JEDEC, PID2, JEPIDH) << 4);
192
193 //
194 // CHIPREV is 8 bits located across 2 registers.
195 //
196 psDevice->ui32JedecCHIPREV = (AM_BFR(JEDEC, PID2, CHIPREVH4) << 4);
197 psDevice->ui32JedecCHIPREV |= (AM_BFR(JEDEC, PID3, CHIPREVL4) << 0);
198
199 //
200 // Let's get the Coresight ID (32-bits across 4 registers)
201 // For Apollo and Apollo2, it's expected to be 0xB105100D.
202 //
203 psDevice->ui32JedecCID = (AM_BFR(JEDEC, CID3, CID) << 24);
204 psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID2, CID) << 16);
205 psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID1, CID) << 8);
206 psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID0, CID) << 0);
207 }
208
209 //*****************************************************************************
210 //
211 //! @brief Enables the fault capture registers.
212 //!
213 //! This function enables the DCODEFAULTADDR and ICODEFAULTADDR registers.
214 //!
215 //! @return None
216 //
217 //*****************************************************************************
218 void
am_hal_mcuctrl_fault_capture_enable(void)219 am_hal_mcuctrl_fault_capture_enable(void)
220 {
221 //
222 // Enable the Fault Capture registers.
223 //
224 AM_BFW(MCUCTRL, FAULTCAPTUREEN, ENABLE, 1);
225 }
226
227 //*****************************************************************************
228 //
229 //! @brief Disables the fault capture registers.
230 //!
231 //! This function disables the DCODEFAULTADDR and ICODEFAULTADDR registers.
232 //!
233 //! @return None
234 //
235 //*****************************************************************************
236 void
am_hal_mcuctrl_fault_capture_disable(void)237 am_hal_mcuctrl_fault_capture_disable(void)
238 {
239 //
240 // Disable the Fault Capture registers.
241 //
242 AM_BFW(MCUCTRL, FAULTCAPTUREEN, ENABLE, 0);
243 }
244
245 //*****************************************************************************
246 //
247 //! @brief Gets the fault status and capture registers.
248 //!
249 //! @param psFault is a pointer to a structure that will be used to store all
250 //! fault info.
251 //!
252 //! This function gets the status of the ICODE, DCODE, and SYS bus faults and
253 //! the addresses associated with the fault.
254 //!
255 //! @return None
256 //
257 //*****************************************************************************
258 void
am_hal_mcuctrl_fault_status(am_hal_mcuctrl_fault_t * psFault)259 am_hal_mcuctrl_fault_status(am_hal_mcuctrl_fault_t *psFault)
260 {
261 uint32_t ui32FaultStat;
262
263 //
264 // Read the Fault Status Register.
265 //
266 ui32FaultStat = AM_REG(MCUCTRL, FAULTSTATUS);
267 psFault->bICODE = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_ICODE_M);
268 psFault->bDCODE = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_DCODE_M);
269 psFault->bSYS = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_SYS_M);
270
271 //
272 // Read the DCODE fault capture address register.
273 //
274 psFault->ui32DCODE = AM_REG(MCUCTRL, DCODEFAULTADDR);
275
276 //
277 // Read the ICODE fault capture address register.
278 //
279 psFault->ui32ICODE |= AM_REG(MCUCTRL, ICODEFAULTADDR);
280
281 //
282 // Read the ICODE fault capture address register.
283 //
284 psFault->ui32SYS |= AM_REG(MCUCTRL, SYSFAULTADDR);
285 }
286
287 //*****************************************************************************
288 //
289 // End Doxygen group.
290 //! @}
291 //
292 //*****************************************************************************
293