1 /**
2 * @file mxc_sys.h
3 * @brief System level header file.
4 */
5
6 /******************************************************************************
7 *
8 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
9 * Analog Devices, Inc.),
10 * Copyright (C) 2023-2024 Analog Devices, Inc.
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 ******************************************************************************/
25
26 #ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_MXC_SYS_H_
27 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_MXC_SYS_H_
28
29 #include "mxc_device.h"
30 #include "gcr_regs.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 /**
37 * @defgroup mxc_sys System Configuration (MXC_SYS)
38 * @ingroup syscfg
39 * @details API for system configuration including clock source selection and entering critical sections of code.
40 * @{
41 */
42
43 /** @brief System reset0 and reset1 enumeration. Used in MXC_SYS_PeriphReset0 function */
44 typedef enum {
45 MXC_SYS_RESET0_DMA = MXC_F_GCR_RST0_DMA_POS, /**< Reset DMA */
46 MXC_SYS_RESET0_WDT = MXC_F_GCR_RST0_WDT0_POS, /**< Reset WDT */
47 MXC_SYS_RESET0_GPIO0 = MXC_F_GCR_RST0_GPIO0_POS, /**< Reset GPIO0 */
48 MXC_SYS_RESET0_GPIO1 = MXC_F_GCR_RST0_GPIO1_POS, /**< Reset GPIO1 */
49 MXC_SYS_RESET0_GPIO2 = MXC_F_GCR_RST0_GPIO2_POS, /**< Reset GPIO2 */
50 MXC_SYS_RESET0_TMR0 = MXC_F_GCR_RST0_TMR0_POS, /**< Reset TMR0 */
51 MXC_SYS_RESET0_TMR1 = MXC_F_GCR_RST0_TMR1_POS, /**< Reset TMR1 */
52 MXC_SYS_RESET0_TMR2 = MXC_F_GCR_RST0_TMR2_POS, /**< Reset TMR2 */
53 MXC_SYS_RESET0_TMR3 = MXC_F_GCR_RST0_TMR3_POS, /**< Reset TMR3 */
54 MXC_SYS_RESET0_TMR4 = MXC_F_GCR_RST0_TMR4_POS, /**< Reset TMR4 */
55 MXC_SYS_RESET0_TMR5 = MXC_F_GCR_RST0_TMR5_POS, /**< Reset TMR5 */
56 MXC_SYS_RESET0_TMR6 = MXC_F_GCR_RST0_TMR6_POS, /**< Reset TMR6 */
57 MXC_SYS_RESET0_TMR7 = MXC_F_GCR_RST0_TMR7_POS, /**< Reset TMR7 */
58 MXC_SYS_RESET0_UART0 = MXC_F_GCR_RST0_UART0_POS, /**< Reset UART0 */
59 MXC_SYS_RESET0_UART1 = MXC_F_GCR_RST0_UART1_POS, /**< Reset UART1 */
60 MXC_SYS_RESET0_SPI0 = MXC_F_GCR_RST0_SPI0_POS, /**< Reset SPI0 */
61 MXC_SYS_RESET0_SPI1 = MXC_F_GCR_RST0_SPI1_POS, /**< Reset SPI1 */
62 MXC_SYS_RESET0_SPI2 = MXC_F_GCR_RST0_SPI2_POS, /**< Reset SPI2 */
63 MXC_SYS_RESET0_I2C0 = MXC_F_GCR_RST0_I2C0_POS, /**< Reset I2C0 */
64 MXC_SYS_RESET0_RTC = MXC_F_GCR_RST0_RTC_POS, /**< Reset RTC */
65 MXC_SYS_RESET0_CTB = MXC_F_GCR_RST0_CRYPTO_POS, /**< Reset CRYPTO */
66 MXC_SYS_RESET0_CLCD = MXC_F_GCR_RST0_CLCD_POS, /**< Reset CLCD */
67 MXC_SYS_RESET0_USB = MXC_F_GCR_RST0_USB_POS, /**< Reset USB */
68 MXC_SYS_RESET0_ADC = MXC_F_GCR_RST0_ADC_POS, /**< Reset ADC */
69 MXC_SYS_RESET0_UART2 = MXC_F_GCR_RST0_UART2_POS, /**< Reset UART2 */
70 MXC_SYS_RESET0_SRST = MXC_F_GCR_RST0_SOFT_POS, /**< Soft reset */
71 MXC_SYS_RESET0_PRST = MXC_F_GCR_RST0_PERIPH_POS, /**< Peripheral reset */
72 MXC_SYS_RESET0_SYS = MXC_F_GCR_RST0_SYS_POS, /**< System reset */
73 /* RESET1 Below this line we add 32 to separate RESET0 and RESET1 */
74 MXC_SYS_RESET1_I2C1 = (MXC_F_GCR_RST1_I2C1_POS + 32), /**< Reset I2C1 */
75 MXC_SYS_RESET1_PT = (MXC_F_GCR_RST1_PT_POS + 32), /**< Reset PT */
76 MXC_SYS_RESET1_SPIXIP = (MXC_F_GCR_RST1_SPIXIP_POS + 32), /**< Reset SPIXIP */
77 MXC_SYS_RESET1_XSPIM = (MXC_F_GCR_RST1_XSPIM_POS + 32), /**< Reset XSPIM */
78 MXC_SYS_RESET1_SDHC = (MXC_F_GCR_RST1_SDHC_POS + 32), /**< Reset SDHC */
79 MXC_SYS_RESET1_GPIO3 = (MXC_F_GCR_RST1_GPIO3_POS + 32), /**< Reset GPIO3 */
80 MXC_SYS_RESET1_OWIRE = (MXC_F_GCR_RST1_OWIRE_POS + 32), /**< Reset OWIRE */
81 MXC_SYS_RESET1_WDT1 = (MXC_F_GCR_RST1_WDT1_POS + 32), /**< Reset WDT1 */
82 MXC_SYS_RESET1_SPI3 = (MXC_F_GCR_RST1_SPI3_POS + 32), /**< Reset SPI3 */
83 MXC_SYS_RESET1_SPIXMEM = (MXC_F_GCR_RST1_SPIXMEM_POS + 32), /**< Reset SPIXMEM */
84 MXC_SYS_RESET1_I2C2 = (MXC_F_GCR_RST1_I2C2_POS + 32), /**< Reset I2C2*/
85 MXC_SYS_RESET1_UART3 = (MXC_F_GCR_RST1_UART3_POS + 32), /**< Reset UART3*/
86 MXC_SYS_RESET1_UART4 = (MXC_F_GCR_RST1_UART4_POS + 32), /**< Reset USRT4*/
87 MXC_SYS_RESET1_UART5 = (MXC_F_GCR_RST1_UART5_POS + 32), /**< Reset UART5*/
88 MXC_SYS_RESET1_KBD = (MXC_F_GCR_RST1_KBD_POS + 32), /**< Reset KBD*/
89 MXC_SYS_RESET1_ADC9 = (MXC_F_GCR_RST1_ADC9_POS + 32), /**< Reset ADC9*/
90 MXC_SYS_RESET1_SC0 = (MXC_F_GCR_RST1_SC0_POS + 32), /**< Reset SC0*/
91 MXC_SYS_RESET1_SC1 = (MXC_F_GCR_RST1_SC1_POS + 32), /**< Reset SC1*/
92 MXC_SYS_RESET1_NFC = (MXC_F_GCR_RST1_NFC_POS + 32), /**< Reset NFC*/
93 MXC_SYS_RESET1_EMAC = (MXC_F_GCR_RST1_EMAC_POS + 32), /**< Reset EMAC*/
94 MXC_SYS_RESET1_PCIF = (MXC_F_GCR_RST1_PCIF_POS + 32), /**< Reset PCIF*/
95 MXC_SYS_RESET1_HTMR0 = (MXC_F_GCR_RST1_HTMR0_POS + 32), /**< Reset HTMR0*/
96 MXC_SYS_RESET1_HTMR1 = (MXC_F_GCR_RST1_HTMR1_POS + 32), /**< Reset HTMR1*/
97 MXC_SYS_RESET1_AC = (MXC_F_GCR_RST1_AC_POS + 32), /**< Reset AC*/
98 } mxc_sys_reset_t;
99
100 /** @brief System clock disable enumeration. Used in MXC_SYS_ClockDisable and MXC_SYS_ClockEnable functions */
101 typedef enum {
102 MXC_SYS_PERIPH_CLOCK_GPIO0 =
103 MXC_F_GCR_PCLKDIS0_GPIO0_POS, /**< Disable MXC_F_GCR_PCLKDIS0_GPIO0 clock */
104 MXC_SYS_PERIPH_CLOCK_GPIO1 =
105 MXC_F_GCR_PCLKDIS0_GPIO1_POS, /**< Disable MXC_F_GCR_PCLKDIS0_GPIO1 clock */
106 MXC_SYS_PERIPH_CLOCK_GPIO2 =
107 MXC_F_GCR_PCLKDIS0_GPIO2_POS, /**< Disable MXC_F_GCR_PCLKDIS0_GPIO2 clock */
108 MXC_SYS_PERIPH_CLOCK_USB =
109 MXC_F_GCR_PCLKDIS0_USB_POS, /**< Disable MXC_F_GCR_PCLKDIS0_USB clock */
110 MXC_SYS_PERIPH_CLOCK_CLCD =
111 MXC_F_GCR_PCLKDIS0_CLCD_POS, /**< Disable MXC_F_GCR_PCLKDIS0_CLC clock */
112 MXC_SYS_PERIPH_CLOCK_DMA =
113 MXC_F_GCR_PCLKDIS0_DMA_POS, /**< Disable MXC_F_GCR_PCLKDIS0_DMA clock */
114 MXC_SYS_PERIPH_CLOCK_SPI0 =
115 MXC_F_GCR_PCLKDIS0_SPI0_POS, /**< Disable MXC_F_GCR_PCLKDIS0_SPI0 clock */
116 MXC_SYS_PERIPH_CLOCK_SPI1 =
117 MXC_F_GCR_PCLKDIS0_SPI1_POS, /**< Disable MXC_F_GCR_PCLKDIS0_SPI1 clock */
118 MXC_SYS_PERIPH_CLOCK_SPI2 =
119 MXC_F_GCR_PCLKDIS0_SPI2_POS, /**< Disable MXC_F_GCR_PCLKDIS0_SPI2 clock */
120 MXC_SYS_PERIPH_CLOCK_UART0 =
121 MXC_F_GCR_PCLKDIS0_UART0_POS, /**< Disable MXC_F_GCR_PCLKDIS0_UART0 clock */
122 MXC_SYS_PERIPH_CLOCK_UART1 =
123 MXC_F_GCR_PCLKDIS0_UART1_POS, /**< Disable MXC_F_GCR_PCLKDIS0_UART1 clock */
124 MXC_SYS_PERIPH_CLOCK_I2C0 =
125 MXC_F_GCR_PCLKDIS0_I2C0_POS, /**< Disable MXC_F_GCR_PCLKDIS0_I2C0 clock */
126 MXC_SYS_PERIPH_CLOCK_CTB =
127 MXC_F_GCR_PCLKDIS0_CRYPTO_POS, /**< Disable MXC_F_GCR_PCLKDIS0_CRYPTO clock */
128 MXC_SYS_PERIPH_CLOCK_TMR0 =
129 MXC_F_GCR_PCLKDIS0_TMR0_POS, /**< Disable MXC_F_GCR_PCLKDIS0_TMR0 clock */
130 MXC_SYS_PERIPH_CLOCK_TMR1 =
131 MXC_F_GCR_PCLKDIS0_TMR1_POS, /**< Disable MXC_F_GCR_PCLKDIS0_TMR1 clock */
132 MXC_SYS_PERIPH_CLOCK_TMR2 =
133 MXC_F_GCR_PCLKDIS0_TMR2_POS, /**< Disable MXC_F_GCR_PCLKDIS0_TMR2 clock */
134 MXC_SYS_PERIPH_CLOCK_TMR3 =
135 MXC_F_GCR_PCLKDIS0_TMR3_POS, /**< Disable MXC_F_GCR_PCLKDIS0_TMR3 clock */
136 MXC_SYS_PERIPH_CLOCK_TMR4 =
137 MXC_F_GCR_PCLKDIS0_TMR4_POS, /**< Disable MXC_F_GCR_PCLKDIS0_TMR4 clock */
138 MXC_SYS_PERIPH_CLOCK_TMR5 =
139 MXC_F_GCR_PCLKDIS0_TMR5_POS, /**< Disable MXC_F_GCR_PCLKDIS0_TMR5 clock */
140 MXC_SYS_PERIPH_CLOCK_TMR6 =
141 MXC_F_GCR_PCLKDIS0_TMR6_POS, /**< Disable MXC_F_GCR_PCLKDIS0_TMR6 clock */
142 MXC_SYS_PERIPH_CLOCK_TMR7 =
143 MXC_F_GCR_PCLKDIS0_TMR7_POS, /**< Disable MXC_F_GCR_PCLKDIS0_TMR7 clock */
144 MXC_SYS_PERIPH_CLOCK_KBD =
145 MXC_F_GCR_PCLKDIS0_KBD_POS, /**< Disable MXC_F_GCR_PCLKDIS0_ADC clock */
146 MXC_SYS_PERIPH_CLOCK_ADC =
147 MXC_F_GCR_PCLKDIS0_ADC_POS, /**< Disable MXC_F_GCR_PCLKDIS0_ADC clock */
148 MXC_SYS_PERIPH_CLOCK_HTMR0 =
149 MXC_F_GCR_PCLKDIS0_HTMR0_POS, /**< Disable MXC_F_GCR_PCLKDIS1_HTMR0 clock */
150 MXC_SYS_PERIPH_CLOCK_HTMR1 =
151 MXC_F_GCR_PCLKDIS0_HTMR1_POS, /**< Disable MXC_F_GCR_PCLKDIS1_HTMR1 clock */
152 MXC_SYS_PERIPH_CLOCK_I2C1 =
153 MXC_F_GCR_PCLKDIS0_I2C1_POS, /**< Disable MXC_F_GCR_PCLKDIS0_I2C1 clock */
154 MXC_SYS_PERIPH_CLOCK_PT = MXC_F_GCR_PCLKDIS0_PT_POS, /**< Disable MXC_F_GCR_PCLKDIS0_PT clock */
155 MXC_SYS_PERIPH_CLOCK_SPIXIP =
156 MXC_F_GCR_PCLKDIS0_SPIXIP_POS, /**< Disable MXC_F_GCR_PCLKDIS0_SPIXIP clock */
157 MXC_SYS_PERIPH_CLOCK_SPIXFC =
158 MXC_F_GCR_PCLKDIS0_SPIM_POS, /**< Disable MXC_F_GCR_PCLKDIS0_SPIM clock */
159 /* PCLKDIS1 Below this line we add 32 to separate PCLKDIS0 and PCLKDIS1 */
160 MXC_SYS_PERIPH_CLOCK_UART2 =
161 (MXC_F_GCR_PCLKDIS1_UART2_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_UART2 clock */
162 MXC_SYS_PERIPH_CLOCK_TRNG =
163 (MXC_F_GCR_PCLKDIS1_TRNG_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_TRNG clock */
164 MXC_SYS_PERIPH_CLOCK_WDT0 =
165 (MXC_F_GCR_PCLKDIS1_WDT0_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_WDT0 clock */
166 MXC_SYS_PERIPH_CLOCK_WDT1 =
167 (MXC_F_GCR_PCLKDIS1_WDT1_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_WDT1 clock */
168 MXC_SYS_PERIPH_CLOCK_GPIO3 =
169 (MXC_F_GCR_PCLKDIS1_GPIO3_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_GPIO3 clock */
170 MXC_SYS_PERIPH_CLOCK_SCACHE =
171 (MXC_F_GCR_PCLKDIS1_SCACHE_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_SCACHE clock */
172 MXC_SYS_PERIPH_CLOCK_HA0 =
173 (MXC_F_GCR_PCLKDIS1_HA0_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_HA0 clock */
174 MXC_SYS_PERIPH_CLOCK_SDHC =
175 (MXC_F_GCR_PCLKDIS1_SDHC_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_SDHC clock */
176 MXC_SYS_PERIPH_CLOCK_ICACHE =
177 (MXC_F_GCR_PCLKDIS1_ICC0_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_ICACHE clock */
178 MXC_SYS_PERIPH_CLOCK_ICACHEXIP =
179 (MXC_F_GCR_PCLKDIS1_ICCXIP_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_ICACHEXIP clock */
180 MXC_SYS_PERIPH_CLOCK_OWIRE =
181 (MXC_F_GCR_PCLKDIS1_OWIRE_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_OWIRE clock */
182 MXC_SYS_PERIPH_CLOCK_SPI3 =
183 (MXC_F_GCR_PCLKDIS1_SPI3_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_SPI3 clock */
184 MXC_SYS_PERIPH_CLOCK_SPIXIPD =
185 (MXC_F_GCR_PCLKDIS1_SPIXIP_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_SPIXIP clock */
186 MXC_SYS_PERIPH_CLOCK_I2C2 =
187 (MXC_F_GCR_PCLKDIS1_I2C2_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_I2C2 clock */
188 MXC_SYS_PERIPH_CLOCK_UART3 =
189 (MXC_F_GCR_PCLKDIS1_UART3_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_UART3 clock */
190 MXC_SYS_PERIPH_CLOCK_UART4 =
191 (MXC_F_GCR_PCLKDIS1_UART4_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_UART4 clock */
192 MXC_SYS_PERIPH_CLOCK_UART5 =
193 (MXC_F_GCR_PCLKDIS1_UART5_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_UART5 clock */
194 MXC_SYS_PERIPH_CLOCK_ADC9 =
195 (MXC_F_GCR_PCLKDIS1_ADC9_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_ADC9 clock */
196 MXC_SYS_PERIPH_CLOCK_SC0 =
197 (MXC_F_GCR_PCLKDIS1_SC0_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_SC0 clock */
198 MXC_SYS_PERIPH_CLOCK_SC1 =
199 (MXC_F_GCR_PCLKDIS1_SC1_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_SC1 clock */
200 MXC_SYS_PERIPH_CLOCK_NFC =
201 (MXC_F_GCR_PCLKDIS1_NFC_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_NFC clock */
202 MXC_SYS_PERIPH_CLOCK_EMAC =
203 (MXC_F_GCR_PCLKDIS1_EMAC_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_EMAC clock */
204 MXC_SYS_PERIPH_CLOCK_HA1 =
205 (MXC_F_GCR_PCLKDIS1_HA1_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_HA1 clock */
206 MXC_SYS_PERIPH_CLOCK_PCIF =
207 (MXC_F_GCR_PCLKDIS1_PCIF_POS + 32), /**<Disable MXC_F_GCR_PCLKDIS1_PCIF clock */
208 } mxc_sys_periph_clock_t;
209
210 /** @brief Enumeration to select System Clock source */
211 typedef enum {
212 MXC_SYS_CLOCK_IPO =
213 MXC_V_GCR_CLKCTRL_SYSCLK_SEL_IPO, /**< Select the Internal Primary Oscillator (IPO) */
214 MXC_SYS_CLOCK_IBRO =
215 MXC_V_GCR_CLKCTRL_SYSCLK_SEL_IBRO, /**< Select the Internal Baud Rate Oscillator (IBRO) */
216 MXC_SYS_CLOCK_ISO =
217 MXC_V_GCR_CLKCTRL_SYSCLK_SEL_ISO, /**< Select the Internal Secondary Oscillator (ISO) */
218 MXC_SYS_CLOCK_ERFO =
219 MXC_V_GCR_CLKCTRL_SYSCLK_SEL_ERFO, /**< Select the External RF Crystal Oscillator */
220 MXC_SYS_CLOCK_INRO =
221 MXC_V_GCR_CLKCTRL_SYSCLK_SEL_INRO, /**< Select the Internal Nanoring Oscillator (INRO) */
222 MXC_SYS_CLOCK_ERTCO =
223 MXC_V_GCR_CLKCTRL_SYSCLK_SEL_ERTCO, /**< Select the External RTC Crystal Oscillator */
224 } mxc_sys_system_clock_t;
225
226 typedef enum {
227 MXC_SYS_CLOCK_DIV_1 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV1,
228 MXC_SYS_CLOCK_DIV_2 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV2,
229 MXC_SYS_CLOCK_DIV_4 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV4,
230 MXC_SYS_CLOCK_DIV_8 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV8,
231 MXC_SYS_CLOCK_DIV_16 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV16,
232 MXC_SYS_CLOCK_DIV_32 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV32,
233 MXC_SYS_CLOCK_DIV_64 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV64,
234 MXC_SYS_CLOCK_DIV_128 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV128
235 } mxc_sys_system_clock_div_t;
236
237 #define MXC_SYS_SCACHE_CLK 1 // Enable SCACHE CLK
238 #define MXC_SYS_CTB_CLK 1 // Enable CTB CLK
239
240 /***** Function Prototypes *****/
241
242 typedef struct {
243 int ie_status;
244 int in_critical;
245 } mxc_crit_state_t;
246
247 static mxc_crit_state_t _state = { .ie_status = (int)0xFFFFFFFF, .in_critical = 0 };
248
_mxc_crit_get_state(void)249 static inline void _mxc_crit_get_state(void)
250 {
251 #ifndef __riscv
252 /*
253 On ARM M the 0th bit of the Priority Mask register indicates
254 whether interrupts are enabled or not.
255
256 0 = enabled
257 1 = disabled
258 */
259 uint32_t primask = __get_PRIMASK();
260 _state.ie_status = (primask == 0);
261 #else
262 /*
263 On RISC-V bit position 3 (Machine Interrupt Enable) of the
264 mstatus register indicates whether interrupts are enabled.
265
266 0 = disabled
267 1 = enabled
268 */
269 uint32_t mstatus = get_mstatus();
270 _state.ie_status = ((mstatus & (1 << 3)) != 0);
271 #endif
272 }
273
274 /**
275 * @brief Enter a critical section of code that cannot be interrupted. Call @ref MXC_SYS_Crit_Exit to exit the critical section.
276 * @details Ex:
277 * @code
278 * MXC_SYS_Crit_Enter();
279 * printf("Hello critical section!\n");
280 * MXC_SYS_Crit_Exit();
281 * @endcode
282 * The @ref MXC_CRITICAL macro is also provided as a convencience macro for wrapping a code section in this way.
283 * @returns None
284 */
MXC_SYS_Crit_Enter(void)285 static inline void MXC_SYS_Crit_Enter(void)
286 {
287 _mxc_crit_get_state();
288 if (_state.ie_status)
289 __disable_irq();
290 _state.in_critical = 1;
291 }
292
293 /**
294 * @brief Exit a critical section of code from @ref MXC_SYS_Crit_Enter
295 * @returns None
296 */
MXC_SYS_Crit_Exit(void)297 static inline void MXC_SYS_Crit_Exit(void)
298 {
299 if (_state.ie_status) {
300 __enable_irq();
301 }
302 _state.in_critical = 0;
303 _mxc_crit_get_state();
304 /*
305 ^ Reset the state again to prevent edge case
306 where interrupts get disabled, then Crit_Exit() gets
307 called, which would inadvertently re-enable interrupts
308 from old state.
309 */
310 }
311
312 /**
313 * @brief Polls whether code is currently executing from a critical section.
314 * @returns 1 if code is currently in a critical section (interrupts are disabled).
315 * 0 if code is not in a critical section.
316 */
MXC_SYS_In_Crit_Section(void)317 static inline int MXC_SYS_In_Crit_Section(void)
318 {
319 return _state.in_critical;
320 }
321
322 // clang-format off
323 /**
324 * @brief Macro for wrapping a section of code to make it critical (interrupts disabled). Note: this macro
325 * does not support nesting.
326 * @details
327 * Ex:
328 * \code
329 * MXC_CRITICAL(
330 * printf("Hello critical section!\n");
331 * )
332 * \endcode
333 * This macro places a call to @ref MXC_SYS_Crit_Enter before the code, and a call to @ref MXC_SYS_Crit_Exit after.
334 * @param code The code section to wrap.
335 */
336 #define MXC_CRITICAL(code) {\
337 MXC_SYS_Crit_Enter();\
338 code;\
339 MXC_SYS_Crit_Exit();\
340 }
341 // clang-format on
342
343 /**
344 * @brief Determines if the selected peripheral clock is enabled.
345 * @param clock Enumeration for desired clock.
346 * @returns 0 is the clock is disabled, non 0 if the clock is enabled.
347 */
348 int MXC_SYS_IsClockEnabled(mxc_sys_periph_clock_t clock);
349
350 /**
351 * @brief Disables the selected peripheral clock.
352 * @param clock Enumeration for desired clock.
353 */
354 void MXC_SYS_ClockDisable(mxc_sys_periph_clock_t clock);
355
356 /**
357 * @brief Enables the selected peripheral clock.
358 * @param clock Enumeration for desired clock.
359 */
360 void MXC_SYS_ClockEnable(mxc_sys_periph_clock_t clock);
361
362 /**
363 * @brief Enables the 32kHz oscillator
364 * @param mxc_sys_cfg Not used, may be NULL.
365 */
366 void MXC_SYS_RTCClockEnable(void);
367
368 /**
369 * @brief Disables the 32kHz oscillator
370 * @returns E_NO_ERROR if everything is successful
371 */
372 int MXC_SYS_RTCClockDisable(void);
373
374 /**
375 * @brief Enable System Clock Source without switching to it
376 * @param clock The clock to enable
377 * @return E_NO_ERROR if everything is successful
378 */
379 int MXC_SYS_ClockSourceEnable(mxc_sys_system_clock_t clock);
380
381 /**
382 * @brief Disable System Clock Source
383 * @param clock The clock to disable
384 * @return E_NO_ERROR if everything is successful
385 */
386 int MXC_SYS_ClockSourceDisable(mxc_sys_system_clock_t clock);
387
388 /**
389 * @brief Select the system clock.
390 * @param clock Enumeration for desired clock.
391 * @returns E_NO_ERROR if everything is successful.
392 */
393 int MXC_SYS_Clock_Select(mxc_sys_system_clock_t clock);
394
395 /**
396 * @brief Set the system clock divider.
397 * @param div Enumeration for desired clock divider.
398 */
399 void MXC_SYS_SetClockDiv(mxc_sys_system_clock_div_t div);
400
401 /**
402 * @brief Get the system clock divider.
403 * @returns System clock divider.
404 */
405 mxc_sys_system_clock_div_t MXC_SYS_GetClockDiv(void);
406
407 /**
408 * @brief Wait for a clock to enable with timeout
409 * @param ready The clock to wait for
410 * @return E_NO_ERROR if ready, E_TIME_OUT if timeout
411 */
412 int MXC_SYS_Clock_Timeout(uint32_t ready);
413
414 /**
415 * @brief Reset the peripherals and/or CPU in the RST0 or RST1 register.
416 * @param Enumeration for what to reset. Can reset multiple items at once.
417 */
418 void MXC_SYS_Reset_Periph(mxc_sys_reset_t reset);
419
420 /**
421 * @brief Get the revision of the chip
422 * @returns the chip revision
423 */
424 uint8_t MXC_SYS_GetRev(void);
425
426 /**
427 * @brief Get the USN of the chip
428 * @param serialNumber buffer to store the USN
429 * @param len length of the USN buffer
430 * @returns #E_NO_ERROR if everything is successful.
431 */
432 int MXC_SYS_GetUSN(uint8_t *serialNumber, int len);
433
434 /**
435 * @brief This function PERMANENTLY locks the Debug Access Port.
436 *
437 * @warning After executing this function you will never be able
438 * to reprogram the target micro.
439 */
440 int MXC_SYS_LockDAP_Permanent(void);
441
442 #ifdef __cplusplus
443 }
444 #endif
445
446 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_MXC_SYS_H_
447