1 /**
2   ******************************************************************************
3   * @file    lib_flash.c
4   * @author  Application Team
5   * @version V4.3.0
6   * @date    2018-09-27
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 
22 #define FLASH_MODE_MASK     0x1F3
23 
24 /**
25   * @brief  FLASH mode initialization.
26   * @param  CSMode:
27                 FLASH_CSMODE_DISABLE
28                 FLASH_CSMODE_ALWAYSON
29                 FLASH_CSMODE_TIM2OF
30                 FLASH_CSMODE_RTC
31   * @retval None
32   */
FLASH_Init(uint32_t CSMode)33 void FLASH_Init(uint32_t CSMode)
34 {
35   uint32_t tmp;
36 
37   /* Check parameters */
38   assert_parameters(IS_FLASH_CSMODE(CSMode));
39 
40   tmp = FLASH->CTRL;
41   tmp &= ~FLASH_MODE_MASK;
42   tmp |= CSMode;
43   FLASH->CTRL = tmp;
44 }
45 
46 /**
47   * @brief  Configure FLASH interrupt.
48   * @param  IntMask:
49                 FLASH_INT_CS
50             NewState:
51                 ENABLE
52                 DISABLE
53   * @retval None
54   */
FLASH_INTConfig(uint32_t IntMask,uint32_t NewState)55 void FLASH_INTConfig(uint32_t IntMask, uint32_t NewState)
56 {
57   uint32_t tmp;
58 
59   /* Check parameters */
60   assert_parameters(IS_FLASH_INT(IntMask));
61   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
62 
63   tmp = FLASH->CTRL;
64   tmp &= ~IntMask;
65   if (NewState == ENABLE)
66   {
67     tmp |= IntMask;
68   }
69   FLASH->CTRL = tmp;
70 }
71 
72 /**
73   * @brief  Init FLASH 1USCYCLE.
74   * @param  None
75   * @retval None
76   */
FLASH_CycleInit(void)77 void FLASH_CycleInit(void)
78 {
79   uint32_t hclk;
80 
81   hclk = CLK_GetHCLKFreq();
82 
83   if (hclk > 1000000)
84     MISC2->FLASHWC = (hclk/1000000)<<8;
85   else
86     MISC2->FLASHWC = 0;
87 }
88 
89 /**
90   * @brief  Erase FLASH sector.
91   * @param  SectorAddr: sector address.
92   * @retval None
93   */
FLASH_SectorErase(uint32_t SectorAddr)94 void FLASH_SectorErase(uint32_t SectorAddr)
95 {
96   /* Check parameters */
97   assert_parameters(IS_FLASH_ADDRESS(SectorAddr));
98 
99   /* Unlock flash */
100   FLASH->PASS = FLASH_PASS_KEY;
101 
102   FLASH->PGADDR = SectorAddr;
103   FLASH->SERASE = FLASH_SERASE_KEY;
104   while (FLASH->SERASE != 0);
105 
106   /* Lock flash */
107   FLASH->PASS = 0;
108 }
109 
110 /**
111   * @brief  FLASH word program.
112   * @param  Addr: program start address
113             WordBuffer: word's buffer pointer to write
114             Length: The length of WordBuffer
115   * @retval None
116   */
FLASH_ProgramWord(uint32_t Addr,uint32_t * WordBuffer,uint32_t Length)117 void FLASH_ProgramWord(uint32_t Addr, uint32_t *WordBuffer, uint32_t Length)
118 {
119   uint32_t i;
120 
121   /* Check parameters */
122   assert_parameters(IS_FLASH_ADRRW(Addr));
123 
124   /* Unlock flash */
125   FLASH->PASS = FLASH_PASS_KEY;
126 
127   FLASH->PGADDR = Addr;
128   for (i=0; i<Length; i++)
129   {
130     FLASH->PGDATA = *(WordBuffer++);
131   }
132   while (FLASH->STS != 1);
133 
134   /* Lock flash */
135   FLASH->PASS = 0;
136 }
137 
138 /**
139   * @brief  FLASH half-word progarm.
140   * @param  Addr: program start address
141             HWordBuffer: half-word's buffer pointer to write
142             Length: The length of HWordBuffer
143   * @retval None
144   */
FLASH_ProgramHWord(uint32_t Addr,uint16_t * HWordBuffer,uint32_t Length)145 void FLASH_ProgramHWord(uint32_t Addr, uint16_t *HWordBuffer, uint32_t Length)
146 {
147   uint32_t i;
148 
149   /* Check parameters */
150   assert_parameters(IS_FLASH_ADRRHW(Addr));
151 
152   /* Unlock flash */
153   FLASH->PASS = FLASH_PASS_KEY;
154 
155   FLASH->PGADDR = Addr;
156   for (i=0; i<Length; i++)
157   {
158     if (((Addr + 2*i)&0x3) == 0)
159       *((__IO uint16_t*)(&FLASH->PGDATA)) = *(HWordBuffer++);
160     else
161       *((__IO uint16_t*)(&FLASH->PGDATA ) + 1) = *(HWordBuffer++);
162   }
163   while (FLASH->STS != 1);
164 
165   /* Lock flash */
166   FLASH->PASS = 0;
167 }
168 
169 /**
170   * @brief  FLASH byte progarm.
171   * @param  Addr: program start address
172             ByteBuffer: byte's buffer pointer to write
173             Length: The length of ByteBuffer
174   * @retval None
175   */
FLASH_ProgramByte(uint32_t Addr,uint8_t * ByteBuffer,uint32_t Length)176 void FLASH_ProgramByte(uint32_t Addr, uint8_t *ByteBuffer, uint32_t Length)
177 {
178   uint32_t i;
179 
180   /* Check parameters */
181   assert_parameters(IS_FLASH_ADDRESS(Addr));
182 
183   /* Unlock flash */
184   FLASH->PASS = FLASH_PASS_KEY;
185 
186   FLASH->PGADDR = Addr;
187   for (i=0; i<Length; i++)
188   {
189     if (((Addr + i)&0x3) == 0)
190       *((__IO uint8_t*)(&FLASH->PGDATA)) = *(ByteBuffer++);
191     else if (((Addr + i)&0x3) == 1)
192       *((__IO uint8_t*)(&FLASH->PGDATA) + 1) = *(ByteBuffer++);
193     else if (((Addr + i)&0x3) == 2)
194       *((__IO uint8_t*)(&FLASH->PGDATA) + 2) = *(ByteBuffer++);
195     else
196       *((__IO uint8_t*)(&FLASH->PGDATA) + 3) = *(ByteBuffer++);
197   }
198   while (FLASH->STS != 1);
199 
200   /* Lock flash */
201   FLASH->PASS = 0;
202 }
203 
204 /**
205   * @brief  Get Write status.
206   * @param  None.
207   * @retval FLASH_WSTA_BUSY
208             FLASH_WSTA_FINISH
209   */
FLASH_GetWriteStatus(void)210 uint32_t FLASH_GetWriteStatus(void)
211 {
212   if (FLASH->STS == 1)
213   {
214     return FLASH_WSTA_FINISH;
215   }
216   else
217   {
218     return FLASH_WSTA_BUSY;
219   }
220 }
221 
222 /**
223   * @brief  Set checksum range.
224   * @param  AddrStart: checksum start address
225             AddrEnd: checksum end address
226   * @retval None
227   */
FLASH_SetCheckSumRange(uint32_t AddrStart,uint32_t AddrEnd)228 void FLASH_SetCheckSumRange(uint32_t AddrStart, uint32_t AddrEnd)
229 {
230   /* Check parameters */
231   assert_parameters(IS_FLASH_CHECKSUMADDR(AddrStart,AddrEnd));
232 
233   FLASH->CSSADDR = AddrStart;
234   FLASH->CSEADDR = AddrEnd;
235 }
236 
237 /**
238   * @brief  Set checksum compare value.
239   * @param  Checksum: checksum compare value
240   * @retval None
241   */
FLASH_SetCheckSumCompValue(uint32_t Checksum)242 void FLASH_SetCheckSumCompValue(uint32_t Checksum)
243 {
244   FLASH->CSCVALUE = Checksum;
245 }
246 
247 /**
248   * @brief  Get FLASH checksum value.
249   * @param  None
250   * @retval Checksum
251   */
FLASH_GetCheckSum(void)252 uint32_t FLASH_GetCheckSum(void)
253 {
254   return FLASH->CSVALUE;
255 }
256 
257 
258 /**
259   * @brief  Get FLASH interrupt status.
260   * @param  IntMask:
261                 FLASH_INT_CS
262   * @retval 1: interrupt status set
263             0: interrupt status reset
264   */
FLASH_GetINTStatus(uint32_t IntMask)265 uint8_t FLASH_GetINTStatus(uint32_t IntMask)
266 {
267   /* Check parameters */
268   assert_parameters(IS_FLASH_INT(IntMask));
269 
270   if (FLASH->INT&FLASH_INT_CSERR)
271   {
272     return 1;
273   }
274   else
275   {
276     return 0;
277   }
278 }
279 
280 /**
281   * @brief  Clear FLASH interrupt status.
282   * @param  IntMask:
283                 FLASH_INT_CS
284   * @retval None
285   */
FLASH_ClearINTStatus(uint32_t IntMask)286 void FLASH_ClearINTStatus(uint32_t IntMask)
287 {
288   /* Check parameters */
289   assert_parameters(IS_FLASH_INT(IntMask));
290 
291   if (IntMask == FLASH_INT_CS)
292   {
293     FLASH->INT = FLASH_INT_CSERR;
294   }
295 }
296 
297 /*********************************** END OF FILE ******************************/
298