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