| M480 BSP V3.05.001 The Board Support Package for M480 Series

fmc.c
Go to the documentation of this file.
1 /**************************************************************************/
10 #include <stdio.h>
11
12 #include "NuMicro.h"
13
14
33 void FMC_Close(void)
34 {
35 FMC->ISPCTL &= ~FMC_ISPCTL_ISPEN_Msk;
36 }
37
51 int32_t FMC_ConfigXOM(uint32_t u32XomNum, uint32_t u32XomBase, uint8_t u8XomPage)
52 {
53 int32_t ret = 0;
54
55 if(u32XomNum >= 4UL)
56 {
57 ret = -2;
58 }
59
60 if(ret == 0)
61 {
62 ret = FMC_GetXOMState(u32XomNum);
63 }
64
65 if(ret == 0)
66 {
67 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
68 FMC->ISPADDR = FMC_XOM_BASE + (u32XomNum * 0x10u);
69 FMC->ISPDAT = u32XomBase;
70 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
71 while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {}
72
73 if(FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
74 {
75 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
76 ret = -1;
77 }
78 }
79
80 if(ret == 0)
81 {
82 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
83 FMC->ISPADDR = FMC_XOM_BASE + (u32XomNum * 0x10u + 0x04u);
84 FMC->ISPDAT = u8XomPage;
85 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
86 while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {}
87
88 if(FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
89 {
90 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
91 ret = -1;
92 }
93 }
94
95 if(ret == 0)
96 {
97 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
98 FMC->ISPADDR = FMC_XOM_BASE + (u32XomNum * 0x10u + 0x08u);
99 FMC->ISPDAT = 0u;
100 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
101 while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {}
102
103 if(FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
104 {
105 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
106 ret = -1;
107 }
108 }
109
110 return ret;
111 }
112
121 int32_t FMC_Erase(uint32_t u32PageAddr)
122 {
123 int32_t ret = 0;
124
125 if (u32PageAddr == FMC_SPROM_BASE)
126 {
127 ret = FMC_Erase_SPROM();
128 }
129
130 if (ret == 0)
131 {
132 FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
133 FMC->ISPADDR = u32PageAddr;
134 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
135
136 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
137
138 if (FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
139 {
140 FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
141 ret = -1;
142 }
143 }
144 return ret;
145 }
146
147
154 int32_t FMC_Erase_SPROM(void)
155 {
156 int32_t ret = 0;
157
158 FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
159 FMC->ISPADDR = FMC_SPROM_BASE;
160 FMC->ISPDAT = 0x0055AA03UL;
161 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
162
163 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
164
165 if (FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
166 {
167 FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
168 ret = -1;
169 }
170 return ret;
171 }
172
181 int32_t FMC_Erase_Block(uint32_t u32BlockAddr)
182 {
183 int32_t ret = 0;
184
185 FMC->ISPCMD = FMC_ISPCMD_BLOCK_ERASE;
186 FMC->ISPADDR = u32BlockAddr;
187 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
188
189 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
190
191 if (FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
192 {
193 FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
194 ret = -1;
195 }
196 return ret;
197 }
198
206 int32_t FMC_Erase_Bank(uint32_t u32BankAddr)
207 {
208 int32_t ret = 0;
209
210 FMC->ISPCMD = FMC_ISPCMD_BANK_ERASE;
211 FMC->ISPADDR = u32BankAddr;
212 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
213
214 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
215
216 if (FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
217 {
218 FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
219 ret = -1;
220 }
221 return ret;
222 }
223
236 int32_t FMC_EraseXOM(uint32_t u32XomNum)
237 {
238 uint32_t u32Addr;
239 int32_t i32Active, err = 0;
240
241 if(u32XomNum >= 4UL)
242 {
243 err = -2;
244 }
245
246 if(err == 0)
247 {
248 i32Active = FMC_GetXOMState(u32XomNum);
249
250 if(i32Active)
251 {
252 switch(u32XomNum)
253 {
254 case 0u:
255 u32Addr = (FMC->XOMR0STS & 0xFFFFFF00u) >> 8u;
256 break;
257 case 1u:
258 u32Addr = (FMC->XOMR1STS & 0xFFFFFF00u) >> 8u;
259 break;
260 case 2u:
261 u32Addr = (FMC->XOMR2STS & 0xFFFFFF00u) >> 8u;
262 break;
263 case 3u:
264 u32Addr = (FMC->XOMR3STS & 0xFFFFFF00u) >> 8u;
265 break;
266 default:
267 break;
268 }
269 FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
270 FMC->ISPADDR = u32Addr;
271 FMC->ISPDAT = 0x55aa03u;
272 FMC->ISPTRG = 0x1u;
273 #if ISBEN
274 __ISB();
275 #endif
276 while(FMC->ISPTRG) {}
277
278 /* Check ISPFF flag to know whether erase OK or fail. */
279 if(FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
280 {
281 FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
282 err = -1;
283 }
284 }
285 else
286 {
287 err = -1;
288 }
289 }
290 return err;
291 }
292
304 int32_t FMC_GetXOMState(uint32_t u32XomNum)
305 {
306 uint32_t u32act;
307 int32_t ret = 0;
308
309 if(u32XomNum >= 4UL)
310 {
311 ret = -2;
312 }
313
314 if(ret >= 0)
315 {
316 u32act = (((FMC->XOMSTS) & 0xful) & (1ul << u32XomNum)) >> u32XomNum;
317 ret = (int32_t)u32act;
318 }
319 return ret;
320 }
321
329 int32_t FMC_GetBootSource (void)
330 {
331 if (FMC->ISPCTL & FMC_ISPCTL_BL_Msk)
332 {
333 return 2;
334 }
335 if (FMC->ISPCTL & FMC_ISPCTL_BS_Msk)
336 {
337 return 1;
338 }
339 return 0;
340 }
341
342
347 void FMC_Open(void)
348 {
349 FMC->ISPCTL |= FMC_ISPCTL_ISPEN_Msk;
350 }
351
352
359 uint32_t FMC_Read(uint32_t u32Addr)
360 {
361 FMC->ISPCMD = FMC_ISPCMD_READ;
362 FMC->ISPADDR = u32Addr;
363 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
364 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
365
366 return FMC->ISPDAT;
367 }
368
369
379 int32_t FMC_Read_64(uint32_t u32addr, uint32_t * u32data0, uint32_t * u32data1)
380 {
381 int32_t ret = 0;
382
383 FMC->ISPCMD = FMC_ISPCMD_READ_64;
384 FMC->ISPADDR = u32addr;
385 FMC->ISPDAT = 0x0UL;
386 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
387
388 while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
389
390 if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
391 {
392 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
393 ret = -1;
394 }
395 else
396 {
397 *u32data0 = FMC->MPDAT0;
398 *u32data1 = FMC->MPDAT1;
399 }
400 return ret;
401 }
402
403
408 uint32_t FMC_ReadDataFlashBaseAddr(void)
409 {
410 return FMC->DFBA;
411 }
412
423 void FMC_SetBootSource(int32_t i32BootSrc)
424 {
425 if(i32BootSrc)
426 {
427 FMC->ISPCTL |= FMC_ISPCTL_BS_Msk; /* Boot from LDROM */
428 }
429 else
430 {
431 FMC->ISPCTL &= ~FMC_ISPCTL_BS_Msk;/* Boot from APROM */
432 }
433 }
434
442 void FMC_Write(uint32_t u32Addr, uint32_t u32Data)
443 {
444 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
445 FMC->ISPADDR = u32Addr;
446 FMC->ISPDAT = u32Data;
447 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
448 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
449 }
450
460 int32_t FMC_Write8Bytes(uint32_t u32addr, uint32_t u32data0, uint32_t u32data1)
461 {
462 int32_t ret = 0;
463
464 FMC->ISPCMD = FMC_ISPCMD_PROGRAM_64;
465 FMC->ISPADDR = u32addr;
466 FMC->MPDAT0 = u32data0;
467 FMC->MPDAT1 = u32data1;
468 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
469
470 while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
471
472 if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
473 {
474 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
475 ret = -1;
476 }
477 return ret;
478 }
479
480
490 int32_t FMC_WriteMultiple(uint32_t u32Addr, uint32_t pu32Buf[], uint32_t u32Len)
491 {
492 int i, idx, retval = 0;
493
494 if ((u32Addr >= FMC_APROM_END) || ((u32Addr % 8) != 0))
495 {
496 return -1;
497 }
498
499 u32Len = u32Len - (u32Len % 8); /* u32Len must be multiple of 8. */
500
501 idx = 0;
502
503 while (u32Len >= 8)
504 {
505 FMC->ISPADDR = u32Addr;
506 FMC->MPDAT0 = pu32Buf[idx++];
507 FMC->MPDAT1 = pu32Buf[idx++];
508 FMC->MPDAT2 = pu32Buf[idx++];
509 FMC->MPDAT3 = pu32Buf[idx++];
510 FMC->ISPCMD = FMC_ISPCMD_PROGRAM_MUL;
511 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
512
513 for (i = 16; i < FMC_MULTI_WORD_PROG_LEN; )
514 {
515 while (FMC->MPSTS & (FMC_MPSTS_D0_Msk | FMC_MPSTS_D1_Msk))
516 ;
517 retval += 8;
518 u32Len -= 8;
519 if (u32Len < 8)
520 {
521 return retval;
522 }
523
524 if (!(FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk))
525 {
526 /* printf(" [WARNING] busy cleared after D0D1 cleared!\n"); */
527 i += 8;
528 break;
529 }
530
531 FMC->MPDAT0 = pu32Buf[idx++];
532 FMC->MPDAT1 = pu32Buf[idx++];
533
534 if (i == FMC_MULTI_WORD_PROG_LEN/4)
535 break; // done
536
537 while (FMC->MPSTS & (FMC_MPSTS_D2_Msk | FMC_MPSTS_D3_Msk))
538 ;
539 retval += 8;
540 u32Len -= 8;
541 if (u32Len < 8)
542 {
543 return retval;
544 }
545
546 if (!(FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk))
547 {
548 /* printf(" [WARNING] busy cleared after D2D3 cleared!\n"); */
549 i += 8;
550 break;
551 }
552
553 FMC->MPDAT2 = pu32Buf[idx++];
554 FMC->MPDAT3 = pu32Buf[idx++];
555 }
556
557 if (i != FMC_MULTI_WORD_PROG_LEN)
558 {
559 /* printf(" [WARNING] Multi-word program interrupted at 0x%x !!\n", i); */
560 return retval;
561 }
562
563 while (FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk) ;
564
565 u32Addr += FMC_MULTI_WORD_PROG_LEN;
566 }
567 return retval;
568 }
569
570
580 int32_t FMC_Write_OTP(uint32_t otp_num, uint32_t low_word, uint32_t high_word)
581 {
582 int32_t ret = 0;
583
584 if (otp_num > 255UL)
585 {
586 ret = -2;
587 }
588
589 if (ret == 0)
590 {
591 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
592 FMC->ISPADDR = FMC_OTP_BASE + otp_num * 8UL;
593 FMC->ISPDAT = low_word;
594 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
595
596 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
597
598 if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
599 {
600 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
601 ret = -1;
602 }
603 }
604
605 if (ret == 0)
606 {
607 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
608 FMC->ISPADDR = FMC_OTP_BASE + otp_num * 8UL + 4UL;
609 FMC->ISPDAT = high_word;
610 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
611
612 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
613
614 if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
615 {
616 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
617 ret = -1;
618 }
619 }
620
621 return ret;
622 }
623
633 int32_t FMC_Read_OTP(uint32_t otp_num, uint32_t *low_word, uint32_t *high_word)
634 {
635 int32_t ret = 0;
636
637 if (otp_num > 255UL)
638 {
639 ret = -2;
640 }
641
642 if (ret == 0)
643 {
644 FMC->ISPCMD = FMC_ISPCMD_READ_64;
645 FMC->ISPADDR = FMC_OTP_BASE + otp_num * 8UL ;
646 FMC->ISPDAT = 0x0UL;
647 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
648
649 while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
650
651 if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
652 {
653 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
654 ret = -1;
655 }
656 else
657 {
658 *low_word = FMC->MPDAT0;
659 *high_word = FMC->MPDAT1;
660 }
661 }
662 return ret;
663 }
664
672 int32_t FMC_Lock_OTP(uint32_t otp_num)
673 {
674 int32_t ret = 0;
675
676 if (otp_num > 255UL)
677 {
678 ret = -2;
679 }
680
681 if (ret == 0)
682 {
683 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
684 FMC->ISPADDR = FMC_OTP_BASE + 0x800UL + otp_num * 4UL;
685 FMC->ISPDAT = 0UL;
686 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
687
688 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
689
690 if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
691 {
692 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
693 ret = -1;
694 }
695 }
696 return ret;
697 }
698
707 int32_t FMC_Is_OTP_Locked(uint32_t otp_num)
708 {
709 int32_t ret = 0;
710
711 if (otp_num > 255UL)
712 {
713 ret = -2;
714 }
715
716 if (ret == 0)
717 {
718 FMC->ISPCMD = FMC_ISPCMD_READ;
719 FMC->ISPADDR = FMC_OTP_BASE + 0x800UL + otp_num * 4UL;
720 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
721
722 while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) { }
723
724 if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
725 {
726 FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
727 ret = -1;
728 }
729 else
730 {
731 if (FMC->ISPDAT != 0xFFFFFFFFUL)
732 {
733 ret = 1; /* Lock work was progrmmed. OTP was locked. */
734 }
735 }
736 }
737 return ret;
738 }
739
749 int32_t FMC_ReadConfig(uint32_t u32Config[], uint32_t u32Count)
750 {
751 int32_t ret = 0;
752
753 u32Config[0] = FMC_Read(FMC_CONFIG_BASE);
754
755 if (u32Count < 2UL)
756 {
757 ret = -1;
758 }
759 else
760 {
761 u32Config[1] = FMC_Read(FMC_CONFIG_BASE+4UL);
762 }
763 return ret;
764 }
765
766
776 int32_t FMC_WriteConfig(uint32_t u32Config[], uint32_t u32Count)
777 {
778 int i;
779
780 FMC_ENABLE_CFG_UPDATE();
781 FMC_Erase(FMC_CONFIG_BASE);
782
783 if ((FMC_Read(FMC_CONFIG_BASE) != 0xFFFFFFFF) || (FMC_Read(FMC_CONFIG_BASE+4) != 0xFFFFFFFF) ||
784 (FMC_Read(FMC_CONFIG_BASE+8) != 0xFFFF5A5A))
785 {
786 FMC_DISABLE_CFG_UPDATE();
787 return -1;
788 }
789
790 for (i = 0; i < u32Count; i++)
791 {
792 FMC_Write(FMC_CONFIG_BASE+i*4UL, u32Config[i]);
793
794 if (FMC_Read(FMC_CONFIG_BASE+i*4UL) != u32Config[i])
795 {
796 FMC_DISABLE_CFG_UPDATE();
797 return -1;
798 }
799 }
800
801 FMC_DISABLE_CFG_UPDATE();
802 return 0;
803 }
804
805
814 uint32_t FMC_GetChkSum(uint32_t u32addr, uint32_t u32count)
815 {
816 uint32_t ret;
817
818 if ((u32addr % 512UL) || (u32count % 512UL))
819 {
820 ret = 0xFFFFFFFF;
821 }
822 else
823 {
824 FMC->ISPCMD = FMC_ISPCMD_RUN_CKS;
825 FMC->ISPADDR = u32addr;
826 FMC->ISPDAT = u32count;
827 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
828
829 while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
830
831 FMC->ISPCMD = FMC_ISPCMD_READ_CKS;
832 FMC->ISPADDR = u32addr;
833 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
834
835 while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
836
837 ret = FMC->ISPDAT;
838 }
839
840 return ret;
841 }
842
843
852 uint32_t FMC_CheckAllOne(uint32_t u32addr, uint32_t u32count)
853 {
854 uint32_t ret = READ_ALLONE_CMD_FAIL;
855
856 FMC->ISPSTS = 0x80UL; /* clear check all one bit */
857
858 FMC->ISPCMD = FMC_ISPCMD_RUN_ALL1;
859 FMC->ISPADDR = u32addr;
860 FMC->ISPDAT = u32count;
861 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
862
863 while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
864
865 do
866 {
867 FMC->ISPCMD = FMC_ISPCMD_READ_ALL1;
868 FMC->ISPADDR = u32addr;
869 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
870 while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
871 }
872 while (FMC->ISPDAT == 0UL);
873
874 if (FMC->ISPDAT == READ_ALLONE_YES)
875 {
876 ret = FMC->ISPDAT;
877 }
878
879 if (FMC->ISPDAT == READ_ALLONE_NOT)
880 {
881 ret = FMC->ISPDAT;
882 }
883
884 return ret;
885 }
886
887
905 int32_t FMC_SetSPKey(uint32_t key[3], uint32_t kpmax, uint32_t kemax,
906 const int32_t lock_CONFIG, const int32_t lock_SPROM)
907 {
908 uint32_t lock_ctrl = 0UL;
909 uint32_t u32KeySts;
910 int32_t ret = 0;
911
912 if (FMC->KPKEYSTS != 0x200UL)
913 {
914 ret = -1;
915 }
916
917 if (FMC_Erase(FMC_KPROM_BASE))
918 {
919 ret = -2;
920 }
921
922 if (FMC_Erase(FMC_KPROM_BASE+0x200UL))
923 {
924 ret = -3;
925 }
926
927 if (!lock_CONFIG)
928 {
929 lock_ctrl |= 0x1UL;
930 }
931
932 if (!lock_SPROM)
933 {
934 lock_ctrl |= 0x2UL;
935 }
936
937 if (ret == 0)
938 {
939 FMC_Write(FMC_KPROM_BASE, key[0]);
940 FMC_Write(FMC_KPROM_BASE+0x4UL, key[1]);
941 FMC_Write(FMC_KPROM_BASE+0x8UL, key[2]);
942 FMC_Write(FMC_KPROM_BASE+0xCUL, kpmax);
943 FMC_Write(FMC_KPROM_BASE+0x10UL, kemax);
944 FMC_Write(FMC_KPROM_BASE+0x14UL, lock_ctrl);
945
946 while (FMC->KPKEYSTS & FMC_KPKEYSTS_KEYBUSY_Msk) { }
947
948 u32KeySts = FMC->KPKEYSTS;
949
950 if (!(u32KeySts & FMC_KPKEYSTS_KEYLOCK_Msk))
951 {
952 /* Security key lock failed! */
953 ret = -4;
954 }
955 else if ((lock_CONFIG && (!(u32KeySts & FMC_KPKEYSTS_CFGFLAG_Msk))) ||
956 ((!lock_CONFIG) && (u32KeySts & FMC_KPKEYSTS_CFGFLAG_Msk)))
957 {
958 /* CONFIG lock failed! */
959 ret = -5;
960 }
961 else if ((lock_SPROM && (!(u32KeySts & FMC_KPKEYSTS_SPFLAG_Msk))) ||
962 ((!lock_SPROM) && (u32KeySts & FMC_KPKEYSTS_SPFLAG_Msk)))
963 {
964 /* CONFIG lock failed! */
965 ret = -6;
966 }
967 else if (((FMC->KPCNT & FMC_KPCNT_KPMAX_Msk) >> FMC_KPCNT_KPMAX_Pos) != kpmax)
968 {
969 /* KPMAX failed! */
970 ret = -7;
971 }
972 else if (((FMC->KPKEYCNT & FMC_KPKEYCNT_KPKEMAX_Msk) >> FMC_KPKEYCNT_KPKEMAX_Pos) != kemax)
973 {
974 /* KEMAX failed! */
975 ret = -8;
976 }
977 }
978 return ret;
979 }
980
981
990 int32_t FMC_CompareSPKey(uint32_t key[3])
991 {
992 uint32_t u32KeySts;
993 int32_t ret = 0;
994
995 if (FMC->KPKEYSTS & FMC_KPKEYSTS_FORBID_Msk)
996 {
997 /* FMC_CompareSPKey - FORBID! */
998 ret = -1;
999 }
1000
1001 if (!(FMC->KPKEYSTS & FMC_KPKEYSTS_KEYLOCK_Msk))
1002 {
1003 /* FMC_CompareSPKey - key is not locked! */
1004 ret = -3;
1005 }
1006
1007 if (ret == 0)
1008 {
1009 FMC->KPKEY0 = key[0];
1010 FMC->KPKEY1 = key[1];
1011 FMC->KPKEY2 = key[2];
1012 FMC->KPKEYTRG = FMC_KPKEYTRG_KPKEYGO_Msk | FMC_KPKEYTRG_TCEN_Msk;
1013
1014 while (FMC->KPKEYSTS & FMC_KPKEYSTS_KEYBUSY_Msk) { }
1015
1016 u32KeySts = FMC->KPKEYSTS;
1017
1018 if (!(u32KeySts & FMC_KPKEYSTS_KEYMATCH_Msk))
1019 {
1020 /* Key mismatched! */
1021 ret = -2;
1022 }
1023 else if (u32KeySts & FMC_KPKEYSTS_KEYLOCK_Msk)
1024 {
1025 /* Key matched, but still be locked! */
1026 ret = -2;
1027 }
1028 }
1029 return ret;
1030 }
1031
1032 /* end of group FMC_EXPORTED_FUNCTIONS */
1034 /* end of group FMC_Driver */
1036 /* end of group Standard_Driver */
1038
1039 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
1040
1041
FMC_MPSTS_D3_Msk
#define FMC_MPSTS_D3_Msk
Definition: fmc_reg.h:1160
FMC_ISPCTL_ISPFF_Msk
#define FMC_ISPCTL_ISPFF_Msk
Definition: fmc_reg.h:1031
FMC_ReadDataFlashBaseAddr
uint32_t FMC_ReadDataFlashBaseAddr(void)
Get the base address of Data Flash if enabled.
Definition: fmc.c:408
FMC_WriteConfig
int32_t FMC_WriteConfig(uint32_t u32Config[], uint32_t u32Count)
Execute ISP commands to erase then write User Configuration.
Definition: fmc.c:776
FMC_KPCNT_KPMAX_Msk
#define FMC_KPCNT_KPMAX_Msk
Definition: fmc_reg.h:1127
FMC_APROM_END
#define FMC_APROM_END
Definition: fmc.h:35
FMC_Erase_Bank
int32_t FMC_Erase_Bank(uint32_t u32BankAddr)
Execute FMC_ISPCMD_BANK_ERASE command to erase a flash block.
Definition: fmc.c:206
FMC_GetXOMState
int32_t FMC_GetXOMState(uint32_t xom_num)
Check the XOM is actived or not.
Definition: fmc.c:304
FMC_Close
void FMC_Close(void)
Disable FMC ISP function.
Definition: fmc.c:33
FMC_CheckAllOne
uint32_t FMC_CheckAllOne(uint32_t u32addr, uint32_t u32count)
Run flash all one verification and get result.
Definition: fmc.c:852
FMC_KPKEYSTS_FORBID_Msk
#define FMC_KPKEYSTS_FORBID_Msk
Definition: fmc_reg.h:1106
FMC_ConfigXOM
int32_t FMC_ConfigXOM(uint32_t xom_num, uint32_t xom_base, uint8_t xom_page)
Config XOM Region.
Definition: fmc.c:51
FMC_Is_OTP_Locked
int32_t FMC_Is_OTP_Locked(uint32_t otp_num)
Check the OTP is locked or not.
Definition: fmc.c:707
FMC_Erase
int32_t FMC_Erase(uint32_t u32PageAddr)
Execute FMC_ISPCMD_PAGE_ERASE command to erase a flash page. The page size is 4096 bytes.
Definition: fmc.c:121
FMC_MPSTS_MPBUSY_Msk
#define FMC_MPSTS_MPBUSY_Msk
Definition: fmc_reg.h:1142
FMC_Lock_OTP
int32_t FMC_Lock_OTP(uint32_t otp_num)
Lock the specified OTP.
Definition: fmc.c:672
FMC_ISPCMD_BLOCK_ERASE
#define FMC_ISPCMD_BLOCK_ERASE
Definition: fmc.h:89
FMC_SPROM_BASE
#define FMC_SPROM_BASE
Definition: fmc.h:39
FMC_GetBootSource
int32_t FMC_GetBootSource(void)
Get the current boot source.
Definition: fmc.c:329
FMC_KPKEYSTS_SPFLAG_Msk
#define FMC_KPKEYSTS_SPFLAG_Msk
Definition: fmc_reg.h:1115
READ_ALLONE_CMD_FAIL
#define READ_ALLONE_CMD_FAIL
Definition: fmc.h:99
FMC_Open
void FMC_Open(void)
Enable FMC ISP function.
Definition: fmc.c:347
NuMicro.h
NuMicro peripheral access layer header file.
FMC_ISPCMD_RUN_CKS
#define FMC_ISPCMD_RUN_CKS
Definition: fmc.h:92
FMC_KPKEYSTS_KEYBUSY_Msk
#define FMC_KPKEYSTS_KEYBUSY_Msk
Definition: fmc_reg.h:1097
FMC_ISPCTL_BL_Msk
#define FMC_ISPCTL_BL_Msk
Definition: fmc_reg.h:1034
FMC_Write8Bytes
int32_t FMC_Write8Bytes(uint32_t u32addr, uint32_t u32data0, uint32_t u32data1)
Execute ISP FMC_ISPCMD_PROGRAM_64 to program a double-word to flash.
Definition: fmc.c:460
FMC_Read
uint32_t FMC_Read(uint32_t u32Addr)
Execute FMC_ISPCMD_READ command to read a word from flash.
Definition: fmc.c:359
FMC_GetChkSum
uint32_t FMC_GetChkSum(uint32_t u32addr, uint32_t u32count)
Run CRC32 checksum calculation and get result.
Definition: fmc.c:814
FMC_ISPCMD_READ_64
#define FMC_ISPCMD_READ_64
Definition: fmc.h:94
FMC_ISPCMD_READ
#define FMC_ISPCMD_READ
Definition: fmc.h:80
READ_ALLONE_NOT
#define READ_ALLONE_NOT
Definition: fmc.h:98
FMC_ISPCMD_PAGE_ERASE
#define FMC_ISPCMD_PAGE_ERASE
Definition: fmc.h:87
FMC_Erase_SPROM
int32_t FMC_Erase_SPROM(void)
Execute FMC_ISPCMD_PAGE_ERASE command to erase SPROM. The page size is 4096 bytes.
Definition: fmc.c:154
FMC_Erase_Block
int32_t FMC_Erase_Block(uint32_t u32BlockAddr)
Execute FMC_ISPCMD_BLOCK_ERASE command to erase a flash block. The block size is 4 pages.
Definition: fmc.c:181
FMC_DISABLE_CFG_UPDATE
#define FMC_DISABLE_CFG_UPDATE()
Definition: fmc.h:119
FMC_Read_64
int32_t FMC_Read_64(uint32_t u32addr, uint32_t *u32data0, uint32_t *u32data1)
Execute FMC_ISPCMD_READ_64 command to read a double-word from flash.
Definition: fmc.c:379
FMC_ISPSTS_ISPFF_Msk
#define FMC_ISPSTS_ISPFF_Msk
Definition: fmc_reg.h:1067
FMC_KPCNT_KPMAX_Pos
#define FMC_KPCNT_KPMAX_Pos
Definition: fmc_reg.h:1126
FMC_XOM_BASE
#define FMC_XOM_BASE
Definition: fmc.h:41
FMC_ISPSTS_ISPBUSY_Msk
#define FMC_ISPSTS_ISPBUSY_Msk
Definition: fmc_reg.h:1052
FMC_KPKEYSTS_CFGFLAG_Msk
#define FMC_KPKEYSTS_CFGFLAG_Msk
Definition: fmc_reg.h:1112
FMC_SetSPKey
int32_t FMC_SetSPKey(uint32_t key[3], uint32_t kpmax, uint32_t kemax, const int32_t lock_CONFIG, const int32_t lock_SPROM)
Setup security key.
Definition: fmc.c:905
FMC_ISPCMD_PROGRAM_64
#define FMC_ISPCMD_PROGRAM_64
Definition: fmc.h:95
FMC_KPKEYTRG_TCEN_Msk
#define FMC_KPKEYTRG_TCEN_Msk
Definition: fmc_reg.h:1094
FMC_MULTI_WORD_PROG_LEN
#define FMC_MULTI_WORD_PROG_LEN
Definition: fmc.h:55
FMC_KPKEYSTS_KEYLOCK_Msk
#define FMC_KPKEYSTS_KEYLOCK_Msk
Definition: fmc_reg.h:1100
FMC_MPSTS_D1_Msk
#define FMC_MPSTS_D1_Msk
Definition: fmc_reg.h:1154
FMC
#define FMC
Definition: M480.h:391
FMC_ISPCMD_READ_CKS
#define FMC_ISPCMD_READ_CKS
Definition: fmc.h:85
FMC_CONFIG_BASE
#define FMC_CONFIG_BASE
Definition: fmc.h:46
FMC_Write
void FMC_Write(uint32_t u32Addr, uint32_t u32Data)
Execute ISP FMC_ISPCMD_PROGRAM to program a word to flash.
Definition: fmc.c:442
FMC_KPKEYCNT_KPKEMAX_Pos
#define FMC_KPKEYCNT_KPKEMAX_Pos
Definition: fmc_reg.h:1120
FMC_ISPCMD_PROGRAM_MUL
#define FMC_ISPCMD_PROGRAM_MUL
Definition: fmc.h:90
FMC_CompareSPKey
int32_t FMC_CompareSPKey(uint32_t key[3])
Execute security key comparison.
Definition: fmc.c:990
FMC_ISPTRG_ISPGO_Msk
#define FMC_ISPTRG_ISPGO_Msk
Definition: fmc_reg.h:1046
FMC_MPSTS_D0_Msk
#define FMC_MPSTS_D0_Msk
Definition: fmc_reg.h:1151
FMC_ISPCTL_BS_Msk
#define FMC_ISPCTL_BS_Msk
Definition: fmc_reg.h:1016
FMC_ISPCTL_ISPEN_Msk
#define FMC_ISPCTL_ISPEN_Msk
Definition: fmc_reg.h:1013
READ_ALLONE_YES
#define READ_ALLONE_YES
Definition: fmc.h:97
FMC_KPKEYSTS_KEYMATCH_Msk
#define FMC_KPKEYSTS_KEYMATCH_Msk
Definition: fmc_reg.h:1103
FMC_ISPCMD_BANK_ERASE
#define FMC_ISPCMD_BANK_ERASE
Definition: fmc.h:88
FMC_Read_OTP
int32_t FMC_Read_OTP(uint32_t otp_num, uint32_t *low_word, uint32_t *high_word)
Read the 64-bits data from the specified OTP.
Definition: fmc.c:633
FMC_ISPCMD_READ_ALL1
#define FMC_ISPCMD_READ_ALL1
Definition: fmc.h:82
FMC_KPKEYCNT_KPKEMAX_Msk
#define FMC_KPKEYCNT_KPKEMAX_Msk
Definition: fmc_reg.h:1121
FMC_WriteMultiple
int32_t FMC_WriteMultiple(uint32_t u32Addr, uint32_t pu32Buf[], uint32_t u32Len)
Program Multi-Word data into specified address of flash.
Definition: fmc.c:490
FMC_KPROM_BASE
#define FMC_KPROM_BASE
Definition: fmc.h:50
FMC_EraseXOM
int32_t FMC_EraseXOM(uint32_t xom_num)
Execute Erase XOM Region.
Definition: fmc.c:236
FMC_ENABLE_CFG_UPDATE
#define FMC_ENABLE_CFG_UPDATE()
Definition: fmc.h:118
FMC_OTP_BASE
#define FMC_OTP_BASE
Definition: fmc.h:51
FMC_ISPCMD_RUN_ALL1
#define FMC_ISPCMD_RUN_ALL1
Definition: fmc.h:91
FMC_KPKEYTRG_KPKEYGO_Msk
#define FMC_KPKEYTRG_KPKEYGO_Msk
Definition: fmc_reg.h:1091
FMC_ISPCMD_PROGRAM
#define FMC_ISPCMD_PROGRAM
Definition: fmc.h:86
FMC_ReadConfig
int32_t FMC_ReadConfig(uint32_t u32Config[], uint32_t u32Count)
Execute FMC_ISPCMD_READ command to read User Configuration.
Definition: fmc.c:749
FMC_SetBootSource
void FMC_SetBootSource(int32_t i32BootSrc)
Set boot source from LDROM or APROM after next software reset.
Definition: fmc.c:423
FMC_MPSTS_D2_Msk
#define FMC_MPSTS_D2_Msk
Definition: fmc_reg.h:1157
FMC_Write_OTP
int32_t FMC_Write_OTP(uint32_t otp_num, uint32_t low_word, uint32_t high_word)
Program a 64-bits data to the specified OTP.
Definition: fmc.c:580