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