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 
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 
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  {
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  {
797  return -1;
798  }
799  }
800 
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 
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];
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 
#define FMC_MPSTS_D3_Msk
Definition: fmc_reg.h:1160
#define FMC_ISPCTL_ISPFF_Msk
Definition: fmc_reg.h:1031
uint32_t FMC_ReadDataFlashBaseAddr(void)
Get the base address of Data Flash if enabled.
Definition: fmc.c:408
int32_t FMC_WriteConfig(uint32_t u32Config[], uint32_t u32Count)
Execute ISP commands to erase then write User Configuration.
Definition: fmc.c:776
#define FMC_KPCNT_KPMAX_Msk
Definition: fmc_reg.h:1127
#define FMC_APROM_END
Definition: fmc.h:35
int32_t FMC_Erase_Bank(uint32_t u32BankAddr)
Execute FMC_ISPCMD_BANK_ERASE command to erase a flash block.
Definition: fmc.c:206
int32_t FMC_GetXOMState(uint32_t xom_num)
Check the XOM is actived or not.
Definition: fmc.c:304
void FMC_Close(void)
Disable FMC ISP function.
Definition: fmc.c:33
uint32_t FMC_CheckAllOne(uint32_t u32addr, uint32_t u32count)
Run flash all one verification and get result.
Definition: fmc.c:852
#define FMC_KPKEYSTS_FORBID_Msk
Definition: fmc_reg.h:1106
int32_t FMC_ConfigXOM(uint32_t xom_num, uint32_t xom_base, uint8_t xom_page)
Config XOM Region.
Definition: fmc.c:51
int32_t FMC_Is_OTP_Locked(uint32_t otp_num)
Check the OTP is locked or not.
Definition: fmc.c:707
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
#define FMC_MPSTS_MPBUSY_Msk
Definition: fmc_reg.h:1142
int32_t FMC_Lock_OTP(uint32_t otp_num)
Lock the specified OTP.
Definition: fmc.c:672
#define FMC_ISPCMD_BLOCK_ERASE
Definition: fmc.h:89
#define FMC_SPROM_BASE
Definition: fmc.h:39
int32_t FMC_GetBootSource(void)
Get the current boot source.
Definition: fmc.c:329
#define FMC_KPKEYSTS_SPFLAG_Msk
Definition: fmc_reg.h:1115
#define READ_ALLONE_CMD_FAIL
Definition: fmc.h:99
void FMC_Open(void)
Enable FMC ISP function.
Definition: fmc.c:347
NuMicro peripheral access layer header file.
#define FMC_ISPCMD_RUN_CKS
Definition: fmc.h:92
#define FMC_KPKEYSTS_KEYBUSY_Msk
Definition: fmc_reg.h:1097
#define FMC_ISPCTL_BL_Msk
Definition: fmc_reg.h:1034
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
uint32_t FMC_Read(uint32_t u32Addr)
Execute FMC_ISPCMD_READ command to read a word from flash.
Definition: fmc.c:359
uint32_t FMC_GetChkSum(uint32_t u32addr, uint32_t u32count)
Run CRC32 checksum calculation and get result.
Definition: fmc.c:814
#define FMC_ISPCMD_READ_64
Definition: fmc.h:94
#define FMC_ISPCMD_READ
Definition: fmc.h:80
#define READ_ALLONE_NOT
Definition: fmc.h:98
#define FMC_ISPCMD_PAGE_ERASE
Definition: fmc.h:87
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
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
#define FMC_DISABLE_CFG_UPDATE()
Definition: fmc.h:119
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
#define FMC_ISPSTS_ISPFF_Msk
Definition: fmc_reg.h:1067
#define FMC_KPCNT_KPMAX_Pos
Definition: fmc_reg.h:1126
#define FMC_XOM_BASE
Definition: fmc.h:41
#define FMC_ISPSTS_ISPBUSY_Msk
Definition: fmc_reg.h:1052
#define FMC_KPKEYSTS_CFGFLAG_Msk
Definition: fmc_reg.h:1112
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
#define FMC_ISPCMD_PROGRAM_64
Definition: fmc.h:95
#define FMC_KPKEYTRG_TCEN_Msk
Definition: fmc_reg.h:1094
#define FMC_MULTI_WORD_PROG_LEN
Definition: fmc.h:55
#define FMC_KPKEYSTS_KEYLOCK_Msk
Definition: fmc_reg.h:1100
#define FMC_MPSTS_D1_Msk
Definition: fmc_reg.h:1154
#define FMC
Definition: M480.h:391
#define FMC_ISPCMD_READ_CKS
Definition: fmc.h:85
#define FMC_CONFIG_BASE
Definition: fmc.h:46
void FMC_Write(uint32_t u32Addr, uint32_t u32Data)
Execute ISP FMC_ISPCMD_PROGRAM to program a word to flash.
Definition: fmc.c:442
#define FMC_KPKEYCNT_KPKEMAX_Pos
Definition: fmc_reg.h:1120
#define FMC_ISPCMD_PROGRAM_MUL
Definition: fmc.h:90
int32_t FMC_CompareSPKey(uint32_t key[3])
Execute security key comparison.
Definition: fmc.c:990
#define FMC_ISPTRG_ISPGO_Msk
Definition: fmc_reg.h:1046
#define FMC_MPSTS_D0_Msk
Definition: fmc_reg.h:1151
#define FMC_ISPCTL_BS_Msk
Definition: fmc_reg.h:1016
#define FMC_ISPCTL_ISPEN_Msk
Definition: fmc_reg.h:1013
#define READ_ALLONE_YES
Definition: fmc.h:97
#define FMC_KPKEYSTS_KEYMATCH_Msk
Definition: fmc_reg.h:1103
#define FMC_ISPCMD_BANK_ERASE
Definition: fmc.h:88
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
#define FMC_ISPCMD_READ_ALL1
Definition: fmc.h:82
#define FMC_KPKEYCNT_KPKEMAX_Msk
Definition: fmc_reg.h:1121
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
#define FMC_KPROM_BASE
Definition: fmc.h:50
int32_t FMC_EraseXOM(uint32_t xom_num)
Execute Erase XOM Region.
Definition: fmc.c:236
#define FMC_ENABLE_CFG_UPDATE()
Definition: fmc.h:118
#define FMC_OTP_BASE
Definition: fmc.h:51
#define FMC_ISPCMD_RUN_ALL1
Definition: fmc.h:91
#define FMC_KPKEYTRG_KPKEYGO_Msk
Definition: fmc_reg.h:1091
#define FMC_ISPCMD_PROGRAM
Definition: fmc.h:86
int32_t FMC_ReadConfig(uint32_t u32Config[], uint32_t u32Count)
Execute FMC_ISPCMD_READ command to read User Configuration.
Definition: fmc.c:749
void FMC_SetBootSource(int32_t i32BootSrc)
Set boot source from LDROM or APROM after next software reset.
Definition: fmc.c:423
#define FMC_MPSTS_D2_Msk
Definition: fmc_reg.h:1157
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