A31G12x F/W Packages  2.5.0
ABOV Cortex-M0+ Core based MCUs Integrated Driver
A31G12x_hal_fmc.c
Go to the documentation of this file.
1 /***************************************************************************//****************************************************************************/
34 
35 /* Includes ----------------------------------------------------------------- */
36 //******************************************************************************
37 // Include
38 //******************************************************************************
39 
40 #include "A31G12x_hal_fmc.h"
41 
42 //******************************************************************************
43 // Variable
44 //******************************************************************************
45 
46 uint32_t flash_id1_reg;
47 uint32_t flash_id2_reg;
50 
51 /* Public Functions --------------------------------------------------------- */
52 //******************************************************************************
53 // Function
54 //******************************************************************************
55 
56 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
64 void HAL_FMC_FlashEntry( void )
65 {
66  uint32_t WDT_WINDR;
67 
68  flash_id1_reg = FLASH_ID1 ^ FLASH_IDXOR;
69  flash_id2_reg = FLASH_ID2 ^ FLASH_IDXOR;
70  flash_addr_code0 = FLASH_ADDR_CD0 ^ FLASH_ADDR_CDXOR;
71  SCUCG->PPCLKEN2_b.FMCLKE = 1; // Enable Flash Memory Control Clock
72 #if 0
73  SCUCG->CLKSRCR_b.HIRCEN = 1; // Enable HIRC
74  NOP();
75  NOP();
76  NOP();
77 
78  SCULV->LVRCR_b.LVREN = 0x00; // Enable LVR, the Level should be set 2.28V over in CONF_LVRCNFIG register of configure option page 1
79  SCUCC->NMISRCR_b.NMICON = 0; // Disable NMI
80 #endif
81  WDT_WINDR = WDT->WINDR;
82  if( WDT->CNT < WDT_WINDR )
83  {
84  WDT->CNTR_b.CNTR = 0x6a; // Reload WDT Counter if WDT->CNT < WDT_WINDR
85  }
86  DI(); // Disable global interrupt
87 }
88 
89 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
94 void HAL_FMC_FlashExit( void )
95 {
96  flash_id1_reg = 0;
97  flash_id2_reg = 0;
98  flash_addr_code0 = 0;
99  flash_addr_code1 = 0;
100  SCUCG->PPCLKEN2_b.FMCLKE = 0; // Disable Flash Memory Control Clock
101  EI(); // Enable global interrupt
102 }
103 
104 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
120 uint32_t HAL_FMC_FlashFunction( uint32_t u32FncSel, uint32_t u32Addr, uint32_t* u32Buf )
121 {
122  uint32_t i;
123  volatile uint32_t* pagebuffer;
124 
125  pagebuffer = &FMC->PAGEBUF;
126  FMC->ADR = flash_addr_code0 ^ FLASH_ADDR_CDXOR; // Write 0x5FFFFFFF to FMC_ADR during the register is equal to 0x5FFFFF80;
127  FMC->IDR1 = flash_id1_reg ^ FLASH_IDXOR; // Identification Value 0
128  FMC->IDR2 = flash_id2_reg ^ FLASH_IDXOR; // Identification Value 1
129 
130  FMC->CR = FLASH_CLR_PAGEBUF; // Clear page buffer
131  for( i = 0 ; i < SECTOR_SIZE_BYTE / 4 ; i++ )
132  {
133  if( u32FncSel == FLASH_PAGE_WRITE )
134  {
135  *pagebuffer++ = *u32Buf++; // To page write
136  }
137  else if( ( u32FncSel == FLASH_PAGE_ERASE ) || ( u32FncSel == FLASH_BULK_ERASE ) )
138  {
139  *pagebuffer++ = 0xFFFFFFFF; // To page or bulk erase
140  }
141  else
142  {
143  return FLASH_PGM_FAIL;
144  }
145  }
146 
147  if( ( u32FncSel == FLASH_PAGE_WRITE ) || ( u32FncSel == FLASH_PAGE_ERASE ) ) // Page Erase/Write
148  {
149  if( u32Addr < FLASH_START_ADDR )
150  {
151  FMC->ADR = u32Addr + FLASH_START_ADDR; // Flash Page Address to be erased or written
152  }
153  else
154  {
155  FMC->ADR = u32Addr;
156  }
157  }
158  else if( u32FncSel == FLASH_BULK_ERASE ) // Bulk(Chip) Erase
159  {
160  FMC->BCR = FLASH_CHIPER_WOPT; // For bulk erase including Configure Option Page 1/2/3
161  FMC->ADR = flash_addr_code1 ^ FLASH_ADDR_CDXOR; // Identification Address for bulk erase
162  }
163  else
164  {
165  return FLASH_PGM_FAIL;
166  }
167 
168  if( FMC->IDR1 != FLASH_ID1 )
169  {
170  return FLASH_PGM_FAIL; // Check whether ID0 is ok or not
171  }
172  if( FMC->IDR2 != FLASH_ID2 )
173  {
174  return FLASH_PGM_FAIL; // Check whether ID1 is ok or not
175  }
176 
177  if( ( u32FncSel == FLASH_PAGE_WRITE ) || ( u32FncSel == FLASH_PAGE_ERASE ) ) // Page Erase/Write
178  {
179  if( ( FMC->ADR >= FLASH_START_ADDR ) && ( FMC->ADR <= FLASH_END_ADDR ) )
180  {
181  FMC->CR = FLASH_MEM_PGM_CODE | ( u32FncSel & 0x0000000F ); // Start flash page erase/write from here
182  }
183  else if( ( FMC->ADR >= CFG_OPT_SADDR ) && ( FMC->ADR <= CFG_OPT_EADDR ) )
184  {
185  FMC->CR = FLASH_OPT_PGM_CODE | ( u32FncSel & 0x0000000F ); // Start configure page erase/write from here
186  }
187  else
188  {
189  return FLASH_PGM_FAIL;
190  }
191  }
192  else if( u32FncSel == FLASH_BULK_ERASE ) // Bulk(Chip) Erase
193  {
194  if( FMC->ADR != FLASH_ADDR_CD1 )
195  {
196  return FLASH_PGM_FAIL;
197  }
198  FMC->CR = FLASH_BULK_CODE; // Start bulk(chip) erase from here
199  }
200  else
201  {
202  return FLASH_PGM_FAIL;
203  }
204 
205  while( FMC->CR_b.FMBUSY ) {} // Check whether the busy bit. If time over, goes out with error.
206  if( !FMC->ERFLAG_b.FMOPFLAG )
207  {
208  return FLASH_PGM_GOOD; // Success
209  }
210 
211  return FLASH_PGM_FAIL;
212 }
213 
214 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
223 uint32_t HAL_FMC_BulkErase( uint32_t u32UserId )
224 {
225  uint32_t result;
226 
228  flash_addr_code1 = FLASH_ADDR_CD1 ^ FLASH_ADDR_CDXOR;
229  if( u32UserId == 0x90E832CF ) // Ex) 0x90E832CF, The user ID may be changed by programmer
230  {
231  result = HAL_FMC_FlashFunction( FLASH_BULK_ERASE, 0, 0 );
232  }
233  else
234  {
235  result = FLASH_PGM_FAIL;
236  }
237 
238  if( result ) // If fail
239  {
240  FMC->ERFLAG = 0x03uL; // Clear FMC related flag
241  }
243 
244  return result;
245 }
246 
247 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
260 uint32_t HAL_FMC_PageErase( uint32_t u32UserId, uint32_t u32Addr )
261 {
262  uint32_t result;
263 
265  if( u32UserId == 0xA901358F ) // Ex) 0xA901358F, The user ID may be changed by programmer
266  {
267  result = HAL_FMC_FlashFunction( FLASH_PAGE_ERASE, u32Addr, 0 );
268  }
269  else
270  {
271  result = FLASH_PGM_FAIL;
272  }
273 
274  if( result ) // If fail
275  {
276  FMC->ERFLAG = 0x03uL; // Clear FMC related flag
277  }
279 
280  return result;
281 }
282 
283 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
298 uint32_t HAL_FMC_PageWrite( uint32_t u32UserId, uint32_t u32Addr, uint32_t* u32Buf )
299 {
300  uint32_t result;
301 
303  if( u32UserId == 0x4F17DC86 ) // Ex) 0x4F17DC86, The user ID may be changed by programmer
304  {
305  result = HAL_FMC_FlashFunction( FLASH_PAGE_WRITE, u32Addr, u32Buf );
306  }
307  else
308  {
309  result = FLASH_PGM_FAIL;
310  }
311 
312  if( result ) // If fail
313  {
314  FMC->ERFLAG = 0x03uL; // Clear FMC related flag
315  }
317 
318  return result;
319 }
320 
Contains all macro definitions and function prototypes support for fmc firmware library on A31G12x.
void HAL_FMC_FlashEntry(void)
Entry of Flash Memory Control.
uint32_t flash_addr_code0
uint32_t HAL_FMC_BulkErase(uint32_t u32UserId)
Flash Bulk(Chip) Erase Function.
uint32_t flash_id1_reg
uint32_t flash_id2_reg
void HAL_FMC_FlashExit(void)
Exit of Flash Memory Control.
uint32_t HAL_FMC_FlashFunction(uint32_t u32FncSel, uint32_t u32Addr, uint32_t *u32Buf)
Flash Page Erase/Write and Bulk(Chip) Erase.
uint32_t HAL_FMC_PageWrite(uint32_t u32UserId, uint32_t u32Addr, uint32_t *u32Buf)
Flash Page Write Function.
uint32_t HAL_FMC_PageErase(uint32_t u32UserId, uint32_t u32Addr)
Flash Page Erase Function.
uint32_t flash_addr_code1