M471M/R1/S BSP V3.01.000
The Board Support Package for M4521
fmc.h
Go to the documentation of this file.
1/**************************************************************************/
8#ifndef __FMC_H__
9#define __FMC_H__
10
11#include "NuMicro.h"
12
13#ifdef __cplusplus
14extern "C"
15{
16#endif
17
18#ifdef __FMC_C__
19int32_t g_FMC_i32ErrCode;
20#else
21extern int32_t g_FMC_i32ErrCode;
22#endif
23
36/*---------------------------------------------------------------------------------------------------------*/
37/* Global constant definitions */
38/*---------------------------------------------------------------------------------------------------------*/
39#define ISBEN 0
40
41/*---------------------------------------------------------------------------------------------------------*/
42/* Define Base Address */
43/*---------------------------------------------------------------------------------------------------------*/
44#define FMC_APROM_BASE 0x00000000UL
45#define FMC_LDROM_BASE 0x00100000UL
46#define FMC_SPROM_BASE 0x00200000UL
47#define FMC_CONFIG_BASE 0x00300000UL
49#define FMC_CONFIG0_ADDR (FMC_CONFIG_BASE)
50#define FMC_CONFIG1_ADDR (FMC_CONFIG_BASE + 4)
53#define FMC_FLASH_PAGE_SIZE 0x800
54#define FMC_LDROM_SIZE 0x1000
56/*---------------------------------------------------------------------------------------------------------*/
57/* ISPCTL constant definitions */
58/*---------------------------------------------------------------------------------------------------------*/
59#define FMC_ISPCTL_BS_LDROM 0x2
60#define FMC_ISPCTL_BS_APROM 0x0
62/*---------------------------------------------------------------------------------------------------------*/
63/* ISPCMD constant definitions */
64/*---------------------------------------------------------------------------------------------------------*/
65#define FMC_ISPCMD_READ 0x00
66#define FMC_ISPCMD_PROGRAM 0x21
67#define FMC_ISPCMD_WRITE_8 0x61
68#define FMC_ISPCMD_PAGE_ERASE 0x22
69#define FMC_ISPCMD_READ_CID 0x0B
70#define FMC_ISPCMD_READ_UID 0x04
71#define FMC_ISPCMD_READ_DID 0x0C
72#define FMC_ISPCMD_VECMAP 0x2E
73#define FMC_ISPCMD_CHECKSUM 0x0D
74#define FMC_ISPCMD_CAL_CHECKSUM 0x2D
75#define FMC_ISPCMD_MULTI_PROG 0x27
77/*---------------------------------------------------------------------------------------------------------*/
78/* FTCTL constant definitions */
79/*---------------------------------------------------------------------------------------------------------*/
80#define FMC_FTCTL_OPTIMIZE_DISABLE 0x00
81#define FMC_FTCTL_OPTIMIZE_12MHZ 0x01
82#define FMC_FTCTL_OPTIMIZE_36MHZ 0x02
83#define FMC_FTCTL_OPTIMIZE_60MHZ 0x04
84#define FMC_FTCTL_OPTIMIZE_72MHZ 0x05
86#define FMC_TIMEOUT_READ ((SystemCoreClock/10)*2)
87#define FMC_TIMEOUT_WRITE ((SystemCoreClock/10)*2)
88#define FMC_TIMEOUT_ERASE ((SystemCoreClock/10)*4)
89#define FMC_TIMEOUT_CHKSUM (SystemCoreClock*2)
90#define FMC_TIMEOUT_CHKALLONE (SystemCoreClock*2) /* end of group FMC_EXPORTED_CONSTANTS */
93
98/*---------------------------------------------------------------------------------------------------------*/
99/* FMC Macro Definitions */
100/*---------------------------------------------------------------------------------------------------------*/
111#define FMC_ENABLE_ISP() (FMC->ISPCTL |= FMC_ISPCTL_ISPEN_Msk)
123#define FMC_DISABLE_ISP() (FMC->ISPCTL &= ~FMC_ISPCTL_ISPEN_Msk)
136#define FMC_ENABLE_LD_UPDATE() (FMC->ISPCTL |= FMC_ISPCTL_LDUEN_Msk)
148#define FMC_DISABLE_LD_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_LDUEN_Msk)
161#define FMC_ENABLE_CFG_UPDATE() (FMC->ISPCTL |= FMC_ISPCTL_CFGUEN_Msk)
173#define FMC_DISABLE_CFG_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_CFGUEN_Msk)
187#define FMC_ENABLE_AP_UPDATE() (FMC->ISPCTL |= FMC_ISPCTL_APUEN_Msk)
199#define FMC_DISABLE_AP_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_APUEN_Msk)
213#define FMC_SELECT_NEXT_BOOT(x) (FMC->ISPCTL = (FMC->ISPCTL & ~FMC_ISPCTL_BS_Msk) | ((x) << FMC_ISPCTL_BS_Pos))
225#define FMC_GET_BOOT_STATUS() ((FMC->ISPCTL & FMC_ISPCTL_BS_Msk)?1:0)
227/*---------------------------------------------------------------------------------------------------------*/
228/* inline functions */
229/*---------------------------------------------------------------------------------------------------------*/
242static __INLINE void FMC_Write(uint32_t u32Addr, uint32_t u32Data)
243{
244 uint32_t tout;
245
247 FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
248 FMC->ISPADDR = u32Addr;
249 FMC->ISPDAT = u32Data;
250 FMC->ISPTRG = 0x1;
251#if ISBEN
252 __ISB();
253#endif
254 tout = FMC_TIMEOUT_WRITE;
255 while((--tout > 0) && FMC->ISPTRG);
256 if (tout == 0)
257 g_FMC_i32ErrCode = -1;
258}
259
273static __INLINE void FMC_Write8(uint32_t u32Addr, uint32_t u32Data0, uint32_t u32Data1)
274{
275 uint32_t tout;
276
278 FMC->ISPCMD = FMC_ISPCMD_WRITE_8;
279 FMC->ISPADDR = u32Addr;
280 FMC->MPDAT0 = u32Data0;
281 FMC->MPDAT1 = u32Data1;
282 FMC->ISPTRG = 0x1;
283#if ISBEN
284 __ISB();
285#endif
286 tout = FMC_TIMEOUT_WRITE;
287 while((--tout > 0) && FMC->ISPTRG);
288 if (tout == 0)
289 g_FMC_i32ErrCode = -1;
290}
291
292
303static __INLINE uint32_t FMC_Read(uint32_t u32Addr)
304{
305 uint32_t tout;
306
308 FMC->ISPCMD = FMC_ISPCMD_READ;
309 FMC->ISPADDR = u32Addr;
310 FMC->ISPDAT = 0;
311 FMC->ISPTRG = 0x1;
312#if ISBEN
313 __ISB();
314#endif
315 tout = FMC_TIMEOUT_READ;
316 while((--tout > 0) && FMC->ISPTRG);
317 if (tout == 0)
318 g_FMC_i32ErrCode = -1;
319
320 return FMC->ISPDAT;
321}
322
335static __INLINE int32_t FMC_Erase(uint32_t u32Addr)
336{
337 uint32_t tout;
338
340 FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
341 FMC->ISPADDR = u32Addr;
342 FMC->ISPTRG = 0x1;
343#if ISBEN
344 __ISB();
345#endif
346 tout = FMC_TIMEOUT_ERASE;
347 while ((--tout > 0) && FMC->ISPTRG);
348 if (tout == 0)
349 {
350 g_FMC_i32ErrCode = -1;
351 return -1;
352 }
353
354 /* Check ISPFF flag to know whether erase OK or fail. */
355 if(FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
356 {
357 FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
358 return -1;
359 }
360 return 0;
361}
362
373static __INLINE uint32_t FMC_ReadUID(uint8_t u8Index)
374{
375 uint32_t tout;
376
378 FMC->ISPCMD = FMC_ISPCMD_READ_UID;
379 FMC->ISPADDR = (u8Index << 2);
380 FMC->ISPDAT = 0;
381 FMC->ISPTRG = 0x1;
382#if ISBEN
383 __ISB();
384#endif
385 tout = FMC_TIMEOUT_READ;
386 while ((--tout > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk));
387 if (tout == 0)
388 {
389 g_FMC_i32ErrCode = -1;
390 return 0xFFFFFFFF;
391 }
392
393 return FMC->ISPDAT;
394}
395
406static __INLINE uint32_t FMC_ReadCID(void)
407{
408 uint32_t tout;
409
411 FMC->ISPCMD = FMC_ISPCMD_READ_CID; /* Set ISP Command Code */
412 FMC->ISPADDR = 0x0; /* Must keep 0x0 when read CID */
413 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
414#if ISBEN
415 __ISB();
416#endif /* To make sure ISP/CPU be Synchronized */
417 tout = FMC_TIMEOUT_READ;
418 while ((--tout > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk));
419 if (tout == 0)
420 {
421 g_FMC_i32ErrCode = -1;
422 return 0xFFFFFFFF;
423 }
424
425 return FMC->ISPDAT;
426}
427
438static __INLINE uint32_t FMC_ReadPID(void)
439{
440 uint32_t tout;
441
443 FMC->ISPCMD = FMC_ISPCMD_READ_DID; /* Set ISP Command Code */
444 FMC->ISPADDR = 0x04; /* Must keep 0x4 when read PID */
445 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
446#if ISBEN
447 __ISB();
448#endif /* To make sure ISP/CPU be Synchronized */
449 tout = FMC_TIMEOUT_READ;
450 while ((--tout > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk));
451 if (tout == 0)
452 {
453 g_FMC_i32ErrCode = -1;
454 return 0xFFFFFFFF;
455 }
456
457 return FMC->ISPDAT;
458}
459
470static __INLINE uint32_t FMC_ReadUCID(uint32_t u32Index)
471{
472 uint32_t tout;
473
475 FMC->ISPCMD = FMC_ISPCMD_READ_UID; /* Set ISP Command Code */
476 FMC->ISPADDR = (0x04 * u32Index) + 0x10; /* The UCID is at offset 0x10 with word alignment. */
477 FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
478#if ISBEN
479 __ISB();
480#endif /* To make sure ISP/CPU be Synchronized */
481 tout = FMC_TIMEOUT_READ;
482 while ((--tout > 0) && (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk));
483 if (tout == 0)
484 {
485 g_FMC_i32ErrCode = -1;
486 return 0xFFFFFFFF;
487 }
488
489 return FMC->ISPDAT;
490}
491
505static __INLINE void FMC_SetVectorPageAddr(uint32_t u32PageAddr)
506{
507 uint32_t tout;
508
510 FMC->ISPCMD = FMC_ISPCMD_VECMAP; /* Set ISP Command Code */
511 FMC->ISPADDR = u32PageAddr; /* The address of specified page which will be map to address 0x0. It must be page alignment. */
512 FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */
513#if ISBEN
514 __ISB();
515#endif /* To make sure ISP/CPU be Synchronized */
516 tout = FMC_TIMEOUT_WRITE;
517 while ((--tout > 0) && FMC->ISPTRG);
518 if (tout == 0)
519 g_FMC_i32ErrCode = -1;
520}
521
535static __INLINE uint32_t FMC_GetVECMAP(void)
536{
537 return (FMC->ISPSTS & FMC_ISPSTS_VECMAP_Msk);
538}
539
551static __INLINE uint32_t FMC_GetCheckSum(uint32_t u32Addr, int32_t i32Size)
552{
553 uint32_t tout;
554
557 FMC->ISPADDR = u32Addr;
558 FMC->ISPDAT = i32Size;
559 FMC->ISPTRG = 0x1;
560#if ISBEN
561 __ISB();
562#endif
563 tout = FMC_TIMEOUT_READ * 2;
564 while ((--tout > 0) && FMC->ISPTRG);
565
566 FMC->ISPCMD = FMC_ISPCMD_CHECKSUM;
567 FMC->ISPTRG = 0x1;
568 while ((--tout > 0) && FMC->ISPTRG);
569 if (tout == 0)
570 g_FMC_i32ErrCode = -1;
571
572 return FMC->ISPDAT;
573}
574
587static __INLINE void FMC_Write256(uint32_t u32Addr, uint32_t *pu32Buf)
588{
589 int32_t i, idx;
590 uint32_t tout;
591 volatile uint32_t *pu32IspData;
592 //int32_t i32Err;
593
594 //i32Err = 0;
595 idx = 0;
597 FMC->ISPCMD = FMC_ISPCMD_MULTI_PROG;
598 FMC->ISPADDR = u32Addr;
599
600retrigger:
601
602 //if(i32Err)
603 // printf("idx=%d ISPADDR = 0x%08x\n",idx, FMC->ISPADDR);
604
605 FMC->MPDAT0 = pu32Buf[idx + 0];
606 FMC->MPDAT1 = pu32Buf[idx + 1];
607 FMC->MPDAT2 = pu32Buf[idx + 2];
608 FMC->MPDAT3 = pu32Buf[idx + 3];
609
610
611
612 FMC->ISPTRG = 0x1;
613
614 pu32IspData = &FMC->MPDAT0;
615 idx += 4;
616
617 for(i = idx; i < 256 / 4; i += 4) // Max data length is 256 bytes (256/4 words)
618 {
619 tout = FMC_TIMEOUT_WRITE * 2;
620 __set_PRIMASK(1); // Mask interrupt to avoid status check coherence error
621 do
622 {
623 if((FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk) == 0)
624 {
625 __set_PRIMASK(0);
626 //printf("%d %x\n", i, FMC->MPADDR);
627 FMC->ISPADDR = FMC->MPADDR & (~0xful);
628 idx = (FMC->ISPADDR - u32Addr) / 4;
629 //i32Err = -1;
630 goto retrigger;
631 }
632 }
633 while((FMC->MPSTS & (3 << FMC_MPSTS_D0_Pos)) && (--tout > 0));
634
635 // Update new data for D0
636 pu32IspData[0] = pu32Buf[i ];
637 pu32IspData[1] = pu32Buf[i + 1];
638
639 do
640 {
641 if((FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk) == 0)
642 {
643 __set_PRIMASK(0);
644 //printf("%d %x\n", i, FMC->MPADDR);
645 FMC->ISPADDR = FMC->MPADDR & (~0xful);
646 idx = (FMC->ISPADDR - u32Addr) / 4;
647 //i32Err = -1;
648 goto retrigger;
649 }
650 }
651 while((FMC->MPSTS & (3 << FMC_MPSTS_D2_Pos)) && (--tout > 0));
652 if (tout == 0)
653 {
654 g_FMC_i32ErrCode = -1;
655 return;
656 }
657
658 // Update new data for D2
659 pu32IspData[2] = pu32Buf[i + 2];
660 pu32IspData[3] = pu32Buf[i + 3];
661 __set_PRIMASK(0);
662 }
663
664 tout = FMC_TIMEOUT_WRITE;
665 while((FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) && (--tout > 0));
666 if (tout == 0)
667 g_FMC_i32ErrCode = -1;
668}
669
670void FMC_Open(void);
671void FMC_Close(void);
672void FMC_EnableAPUpdate(void);
673void FMC_DisableAPUpdate(void);
674void FMC_EnableConfigUpdate(void);
675void FMC_DisableConfigUpdate(void);
676void FMC_EnableLDUpdate(void);
677void FMC_DisableLDUpdate(void);
678int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count);
679int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count);
680void FMC_SetBootSource(int32_t i32BootSrc);
681int32_t FMC_GetBootSource(void);
682uint32_t FMC_ReadDataFlashBaseAddr(void);
683void FMC_EnableFreqOptimizeMode(uint32_t u32Mode);
684void FMC_DisableFreqOptimizeMode(void); /* end of group FMC_EXPORTED_FUNCTIONS */
686 /* end of group FMC_Driver */
688 /* end of group Standard_Driver */
690
691#ifdef __cplusplus
692}
693#endif
694
695
696#endif
697
#define FMC_ISPSTS_VECMAP_Msk
Definition: M471M_R1_S.h:2418
#define FMC_ISPSTS_ISPBUSY_Msk
Definition: M471M_R1_S.h:2403
#define FMC_MPSTS_D2_Pos
Definition: M471M_R1_S.h:2447
#define FMC_ISPCTL_ISPFF_Msk
Definition: M471M_R1_S.h:2379
#define FMC_ISPTRG_ISPGO_Msk
Definition: M471M_R1_S.h:2394
#define FMC_MPSTS_D0_Pos
Definition: M471M_R1_S.h:2441
#define FMC_MPSTS_MPBUSY_Msk
Definition: M471M_R1_S.h:2433
NuMicro peripheral access layer header file.
int32_t g_FMC_i32ErrCode
#define FMC_TIMEOUT_ERASE
Definition: fmc.h:88
#define FMC_ISPCMD_PROGRAM
Definition: fmc.h:66
#define FMC_ISPCMD_WRITE_8
Definition: fmc.h:67
#define FMC_ISPCMD_CAL_CHECKSUM
Definition: fmc.h:74
#define FMC_ISPCMD_READ_DID
Definition: fmc.h:71
#define FMC_ISPCMD_CHECKSUM
Definition: fmc.h:73
#define FMC_ISPCMD_READ_CID
Definition: fmc.h:69
#define FMC_TIMEOUT_READ
Definition: fmc.h:86
#define FMC_ISPCMD_READ
Definition: fmc.h:65
#define FMC_ISPCMD_VECMAP
Definition: fmc.h:72
#define FMC_ISPCMD_MULTI_PROG
Definition: fmc.h:75
#define FMC_TIMEOUT_WRITE
Definition: fmc.h:87
#define FMC_ISPCMD_READ_UID
Definition: fmc.h:70
#define FMC_ISPCMD_PAGE_ERASE
Definition: fmc.h:68
void FMC_DisableLDUpdate(void)
Disable LDROM update function.
Definition: fmc.c:109
void FMC_Close(void)
Disable ISP Functions.
Definition: fmc.c:60
void FMC_EnableLDUpdate(void)
Enable LDROM update function.
Definition: fmc.c:157
int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count)
Read the User Configuration words.
Definition: fmc.c:230
static __INLINE uint32_t FMC_ReadUCID(uint32_t u32Index)
To read UCID.
Definition: fmc.h:470
void FMC_DisableFreqOptimizeMode(void)
Disable Flash Access Frequency Optimization Mode.
Definition: fmc.c:304
void FMC_EnableAPUpdate(void)
Enable APROM update function.
Definition: fmc.c:125
static __INLINE uint32_t FMC_GetVECMAP(void)
Get current vector mapping address.
Definition: fmc.h:535
static __INLINE void FMC_Write(uint32_t u32Addr, uint32_t u32Data)
Program 32-bit data into specified address of flash.
Definition: fmc.h:242
static __INLINE void FMC_Write256(uint32_t u32Addr, uint32_t *pu32Buf)
Program Multi-Word data into specified address of flash.
Definition: fmc.h:587
uint32_t FMC_ReadDataFlashBaseAddr(void)
Get the base address of Data Flash if enabled.
Definition: fmc.c:211
void FMC_EnableFreqOptimizeMode(uint32_t u32Mode)
Enable Flash Access Frequency Optimization Mode.
Definition: fmc.c:286
void FMC_SetBootSource(int32_t i32BootSrc)
Set boot source from LDROM or APROM after next software reset.
Definition: fmc.c:41
void FMC_DisableAPUpdate(void)
Disable APROM update function.
Definition: fmc.c:77
static __INLINE uint32_t FMC_ReadUID(uint8_t u8Index)
Read Unique ID.
Definition: fmc.h:373
static __INLINE void FMC_SetVectorPageAddr(uint32_t u32PageAddr)
Set vector mapping address.
Definition: fmc.h:505
int32_t FMC_GetBootSource(void)
Get the current boot source.
Definition: fmc.c:174
int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count)
Write User Configuration.
Definition: fmc.c:255
static __INLINE uint32_t FMC_ReadCID(void)
Read company ID.
Definition: fmc.h:406
void FMC_DisableConfigUpdate(void)
Disable User Configuration update function.
Definition: fmc.c:93
void FMC_Open(void)
Enable FMC ISP function.
Definition: fmc.c:196
static __INLINE int32_t FMC_Erase(uint32_t u32Addr)
Flash page erase.
Definition: fmc.h:335
void FMC_EnableConfigUpdate(void)
Enable User Configuration update function.
Definition: fmc.c:141
static __INLINE void FMC_Write8(uint32_t u32Addr, uint32_t u32Data0, uint32_t u32Data1)
Program 64-bit data into specified address of flash.
Definition: fmc.h:273
static __INLINE uint32_t FMC_ReadPID(void)
Read product ID.
Definition: fmc.h:438
static __INLINE uint32_t FMC_GetCheckSum(uint32_t u32Addr, int32_t i32Size)
Get Flash Checksum.
Definition: fmc.h:551
static __INLINE uint32_t FMC_Read(uint32_t u32Addr)
Read 32-bit Data from specified address of flash.
Definition: fmc.h:303
#define FMC
Definition: M471M_R1_S.h:13828