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