1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18
19 /********************************************************************************************************
20 * @file spi.c
21 *
22 * @brief This is the source file for B91
23 *
24 * @author Driver Group
25 *
26 *******************************************************************************************************/
27 #include "spi.h"
28
29 #include "timer.h"
30 #include "compiler.h"
31 static unsigned char s_hspi_tx_dma_chn;
32 static unsigned char s_hspi_rx_dma_chn;
33 static unsigned char s_pspi_tx_dma_chn;
34 static unsigned char s_pspi_rx_dma_chn;
35
36 dma_config_t hspi_tx_dma_config = {
37 .dst_req_sel = DMA_REQ_SPI_AHB_TX,//tx req
38 .src_req_sel = 0,
39 .dst_addr_ctrl = DMA_ADDR_FIX,
40 .src_addr_ctrl = DMA_ADDR_INCREMENT,//increment
41 .dstmode = DMA_HANDSHAKE_MODE,//handshake
42 .srcmode = DMA_NORMAL_MODE,
43 .dstwidth = DMA_CTR_WORD_WIDTH,//must word
44 .srcwidth = DMA_CTR_WORD_WIDTH,//must word
45 .src_burst_size = 0,//must 0
46 .read_num_en = 0,
47 .priority = 0,
48 .write_num_en = 0,
49 .auto_en = 0,//must 0
50 };
51 dma_config_t hspi_rx_dma_config = {
52 .dst_req_sel = 0,//tx req
53 .src_req_sel = DMA_REQ_SPI_AHB_RX,
54 .dst_addr_ctrl = DMA_ADDR_INCREMENT,
55 .src_addr_ctrl = DMA_ADDR_FIX,
56 .dstmode = DMA_NORMAL_MODE,
57 .srcmode = DMA_HANDSHAKE_MODE,
58 .dstwidth = DMA_CTR_WORD_WIDTH,//must word
59 .srcwidth = DMA_CTR_WORD_WIDTH,////must word
60 .src_burst_size = 0,
61 .read_num_en = 0,
62 .priority = 0,
63 .write_num_en = 0,
64 .auto_en = 0,//must 0
65 };
66
67 dma_config_t pspi_tx_dma_config = {
68 .dst_req_sel = DMA_REQ_SPI_APB_TX,//tx req
69 .src_req_sel = 0,
70 .dst_addr_ctrl = DMA_ADDR_FIX,
71 .src_addr_ctrl = DMA_ADDR_INCREMENT,//increment
72 .dstmode = DMA_HANDSHAKE_MODE,//handshake
73 .srcmode = DMA_NORMAL_MODE,
74 .dstwidth = DMA_CTR_WORD_WIDTH,//must word
75 .srcwidth = DMA_CTR_WORD_WIDTH,//must word
76 .src_burst_size = 0,//must 0
77 .read_num_en = 0,
78 .priority = 0,
79 .write_num_en = 0,
80 .auto_en = 0,//must 0
81 };
82
83 dma_config_t pspi_rx_dma_config = {
84 .dst_req_sel = 0,//tx req
85 .src_req_sel = DMA_REQ_SPI_APB_RX,
86 .dst_addr_ctrl = DMA_ADDR_INCREMENT,
87 .src_addr_ctrl = DMA_ADDR_FIX,
88 .dstmode = DMA_NORMAL_MODE,
89 .srcmode = DMA_HANDSHAKE_MODE,
90 .dstwidth = DMA_CTR_WORD_WIDTH,//must word
91 .srcwidth = DMA_CTR_WORD_WIDTH,////must word
92 .src_burst_size = 0,
93 .read_num_en = 0,
94 .priority = 0,
95 .write_num_en = 0,
96 .auto_en = 0,//must 0
97 };
98
99 /**
100 * @brief This function selects pin for hspi master or slave mode.
101 * @param[in] pin - the selected pin.
102 * @return none
103 */
hspi_set_pin_mux(hspi_pin_def_e pin)104 void hspi_set_pin_mux(hspi_pin_def_e pin)
105 {
106 if (pin != HSPI_NONE_PIN)
107 {
108 unsigned char val = 0;
109 unsigned char start_bit = (BIT_LOW_BIT(pin & 0xff) % 4) << 1;
110 unsigned char mask = (unsigned char)~BIT_RNG(start_bit, start_bit + 1);
111
112 if ((pin == HSPI_CLK_PB4_PIN) || (pin == HSPI_CSN_PB6_PIN) || (pin == HSPI_MOSI_IO0_PB3_PIN) || (pin == HSPI_MISO_IO1_PB2_PIN) || (pin == HSPI_WP_IO2_PB1_PIN) || (pin == HSPI_HOLD_IO3_PB0_PIN))
113 {
114 val = 0;//function 0
115 }
116 else if ((pin == HSPI_CLK_PA2_PIN) || (pin == HSPI_CSN_PA1_PIN) || (pin == HSPI_MOSI_IO0_PA4_PIN) || (pin == HSPI_MISO_IO1_PA3_PIN))
117 {
118 val = 2 << (start_bit);//function 2
119 reg_gpio_pad_mul_sel |= BIT(1);
120 }
121 reg_gpio_func_mux(pin) = (reg_gpio_func_mux(pin) & mask) | val;
122 gpio_function_dis(pin);
123 gpio_input_en(pin);
124 }
125 }
126
127 /**
128 * @brief This function enable hspi csn pin.
129 * @param[in] pin - the csn pin.
130 * @return none
131 */
hspi_cs_pin_en(hspi_csn_pin_def_e pin)132 void hspi_cs_pin_en(hspi_csn_pin_def_e pin)
133 {
134 hspi_set_pin_mux(pin);
135 }
136
137 /**
138 * @brief This function disable hspi csn pin.
139 * @param[in] pin - the csn pin.
140 * @return none
141 */
hspi_cs_pin_dis(hspi_csn_pin_def_e pin)142 void hspi_cs_pin_dis(hspi_csn_pin_def_e pin)
143 {
144 /**
145 * Bug fix: Move the operation of gpio_function_en to the end of the function.
146 * changed by chaofan.20210301.
147 */
148 gpio_output_en(pin);
149 gpio_input_dis(pin);
150 gpio_set_high_level(pin);
151 gpio_function_en(pin);
152 }
153
154 /**
155 * @brief This function selects pin for pspi master or slave mode.
156 * @param[in] pin - the selected pin.
157 * @return none
158 */
pspi_set_pin_mux(pspi_pin_def_e pin)159 void pspi_set_pin_mux(pspi_pin_def_e pin)
160 {
161 if (pin!= PSPI_NONE_PIN)
162 {
163 unsigned char val = 0;
164 unsigned char start_bit = (BIT_LOW_BIT(pin & 0xff) %4) << 1;
165 unsigned char mask = (unsigned char)~BIT_RNG(start_bit, start_bit + 1);
166 if ((pin == PSPI_CLK_PC5_PIN) || (pin == PSPI_CSN_PC4_PIN) || (pin == PSPI_MOSI_IO0_PC7_PIN) || (pin == PSPI_MISO_IO1_PC6_PIN))
167 {
168 val = 0;//function 0
169 }
170
171 else if ((pin == PSPI_CLK_PB5_PIN) || (pin == PSPI_CLK_PD1_PIN) || (pin == PSPI_CSN_PC0_PIN) || (pin == PSPI_CSN_PD0_PIN) || (pin == PSPI_MOSI_IO0_PB7_PIN) || (pin == PSPI_MOSI_IO0_PD3_PIN) || (pin == PSPI_MISO_IO1_PB6_PIN) || (pin == PSPI_MISO_IO1_PD2_PIN))
172 {
173 val = 1 << (start_bit);//function 1
174 }
175
176 reg_gpio_func_mux(pin) = (reg_gpio_func_mux(pin) & mask) | val;
177 gpio_function_dis(pin);
178 gpio_input_en(pin);
179 }
180 }
181 /**
182 * @brief This function enable pspi csn pin.
183 * @param[in] pin - the csn pin.
184 * @return none
185 */
pspi_cs_pin_en(pspi_csn_pin_def_e pin)186 void pspi_cs_pin_en(pspi_csn_pin_def_e pin)
187 {
188 pspi_set_pin_mux(pin);
189 }
190
191 /**
192 * @brief This function disable pspi csn pin.
193 * @param[in] pin - the csn pin.
194 * @return none
195 */
pspi_cs_pin_dis(pspi_csn_pin_def_e pin)196 void pspi_cs_pin_dis(pspi_csn_pin_def_e pin)
197 {
198 /**
199 * Bug fix: Move the operation of gpio_function_en to the end of the function.
200 * changed by chaofan.20210301.
201 */
202 gpio_output_en(pin);
203 gpio_input_dis(pin);
204 gpio_set_high_level(pin);
205 gpio_function_en(pin);
206 }
207
208 /**
209 * @brief This function configures hspi pin.
210 * @param[in] config - the pointer of pin config struct.
211 * @return none
212 */
hspi_set_pin(hspi_pin_config_t * config)213 void hspi_set_pin(hspi_pin_config_t *config)
214 {
215 hspi_set_pin_mux(config->hspi_csn_pin);
216 hspi_set_pin_mux(config->hspi_clk_pin);
217 hspi_set_pin_mux(config->hspi_mosi_io0_pin);
218 hspi_set_pin_mux(config->hspi_miso_io1_pin);
219 hspi_set_pin_mux(config->hspi_wp_io2_pin);
220 hspi_set_pin_mux(config->hspi_hold_io3_pin);
221 }
222
223 /**
224 * @brief This function configures pspi pin.
225 * @param[in] config - the pointer of pin config struct.
226 * @return none
227 */
pspi_set_pin(pspi_pin_config_t * config)228 void pspi_set_pin(pspi_pin_config_t *config)
229 {
230 pspi_set_pin_mux(config->pspi_clk_pin);
231 pspi_set_pin_mux(config->pspi_csn_pin);
232 pspi_set_pin_mux(config->pspi_mosi_io0_pin);
233 pspi_set_pin_mux(config->pspi_miso_io1_pin);
234 }
235
236 /**
237 * @brief This function selects pin for hspi master or slave.
238 * @return none
239 */
spi_slave_set_pin(void)240 void spi_slave_set_pin(void)
241 {
242 /**
243 * Bug fix: Replace the incorrectly used reg_gpio_pb_fuc_l with reg_gpio_pa_fuc_l.
244 * changed by chaofan.20210301.
245 */
246 reg_gpio_pa_fuc_l = (reg_gpio_pa_fuc_l & 0x03);//set PA1 as csn,PA2 as clk,PA3 as mosi_io0,
247 reg_gpio_pa_fuc_h = (reg_gpio_pa_fuc_l & 0xfc);//set PA4 slave miso_io1
248 gpio_function_dis(GPIO_PA1 | GPIO_PA2 | GPIO_PA3 | GPIO_PA4);
249 gpio_input_en(GPIO_PA1 | GPIO_PA2 | GPIO_PA3 | GPIO_PA4);
250 }
251
252 /**
253 * @brief This function configures the clock and working mode for SPI interface.
254 * @param[in] spi_sel - the spi module.
255 * @param[in] div_clock - the division factor for SPI module.
256 * spi_clock_out = ahb_clock / ((div_clock+1)*2)
257 * @param[in] mode - the selected working mode of SPI module.
258 * bit5:CPHA-Clock Polarity ; bit6:CPOL:CPHA-Clock Phase
259 * MODE0: CPOL = 0, CPHA =0;
260 * MODE1: CPOL = 0, CPHA =1;
261 * MODE2: CPOL = 1, CPHA =0;
262 * MODE3: CPOL = 1, CPHA =1;
263 * @return none
264 */
spi_master_init(spi_sel_e spi_sel,unsigned char div_clock,spi_mode_type_e mode)265 void spi_master_init(spi_sel_e spi_sel, unsigned char div_clock, spi_mode_type_e mode)
266 {
267 reg_spi_mode1(spi_sel) = div_clock;
268 reg_spi_mode0(spi_sel) |= FLD_SPI_MASTER_MODE;//master
269 reg_spi_mode0(spi_sel) &= (~FLD_SPI_MODE_WORK_MODE); // clear spi working mode
270 reg_spi_mode0(spi_sel) |= (mode << 5);// select SPI mode, support four modes
271 }
272
273
274 /**
275 * @brief This function configures the clock and working mode for SPI interface.
276 * @param[in] spi_sel - the spi module.
277 * @param[in] mode - the selected working mode of SPI module.
278 * bit5:CPHA-Clock Polarity ; bit6:CPOL:CPHA-Clock Phase
279 * MODE0: CPOL = 0, CPHA =0;
280 * MODE1: CPOL = 0, CPHA =1;
281 * MODE2: CPOL = 1, CPHA =0;
282 * MODE3: CPOL = 1, CPHA =1;
283 * @return none
284 * @note spi_clock_in (spi_slave_clock frequency)/3
285 */
spi_slave_init(spi_sel_e spi_sel,spi_mode_type_e mode)286 void spi_slave_init(spi_sel_e spi_sel, spi_mode_type_e mode)
287 {
288 reg_spi_mode0(spi_sel) &= (~FLD_SPI_MASTER_MODE);//slave
289 reg_spi_mode0(spi_sel) &= (~FLD_SPI_MODE_WORK_MODE); // clear spi working mode
290 reg_spi_mode0(spi_sel) |= (mode << 5);// select SPI mode, support four modes
291 }
292
293 /**
294 * @brief This function servers to set dummy cycle cnt.
295 * @param[in] spi_sel - the spi module.
296 * @param[in] dummy_cnt - the cnt of dummy clock.
297 * @return none
298 */
spi_set_dummy_cnt(spi_sel_e spi_sel,unsigned char dummy_cnt)299 void spi_set_dummy_cnt(spi_sel_e spi_sel, unsigned char dummy_cnt)
300 {
301 reg_spi_trans0(spi_sel) &= (~FLD_SPI_DUMMY_CNT);
302 reg_spi_trans0(spi_sel) |= (dummy_cnt - 1) & FLD_SPI_DUMMY_CNT;
303 }
304
305 /**
306 * @brief This function servers to set spi transfer mode.
307 * @param[in] spi_sel - the spi module.
308 * @param[in] mode - transfer mode.
309 * @return none
310 */
spi_set_transmode(spi_sel_e spi_sel,spi_tans_mode_e mode)311 void spi_set_transmode(spi_sel_e spi_sel, spi_tans_mode_e mode)
312 {
313 reg_spi_trans0(spi_sel) &= (~FLD_SPI_TRANSMODE);
314 reg_spi_trans0(spi_sel) |= (mode & 0xf) << 4;
315 }
316
317 /**
318 * @brief This function servers to set normal mode.
319 * @param[in] spi_sel - the spi module.
320 * @return none
321 */
spi_set_normal_mode(spi_sel_e spi_sel)322 void spi_set_normal_mode(spi_sel_e spi_sel)
323 {
324 spi_dual_mode_dis(spi_sel);
325 spi_3line_mode_dis(spi_sel);
326 if (HSPI_MODULE == spi_sel)
327 {
328 hspi_quad_mode_dis(spi_sel);
329 }
330 }
331
332 /**
333 * @brief This function servers to set dual mode.
334 * @param[in] spi_sel - the spi module.
335 * @return none
336 */
spi_set_dual_mode(spi_sel_e spi_sel)337 void spi_set_dual_mode(spi_sel_e spi_sel)
338 {
339 spi_dual_mode_en(spi_sel);//quad precede over dual
340 spi_3line_mode_dis(spi_sel);
341 if (HSPI_MODULE == spi_sel)
342 {
343 hspi_quad_mode_dis(spi_sel);
344 }
345 }
346
347 /**
348 * @brief This function servers to set quad mode.
349 * @return none
350 */
hspi_set_quad_mode()351 void hspi_set_quad_mode()
352 {
353 hspi_quad_mode_en();
354 spi_dual_mode_dis(HSPI_MODULE);
355 spi_3line_mode_dis(HSPI_MODULE);
356 }
357
358 /**
359 * @brief This function servers to set 3line mode.
360 * @param[in] spi_sel - the spi module.
361 * @return none
362 */
spi_set_3line_mode(spi_sel_e spi_sel)363 void spi_set_3line_mode(spi_sel_e spi_sel)
364 {
365 /*must disable dual and quad*/
366 spi_3line_mode_en(spi_sel);
367 spi_dual_mode_dis(spi_sel);
368 if (HSPI_MODULE == spi_sel)
369 {
370 hspi_quad_mode_dis(spi_sel);
371 }
372 }
373
374 /**
375 * @brief This function servers to set hspi io mode.
376 * @param[in] spi_sel - the spi module.
377 * @param[in] mode - single/dual/quad /3line.
378 * @return none
379 */
spi_set_io_mode(spi_sel_e spi_sel,spi_io_mode_e mode)380 void spi_set_io_mode(spi_sel_e spi_sel, spi_io_mode_e mode)
381 {
382 switch (mode)
383 {
384 case SPI_SINGLE_MODE:
385 spi_set_normal_mode(spi_sel);
386 break;
387 case SPI_DUAL_MODE:
388 spi_set_dual_mode(spi_sel);
389 break;
390 case HSPI_QUAD_MODE:
391 hspi_set_quad_mode();
392 break;
393 case SPI_3_LINE_MODE:
394 spi_set_3line_mode(spi_sel);
395 break;
396 }
397 }
398
399 /**
400 * @brief This function servers to config normal mode.
401 * @param[in] spi_sel - the spi module.
402 * @param[in] mode - nomal ,mode 3line.
403 * @return none
404 */
spi_master_config(spi_sel_e spi_sel,spi_nomal_3line_mode_e mode)405 void spi_master_config(spi_sel_e spi_sel, spi_nomal_3line_mode_e mode)
406 {
407 spi_cmd_dis(spi_sel);
408 if (HSPI_MODULE == spi_sel)
409 {
410 hspi_addr_dis();
411 }
412 spi_set_io_mode(spi_sel, mode);
413 }
414
415 /**
416 * @brief This function servers to config hspi special mode.
417 * @param[in] config - the pointer of pin special config struct.
418 * @return none
419 */
hspi_master_config_plus(hspi_config_t * config)420 void hspi_master_config_plus(hspi_config_t *config)
421 {
422 spi_set_io_mode(HSPI_MODULE, config->hspi_io_mode);
423 hspi_set_addr_len(config->hspi_addr_len);
424 spi_set_dummy_cnt(HSPI_MODULE, config->hspi_dummy_cnt);
425
426 if (1 == config->hspi_cmd_en)
427 {
428 spi_cmd_en(HSPI_MODULE);
429 }
430 else if (0 == config->hspi_cmd_en)
431 {
432 spi_cmd_dis(HSPI_MODULE);
433 }
434
435 if (1 == config->hspi_cmd_fmt_en)
436 {
437 hspi_cmd_fmt_en();
438 }
439 else if (0 == config->hspi_cmd_fmt_en)
440 {
441 hspi_cmd_fmt_dis();
442 }
443
444 if (1 == config->hspi_addr_en)
445 {
446 hspi_addr_en();
447 }
448 else if (0 == config->hspi_addr_en)
449 {
450 hspi_addr_dis();
451 }
452
453 if (1 == config->hspi_addr_fmt_en)
454 {
455 hspi_addr_fmt_en();
456 }
457 else if (0 == config->hspi_addr_fmt_en)
458 {
459 hspi_addr_fmt_dis();
460 }
461 }
462
463 /**
464 * @brief This function servers to config pspi special mode.
465 * @param[in] config - the pointer of pin special config struct.
466 * @return none
467 */
pspi_master_config_plus(pspi_config_t * config)468 void pspi_master_config_plus(pspi_config_t *config)
469 {
470 spi_set_io_mode(PSPI_MODULE, config->pspi_io_mode);
471 spi_set_dummy_cnt(PSPI_MODULE, config->pspi_dummy_cnt);
472 if (1 == config->pspi_cmd_en)
473 {
474 spi_cmd_en(PSPI_MODULE);
475 }
476 else if (0 == config->pspi_cmd_en)
477 {
478 spi_cmd_dis(PSPI_MODULE);
479 }
480 }
481
482 /**
483 * @brief This function servers to set slave address hspi only.
484 * @param[in] addr - address of slave.
485 * @return none
486 */
hspi_set_address(unsigned int addr)487 void hspi_set_address(unsigned int addr)
488 {
489 reg_hspi_addr_32 = addr;
490 }
491
492 /**
493 * @brief This function servers to write hspi fifo.
494 * @param[in] spi_sel - the spi module.
495 * @param[in] data - the pointer to the data for write.
496 * @param[in] len - write length.
497 * @return none
498 */
spi_write(spi_sel_e spi_sel,unsigned char * data,unsigned int len)499 void spi_write(spi_sel_e spi_sel, unsigned char *data, unsigned int len)
500 {
501 for (unsigned int i = 0; i < len; i++)
502 {
503 while (reg_spi_fifo_state(spi_sel) & FLD_SPI_TXF_FULL);
504 reg_spi_wr_rd_data(spi_sel, i % REG_SPI_WR_RD_SIZE) = data[i];
505 }
506 }
507
508
509 /**
510 * @brief This function servers to read hspi fifo.
511 * @param[in] spi_sel - the spi module.
512 * @param[in] data - the pointer to the data for read.
513 * @param[in] len - write length.
514 * @return none
515 */
spi_read(spi_sel_e spi_sel,unsigned char * data,unsigned int len)516 void spi_read(spi_sel_e spi_sel, unsigned char *data, unsigned int len)
517 {
518 for (unsigned int i = 0; i < len; i++)
519 {
520 while (reg_spi_fifo_state(spi_sel) & FLD_SPI_RXF_EMPTY);
521 data[i] = reg_spi_wr_rd_data(spi_sel, i % REG_SPI_WR_RD_SIZE);
522 }
523 }
524
525 /**
526 * @brief This function serves to normal write data in normal.
527 * @param[in] spi_sel - the spi module.
528 * @param[in] data - the pointer to the data for write.
529 * @param[in] len - write length.
530 * @return none
531 */
spi_master_write(spi_sel_e spi_sel,unsigned char * data,unsigned int len)532 void spi_master_write(spi_sel_e spi_sel, unsigned char *data, unsigned int len)
533 {
534 spi_tx_fifo_clr(spi_sel);
535 spi_tx_cnt(spi_sel, len);
536 spi_set_transmode(spi_sel, SPI_MODE_WRITE_ONLY);
537 spi_set_cmd(spi_sel, 0x00);//when cmd disable that will not sent cmd,just trigger spi send .
538 spi_write(spi_sel, (unsigned char *)data, len);
539 while (spi_is_busy(spi_sel));
540 }
541
542 /**
543 * @brief This function serves to normal write and read data.
544 * @param[in] spi_sel - the spi module.
545 * @param[in] wr_data - the pointer to the data for write.
546 * @param[in] wr_len - write length.
547 * @param[in] rd_data - the pointer to the data for read.
548 * @param[in] rd_len - read length.
549 * @return none
550 */
spi_master_write_read(spi_sel_e spi_sel,unsigned char * wr_data,unsigned int wr_len,unsigned char * rd_data,unsigned int rd_len)551 void spi_master_write_read(spi_sel_e spi_sel, unsigned char *wr_data, unsigned int wr_len, unsigned char *rd_data, unsigned int rd_len)
552 {
553 spi_tx_fifo_clr(spi_sel);
554 spi_rx_fifo_clr(spi_sel);
555 spi_tx_cnt(spi_sel, wr_len);
556 spi_rx_cnt(spi_sel, rd_len);
557 spi_set_transmode(spi_sel, SPI_MODE_WRITE_READ);
558 spi_set_cmd(spi_sel, 0x00);//when cmd disable that will not sent cmd,just trigger spi send .
559 spi_write(spi_sel, (unsigned char *)wr_data, wr_len);
560 spi_read(spi_sel, (unsigned char *)rd_data, rd_len);
561 while (spi_is_busy(spi_sel));
562 }
563
564 /**
565 * @brief This function serves to write and read data simultaneously
566 * @param[in] spi_sel - the spi module.
567 * @param[in] write_data - write data pointer.
568 * @param[in] read_data - read data pointer.
569 * @param[in] len - write/read length.
570 * @return none
571 */
spi_master_write_read_loopback(spi_sel_e spi_sel,unsigned char * write_data,unsigned char * read_data,unsigned int len)572 void spi_master_write_read_loopback(spi_sel_e spi_sel,
573 unsigned char *write_data,
574 unsigned char *read_data,
575 unsigned int len)
576 {
577 unsigned int chunk_size = REG_SPI_WR_RD_SIZE;
578
579 spi_set_transmode(spi_sel, SPI_MODE_WRITE_AND_READ);
580 spi_set_cmd(spi_sel, 0);
581 spi_tx_fifo_clr(spi_sel);
582 spi_rx_fifo_clr(spi_sel);
583 spi_tx_cnt(spi_sel, len);
584 spi_rx_cnt(spi_sel, len);
585
586 /* write and read bytes in chunks */
587 for(int i=0; i<len; i=i+chunk_size)
588 {
589 /* check for tail */
590 if(chunk_size > (len-i))
591 {
592 chunk_size = len-i;
593 }
594
595 /* write bytes */
596 spi_write(spi_sel, write_data + i, chunk_size);
597
598 /* read bytes */
599 if(len <= REG_SPI_WR_RD_SIZE)
600 {
601 /* read all bytes if len is less than 4 (data0 .. data3)*/
602 spi_read(spi_sel, read_data, chunk_size);
603 }
604 else if(i==0)
605 {
606 /* head, read 1 byte less than is sent */
607 spi_read(spi_sel, read_data, chunk_size - 1);
608 }
609 else if((len-i) > REG_SPI_WR_RD_SIZE)
610 {
611 /* body, read so many bytes as is sent*/
612 spi_read(spi_sel, read_data + i-1, chunk_size);
613 }
614 else
615 {
616 /* tail, read the rest bytes */
617 spi_read(spi_sel, read_data + i-1, chunk_size + 1);
618 }
619
620 /* clear TX and RX fifo */
621 spi_tx_fifo_clr(spi_sel);
622 spi_rx_fifo_clr(spi_sel);
623 }
624
625 while (spi_is_busy(spi_sel));
626 }
627
628 /**
629 * @brief This function serves to single/dual/quad write to the SPI slave.
630 * @param[in] spi_sel - the spi module.
631 * @param[in] cmd - cmd one byte will first write.
632 * @param[in] addr - the address of slave.
633 * @param[in] data - pointer to the data need to write.
634 * @param[in] data_len - length in byte of the data need to write.
635 * @param[in] wr_mode - write mode.dummy or not dummy.
636 * @return none
637 */
spi_master_write_plus(spi_sel_e spi_sel,unsigned char cmd,unsigned int addr,unsigned char * data,unsigned int data_len,spi_wr_tans_mode_e wr_mode)638 void spi_master_write_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode)
639 {
640 spi_tx_fifo_clr(spi_sel);
641 if (HSPI_MODULE == spi_sel)
642 {
643 hspi_set_address(addr);
644 }
645 spi_set_transmode(spi_sel, wr_mode);
646
647 spi_tx_cnt(spi_sel, data_len);
648 spi_set_cmd(spi_sel, cmd);
649 spi_write(spi_sel, (unsigned char *)data, data_len);
650 while (spi_is_busy(spi_sel));
651 }
652
653 /**
654 * @brief This function serves to single/dual/quad read from the SPI slave.
655 * @param[in] spi_sel - the spi module.
656 * @param[in] cmd - cmd one byte will first write.
657 * @param[in] addr - the address of slave.
658 * @param[in] data - pointer to the data need to read.
659 * @param[in] data_len - the length of data.
660 * @param[in] rd_mode - read mode.dummy or not dummy.
661 * @return none
662 */
spi_master_read_plus(spi_sel_e spi_sel,unsigned char cmd,unsigned int addr,unsigned char * data,unsigned int data_len,spi_rd_tans_mode_e rd_mode)663 void spi_master_read_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e rd_mode)
664 {
665 spi_rx_fifo_clr(spi_sel);
666 if (HSPI_MODULE == spi_sel)
667 {
668 hspi_set_address(addr);
669 }
670 spi_set_transmode(spi_sel, rd_mode);
671 spi_rx_cnt(spi_sel, data_len);
672 spi_set_cmd(spi_sel, cmd);
673 spi_read(spi_sel, (unsigned char *)data, data_len);
674 while (spi_is_busy(spi_sel));
675 }
676
677 /**
678 * @brief This function serves to write address, then read data from the SPI slave.
679 * @param[in] spi_sel - the spi module.
680 * @param[in] cmd - cmd one byte will first write.
681 * @param[in] addrs - pointer to the address of slave.
682 * @param[in] addr_len - the length of address.
683 * @param[in] data - the pointer to the data for read.
684 * @param[in] data_len - read length.
685 * @param[in] wr_mode - write mode.dummy or not dummy.
686 * @return none
687 */
spi_master_write_read_plus(spi_sel_e spi_sel,unsigned char cmd,unsigned char * addrs,unsigned int addr_len,unsigned char * data,unsigned int data_len,spi_rd_tans_mode_e wr_mode)688 void spi_master_write_read_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned char *addrs, unsigned int addr_len, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e wr_mode)
689 {
690 spi_tx_fifo_clr(spi_sel);
691 spi_rx_fifo_clr(spi_sel);
692 spi_tx_cnt(spi_sel, addr_len);
693 spi_rx_cnt(spi_sel, data_len);
694 spi_set_transmode(spi_sel, wr_mode);
695
696 spi_set_cmd(spi_sel, cmd);
697 spi_write(spi_sel, (unsigned char *)addrs, addr_len);
698 spi_read(spi_sel, (unsigned char *)data, data_len);
699 while (spi_is_busy(spi_sel));
700 }
701
702 /**
703 * @brief This function serves to set tx_dam channel and config dma tx default.
704 * @param[in] chn - dma channel.
705 * @return none
706 */
hspi_set_tx_dma_config(dma_chn_e chn)707 void hspi_set_tx_dma_config(dma_chn_e chn)
708 {
709 s_hspi_tx_dma_chn = chn;
710 dma_config(chn, &hspi_tx_dma_config);
711
712 }
713
714 /**
715 * @brief This function serves to set rx_dam channel and config dma rx default.
716 * @param[in] chn - dma channel.
717 * @return none
718 */
hspi_set_rx_dma_config(dma_chn_e chn)719 void hspi_set_rx_dma_config(dma_chn_e chn)
720 {
721 s_hspi_rx_dma_chn = chn;
722 dma_config(chn, &hspi_rx_dma_config);
723 }
724
725 /**
726 * @brief This function serves to set tx_dam channel and config dma tx default.
727 * @param[in] chn - dma channel.
728 * @return none
729 */
pspi_set_tx_dma_config(dma_chn_e chn)730 void pspi_set_tx_dma_config(dma_chn_e chn)
731 {
732 s_pspi_tx_dma_chn = chn;
733 dma_config(chn, &pspi_tx_dma_config);
734
735 }
736
737 /**
738 * @brief This function serves to set rx_dam channel and config dma rx default.
739 * @param[in] chn - dma channel.
740 * @return none
741 */
pspi_set_rx_dma_config(dma_chn_e chn)742 void pspi_set_rx_dma_config(dma_chn_e chn)
743 {
744 s_pspi_rx_dma_chn = chn;
745 dma_config(chn, &pspi_rx_dma_config);
746 }
747
748 /**
749 * @brief this function set spi dma channel.
750 * @param[in] spi_dma_chn - dma channel.
751 * @param[in] src_addr - the address of source.
752 * @param[in] dst_addr - the address of destination.
753 * @param[in] len - the length of data.
754 * */
spi_set_dma(dma_chn_e spi_dma_chn,unsigned int src_addr,unsigned int dst_addr,unsigned int len)755 void spi_set_dma(dma_chn_e spi_dma_chn, unsigned int src_addr, unsigned int dst_addr, unsigned int len)
756 {
757 dma_set_address(spi_dma_chn, src_addr, dst_addr);
758 dma_set_size(spi_dma_chn, len, DMA_WORD_WIDTH);
759 dma_chn_en(spi_dma_chn);
760 }
761
762 /**
763 * @brief this function set spi tx dma channel.
764 * @param[in] spi_sel - the spi module.
765 * @param[in] src_addr - the address of source.
766 * @param[in] len - the length of data.
767 * */
spi_set_tx_dma(spi_sel_e spi_sel,unsigned char * src_addr,unsigned int len)768 void spi_set_tx_dma(spi_sel_e spi_sel, unsigned char* src_addr,unsigned int len)
769 {
770 unsigned char tx_dma_chn;
771 if (HSPI_MODULE == spi_sel)
772 {
773 tx_dma_chn = s_hspi_tx_dma_chn;
774 }
775 else
776 {
777 tx_dma_chn = s_pspi_tx_dma_chn;
778 }
779 spi_rx_tx_irq_trig_cnt(spi_sel, 4);//recover trigger level to 4.
780 spi_tx_cnt(spi_sel,len);
781 dma_set_address(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(src_addr), reg_spi_data_buf_adr(spi_sel));
782 dma_set_size(tx_dma_chn, len, DMA_WORD_WIDTH);
783 dma_chn_en(tx_dma_chn);
784 }
785
786
787 /**
788 * @brief this function set spi rx dma channel.
789 * @param[in] spi_sel - the spi module.
790 * @param[in] dst_addr - the address of destination.
791 * @param[in] len - the length of data.
792 * */
spi_set_rx_dma(spi_sel_e spi_sel,unsigned char * dst_addr,unsigned int len)793 void spi_set_rx_dma(spi_sel_e spi_sel, unsigned char* dst_addr,unsigned int len)
794 {
795 unsigned char rx_dma_chn;
796 if (HSPI_MODULE == spi_sel)
797 {
798 rx_dma_chn = s_hspi_rx_dma_chn;
799 }
800 else
801 {
802 rx_dma_chn = s_pspi_rx_dma_chn;
803 }
804 spi_rx_tx_irq_trig_cnt(spi_sel, 5);//setting only for fixing the bug that slave receive number of bytes in multiples of 4 will fail.
805 dma_set_address(rx_dma_chn, reg_spi_data_buf_adr(spi_sel), (unsigned int)convert_ram_addr_cpu2bus(dst_addr));
806 dma_set_size(rx_dma_chn, len, DMA_WORD_WIDTH);
807 dma_chn_en(rx_dma_chn);
808 }
809
810
811 /**
812 * @brief This function serves to normal write data by dma.
813 * @param[in] spi_sel - the spi module.
814 * @param[in] src_addr - the pointer to the data for write.
815 * @param[in] len - write length.
816 * @return none
817 */
spi_master_write_dma(spi_sel_e spi_sel,unsigned char * src_addr,unsigned int len)818 void spi_master_write_dma(spi_sel_e spi_sel, unsigned char *src_addr, unsigned int len)
819 {
820 unsigned char tx_dma_chn;
821 spi_tx_fifo_clr(spi_sel);
822 spi_tx_dma_en(spi_sel);
823 spi_tx_cnt(spi_sel, len);
824 spi_set_transmode(spi_sel, SPI_MODE_WRITE_ONLY);
825 if (HSPI_MODULE == spi_sel)
826 {
827 tx_dma_chn = s_hspi_tx_dma_chn;
828 }
829 else
830 {
831 tx_dma_chn = s_pspi_tx_dma_chn;
832 }
833 spi_set_dma(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(src_addr), reg_spi_data_buf_adr(spi_sel), len);
834 spi_set_cmd(spi_sel, 0x00);
835 }
836
837 /**
838 * @brief This function serves to normal write cmd and address, then read data by dma.
839 * @param[in] spi_sel - the spi module.
840 * @param[in] addr - the pointer to the cmd and address for write.
841 * @param[in] addr_len - write length.
842 * @param[in] data - the pointer to the data for read.
843 * @param[in] data_len - read length.
844 * @return none
845 */
spi_master_write_read_dma(spi_sel_e spi_sel,unsigned char * addr,unsigned int addr_len,unsigned char * data,unsigned int data_len)846 void spi_master_write_read_dma(spi_sel_e spi_sel, unsigned char *addr, unsigned int addr_len, unsigned char *data, unsigned int data_len)
847 {
848 unsigned char tx_dma_chn, rx_dma_chn;
849 spi_tx_fifo_clr(spi_sel);
850 spi_rx_fifo_clr(spi_sel);
851 spi_tx_dma_en(spi_sel);
852 spi_rx_dma_en(spi_sel);
853 spi_tx_cnt(spi_sel, addr_len);
854 spi_rx_cnt(spi_sel, data_len);
855 spi_set_transmode(spi_sel, SPI_MODE_WRITE_READ);
856 if (HSPI_MODULE == spi_sel)
857 {
858 tx_dma_chn = s_hspi_tx_dma_chn;
859 rx_dma_chn = s_hspi_rx_dma_chn;
860 }
861 else
862 {
863 tx_dma_chn = s_pspi_tx_dma_chn;
864 rx_dma_chn = s_pspi_rx_dma_chn;
865 }
866 spi_set_dma(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(addr), reg_spi_data_buf_adr(spi_sel), addr_len);
867 spi_set_dma(rx_dma_chn, reg_spi_data_buf_adr(spi_sel), (unsigned int)convert_ram_addr_cpu2bus(data), data_len);
868 spi_set_cmd(spi_sel, 0x00);//when cmd disable that will not sent cmd,just trigger spi send .
869 }
870
871 /**
872 * @brief This function serves to single/dual/quad write to the SPI slave by dma.
873 * @param[in] spi_sel - the spi module.
874 * @param[in] cmd - cmd one byte will first write.
875 * @param[in] addr - the address of slave.
876 * @param[in] data - pointer to the data need to write.
877 * @param[in] data_len - length in byte of the data need to write.
878 * @param[in] wr_mode - write mode.dummy or not dummy.
879 * @return none
880 */
spi_master_write_dma_plus(spi_sel_e spi_sel,unsigned char cmd,unsigned int addr,unsigned char * data,unsigned int data_len,spi_wr_tans_mode_e wr_mode)881 void spi_master_write_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode)
882 {
883 unsigned char tx_dma_chn;
884 spi_tx_fifo_clr(spi_sel);
885 spi_tx_dma_en(spi_sel);
886 spi_tx_cnt(spi_sel, data_len);
887 spi_set_transmode(spi_sel, wr_mode);
888 if (HSPI_MODULE == spi_sel)
889 {
890 tx_dma_chn = s_hspi_tx_dma_chn;
891 hspi_set_address(addr);
892 }
893 else
894 {
895 tx_dma_chn = s_pspi_tx_dma_chn;
896 }
897 spi_set_dma(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(data), reg_spi_data_buf_adr(spi_sel), data_len);
898 spi_set_cmd(spi_sel, cmd);
899 }
900
901 /**
902 * @brief This function serves to single/dual/quad read from the SPI slave by dma.
903 * @param[in] spi_sel - the spi module.
904 * @param[in] cmd - cmd one byte will first write.
905 * @param[in] addr - the address of slave.
906 * @param[in] dst_addr - pointer to the buffer that will cache the reading out data.
907 * @param[in] data_len - length in byte of the data need to read.
908 * @param[in] rd_mode - read mode.dummy or not dummy.
909 * @return none
910 */
spi_master_read_dma_plus(spi_sel_e spi_sel,unsigned char cmd,unsigned int addr,unsigned char * dst_addr,unsigned int data_len,spi_rd_tans_mode_e rd_mode)911 void spi_master_read_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *dst_addr, unsigned int data_len, spi_rd_tans_mode_e rd_mode)
912 {
913 unsigned char rx_dma_chn;
914 spi_rx_fifo_clr(spi_sel);
915 spi_rx_dma_en(spi_sel);
916 spi_set_transmode(spi_sel, rd_mode);
917 spi_rx_cnt(spi_sel, data_len);
918 if (HSPI_MODULE == spi_sel)
919 {
920 rx_dma_chn = s_hspi_rx_dma_chn;
921 hspi_set_address(addr);
922 }
923 else
924 {
925 rx_dma_chn = s_pspi_rx_dma_chn;
926 }
927 spi_set_dma(rx_dma_chn, reg_spi_data_buf_adr(spi_sel), (unsigned int)convert_ram_addr_cpu2bus(dst_addr), data_len);
928 spi_set_cmd(spi_sel, cmd);
929 }
930
931 /**
932 * @brief This function serves to single/dual/quad write address and read from the SPI slave by dma.
933 * @param[in] spi_sel - the spi module.
934 * @param[in] cmd - cmd one byte will first write.
935 * @param[in] addr - the address of slave.
936 * @param[in] addr_len - the length of address.
937 * @param[in] rd_data - pointer to the buffer that will cache the reading out data.
938 * @param[in] rd_len - length in byte of the data need to read.
939 * @param[in] rd_mode - read mode.dummy or not dummy.
940 * @return none
941 */
spi_master_write_read_dma_plus(spi_sel_e spi_sel,unsigned char cmd,unsigned char * addr,unsigned int addr_len,unsigned char * dst_addr,unsigned int rd_len,spi_rd_tans_mode_e rd_mode)942 void spi_master_write_read_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned char *addr, unsigned int addr_len, unsigned char *dst_addr, unsigned int rd_len, spi_rd_tans_mode_e rd_mode)
943 {
944 unsigned char tx_dma_chn, rx_dma_chn;
945 spi_tx_fifo_clr(spi_sel);
946 spi_rx_fifo_clr(spi_sel);
947 spi_tx_dma_en(spi_sel);
948 spi_rx_dma_en(spi_sel);
949 spi_tx_cnt(spi_sel,addr_len);
950 spi_rx_cnt(spi_sel, rd_len);
951 spi_set_transmode(spi_sel, rd_mode);
952 if (HSPI_MODULE == spi_sel)
953 {
954 tx_dma_chn = s_hspi_tx_dma_chn;
955 rx_dma_chn = s_hspi_rx_dma_chn;
956 }
957 else
958 {
959 tx_dma_chn = s_pspi_tx_dma_chn;
960 rx_dma_chn = s_pspi_rx_dma_chn;
961 }
962 spi_set_dma(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(addr), reg_spi_data_buf_adr(spi_sel), addr_len);
963 spi_set_dma(rx_dma_chn, reg_spi_data_buf_adr(spi_sel), (unsigned int)convert_ram_addr_cpu2bus(dst_addr), rd_len);
964 spi_set_cmd(spi_sel, cmd);//when cmd disable that will not sent cmd,just trigger spi send .
965 }
966
967 /**
968 * @brief This function serves to single/dual (quad) write to the SPI slave by xip.
969 * @param[in] cmd - cmd one byte will first write.
970 * @param[in] addr_offset - offset of xip base address.
971 * @param[in] data - pointer to the data need to write.
972 * @param[in] data_len - length in byte of the data need to write.
973 * @param[in] wr_mode - write mode dummy or not dummy.
974 * @return none
975 */
hspi_master_write_xip(unsigned char cmd,unsigned int addr_offset,unsigned char * data,unsigned int data_len,spi_wr_tans_mode_e wr_mode)976 _attribute_ram_code_sec_noinline_ void hspi_master_write_xip(unsigned char cmd, unsigned int addr_offset, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode)
977 {
978 hspi_xip_write_transmode(wr_mode);
979 hspi_xip_addr_offset(addr_offset);
980 hspi_xip_set_wr_cmd(cmd);
981 for (unsigned int i = 0; i < data_len; i++)
982 {
983 write_reg8(reg_hspi_xip_base_adr + i, data[i]);
984 }
985 }
986
987 /**
988 * @brief This function serves to single/dual (quad) read from the SPI slave by xip.
989 * @param[in] cmd - cmd one byte will first write.
990 * @param[in] addr_offset - offset of xip base address.
991 * @param[in] data - pointer to the data need to read.
992 * @param[in] data_len - length in byte of the data need to read.
993 * @param[in] rd_mode - read mode.dummy or not dummy.
994 * @return none
995 */
hspi_master_read_xip(unsigned char cmd,unsigned int addr_offset,unsigned char * data,unsigned int data_len,spi_rd_tans_mode_e rd_mode)996 _attribute_ram_code_sec_noinline_ void hspi_master_read_xip(unsigned char cmd, unsigned int addr_offset, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e rd_mode)
997 {
998 hspi_xip_read_transmode(rd_mode);
999 hspi_xip_addr_offset(addr_offset);
1000 hspi_xip_set_rd_cmd(cmd);
1001
1002 for (unsigned int i = 0; i < data_len; i++)
1003 {
1004 data[i] = read_reg8(reg_hspi_xip_base_adr + i);
1005 }
1006 }
1007
1008 /**
1009 * @brief This function serves to a cmd and one data write to the SPI slave by xip.
1010 * @param[in] cmd - cmd one byte will first write.
1011 * @param[in] addr_offset - offset of xip base address.
1012 * @param[in] data_in - data need to write.
1013 * @param[in] wr_mode - write mode dummy or not dummy.
1014 * @return none
1015 */
hspi_master_write_xip_cmd_data(unsigned char cmd,unsigned int addr_offset,unsigned char data_in,spi_wr_tans_mode_e wr_mode)1016 void hspi_master_write_xip_cmd_data(unsigned char cmd, unsigned int addr_offset, unsigned char data_in, spi_wr_tans_mode_e wr_mode)
1017 {
1018 hspi_xip_write_transmode(wr_mode);
1019 hspi_xip_addr_offset(addr_offset);
1020 hspi_xip_set_wr_cmd(cmd);
1021 write_reg8(reg_hspi_xip_base_adr, data_in);
1022 }
1023