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