NANO103 BSP V3.01.004
The Board Support Package for Nano103 Series
fmc.c
Go to the documentation of this file.
1/**************************************************************************/
13//* Includes ------------------------------------------------------------------*/
14#include <stdio.h>
15
16#include "Nano103.h"
17
18
27int32_t g_FMC_i32ErrCode = 0;
38void FMC_Close(void)
39{
40 FMC->ISPCTL &= ~FMC_ISPCTL_ISPEN_Msk;
41}
42
51int32_t FMC_Erase(uint32_t u32PageAddr)
52{
53 uint32_t u32TimeOutCnt;
54
56
57 FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
58 FMC->ISPADDR = u32PageAddr;
59 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
60
61 u32TimeOutCnt = FMC_TIMEOUT_ERASE;
62 while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) /* Waiting for ISP Done */
63 {
64 if(--u32TimeOutCnt == 0)
65 {
67 return -1;
68 }
69 }
70
71 if (FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
72 {
73 FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
75 return -1;
76 }
77
78 return 0;
79}
80
87int32_t FMC_GetBootSource (void)
88{
89 if (FMC->ISPCTL & FMC_ISPCTL_BS_Msk)
90 return 1;
91 else
92 return 0;
93}
94
95
100void FMC_Open(void)
101{
102 FMC->ISPCTL |= FMC_ISPCTL_ISPEN_Msk;
103}
104
105
116uint32_t FMC_Read(uint32_t u32Addr)
117{
118 int32_t i32TimeOutCnt;
119
121
122 FMC->ISPCMD = FMC_ISPCMD_READ;
123 FMC->ISPADDR = u32Addr;
124 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
125
126 i32TimeOutCnt = FMC_TIMEOUT_READ;
127 while ((i32TimeOutCnt-- > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk)) {}
128 if (i32TimeOutCnt <= 0)
129 {
130 g_FMC_i32ErrCode = -1;
131 return 0xFFFFFFFF;
132 }
133 return FMC->ISPDAT;
134}
135
136
144uint32_t FMC_ReadCID(void)
145{
146 int32_t i32TimeOutCnt;
147
149
150 FMC->ISPCMD = FMC_ISPCMD_READ_CID;
151 FMC->ISPADDR = 0x0;
152 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
153
154 i32TimeOutCnt = FMC_TIMEOUT_READ;
155 while ((i32TimeOutCnt-- > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk)) {}
156 if (i32TimeOutCnt <= 0)
157 {
158 g_FMC_i32ErrCode = -1;
159 return 0xFFFFFFFF;
160 }
161
162 return FMC->ISPDAT;
163}
164
165
173uint32_t FMC_ReadPID(void)
174{
175 int32_t i32TimeOutCnt;
176
178
179 FMC->ISPCMD = FMC_ISPCMD_READ_PID;
180 FMC->ISPADDR = 0x04;
181 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
182
183 i32TimeOutCnt = FMC_TIMEOUT_READ;
184 while ((i32TimeOutCnt-- > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk)) {}
185 if (i32TimeOutCnt <= 0)
186 {
187 g_FMC_i32ErrCode = -1;
188 return 0xFFFFFFFF;
189 }
190
191 return FMC->ISPDAT;
192}
193
194
203uint32_t FMC_ReadUCID(uint32_t u32Index)
204{
205 int32_t i32TimeOutCnt;
206
208
209 FMC->ISPCMD = FMC_ISPCMD_READ_UID;
210 FMC->ISPADDR = (0x04 * u32Index) + 0x10;
211 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
212
213 i32TimeOutCnt = FMC_TIMEOUT_READ;
214 while ((i32TimeOutCnt-- > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk)) {}
215 if (i32TimeOutCnt <= 0)
216 {
217 g_FMC_i32ErrCode = -1;
218 return 0xFFFFFFFF;
219 }
220
221 return FMC->ISPDAT;
222}
223
224
233uint32_t FMC_ReadUID(uint32_t u32Index)
234{
235 int32_t i32TimeOutCnt;
236
238
239 FMC->ISPCMD = FMC_ISPCMD_READ_UID;
240 FMC->ISPADDR = 0x04 * u32Index;
241 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
242
243 i32TimeOutCnt = FMC_TIMEOUT_READ;
244 while ((i32TimeOutCnt-- > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk)) {}
245 if (i32TimeOutCnt <= 0)
246 {
247 g_FMC_i32ErrCode = -1;
248 return 0xFFFFFFFF;
249 }
250
251 return FMC->ISPDAT;
252}
253
254
260{
261 return FMC->DFBA;
262}
263
264
273void FMC_SetVectorPageAddr(uint32_t u32PageAddr)
274{
275 int32_t i32TimeOutCnt;
276
278
279 FMC->ISPCMD = FMC_ISPCMD_VECMAP;
280 FMC->ISPADDR = u32PageAddr;
281 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
282
283 i32TimeOutCnt = FMC_TIMEOUT_WRITE;
284 while ((i32TimeOutCnt-- > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk)) {}
285 if (i32TimeOutCnt <= 0)
286 g_FMC_i32ErrCode = -1;
287}
288
289
295{
296 return (FMC->ISPSTS & 0x0FFFFF00ul);
297}
298
299
311int32_t FMC_Write(uint32_t u32Addr, uint32_t u32Data)
312{
313 int32_t i32TimeOutCnt;
314
316
317 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
318 FMC->ISPADDR = u32Addr;
319 FMC->ISPDAT = u32Data;
320 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
321
322 i32TimeOutCnt = FMC_TIMEOUT_WRITE;
323 while ((i32TimeOutCnt-- > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk)) {}
324 if (i32TimeOutCnt <= 0)
325 {
326 g_FMC_i32ErrCode = -1;
327 return -1;
328 }
329
330 return 0;
331}
332
333
343int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count)
344{
345 u32Config[0] = FMC_Read(FMC_CONFIG_BASE);
346 if (u32Count < 2)
347 return 0;
348 u32Config[1] = FMC_Read(FMC_CONFIG_BASE+4);
349 return 0;
350}
351
352
362int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count)
363{
366 FMC_Write(FMC_CONFIG_BASE, u32Config[0]);
367 FMC_Write(FMC_CONFIG_BASE+4, u32Config[1]);
369 return 0;
370}
371
372
387int32_t FMC_GetChkSum(uint32_t u32Addr, uint32_t u32Count, uint32_t *u32ChkSum)
388{
389 int32_t i32TimeOutCnt;
390
392
393 if ((u32Addr % 512) || (u32Count % 512))
394 {
395 g_FMC_i32ErrCode = -2;
396 return 0xFFFFFFFF;
397 }
398
399 *u32ChkSum = 0;
400
401 FMC->ISPCMD = FMC_ISPCMD_RUN_CKS;
402 FMC->ISPADDR = u32Addr;
403 FMC->ISPDAT = u32Count;
404 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
405
406 i32TimeOutCnt = FMC_TIMEOUT_CHKSUM;
407 while ((i32TimeOutCnt-- > 0) && (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk)) {}
408 if (i32TimeOutCnt <= 0)
409 {
410 g_FMC_i32ErrCode = -1;
411 return 0xFFFFFFFF;
412 }
413
414 if (FMC_GET_FAIL_FLAG())
415 return -1;
416
417 FMC->ISPCMD = FMC_ISPCMD_READ_CKS;
418 FMC->ISPADDR = u32Addr;
419 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
420
421 i32TimeOutCnt = FMC_TIMEOUT_CHKSUM;
422 while ((i32TimeOutCnt-- > 0) && (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk)) {}
423 if (i32TimeOutCnt <= 0)
424 {
425 g_FMC_i32ErrCode = -1;
426 return 0xFFFFFFFF;
427 }
428
429 if (FMC_GET_FAIL_FLAG())
430 return -1;
431
432 *u32ChkSum = FMC->ISPDAT;
433 return 0;
434}
435
436
448uint32_t FMC_CheckAllOne(uint32_t u32Addr, uint32_t u32Count)
449{
450 int32_t i32TimeOutCnt;
451
453
454 FMC->ISPSTS = 0x80; // clear check alll one bit
455
456 FMC->ISPCMD = FMC_ISPCMD_RUN_ALL1;
457 FMC->ISPADDR = u32Addr;
458 FMC->ISPDAT = u32Count;
459 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
460
461
462 i32TimeOutCnt = FMC_TIMEOUT_CHKALLONE;
463 while ((i32TimeOutCnt-- > 0) && (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk)) {}
464 if (i32TimeOutCnt <= 0)
465 {
466 g_FMC_i32ErrCode = -1;
468 }
469
470 if (FMC_GET_FAIL_FLAG())
471 {
472 //printf("FMC_ISPCMD_RUN_ALL1 ISP failed!\n");
474 }
475
476 i32TimeOutCnt = FMC_TIMEOUT_CHKALLONE;
477 do
478 {
479 FMC->ISPCMD = FMC_ISPCMD_READ_ALL1;
480 FMC->ISPADDR = u32Addr;
481 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
482 while ((i32TimeOutCnt-- > 0) && (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk)) {}
483 if (i32TimeOutCnt <= 0)
484 {
485 g_FMC_i32ErrCode = -1;
487 }
488 }
489 while (FMC->ISPDAT == 0);
490
491 if (FMC_GET_FAIL_FLAG())
492 {
493 printf("FMC_ISPCMD_READ_ALL1 ISP failed!\n");
494 g_FMC_i32ErrCode = -1;
496 }
497
498 if ((FMC->ISPDAT == READ_ALLONE_YES) || (FMC->ISPDAT == READ_ALLONE_NOT))
499 return FMC->ISPDAT;
500
502}
503
504
523int32_t FMC_SKey_Setup(uint32_t key[3], uint32_t kpmax, uint32_t kemax, int lock_CONFIG)
524{
525 uint32_t lock_ctrl = 0;
526 int32_t i32TimeOutCnt;
527
529
530 if (FMC->KEYSTS != 0)
531 {
532 g_FMC_i32ErrCode = -1;
533 return g_FMC_i32ErrCode;
534 }
535
537 {
538 g_FMC_i32ErrCode = -2;
539 return g_FMC_i32ErrCode;
540 }
541
543 {
544 g_FMC_i32ErrCode = -2;
545 return g_FMC_i32ErrCode;
546 }
547
548 if (!lock_CONFIG)
549 lock_ctrl |= 0x1;
550
551 FMC_Write(FMC_KPROM_BASE, key[0]);
552 FMC_Write(FMC_KPROM_BASE+0x4, key[1]);
553 FMC_Write(FMC_KPROM_BASE+0x8, key[2]);
554 FMC_Write(FMC_KPROM_BASE+0xC, kpmax);
555 FMC_Write(FMC_KPROM_BASE+0x10, kemax);
556 FMC_Write(FMC_KPROM_BASE+0x14, lock_ctrl);
557
558 i32TimeOutCnt = FMC_TIMEOUT_WRITE;
559 while ((i32TimeOutCnt-- > 0) && (FMC->KEYSTS & FMC_KEYSTS_KEYBUSY_Msk)) {}
560 if(i32TimeOutCnt <= 0)
561 {
562 g_FMC_i32ErrCode = -1;
563 return g_FMC_i32ErrCode;
564 }
565
566 if (!(FMC->KEYSTS & FMC_KEYSTS_KEYLOCK_Msk))
567 {
568 printf("Security key lock failed!\n");
569 g_FMC_i32ErrCode = -4;
570 return g_FMC_i32ErrCode;
571 }
572
573 if ((lock_CONFIG && !(FMC->KEYSTS & FMC_KEYSTS_CFGFLAG_Msk)) ||
574 (!lock_CONFIG && (FMC->KEYSTS & FMC_KEYSTS_CFGFLAG_Msk)))
575 {
576 printf("CONFIG lock failed!\n");
577 g_FMC_i32ErrCode = -5;
578 return g_FMC_i32ErrCode;
579 }
580
581 if (((FMC->KPCNT & FMC_KPCNT_KPMAX_Msk) >> FMC_KPCNT_KPMAX_Pos) != kpmax)
582 {
583 printf("KPMAX failed!\n");
584 g_FMC_i32ErrCode = -7;
585 return g_FMC_i32ErrCode;
586 }
587
588 if (((FMC->KECNT & FMC_KECNT_KEMAX_Msk) >> FMC_KECNT_KEMAX_Pos) != kemax)
589 {
590 printf("KEMAX failed!\n");
591 g_FMC_i32ErrCode = -8;
592 return g_FMC_i32ErrCode;
593 }
594
595 return 0;
596}
597
598
610int32_t FMC_SKey_Compare(uint32_t key[3])
611{
612 int32_t i32TimeOutCnt;
613
615
616 if (FMC->KEYSTS & FMC_KEYSTS_FORBID_Msk)
617 {
618 printf("FMC_SKey_Compare - FORBID!\n");
619 g_FMC_i32ErrCode = -1;
620 return -1;
621 }
622
623 if (!(FMC->KEYSTS & FMC_KEYSTS_KEYLOCK_Msk))
624 {
625 printf("FMC_SKey_Compare - key is not locked!\n");
626 g_FMC_i32ErrCode = -3;
627 return -3;
628 }
629
630 FMC->KEY0 = key[0];
631 FMC->KEY1 = key[1];
632 FMC->KEY2 = key[2];
634
635 i32TimeOutCnt = FMC_TIMEOUT_READ;
636 while ((i32TimeOutCnt-- > 0) && (FMC->KEYSTS & FMC_KEYSTS_KEYBUSY_Msk)) {}
637 if (i32TimeOutCnt <= 0)
638 {
639 g_FMC_i32ErrCode = -1;
640 return 1;
641 }
642
643 if (!(FMC->KEYSTS & FMC_KEYSTS_KEYMATCH_Msk))
644 {
645 printf("Key mismatched!\n");
646 g_FMC_i32ErrCode = -2;
647 return -2;
648 }
649
650 if (FMC->KEYSTS & FMC_KEYSTS_KEYLOCK_Msk)
651 {
652 printf("Key matched, but still be locked!\n");
653 g_FMC_i32ErrCode = -2;
654 return -2;
655 }
656
657 printf("FMC_SKey_Compare - OK.\n");
658 return 0;
659}
660
661 /* end of group NANO103_FMC_EXPORTED_FUNCTIONS */
663 /* end of group NANO103_FMC_Driver */
665 /* end of group NANO103_Device_Driver */
667
668/*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
669
670
NANO103 peripheral access layer header file. This file contains all the peripheral register's definit...
#define FMC_ISPSTS_ISPBUSY_Msk
Definition: Nano103.h:3302
#define FMC_KEYSTS_FORBID_Msk
Definition: Nano103.h:3344
#define FMC_ISPCTL_ISPFF_Msk
Definition: Nano103.h:3278
#define FMC_ISPCTL_BS_Msk
Definition: Nano103.h:3266
#define FMC_KPCNT_KPMAX_Pos
Definition: Nano103.h:3361
#define FMC_KEYSTS_KEYBUSY_Msk
Definition: Nano103.h:3335
#define FMC_KEYSTS_KEYLOCK_Msk
Definition: Nano103.h:3338
#define FMC_KEYTRG_KEYGO_Msk
Definition: Nano103.h:3329
#define FMC_KEYSTS_KEYMATCH_Msk
Definition: Nano103.h:3341
#define FMC_ISPCTL_ISPEN_Msk
Definition: Nano103.h:3263
#define FMC_KEYTRG_TCEN_Msk
Definition: Nano103.h:3332
#define FMC_KPCNT_KPMAX_Msk
Definition: Nano103.h:3362
#define FMC_KECNT_KEMAX_Pos
Definition: Nano103.h:3355
#define FMC_KECNT_KEMAX_Msk
Definition: Nano103.h:3356
#define FMC_ISPTRG_ISPGO_Msk
Definition: Nano103.h:3290
#define FMC_KEYSTS_CFGFLAG_Msk
Definition: Nano103.h:3350
int32_t g_FMC_i32ErrCode
Definition: fmc.c:27
#define FMC_TIMEOUT_ERASE
Definition: fmc.h:78
#define FMC_ISPCMD_READ_CKS
Definition: fmc.h:61
#define FMC_ISPCMD_PROGRAM
Definition: fmc.h:55
#define FMC_FLASH_PAGE_SIZE
Definition: fmc.h:45
#define FMC_CONFIG_BASE
Definition: fmc.h:42
#define FMC_TIMEOUT_CHKSUM
Definition: fmc.h:79
#define FMC_ISPCMD_READ_CID
Definition: fmc.h:57
#define FMC_ISPCMD_RUN_ALL1
Definition: fmc.h:62
#define FMC_ISPCMD_READ_PID
Definition: fmc.h:58
#define READ_ALLONE_NOT
Definition: fmc.h:70
#define FMC_TIMEOUT_READ
Definition: fmc.h:76
#define FMC_TIMEOUT_CHKALLONE
Definition: fmc.h:80
#define FMC_ISPCMD_RUN_CKS
Definition: fmc.h:60
#define FMC_ISPCMD_READ
Definition: fmc.h:54
#define FMC_ISPCMD_READ_ALL1
Definition: fmc.h:63
#define FMC_ISPCMD_VECMAP
Definition: fmc.h:64
#define FMC_TIMEOUT_WRITE
Definition: fmc.h:77
#define READ_ALLONE_YES
Definition: fmc.h:69
#define READ_ALLONE_CMD_FAIL
Definition: fmc.h:71
#define FMC_ISPCMD_READ_UID
Definition: fmc.h:59
#define FMC_KPROM_BASE
Definition: fmc.h:43
#define FMC_ISPCMD_PAGE_ERASE
Definition: fmc.h:56
void FMC_Close(void)
Disable FMC ISP function.
Definition: fmc.c:38
int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count)
Execute ISP command to read User Configuration.
Definition: fmc.c:343
void FMC_SetVectorPageAddr(uint32_t u32PageAddr)
This function will force re-map assigned flash page to CPU address 0x0.
Definition: fmc.c:273
uint32_t FMC_ReadCID(void)
Read company ID.
Definition: fmc.c:144
uint32_t FMC_GetVectorPageAddr(void)
Obtain the current vector page address setting.
Definition: fmc.c:294
uint32_t FMC_ReadUID(uint32_t u32Index)
This function reads one of the three UID.
Definition: fmc.c:233
int32_t FMC_Erase(uint32_t u32PageAddr)
Execute FMC_ISPCMD_PAGE_ERASE command to erase a flash page. The page size is 512 bytes.
Definition: fmc.c:51
int32_t FMC_SKey_Setup(uint32_t key[3], uint32_t kpmax, uint32_t kemax, int lock_CONFIG)
Setup security key.
Definition: fmc.c:523
uint32_t FMC_ReadDataFlashBaseAddr(void)
Get the base address of Data Flash if enabled.
Definition: fmc.c:259
int32_t FMC_Write(uint32_t u32Addr, uint32_t u32Data)
Execute ISP command to program a word to flash.
Definition: fmc.c:311
#define FMC_DISABLE_CFG_UPDATE()
Definition: fmc.h:98
uint32_t FMC_Read(uint32_t u32Addr)
Execute ISP command to read a word from flash.
Definition: fmc.c:116
#define FMC_ENABLE_CFG_UPDATE()
Definition: fmc.h:97
uint32_t FMC_ReadPID(void)
Read product ID.
Definition: fmc.c:173
uint32_t FMC_CheckAllOne(uint32_t u32addr, uint32_t u32count)
Run flash all one verification and get result.
Definition: fmc.c:448
int32_t FMC_GetBootSource(void)
Get the current boot source.
Definition: fmc.c:87
int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count)
Execute ISP command to write User Configuration.
Definition: fmc.c:362
#define FMC_GET_FAIL_FLAG()
Definition: fmc.h:103
void FMC_Open(void)
Enable FMC ISP function.
Definition: fmc.c:100
int32_t FMC_SKey_Compare(uint32_t key[3])
Execute security key comparison.
Definition: fmc.c:610
int32_t FMC_GetChkSum(uint32_t u32Addr, uint32_t u32Count, uint32_t *u32ChkSum)
Run CRC32 checksum calculation and get result.
Definition: fmc.c:387
uint32_t FMC_ReadUCID(uint32_t u32Index)
This function reads one of the four UCID.
Definition: fmc.c:203
#define FMC
Pointer to FMC register structure.
Definition: Nano103.h:13816