1 ////////////////////////////////////////////////////////////////////////////////
2 /// @file hal_flash.c
3 /// @author AE TEAM
4 /// @brief THIS FILE PROVIDES ALL THE FLASH FIRMWARE FUNCTIONS.
5 ////////////////////////////////////////////////////////////////////////////////
6 /// @attention
7 ///
8 /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
9 /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
10 /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
11 /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
12 /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
13 /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
14 ///
15 /// <H2><CENTER>© COPYRIGHT MINDMOTION </CENTER></H2>
16 ////////////////////////////////////////////////////////////////////////////////
17
18 // Define to prevent recursive inclusion
19 #define _HAL_FLASH_C_
20
21 // Files includes
22 #include "hal_flash.h"
23
24 ////////////////////////////////////////////////////////////////////////////////
25 /// @addtogroup MM32_Hardware_Abstract_Layer
26 /// @{
27
28 ////////////////////////////////////////////////////////////////////////////////
29 /// @addtogroup FLASH_HAL
30 /// @{
31
32 ////////////////////////////////////////////////////////////////////////////////
33 /// @addtogroup FLASH_Exported_Functions
34 /// @{
35
36 ////////////////////////////////////////////////////////////////////////////////
37 /// @brief Sets the code latency value.
38 /// @note This function can be used for all MM32 devices.
39 /// @param latency: specifies the FLASH Latency value.
40 /// This parameter can be one of the following values:
41 /// @arg FLASH_Latency_0: FLASH Zero Latency cycle
42 /// @arg FLASH_Latency_1: FLASH One Latency cycle
43 /// @arg FLASH_Latency_2: FLASH Two Latency cycles
44 /// @arg FLASH_Latency_3: FLASH Three Latency cycles
45 /// @retval None.
46 ////////////////////////////////////////////////////////////////////////////////
FLASH_SetLatency(FLASH_Latency_TypeDef latency)47 void FLASH_SetLatency(FLASH_Latency_TypeDef latency)
48 {
49 FLASH->ACR = (FLASH->ACR & (~FLASH_ACR_LATENCY)) | latency;
50 }
51
52 ////////////////////////////////////////////////////////////////////////////////
53 /// @brief Enables or disables the Half cycle flash access.
54 /// @note This function can be used for all MM32 devices.
55 /// @param half_cycle_access: specifies the FLASH Half cycle Access mode.
56 /// This parameter can be one of the following values:
57 /// @arg FLASH_HalfCycleAccess_Enable: FLASH Half Cycle Enable
58 /// @arg FLASH_HalfCycleAccess_Disable: FLASH Half Cycle Disable
59 /// @retval None.
60 ////////////////////////////////////////////////////////////////////////////////
FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_TypeDef half_cycle_access)61 void FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_TypeDef half_cycle_access)
62 {
63 FLASH->ACR &= ~FLASH_ACR_HLFCYA;
64 FLASH->ACR |= half_cycle_access;
65 }
66
67 ////////////////////////////////////////////////////////////////////////////////
68 /// @brief Enables or disables the Prefetch Buffer.
69 /// @note This function can be used for all MM32 devices.
70 /// @param prefetch_buffer: specifies the Prefetch buffer status.
71 /// This parameter can be one of the following values:
72 /// @arg FLASH_PrefetchBuffer_Enable: FLASH Prefetch Buffer Enable
73 /// @arg FLASH_PrefetchBuffer_Disable: FLASH Prefetch Buffer Disable
74 /// @retval None.
75 ////////////////////////////////////////////////////////////////////////////////
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_TypeDef prefetch_buffer)76 void FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_TypeDef prefetch_buffer)
77 {
78 FLASH->ACR &= ~FLASH_ACR_PRFTBE;
79 FLASH->ACR |= prefetch_buffer;
80 }
81
82 ////////////////////////////////////////////////////////////////////////////////
83 /// @brief Locks the FLASH Program Erase Controller.
84 /// @note This function can be used for all MM32 devices.
85 /// @param None.
86 /// @retval None.
87 ////////////////////////////////////////////////////////////////////////////////
FLASH_Lock(void)88 void FLASH_Lock(void)
89 {
90 FLASH->CR |= FLASH_CR_LOCK;
91 }
92
93 ////////////////////////////////////////////////////////////////////////////////
94 /// @brief Unlocks the FLASH Program Erase Controller.
95 /// @note This function can be used for all MM32 devices.
96 /// @param None.
97 /// @retval None.
98 ////////////////////////////////////////////////////////////////////////////////
FLASH_Unlock()99 void FLASH_Unlock()
100 {
101 FLASH->KEYR = FLASH_KEY1;
102 FLASH->KEYR = FLASH_KEY2;
103 }
104
105 ////////////////////////////////////////////////////////////////////////////////
106 /// @brief Enable to program the FLASH Option Byte.
107 /// @note This function can be used for all MM32 devices.
108 /// @param None.
109 /// @retval None.
110 ////////////////////////////////////////////////////////////////////////////////
FLASH_OPTB_Enable(void)111 void FLASH_OPTB_Enable(void)
112 {
113 FLASH->OPTKEYR = FLASH_KEY1;
114 FLASH->OPTKEYR = FLASH_KEY2;
115 }
116
117 ////////////////////////////////////////////////////////////////////////////////
118 /// @brief Erases a specified FLASH page.
119 /// @note This function can be used for all MM32 devices.
120 /// @param page_address: The page address to be erased.
121 /// @retval FLASH Status: The returned value can be: FLASH_BUSY,
122 /// FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
123 ////////////////////////////////////////////////////////////////////////////////
FLASH_ErasePage(u32 page_address)124 FLASH_Status FLASH_ErasePage(u32 page_address)
125 {
126 FLASH->CR |= FLASH_CR_PER;
127 FLASH->AR = page_address;
128 FLASH->CR |= FLASH_CR_STRT;
129 return FLASH_WaitForLastOperation(EraseTimeout);
130 }
131
132 ////////////////////////////////////////////////////////////////////////////////
133 /// @brief Erases all FLASH pages.
134 /// @note This function can be used for all MM32 devices.
135 /// @param None.
136 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
137 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
138 ////////////////////////////////////////////////////////////////////////////////
FLASH_EraseAllPages()139 FLASH_Status FLASH_EraseAllPages()
140 {
141 FLASH->AR = FLASH_BASE;
142 FLASH->CR |= (FLASH_CR_MER | FLASH_CR_STRT);
143 return FLASH_WaitForLastOperation(EraseTimeout);
144 }
145
146 ////////////////////////////////////////////////////////////////////////////////
147 /// @brief Erases the FLASH option bytes.
148 /// @note This function can be used for all MM32 devices.
149 /// @param None.
150 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
151 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
152 ////////////////////////////////////////////////////////////////////////////////
FLASH_EraseOptionBytes()153 FLASH_Status FLASH_EraseOptionBytes()
154 {
155 FLASH_OPTB_Enable();
156 FLASH->AR = OB_BASE;
157 FLASH->CR |= (FLASH_CR_OPTER | FLASH_CR_STRT);
158 return FLASH_WaitForLastOperation(EraseTimeout);
159 }
160 ////////////////////////////////////////////////////////////////////////////////
161 /// @brief Programs a half word at a specified address.
162 /// @note This function can be used for all MM32 devices.
163 /// @param address: specifies the address to be programmed.
164 /// @param data: specifies the data to be programmed.
165 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
166 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
167 ////////////////////////////////////////////////////////////////////////////////
FLASH_ProgramHalfWord(u32 address,u16 data)168 FLASH_Status FLASH_ProgramHalfWord(u32 address, u16 data)
169 {
170 FLASH->CR |= FLASH_CR_PG;
171
172 *(vu16*)address = data;
173
174
175 return FLASH_WaitForLastOperation(ProgramTimeout);
176 }
177
178 ////////////////////////////////////////////////////////////////////////////////
179 /// @brief Programs a word at a specified address.
180 /// @note This function can be used for all MM32 devices.
181 /// @param address: specifies the address to be programmed.
182 /// @param data: specifies the data to be programmed.
183 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
184 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
185 ////////////////////////////////////////////////////////////////////////////////
FLASH_ProgramWord(u32 address,u32 data)186 FLASH_Status FLASH_ProgramWord(u32 address, u32 data)
187 {
188 FLASH_Status ret = FLASH_ProgramHalfWord(address, data);
189 if (ret == FLASH_COMPLETE) {
190 ret = FLASH_ProgramHalfWord(address + 2, data >> 16);
191 }
192 return ret;
193 }
194
195 ////////////////////////////////////////////////////////////////////////////////
196 /// @brief Programs a byte at a specified Option Byte Data address.
197 /// @note This function can be used for all MM32 devices.
198 /// @param address: specifies the address to be programmed.
199 /// This parameter can be 0x1FFFF804 or 0x1FFFF806.
200 /// @param data: specifies the data to be programmed.
201 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
202 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
203 ////////////////////////////////////////////////////////////////////////////////
FLASH_ProgramOptionByteData(u32 address,u8 data)204 FLASH_Status FLASH_ProgramOptionByteData(u32 address, u8 data)
205 {
206 FLASH_Status ret;
207 __IO u16 temp;
208 FLASH_OPTB_Enable();
209 FLASH->CR |= FLASH_CR_OPTPG;
210 temp = (u16)(~data);
211 temp = (temp << 8) & 0xFF00;
212 temp = temp | (u16)data;
213 address = address & (~0x1);
214 *(vu16*)address = temp;
215 ret = FLASH_WaitForLastOperation(ProgramTimeout);
216
217 return ret;
218 }
219
220 ////////////////////////////////////////////////////////////////////////////////
221 /// @brief Programs a half word at a specified Option Byte Data address.
222 /// @note This function can be used for all MM32 devices.
223 /// @param address: specifies the address to be programmed.
224 /// This parameter can be 0x1FFFF804 or 0x1FFFF806.
225 /// @param data: specifies the data to be programmed.
226 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
227 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
228 ////////////////////////////////////////////////////////////////////////////////
FLASH_ProgramOptionHalfWord(u32 address,u16 data)229 FLASH_Status FLASH_ProgramOptionHalfWord(u32 address, u16 data)
230 {
231 FLASH_Status ret;
232 FLASH_OPTB_Enable();
233 FLASH->CR |= FLASH_CR_OPTPG;
234 *(vu16*)address = data;
235 ret = FLASH_WaitForLastOperation(ProgramTimeout);
236
237 return ret;
238 }
239
240 ////////////////////////////////////////////////////////////////////////////////
241 /// @brief Read protection for the specified address
242 /// @note This function can be used for all MM32 devices.
243 /// @retval None.
244 ////////////////////////////////////////////////////////////////////////////////
FLASH_ProgramProtect(u32 address,u16 data)245 FLASH_Status FLASH_ProgramProtect(u32 address, u16 data)
246 {
247 return FLASH_ProgramOptionHalfWord(address, data);
248
249 // FLASH_Status ret;
250 // ret = FLASH_ProgramOptionHalfWord(address, 0x7F80);
251 //
252 // if (ret == FLASH_COMPLETE) {
253 // ret = FLASH_ProgramOptionHalfWord(address + 2, 0xFF00);
254 // }
255 // return ret;
256 }
257
258 ////////////////////////////////////////////////////////////////////////////////
259 /// @brief Write protection for the specified address
260 /// @note This function can be used for all MM32 devices.
261 /// @param page: specifies the address of the pages to be write
262 /// protected.
263 /// This parameter is (0x01 << ((Absolute address - 0x08000000)/0x1000))
264 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
265 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
266 ////////////////////////////////////////////////////////////////////////////////
FLASH_EnableWriteProtection(u32 page)267 FLASH_Status FLASH_EnableWriteProtection(u32 page)
268 {
269 FLASH_Status ret;
270 u8 i;
271 for (i = 0; i < 4; i++) {
272 ret = FLASH_ProgramOptionHalfWord((OB_BASE + 8 + i * 2), ~(page >> (i * 8)));
273 if (ret != FLASH_COMPLETE) {
274 break;
275 }
276 }
277 return ret;
278 }
279
280 ////////////////////////////////////////////////////////////////////////////////
281 /// @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
282 /// @note This function can be used for all MM32 devices.
283 /// @param ob_iwdg: Selects the IWDG mode
284 /// @param ob_stop: Reset event when entering STOP mode.
285 /// @param standby: Reset event when entering Standby mode.
286 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
287 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
288 ////////////////////////////////////////////////////////////////////////////////
FLASH_UserOptionByteConfig(OB_IWDG_TypeDef ob_iwdg,OB_STOP_TypeDef ob_stop,OB_STDBY_TypeDef standby)289 FLASH_Status FLASH_UserOptionByteConfig(OB_IWDG_TypeDef ob_iwdg, OB_STOP_TypeDef ob_stop, OB_STDBY_TypeDef standby)
290 {
291 FLASH_OPTB_Enable();
292 FLASH->CR |= FLASH_CR_OPTPG;
293 OB->USER = ob_iwdg;
294 OB->USER |= ob_stop;
295 OB->USER |= standby;
296 OB->USER |= 0xF8;
297 // OB->USER = iwdg | stop | stdby | 0xF8;
298 return FLASH_WaitForLastOperation(ProgramTimeout);
299 }
300
301 ////////////////////////////////////////////////////////////////////////////////
302 /// @brief Returns the FLASH User Option Bytes values.
303 /// @note This function can be used for all MM32 devices.
304 /// @param None.
305 /// @retval The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1)
306 /// and RST_STDBY(Bit2).
307 ////////////////////////////////////////////////////////////////////////////////
FLASH_GetUserOptionByte()308 u32 FLASH_GetUserOptionByte()
309 {
310 return (FLASH->OBR >> 2);
311 }
312
313 ////////////////////////////////////////////////////////////////////////////////
314 /// @brief Returns the FLASH Write Protection Option Bytes Register value.
315 /// @note This function can be used for all MM32 devices.
316 /// @param None.
317 /// @retval The FLASH Write Protection Option Bytes Register value.
318 ////////////////////////////////////////////////////////////////////////////////
FLASH_GetWriteProtectionOptionByte()319 u32 FLASH_GetWriteProtectionOptionByte()
320 {
321 return (FLASH->WRPR);
322 }
323 ////////////////////////////////////////////////////////////////////////////////
324 /// @brief Checks whether the FLASH Prefetch Buffer status is set or not.
325 /// @note This function can be used for all MM32 devices.
326 /// @param None.
327 /// @retval FLASH Prefetch Buffer Status (SET or RESET).
328 ////////////////////////////////////////////////////////////////////////////////
FLASH_GetPrefetchBufferStatus(void)329 FlagStatus FLASH_GetPrefetchBufferStatus(void)
330 {
331 return (FLASH->ACR & FLASH_ACR_PRFTBS) ? SET : RESET;
332 }
333 ////////////////////////////////////////////////////////////////////////////////
334 /// @brief Enables or disables the specified FLASH interrupts.
335 /// @note This function can be used for all MM32 devices.
336 /// @param interrupt: specifies the FLASH interrupt sources to be enabled or
337 /// disabled.
338 /// @param state: new state of the specified Flash interrupts.
339 /// This parameter can be: ENABLE or DISABLE.
340 /// @retval None.
341 ////////////////////////////////////////////////////////////////////////////////
FLASH_ITConfig(FLASH_IT_TypeDef interrupt,FunctionalState state)342 void FLASH_ITConfig(FLASH_IT_TypeDef interrupt, FunctionalState state)
343 {
344 (state) ? (FLASH->CR |= interrupt) : (FLASH->CR &= ~interrupt);
345 }
346
347 ////////////////////////////////////////////////////////////////////////////////
348 /// @brief Checks whether the specified FLASH flag is set or not.
349 /// @note This function can be used for all MM32 devices.
350 /// @param flag: specifies the FLASH flags to clear.
351 /// This parameter can be one of the following values:
352 /// @arg FLASH_FLAG_BSY: FLASH Busy flag
353 /// @arg FLASH_FLAG_PGERR: FLASH Program error flag
354 /// @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
355 /// @arg FLASH_FLAG_EOP: FLASH End of Operation flag
356 /// @arg FLASH_FLAG_OPTERR: FLASH Option Byte error flag
357 /// @retval The new state of FLASH_FLAG (SET or RESET).
358 ////////////////////////////////////////////////////////////////////////////////
FLASH_GetFlagStatus(u16 flag)359 FlagStatus FLASH_GetFlagStatus(u16 flag)
360 {
361 return ((flag == FLASH_FLAG_OPTERR) ? (FLASH->OBR & FLASH_FLAG_OPTERR) : (FLASH->SR & flag)) ? SET : RESET;
362 }
363
364 ////////////////////////////////////////////////////////////////////////////////
365 /// @brief Clears the FLASH's pending flags.
366 /// @note This function can be used for all MM32 devices.
367 /// @param flag: specifies the FLASH flags to clear.
368 /// This parameter can be any combination of the following values:
369 /// @arg FLASH_FLAG_PGERR: FLASH Program error flag
370 /// @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag
371 /// @arg FLASH_FLAG_EOP: FLASH End of Operation flag
372 /// @retval None.
373 ////////////////////////////////////////////////////////////////////////////////
FLASH_ClearFlag(u16 flag)374 void FLASH_ClearFlag(u16 flag)
375 {
376 FLASH->SR = flag;
377 }
378
379 ////////////////////////////////////////////////////////////////////////////////
380 /// @brief Returns the FLASH Status.
381 /// @note This function can be used for all MM32 devices.
382 /// @param None.
383 /// @retval FLASH Status: The returned value can be: FLASH_BUSY,
384 /// FLASH_ERROR_PG, FLASH_ERROR_WRP or FLASH_COMPLETE.
385 ////////////////////////////////////////////////////////////////////////////////
FLASH_GetStatus()386 FLASH_Status FLASH_GetStatus()
387 {
388 return (FLASH_Status)((FLASH->SR & FLASH_FLAG_BSY))
389 ? FLASH_BUSY
390 : ((FLASH->SR & FLASH_FLAG_PGERR) ? FLASH_ERROR_PG
391 : ((FLASH->SR & FLASH_FLAG_WRPRTERR) ? FLASH_ERROR_WRP : FLASH_COMPLETE));
392 }
393
394 ////////////////////////////////////////////////////////////////////////////////
395 /// @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
396 /// @note This function can be used for all MM32 devices
397 /// @param time_out: FLASH programming time_out
398 /// @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
399 /// FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
400 ////////////////////////////////////////////////////////////////////////////////
FLASH_WaitForLastOperation(u32 time_out)401 FLASH_Status FLASH_WaitForLastOperation(u32 time_out)
402 {
403 u32 i;
404 FLASH_Status ret;
405 do {
406 ret = FLASH_GetStatus();
407 time_out--;
408 for (i = 0xFF; i != 0; i--)
409 ;
410 } while ((ret == FLASH_BUSY) && (time_out != 0x00));
411
412 FLASH->CR = 0;
413 FLASH->SR = FLASH_SR_EOP | FLASH_SR_WRPRTERR | FLASH_SR_PGERR;
414 return (FLASH_Status)((time_out == 0x00) ? FLASH_TIMEOUT : ret);
415 }
416
417 ////////////////////////////////////////////////////////////////////////////////
418 /// @brief Erases a specified FLASH page.
419 /// @note This function can be used for all MM32 devices.
420 /// @param Page_Address: The page address to be erased.
421 /// @retval None.
422 ////////////////////////////////////////////////////////////////////////////////
exFLASH_EraseEE(u32 page_address)423 void exFLASH_EraseEE(u32 page_address)
424 {
425 FLASH_Unlock();
426 FLASH_ErasePage(page_address);
427 FLASH_Lock();
428 }
429
430 ////////////////////////////////////////////////////////////////////////////////
431 /// @brief Programs a buffer at a specified address.
432 /// @note This function can be used for all MM32 devices.
433 /// @param *buf: the pointer of the buffer to be programmed.
434 /// @param addr: specifies the address to be programmed.
435 /// @param len: the number of bytes in the buffer.
436 /// This parameter can only be even.
437 /// @retval None.
438 ////////////////////////////////////////////////////////////////////////////////
exFLASH_ProgramEE(u16 * buf,u32 addr,u16 len)439 void exFLASH_ProgramEE(u16* buf, u32 addr, u16 len)
440 {
441 u16 i;
442 FLASH_Unlock();
443 for (i = 0; i < len / 2; i++) {
444 FLASH_ProgramHalfWord(addr, *buf);
445 addr += 2;
446 buf++;
447 }
448 FLASH_Lock();
449 }
450
451 ////////////////////////////////////////////////////////////////////////////////
452 /// @brief Determine if the data that at the ptr address with the length is len
453 /// is empty.
454 /// @note This function can be used for all MM32 devices.
455 /// @param *ptr: the pointer of the starting address.
456 /// @param len: the number of bytes.
457 /// This parameter can only be even.
458 /// @retval 1 presents the data is empty,
459 /// 0 presents the data has been written.
460 ////////////////////////////////////////////////////////////////////////////////
exFLASH_FindEmpty(u16 * ptr,u16 len)461 u8 exFLASH_FindEmpty(u16* ptr, u16 len)
462 {
463 u16 i;
464 for (i = 0; i < (len / 2); i++) {
465 if (*(ptr + i) != 0xffff)
466 return 0;
467 }
468 return 1;
469 }
470
471 ////////////////////////////////////////////////////////////////////////////////
472 /// @brief Locate the writable area on the specified address.
473 /// @note This function can be used for all MM32 devices.
474 /// @param page_address: specifies the beginning of the EEprom.
475 /// The EEprom can be some continuously pages in the flash.
476 /// @param len: the number of bytes to be written.
477 /// This parameter can only be even.
478 /// @retval the pointer of the starting address.
479 ////////////////////////////////////////////////////////////////////////////////
exFLASH_Locate(u32 page_address,u16 len)480 void* exFLASH_Locate(u32 page_address, u16 len)
481 {
482 u16 i;
483 u16* ptr = (u16*)page_address;
484 for (i = 0; i < (0x0800 / len); i++) {
485 if (exFLASH_FindEmpty(ptr, len)) {
486 if (i == 0)
487 return 0;
488 break;
489 }
490 ptr += len / 2;
491 }
492 return ptr;
493 }
494
495 ////////////////////////////////////////////////////////////////////////////////
496 /// @brief Programs a buffer at a specified address.
497 /// @note This function can be used for all MM32 devices.
498 /// @param *buf: the pointer of the buffer to be programmed.
499 /// @param page_address: specifies the beginning of the EEprom.
500 /// The EEprom can be some continuously pages in the flash.
501 /// @param len: the number of bytes in the buffer.
502 /// This parameter can only be even.
503 /// @retval None.
504 ////////////////////////////////////////////////////////////////////////////////
exFLASH_WriteEE(u16 * buf,u32 page_address,u16 len)505 void exFLASH_WriteEE(u16* buf, u32 page_address, u16 len)
506 {
507 u16* ptr = exFLASH_Locate(page_address, len);
508 if (ptr == 0) {
509 exFLASH_EraseEE(page_address + 0x000);
510 exFLASH_EraseEE(page_address + 0x400);
511 exFLASH_ProgramEE(buf, page_address, len);
512 }
513 else {
514 if (ptr == (u16*)(page_address + ((0x0400 / len) - 1) * len)) {
515 exFLASH_EraseEE(page_address + 0x400);
516 exFLASH_ProgramEE(buf, (u32)ptr, len);
517 }
518 else if (ptr == (u16*)(page_address + 0x0800)) {
519 exFLASH_EraseEE(page_address + 0x000);
520 exFLASH_ProgramEE(buf, (u32)page_address, len);
521 }
522 else {
523 exFLASH_ProgramEE(buf, (u32)ptr, len);
524 }
525 }
526 }
527
528 ////////////////////////////////////////////////////////////////////////////////
529 /// @brief Read the beginning address of the last written data.
530 /// @note This function can be used for all MM32 devices.
531 /// @param page_address: specifies the beginning of the EEprom.
532 /// The EEprom can be some continuously pages in the flash.
533 /// @param len: the number of bytes have been written.
534 /// This parameter can only be even.
535 /// @retval the beginning address of the last written data.
536 /// 0 presents that this is the first time to use this as EEprom.
537 ////////////////////////////////////////////////////////////////////////////////
exFLASH_ReadEE(u32 page_address,u16 len)538 void* exFLASH_ReadEE(u32 page_address, u16 len)
539 {
540 u16* ptr = exFLASH_Locate(page_address, len);
541 return (ptr == 0) ? 0 : (ptr - len / 2);
542 }
543
544 /// @}
545
546 /// @}
547
548 /// @}
549