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