1 /**
2 ******************************************************************************
3 * @file bl702_sflash_ext.c
4 * @version V1.0
5 * @date
6 * @brief This file is the standard driver c file
7 ******************************************************************************
8 * @attention
9 *
10 * <h2><center>© COPYRIGHT(c) 2019 Bouffalo Lab</center></h2>
11 *
12 * Redistribution and use in source and binary forms, with or without modification,
13 * are permitted provided that the following conditions are met:
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. Neither the name of Bouffalo Lab nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 ******************************************************************************
35 */
36
37 #include "bflb_sf_ctrl.h"
38 #include "bl702_sflash_ext.h"
39 #include "l1c_reg.h"
40
41 /** @addtogroup BL702_Peripheral_Driver
42 * @{
43 */
44
45 /** @addtogroup SFLASH_EXT
46 * @{
47 */
48
49 /** @defgroup SFLASH_EXT_Private_Macros
50 * @{
51 */
52
53 /*@} end of group SFLASH_EXT_Private_Macros */
54
55 /** @defgroup SFLASH_EXT_Private_Types
56 * @{
57 */
58
59 /*@} end of group SFLASH_EXT_Private_Types */
60
61 /** @defgroup SFLASH_EXT_Private_Variables
62 * @{
63 */
64
65 /*@} end of group SFLASH_EXT_Private_Variables */
66
67 /** @defgroup SFLASH_EXT_Global_Variables
68 * @{
69 */
70
71 /*@} end of group SFLASH_EXT_Global_Variables */
72
73 /** @defgroup SFLASH_EXT_Private_Fun_Declaration
74 * @{
75 */
76
77 /*@} end of group SFLASH_EXT_Private_Fun_Declaration */
78
79 /** @defgroup SFLASH_EXT_Private_Functions
80 * @{
81 */
82
83 /*@} end of group SFLASH_EXT_Private_Functions */
84
85 /** @defgroup SFLASH_EXT_Public_Functions
86 * @{
87 */
88
89 /****************************************************************************/ /**
90 * @brief KH25V40 flash write protect set
91 *
92 * @param flash_cfg: Serial flash parameter configuration pointer
93 * @param protect: protect area
94 *
95 * @return 0 or -1
96 *
97 *******************************************************************************/
98 __WEAK
bflb_sflash_kh25v40_write_protect(spi_flash_cfg_type * flash_cfg,uint8_t protect)99 int ATTR_TCM_SECTION bflb_sflash_kh25v40_write_protect(spi_flash_cfg_type *flash_cfg, uint8_t protect)
100 {
101 uint32_t stat = 0, ret;
102
103 bflb_sflash_read_reg(flash_cfg, 0, (uint8_t *)&stat, 1);
104 if (((stat >> 2) & 0xf) == protect) {
105 return 0;
106 }
107
108 stat |= ((protect << 2) & 0xff);
109
110 ret = bflb_sflash_write_enable(flash_cfg);
111 if (0 != ret) {
112 return -1;
113 }
114
115 bflb_sflash_write_reg(flash_cfg, 0, (uint8_t *)&stat, 1);
116 bflb_sflash_read_reg(flash_cfg, 0, (uint8_t *)&stat, 1);
117 if (((stat >> 2) & 0xf) == protect) {
118 return 0;
119 }
120
121 return -1;
122 }
123
124 /****************************************************************************/ /**
125 * @brief Read flash register with read command
126 *
127 * @param flash_cfg: Serial flash parameter configuration pointer
128 * @param read_reg_cmd: read command
129 * @param reg_value: register value pointer to store data
130 * @param reg_len: register value length
131 *
132 * @return 0 or -1
133 *
134 *******************************************************************************/
135 __WEAK
bflb_sflash_read_reg_with_cmd(spi_flash_cfg_type * flash_cfg,uint8_t read_reg_cmd,uint8_t * reg_value,uint8_t reg_len)136 int ATTR_TCM_SECTION bflb_sflash_read_reg_with_cmd(spi_flash_cfg_type *flash_cfg, uint8_t read_reg_cmd, uint8_t *reg_value, uint8_t reg_len)
137 {
138 uint8_t *const flash_ctrl_buf = (uint8_t *)SF_CTRL_BUF_BASE;
139 struct sf_ctrl_cmd_cfg_type flash_cmd;
140 uint32_t cnt = 0;
141
142 if (((uint32_t)&flash_cmd) % 4 == 0) {
143 BL702_MemSet4((uint32_t *)&flash_cmd, 0, sizeof(flash_cmd) / 4);
144 } else {
145 BL702_MemSet(&flash_cmd, 0, sizeof(flash_cmd));
146 }
147
148 flash_cmd.cmd_buf[0] = read_reg_cmd << 24;
149 flash_cmd.rw_flag = SF_CTRL_READ;
150 flash_cmd.nb_data = reg_len;
151
152 bflb_sf_ctrl_sendcmd(&flash_cmd);
153
154 while (SET == bflb_sf_ctrl_get_busy_state()) {
155 BL702_Delay_US(1);
156 cnt++;
157
158 if (cnt > 1000) {
159 return -1;
160 }
161 }
162
163 BL702_MemCpy(reg_value, flash_ctrl_buf, reg_len);
164 return 0;
165 }
166
167 /****************************************************************************/ /**
168 * @brief Write flash register with write command
169 *
170 * @param flash_cfg: Serial flash parameter configuration pointer
171 * @param read_reg_cmd: write command
172 * @param reg_value: register value pointer storing data
173 * @param reg_len: register value length
174 *
175 * @return 0 or -1
176 *
177 *******************************************************************************/
178 __WEAK
bflb_sflash_write_reg_with_cmd(spi_flash_cfg_type * flash_cfg,uint8_t read_reg_cmd,uint8_t * reg_value,uint8_t reg_len)179 int ATTR_TCM_SECTION bflb_sflash_write_reg_with_cmd(spi_flash_cfg_type *flash_cfg, uint8_t read_reg_cmd, uint8_t *reg_value, uint8_t reg_len)
180 {
181 uint8_t *const flash_ctrl_buf = (uint8_t *)SF_CTRL_BUF_BASE;
182 uint32_t cnt = 0;
183 struct sf_ctrl_cmd_cfg_type flash_cmd;
184
185 if (((uint32_t)&flash_cmd) % 4 == 0) {
186 BL702_MemSet4((uint32_t *)&flash_cmd, 0, sizeof(flash_cmd) / 4);
187 } else {
188 BL702_MemSet(&flash_cmd, 0, sizeof(flash_cmd));
189 }
190
191 BL702_MemCpy(flash_ctrl_buf, reg_value, reg_len);
192
193 flash_cmd.cmd_buf[0] = read_reg_cmd << 24;
194 flash_cmd.rw_flag = SF_CTRL_WRITE;
195 flash_cmd.nb_data = reg_len;
196
197 bflb_sf_ctrl_sendcmd(&flash_cmd);
198
199 /* take 40ms for tw(write status register) as default */
200 while (SET == bflb_sflash_busy(flash_cfg)) {
201 BL702_Delay_US(100);
202 cnt++;
203
204 if (cnt > 400) {
205 return -1;
206 }
207 }
208
209 return 0;
210 }
211
212 /****************************************************************************//**
213 * @brief Clear flash status register
214 *
215 * @param p_flash_cfg: Flash configuration pointer
216 *
217 * @return 0 or -1
218 *
219 *******************************************************************************/
bflb_sflash_clear_status_register(spi_flash_cfg_type * p_flash_cfg)220 int ATTR_TCM_SECTION bflb_sflash_clear_status_register(spi_flash_cfg_type *p_flash_cfg)
221 {
222 uint32_t ret = 0;
223 uint32_t qe_value = 0;
224 uint32_t reg_value = 0;
225 uint32_t read_value = 0;
226 uint8_t readreg_value0 = 0;
227 uint8_t readreg_value1 = 0;
228
229 if((p_flash_cfg->io_mode&0xf)==SF_CTRL_QO_MODE || (p_flash_cfg->io_mode&0xf)==SF_CTRL_QIO_MODE){
230 qe_value = 1;
231 }
232
233 bflb_sflash_read_reg(p_flash_cfg, 0, (uint8_t *)&readreg_value0, 1);
234 bflb_sflash_read_reg(p_flash_cfg, 1, (uint8_t *)&readreg_value1, 1);
235 read_value = (readreg_value0|(readreg_value1<<8));
236 if ((read_value & (~((1<<(p_flash_cfg->qe_index*8+p_flash_cfg->qe_bit)) |
237 (1<<(p_flash_cfg->busy_index*8+p_flash_cfg->busy_bit)) |
238 (1<<(p_flash_cfg->wr_enable_index*8+p_flash_cfg->wr_enable_bit))))) == 0){
239 return 0;
240 }
241
242 ret = bflb_sflash_write_enable(p_flash_cfg);
243 if (0 != ret) {
244 return -1;
245 }
246 if (p_flash_cfg->qe_write_reg_len == 2) {
247 reg_value = (qe_value<<(p_flash_cfg->qe_index*8+p_flash_cfg->qe_bit));
248 bflb_sflash_write_reg(p_flash_cfg, 0, (uint8_t *)®_value, 2);
249 } else {
250 if (p_flash_cfg->qe_index == 0) {
251 reg_value = (qe_value<<p_flash_cfg->qe_bit);
252 } else {
253 reg_value = 0;
254 }
255 bflb_sflash_write_reg(p_flash_cfg, 0, (uint8_t *)®_value, 1);
256 ret = bflb_sflash_write_enable(p_flash_cfg);
257 if (0 != ret) {
258 return -1;
259 }
260 if (p_flash_cfg->qe_index == 1) {
261 reg_value = (qe_value<<p_flash_cfg->qe_bit);
262 } else {
263 reg_value = 0;
264 }
265 bflb_sflash_write_reg(p_flash_cfg, 1, (uint8_t *)®_value, 1);
266 }
267 return 0;
268 }
269
270 /*@} end of group SFLASH_EXT_Public_Functions */
271
272 /*@} end of group SFLASH_EXT */
273
274 /*@} end of group BL702_Peripheral_Driver */
275