1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-01-26     armink       the first version
9  */
10 
11 #include <fal.h>
12 
13 #include <stm32f2xx.h>
14 
15 /* base address of the flash sectors */
16 #define ADDR_FLASH_SECTOR_0      ((rt_uint32_t)0x08000000) /* Base address of Sector 0, 16 K bytes   */
17 #define ADDR_FLASH_SECTOR_1      ((rt_uint32_t)0x08004000) /* Base address of Sector 1, 16 K bytes   */
18 #define ADDR_FLASH_SECTOR_2      ((rt_uint32_t)0x08008000) /* Base address of Sector 2, 16 K bytes   */
19 #define ADDR_FLASH_SECTOR_3      ((rt_uint32_t)0x0800C000) /* Base address of Sector 3, 16 K bytes   */
20 #define ADDR_FLASH_SECTOR_4      ((rt_uint32_t)0x08010000) /* Base address of Sector 4, 64 K bytes   */
21 #define ADDR_FLASH_SECTOR_5      ((rt_uint32_t)0x08020000) /* Base address of Sector 5, 128 K bytes  */
22 #define ADDR_FLASH_SECTOR_6      ((rt_uint32_t)0x08040000) /* Base address of Sector 6, 128 K bytes  */
23 #define ADDR_FLASH_SECTOR_7      ((rt_uint32_t)0x08060000) /* Base address of Sector 7, 128 K bytes  */
24 #define ADDR_FLASH_SECTOR_8      ((rt_uint32_t)0x08080000) /* Base address of Sector 8, 128 K bytes  */
25 #define ADDR_FLASH_SECTOR_9      ((rt_uint32_t)0x080A0000) /* Base address of Sector 9, 128 K bytes  */
26 #define ADDR_FLASH_SECTOR_10     ((rt_uint32_t)0x080C0000) /* Base address of Sector 10, 128 K bytes */
27 #define ADDR_FLASH_SECTOR_11     ((rt_uint32_t)0x080E0000) /* Base address of Sector 11, 128 K bytes */
28 
29 /**
30  * Get the sector of a given address
31  *
32  * @param address flash address
33  *
34  * @return The sector of a given address
35  */
stm32_get_sector(rt_uint32_t address)36 static rt_uint32_t stm32_get_sector(rt_uint32_t address)
37 {
38     rt_uint32_t sector = 0;
39 
40     if ((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0))
41     {
42         sector = FLASH_Sector_0;
43     }
44     else if ((address < ADDR_FLASH_SECTOR_2) && (address >= ADDR_FLASH_SECTOR_1))
45     {
46         sector = FLASH_Sector_1;
47     }
48     else if ((address < ADDR_FLASH_SECTOR_3) && (address >= ADDR_FLASH_SECTOR_2))
49     {
50         sector = FLASH_Sector_2;
51     }
52     else if ((address < ADDR_FLASH_SECTOR_4) && (address >= ADDR_FLASH_SECTOR_3))
53     {
54         sector = FLASH_Sector_3;
55     }
56     else if ((address < ADDR_FLASH_SECTOR_5) && (address >= ADDR_FLASH_SECTOR_4))
57     {
58         sector = FLASH_Sector_4;
59     }
60     else if ((address < ADDR_FLASH_SECTOR_6) && (address >= ADDR_FLASH_SECTOR_5))
61     {
62         sector = FLASH_Sector_5;
63     }
64     else if ((address < ADDR_FLASH_SECTOR_7) && (address >= ADDR_FLASH_SECTOR_6))
65     {
66         sector = FLASH_Sector_6;
67     }
68     else if ((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7))
69     {
70         sector = FLASH_Sector_7;
71     }
72     else if ((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8))
73     {
74         sector = FLASH_Sector_8;
75     }
76     else if ((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9))
77     {
78         sector = FLASH_Sector_9;
79     }
80     else if ((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10))
81     {
82         sector = FLASH_Sector_10;
83     }
84     else
85     {
86         sector = FLASH_Sector_11;
87     }
88 
89     return sector;
90 }
91 
92 /**
93  * Get the sector size
94  *
95  * @param sector sector
96  *
97  * @return sector size
98  */
stm32_get_sector_size(rt_uint32_t sector)99 static rt_uint32_t stm32_get_sector_size(rt_uint32_t sector) {
100     RT_ASSERT(IS_FLASH_SECTOR(sector));
101 
102     switch (sector) {
103     case FLASH_Sector_0: return 16 * 1024;
104     case FLASH_Sector_1: return 16 * 1024;
105     case FLASH_Sector_2: return 16 * 1024;
106     case FLASH_Sector_3: return 16 * 1024;
107     case FLASH_Sector_4: return 64 * 1024;
108     case FLASH_Sector_5: return 128 * 1024;
109     case FLASH_Sector_6: return 128 * 1024;
110     case FLASH_Sector_7: return 128 * 1024;
111     case FLASH_Sector_8: return 128 * 1024;
112     case FLASH_Sector_9: return 128 * 1024;
113     case FLASH_Sector_10: return 128 * 1024;
114     case FLASH_Sector_11: return 128 * 1024;
115     default : return 128 * 1024;
116     }
117 }
init(void)118 static int init(void)
119 {
120     /* do nothing now */
121 }
122 
read(long offset,rt_uint8_t * buf,rt_size_t size)123 static int read(long offset, rt_uint8_t *buf, rt_size_t size)
124 {
125     rt_size_t i;
126     rt_uint32_t addr = stm32f2_onchip_flash.addr + offset;
127     for (i = 0; i < size; i++, addr++, buf++)
128     {
129         *buf = *(rt_uint8_t *) addr;
130     }
131 
132     return size;
133 }
134 
write(long offset,const rt_uint8_t * buf,rt_size_t size)135 static int write(long offset, const rt_uint8_t *buf, rt_size_t size)
136 {
137     rt_size_t i;
138     rt_uint32_t read_data;
139     rt_uint32_t addr = stm32f2_onchip_flash.addr + offset;
140 
141     FLASH_Unlock();
142     FLASH_ClearFlag(
143             FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR
144                     | FLASH_FLAG_PGSERR);
145     for (i = 0; i < size; i++, buf++, addr++)
146     {
147         /* write data */
148         FLASH_ProgramByte(addr, *buf);
149         read_data = *(rt_uint8_t *) addr;
150         /* check data */
151         if (read_data != *buf)
152         {
153             return -1;
154         }
155     }
156     FLASH_Lock();
157 
158     return size;
159 }
160 
erase(long offset,rt_size_t size)161 static int erase(long offset, rt_size_t size)
162 {
163     FLASH_Status flash_status;
164     rt_size_t erased_size = 0;
165     rt_uint32_t cur_erase_sector;
166     rt_uint32_t addr = stm32f2_onchip_flash.addr + offset;
167 
168     /* start erase */
169     FLASH_Unlock();
170     FLASH_ClearFlag(
171             FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR
172                     | FLASH_FLAG_PGSERR);
173     /* it will stop when erased size is greater than setting size */
174     while (erased_size < size)
175     {
176         cur_erase_sector = stm32_get_sector(addr + erased_size);
177         flash_status = FLASH_EraseSector(cur_erase_sector, VoltageRange_3);
178         if (flash_status != FLASH_COMPLETE)
179         {
180             return -1;
181         }
182         erased_size += stm32_get_sector_size(cur_erase_sector);
183     }
184     FLASH_Lock();
185 
186     return size;
187 }
188 
189 const struct fal_flash_dev stm32f2_onchip_flash =
190 {
191     .name       = "stm32_onchip",
192     .addr       = 0x08000000,
193     .len        = 1024*1024,
194     .blk_size   = 128*1024,
195     .ops        = {init, read, write, erase},
196     .write_gran = 8
197 };
198 
199