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