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>&copy; 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 *)&reg_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 *)&reg_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 *)&reg_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