1 /*
2 * Copyright (c) 2015, Armink, <armink.ztl@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * 'Software'), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Function: Portable interface for stm32f4xx platform.
24 * Created on: 2015-01-16
25 */
26 #include <common/bk_include.h>
27 #include <easyflash.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31
32 #if CONFIG_FLASH_ORIGIN_API
33 #include "bk_flash.h"
34 #include "flash.h"
35 #else
36 #include "driver/flash.h"
37 #endif
38
39 #include <os/os.h>
40 #include "bk_uart.h"
41 #include "bk_drv_model.h"
42
43 /* default ENV set for user */
44 static const ef_env default_env_set[] = {
45 {"user", "user"},
46 };
47
48 static beken_semaphore_t env_cache_lock = NULL;
49
50 #ifdef PRINT_DEBUG
51 static char log_buf[256];
52 #endif
53
54 /**
55 * Flash port for hardware initialize.
56 *
57 * @param default_env default ENV set for user
58 * @param default_env_size default ENV size
59 *
60 * @return result
61 */
ef_port_init(ef_env const ** default_env,size_t * default_env_size)62 EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size)
63 {
64 bk_err_t ret;
65 EfErrCode result = EF_NO_ERR;
66
67 *default_env = default_env_set;
68 *default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]);
69
70 ret = rtos_init_semaphore_adv(&env_cache_lock, 1, 1);
71 BK_ASSERT(kNoErr == ret);
72
73 return result;
74 }
75
76 /**
77 * Read data from flash.
78 * @note This operation's units is word.
79 *
80 * @param addr flash address
81 * @param buf buffer to store read data
82 * @param size read bytes size
83 *
84 * @return result
85 */
ef_port_read(uint32_t addr,uint32_t * buf,size_t size)86 EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size)
87 {
88 EfErrCode result = EF_NO_ERR;
89
90 EF_ASSERT(size % 4 == 0);
91
92 #if CONFIG_FLASH_ORIGIN_API
93 flash_read((char *)buf, (unsigned long)size, addr);
94 #else
95 bk_flash_read_bytes(addr, (uint8_t *)buf, (unsigned long)size);
96 #endif
97
98 return result;
99 }
100
101 /*
102 * size param: The flash size of you want to erase in bytes.
103 * return: Returns the size of the actual erase.
104 */
bk_erase(uint32_t addr,size_t size)105 static int bk_erase(uint32_t addr, size_t size)
106 {
107 #if CONFIG_FLASH_ORIGIN_API
108 int param;
109 UINT32 status;
110 int protect_type;
111 DD_HANDLE flash_handle;
112 #else
113 flash_protect_type_t protect_type;
114 #endif
115 unsigned int _size = size;
116
117 #if CONFIG_FLASH_ORIGIN_API
118 flash_handle = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
119 ddev_control(flash_handle, CMD_FLASH_GET_PROTECT, (void *)&protect_type);
120
121 if (FLASH_PROTECT_NONE != protect_type) {
122 param = FLASH_PROTECT_NONE;
123 ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)¶m);
124 }
125 #else
126 protect_type = bk_flash_get_protect_type();
127 if (FLASH_PROTECT_NONE != protect_type) {
128 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
129 }
130 #endif
131
132 /* Calculate the start address of the flash sector(4kbytes) */
133 addr = addr & 0x00FFF000;
134
135 do {
136 #if CONFIG_FLASH_ORIGIN_API
137 flash_ctrl(CMD_FLASH_ERASE_SECTOR, &addr);
138 #else
139 bk_flash_erase_sector(addr);
140 #endif
141 addr += 4096;
142
143 if (_size < 4096)
144 _size = 0;
145 else
146 _size -= 4096;
147
148 } while (_size);
149
150 if (FLASH_PROTECT_NONE != protect_type) {
151 #if CONFIG_FLASH_ORIGIN_API
152 param = protect_type;
153 ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)¶m);
154 #else
155 bk_flash_set_protect_type(protect_type);
156 #endif
157 }
158
159 return size; // return true erase size
160 }
161
162 /**
163 * Erase data on flash.
164 * @note This operation is irreversible.
165 * @note This operation's units is different which on many chips.
166 *
167 * @param addr flash address
168 * @param size erase bytes size
169 *
170 * @return result
171 */
ef_port_erase(uint32_t addr,size_t size)172 EfErrCode ef_port_erase(uint32_t addr, size_t size)
173 {
174 EfErrCode result = EF_NO_ERR;
175
176 /* make sure the start address is a multiple of FLASH_ERASE_MIN_SIZE */
177 EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0);
178
179 bk_erase(addr, size);
180
181 return result;
182 }
183
184 /**
185 * Write data to flash.
186 * @note This operation's units is word.
187 * @note This operation must after erase. @see flash_erase.
188 *
189 * @param addr flash address
190 * @param buf the write data buffer
191 * @param size write bytes size
192 *
193 * @return result
194 */
ef_port_write(uint32_t addr,const uint32_t * buf,size_t size)195 EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size)
196 {
197 #if CONFIG_FLASH_ORIGIN_API
198 int param;
199 UINT32 status;
200 int protect_type;
201 DD_HANDLE flash_handle;
202 #else
203 flash_protect_type_t protect_type;
204 #endif
205 EfErrCode result = EF_NO_ERR;
206
207 EF_ASSERT(size % 4 == 0);
208
209 #if CONFIG_FLASH_ORIGIN_API
210 flash_handle = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
211 ddev_control(flash_handle, CMD_FLASH_GET_PROTECT, (void *)&protect_type);
212
213 if (FLASH_PROTECT_NONE != protect_type) {
214 param = FLASH_PROTECT_NONE;
215 ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)¶m);
216 }
217
218 flash_write((char *)buf, (unsigned long)size, addr);
219 if (FLASH_PROTECT_NONE != protect_type) {
220 param = protect_type;
221 ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)¶m);
222 }
223 #else
224 protect_type = bk_flash_get_protect_type();
225 if (FLASH_PROTECT_NONE != protect_type) {
226 bk_flash_set_protect_type(FLASH_PROTECT_NONE);
227 }
228
229 bk_flash_write_bytes(addr, (const uint8_t *)buf, size);
230 bk_flash_set_protect_type(protect_type);
231 #endif
232
233 return result;
234 }
235
236 /**
237 * lock the ENV ram cache
238 */
ef_port_env_lock(void)239 void ef_port_env_lock(void)
240 {
241 rtos_get_semaphore(&env_cache_lock, BEKEN_WAIT_FOREVER);
242 }
243
244 /**
245 * unlock the ENV ram cache
246 */
ef_port_env_unlock(void)247 void ef_port_env_unlock(void)
248 {
249 rtos_set_semaphore(&env_cache_lock);
250 }
251
252 /**
253 * This function is print flash debug info.
254 *
255 * @param file the file which has call this function
256 * @param line the line number which has call this function
257 * @param format output format
258 * @param ... args
259 *
260 */
ef_log_debug(const char * file,const long line,const char * format,...)261 void ef_log_debug(const char *file, const long line, const char *format, ...)
262 {
263 #ifdef PRINT_DEBUG
264 va_list args;
265
266 /* args point to the first variable parameter */
267 va_start(args, format);
268 ef_print("[Flash](%s:%ld) ", file, line);
269 /* must use vprintf to print */
270 vsprintf(log_buf, format, args);
271 ef_print("%s", log_buf);
272 va_end(args);
273 #endif
274 }
275
276 /**
277 * This function is print flash routine info.
278 *
279 * @param format output format
280 * @param ... args
281 */
ef_log_info(const char * format,...)282 void ef_log_info(const char *format, ...)
283 {
284 #ifdef PRINT_DEBUG
285 va_list args;
286
287 /* args point to the first variable parameter */
288 va_start(args, format);
289 ef_print("[Flash]");
290 /* must use vprintf to print */
291 vsprintf(log_buf, format, args);
292 ef_print("%s", log_buf);
293 va_end(args);
294 #endif
295 }
296 /**
297 * This function is print flash non-package info.
298 *
299 * @param format output format
300 * @param ... args
301 */
ef_print(const char * format,...)302 void ef_print(const char *format, ...)
303 {
304 #ifdef PRINT_DEBUG
305 va_list args;
306
307 /* args point to the first variable parameter */
308 va_start(args, format);
309 /* must use vprintf to print */
310 vsprintf(log_buf, format, args);
311 os_printf("%s", log_buf);
312 va_end(args);
313 #endif
314 }
315 // eof
316
317