• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2   ****************************************************************************************
3   * @file    gr551x_spi_flash.c
4   * @author  BLE Driver Team
5   * @brief   HAL APP module driver.
6   ****************************************************************************************
7   * @attention
8   #####Copyright (c) 2019 GOODIX
9    All rights reserved.
10 
11    Redistribution and use in source and binary forms, with or without
12    modification, are permitted provided that the following conditions are met:
13    * Redistributions of source code must retain the above copyright
14     notice, this list of conditions and the following disclaimer.
15    * Redistributions in binary form must reproduce the above copyright
16      notice, this list of conditions and the following disclaimer in the
17      documentation and/or other materials provided with the distribution.
18    * Neither the name of GOODIX nor the names of its contributors may be used
19      to endorse or promote products derived from this software without
20      specific prior written permission.
21 
22    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25    ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
26    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32    POSSIBILITY OF SUCH DAMAGE.
33   ****************************************************************************************
34   */
35 
36 /*
37  * INCLUDE FILES
38  *****************************************************************************************
39  */
40 #include <string.h>
41 #include "gr55xx_hal.h"
42 #include "gr551x_spi_flash.h"
43 
44 /*
45  * DEFINES
46  *****************************************************************************************
47  */
48 #define BIT_0                             0
49 #define BIT_8                             8
50 #define BIT_16                            16
51 #define BIT_24                            24
52 
53 #define SPI_SPEED_1M                      (1000000)
54 #define SPI_SPEED_2M                      (2000000)
55 #define SPI_SPEED_4M                      (4000000)
56 #define SPI_SPEED_8M                      (8000000)
57 #define SPI_SPEED_16M                     (16000000)
58 #define SPI_SPEED_32M                     (32000000)
59 
60 #define DEFAULT_QSPI_SPEED                (SPI_SPEED_8M)
61 #define DEFAULT_QSPI_IO_CONFIG            { { APP_IO_TYPE_NORMAL, APP_IO_MUX_2, APP_IO_PIN_15}, \
62                                             { APP_IO_TYPE_NORMAL, APP_IO_MUX_2, APP_IO_PIN_9 }, \
63                                             { APP_IO_TYPE_NORMAL, APP_IO_MUX_2, APP_IO_PIN_8 }, \
64                                             { APP_IO_TYPE_NORMAL, APP_IO_MUX_2, APP_IO_PIN_14}, \
65                                             { APP_IO_TYPE_NORMAL, APP_IO_MUX_2, APP_IO_PIN_13}, \
66                                             { APP_IO_TYPE_NORMAL, APP_IO_MUX_2, APP_IO_PIN_12} }
67 #define DEFAULT_QSPI_MODE_CONFIG          { APP_QSPI_TYPE_DMA, DMA_Channel7 }
68 #define DEFAULT_QSPI_CONFIG               { (SystemCoreClock / DEFAULT_QSPI_SPEED), QSPI_CLOCK_MODE_3, 0}
69 #define DEFAULT_QSPI_PARAM_CONFIG         { APP_QSPI_ID_1, DEFAULT_QSPI_IO_CONFIG, \
70                                             DEFAULT_QSPI_MODE_CONFIG, DEFAULT_QSPI_CONFIG}
71 
72 #define DEFAULT_SPIM_SPEED                (SPI_SPEED_8M)
73 #define DEFAULT_SPIM_IO_CONFIG            { {APP_IO_TYPE_NORMAL, APP_IO_MUX_7, APP_IO_PIN_15}, \
74                                             {APP_IO_TYPE_NORMAL, APP_IO_MUX_1, APP_IO_PIN_12}, \
75                                             {APP_IO_TYPE_NORMAL, APP_IO_MUX_1, APP_IO_PIN_13}, \
76                                             {APP_IO_TYPE_NORMAL, APP_IO_MUX_1, APP_IO_PIN_14} }
77 #define DEFAULT_SPIM_MODE_CONFIG          {APP_SPI_TYPE_DMA, DMA_Channel5, DMA_Channel6}
78 #define DEFAULT_SPIM_CONFIG               {SPI_DATASIZE_8BIT, SPI_POLARITY_LOW, \
79                                            SPI_PHASE_1EDGE, (SystemCoreClock / DEFAULT_SPIM_SPEED), \
80                                            SPI_TIMODE_DISABLE, SPI_SLAVE_SELECT_0}
81 #define DEFAULT_SPIM_PARAM_CONFIG         {APP_SPI_ID_MASTER, DEFAULT_SPIM_IO_CONFIG, \
82                                            DEFAULT_SPIM_MODE_CONFIG, DEFAULT_SPIM_CONFIG}
83 
84 #define MS_5000                           5000
85 /*
86  * LOCAL VARIABLE DEFINITIONS
87  *****************************************************************************************
88  */
89 static volatile qspi_control_t g_qspi_ctl;
90 static dma_handle_t            g_dma_handle;
91 static spi_handle_t            g_spim_handle;
92 static qspi_handle_t           g_qspi_handle;
93 static flash_init_t            g_flash_init;
94 
95 /*
96  * LOCAL FUNCTION DEFINITIONS
97  *****************************************************************************************
98  */
spi_app_qspi_callback(app_qspi_evt_t * p_evt)99 static void spi_app_qspi_callback(app_qspi_evt_t *p_evt)
100 {
101     if (p_evt->type == APP_QSPI_EVT_TX_CPLT) {
102         g_qspi_ctl.qspi_tmt_done = 1;
103     }
104     if (p_evt->type == APP_QSPI_EVT_RX_DATA) {
105         g_qspi_ctl.qspi_rcv_done = 1;
106     }
107     if (p_evt->type == APP_QSPI_EVT_ERROR) {
108         g_qspi_ctl.qspi_tmt_done = 1;
109         g_qspi_ctl.qspi_rcv_done = 1;
110     }
111 }
112 
spi_app_spim_callback(app_spi_evt_t * p_evt)113 void spi_app_spim_callback(app_spi_evt_t *p_evt)
114 {
115     if (p_evt->type == APP_SPI_EVT_TX_CPLT) {
116         g_qspi_ctl.spi_tmt_done = 1;
117     }
118     if (p_evt->type == APP_SPI_EVT_RX_DATA) {
119         g_qspi_ctl.spi_rcv_done = 1;
120     }
121     if (p_evt->type == APP_SPI_EVT_ERROR) {
122         g_qspi_ctl.spi_tmt_done = 1;
123         g_qspi_ctl.spi_rcv_done = 1;
124     }
125 }
126 
spi_flash_write_enable(void)127 static void spi_flash_write_enable(void)
128 {
129     uint8_t control_frame[1] = {SPI_FLASH_CMD_WREN};
130 
131     if (FLASH_SPIM_ID == g_flash_init.spi_type) {
132         g_qspi_ctl.spi_tmt_done = 0;
133         app_spi_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
134         while (g_qspi_ctl.spi_tmt_done == 0);
135     } else {
136         g_qspi_ctl.qspi_tmt_done = 0;
137         app_qspi_transmit_async(g_qspi_ctl.qspi_id, control_frame, sizeof(control_frame));
138         while (g_qspi_ctl.qspi_tmt_done == 0);
139     }
140 
141     return;
142 }
143 
spi_flash_read_status(void)144 static uint8_t spi_flash_read_status(void)
145 {
146     uint8_t status = 0;
147 
148     if (FLASH_SPIM_ID == g_flash_init.spi_type) {
149         uint8_t control_frame[1] = {SPI_FLASH_CMD_RDSR};
150 
151         g_qspi_ctl.spi_rcv_done = 0;
152         app_spi_read_memory_async(g_qspi_ctl.spi_id, control_frame, (uint8_t*)&status, sizeof(control_frame), 1);
153         while (g_qspi_ctl.spi_rcv_done == 0);
154     } else {
155         qspi_command_t command = {
156             .instruction      = SPI_FLASH_CMD_RDSR,
157             .address          = 0,
158             .instruction_size = QSPI_INSTSIZE_08_BITS,
159             .address_size     = QSPI_ADDRSIZE_00_BITS,
160             .data_size        = QSPI_DATASIZE_08_BITS,
161             .dummy_cycles     = 0,
162             .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
163             .data_mode        = QSPI_DATA_MODE_SPI,
164             .length           = 1,
165         };
166 
167         g_qspi_ctl.qspi_rcv_done = 0;
168         app_qspi_command_receive_async(g_qspi_ctl.qspi_id, &command, (uint8_t*)&status);
169         while (g_qspi_ctl.qspi_rcv_done == 0);
170     }
171 
172     return status;
173 }
174 
spi_flash_device_size(void)175 static uint32_t spi_flash_device_size(void)
176 {
177     uint32_t flash_size = 0;
178 
179     if (FLASH_SPIM_ID == g_flash_init.spi_type) {
180         uint8_t data[ITEM_5] = {0};
181         uint8_t control_frame[ITEM_5] = {SPI_FLASH_CMD_SFUD, 0, 0, 0x34, DUMMY_BYTE};
182 
183         g_qspi_ctl.spi_rcv_done = 0;
184         app_spi_read_memory_async(g_qspi_ctl.spi_id, control_frame, data, sizeof(control_frame), sizeof(data));
185         while (g_qspi_ctl.spi_rcv_done == 0);
186 
187         if (data[ITEM_0] != 0 && data[ITEM_3] < 0xFF) {
188             flash_size = ((data[ITEM_3] << BIT_24) + (data[ITEM_2] << BIT_16) +
189                           (data[ITEM_1] << BIT_8) + (data[ITEM_0] << BIT_0) + 1) / BIT_8;
190         }
191     } else {
192         uint8_t data[ITEM_4] = {0};
193         qspi_command_t command = {
194             .instruction      = SPI_FLASH_CMD_SFUD,   // SPI_FLASH_CMD_SFUD  //SPI_FLASH_CMD_RDSR
195             .address          = 0x000034,
196             .instruction_size = QSPI_INSTSIZE_08_BITS,
197             .address_size     = QSPI_ADDRSIZE_24_BITS,
198             .data_size        = QSPI_DATASIZE_08_BITS,
199             .dummy_cycles     = 8,
200             .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
201             .data_mode        = QSPI_DATA_MODE_SPI,
202             .length           = sizeof(data),
203         };
204 
205         g_qspi_ctl.qspi_rcv_done = 0;
206         app_qspi_command_receive_async(g_qspi_ctl.qspi_id, &command, data);
207         while (g_qspi_ctl.qspi_rcv_done == 0);
208 
209         if (data[ITEM_0] != 0 && data[ITEM_3] < 0xFF) {
210             flash_size = ((data[ITEM_3] << BIT_24) + (data[ITEM_2] << BIT_16) +
211                           (data[ITEM_1] << BIT_8) + (data[ITEM_0] << BIT_0) + 1) / BIT_8;
212         }
213     }
214 
215     return flash_size;
216 }
217 
218 
spim_flash_write(uint32_t address,uint8_t * buffer,uint32_t nbytes)219 static uint32_t spim_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes)
220 {
221     uint8_t control_frame[ITEM_4] = {0};
222 
223     control_frame[ITEM_0] = SPI_FLASH_CMD_PP;
224     control_frame[ITEM_1] = (address >> BIT_16) & 0xFF;
225     control_frame[ITEM_2] = (address >> BIT_8) & 0xFF;
226     control_frame[ITEM_3] = address & 0xFF;
227 
228     g_qspi_ctl.spi_tmt_done = 0;
229     app_spi_write_memory_async(g_qspi_ctl.spi_id, control_frame, buffer, sizeof(control_frame), nbytes);
230     while (g_qspi_ctl.spi_tmt_done == 0);
231 
232     return nbytes;
233 }
234 
qspi_flash_write(uint32_t address,uint8_t * buffer,uint32_t nbytes)235 static uint32_t qspi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes)
236 {
237     qspi_command_t command = {
238         .instruction      = SPI_FLASH_CMD_PP,
239         .address          = address,
240         .instruction_size = QSPI_INSTSIZE_08_BITS,
241         .address_size     = QSPI_ADDRSIZE_24_BITS,
242         .data_size        = QSPI_DATASIZE_08_BITS,
243         .dummy_cycles     = 0,
244         .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
245         .data_mode        = QSPI_DATA_MODE_SPI,
246         .length           = nbytes,
247     };
248 
249     g_qspi_ctl.qspi_tmt_done = 0;
250     app_qspi_command_transmit_async(g_qspi_ctl.qspi_id, &command, buffer);
251     while (g_qspi_ctl.qspi_tmt_done == 0);
252 
253     return nbytes;
254 }
255 
spim_flash_read(uint32_t address,uint8_t * buffer,uint32_t nbytes)256 static uint32_t spim_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes)
257 {
258     uint8_t control_frame[ITEM_4] = {0};
259 
260     control_frame[ITEM_0] = SPI_FLASH_CMD_READ;
261     control_frame[ITEM_1] = (address >> BIT_16) & 0xFF;
262     control_frame[ITEM_2] = (address >> BIT_8) & 0xFF;
263     control_frame[ITEM_3] = address & 0xFF;
264 
265     g_qspi_ctl.spi_rcv_done = 0;
266     app_spi_read_memory_async(g_qspi_ctl.spi_id, control_frame, buffer, sizeof(control_frame), nbytes);
267     while (g_qspi_ctl.spi_rcv_done == 0);
268 
269     return nbytes;
270 }
271 
qspi_flash_read(uint32_t address,uint8_t * buffer,uint32_t nbytes)272 static uint32_t qspi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes)
273 {
274     qspi_command_t command = {
275         .instruction      = SPI_FLASH_CMD_READ,
276         .address          = address,
277         .instruction_size = QSPI_INSTSIZE_08_BITS,
278         .address_size     = QSPI_ADDRSIZE_24_BITS,
279         .data_size        = QSPI_DATASIZE_08_BITS,
280         .dummy_cycles     = 0,
281         .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
282         .data_mode        = QSPI_DATA_MODE_SPI,
283         .length           = nbytes,
284     };
285 
286     g_qspi_ctl.qspi_rcv_done = 0;
287     app_qspi_command_receive_async(g_qspi_ctl.qspi_id, &command, buffer);
288     while (g_qspi_ctl.qspi_rcv_done == 0);
289 
290     return nbytes;
291 }
292 
spim_flash_sector_erase(uint32_t address)293 bool spim_flash_sector_erase(uint32_t address)
294 {
295     uint8_t control_frame[4] = {0};
296 
297     control_frame[ITEM_0] = SPI_FLASH_CMD_SE;
298     control_frame[ITEM_1] = (address >> BIT_16) & 0xFF;
299     control_frame[ITEM_2] = (address >> BIT_8) & 0xFF;
300     control_frame[ITEM_3] = address & 0xFF;
301 
302     g_qspi_ctl.spi_tmt_done = 0;
303     app_spi_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
304     while (g_qspi_ctl.spi_tmt_done == 0);
305 
306     return true;
307 }
308 
qspi_flash_sector_erase(uint32_t address)309 bool qspi_flash_sector_erase(uint32_t address)
310 {
311     uint8_t control_frame[4] = {0};
312 
313     control_frame[ITEM_0] = SPI_FLASH_CMD_SE;
314     control_frame[ITEM_1] = (address >> BIT_16) & 0xFF;
315     control_frame[ITEM_2] = (address >> BIT_8) & 0xFF;
316     control_frame[ITEM_3] = address & 0xFF;
317 
318     g_qspi_ctl.qspi_tmt_done = 0;
319     app_qspi_transmit_async(g_qspi_ctl.qspi_id, control_frame, sizeof(control_frame));
320     while (g_qspi_ctl.qspi_tmt_done == 0);
321 
322     return true;
323 }
324 
FLASH_SPIM_ID_init(flash_init_t * p_flash_init)325 uint32_t FLASH_SPIM_ID_init(flash_init_t *p_flash_init)
326 {
327     app_spi_params_t spim_params = DEFAULT_SPIM_PARAM_CONFIG;
328 
329     spim_params.pin_cfg.cs.type     = p_flash_init->flash_io.spi_cs.gpio;
330     spim_params.pin_cfg.cs.pin      = p_flash_init->flash_io.spi_cs.pin;
331     spim_params.pin_cfg.cs.mux      = p_flash_init->flash_io.spi_cs.mux;
332     spim_params.pin_cfg.cs.pull     = APP_IO_NOPULL;
333     spim_params.pin_cfg.cs.enable   = APP_SPI_PIN_ENABLE;
334     spim_params.pin_cfg.clk.type    = p_flash_init->flash_io.spi_clk.gpio;
335     spim_params.pin_cfg.clk.pin     = p_flash_init->flash_io.spi_clk.pin;
336     spim_params.pin_cfg.clk.mux     = p_flash_init->flash_io.spi_clk.mux;
337     spim_params.pin_cfg.clk.pull    = APP_IO_NOPULL;
338     spim_params.pin_cfg.clk.enable  = APP_SPI_PIN_ENABLE;
339     spim_params.pin_cfg.mosi.type   = p_flash_init->flash_io.spi_io0.qspi_io0.gpio;
340     spim_params.pin_cfg.mosi.pin    = p_flash_init->flash_io.spi_io0.qspi_io0.pin;
341     spim_params.pin_cfg.mosi.mux    = p_flash_init->flash_io.spi_io0.qspi_io0.mux;
342     spim_params.pin_cfg.mosi.pull   = APP_IO_NOPULL;
343     spim_params.pin_cfg.mosi.enable = APP_SPI_PIN_ENABLE;
344     spim_params.pin_cfg.miso.type   = p_flash_init->flash_io.spi_io1.qspi_io1.gpio;
345     spim_params.pin_cfg.miso.pin    = p_flash_init->flash_io.spi_io1.qspi_io1.pin;
346     spim_params.pin_cfg.miso.mux    = p_flash_init->flash_io.spi_io1.qspi_io1.mux;
347     spim_params.pin_cfg.miso.pull   = APP_IO_NOPULL;
348     spim_params.pin_cfg.miso.enable = APP_SPI_PIN_ENABLE;
349 
350     g_qspi_ctl.spi_id = APP_SPI_ID_MASTER;
351 
352     app_spi_deinit(g_qspi_ctl.spi_id);
353 
354     if (app_spi_init(&spim_params, spi_app_spim_callback)) {
355         return;
356     }
357 }
358 
FLASH_SPIM_ID0_ID1_init(flash_init_t * p_flash_init,app_qspi_params_t * qspi_params)359 uint32_t FLASH_SPIM_ID0_ID1_init(flash_init_t *p_flash_init, app_qspi_params_t *qspi_params)
360 {
361     if (FLASH_QSPI_ID0 == p_flash_init->spi_type) {
362         g_qspi_ctl.qspi_id = APP_QSPI_ID_0;
363     } else {
364         g_qspi_ctl.qspi_id = APP_QSPI_ID_1;
365     }
366 
367     qspi_params->id                     = g_qspi_ctl.qspi_id;
368     qspi_params->pin_cfg.cs.type        = p_flash_init->flash_io.spi_cs.gpio;
369     qspi_params->pin_cfg.cs.pin         = p_flash_init->flash_io.spi_cs.pin;
370     qspi_params->pin_cfg.cs.mux         = p_flash_init->flash_io.spi_cs.mux;
371     qspi_params->pin_cfg.cs.pull        = APP_IO_NOPULL;
372     qspi_params->pin_cfg.cs.enable      = APP_SPI_PIN_ENABLE;
373     qspi_params->pin_cfg.clk.type       = p_flash_init->flash_io.spi_clk.gpio;
374     qspi_params->pin_cfg.clk.pin        = p_flash_init->flash_io.spi_clk.pin;
375     qspi_params->pin_cfg.clk.mux        = p_flash_init->flash_io.spi_clk.mux;
376     qspi_params->pin_cfg.clk.pull       = APP_IO_NOPULL;
377     qspi_params->pin_cfg.clk.enable     = APP_SPI_PIN_ENABLE;
378     qspi_params->pin_cfg.io_0.type      = p_flash_init->flash_io.spi_io0.qspi_io0.gpio;
379     qspi_params->pin_cfg.io_0.pin       = p_flash_init->flash_io.spi_io0.qspi_io0.pin;
380     qspi_params->pin_cfg.io_0.mux       = p_flash_init->flash_io.spi_io0.qspi_io0.mux;
381     qspi_params->pin_cfg.io_0.pull      = APP_IO_NOPULL;
382     qspi_params->pin_cfg.io_0.enable    = APP_SPI_PIN_ENABLE;
383     qspi_params->pin_cfg.io_1.type      = p_flash_init->flash_io.spi_io1.qspi_io1.gpio;
384     qspi_params->pin_cfg.io_1.pin       = p_flash_init->flash_io.spi_io1.qspi_io1.pin;
385     qspi_params->pin_cfg.io_1.mux       = p_flash_init->flash_io.spi_io1.qspi_io1.mux;
386     qspi_params->pin_cfg.io_1.pull      = APP_IO_NOPULL;
387     qspi_params->pin_cfg.io_1.enable    = APP_SPI_PIN_ENABLE;
388     qspi_params->pin_cfg.io_2.type      = p_flash_init->flash_io.qspi_io2.gpio;
389     qspi_params->pin_cfg.io_2.pin       = p_flash_init->flash_io.qspi_io2.pin;
390     qspi_params->pin_cfg.io_2.mux       = p_flash_init->flash_io.qspi_io2.mux;
391     qspi_params->pin_cfg.io_2.pull      = APP_IO_NOPULL;
392     qspi_params->pin_cfg.io_2.enable    = APP_SPI_PIN_ENABLE;
393     qspi_params->pin_cfg.io_3.type      = p_flash_init->flash_io.qspi_io3.gpio;
394     qspi_params->pin_cfg.io_3.pin       = p_flash_init->flash_io.qspi_io3.pin;
395     qspi_params->pin_cfg.io_3.mux       = p_flash_init->flash_io.qspi_io3.mux;
396     qspi_params->pin_cfg.io_3.pull      = APP_IO_NOPULL;
397     qspi_params->pin_cfg.io_3.enable    = APP_SPI_PIN_ENABLE;
398 }
399 
IO_init(app_qspi_params_t qspi_params)400 uint32_t IO_init(app_qspi_params_t qspi_params)
401 {
402     if (app_qspi_init(&qspi_params, spi_app_qspi_callback)) {
403         return false;
404     }
405     // set qspi hold/wp pin to high
406     app_io_init_t io_init = APP_IO_DEFAULT_CONFIG;
407 
408     io_init.mode = APP_IO_MODE_OUT_PUT;
409     io_init.pull = APP_IO_PULLUP;
410     io_init.pin  = qspi_params.pin_cfg.io_2.pin;
411     io_init.mux  = APP_IO_MUX_7;
412     if (app_io_init(qspi_params.pin_cfg.io_2.type, &io_init)) {
413         return false;
414     }
415 
416     io_init.mode = APP_IO_MODE_OUT_PUT;
417     io_init.pull = APP_IO_PULLUP;
418     io_init.pin  = qspi_params.pin_cfg.io_3.pin;
419     io_init.mux  = APP_IO_MUX_7;
420     if (app_io_init(qspi_params.pin_cfg.io_3.type, &io_init)) {
421         return false;
422     }
423 
424     if (app_io_write_pin(qspi_params.pin_cfg.io_2.type, qspi_params.pin_cfg.io_2.pin, APP_IO_PIN_SET)) {
425         return false;
426     }
427 
428     if (app_io_write_pin(qspi_params.pin_cfg.io_3.type, qspi_params.pin_cfg.io_3.pin, APP_IO_PIN_SET)) {
429         return false;
430     }
431 }
432 
433 /*
434  * GLOBAL FUNCTION DEFINITIONS
435  ****************************************************************************************
436  */
spi_flash_init(flash_init_t * p_flash_init)437 bool spi_flash_init(flash_init_t *p_flash_init)
438 {
439     memcpy_s(&g_flash_init, sizeof (g_flash_init), p_flash_init, sizeof(flash_init_t));
440 
441     if (FLASH_SPIM_ID == p_flash_init->spi_type) {
442         FLASH_SPIM_ID_init(p_flash_init);
443     } else if ((FLASH_QSPI_ID0 == p_flash_init->spi_type) || (FLASH_QSPI_ID1 == p_flash_init->spi_type)) {
444         app_qspi_params_t qspi_params = DEFAULT_QSPI_PARAM_CONFIG;
445         FLASH_SPIM_ID0_ID1_init(p_flash_init, &qspi_params);
446         app_qspi_deinit(g_qspi_ctl.qspi_id);
447         IO_init(qspi_params);
448     }
449 
450     return true;
451 }
452 
spi_flash_write(uint32_t address,uint8_t * buffer,uint32_t nbytes)453 uint32_t spi_flash_write(uint32_t address, uint8_t *buffer, uint32_t nbytes)
454 {
455     uint32_t page_ofs, write_size, write_cont = nbytes;
456     hal_status_t status      = HAL_OK;
457 
458     while (write_cont) {
459         page_ofs = address & 0xFF;
460         write_size = EXFLASH_SIZE_PAGE_BYTES - page_ofs;
461 
462         if (write_cont < write_size) {
463             write_size = write_cont;
464             write_cont = 0;
465         } else {
466             write_cont -= write_size;
467         }
468 
469         spi_flash_write_enable();
470 
471         if (FLASH_SPIM_ID == g_flash_init.spi_type) {
472             spim_flash_write(address, buffer, write_size);
473         } else {
474             qspi_flash_write(address, buffer, write_size);
475         }
476 
477         while (spi_flash_read_status() & 0x1);
478 
479         address += write_size;
480         buffer += write_size;
481     }
482 
483     return ((status == HAL_OK) ? nbytes : 0);
484 }
485 
spi_flash_read(uint32_t address,uint8_t * buffer,uint32_t nbytes)486 uint32_t spi_flash_read(uint32_t address, uint8_t *buffer, uint32_t nbytes)
487 {
488     uint32_t count = 0;
489 
490     if (FLASH_SPIM_ID == g_flash_init.spi_type) {
491         count = spim_flash_read(address, buffer, nbytes);
492     } else {
493         count = qspi_flash_read(address, buffer, nbytes);
494     }
495 
496     return count;
497 }
498 
spi_flash_sector_erase(uint32_t address,uint32_t size)499 bool spi_flash_sector_erase(uint32_t address, uint32_t size)
500 {
501     bool status = true;
502 
503     uint32_t erase_addr = address;
504     uint32_t sector_ofs, erase_size, erase_cont = size;
505 
506     while (erase_cont) {
507         sector_ofs = erase_addr & 0xFFF;
508         erase_size = EXFLASH_SIZE_SECTOR_BYTES - sector_ofs;
509 
510         if (erase_cont < erase_size) {
511             erase_size = erase_cont;
512             erase_cont = 0;
513         } else {
514             erase_cont -= erase_size;
515         }
516 
517         spi_flash_write_enable();
518 
519         if (FLASH_SPIM_ID == g_flash_init.spi_type) {
520             status = spim_flash_sector_erase(erase_addr);
521         } else {
522             status = qspi_flash_sector_erase(erase_addr);
523         }
524 
525         while (spi_flash_read_status() & 0x1);
526 
527         erase_addr += erase_size;
528     }
529 
530     return status;
531 }
532 
spi_flash_chip_erase(void)533 bool spi_flash_chip_erase(void)
534 {
535     hal_status_t status = HAL_OK;
536     uint8_t control_frame[1] = {SPI_FLASH_CMD_CE};
537 
538     spi_flash_write_enable();
539 
540     if (FLASH_SPIM_ID == g_flash_init.spi_type) {
541         g_qspi_ctl.spi_tmt_done = 0;
542         app_spi_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
543         while (g_qspi_ctl.spi_tmt_done == 0);
544     } else {
545         g_qspi_ctl.qspi_tmt_done = 0;
546         app_qspi_transmit_async(g_qspi_ctl.qspi_id, control_frame, sizeof(control_frame));
547         while (g_qspi_ctl.qspi_tmt_done == 0);
548     }
549     while (spi_flash_read_status() & 0x1);
550 
551     return ((status == HAL_OK) ? true : false);
552 }
553 
spi_flash_chip_reset(void)554 void spi_flash_chip_reset(void)
555 {
556     uint8_t control_frame[1] = {SPI_FLASH_CMD_RSTEN};
557 
558     if (FLASH_SPIM_ID == g_flash_init.spi_type) {
559         g_qspi_ctl.spi_tmt_done = 0;
560         app_spi_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
561         while (g_qspi_ctl.spi_tmt_done == 0);
562     } else {
563         hal_qspi_transmit(&g_qspi_handle, control_frame, sizeof(control_frame), MS_5000);
564     }
565 
566     control_frame[0] = SPI_FLASH_CMD_RST;
567     if (FLASH_SPIM_ID == g_flash_init.spi_type) {
568         g_qspi_ctl.spi_tmt_done = 0;
569         app_spi_transmit_async(g_qspi_ctl.spi_id, control_frame, sizeof(control_frame));
570         while (g_qspi_ctl.spi_tmt_done == 0);
571     } else {
572         hal_qspi_transmit(&g_qspi_handle, control_frame, sizeof(control_frame), MS_5000);
573     }
574 
575     return;
576 }
577 
spi_flash_device_id(void)578 uint32_t spi_flash_device_id(void)
579 {
580     uint8_t data[3] = {0};
581 
582     if (FLASH_SPIM_ID == g_flash_init.spi_type) {
583         uint8_t control_frame[1] = {SPI_FLASH_CMD_RDID};
584 
585         g_qspi_ctl.spi_rcv_done = 0;
586         app_spi_read_memory_async(g_qspi_ctl.spi_id, control_frame, data, sizeof(control_frame), sizeof(data));
587         while (g_qspi_ctl.spi_rcv_done == 0);
588     } else {
589         qspi_command_t command = {
590             .instruction      = SPI_FLASH_CMD_RDID,
591             .address          = 0,
592             .instruction_size = QSPI_INSTSIZE_08_BITS,
593             .address_size     = QSPI_ADDRSIZE_00_BITS,
594             .data_size        = QSPI_DATASIZE_08_BITS,
595             .dummy_cycles     = 0,
596             .instruction_address_mode = QSPI_INST_ADDR_ALL_IN_SPI,
597             .data_mode        = QSPI_DATA_MODE_SPI,
598             .length           = 3,
599         };
600 
601         g_qspi_ctl.qspi_rcv_done = 0;
602         app_qspi_command_receive_async(g_qspi_ctl.qspi_id, &command, data);
603         while (g_qspi_ctl.qspi_rcv_done == 0);
604     }
605 
606     return (((uint32_t)data[ITEM_0] << BIT_16) + ((uint32_t)data[ITEM_1] << BIT_8) + data[ITEM_2]);
607 }
608 
spi_flash_device_info(uint32_t * id,uint32_t * size)609 void spi_flash_device_info(uint32_t *id, uint32_t *size)
610 {
611     if (id == NULL || size == NULL) {
612         return;
613     }
614 
615     *id   = spi_flash_device_id();
616     *size = spi_flash_device_size();
617 
618     return;
619 }
620 
621