1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "hpm_common.h"
9 #include "hpm_spi_drv.h"
10
11 #ifndef HPM_SPI_DRV_DEFAULT_RETRY_COUNT
12 /* the waiting time of timeout status is related to retry count and CPU frequency */
13 #define HPM_SPI_DRV_DEFAULT_RETRY_COUNT (5000U)
14 #endif
15
spi_wait_for_idle_status(SPI_Type * ptr)16 hpm_stat_t spi_wait_for_idle_status(SPI_Type *ptr)
17 {
18 uint32_t status;
19 uint32_t retry = 0;
20
21 do {
22 status = ptr->STATUS;
23 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
24 break;
25 }
26 retry++;
27 } while (status & SPI_STATUS_SPIACTIVE_MASK);
28
29 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
30 return status_timeout;
31 }
32
33 return status_success;
34 }
35
spi_wait_for_busy_status(SPI_Type * ptr)36 hpm_stat_t spi_wait_for_busy_status(SPI_Type *ptr)
37 {
38 uint32_t status;
39 uint32_t retry = 0;
40
41 do {
42 status = ptr->STATUS;
43 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
44 break;
45 }
46 retry++;
47 } while (!(status & SPI_STATUS_SPIACTIVE_MASK));
48
49 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
50 return status_timeout;
51 }
52
53 return status_success;
54 }
55
spi_write_command(SPI_Type * ptr,spi_mode_selection_t mode,spi_control_config_t * config,uint8_t * cmd)56 hpm_stat_t spi_write_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd)
57 {
58 if (mode == spi_master_mode) {
59 if (config->master_config.cmd_enable == true) {
60 if (cmd == NULL) {
61 return status_invalid_argument;
62 }
63 ptr->CMD = SPI_CMD_CMD_SET(*cmd);
64 } else {
65 ptr->CMD = SPI_CMD_CMD_SET(0xff); /* Write a dummy byte */
66 }
67 }
68
69 return status_success;
70 }
71
spi_read_command(SPI_Type * ptr,spi_mode_selection_t mode,spi_control_config_t * config,uint8_t * cmd)72 hpm_stat_t spi_read_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd)
73 {
74 if (mode == spi_slave_mode) {
75 if (config->slave_config.slave_data_only == false) {
76 if (cmd == NULL) {
77 return status_invalid_argument;
78 }
79 *cmd = (uint8_t)(ptr->CMD & SPI_CMD_CMD_MASK) >> SPI_CMD_CMD_SHIFT;
80 }
81 }
82
83 return status_success;
84 }
85
spi_write_address(SPI_Type * ptr,spi_mode_selection_t mode,spi_control_config_t * config,uint32_t * addr)86 hpm_stat_t spi_write_address(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint32_t *addr)
87 {
88 if (mode == spi_master_mode) {
89 if (config->master_config.addr_enable == true) {
90 if (addr == NULL) {
91 return status_invalid_argument;
92 }
93 ptr->ADDR = SPI_ADDR_ADDR_SET(*addr);
94 }
95 }
96
97 return status_success;
98 }
99
spi_write_data(SPI_Type * ptr,uint8_t data_len_in_bytes,uint8_t * buff,uint32_t count)100 hpm_stat_t spi_write_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *buff, uint32_t count)
101 {
102 uint32_t status;
103 uint32_t transferred = 0;
104 uint32_t retry = 0;
105 uint32_t temp;
106
107 /* check parameter validity */
108 if (buff == NULL || count == 0) {
109 return status_invalid_argument;
110 }
111
112 if (data_len_in_bytes > 4 || data_len_in_bytes < 1) {
113 return status_invalid_argument;
114 }
115
116 /* data transfer */
117 while (transferred < count) {
118 status = ptr->STATUS;
119 if (!(status & SPI_STATUS_TXFULL_MASK)) {
120 /* write data into the txfifo */
121 temp = 0;
122 for (uint8_t i = 0; i < data_len_in_bytes; i++) {
123 temp += *(buff++) << i * 8;
124 }
125 ptr->DATA = temp;
126 /* transfer count increment */
127 transferred++;
128 retry = 0;
129 } else {
130 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
131 break;
132 }
133 retry++;
134 }
135 }
136
137 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
138 /* dummy state may triggers timeout if dummy count, retry count, spi rate and cpu frequency are inappropriate */
139 return status_timeout;
140 }
141
142 return status_success;
143 }
144
spi_read_data(SPI_Type * ptr,uint8_t data_len_in_bytes,uint8_t * buff,uint32_t count)145 hpm_stat_t spi_read_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *buff, uint32_t count)
146 {
147 uint32_t transferred = 0;
148 uint32_t retry = 0;
149 uint32_t temp;
150 uint8_t rx_valid_size = 0;
151 uint8_t j = 0;
152 /* check parameter validity */
153 if (buff == NULL || count == 0) {
154 return status_invalid_argument;
155 }
156
157 if (data_len_in_bytes > 4 || data_len_in_bytes < 1) {
158 return status_invalid_argument;
159 }
160
161 /* data transfer */
162 while (transferred < count) {
163 rx_valid_size = spi_get_rx_fifo_valid_data_size(ptr);
164 if (rx_valid_size > 0) {
165 for (j = 0; j < rx_valid_size; j++) {
166 temp = ptr->DATA;
167 for (uint8_t i = 0; i < data_len_in_bytes; i++) {
168 *(buff++) = (uint8_t)(temp >> (i * 8));
169 }
170 }
171 /* transfer count increment */
172 transferred += rx_valid_size;
173 retry = 0;
174 } else {
175 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
176 break;
177 }
178 retry++;
179 }
180 }
181
182 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
183 /* dummy state may triggers timeout if dummy count, retry count, spi rate and cpu frequency are inappropriate */
184 return status_timeout;
185 }
186
187 return status_success;
188 }
189
spi_write_read_data(SPI_Type * ptr,uint8_t data_len_in_bytes,uint8_t * wbuff,uint32_t wcount,uint8_t * rbuff,uint32_t rcount)190 hpm_stat_t spi_write_read_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *wbuff, uint32_t wcount, uint8_t *rbuff, uint32_t rcount)
191 {
192 uint32_t status;
193 uint32_t wtransferred = 0;
194 uint32_t rtransferred = 0;
195 uint32_t retry = 0;
196 uint32_t temp;
197
198 /* check parameter validity */
199 if (wbuff == NULL || wcount == 0 || rbuff == NULL || rcount == 0) {
200 return status_invalid_argument;
201 }
202
203 if (data_len_in_bytes > 4 || data_len_in_bytes < 1) {
204 return status_invalid_argument;
205 }
206
207 /* data transfer */
208 while (wtransferred < wcount || rtransferred < rcount) {
209 status = ptr->STATUS;
210
211 if (wtransferred < wcount) {
212 /* write data into the txfifo */
213 if (!(status & SPI_STATUS_TXFULL_MASK)) {
214 temp = 0;
215 for (uint8_t i = 0; i < data_len_in_bytes; i++) {
216 temp += *(wbuff++) << i * 8;
217 }
218 ptr->DATA = temp;
219 /* transfer count increment */
220 wtransferred++;
221 retry = 0;
222 } else {
223 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
224 break;
225 }
226 retry++;
227 }
228 }
229
230 if (rtransferred < rcount) {
231 /* read data from the txfifo */
232 if (!(status & SPI_STATUS_RXEMPTY_MASK)) {
233 temp = ptr->DATA;
234 for (uint8_t i = 0; i < data_len_in_bytes; i++) {
235 *(rbuff++) = (uint8_t)(temp >> (i * 8));
236 }
237 /* transfer count increment */
238 rtransferred++;
239 retry = 0;
240 } else {
241 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
242 break;
243 }
244 retry++;
245 }
246 }
247 }
248
249 if (retry > HPM_SPI_DRV_DEFAULT_RETRY_COUNT) {
250 /* dummy state may triggers timeout if dummy count, retry count, spi rate and cpu frequency are inappropriate */
251 return status_timeout;
252 }
253
254 return status_success;
255 }
256
spi_no_data(SPI_Type * ptr,spi_mode_selection_t mode,spi_control_config_t * config)257 static hpm_stat_t spi_no_data(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config)
258 {
259 (void) ptr;
260 if (mode == spi_master_mode) {
261 if (config->master_config.cmd_enable == false && config->master_config.addr_enable == false) {
262 return status_invalid_argument;
263 }
264 }
265 return status_success;
266 }
267
spi_master_get_default_timing_config(spi_timing_config_t * config)268 void spi_master_get_default_timing_config(spi_timing_config_t *config)
269 {
270 config->master_config.cs2sclk = spi_cs2sclk_half_sclk_4;
271 config->master_config.csht = spi_csht_half_sclk_12;
272 }
273
spi_master_get_default_format_config(spi_format_config_t * config)274 void spi_master_get_default_format_config(spi_format_config_t *config)
275 {
276 config->master_config.addr_len_in_bytes = 1;
277 config->common_config.data_len_in_bits = 32;
278 config->common_config.data_merge = false;
279 config->common_config.mosi_bidir = false;
280 config->common_config.lsb = false;
281 config->common_config.mode = spi_master_mode;
282 config->common_config.cpol = spi_sclk_high_idle;
283 config->common_config.cpha = spi_sclk_sampling_even_clk_edges;
284 }
285
spi_slave_get_default_format_config(spi_format_config_t * config)286 void spi_slave_get_default_format_config(spi_format_config_t *config)
287 {
288 config->common_config.data_len_in_bits = 32;
289 config->common_config.data_merge = false;
290 config->common_config.mosi_bidir = false;
291 config->common_config.lsb = false;
292 config->common_config.mode = spi_master_mode;
293 config->common_config.cpol = spi_sclk_high_idle;
294 config->common_config.cpha = spi_sclk_sampling_even_clk_edges;
295 }
296
spi_master_get_default_control_config(spi_control_config_t * config)297 void spi_master_get_default_control_config(spi_control_config_t *config)
298 {
299 config->master_config.cmd_enable = false;
300 config->master_config.addr_enable = false;
301 config->master_config.token_enable = false;
302 config->master_config.token_value = spi_token_value_0x00;
303 config->master_config.addr_phase_fmt = spi_address_phase_format_single_io_mode;
304 config->common_config.tx_dma_enable = false;
305 config->common_config.rx_dma_enable = false;
306 config->common_config.trans_mode = spi_trans_write_only;
307 config->common_config.data_phase_fmt = spi_single_io_mode;
308 config->common_config.dummy_cnt = spi_dummy_count_2;
309 #if defined(HPM_IP_FEATURE_SPI_CS_SELECT) && (HPM_IP_FEATURE_SPI_CS_SELECT == 1)
310 config->common_config.cs_index = spi_cs_0;
311 #endif
312 }
313
spi_slave_get_default_control_config(spi_control_config_t * config)314 void spi_slave_get_default_control_config(spi_control_config_t *config)
315 {
316 config->slave_config.slave_data_only = false;
317 config->common_config.tx_dma_enable = false;
318 config->common_config.rx_dma_enable = false;
319 config->common_config.trans_mode = spi_trans_read_only;
320 config->common_config.data_phase_fmt = spi_single_io_mode;
321 config->common_config.dummy_cnt = spi_dummy_count_2;
322 #if defined(HPM_IP_FEATURE_SPI_CS_SELECT) && (HPM_IP_FEATURE_SPI_CS_SELECT == 1)
323 config->common_config.cs_index = spi_cs_0;
324 #endif
325 }
326
spi_master_timing_init(SPI_Type * ptr,spi_timing_config_t * config)327 hpm_stat_t spi_master_timing_init(SPI_Type *ptr, spi_timing_config_t *config)
328 {
329 uint8_t sclk_div;
330 uint8_t div_remainder;
331 uint8_t div_integer;
332 if (config->master_config.sclk_freq_in_hz == 0) {
333 return status_invalid_argument;
334 }
335
336 if (config->master_config.clk_src_freq_in_hz > config->master_config.sclk_freq_in_hz) {
337 div_remainder = (config->master_config.clk_src_freq_in_hz % config->master_config.sclk_freq_in_hz);
338 div_integer = (config->master_config.clk_src_freq_in_hz / config->master_config.sclk_freq_in_hz);
339 if ((div_remainder != 0) || ((div_integer % 2) != 0)) {
340 return status_invalid_argument;
341 }
342 sclk_div = (div_integer / 2) - 1;
343 } else {
344 sclk_div = 0xff;
345 }
346
347 ptr->TIMING = SPI_TIMING_CS2SCLK_SET(config->master_config.cs2sclk) |
348 SPI_TIMING_CSHT_SET(config->master_config.csht) |
349 SPI_TIMING_SCLK_DIV_SET(sclk_div);
350
351 return status_success;
352 }
353
spi_format_init(SPI_Type * ptr,spi_format_config_t * config)354 void spi_format_init(SPI_Type *ptr, spi_format_config_t *config)
355 {
356 ptr->TRANSFMT = SPI_TRANSFMT_ADDRLEN_SET(config->master_config.addr_len_in_bytes - 1) |
357 SPI_TRANSFMT_DATALEN_SET(config->common_config.data_len_in_bits - 1) |
358 SPI_TRANSFMT_DATAMERGE_SET(config->common_config.data_merge) |
359 SPI_TRANSFMT_MOSIBIDIR_SET(config->common_config.mosi_bidir) |
360 SPI_TRANSFMT_LSB_SET(config->common_config.lsb) |
361 SPI_TRANSFMT_SLVMODE_SET(config->common_config.mode) |
362 SPI_TRANSFMT_CPOL_SET(config->common_config.cpol) |
363 SPI_TRANSFMT_CPHA_SET(config->common_config.cpha);
364 }
365
spi_control_init(SPI_Type * ptr,spi_control_config_t * config,uint32_t wcount,uint32_t rcount)366 hpm_stat_t spi_control_init(SPI_Type *ptr, spi_control_config_t *config, uint32_t wcount, uint32_t rcount)
367 {
368 #if defined (SPI_SOC_TRANSFER_COUNT_MAX) && (SPI_SOC_TRANSFER_COUNT_MAX == 512)
369 if ((wcount > SPI_SOC_TRANSFER_COUNT_MAX) || (rcount > SPI_SOC_TRANSFER_COUNT_MAX)) {
370 return status_invalid_argument;
371 }
372 #endif
373 /* slave data only mode only works on write read together transfer mode */
374 if (config->slave_config.slave_data_only == true && config->common_config.trans_mode != spi_trans_write_read_together) {
375 return status_invalid_argument;
376 }
377
378 ptr->TRANSCTRL = SPI_TRANSCTRL_SLVDATAONLY_SET(config->slave_config.slave_data_only) |
379 SPI_TRANSCTRL_CMDEN_SET(config->master_config.cmd_enable) |
380 SPI_TRANSCTRL_ADDREN_SET(config->master_config.addr_enable) |
381 SPI_TRANSCTRL_ADDRFMT_SET(config->master_config.addr_phase_fmt) |
382 SPI_TRANSCTRL_TRANSMODE_SET(config->common_config.trans_mode) |
383 SPI_TRANSCTRL_DUALQUAD_SET(config->common_config.data_phase_fmt) |
384 SPI_TRANSCTRL_TOKENEN_SET(config->master_config.token_enable) |
385 SPI_TRANSCTRL_WRTRANCNT_SET(wcount - 1) |
386 SPI_TRANSCTRL_TOKENVALUE_SET(config->master_config.token_value) |
387 SPI_TRANSCTRL_DUMMYCNT_SET(config->common_config.dummy_cnt) |
388 SPI_TRANSCTRL_RDTRANCNT_SET(rcount - 1);
389
390 #if defined(HPM_IP_FEATURE_SPI_CS_SELECT) && (HPM_IP_FEATURE_SPI_CS_SELECT == 1)
391 ptr->CTRL = (ptr->CTRL & ~SPI_CTRL_CS_EN_MASK) | SPI_CTRL_CS_EN_SET(config->common_config.cs_index);
392 #endif
393
394 #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
395 ptr->WR_TRANS_CNT = wcount - 1;
396 ptr->RD_TRANS_CNT = rcount - 1;
397 #endif
398
399 /* reset txfifo, rxfifo and control */
400 ptr->CTRL |= SPI_CTRL_TXFIFORST_MASK | SPI_CTRL_RXFIFORST_MASK | SPI_CTRL_SPIRST_MASK;
401
402 return status_success;
403 }
404
spi_transfer(SPI_Type * ptr,spi_control_config_t * config,uint8_t * cmd,uint32_t * addr,uint8_t * wbuff,uint32_t wcount,uint8_t * rbuff,uint32_t rcount)405 hpm_stat_t spi_transfer(SPI_Type *ptr,
406 spi_control_config_t *config,
407 uint8_t *cmd, uint32_t *addr,
408 uint8_t *wbuff, uint32_t wcount, uint8_t *rbuff, uint32_t rcount)
409 {
410 hpm_stat_t stat = status_fail;
411 uint8_t mode, data_len_in_bytes, trans_mode;
412
413 stat = spi_control_init(ptr, config, wcount, rcount);
414 if (stat != status_success) {
415 return stat;
416 }
417
418 /* read data length */
419 data_len_in_bytes = spi_get_data_length_in_bytes(ptr);
420
421 /* read spi control mode */
422 mode = (ptr->TRANSFMT & SPI_TRANSFMT_SLVMODE_MASK) >> SPI_TRANSFMT_SLVMODE_SHIFT;
423
424 /* read spi transfer mode */
425 trans_mode = config->common_config.trans_mode;
426
427 /* write address on master mode */
428 stat = spi_write_address(ptr, mode, config, addr);
429 if (stat != status_success) {
430 return stat;
431 }
432
433 /* write command on master mode */
434 stat = spi_write_command(ptr, mode, config, cmd);
435 if (stat != status_success) {
436 return stat;
437 }
438
439 /* data phase */
440 if (trans_mode == spi_trans_write_read_together) {
441 stat = spi_write_read_data(ptr, data_len_in_bytes, wbuff, wcount, rbuff, rcount);
442 } else if (trans_mode == spi_trans_write_only || trans_mode == spi_trans_dummy_write) {
443 stat = spi_write_data(ptr, data_len_in_bytes, wbuff, wcount);
444 } else if (trans_mode == spi_trans_read_only || trans_mode == spi_trans_dummy_read) {
445 stat = spi_read_data(ptr, data_len_in_bytes, rbuff, rcount);
446 } else if (trans_mode == spi_trans_write_read || trans_mode == spi_trans_write_dummy_read) {
447 stat = spi_write_read_data(ptr, data_len_in_bytes, wbuff, wcount, rbuff, rcount);
448 } else if (trans_mode == spi_trans_read_write || trans_mode == spi_trans_read_dummy_write) {
449 stat = spi_write_read_data(ptr, data_len_in_bytes, wbuff, wcount, rbuff, rcount);
450 } else if (trans_mode == spi_trans_no_data) {
451 stat = spi_no_data(ptr, mode, config);
452 } else {
453 stat = status_invalid_argument;
454 }
455
456 if (stat != status_success) {
457 return stat;
458 }
459
460 /* read command on slave mode */
461 stat = spi_read_command(ptr, mode, config, cmd);
462 if (stat != status_success) {
463 return stat;
464 }
465 /* on the slave mode, if master keeps asserting the cs signal, it's maybe timeout */
466 stat = spi_wait_for_idle_status(ptr);
467 return stat;
468 }
469
spi_setup_dma_transfer(SPI_Type * ptr,spi_control_config_t * config,uint8_t * cmd,uint32_t * addr,uint32_t wcount,uint32_t rcount)470 hpm_stat_t spi_setup_dma_transfer(SPI_Type *ptr,
471 spi_control_config_t *config,
472 uint8_t *cmd, uint32_t *addr,
473 uint32_t wcount, uint32_t rcount)
474 {
475 hpm_stat_t stat = status_fail;
476 uint8_t mode;
477
478 stat = spi_control_init(ptr, config, wcount, rcount);
479 if (stat != status_success) {
480 return stat;
481 }
482
483 if (config->common_config.tx_dma_enable) {
484 ptr->CTRL |= SPI_CTRL_TXDMAEN_MASK;
485 }
486 if (config->common_config.rx_dma_enable) {
487 ptr->CTRL |= SPI_CTRL_RXDMAEN_MASK;
488 }
489
490 /* read spi control mode */
491 mode = (ptr->TRANSFMT & SPI_TRANSFMT_SLVMODE_MASK) >> SPI_TRANSFMT_SLVMODE_SHIFT;
492
493 /* address phase */
494 stat = spi_write_address(ptr, mode, config, addr);
495 if (stat != status_success) {
496 return stat;
497 }
498
499 /* command phase */
500 stat = spi_write_command(ptr, mode, config, cmd);
501 if (stat != status_success) {
502 return stat;
503 }
504
505 return stat;
506 }
507
508
509 #if defined(HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO) && (HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO == 1)
spi_directio_enable_output(SPI_Type * ptr,spi_directio_pin_t pin)510 hpm_stat_t spi_directio_enable_output(SPI_Type *ptr, spi_directio_pin_t pin)
511 {
512 hpm_stat_t stat = status_success;
513 switch (pin) {
514 case hold_pin:
515 ptr->DIRECTIO |= SPI_DIRECTIO_HOLD_OE_MASK;
516 break;
517 case wp_pin:
518 ptr->DIRECTIO |= SPI_DIRECTIO_WP_OE_MASK;
519 break;
520 case miso_pin:
521 ptr->DIRECTIO |= SPI_DIRECTIO_MISO_OE_MASK;
522 break;
523 case mosi_pin:
524 ptr->DIRECTIO |= SPI_DIRECTIO_MOSI_OE_MASK;
525 break;
526 case sclk_pin:
527 ptr->DIRECTIO |= SPI_DIRECTIO_SCLK_OE_MASK;
528 break;
529 case cs_pin:
530 ptr->DIRECTIO |= SPI_DIRECTIO_CS_OE_MASK;
531 break;
532 default:
533 stat = status_invalid_argument;
534 break;
535 }
536 return stat;
537 }
538
spi_directio_disable_output(SPI_Type * ptr,spi_directio_pin_t pin)539 hpm_stat_t spi_directio_disable_output(SPI_Type *ptr, spi_directio_pin_t pin)
540 {
541 hpm_stat_t stat = status_success;
542 switch (pin) {
543 case hold_pin:
544 ptr->DIRECTIO &= ~SPI_DIRECTIO_HOLD_OE_MASK;
545 break;
546 case wp_pin:
547 ptr->DIRECTIO &= ~SPI_DIRECTIO_WP_OE_MASK;
548 break;
549 case miso_pin:
550 ptr->DIRECTIO &= ~SPI_DIRECTIO_MISO_OE_MASK;
551 break;
552 case mosi_pin:
553 ptr->DIRECTIO &= ~SPI_DIRECTIO_MOSI_OE_MASK;
554 break;
555 case sclk_pin:
556 ptr->DIRECTIO &= ~SPI_DIRECTIO_SCLK_OE_MASK;
557 break;
558 case cs_pin:
559 ptr->DIRECTIO &= ~SPI_DIRECTIO_CS_OE_MASK;
560 break;
561 default:
562 stat = status_invalid_argument;
563 break;
564 }
565 return stat;
566 }
567
spi_directio_write(SPI_Type * ptr,spi_directio_pin_t pin,bool high)568 hpm_stat_t spi_directio_write(SPI_Type *ptr, spi_directio_pin_t pin, bool high)
569 {
570 hpm_stat_t stat = status_success;
571 switch (pin) {
572 case hold_pin:
573 (high == true) ? (ptr->DIRECTIO |= SPI_DIRECTIO_HOLD_O_MASK) : (ptr->DIRECTIO &= ~SPI_DIRECTIO_HOLD_O_MASK);
574 break;
575 case wp_pin:
576 (high == true) ? (ptr->DIRECTIO |= SPI_DIRECTIO_WP_O_MASK) : (ptr->DIRECTIO &= ~SPI_DIRECTIO_WP_O_MASK);
577 break;
578 case miso_pin:
579 (high == true) ? (ptr->DIRECTIO |= SPI_DIRECTIO_MISO_O_MASK) : (ptr->DIRECTIO &= ~SPI_DIRECTIO_MISO_O_MASK);
580 break;
581 case mosi_pin:
582 (high == true) ? (ptr->DIRECTIO |= SPI_DIRECTIO_MOSI_O_MASK) : (ptr->DIRECTIO &= ~SPI_DIRECTIO_MOSI_O_MASK);
583 break;
584 case sclk_pin:
585 (high == true) ? (ptr->DIRECTIO |= SPI_DIRECTIO_SCLK_O_MASK) : (ptr->DIRECTIO &= ~SPI_DIRECTIO_SCLK_O_MASK);
586 break;
587 case cs_pin:
588 (high == true) ? (ptr->DIRECTIO |= SPI_DIRECTIO_CS_O_MASK) : (ptr->DIRECTIO &= ~SPI_DIRECTIO_CS_O_MASK);
589 break;
590 default:
591 stat = status_invalid_argument;
592 break;
593 }
594 return stat;
595 }
596
spi_directio_read(SPI_Type * ptr,spi_directio_pin_t pin)597 uint8_t spi_directio_read(SPI_Type *ptr, spi_directio_pin_t pin)
598 {
599 uint8_t io_sta = 0;
600 switch (pin) {
601 case hold_pin:
602 io_sta = SPI_DIRECTIO_HOLD_I_GET(ptr->DIRECTIO);
603 break;
604 case wp_pin:
605 io_sta = SPI_DIRECTIO_WP_I_GET(ptr->DIRECTIO);
606 break;
607 case miso_pin:
608 io_sta = SPI_DIRECTIO_MISO_I_GET(ptr->DIRECTIO);
609 break;
610 case mosi_pin:
611 io_sta = SPI_DIRECTIO_MOSI_I_GET(ptr->DIRECTIO);
612 break;
613 case sclk_pin:
614 io_sta = SPI_DIRECTIO_SCLK_I_GET(ptr->DIRECTIO);
615 break;
616 case cs_pin:
617 io_sta = SPI_DIRECTIO_CS_I_GET(ptr->DIRECTIO);
618 break;
619 default:
620 break;
621 }
622 return io_sta;
623 }
624 #endif
625
626