1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 *
9 */
10
11 #include <easyflash.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stdarg.h>
15 #include <sfud.h>
16 #include <rthw.h>
17 #include <rtthread.h>
18 #include <fal.h>
19
20 /* EasyFlash partition name on FAL partition table */
21 #define FAL_EF_PART_NAME "easyflash"
22
23 /* default ENV set for user */
24 static const ef_env default_env_set[] = {
25 {"boot_times", "0"}
26 };
27
28 static char log_buf[RT_CONSOLEBUF_SIZE];
29 static struct rt_semaphore env_cache_lock;
30 static const struct fal_partition *part = NULL;
31
32 /**
33 * Flash port for hardware initialize.
34 *
35 * @param default_env default ENV set for user
36 * @param default_env_size default ENV size
37 *
38 * @return result
39 */
ef_port_init(ef_env const ** default_env,rt_size_t * default_env_size)40 EfErrCode ef_port_init(ef_env const **default_env, rt_size_t *default_env_size) {
41 EfErrCode result = EF_NO_ERR;
42
43 *default_env = default_env_set;
44 *default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]);
45
46 rt_sem_init(&env_cache_lock, "env lock", 1, RT_IPC_FLAG_PRIO);
47
48 part = fal_partition_find(FAL_EF_PART_NAME);
49 EF_ASSERT(part);
50
51 return result;
52 }
53
54 /**
55 * Read data from flash.
56 * @note This operation's units is word.
57 *
58 * @param addr flash address
59 * @param buf buffer to store read data
60 * @param size read bytes size
61 *
62 * @return result
63 */
ef_port_read(rt_uint32_t addr,rt_uint32_t * buf,rt_size_t size)64 EfErrCode ef_port_read(rt_uint32_t addr, rt_uint32_t *buf, rt_size_t size) {
65 EfErrCode result = EF_NO_ERR;
66
67 fal_partition_read(part, addr, (rt_uint8_t *)buf, size);
68
69 return result;
70 }
71
72 /**
73 * Erase data on flash.
74 * @note This operation is irreversible.
75 * @note This operation's units is different which on many chips.
76 *
77 * @param addr flash address
78 * @param size erase bytes size
79 *
80 * @return result
81 */
ef_port_erase(rt_uint32_t addr,rt_size_t size)82 EfErrCode ef_port_erase(rt_uint32_t addr, rt_size_t size) {
83 EfErrCode result = EF_NO_ERR;
84
85 /* make sure the start address is a multiple of FLASH_ERASE_MIN_SIZE */
86 EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0);
87
88 if (fal_partition_erase(part, addr, size) < 0)
89 {
90 result = EF_ERASE_ERR;
91 }
92
93 return result;
94 }
95 /**
96 * Write data to flash.
97 * @note This operation's units is word.
98 * @note This operation must after erase. @see flash_erase.
99 *
100 * @param addr flash address
101 * @param buf the write data buffer
102 * @param size write bytes size
103 *
104 * @return result
105 */
ef_port_write(rt_uint32_t addr,const rt_uint32_t * buf,rt_size_t size)106 EfErrCode ef_port_write(rt_uint32_t addr, const rt_uint32_t *buf, rt_size_t size) {
107 EfErrCode result = EF_NO_ERR;
108
109 if (fal_partition_write(part, addr, (rt_uint8_t *)buf, size) < 0)
110 {
111 result = EF_WRITE_ERR;
112 }
113
114 return result;
115 }
116
117 /**
118 * lock the ENV ram cache
119 */
ef_port_env_lock(void)120 void ef_port_env_lock(void) {
121 rt_sem_take(&env_cache_lock, RT_WAITING_FOREVER);
122 }
123
124 /**
125 * unlock the ENV ram cache
126 */
ef_port_env_unlock(void)127 void ef_port_env_unlock(void) {
128 rt_sem_release(&env_cache_lock);
129 }
130
131 /**
132 * This function is print flash debug info.
133 *
134 * @param file the file which has call this function
135 * @param line the line number which has call this function
136 * @param format output format
137 * @param ... args
138 *
139 */
ef_log_debug(const char * file,const long line,const char * format,...)140 void ef_log_debug(const char *file, const long line, const char *format, ...) {
141
142 #ifdef PRINT_DEBUG
143
144 va_list args;
145
146 /* args point to the first variable parameter */
147 va_start(args, format);
148 ef_print("[Flash] (%s:%ld) ", file, line);
149 /* must use vprintf to print */
150 rt_vsprintf(log_buf, format, args);
151 ef_print("%s", log_buf);
152 va_end(args);
153
154 #endif
155
156 }
157
158 /**
159 * This function is print flash routine info.
160 *
161 * @param format output format
162 * @param ... args
163 */
ef_log_info(const char * format,...)164 void ef_log_info(const char *format, ...) {
165 va_list args;
166
167 /* args point to the first variable parameter */
168 va_start(args, format);
169 ef_print("[Flash] ");
170 /* must use vprintf to print */
171 rt_vsprintf(log_buf, format, args);
172 ef_print("%s", log_buf);
173 va_end(args);
174 }
175 /**
176 * This function is print flash non-package info.
177 *
178 * @param format output format
179 * @param ... args
180 */
ef_print(const char * format,...)181 void ef_print(const char *format, ...) {
182 va_list args;
183
184 /* args point to the first variable parameter */
185 va_start(args, format);
186 /* must use vprintf to print */
187 rt_vsprintf(log_buf, format, args);
188 rt_kprintf("%s", log_buf);
189 va_end(args);
190 }
191