1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-12-5      SummerGift   first version
9  */
10 
11 #include <rtconfig.h>
12 #include <rtdef.h>
13 
14 #ifdef BSP_USING_ON_CHIP_FLASH
15 #include "drv_config.h"
16 #include "drv_flash.h"
17 #include <board.h>
18 
19 #if defined(RT_USING_FAL)
20 #include "fal.h"
21 #endif
22 
23 //#define DRV_DEBUG
24 #define LOG_TAG                "drv.flash"
25 #include <drv_log.h>
26 
27 /* Base address of the Flash sectors Bank 1 */
28 #define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
29 #define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
30 #define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
31 #define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
32 #define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
33 #define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
34 #define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
35 #define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
36 #define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
37 #define ADDR_FLASH_SECTOR_9     ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
38 #define ADDR_FLASH_SECTOR_10    ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
39 #define ADDR_FLASH_SECTOR_11    ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
40 
41 
42 /**
43   * @brief  Gets the sector of a given address
44   * @param  None
45   * @retval The sector of a given address
46   */
GetSector(rt_uint32_t Address)47 static rt_uint32_t GetSector(rt_uint32_t Address)
48 {
49     rt_uint32_t sector = 0;
50 
51     if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
52     {
53         sector = FLASH_SECTOR_0;
54     }
55     else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
56     {
57         sector = FLASH_SECTOR_1;
58     }
59     else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
60     {
61         sector = FLASH_SECTOR_2;
62     }
63     else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
64     {
65         sector = FLASH_SECTOR_3;
66     }
67     else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
68     {
69         sector = FLASH_SECTOR_4;
70     }
71     else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
72     {
73         sector = FLASH_SECTOR_5;
74     }
75     else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
76     {
77         sector = FLASH_SECTOR_6;
78     }
79     else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
80     {
81         sector = FLASH_SECTOR_7;
82     }
83 #if defined(FLASH_SECTOR_8)
84     else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
85     {
86         sector = FLASH_SECTOR_8;
87     }
88 #endif
89 #if defined(FLASH_SECTOR_9)
90     else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
91     {
92         sector = FLASH_SECTOR_9;
93     }
94 #endif
95 #if defined(FLASH_SECTOR_10)
96     else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
97     {
98         sector = FLASH_SECTOR_10;
99     }
100 #endif
101 #if defined(FLASH_SECTOR_11)
102     else /* (Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11) */
103     {
104         sector = FLASH_SECTOR_11;
105     }
106 #endif
107 
108     return sector;
109 }
110 
111 /**
112  * Read data from flash.
113  * @note This operation's units is word.
114  *
115  * @param addr flash address
116  * @param buf buffer to store read data
117  * @param size read bytes size
118  *
119  * @return result
120  */
stm32_flash_read(rt_uint32_t addr,rt_uint8_t * buf,size_t size)121 int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
122 {
123     size_t i;
124 
125     if ((addr + size) > STM32_FLASH_END_ADDRESS)
126     {
127         LOG_E("read outrange flash size! addr is (0x%p)", (void*)(addr + size));
128         return -1;
129     }
130 
131     for (i = 0; i < size; i++, buf++, addr++)
132     {
133         *buf = *(rt_uint8_t *) addr;
134     }
135 
136     return size;
137 }
138 
139 /**
140  * Write data to flash.
141  * @note This operation's units is word.
142  * @note This operation must after erase. @see flash_erase.
143  *
144  * @param addr flash address
145  * @param buf the write data buffer
146  * @param size write bytes size
147  *
148  * @return result
149  */
stm32_flash_write(rt_uint32_t addr,const rt_uint8_t * buf,size_t size)150 int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
151 {
152     rt_err_t result      = RT_EOK;
153     rt_uint32_t end_addr = addr + size;
154 
155     if ((end_addr) > STM32_FLASH_END_ADDRESS)
156     {
157         LOG_E("write outrange flash size! addr is (0x%p)", (void*)(addr + size));
158         return -RT_EINVAL;
159     }
160 
161     if (size < 1)
162     {
163         return -RT_EINVAL;
164     }
165 
166     HAL_FLASH_Unlock();
167 
168     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
169 
170     for (size_t i = 0; i < size; i++, addr++, buf++)
171     {
172         /* write data to flash */
173         if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, addr, (rt_uint64_t)(*buf)) == HAL_OK)
174         {
175             if (*(rt_uint8_t *)addr != *buf)
176             {
177                 result = -RT_ERROR;
178                 break;
179             }
180         }
181         else
182         {
183             result = -RT_ERROR;
184             break;
185         }
186     }
187 
188     HAL_FLASH_Lock();
189 
190     if (result != RT_EOK)
191     {
192         return result;
193     }
194 
195     return size;
196 }
197 
198 /**
199  * Erase data on flash.
200  * @note This operation is irreversible.
201  * @note This operation's units is different which on many chips.
202  *
203  * @param addr flash address
204  * @param size erase bytes size
205  *
206  * @return result
207  */
stm32_flash_erase(rt_uint32_t addr,size_t size)208 int stm32_flash_erase(rt_uint32_t addr, size_t size)
209 {
210     rt_err_t result = RT_EOK;
211     rt_uint32_t FirstSector = 0, NbOfSectors = 0;
212     rt_uint32_t SECTORError = 0;
213 
214     if ((addr + size) > STM32_FLASH_END_ADDRESS)
215     {
216         LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void*)(addr + size));
217         return -RT_EINVAL;
218     }
219 
220     /*Variable used for Erase procedure*/
221     FLASH_EraseInitTypeDef EraseInitStruct;
222 
223     /* Unlock the Flash to enable the flash control register access */
224     HAL_FLASH_Unlock();
225 
226     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
227 
228     /* Get the 1st sector to erase */
229     FirstSector = GetSector(addr);
230     /* Get the number of sector to erase from 1st sector*/
231     NbOfSectors = GetSector(addr + size - 1) - FirstSector + 1;
232     /* Fill EraseInit structure*/
233     EraseInitStruct.TypeErase     = FLASH_TYPEERASE_SECTORS;
234     EraseInitStruct.VoltageRange  = FLASH_VOLTAGE_RANGE_3;
235     EraseInitStruct.Sector        = FirstSector;
236     EraseInitStruct.NbSectors     = NbOfSectors;
237 
238     if (HAL_FLASHEx_Erase(&EraseInitStruct, (uint32_t *)&SECTORError) != HAL_OK)
239     {
240         result = -RT_ERROR;
241         goto __exit;
242     }
243 
244 __exit:
245     HAL_FLASH_Lock();
246 
247     if (result != RT_EOK)
248     {
249         return result;
250     }
251 
252     LOG_D("erase done: addr (0x%p), size %d", (void*)addr, size);
253     return result;
254 }
255 
256 #if defined(RT_USING_FAL)
257 
258 static int fal_flash_read_16k(long offset, rt_uint8_t *buf, size_t size);
259 static int fal_flash_read_64k(long offset, rt_uint8_t *buf, size_t size);
260 static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size);
261 
262 static int fal_flash_write_16k(long offset, const rt_uint8_t *buf, size_t size);
263 static int fal_flash_write_64k(long offset, const rt_uint8_t *buf, size_t size);
264 static int fal_flash_write_128k(long offset, const rt_uint8_t *buf, size_t size);
265 
266 static int fal_flash_erase_16k(long offset, size_t size);
267 static int fal_flash_erase_64k(long offset, size_t size);
268 static int fal_flash_erase_128k(long offset, size_t size);
269 
270 const struct fal_flash_dev stm32_onchip_flash_16k = { "onchip_flash_16k", STM32_FLASH_START_ADRESS_16K, FLASH_SIZE_GRANULARITY_16K, (16 * 1024), {NULL, fal_flash_read_16k, fal_flash_write_16k, fal_flash_erase_16k} };
271 const struct fal_flash_dev stm32_onchip_flash_64k = { "onchip_flash_64k", STM32_FLASH_START_ADRESS_64K, FLASH_SIZE_GRANULARITY_64K, (64 * 1024), {NULL, fal_flash_read_64k, fal_flash_write_64k, fal_flash_erase_64k} };
272 const struct fal_flash_dev stm32_onchip_flash_128k = { "onchip_flash_128k", STM32_FLASH_START_ADRESS_128K, FLASH_SIZE_GRANULARITY_128K, (128 * 1024), {NULL, fal_flash_read_128k, fal_flash_write_128k, fal_flash_erase_128k} };
273 
fal_flash_read_16k(long offset,rt_uint8_t * buf,size_t size)274 static int fal_flash_read_16k(long offset, rt_uint8_t *buf, size_t size)
275 {
276     return stm32_flash_read(stm32_onchip_flash_16k.addr + offset, buf, size);
277 }
fal_flash_read_64k(long offset,rt_uint8_t * buf,size_t size)278 static int fal_flash_read_64k(long offset, rt_uint8_t *buf, size_t size)
279 {
280     return stm32_flash_read(stm32_onchip_flash_64k.addr + offset, buf, size);
281 }
fal_flash_read_128k(long offset,rt_uint8_t * buf,size_t size)282 static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size)
283 {
284     return stm32_flash_read(stm32_onchip_flash_128k.addr + offset, buf, size);
285 }
286 
fal_flash_write_16k(long offset,const rt_uint8_t * buf,size_t size)287 static int fal_flash_write_16k(long offset, const rt_uint8_t *buf, size_t size)
288 {
289     return stm32_flash_write(stm32_onchip_flash_16k.addr + offset, buf, size);
290 }
fal_flash_write_64k(long offset,const rt_uint8_t * buf,size_t size)291 static int fal_flash_write_64k(long offset, const rt_uint8_t *buf, size_t size)
292 {
293     return stm32_flash_write(stm32_onchip_flash_64k.addr + offset, buf, size);
294 }
fal_flash_write_128k(long offset,const rt_uint8_t * buf,size_t size)295 static int fal_flash_write_128k(long offset, const rt_uint8_t *buf, size_t size)
296 {
297     return stm32_flash_write(stm32_onchip_flash_128k.addr + offset, buf, size);
298 }
299 
fal_flash_erase_16k(long offset,size_t size)300 static int fal_flash_erase_16k(long offset, size_t size)
301 {
302     return stm32_flash_erase(stm32_onchip_flash_16k.addr + offset, size);
303 }
fal_flash_erase_64k(long offset,size_t size)304 static int fal_flash_erase_64k(long offset, size_t size)
305 {
306     return stm32_flash_erase(stm32_onchip_flash_64k.addr + offset, size);
307 }
fal_flash_erase_128k(long offset,size_t size)308 static int fal_flash_erase_128k(long offset, size_t size)
309 {
310     return stm32_flash_erase(stm32_onchip_flash_128k.addr + offset, size);
311 }
312 
313 #endif
314 #endif /* BSP_USING_ON_CHIP_FLASH */
315