1 /**
2   ******************************************************************************
3   * @file    lib_flash.c
4   * @author  Application Team
5   * @version V1.1.0
6   * @date    2019-10-28
7   * @brief   FLASH library.
8   ******************************************************************************
9   * @attention
10   *
11   ******************************************************************************
12   */
13 #include "lib_flash.h"
14 #include "lib_clk.h"
15 
16 /* FLASH Keys */
17 #define FLASH_PASS_KEY      0x55AAAA55
18 #define FLASH_SERASE_KEY    0xAA5555AA
19 #define FLASH_CERASE_KEY    0xAA5555AA
20 #define FLASH_DSTB_KEY      0xAA5555AA
21 #define FLASH_ICE_KEY       0xAA5555AA
22 
23 #define FLASH_MODE_MASK     0x1F3
24 
25 /**
26   * @brief  Initializes FLASH mode.
27   * @param  CSMode:
28                 FLASH_CSMODE_DISABLE
29                 FLASH_CSMODE_ALWAYSON
30                 FLASH_CSMODE_TMR2OF
31                 FLASH_CSMODE_RTC
32   * @retval None
33   */
FLASH_Init(uint32_t CSMode)34 void FLASH_Init(uint32_t CSMode)
35 {
36   uint32_t tmp;
37 
38   /* Check parameters */
39   assert_parameters(IS_FLASH_CSMODE(CSMode));
40 
41   tmp = FLASH->CTRL;
42   tmp &= ~FLASH_MODE_MASK;
43   tmp |= CSMode;
44   FLASH->CTRL = tmp;
45 }
46 
47 /**
48   * @brief  Enables or disables FLASH interrupt.
49   * @param  IntMask:
50                 FLASH_INT_CS
51             NewState:
52                 ENABLE
53                 DISABLE
54   * @retval None
55   */
FLASH_INTConfig(uint32_t IntMask,uint32_t NewState)56 void FLASH_INTConfig(uint32_t IntMask, uint32_t NewState)
57 {
58   uint32_t tmp;
59 
60   /* Check parameters */
61   assert_parameters(IS_FLASH_INT(IntMask));
62   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
63 
64   tmp = FLASH->CTRL;
65   tmp &= ~IntMask;
66   if (NewState == ENABLE)
67   {
68     tmp |= IntMask;
69   }
70   FLASH->CTRL = tmp;
71 }
72 
73 /**
74   * @brief  Initializes FLASH 1USCYCLE.
75   * @param  None
76   * @retval None
77   */
FLASH_CycleInit(void)78 void FLASH_CycleInit(void)
79 {
80   uint32_t hclk;
81 
82   hclk = CLK_GetHCLKFreq();
83 
84   if (hclk > 1000000)
85     MISC2->FLASHWC = (hclk/1000000)<<8;
86   else
87     MISC2->FLASHWC = 0;
88 }
89 
90 /**
91   * @brief  Erases a specified FLASH sector.
92   * @param  SectorAddr: Erase start address.
93   * @retval None
94   */
FLASH_SectorErase(uint32_t SectorAddr)95 void FLASH_SectorErase(uint32_t SectorAddr)
96 {
97   /* Check parameters */
98   assert_parameters(IS_FLASH_ADDRESS(SectorAddr));
99 
100   /* Unlock flash */
101   FLASH->PASS = FLASH_PASS_KEY;
102 
103   FLASH->PGADDR = SectorAddr;
104   FLASH->SERASE = FLASH_SERASE_KEY;
105   while (FLASH->SERASE != 0);
106 
107   /* Lock flash */
108   FLASH->PASS = 0;
109 }
110 
111 /**
112   * @brief  Erases chip.
113   * @param  None.
114   * @retval None
115   */
FLASH_ChipErase(void)116 void FLASH_ChipErase(void)
117 {
118   /* Unlock flash */
119   FLASH->PASS = FLASH_PASS_KEY;
120 
121   FLASH->PGADDR = 0;
122   FLASH->CERASE = FLASH_CERASE_KEY;
123   while (FLASH->CERASE != 0);
124 
125   /* Lock flash */
126   FLASH->PASS = 0;
127 }
128 
129 /**
130   * @brief  Programs n word at a specified start address.
131   * @param  Addr: program start address
132             WordBuffer: word's buffer pointer to write
133             Length: The length of WordBuffer
134   * @retval None
135   */
FLASH_ProgramWord(uint32_t Addr,uint32_t * WordBuffer,uint32_t Length)136 void FLASH_ProgramWord(uint32_t Addr, uint32_t *WordBuffer, uint32_t Length)
137 {
138   uint32_t i;
139 
140   /* Check parameters */
141   assert_parameters(IS_FLASH_ADRRW(Addr));
142 
143   FLASH->PGADDR = Addr;
144   /* Unlock flash */
145   FLASH->PASS = FLASH_PASS_KEY;
146 
147   for (i=0; i<Length; i++)
148   {
149     FLASH->PGDATA = *(WordBuffer++);
150     while (FLASH->STS != 1);
151   }
152 
153   /* Lock flash */
154   FLASH->PASS = 0;
155 }
156 
157 /**
158   * @brief  Programs n half-word at a specified start address.
159   * @param  Addr: program start address
160             HWordBuffer: half-word's buffer pointer to write
161             Length: The length of HWordBuffer
162   * @retval None
163   */
FLASH_ProgramHWord(uint32_t Addr,uint16_t * HWordBuffer,uint32_t Length)164 void FLASH_ProgramHWord(uint32_t Addr, uint16_t *HWordBuffer, uint32_t Length)
165 {
166   uint32_t i;
167 
168   /* Check parameters */
169   assert_parameters(IS_FLASH_ADRRHW(Addr));
170 
171   FLASH->PGADDR = Addr;
172   /* Unlock flash */
173   FLASH->PASS = FLASH_PASS_KEY;
174 
175   for (i=0; i<Length; i++)
176   {
177     if (((Addr + 2*i)&0x3) == 0)
178       *((__IO uint16_t*)(&FLASH->PGDATA)) = *(HWordBuffer++);
179     else
180       *((__IO uint16_t*)(&FLASH->PGDATA ) + 1) = *(HWordBuffer++);
181     while (FLASH->STS != 1);
182   }
183 
184   /* Lock flash */
185   FLASH->PASS = 0;
186 }
187 
188 /**
189   * @brief  Programs n byte at a specified start address.
190   * @param  Addr: program start address
191             ByteBuffer: byte's buffer pointer to write
192             Length: The length of ByteBuffer
193   * @retval None
194   */
FLASH_ProgramByte(uint32_t Addr,uint8_t * ByteBuffer,uint32_t Length)195 void FLASH_ProgramByte(uint32_t Addr, uint8_t *ByteBuffer, uint32_t Length)
196 {
197   uint32_t i;
198 
199   /* Check parameters */
200   assert_parameters(IS_FLASH_ADDRESS(Addr));
201 
202   FLASH->PGADDR = Addr;
203   /* Unlock flash */
204   FLASH->PASS = FLASH_PASS_KEY;
205 
206   for (i=0; i<Length; i++)
207   {
208     if (((Addr + i)&0x3) == 0)
209       *((__IO uint8_t*)(&FLASH->PGDATA)) = *(ByteBuffer++);
210     else if (((Addr + i)&0x3) == 1)
211       *((__IO uint8_t*)(&FLASH->PGDATA) + 1) = *(ByteBuffer++);
212     else if (((Addr + i)&0x3) == 2)
213       *((__IO uint8_t*)(&FLASH->PGDATA) + 2) = *(ByteBuffer++);
214     else
215       *((__IO uint8_t*)(&FLASH->PGDATA) + 3) = *(ByteBuffer++);
216     while (FLASH->STS != 1);
217   }
218 
219   /* Lock flash */
220   FLASH->PASS = 0;
221 }
222 
223 /**
224   * @brief  Enables FLASH read protection.
225   * @param  Block: can use the '|' operator.
226                 FLASH_BLOCK_0 ~ FLASH_BLOCK_31 or FLASH_BLOCK_ALL
227   * @retval None
228   */
FLASH_SetReadProtection(uint32_t Block)229 void FLASH_SetReadProtection(uint32_t Block)
230 {
231   uint32_t tmp;
232 
233   /* Check parameters */
234   assert_parameters(IS_FLASH_RWBLOCK(Block));
235 
236   tmp = *(volatile unsigned int *)(0x0007FC00);
237   tmp &= ~Block;
238 
239   /* Unlock flash */
240   FLASH->PASS = FLASH_PASS_KEY;
241 
242   FLASH->PGADDR = 0x7FC00;
243   FLASH->PGDATA = tmp;
244   while (FLASH->STS != 1);
245   /* Lock flash */
246   FLASH->PASS = 0;
247 
248   tmp = *(volatile unsigned int *)(0x0007FC00);
249 }
250 
251 /**
252   * @brief  Enables or disables FLASH write protection.
253   * @param  Block: can use the '|' operator.
254                 FLASH_BLOCK_0 ~ FLASH_BLOCK_31 or FLASH_BLOCK_ALL
255             NewState:
256                 ENABLE
257                 DISABLE
258   * @retval None
259   */
FLASH_WriteProtection(uint32_t Block,uint32_t NewState)260 void FLASH_WriteProtection(uint32_t Block, uint32_t NewState)
261 {
262   uint32_t wrprot;
263 
264   /* Check parameters */
265   assert_parameters(IS_FLASH_RWBLOCK(Block));
266   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
267 
268   wrprot = FLASH->WRPROT;
269 
270   if (NewState == ENABLE)
271   {
272     wrprot |= Block;
273   }
274   else
275   {
276     wrprot &= ~Block;
277   }
278   FLASH->WRPROT = wrprot;
279 }
280 
281 /**
282   * @brief  Enables or disables ICE protection.
283   * @param  NewState:
284                 ENABLE(ICE protection is successful when 0x7FC08 is 0xFFFFFFFF )
285                 DISABLE
286   * @retval None.
287   */
FLASH_ICEProtection(uint32_t NewState)288 void FLASH_ICEProtection(uint32_t NewState)
289 {
290   /* Check parameters */
291   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
292 
293   if (NewState == ENABLE)
294   {
295     /* Unlock flash */
296     FLASH->PASS = FLASH_PASS_KEY;
297 
298     FLASH->PGADDR = 0x7FC08;
299     FLASH->PGDATA = 0x0A;
300     while (FLASH->STS != 1);
301     /* Lock flash */
302     FLASH->PASS = 0;
303   }
304   else
305   {
306     FLASH_SectorErase(0x7FFFF);
307     CORTEX_NVIC_SystemReset();
308   }
309 }
310 
311 /**
312   * @brief  Gets read/write/erase protection status.
313   * @param  Block:
314                 FLASH_BLOCK_0 ~ FLASH_BLOCK_31
315             Operation:
316                 FLASH_READ
317                 FLASH_WRITE
318   * @retval
319             When Operation is FLASH_READ:
320                 1: Read protection enabled.
321                 0: Read protection disabled.
322             When Operation is FLASH_WRITE:
323                 1: Write/erase protection enabled.
324                 0: Write/erase protection disabled.
325   */
FLASH_GetProtectionStatus(uint32_t Block,uint32_t Operation)326 uint8_t FLASH_GetProtectionStatus(uint32_t Block, uint32_t Operation)
327 {
328   /* Check parameters */
329   assert_parameters(IS_FLASH_BLOCK(Block));
330   assert_parameters(IS_FLASH_OPERATION(Operation));
331 
332   if (Operation == FLASH_READ)
333   {
334     if (FLASH->RDPROT & Block)
335       return 1;
336     else
337       return 0;
338   }
339   else
340   {
341     if (FLASH->WRPROT & Block)
342       return 1;
343     else
344       return 0;
345   }
346 }
347 
348 /**
349   * @brief  Gets read/write/erase protection status.
350   * @param  Operation:
351                 FLASH_READ
352                 FLASH_WRITE
353   * @retval Read or write/erase protection status.
354   */
FLASH_GetAllProtectionStatus(uint32_t Operation)355 uint32_t FLASH_GetAllProtectionStatus(uint32_t Operation)
356 {
357   if (Operation == FLASH_READ)
358   {
359     return FLASH->RDPROT;
360   }
361   else
362   {
363     return FLASH->WRPROT;
364   }
365 }
366 
367 /**
368   * @brief  Sets checksum range.
369   * @param  AddrStart: checksum start address
370             AddrEnd: checksum end address
371   * @retval None
372   */
FLASH_SetCheckSumRange(uint32_t AddrStart,uint32_t AddrEnd)373 void FLASH_SetCheckSumRange(uint32_t AddrStart, uint32_t AddrEnd)
374 {
375   /* Check parameters */
376   assert_parameters(IS_FLASH_CHECKSUMADDR(AddrStart,AddrEnd));
377 
378   FLASH->CSSADDR = AddrStart;
379   FLASH->CSEADDR = AddrEnd;
380 }
381 
382 /**
383   * @brief  Sets checksum compare value.
384   * @param  Checksum: checksum compare value
385   * @retval None
386   */
FLASH_SetCheckSumCompValue(uint32_t Checksum)387 void FLASH_SetCheckSumCompValue(uint32_t Checksum)
388 {
389   FLASH->CSCVALUE = Checksum;
390 }
391 
392 /**
393   * @brief  Gets FLASH checksum value.
394   * @param  None
395   * @retval Checksum
396   */
FLASH_GetCheckSum(void)397 uint32_t FLASH_GetCheckSum(void)
398 {
399   return FLASH->CSVALUE;
400 }
401 
402 /**
403   * @brief  Gets FLASH interrupt status.
404   * @param  IntMask:
405                 FLASH_INT_CS
406   * @retval 1: interrupt status set
407             0: interrupt status reset
408   */
FLASH_GetINTStatus(uint32_t IntMask)409 uint8_t FLASH_GetINTStatus(uint32_t IntMask)
410 {
411   /* Check parameters */
412   assert_parameters(IS_FLASH_INT(IntMask));
413 
414   if (FLASH->INTSTS & FLASH_INTSTS_CSERR)
415   {
416     return 1;
417   }
418   else
419   {
420     return 0;
421   }
422 }
423 
424 /**
425   * @brief  Clears FLASH interrupt status.
426   * @param  IntMask:
427                 FLASH_INT_CS
428   * @retval None
429   */
FLASH_ClearINTStatus(uint32_t IntMask)430 void FLASH_ClearINTStatus(uint32_t IntMask)
431 {
432   /* Check parameters */
433   assert_parameters(IS_FLASH_INT(IntMask));
434 
435   if (IntMask == FLASH_INT_CS)
436   {
437     FLASH->INTSTS = FLASH_INTSTS_CSERR;
438   }
439 }
440 
441 /*********************************** END OF FILE ******************************/
442