1 /**************************************************************************//**
2  * @file     scu.h
3  * @version  V3.00
4  * @brief    Secure Configuration Unit Driver Header
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 #ifndef __SCU_H__
10 #define __SCU_H__
11 
12 #ifdef __cplusplus
13 extern "C"
14 {
15 #endif
16 
17 
18 /** @addtogroup Standard_Driver Standard Driver
19   @{
20 */
21 
22 /** @addtogroup SCU_Driver SCU Driver
23   @{
24 */
25 
26 /** @addtogroup SCU_EXPORTED_CONSTANTS SCU Exported Constants
27   @{
28 */
29 
30 
31 
32 
33 /**
34  * @details  Non-secure Attribution Definition.
35  */
36 typedef enum NSATTR
37 {
38     /******  PNNSET0 **********************************************************************************/
39     USBH_Attr   =     9,
40     SDH0_Attr   =    13,
41     EBI_Attr    =    16,
42     PDMA1_Attr  =    24,
43 
44     /******  PNNSET1 **********************************************************************************/
45     CRC_Attr    = 32 + 17,
46     CRPT_Attr   = 32 + 18,
47 
48     /******  PNNSET2 **********************************************************************************/
49     EWDT_Attr   = 64 + 2,
50     EADC_Attr   = 64 + 3,
51     ACMP01_Attr = 64 + 5,
52     DAC_Attr    = 64 + 7,
53     I2S0_Attr   = 64 + 8,
54     OTG_Attr    = 64 + 13,
55     TMR23_Attr  = 64 + 17,
56     TMR45_Attr  = 64 + 18,
57     EPWM0_Attr  = 64 + 24,
58     EPWM1_Attr  = 64 + 25,
59     BPWM0_Attr  = 64 + 26,
60     BPWM1_Attr  = 64 + 27,
61     /******  PNNSET3 **********************************************************************************/
62     QSPI0_Attr  = 96 + 0,
63     SPI0_Attr   = 96 + 1,
64     SPI1_Attr   = 96 + 2,
65     SPI2_Attr   = 96 + 3,
66     SPI3_Attr   = 96 + 4,
67     UART0_Attr  = 96 + 16,
68     UART1_Attr  = 96 + 17,
69     UART2_Attr  = 96 + 18,
70     UART3_Attr  = 96 + 19,
71     UART4_Attr  = 96 + 20,
72     UART5_Attr  = 96 + 21,
73     /******  PNNSET4 **********************************************************************************/
74     I2C0_Attr   = 128 + 0,
75     I2C1_Attr   = 128 + 1,
76     I2C2_Attr   = 128 + 2,
77     SC0_Attr    = 128 + 16,
78     SC1_Attr    = 128 + 17,
79     SC2_Attr    = 128 + 18,
80 
81 
82     /******  PNNSET5 **********************************************************************************/
83     CAN0_Attr   = 160 + 0,
84     QEI0_Attr   = 160 + 16,
85     QEI1_Attr   = 160 + 17,
86     ECAP0_Attr  = 160 + 20,
87     ECAP1_Attr  = 160 + 21,
88     TRNG_Attr   = 160 + 25,
89     LCD_Attr    = 160 + 27,
90 
91     /******  PNNSET6 **********************************************************************************/
92     USBD_Attr   = 192 + 0,
93     USCI0_Attr  = 192 + 16,
94     USCI1_Attr  = 192 + 17
95 
96 
97 } NSATTR_T;
98 
99 
100 /**@}*/ /* end of group SCU_EXPORTED_CONSTANTS */
101 
102 
103 /** @addtogroup SCU_EXPORTED_FUNCTIONS SCU Exported Functions
104   @{
105 */
106 
107 /**
108   * @brief      Set peripheral non-secure attribution
109   *
110   * @param[in]  nsattr     The secure/non-secure attribution of specified module.
111                            The possible value could be refer to \ref NSATTR.
112   *
113   * @return     None
114   *
115   * @details    This macro is used to set a peripheral to be non-secure peripheral.
116   *
117   */
118 #define SCU_SET_PNSSET(nsattr)   { SCU->PNSSET[(nsattr)/32] |= (1 << ((nsattr) & 0x1ful)); }
119 
120 /**
121  * @brief       Get peripheral secure/non-secure attribution
122  *
123   * @param[in]  nsattr     The secure/non-secure attribution of specified module.
124                            The possible value could be refer to \ref NSATTR.
125  *
126  * @return      The secure/non-secure attribution of specified peripheral.
127  * @retval      0 The peripheral is secure
128  * @retval      1 The peripheral is non-secure
129  *
130  * @details     This macro gets the peripheral secure/non-secure attribution.
131  */
132 #define SCU_GET_PNSSET(nsattr)   ((SCU->PNSSET[(nsattr)/32] >> ((nsattr) & 0x1ful)) & 1ul)
133 
134 
135 /**
136  * @brief       Set secure/non-secure attribution of specified GPIO pin
137  *
138  * @param[in]   port        GPIO Port. It could be PA, PB, PC, PD, PE, PF, PG and PH.
139  * @param[in]   bitmask     Bit mask of each bit. 0 is secure. 1 is non-secure.
140  *
141  * @return      None
142  *
143  * @details     This macro sets GPIO pin secure/non-secure attribution.
144  */
145 #define SCU_SET_IONSSET(port, mask)   (SCU->IONSSET[((uint32_t)(port)-(GPIOA_BASE))/0x40] = (mask))
146 
147 
148 /**
149  * @brief       Get secure/non-secure attribution of specified GPIO port
150  *
151  * @param[in]   port        GPIO Port. It could be PA, PB, PC, PD, PE, PF, PG and PH.
152  *
153  * @return      The secure/non-secure attribution of the port.
154  * @retval      0 The relative bit of specified IO port is secure
155  * @retval      1 The relative bit of specified IO port is non-secure
156  *
157  * @details     This macro gets IO secure/non-secure attribution of specified IO port.
158  */
159 #define SCU_GET_IONSSET(port)   (SCU->IONSSET[((uint32_t)(port) - (GPIOA_BASE))/0x40])
160 
161 
162 /**
163  * @brief       Enable sercure violation interrupts
164  *
165  * @param[in]   mask    The mask of each secure violation interrupt source
166  *              - \ref SCU_SVIOIEN_APB0IEN_Msk
167  *              - \ref SCU_SVIOIEN_APB1IEN_Msk
168  *              - \ref SCU_SVIOIEN_GPIOIEN_Msk
169  *              - \ref SCU_SVIOIEN_EBIIEN_Msk
170  *              - \ref SCU_SVIOIEN_USBHIEN_Msk
171  *              - \ref SCU_SVIOIEN_CRCIEN_Msk
172  *              - \ref SCU_SVIOIEN_SDH0IEN_Msk
173  *              - \ref SCU_SVIOIEN_PDMA0IEN_Msk
174  *              - \ref SCU_SVIOIEN_PDMA1IEN_Msk
175  *              - \ref SCU_SVIOIEN_SRAM0IEN_Msk
176  *              - \ref SCU_SVIOIEN_SRAM1IEN_Msk
177  *              - \ref SCU_SVIOIEN_FMCIEN_Msk
178  *              - \ref SCU_SVIOIEN_FLASHIEN_Msk
179  *              - \ref SCU_SVIOIEN_SCUIEN_Msk
180  *              - \ref SCU_SVIOIEN_SYSIEN_Msk
181  *              - \ref SCU_SVIOIEN_CRPTIEN_Msk
182  *
183  * @return      None
184  *
185  * @details     This macro is used to enable secure violation interrupt of SCU.
186  *              The secure violation interrupt could be used to detect attack of secure elements.
187  */
188 #define SCU_ENABLE_INT(mask)    (SCU->SVIOIEN |= (mask))
189 
190 
191 /**
192  * @brief       Disable sercure violation interrupts
193  *
194  * @param[in]   mask    The mask of each secure violation interrupt source
195  *              - \ref SCU_SVIOIEN_APB0IEN_Msk
196  *              - \ref SCU_SVIOIEN_APB1IEN_Msk
197  *              - \ref SCU_SVIOIEN_GPIOIEN_Msk
198  *              - \ref SCU_SVIOIEN_EBIIEN_Msk
199  *              - \ref SCU_SVIOIEN_USBHIEN_Msk
200  *              - \ref SCU_SVIOIEN_CRCIEN_Msk
201  *              - \ref SCU_SVIOIEN_SDH0IEN_Msk
202  *              - \ref SCU_SVIOIEN_PDMA0IEN_Msk
203  *              - \ref SCU_SVIOIEN_PDMA1IEN_Msk
204  *              - \ref SCU_SVIOIEN_SRAM0IEN_Msk
205  *              - \ref SCU_SVIOIEN_SRAM1IEN_Msk
206  *              - \ref SCU_SVIOIEN_FMCIEN_Msk
207  *              - \ref SCU_SVIOIEN_FLASHIEN_Msk
208  *              - \ref SCU_SVIOIEN_SCUIEN_Msk
209  *              - \ref SCU_SVIOIEN_SYSIEN_Msk
210  *              - \ref SCU_SVIOIEN_CRPTIEN_Msk
211  *
212  * @return      None
213  *
214  * @details     This macro is used to disable secure violation interrupt of SCU.
215  *
216  */
217 #define SCU_DISABLE_INT(mask)    (SCU->SVIOIEN &= (~(mask)))
218 
219 
220 /**
221   * @brief    Get secure violation interrupt status
222   *
223   * @param    mask  The interrupt flag mask bit
224   *
225   * @return   The value of SCU_SVINTSTS register
226   *
227   * @details  Return interrupt flag of SCU_SVINTSTS register.
228   *
229   */
230 #define SCU_GET_INT_FLAG(mask)         (SCU->SVINTSTS&(mask))
231 
232 /**
233   * @brief      Clear secure violation interrupt flag
234   *
235   * @param[in]  flag The combination of the specified interrupt flags.
236   *             Each bit corresponds to a interrupt source.
237   *             This parameter decides which interrupt flags will be cleared.
238   *             - \ref SCU_SVINTSTS_APB0IF_Msk
239   *             - \ref SCU_SVINTSTS_APB1IF_Msk
240   *             - \ref SCU_SVINTSTS_GPIOIF_Msk
241   *             - \ref SCU_SVINTSTS_EBIIF_Msk
242   *             - \ref SCU_SVINTSTS_USBHIF_Msk
243   *             - \ref SCU_SVINTSTS_CRCIF_Msk
244   *             - \ref SCU_SVINTSTS_SDH0IF_Msk
245   *             - \ref SCU_SVINTSTS_PDMA0IF_Msk
246   *             - \ref SCU_SVINTSTS_PDMA1IF_Msk
247   *             - \ref SCU_SVINTSTS_SRAM0IF_Msk
248   *             - \ref SCU_SVINTSTS_SRAM1IF_Msk
249   *             - \ref SCU_SVINTSTS_FMCIF_Msk
250   *             - \ref SCU_SVINTSTS_FLASHIF_Msk
251   *             - \ref SCU_SVINTSTS_SCUIF_Msk
252   *             - \ref SCU_SVINTSTS_SYSIF_Msk
253   *             - \ref SCU_SVINTSTS_CRPTIF_Msk
254   *
255   * @return     None
256   *
257   * @details    Clear SCU related interrupt flags specified by flag parameter.
258   *
259   */
260 #define SCU_CLR_INT_FLAG(flag)     (SCU->SVINTSTS = (flag))
261 
262 
263 
264 /**
265   * @brief      Control the behavior of non-secure monitor when CPU is in idle state.
266   *
267   * @param[in]  opt Option for behavior control of non-secure monitor when CPU in idle.
268   *              - true     The counter keeps counting when CPU is in idle.
269                  - false    The counter will stop when CPU is in idle.
270   *
271   * @return     None
272   *
273   * @details    To control non-secure monitor counter when CPU is in idle.
274   *
275   */
276 #define SCU_NSM_IDLE_ON(opt)    ((opt)?(SCU->NSMCTL |= SCU_NSMCTL_IDLEON_Msk):(SCU->NSMCTL &= ~SCU_NSMCTL_IDLEON_Msk))
277 
278 /**
279   * @brief      Control the behavior of non-secure monitor when CPU is in debug state.
280   *
281   * @param[in]  opt Option for behavior control of non-secure monitor when CPU in debug.
282   *              - true     The counter keeps counting when CPU is in debug.
283                  - false    The counter will stop when CPU is in debug.
284   *
285   * @return     None
286   *
287   * @details    To control non-secure monitor counter when CPU is in debug.
288   *
289   */
290 #define SCU_NSM_DBG_ON(opt)    ((opt)?(SCU->NSMCTL |= SCU_NSMCTL_DBGON_Msk):(SCU->NSMCTL &= ~SCU_NSMCTL_DBGON_Msk))
291 
292 
293 /* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
294 __STATIC_INLINE void SCU_NSMConfig(uint32_t u32Ticks, uint32_t u32Prescale);
295 __STATIC_INLINE void SCU_TimerConfig(uint32_t u32Ticks, uint32_t u32Prescale);
296 
297 
298 /**
299   * @brief      Config non-secure monitor to detect timeout in non-secure state.
300   *
301   * @param[in]  u32Ticks       A specified period for timeout in non-secure state
302   * @param[in]  u32Prescale    A pre-scale divider to non-secure monitor clock
303 
304   *
305   * @return     None
306   *
307   * @details    This function is used to configure non-secure monitor. If the CPU state stay in non-secure state for
308   *             a specified period. The non-secure monitor will timeout and assert an interrupt. Otherwise, the
309   *             non-secure monitor will auto clear whenever returning to secure state. This could be used to avoid
310   *             CPU state in non-secure state too long time for security purpose. User must enable SCU_IRQn if interrupt
311   *             is necessary.
312   *
313   */
SCU_NSMConfig(uint32_t u32Ticks,uint32_t u32Prescale)314 __STATIC_INLINE void SCU_NSMConfig(uint32_t u32Ticks, uint32_t u32Prescale)
315 {
316 
317     SCU->NSMLOAD = u32Ticks;
318     SCU->NSMVAL  = 0ul;
319     SCU->NSMCTL  = SCU_NSMCTL_AUTORLD_Msk | SCU_NSMCTL_NSMIEN_Msk | (u32Prescale & 0xfful);
320 }
321 
322 
323 /**
324   * @brief      Config non-secure monitor to be a timer.
325   *
326   * @param[in]  u32Ticks       A specified period for timer interrupt.
327   * @param[in]  u32Prescale    A pre-scale divider to timer clock source.
328 
329   *
330   * @return     None
331   *
332   * @details    This function is used to configure non-secure monitor as a timer. In other words, the timer counter
333   *             keeps counting even CPU is in secure state.
334   *
335   */
SCU_TimerConfig(uint32_t u32Ticks,uint32_t u32Prescale)336 __STATIC_INLINE void SCU_TimerConfig(uint32_t u32Ticks, uint32_t u32Prescale)
337 {
338 
339     SCU->NSMLOAD = u32Ticks;
340     SCU->NSMVAL  = 0ul;
341     SCU->NSMCTL  = SCU_NSMCTL_AUTORLD_Msk | SCU_NSMCTL_NSMIEN_Msk | SCU_NSMCTL_TMRMOD_Msk | (u32Prescale & 0xfful);
342 }
343 
344 
345 
346 
347 /**@}*/ /* end of group SCU_EXPORTED_FUNCTIONS */
348 
349 /**@}*/ /* end of group SCU_Driver */
350 
351 /**@}*/ /* end of group Standard_Driver */
352 
353 #ifdef __cplusplus
354 }
355 #endif
356 
357 #endif /* __SCU_H__ */
358