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