]> git.sur5r.net Git - freertos/blob - Demo/Common/drivers/ST/STM32F10xFWLib/src/stm32f10x_flash.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / Common / drivers / ST / STM32F10xFWLib / src / stm32f10x_flash.c
1 /**\r
2   ******************************************************************************\r
3   * @file  stm32f10x_flash.c\r
4   * @author  MCD Application Team\r
5   * @version  V3.0.0\r
6   * @date  04/06/2009\r
7   * @brief  This file provides all the FLASH firmware functions.\r
8   ******************************************************************************\r
9   * @copy\r
10   *\r
11   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
12   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
13   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
14   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
15   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
16   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
17   *\r
18   * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>\r
19   */ \r
20 \r
21 /* Includes ------------------------------------------------------------------*/\r
22 #include "stm32f10x_flash.h"\r
23 \r
24 /** @addtogroup StdPeriph_Driver\r
25   * @{\r
26   */\r
27 \r
28 /** @defgroup FLASH \r
29   * @brief FLASH driver modules\r
30   * @{\r
31   */ \r
32 \r
33 /** @defgroup FLASH_Private_TypesDefinitions\r
34   * @{\r
35   */\r
36 \r
37 /**\r
38   * @}\r
39   */ \r
40 \r
41 /** @defgroup FLASH_Private_Defines\r
42   * @{\r
43   */ \r
44 \r
45 /* Flash Access Control Register bits */\r
46 #define ACR_LATENCY_Mask         ((uint32_t)0x00000038)\r
47 #define ACR_HLFCYA_Mask          ((uint32_t)0xFFFFFFF7)\r
48 #define ACR_PRFTBE_Mask          ((uint32_t)0xFFFFFFEF)\r
49 \r
50 /* Flash Access Control Register bits */\r
51 #define ACR_PRFTBS_Mask          ((uint32_t)0x00000020) \r
52 \r
53 /* Flash Control Register bits */\r
54 #define CR_PG_Set                ((uint32_t)0x00000001)\r
55 #define CR_PG_Reset              ((uint32_t)0x00001FFE) \r
56 #define CR_PER_Set               ((uint32_t)0x00000002)\r
57 #define CR_PER_Reset             ((uint32_t)0x00001FFD)\r
58 #define CR_MER_Set               ((uint32_t)0x00000004)\r
59 #define CR_MER_Reset             ((uint32_t)0x00001FFB)\r
60 #define CR_OPTPG_Set             ((uint32_t)0x00000010)\r
61 #define CR_OPTPG_Reset           ((uint32_t)0x00001FEF)\r
62 #define CR_OPTER_Set             ((uint32_t)0x00000020)\r
63 #define CR_OPTER_Reset           ((uint32_t)0x00001FDF)\r
64 #define CR_STRT_Set              ((uint32_t)0x00000040)\r
65 #define CR_LOCK_Set              ((uint32_t)0x00000080)\r
66 \r
67 /* FLASH Mask */\r
68 #define RDPRT_Mask               ((uint32_t)0x00000002)\r
69 #define WRP0_Mask                ((uint32_t)0x000000FF)\r
70 #define WRP1_Mask                ((uint32_t)0x0000FF00)\r
71 #define WRP2_Mask                ((uint32_t)0x00FF0000)\r
72 #define WRP3_Mask                ((uint32_t)0xFF000000)\r
73 \r
74 /* FLASH Keys */\r
75 #define RDP_Key                  ((uint16_t)0x00A5)\r
76 #define FLASH_KEY1               ((uint32_t)0x45670123)\r
77 #define FLASH_KEY2               ((uint32_t)0xCDEF89AB)\r
78 \r
79 /* Delay definition */   \r
80 #define EraseTimeout             ((uint32_t)0x00000FFF)\r
81 #define ProgramTimeout           ((uint32_t)0x0000000F)\r
82 \r
83 /**\r
84   * @}\r
85   */ \r
86 \r
87 /** @defgroup FLASH_Private_Macros\r
88   * @{\r
89   */\r
90 \r
91 /**\r
92   * @}\r
93   */ \r
94 \r
95 /** @defgroup FLASH_Private_Variables\r
96   * @{\r
97   */\r
98 \r
99 /**\r
100   * @}\r
101   */ \r
102 \r
103 /** @defgroup FLASH_Private_FunctionPrototypes\r
104   * @{\r
105   */\r
106 \r
107 static void delay(void);\r
108 /**\r
109   * @}\r
110   */\r
111 \r
112 /** @defgroup FLASH_Private_Functions\r
113   * @{\r
114   */\r
115 \r
116 /**\r
117   * @brief  Sets the code latency value.\r
118   * @param FLASH_Latency: specifies the FLASH Latency value.\r
119   *   This parameter can be one of the following values:\r
120   * @arg FLASH_Latency_0: FLASH Zero Latency cycle\r
121   * @arg FLASH_Latency_1: FLASH One Latency cycle\r
122   * @arg FLASH_Latency_2: FLASH Two Latency cycles\r
123   * @retval : None\r
124   */\r
125 void FLASH_SetLatency(uint32_t FLASH_Latency)\r
126 {\r
127   uint32_t tmpreg = 0;\r
128   \r
129   /* Check the parameters */\r
130   assert_param(IS_FLASH_LATENCY(FLASH_Latency));\r
131   \r
132   /* Read the ACR register */\r
133   tmpreg = FLASH->ACR;  \r
134   \r
135   /* Sets the Latency value */\r
136   tmpreg &= ACR_LATENCY_Mask;\r
137   tmpreg |= FLASH_Latency;\r
138   \r
139   /* Write the ACR register */\r
140   FLASH->ACR = tmpreg;\r
141 }\r
142 \r
143 /**\r
144   * @brief  Enables or disables the Half cycle flash access.\r
145   * @param FLASH_HalfCycleAccess: specifies the FLASH Half cycle Access mode.\r
146   *   This parameter can be one of the following values:\r
147   * @arg FLASH_HalfCycleAccess_Enable: FLASH Half Cycle Enable\r
148   * @arg FLASH_HalfCycleAccess_Disable: FLASH Half Cycle Disable\r
149   * @retval : None\r
150   */\r
151 void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess)\r
152 {\r
153   /* Check the parameters */\r
154   assert_param(IS_FLASH_HALFCYCLEACCESS_STATE(FLASH_HalfCycleAccess));\r
155   \r
156   /* Enable or disable the Half cycle access */\r
157   FLASH->ACR &= ACR_HLFCYA_Mask;\r
158   FLASH->ACR |= FLASH_HalfCycleAccess;\r
159 }\r
160 \r
161 /**\r
162   * @brief  Enables or disables the Prefetch Buffer.\r
163   * @param FLASH_PrefetchBuffer: specifies the Prefetch buffer status.\r
164   *   This parameter can be one of the following values:\r
165   * @arg FLASH_PrefetchBuffer_Enable: FLASH Prefetch Buffer Enable\r
166   * @arg FLASH_PrefetchBuffer_Disable: FLASH Prefetch Buffer Disable\r
167   * @retval : None\r
168   */\r
169 void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer)\r
170 {\r
171   /* Check the parameters */\r
172   assert_param(IS_FLASH_PREFETCHBUFFER_STATE(FLASH_PrefetchBuffer));\r
173   \r
174   /* Enable or disable the Prefetch Buffer */\r
175   FLASH->ACR &= ACR_PRFTBE_Mask;\r
176   FLASH->ACR |= FLASH_PrefetchBuffer;\r
177 }\r
178 \r
179 /**\r
180   * @brief  Unlocks the FLASH Program Erase Controller.\r
181   * @param  None\r
182   * @retval : None\r
183   */\r
184 void FLASH_Unlock(void)\r
185 {\r
186   /* Authorize the FPEC Access */\r
187   FLASH->KEYR = FLASH_KEY1;\r
188   FLASH->KEYR = FLASH_KEY2;\r
189 }\r
190 \r
191 /**\r
192   * @brief  Locks the FLASH Program Erase Controller.\r
193   * @param  None\r
194   * @retval : None\r
195   */\r
196 void FLASH_Lock(void)\r
197 {\r
198   /* Set the Lock Bit to lock the FPEC and the FCR */\r
199   FLASH->CR |= CR_LOCK_Set;\r
200 }\r
201 \r
202 /**\r
203   * @brief  Erases a specified FLASH page.\r
204   * @param Page_Address: The page address to be erased.\r
205   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
206   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
207   *   FLASH_TIMEOUT.\r
208   */\r
209 FLASH_Status FLASH_ErasePage(uint32_t Page_Address)\r
210 {\r
211   FLASH_Status status = FLASH_COMPLETE;\r
212   /* Check the parameters */\r
213   assert_param(IS_FLASH_ADDRESS(Page_Address));\r
214   /* Wait for last operation to be completed */\r
215   status = FLASH_WaitForLastOperation(EraseTimeout);\r
216   \r
217   if(status == FLASH_COMPLETE)\r
218   { \r
219     /* if the previous operation is completed, proceed to erase the page */\r
220     FLASH->CR|= CR_PER_Set;\r
221     FLASH->AR = Page_Address; \r
222     FLASH->CR|= CR_STRT_Set;\r
223     \r
224     /* Wait for last operation to be completed */\r
225     status = FLASH_WaitForLastOperation(EraseTimeout);\r
226     if(status != FLASH_BUSY)\r
227     {\r
228       /* if the erase operation is completed, disable the PER Bit */\r
229       FLASH->CR &= CR_PER_Reset;\r
230     }\r
231   }\r
232   /* Return the Erase Status */\r
233   return status;\r
234 }\r
235 \r
236 /**\r
237   * @brief  Erases all FLASH pages.\r
238   * @param  None\r
239   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
240   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
241   *   FLASH_TIMEOUT.\r
242   */\r
243 FLASH_Status FLASH_EraseAllPages(void)\r
244 {\r
245   FLASH_Status status = FLASH_COMPLETE;\r
246   /* Wait for last operation to be completed */\r
247   status = FLASH_WaitForLastOperation(EraseTimeout);\r
248   \r
249   if(status == FLASH_COMPLETE)\r
250   {\r
251     /* if the previous operation is completed, proceed to erase all pages */\r
252      FLASH->CR |= CR_MER_Set;\r
253      FLASH->CR |= CR_STRT_Set;\r
254     \r
255     /* Wait for last operation to be completed */\r
256     status = FLASH_WaitForLastOperation(EraseTimeout);\r
257     if(status != FLASH_BUSY)\r
258     {\r
259       /* if the erase operation is completed, disable the MER Bit */\r
260       FLASH->CR &= CR_MER_Reset;\r
261     }\r
262   }        \r
263   /* Return the Erase Status */\r
264   return status;\r
265 }\r
266 \r
267 /**\r
268   * @brief  Erases the FLASH option bytes.\r
269   * @param  None\r
270   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
271   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
272   *   FLASH_TIMEOUT.\r
273   */\r
274 FLASH_Status FLASH_EraseOptionBytes(void)\r
275 {\r
276   FLASH_Status status = FLASH_COMPLETE;\r
277   \r
278   /* Wait for last operation to be completed */\r
279   status = FLASH_WaitForLastOperation(EraseTimeout);\r
280   if(status == FLASH_COMPLETE)\r
281   {\r
282     /* Authorize the small information block programming */\r
283     FLASH->OPTKEYR = FLASH_KEY1;\r
284     FLASH->OPTKEYR = FLASH_KEY2;\r
285     \r
286     /* if the previous operation is completed, proceed to erase the option bytes */\r
287     FLASH->CR |= CR_OPTER_Set;\r
288     FLASH->CR |= CR_STRT_Set;\r
289     /* Wait for last operation to be completed */\r
290     status = FLASH_WaitForLastOperation(EraseTimeout);\r
291     \r
292     if(status == FLASH_COMPLETE)\r
293     {\r
294       /* if the erase operation is completed, disable the OPTER Bit */\r
295       FLASH->CR &= CR_OPTER_Reset;\r
296        \r
297       /* Enable the Option Bytes Programming operation */\r
298       FLASH->CR |= CR_OPTPG_Set;\r
299       /* Enable the readout access */\r
300       OB->RDP= RDP_Key; \r
301       /* Wait for last operation to be completed */\r
302       status = FLASH_WaitForLastOperation(ProgramTimeout);\r
303  \r
304       if(status != FLASH_BUSY)\r
305       {\r
306         /* if the program operation is completed, disable the OPTPG Bit */\r
307         FLASH->CR &= CR_OPTPG_Reset;\r
308       }\r
309     }\r
310     else\r
311     {\r
312       if (status != FLASH_BUSY)\r
313       {\r
314         /* Disable the OPTPG Bit */\r
315         FLASH->CR &= CR_OPTPG_Reset;\r
316       }\r
317     }  \r
318   }\r
319   /* Return the erase status */\r
320   return status;\r
321 }\r
322 \r
323 /**\r
324   * @brief  Programs a word at a specified address.\r
325   * @param Address: specifies the address to be programmed.\r
326   * @param Data: specifies the data to be programmed.\r
327   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
328   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
329   *   FLASH_TIMEOUT. \r
330   */\r
331 FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)\r
332 {\r
333   FLASH_Status status = FLASH_COMPLETE;\r
334   /* Check the parameters */\r
335   assert_param(IS_FLASH_ADDRESS(Address));\r
336   /* Wait for last operation to be completed */\r
337   status = FLASH_WaitForLastOperation(ProgramTimeout);\r
338   \r
339   if(status == FLASH_COMPLETE)\r
340   {\r
341     /* if the previous operation is completed, proceed to program the new first \r
342     half word */\r
343     FLASH->CR |= CR_PG_Set;\r
344   \r
345     *(__IO uint16_t*)Address = (uint16_t)Data;\r
346     /* Wait for last operation to be completed */\r
347     status = FLASH_WaitForLastOperation(ProgramTimeout);\r
348  \r
349     if(status == FLASH_COMPLETE)\r
350     {\r
351       /* if the previous operation is completed, proceed to program the new second \r
352       half word */\r
353       *(__IO uint16_t*)(Address + 2) = Data >> 16;\r
354     \r
355       /* Wait for last operation to be completed */\r
356       status = FLASH_WaitForLastOperation(ProgramTimeout);\r
357         \r
358       if(status != FLASH_BUSY)\r
359       {\r
360         /* Disable the PG Bit */\r
361         FLASH->CR &= CR_PG_Reset;\r
362       }\r
363     }\r
364     else\r
365     {\r
366       if (status != FLASH_BUSY)\r
367       {\r
368         /* Disable the PG Bit */\r
369         FLASH->CR &= CR_PG_Reset;\r
370       }\r
371      }\r
372   }\r
373   /* Return the Program Status */\r
374   return status;\r
375 }\r
376 \r
377 /**\r
378   * @brief  Programs a half word at a specified address.\r
379   * @param Address: specifies the address to be programmed.\r
380   * @param Data: specifies the data to be programmed.\r
381   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
382   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
383   *   FLASH_TIMEOUT. \r
384   */\r
385 FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)\r
386 {\r
387   FLASH_Status status = FLASH_COMPLETE;\r
388   /* Check the parameters */\r
389   assert_param(IS_FLASH_ADDRESS(Address));\r
390   /* Wait for last operation to be completed */\r
391   status = FLASH_WaitForLastOperation(ProgramTimeout);\r
392   \r
393   if(status == FLASH_COMPLETE)\r
394   {\r
395     /* if the previous operation is completed, proceed to program the new data */\r
396     FLASH->CR |= CR_PG_Set;\r
397   \r
398     *(__IO uint16_t*)Address = Data;\r
399     /* Wait for last operation to be completed */\r
400     status = FLASH_WaitForLastOperation(ProgramTimeout);\r
401     if(status != FLASH_BUSY)\r
402     {\r
403       /* if the program operation is completed, disable the PG Bit */\r
404       FLASH->CR &= CR_PG_Reset;\r
405     }\r
406   } \r
407   /* Return the Program Status */\r
408   return status;\r
409 }\r
410 \r
411 /**\r
412   * @brief  Programs a half word at a specified Option Byte Data address.\r
413   * @param Address: specifies the address to be programmed.\r
414   *   This parameter can be 0x1FFFF804 or 0x1FFFF806. \r
415   * @param Data: specifies the data to be programmed.\r
416   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
417   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
418   *   FLASH_TIMEOUT. \r
419   */\r
420 FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data)\r
421 {\r
422   FLASH_Status status = FLASH_COMPLETE;\r
423   /* Check the parameters */\r
424   assert_param(IS_OB_DATA_ADDRESS(Address));\r
425   status = FLASH_WaitForLastOperation(ProgramTimeout);\r
426   if(status == FLASH_COMPLETE)\r
427   {\r
428     /* Authorize the small information block programming */\r
429     FLASH->OPTKEYR = FLASH_KEY1;\r
430     FLASH->OPTKEYR = FLASH_KEY2;\r
431     /* Enables the Option Bytes Programming operation */\r
432     FLASH->CR |= CR_OPTPG_Set; \r
433     *(__IO uint16_t*)Address = Data;\r
434     \r
435     /* Wait for last operation to be completed */\r
436     status = FLASH_WaitForLastOperation(ProgramTimeout);\r
437     if(status != FLASH_BUSY)\r
438     {\r
439       /* if the program operation is completed, disable the OPTPG Bit */\r
440       FLASH->CR &= CR_OPTPG_Reset;\r
441     }\r
442   }    \r
443   /* Return the Option Byte Data Program Status */\r
444   return status;\r
445 }\r
446 \r
447 /**\r
448   * @brief  Write protects the desired pages\r
449   * @param FLASH_Pages: specifies the address of the pages to be \r
450   *   write protected. This parameter can be:\r
451   * @arg For STM32F10Xxx Medium-density devices (FLASH page size equal to 1 KB)\r
452   * A value between FLASH_WRProt_Pages0to3 and FLASH_WRProt_Pages124to127\r
453   * @arg For STM32F10Xxx High-density devices (FLASH page size equal to 2 KB) \r
454   * A value between FLASH_WRProt_Pages0to1 and  FLASH_WRProt_Pages60to61 \r
455   * or FLASH_WRProt_Pages62to255 \r
456   * @arg FLASH_WRProt_AllPages\r
457   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
458   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
459   *   FLASH_TIMEOUT.\r
460   */\r
461 FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)\r
462 {\r
463   uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;\r
464   \r
465   FLASH_Status status = FLASH_COMPLETE;\r
466   \r
467   /* Check the parameters */\r
468   assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages));\r
469   \r
470   FLASH_Pages = (uint32_t)(~FLASH_Pages);\r
471   WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask);\r
472   WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8);\r
473   WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16);\r
474   WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24);\r
475   \r
476   /* Wait for last operation to be completed */\r
477   status = FLASH_WaitForLastOperation(ProgramTimeout);\r
478   \r
479   if(status == FLASH_COMPLETE)\r
480   {\r
481     /* Authorizes the small information block programming */\r
482     FLASH->OPTKEYR = FLASH_KEY1;\r
483     FLASH->OPTKEYR = FLASH_KEY2;\r
484     FLASH->CR |= CR_OPTPG_Set;\r
485     if(WRP0_Data != 0xFF)\r
486     {\r
487       OB->WRP0 = WRP0_Data;\r
488       \r
489       /* Wait for last operation to be completed */\r
490       status = FLASH_WaitForLastOperation(ProgramTimeout);\r
491     }\r
492     if((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF))\r
493     {\r
494       OB->WRP1 = WRP1_Data;\r
495       \r
496       /* Wait for last operation to be completed */\r
497       status = FLASH_WaitForLastOperation(ProgramTimeout);\r
498     }\r
499     if((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF))\r
500     {\r
501       OB->WRP2 = WRP2_Data;\r
502       \r
503       /* Wait for last operation to be completed */\r
504       status = FLASH_WaitForLastOperation(ProgramTimeout);\r
505     }\r
506     \r
507     if((status == FLASH_COMPLETE)&& (WRP3_Data != 0xFF))\r
508     {\r
509       OB->WRP3 = WRP3_Data;\r
510      \r
511       /* Wait for last operation to be completed */\r
512       status = FLASH_WaitForLastOperation(ProgramTimeout);\r
513     }\r
514           \r
515     if(status != FLASH_BUSY)\r
516     {\r
517       /* if the program operation is completed, disable the OPTPG Bit */\r
518       FLASH->CR &= CR_OPTPG_Reset;\r
519     }\r
520   } \r
521   /* Return the write protection operation Status */\r
522   return status;       \r
523 }\r
524 \r
525 /**\r
526   * @brief  Enables or disables the read out protection.\r
527   *   If the user has already programmed the other option bytes before \r
528   *   calling this function, he must re-program them since this \r
529   *   function erases all option bytes.\r
530   * @param Newstate: new state of the ReadOut Protection.\r
531   *   This parameter can be: ENABLE or DISABLE.\r
532   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
533   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
534   *   FLASH_TIMEOUT.\r
535   */\r
536 FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)\r
537 {\r
538   FLASH_Status status = FLASH_COMPLETE;\r
539   /* Check the parameters */\r
540   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
541   status = FLASH_WaitForLastOperation(EraseTimeout);\r
542   if(status == FLASH_COMPLETE)\r
543   {\r
544     /* Authorizes the small information block programming */\r
545     FLASH->OPTKEYR = FLASH_KEY1;\r
546     FLASH->OPTKEYR = FLASH_KEY2;\r
547     FLASH->CR |= CR_OPTER_Set;\r
548     FLASH->CR |= CR_STRT_Set;\r
549     /* Wait for last operation to be completed */\r
550     status = FLASH_WaitForLastOperation(EraseTimeout);\r
551     if(status == FLASH_COMPLETE)\r
552     {\r
553       /* if the erase operation is completed, disable the OPTER Bit */\r
554       FLASH->CR &= CR_OPTER_Reset;\r
555       /* Enable the Option Bytes Programming operation */\r
556       FLASH->CR |= CR_OPTPG_Set; \r
557       if(NewState != DISABLE)\r
558       {\r
559         OB->RDP = 0x00;\r
560       }\r
561       else\r
562       {\r
563         OB->RDP = RDP_Key;  \r
564       }\r
565       /* Wait for last operation to be completed */\r
566       status = FLASH_WaitForLastOperation(EraseTimeout); \r
567     \r
568       if(status != FLASH_BUSY)\r
569       {\r
570         /* if the program operation is completed, disable the OPTPG Bit */\r
571         FLASH->CR &= CR_OPTPG_Reset;\r
572       }\r
573     }\r
574     else \r
575     {\r
576       if(status != FLASH_BUSY)\r
577       {\r
578         /* Disable the OPTER Bit */\r
579         FLASH->CR &= CR_OPTER_Reset;\r
580       }\r
581     }\r
582   }\r
583   /* Return the protection operation Status */\r
584   return status;      \r
585 }\r
586 \r
587 /**\r
588   * @brief  Programs the FLASH User Option Byte: IWDG_SW / RST_STOP /\r
589   *   RST_STDBY.\r
590   * @param OB_IWDG: Selects the IWDG mode\r
591   *   This parameter can be one of the following values:\r
592   * @arg OB_IWDG_SW: Software IWDG selected\r
593   * @arg OB_IWDG_HW: Hardware IWDG selected\r
594   * @param OB_STOP: Reset event when entering STOP mode.\r
595   *   This parameter can be one of the following values:\r
596   * @arg OB_STOP_NoRST: No reset generated when entering in STOP\r
597   * @arg OB_STOP_RST: Reset generated when entering in STOP\r
598   * @param OB_STDBY: Reset event when entering Standby mode.\r
599   *   This parameter can be one of the following values:\r
600   * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY\r
601   * @arg OB_STDBY_RST: Reset generated when entering in STANDBY\r
602   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
603   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
604   *   FLASH_TIMEOUT.\r
605   */\r
606 FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY)\r
607 {\r
608   FLASH_Status status = FLASH_COMPLETE; \r
609   /* Check the parameters */\r
610   assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));\r
611   assert_param(IS_OB_STOP_SOURCE(OB_STOP));\r
612   assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));\r
613   /* Authorize the small information block programming */\r
614   FLASH->OPTKEYR = FLASH_KEY1;\r
615   FLASH->OPTKEYR = FLASH_KEY2;\r
616   \r
617   /* Wait for last operation to be completed */\r
618   status = FLASH_WaitForLastOperation(ProgramTimeout);\r
619   \r
620   if(status == FLASH_COMPLETE)\r
621   {  \r
622     /* Enable the Option Bytes Programming operation */\r
623     FLASH->CR |= CR_OPTPG_Set; \r
624            \r
625     OB->USER = ( OB_IWDG | OB_STOP |OB_STDBY) | (uint16_t)0xF8; \r
626   \r
627     /* Wait for last operation to be completed */\r
628     status = FLASH_WaitForLastOperation(ProgramTimeout);\r
629     if(status != FLASH_BUSY)\r
630     {\r
631       /* if the program operation is completed, disable the OPTPG Bit */\r
632       FLASH->CR &= CR_OPTPG_Reset;\r
633     }\r
634   }    \r
635   /* Return the Option Byte program Status */\r
636   return status;\r
637 }\r
638 \r
639 /**\r
640   * @brief  Returns the FLASH User Option Bytes values.\r
641   * @param  None\r
642   * @retval : The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1)\r
643   *   and RST_STDBY(Bit2).\r
644   */\r
645 uint32_t FLASH_GetUserOptionByte(void)\r
646 {\r
647   /* Return the User Option Byte */\r
648   return (uint32_t)(FLASH->OBR >> 2);\r
649 }\r
650 \r
651 /**\r
652   * @brief  Returns the FLASH Write Protection Option Bytes Register value.\r
653   * @param  None\r
654   * @retval : The FLASH Write Protection  Option Bytes Register value\r
655   */\r
656 uint32_t FLASH_GetWriteProtectionOptionByte(void)\r
657 {\r
658   /* Return the Falsh write protection Register value */\r
659   return (uint32_t)(FLASH->WRPR);\r
660 }\r
661 \r
662 /**\r
663   * @brief  Checks whether the FLASH Read Out Protection Status is set \r
664   *   or not.\r
665   * @param  None\r
666   * @retval : FLASH ReadOut Protection Status(SET or RESET)\r
667   */\r
668 FlagStatus FLASH_GetReadOutProtectionStatus(void)\r
669 {\r
670   FlagStatus readoutstatus = RESET;\r
671   if ((FLASH->OBR & RDPRT_Mask) != (uint32_t)RESET)\r
672   {\r
673     readoutstatus = SET;\r
674   }\r
675   else\r
676   {\r
677     readoutstatus = RESET;\r
678   }\r
679   return readoutstatus;\r
680 }\r
681 \r
682 /**\r
683   * @brief  Checks whether the FLASH Prefetch Buffer status is set or not.\r
684   * @param  None\r
685   * @retval : FLASH Prefetch Buffer Status (SET or RESET).\r
686   */\r
687 FlagStatus FLASH_GetPrefetchBufferStatus(void)\r
688 {\r
689   FlagStatus bitstatus = RESET;\r
690   \r
691   if ((FLASH->ACR & ACR_PRFTBS_Mask) != (uint32_t)RESET)\r
692   {\r
693     bitstatus = SET;\r
694   }\r
695   else\r
696   {\r
697     bitstatus = RESET;\r
698   }\r
699   /* Return the new state of FLASH Prefetch Buffer Status (SET or RESET) */\r
700   return bitstatus; \r
701 }\r
702 \r
703 /**\r
704   * @brief  Enables or disables the specified FLASH interrupts.\r
705   * @param FLASH_IT: specifies the FLASH interrupt sources to be \r
706   *   enabled or disabled.\r
707   *   This parameter can be any combination of the following values:\r
708   * @arg FLASH_IT_ERROR: FLASH Error Interrupt\r
709   * @arg FLASH_IT_EOP: FLASH end of operation Interrupt\r
710   * @param NewState: new state of the specified Flash interrupts.\r
711   *   This parameter can be: ENABLE or DISABLE.      \r
712   * @retval : None \r
713   */\r
714 void FLASH_ITConfig(uint16_t FLASH_IT, FunctionalState NewState)\r
715 {\r
716   /* Check the parameters */\r
717   assert_param(IS_FLASH_IT(FLASH_IT)); \r
718   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
719   if(NewState != DISABLE)\r
720   {\r
721     /* Enable the interrupt sources */\r
722     FLASH->CR |= FLASH_IT;\r
723   }\r
724   else\r
725   {\r
726     /* Disable the interrupt sources */\r
727     FLASH->CR &= ~(uint32_t)FLASH_IT;\r
728   }\r
729 }\r
730 \r
731 /**\r
732   * @brief  Checks whether the specified FLASH flag is set or not.\r
733   * @param FLASH_FLAG: specifies the FLASH flag to check.\r
734   *   This parameter can be one of the following values:\r
735   * @arg FLASH_FLAG_BSY: FLASH Busy flag           \r
736   * @arg FLASH_FLAG_PGERR: FLASH Program error flag       \r
737   * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag      \r
738   * @arg FLASH_FLAG_EOP: FLASH End of Operation flag           \r
739   * @arg FLASH_FLAG_OPTERR:  FLASH Option Byte error flag     \r
740   * @retval : The new state of FLASH_FLAG (SET or RESET).\r
741   */\r
742 FlagStatus FLASH_GetFlagStatus(uint16_t FLASH_FLAG)\r
743 {\r
744   FlagStatus bitstatus = RESET;\r
745   /* Check the parameters */\r
746   assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG)) ;\r
747   if(FLASH_FLAG == FLASH_FLAG_OPTERR) \r
748   {\r
749     if((FLASH->OBR & FLASH_FLAG_OPTERR) != (uint32_t)RESET)\r
750     {\r
751       bitstatus = SET;\r
752     }\r
753     else\r
754     {\r
755       bitstatus = RESET;\r
756     }\r
757   }\r
758   else\r
759   {\r
760    if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)\r
761     {\r
762       bitstatus = SET;\r
763     }\r
764     else\r
765     {\r
766       bitstatus = RESET;\r
767     }\r
768   }\r
769   /* Return the new state of FLASH_FLAG (SET or RESET) */\r
770   return bitstatus;\r
771 }\r
772 \r
773 /**\r
774   * @brief  Clears the FLASH\92s pending flags.\r
775   * @param FLASH_FLAG: specifies the FLASH flags to clear.\r
776   *   This parameter can be any combination of the following values:\r
777   * @arg FLASH_FLAG_BSY: FLASH Busy flag           \r
778   * @arg FLASH_FLAG_PGERR: FLASH Program error flag       \r
779   * @arg FLASH_FLAG_WRPRTERR: FLASH Write protected error flag      \r
780   * @arg FLASH_FLAG_EOP: FLASH End of Operation flag           \r
781   * @retval : None\r
782   */\r
783 void FLASH_ClearFlag(uint16_t FLASH_FLAG)\r
784 {\r
785   /* Check the parameters */\r
786   assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG)) ;\r
787   \r
788   /* Clear the flags */\r
789   FLASH->SR = FLASH_FLAG;\r
790 }\r
791 \r
792 /**\r
793   * @brief  Returns the FLASH Status.\r
794   * @param  None\r
795   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
796   *   FLASH_ERROR_PG, FLASH_ERROR_WRP or FLASH_COMPLETE\r
797   */\r
798 FLASH_Status FLASH_GetStatus(void)\r
799 {\r
800   FLASH_Status flashstatus = FLASH_COMPLETE;\r
801   \r
802   if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) \r
803   {\r
804     flashstatus = FLASH_BUSY;\r
805   }\r
806   else \r
807   {  \r
808     if(FLASH->SR & FLASH_FLAG_PGERR)\r
809     { \r
810       flashstatus = FLASH_ERROR_PG;\r
811     }\r
812     else \r
813     {\r
814       if(FLASH->SR & FLASH_FLAG_WRPRTERR)\r
815       {\r
816         flashstatus = FLASH_ERROR_WRP;\r
817       }\r
818       else\r
819       {\r
820         flashstatus = FLASH_COMPLETE;\r
821       }\r
822     }\r
823   }\r
824   /* Return the Flash Status */\r
825   return flashstatus;\r
826 }\r
827 \r
828 /**\r
829   * @brief  Waits for a Flash operation to complete or a TIMEOUT to occur.\r
830   * @param Timeout: FLASH progamming Timeout\r
831   * @retval : FLASH Status: The returned value can be: FLASH_BUSY, \r
832   *   FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_COMPLETE or \r
833   *   FLASH_TIMEOUT.\r
834   */\r
835 FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)\r
836\r
837   FLASH_Status status = FLASH_COMPLETE;\r
838    \r
839   /* Check for the Flash Status */\r
840   status = FLASH_GetStatus();\r
841   /* Wait for a Flash operation to complete or a TIMEOUT to occur */\r
842   while((status == FLASH_BUSY) && (Timeout != 0x00))\r
843   {\r
844     delay();\r
845     status = FLASH_GetStatus();\r
846     Timeout--;\r
847   }\r
848   if(Timeout == 0x00 )\r
849   {\r
850     status = FLASH_TIMEOUT;\r
851   }\r
852   /* Return the operation status */\r
853   return status;\r
854 }\r
855 \r
856 /**\r
857   * @brief  Inserts a time delay.\r
858   * @param  None\r
859   * @retval : None\r
860   */\r
861 static void delay(void)\r
862 {\r
863   __IO uint32_t i = 0;\r
864   for(i = 0xFF; i != 0; i--)\r
865   {\r
866   }\r
867 }\r
868 \r
869 /**\r
870   * @}\r
871   */\r
872 \r
873 /**\r
874   * @}\r
875   */\r
876 \r
877 /**\r
878   * @}\r
879   */\r
880 \r
881 /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/\r