system_M2351.c
17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
/**************************************************************************//**
* @file system_M2351.c
* @version V2.00
* @brief System Setting Source File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler 6 */
#include <arm_cmse.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include "NuMicro.h"
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#include "partition_M2351.h"
extern void SCU_IRQHandler(void);
void TZ_SAU_Setup(void);
#else
extern void SCU_IRQHandler(void)__attribute__((noreturn));
#endif
extern void *__Vectors; /* see startup file */
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Core Clock) */
uint32_t CyclesPerUs = (__HSI / 1000000UL);/*!< Cycles per micro second */
uint32_t PllClock = __HSI; /*!< PLL Output Clock Frequency */
//const uint32_t gau32ClkSrcTbl[] = {__HXT, __LXT, 0UL, __LIRC, 0UL, __HIRC48, 0UL, __HIRC};
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
void FMC_NSBA_Setup(void);
void SCU_Setup(void);
void NSC_Init(void);
/**
* @brief Setup Non-secure boundary
*
* @param None
*
* @return None
*
* @details This function is used to set Non-secure boundary according to
* the configuration of partition header file
*/
void FMC_NSBA_Setup(void)
{
/* Skip NSBA Setupt according config */
if(FMC_INIT_NSBA == 0)
return;
/* Check if NSBA value with current active NSBA */
if(SCU->FNSADDR != FMC_SECURE_ROM_SIZE)
{
/* Unlock Protected Register */
SYS_UnlockReg();
/* Enable ISP and config update */
FMC->ISPCTL = FMC_ISPCTL_ISPEN_Msk | FMC_ISPCTL_CFGUEN_Msk;
/* Config Base of NSBA */
FMC->ISPADDR = FMC_NSCBA_BASE ;
/* Read Non-secure base address config */
FMC->ISPCMD = FMC_ISPCMD_READ;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while(FMC->ISPTRG);
/* Setting NSBA when it is empty */
if(FMC->ISPDAT == 0xfffffffful)
{
/* Set new base */
FMC->ISPDAT = FMC_SECURE_ROM_SIZE;
FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while(FMC->ISPTRG);
/* Verify new base */
FMC->ISPDAT = 0;
FMC->ISPCMD = FMC_ISPCMD_READ;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while(FMC->ISPTRG);
if(FMC->ISPDAT == FMC_SECURE_ROM_SIZE)
{
/* Force Chip Reset to valid new setting */
SYS->IPRST0 = SYS_IPRST0_CHIPRST_Msk;
}
}
}
}
/**
\brief Setup SCU Configuration Unit
\details
*/
void SCU_Setup(void)
{
int32_t i;
SCU->PNSSET[0] = SCU_INIT_PNSSET0_VAL;
SCU->PNSSET[1] = SCU_INIT_PNSSET1_VAL;
SCU->PNSSET[2] = SCU_INIT_PNSSET2_VAL;
SCU->PNSSET[3] = SCU_INIT_PNSSET3_VAL;
SCU->PNSSET[4] = SCU_INIT_PNSSET4_VAL;
SCU->PNSSET[5] = SCU_INIT_PNSSET5_VAL;
SCU->PNSSET[6] = SCU_INIT_PNSSET6_VAL;
SCU->IONSSET = SCU_INIT_IONSSET_VAL;
/* Set Non-secure SRAM */
for(i = 11; i >= SCU_SECURE_SRAM_SIZE / 8192; i--)
{
SCU->SRAMNSSET |= (1U << i);
}
/* Set interrupt to non-secure according to PNNSET settings */
if(SCU_INIT_PNSSET0_VAL & BIT9 ) NVIC->ITNS[1] |= BIT22; /* Int of USBH_INT */
if(SCU_INIT_PNSSET0_VAL & BIT13) NVIC->ITNS[2] |= BIT0 ; /* Int of SDHOST0_INT */
if(SCU_INIT_PNSSET0_VAL & BIT24) NVIC->ITNS[3] |= BIT2 ; /* Int of PDMA1_INT */
if(SCU_INIT_PNSSET1_VAL & BIT18) NVIC->ITNS[2] |= BIT7 ; /* Int of CRYPTO */
if(SCU_INIT_PNSSET2_VAL & BIT2 ) NVIC->ITNS[3] |= BIT15; /* Int of EWDT_INT */
if(SCU_INIT_PNSSET2_VAL & BIT2 ) NVIC->ITNS[3] |= BIT16; /* Int of EWWDT_INT */
if(SCU_INIT_PNSSET2_VAL & BIT3 ) NVIC->ITNS[1] |= BIT10; /* Int of EADC0_INT */
if(SCU_INIT_PNSSET2_VAL & BIT3 ) NVIC->ITNS[1] |= BIT11; /* Int of EADC1_INT */
if(SCU_INIT_PNSSET2_VAL & BIT3 ) NVIC->ITNS[1] |= BIT14; /* Int of EADC2_INT */
if(SCU_INIT_PNSSET2_VAL & BIT3 ) NVIC->ITNS[1] |= BIT15; /* Int of EADC3_INT */
if(SCU_INIT_PNSSET2_VAL & BIT5 ) NVIC->ITNS[1] |= BIT12; /* Int of ACMP01_INT */
if(SCU_INIT_PNSSET2_VAL & BIT7 ) NVIC->ITNS[1] |= BIT9 ; /* Int of DAC_INT */
if(SCU_INIT_PNSSET2_VAL & BIT8 ) NVIC->ITNS[2] |= BIT4 ; /* Int of I2S0_INT */
if(SCU_INIT_PNSSET2_VAL & BIT13) NVIC->ITNS[1] |= BIT23; /* Int of USBOTG_INT */
if(SCU_INIT_PNSSET2_VAL & BIT17) NVIC->ITNS[1] |= BIT2 ; /* Int of TMR2_INT */
if(SCU_INIT_PNSSET2_VAL & BIT17) NVIC->ITNS[1] |= BIT3 ; /* Int of TMR3_INT */
if(SCU_INIT_PNSSET2_VAL & BIT24) NVIC->ITNS[0] |= BIT25; /* Int of EPWM0_P0_INT */
if(SCU_INIT_PNSSET2_VAL & BIT24) NVIC->ITNS[0] |= BIT26; /* Int of EPWM0_P1_INT */
if(SCU_INIT_PNSSET2_VAL & BIT24) NVIC->ITNS[0] |= BIT27; /* Int of EPWM0_P2_INT */
if(SCU_INIT_PNSSET2_VAL & BIT25) NVIC->ITNS[0] |= BIT29; /* Int of EPWM1_P0_INT */
if(SCU_INIT_PNSSET2_VAL & BIT25) NVIC->ITNS[0] |= BIT30; /* Int of EPWM1_P1_INT */
if(SCU_INIT_PNSSET2_VAL & BIT25) NVIC->ITNS[0] |= BIT31; /* Int of EPWM1_P2_INT */
if(SCU_INIT_PNSSET2_VAL & BIT26) NVIC->ITNS[2] |= BIT14; /* Int of BPWM0_INT */
if(SCU_INIT_PNSSET2_VAL & BIT27) NVIC->ITNS[2] |= BIT15; /* Int of BPWM1_INT */
if(SCU_INIT_PNSSET3_VAL & BIT0 ) NVIC->ITNS[0] |= BIT22; /* Int of QSPI0_INT */
if(SCU_INIT_PNSSET3_VAL & BIT1 ) NVIC->ITNS[0] |= BIT23; /* Int of SPI0_INT */
if(SCU_INIT_PNSSET3_VAL & BIT2 ) NVIC->ITNS[1] |= BIT19; /* Int of SPI1_INT */
if(SCU_INIT_PNSSET3_VAL & BIT3 ) NVIC->ITNS[1] |= BIT20; /* Int of SPI2_INT */
if(SCU_INIT_PNSSET3_VAL & BIT4 ) NVIC->ITNS[1] |= BIT30; /* Int of SPI3_INT */
if(SCU_INIT_PNSSET3_VAL & BIT16) NVIC->ITNS[1] |= BIT4 ; /* Int of UART0_INT */
if(SCU_INIT_PNSSET3_VAL & BIT17) NVIC->ITNS[1] |= BIT5 ; /* Int of UART1_INT */
if(SCU_INIT_PNSSET3_VAL & BIT18) NVIC->ITNS[1] |= BIT16; /* Int of UART2_INT */
if(SCU_INIT_PNSSET3_VAL & BIT19) NVIC->ITNS[1] |= BIT17; /* Int of UART3_INT */
if(SCU_INIT_PNSSET3_VAL & BIT20) NVIC->ITNS[2] |= BIT10; /* Int of UART4_INT */
if(SCU_INIT_PNSSET3_VAL & BIT21) NVIC->ITNS[2] |= BIT11; /* Int of UART5_INT */
if(SCU_INIT_PNSSET4_VAL & BIT0 ) NVIC->ITNS[1] |= BIT6 ; /* Int of I2C0_INT */
if(SCU_INIT_PNSSET4_VAL & BIT1 ) NVIC->ITNS[1] |= BIT7 ; /* Int of I2C1_INT */
if(SCU_INIT_PNSSET4_VAL & BIT2 ) NVIC->ITNS[2] |= BIT18; /* Int of I2C2_INT */
if(SCU_INIT_PNSSET4_VAL & BIT16) NVIC->ITNS[1] |= BIT26; /* Int of SC0_INT */
if(SCU_INIT_PNSSET4_VAL & BIT17) NVIC->ITNS[1] |= BIT27; /* Int of SC1_INT */
if(SCU_INIT_PNSSET4_VAL & BIT18) NVIC->ITNS[1] |= BIT28; /* Int of SC2_INT */
if(SCU_INIT_PNSSET5_VAL & BIT0 ) NVIC->ITNS[1] |= BIT24; /* Int of CAN0_INT */
if(SCU_INIT_PNSSET5_VAL & BIT16) NVIC->ITNS[2] |= BIT20; /* Int of QEI0_INT */
if(SCU_INIT_PNSSET5_VAL & BIT17) NVIC->ITNS[2] |= BIT21; /* Int of QEI1_INT */
if(SCU_INIT_PNSSET5_VAL & BIT20) NVIC->ITNS[2] |= BIT22; /* Int of ECAP0_INT */
if(SCU_INIT_PNSSET5_VAL & BIT21) NVIC->ITNS[2] |= BIT23; /* Int of ECAP1_INT */
if(SCU_INIT_PNSSET5_VAL & BIT25) NVIC->ITNS[3] |= BIT5 ; /* Int of TRNG_INT */
if(SCU_INIT_PNSSET5_VAL & BIT27) NVIC->ITNS[3] |= BIT4 ; /* Int of LCD_INT */
if(SCU_INIT_PNSSET5_VAL & BIT29) NVIC->ITNS[3] |= BIT14; /* Int of TAMPER_INT */
if(SCU_INIT_PNSSET6_VAL & BIT0 ) NVIC->ITNS[1] |= BIT21; /* Int of USBD_INT */
if(SCU_INIT_PNSSET6_VAL & BIT16) NVIC->ITNS[2] |= BIT12; /* Int of USCI0_INT */
if(SCU_INIT_PNSSET6_VAL & BIT17) NVIC->ITNS[2] |= BIT13; /* Int of USCI1_INT */
if(SCU_INIT_IONSSET_VAL & BIT0 ) NVIC->ITNS[0] |= BIT16; /* Int of PA */
if(SCU_INIT_IONSSET_VAL & BIT1 ) NVIC->ITNS[0] |= BIT17; /* Int of PB */
if(SCU_INIT_IONSSET_VAL & BIT2 ) NVIC->ITNS[0] |= BIT18; /* Int of PC */
if(SCU_INIT_IONSSET_VAL & BIT3 ) NVIC->ITNS[0] |= BIT19; /* Int of PD */
if(SCU_INIT_IONSSET_VAL & BIT4 ) NVIC->ITNS[0] |= BIT20; /* Int of PE */
if(SCU_INIT_IONSSET_VAL & BIT5 ) NVIC->ITNS[0] |= BIT21; /* Int of PF */
if(SCU_INIT_IONSSET_VAL & BIT6 ) NVIC->ITNS[2] |= BIT8 ; /* Int of PG */
if(SCU_INIT_IONSSET_VAL & BIT7 ) NVIC->ITNS[2] |= BIT24; /* Int of PH */
/* Enable SCU Int status */
SCU->SVIOIEN = (uint32_t)-1;
NVIC_EnableIRQ(SCU_IRQn);
}
#if defined( __ICCARM__ )
__WEAK
#else
__attribute__((weak))
#endif
void SCU_IRQHandler(void)
{
char const *master[] = {"CPU", 0, 0, "PDMA0", "SDH0", "CRPT", "USBH", 0,0,0,0,"PDMA1"};
char const *ipname[] = {"APB0","APB1",0,0,"GPIO","EBI","USBH","CRC","SDH0",0,"PDMA0","PDMA1"
,"SRAM0","SRAM1","FMC","FLASH","SCU","SYS","CRPT"};
const uint8_t info[] = {0x34,0x3C,0,0, 0x44,0x4C,0x54,0x5C,0x64,0,0x74,0x7C,0x84,0x8C,0x94,0x9C,0xA4,0xAC,0xB4};
uint32_t u32Reg, u32Addr;
uint32_t i;
/* TrustZone access policy */
u32Reg = SCU->SVINTSTS;
if(u32Reg)
{
/* Get violation address and source */
for(i=0;i< sizeof(ipname);i++)
{
if(u32Reg & (1 << i))
{
u32Addr = M32(SCU_BASE+info[i]+4);
printf(" %s(0x%08x) Alarm! illegal access by %s\n",ipname[i], u32Addr,master[M32(SCU_BASE+info[i])]);
SCU->SVINTSTS = (1 << i);
break;
}
}
}
}
/**
\brief Setup a Nonsecure callable Region
\details The base and limit of Nonsecure callable region is dependent on the
application code size.
*/
void NSC_Init(void)
{
uint32_t u32Region;
uint32_t u32Base, u32Limit;
#if defined (__ICCARM__)
# pragma section = "NSC"
u32Base = (uint32_t)__section_begin("NSC");
u32Limit = (uint32_t)__section_end("NSC");
#elif defined(__ARMCC_VERSION)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
extern uint32_t Image$$NSC_ROM$$XO$$Base[];
extern uint32_t Image$$NSC_ROM$$XO$$Limit[];
u32Base = (uint32_t)Image$$NSC_ROM$$XO$$Base;
u32Limit = (uint32_t)Image$$NSC_ROM$$XO$$Limit;
#pragma clang diagnostic pop
#else
extern uint32_t __start_NSC[];
extern uint32_t __end_NSC[];
u32Base = (uint32_t)__start_NSC;
u32Limit = (uint32_t)__end_NSC;
#endif
/* SAU region 3 is dedicated for NSC */
u32Region = 3;
SAU->RNR = (u32Region & SAU_RNR_REGION_Msk);
SAU->RBAR = (u32Base & SAU_RBAR_BADDR_Msk);
SAU->RLAR = ((u32Limit-1) & SAU_RLAR_LADDR_Msk) |
((1ul << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1ul;
}
/**
\brief Setup a SAU Region
\details Writes the region information contained in SAU_Region to the
registers SAU_RNR, SAU_RBAR, and SAU_RLAR
*/
void TZ_SAU_Setup(void)
{
#if defined (__SAU_PRESENT) && (__SAU_PRESENT == 1U)
#if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U)
SAU_INIT_REGION(0);
#endif
#if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U)
SAU_INIT_REGION(1);
#endif
#if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U)
SAU_INIT_REGION(2);
#endif
#if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U)
SAU_INIT_REGION(3);
#endif
#if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U)
SAU_INIT_REGION(4);
#endif
#if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U)
SAU_INIT_REGION(5);
#endif
#if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U)
SAU_INIT_REGION(6);
#endif
#if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U)
SAU_INIT_REGION(7);
#endif
/* repeat this for all possible SAU regions */
#if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U)
SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) |
((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ;
#endif
#endif /* defined (__SAU_PRESENT) && (__SAU_PRESENT == 1U) */
#if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U)
SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk)) |
((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk);
SCB->AIRCR = (0x05FA << 16) |
((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) |
((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk) |
((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk);
#endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */
#if defined (SCB_ICSR_INIT) && (SCB_ICSR_INIT == 1U)
SCB->ICSR = (SCB->ICSR & ~(SCB_ICSR_STTNS_Msk)) |
((SCB_ICSR_STTNS_VAL << SCB_ICSR_STTNS_Pos) & SCB_ICSR_STTNS_Msk);
#endif /* defined (SCB_ICSR_INIT) && (SCB_ICSR_INIT == 1U) */
/* repeat this for all possible ITNS elements */
/* Initial Nonsecure callable region */
NSC_Init();
}
#else
void SCU_IRQHandler(void)
{
while(1);
}
#endif
/**
* @brief Update the Variable SystemCoreClock
*
* @param None
*
* @return None
*
* @details This function is used to update the variable SystemCoreClock
* and must be called whenever the core clock is changed.
*/
void SystemCoreClockUpdate(void)
{
/* Update PLL Clock */
PllClock = CLK_GetPLLClockFreq();
/* Update System Core Clock */
SystemCoreClock = CLK_GetCPUFreq();
/* Update Cycles per micro second */
CyclesPerUs = (SystemCoreClock + 500000UL) / 1000000UL;
}
/**
* @brief System Initialization
*
* @param None
*
* @return None
*
* @details The necessary initialization of system. Global variables are forbidden here.
*/
void SystemInit(void)
{
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
SCB->VTOR = (uint32_t) &__Vectors;
#endif
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
TZ_SAU_Setup();
SCU_Setup();
FMC_NSBA_Setup();
#endif
#ifdef INIT_SYSCLK_AT_BOOTING
#endif
}
#if USE_ASSERT
/**
* @brief Assert Error Message
*
* @param[in] file the source file name
* @param[in] line line number
*
* @return None
*
* @details The function prints the source file name and line number where
* the ASSERT_PARAM() error occurs, and then stops in an infinite loop.
*/
void AssertError(uint8_t * file, uint32_t line)
{
printf("[%s] line %d : wrong parameters.\r\n", file, line);
/* Infinite loop */
while(1) ;
}
#endif
#if (defined(__ICCARM__) && (__VER__ >= 7080000) && (__VER__ < 8020000))
#if (__ARM_FEATURE_CMSE == 3U)
/**
\brief Get Process Stack Pointer (non-secure)
\details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
\return PSP Register value
*/
uint32_t __TZ_get_PSP_NS(void)
{
register uint32_t result;
__ASM volatile("MRS %0, psp_ns" : "=r"(result));
return(result);
}
/**
\brief Set Process Stack Pointer (non-secure)
\details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
\param [in] topOfProcStack Process Stack Pointer value to set
*/
void __TZ_set_PSP_NS(uint32_t topOfProcStack)
{
__ASM volatile("MSR psp_ns, %0" : : "r"(topOfProcStack));
}
/**
\brief Get Main Stack Pointer (non-secure)
\details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
\return MSP Register value
*/
int32_t __TZ_get_MSP_NS(void)
{
register uint32_t result;
__ASM volatile("MRS %0, msp_ns" : "=r"(result));
return(result);
}
/**
\brief Set Main Stack Pointer (non-secure)
\details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
\param [in] topOfMainStack Main Stack Pointer value to set
*/
void __TZ_set_MSP_NS(uint32_t topOfMainStack)
{
__ASM volatile("MSR msp_ns, %0" : : "r"(topOfMainStack));
}
/**
\brief Get Priority Mask (non-secure)
\details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
\return Priority Mask value
*/
uint32_t __TZ_get_PRIMASK_NS(void)
{
uint32_t result;
__ASM volatile("MRS %0, primask_ns" : "=r"(result));
return(result);
}
/**
\brief Set Priority Mask (non-secure)
\details Assigns the given value to the non-secure Priority Mask Register when in secure state.
\param [in] priMask Priority Mask
*/
void __TZ_set_PRIMASK_NS(uint32_t priMask)
{
__ASM volatile("MSR primask_ns, %0" : : "r"(priMask) : "memory");
}
#endif
#endif