1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_SPI_DRV_H
9 #define HPM_SPI_DRV_H
10 #include "hpm_spi_regs.h"
11 #include "hpm_soc_feature.h"
12
13 /**
14 * @brief SPI driver APIs
15 * @defgroup spi_interface SPI driver APIs
16 * @ingroup io_interfaces
17 * @{
18 */
19
20 /**
21 * @brief spi dma enable
22 */
23 typedef enum {
24 spi_tx_dma_enable = SPI_CTRL_TXDMAEN_MASK,
25 spi_rx_dma_enable = SPI_CTRL_RXDMAEN_MASK
26 } spi_dma_enable_t;
27
28 /**
29 * @brief spi interrupt mask
30 */
31 typedef enum {
32 spi_rx_fifo_overflow_int = SPI_INTREN_RXFIFOORINTEN_MASK,
33 spi_tx_fifo_underflow_int = SPI_INTREN_TXFIFOURINTEN_MASK,
34 spi_rx_fifo_threshold_int = SPI_INTREN_RXFIFOINTEN_MASK,
35 spi_tx_fifo_threshold_int = SPI_INTREN_TXFIFOINTEN_MASK,
36 spi_end_int = SPI_INTREN_ENDINTEN_MASK,
37 spi_slave_cmd_int = SPI_INTREN_SLVCMDEN_MASK,
38 } spi_interrupt_t;
39
40 /**
41 * @brief spi mode selection
42 */
43 typedef enum {
44 spi_master_mode = 0,
45 spi_slave_mode
46 } spi_mode_selection_t;
47
48 /**
49 * @brief spi clock polarity
50 */
51 typedef enum {
52 spi_sclk_low_idle = 0,
53 spi_sclk_high_idle
54 } spi_sclk_idle_state_t;
55
56 /**
57 * @brief spi clock phase
58 */
59 typedef enum {
60 spi_sclk_sampling_odd_clk_edges = 0,
61 spi_sclk_sampling_even_clk_edges
62 } spi_sclk_sampling_clk_edges_t;
63
64 /**
65 * @brief spi cs to sclk edge duration
66 */
67 typedef enum {
68 spi_cs2sclk_half_sclk_1 = 0,
69 spi_cs2sclk_half_sclk_2,
70 spi_cs2sclk_half_sclk_3,
71 spi_cs2sclk_half_sclk_4
72 } spi_cs2sclk_duration_t;
73
74 /**
75 * @brief spi cs high level duration
76 */
77 typedef enum {
78 spi_csht_half_sclk_1 = 0,
79 spi_csht_half_sclk_2,
80 spi_csht_half_sclk_3,
81 spi_csht_half_sclk_4,
82 spi_csht_half_sclk_5,
83 spi_csht_half_sclk_6,
84 spi_csht_half_sclk_7,
85 spi_csht_half_sclk_8,
86 spi_csht_half_sclk_9,
87 spi_csht_half_sclk_10,
88 spi_csht_half_sclk_11,
89 spi_csht_half_sclk_12,
90 spi_csht_half_sclk_13,
91 spi_csht_half_sclk_14,
92 spi_csht_half_sclk_15,
93 spi_csht_half_sclk_16,
94 } spi_csht_duration_t;
95
96 /**
97 * @brief spi address phase format
98 */
99 typedef enum {
100 spi_address_phase_format_single_io_mode = 0,
101 spi_address_phase_format_dualquad_io_mode
102 } spi_addr_phase_format_t;
103
104 /**
105 * @brief spi transfer mode
106 */
107 typedef enum {
108 spi_trans_write_read_together = 0,
109 spi_trans_write_only,
110 spi_trans_read_only,
111 spi_trans_write_read,
112 spi_trans_read_write,
113 spi_trans_write_dummy_read,
114 spi_trans_read_dummy_write,
115 spi_trans_no_data,
116 spi_trans_dummy_write,
117 spi_trans_dummy_read
118 } spi_trans_mode_t;
119
120 /**
121 * @brief spi data phase format
122 */
123 typedef enum {
124 spi_single_io_mode = 0,
125 spi_dual_io_mode,
126 spi_quad_io_mode,
127 } spi_data_phase_format_t;
128
129 /**
130 * @brief spi token value
131 */
132 typedef enum {
133 spi_token_value_0x00 = 0,
134 spi_token_value_0x69
135 } spi_token_value_t;
136
137 /**
138 * @brief spi dummy count
139 */
140 typedef enum {
141 spi_dummy_count_1 = 0,
142 spi_dummy_count_2,
143 spi_dummy_count_3,
144 spi_dummy_count_4
145 } spi_dummy_count_t;
146
147 /**
148 * @brief spi master interface timing config structure
149 */
150 typedef struct {
151 uint32_t clk_src_freq_in_hz;
152 uint32_t sclk_freq_in_hz;
153 uint8_t cs2sclk;
154 uint8_t csht;
155 } spi_master_timing_config_t;
156
157 /**
158 * @brief spi interface timing config structure
159 */
160 typedef struct {
161 spi_master_timing_config_t master_config;
162 } spi_timing_config_t;
163
164 /**
165 * @brief spi master transfer format config structure
166 */
167 typedef struct {
168 uint8_t addr_len_in_bytes;
169 } spi_master_format_config_t;
170
171 /**
172 * @brief spi common format config structure
173 */
174 typedef struct {
175 uint8_t data_len_in_bits;
176 bool data_merge;
177 bool mosi_bidir;
178 bool lsb;
179 uint8_t mode;
180 uint8_t cpol;
181 uint8_t cpha;
182 } spi_common_format_config_t;
183
184 /**
185 * @brief spi format config structure
186 */
187 typedef struct {
188 spi_master_format_config_t master_config;
189 spi_common_format_config_t common_config;
190 } spi_format_config_t;
191
192 /**
193 * @brief spi master transfer control config structure
194 */
195 typedef struct {
196 bool cmd_enable;
197 bool addr_enable;
198 uint8_t addr_phase_fmt;
199 bool token_enable;
200 uint8_t token_value;
201 } spi_master_control_config_t;
202
203 /**
204 * @brief spi slave transfer control config structure
205 */
206 typedef struct {
207 bool slave_data_only;
208 } spi_slave_control_config_t;
209
210 /**
211 * @brief spi common transfer control config structure
212 */
213 typedef struct {
214 bool tx_dma_enable;
215 bool rx_dma_enable;
216 uint8_t trans_mode;
217 uint8_t data_phase_fmt;
218 uint8_t dummy_cnt;
219 #if defined(SPI_SOC_HAS_CS_SELECT) && (SPI_SOC_HAS_CS_SELECT == 1)
220 uint8_t cs_index;
221 #endif
222 } spi_common_control_config_t; /*!< value in spi_cs_index_t */
223
224 /**
225 * @brief spi control config structure
226 */
227 typedef struct {
228 spi_master_control_config_t master_config;
229 spi_slave_control_config_t slave_config;
230 spi_common_control_config_t common_config;
231 } spi_control_config_t;
232
233 #if defined(SPI_SOC_HAS_CS_SELECT) && (SPI_SOC_HAS_CS_SELECT == 1)
234 typedef enum {
235 spi_cs_0 = 1,
236 spi_cs_1 = 2,
237 spi_cs_2 = 4,
238 spi_cs_3 = 8,
239 } spi_cs_index_t;
240 #endif
241
242 typedef enum {
243 addrlen_8bit = 0,
244 addrlen_16bit,
245 addrlen_24bit,
246 addrlen_32bit
247 } spi_address_len_t;
248
249 #if defined(SPI_SOC_SUPPORT_DIRECTIO) && (SPI_SOC_SUPPORT_DIRECTIO == 1)
250 typedef enum {
251 hold_pin = 0,
252 wp_pin,
253 miso_pin,
254 mosi_pin,
255 sclk_pin,
256 cs_pin
257 } spi_directio_pin_t;
258 #endif
259
260 #if defined(__cplusplus)
261 extern "C" {
262 #endif /* __cplusplus */
263
264 /**
265 * @brief spi master get default timing config
266 *
267 * @param [out] config spi_timing_config_t
268 */
269 void spi_master_get_default_timing_config(spi_timing_config_t *config);
270
271 /**
272 * @brief spi master get default format config
273 *
274 * @param [out] config spi_format_config_t
275 */
276 void spi_master_get_default_format_config(spi_format_config_t *config);
277
278 /**
279 * @brief spi master get default control config
280 *
281 * @param [out] config spi_control_config_t
282 */
283 void spi_master_get_default_control_config(spi_control_config_t *config);
284
285 /**
286 * @brief spi slave get default format config
287 *
288 * @param [out] config spi_format_config_t
289 */
290 void spi_slave_get_default_format_config(spi_format_config_t *config);
291
292 /**
293 * @brief spi slave get default control config
294 *
295 * @param [out] config spi_control_config_t
296 */
297 void spi_slave_get_default_control_config(spi_control_config_t *config);
298
299 /**
300 * @brief spi master timing initialization
301 *
302 * @param [in] ptr SPI base address
303 * @param [in] config spi_timing_config_t
304 * @retval hpm_stat_t status_invalid_argument or status_success
305 */
306 hpm_stat_t spi_master_timing_init(SPI_Type *ptr, spi_timing_config_t *config);
307
308 /**
309 * @brief spi format initialization
310 *
311 * @param [in] ptr SPI base address
312 * @param [in] config spi_format_config_t
313 */
314 void spi_format_init(SPI_Type *ptr, spi_format_config_t *config);
315
316 /**
317 * @brief spi transfer
318 *
319 * @param [in] ptr SPI base address
320 * @param [in] config spi_control_config_t
321 * @param [in,out] cmd spi transfer command address
322 * @param [in] addr spi transfer target address
323 * @param [in] wbuff spi sent data buff address
324 * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
325 * @param [out] rbuff spi receive data buff address
326 * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
327 * @retval hpm_stat_t status_success if spi transfer without any error
328 */
329 hpm_stat_t spi_transfer(SPI_Type *ptr,
330 spi_control_config_t *config,
331 uint8_t *cmd, uint32_t *addr,
332 uint8_t *wbuff, uint32_t wcount, uint8_t *rbuff, uint32_t rcount);
333
334 /**
335 * @brief spi setup dma transfer
336 *
337 * @param [in] ptr SPI base address
338 * @param [in] config spi_control_config_t
339 * @param [in] cmd spi transfer command address
340 * @param [in] addr spi transfer target address
341 * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
342 * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
343 * @retval hpm_stat_t status_success if spi setup dma transfer without any error
344 */
345 hpm_stat_t spi_setup_dma_transfer(SPI_Type *ptr,
346 spi_control_config_t *config,
347 uint8_t *cmd, uint32_t *addr,
348 uint32_t wcount, uint32_t rcount);
349
350 /**
351 * @brief spi wait for idle status
352 *
353 * @note on slave mode, if CS signal is asserted, take it as busy; if SPI CS signal is de-asserted, take it as idle.
354 *
355 * @param [in] ptr SPI base address
356 * @retval hpm_stat_t status_success if spi in idle status
357 */
358 hpm_stat_t spi_wait_for_idle_status(SPI_Type *ptr);
359
360 /**
361 * @brief spi wait for busy status
362 *
363 * @note on slave mode, if CS signal is asserted, take it as busy; if SPI CS signal is de-asserted, take it as idle.
364 *
365 * @param [in] ptr SPI base address
366 * @retval hpm_stat_t status_success if spi in busy status
367 */
368 hpm_stat_t spi_wait_for_busy_status(SPI_Type *ptr);
369
370 /**
371 * @brief SPI set TX FIFO threshold
372 *
373 * This function configures SPI TX FIFO threshold.
374 *
375 * @param ptr SPI base address.
376 * @param threshold The FIFO threshold value, the value should not greater than FIFO size.
377 */
spi_set_tx_fifo_threshold(SPI_Type * ptr,uint32_t threshold)378 static inline void spi_set_tx_fifo_threshold(SPI_Type *ptr, uint32_t threshold)
379 {
380 ptr->CTRL = (ptr->CTRL & ~SPI_CTRL_TXTHRES_MASK) | SPI_CTRL_TXTHRES_SET(threshold);
381 }
382
383 /**
384 * @brief SPI set RX FIFO threshold
385 *
386 * This function configures SPI RX FIFO threshold.
387 *
388 * @param ptr SPI base address.
389 * @param threshold The FIFO threshold value, the value should not greater than FIFO size.
390 */
spi_set_rx_fifo_threshold(SPI_Type * ptr,uint32_t threshold)391 static inline void spi_set_rx_fifo_threshold(SPI_Type *ptr, uint32_t threshold)
392 {
393 ptr->CTRL = (ptr->CTRL & ~SPI_CTRL_RXTHRES_MASK) | SPI_CTRL_RXTHRES_SET(threshold);
394 }
395
396 /**
397 * @brief Enables the SPI DMA request.
398 *
399 * This function configures the Rx and Tx DMA mask of the SPI. The parameters are base and a DMA mask.
400 *
401 * @param ptr SPI base address.
402 * @param mask The dma enable mask; Use the spi_dma_enable_t.
403 */
spi_enable_dma(SPI_Type * ptr,uint32_t mask)404 static inline void spi_enable_dma(SPI_Type *ptr, uint32_t mask)
405 {
406 ptr->CTRL |= mask;
407 }
408
409 /*!
410 * @brief Disables the SPI DMA request.
411 *
412 * This function configures the Rx and Tx DMA mask of the SPI. The parameters are base and a DMA mask.
413 *
414 * @param ptr SPI base address.
415 * @param mask The dma enable mask; Use the spi_dma_enable_t.
416 */
spi_disable_dma(SPI_Type * ptr,uint32_t mask)417 static inline void spi_disable_dma(SPI_Type *ptr, uint32_t mask)
418 {
419 ptr->CTRL &= ~mask;
420 }
421
422 /**
423 * @brief Get the SPI interrupt status.
424 *
425 * This function gets interrupt status of the SPI.
426 *
427 * @param ptr SPI base address.
428 * @retval SPI interrupt status register value
429 */
spi_get_interrupt_status(SPI_Type * ptr)430 static inline uint32_t spi_get_interrupt_status(SPI_Type *ptr)
431 {
432 return ptr->INTRST;
433 }
434
435 /**
436 * @brief Clear the SPI interrupt status.
437 *
438 * This function clears interrupt status of the SPI.
439 *
440 * @param ptr SPI base address.
441 * @param mask The interrupt mask; Use the spi_interrupt_t.
442 *
443 */
spi_clear_interrupt_status(SPI_Type * ptr,uint32_t mask)444 static inline void spi_clear_interrupt_status(SPI_Type *ptr, uint32_t mask)
445 {
446 /* write 1 to clear */
447 ptr->INTRST = mask;
448 }
449
450 /**
451 * @brief Enables the SPI interrupt.
452 *
453 * This function configures interrupt of the SPI. The parameters are base and a interrupt mask.
454 *
455 * @param ptr SPI base address.
456 * @param mask The interrupt mask; Use the spi_interrupt_t.
457 */
spi_enable_interrupt(SPI_Type * ptr,uint32_t mask)458 static inline void spi_enable_interrupt(SPI_Type *ptr, uint32_t mask)
459 {
460 ptr->INTREN |= mask;
461 }
462
463 /*!
464 * @brief Disables the SPI interrupt.
465 *
466 * This function configures interrupt of the SPI. The parameters are base and a interrupt mask.
467 *
468 * @param ptr SPI base address.
469 * @param mask The interrupt mask; Use the spi_interrupt_t.
470 */
spi_disable_interrupt(SPI_Type * ptr,uint32_t mask)471 static inline void spi_disable_interrupt(SPI_Type *ptr, uint32_t mask)
472 {
473 ptr->INTREN &= ~mask;
474 }
475
476 /**
477 * @brief spi write and read data
478 *
479 * @note Call this function after SPI CONTROL is configured by spi_control_init.
480 * The order of reading and writing is controlled by spi_control_init.
481 *
482 * @param [in] ptr SPI base address
483 * @param [in] data_len_in_bytes data length in bytes
484 * @param [in] wbuff spi sent data buff address
485 * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
486 * @param [out] rbuff spi receive data buff address
487 * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
488 * @retval hpm_stat_t status_success if spi transfer without any error
489 */
490 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);
491
492 /**
493 * @brief spi read data
494 *
495 * @note Call this function after SPI CONTROL is configured by spi_control_init.
496 *
497 * @param [in] ptr SPI base address
498 * @param [in] data_len_in_bytes data length in bytes
499 * @param [out] buff spi receive data buff address
500 * @param [in] count spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
501 * @retval hpm_stat_t status_success if spi transfer without any error
502 */
503 hpm_stat_t spi_read_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *buff, uint32_t count);
504
505 /**
506 * @brief spi write data
507 *
508 * @note Call this function after SPI CONTROL is configured by spi_control_init.
509 *
510 * @param [in] ptr SPI base address
511 * @param [in] data_len_in_bytes data length in bytes
512 * @param [in] buff spi sent data buff address
513 * @param [in] count spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
514 * @retval hpm_stat_t status_success if spi transfer without any error
515 */
516 hpm_stat_t spi_write_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *buff, uint32_t count);
517
518 /**
519 * @brief spi write command
520 *
521 * Writing operations on this register will trigger SPI transfers, call this function on master mode.
522 *
523 * @param [in] ptr SPI base address
524 * @param [in] mode spi mode, use the spi_mode_selection_t
525 * @param [in] config point to spi_control_config_t
526 * @param [in] cmd command data address
527 * @retval hpm_stat_t status_success if spi transfer without any error
528 */
529 hpm_stat_t spi_write_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd);
530
531 /**
532 * @brief spi read command
533 *
534 * On slave mode, the command field of the last received SPI transaction is stored in this SPI Command Register
535 *
536 * @param [in] ptr SPI base address
537 * @param [in] mode spi mode, use the spi_mode_selection_t
538 * @param [in] config point to spi_control_config_t
539 * @param [out] cmd command data address
540 * @retval hpm_stat_t status_success if spi transfer without any error
541 */
542 hpm_stat_t spi_read_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd);
543
544 /**
545 * @brief spi write address
546 *
547 * @note Call this function on master mode.
548 *
549 * @param [in] ptr SPI base address
550 * @param [in] mode spi mode, use the spi_mode_selection_t
551 * @param [in] config point to spi_control_config_t
552 * @param [in] addr point to address
553 * @retval hpm_stat_t status_success if spi transfer without any error
554 */
555 hpm_stat_t spi_write_address(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint32_t *addr);
556
557 /**
558 * @brief spi control initialization
559 *
560 * @param [in] ptr SPI base address
561 * @param [in] config point to spi_control_config_t
562 * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
563 * @param [in] rcount spi receive count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
564 * @retval hpm_stat_t status_success if spi transfer without any error
565 */
566 hpm_stat_t spi_control_init(SPI_Type *ptr, spi_control_config_t *config, uint32_t wcount, uint32_t rcount);
567
568 /**
569 * @brief Get the SPI data length in bits.
570 *
571 * @param ptr SPI base address.
572 * @retval SPI data length in bits
573 */
spi_get_data_length_in_bits(SPI_Type * ptr)574 static inline uint8_t spi_get_data_length_in_bits(SPI_Type *ptr)
575 {
576 return ((ptr->TRANSFMT & SPI_TRANSFMT_DATALEN_MASK) >> SPI_TRANSFMT_DATALEN_SHIFT) + 1;
577 }
578
579 /**
580 * @brief Get the SPI data length in bytes.
581 *
582 * @param ptr SPI base address.
583 * @retval SPI data length in bytes
584 */
spi_get_data_length_in_bytes(SPI_Type * ptr)585 static inline uint8_t spi_get_data_length_in_bytes(SPI_Type *ptr)
586 {
587 return ((spi_get_data_length_in_bits(ptr) + 7U) / 8U);
588 }
589
590 /**
591 * @brief SPI get active status.
592 *
593 * @param ptr SPI base address.
594 * @retval bool true for active, false for inactive
595 */
spi_is_active(SPI_Type * ptr)596 static inline bool spi_is_active(SPI_Type *ptr)
597 {
598 return ((ptr->STATUS & SPI_STATUS_SPIACTIVE_MASK) == SPI_STATUS_SPIACTIVE_MASK) ? true : false;
599 }
600
601 /**
602 * @brief SPI enable tx dma
603 *
604 * @param ptr SPI base address
605 */
spi_enable_tx_dma(SPI_Type * ptr)606 static inline void spi_enable_tx_dma(SPI_Type *ptr)
607 {
608 ptr->CTRL |= SPI_CTRL_TXDMAEN_MASK;
609 }
610
611 /**
612 * @brief SPI disable tx dma
613 *
614 * @param ptr SPI base address
615 */
spi_disable_tx_dma(SPI_Type * ptr)616 static inline void spi_disable_tx_dma(SPI_Type *ptr)
617 {
618 ptr->CTRL &= ~SPI_CTRL_TXDMAEN_MASK;
619 }
620
621 /**
622 * @brief SPI enable rx dma
623 *
624 * @param ptr SPI base address
625 */
spi_enable_rx_dma(SPI_Type * ptr)626 static inline void spi_enable_rx_dma(SPI_Type *ptr)
627 {
628 ptr->CTRL |= SPI_CTRL_RXDMAEN_MASK;
629 }
630
631 /**
632 * @brief SPI disable rx dma
633 *
634 * @param ptr SPI base address
635 */
spi_disable_rx_dma(SPI_Type * ptr)636 static inline void spi_disable_rx_dma(SPI_Type *ptr)
637 {
638 ptr->CTRL &= ~SPI_CTRL_RXDMAEN_MASK;
639 }
640
641 /**
642 * @brief SPI slave get sent data count
643 *
644 * @param ptr SPI base address
645 * @retval uint32_t data count
646 */
spi_slave_get_sent_data_count(SPI_Type * ptr)647 static inline uint32_t spi_slave_get_sent_data_count(SPI_Type *ptr)
648 {
649 #if defined(SPI_SOC_HAS_NEW_TRANS_COUNT) && (SPI_SOC_HAS_NEW_TRANS_COUNT == 1)
650 return ptr->SLVDATAWCNT;
651 #else
652 return SPI_SLVDATACNT_WCNT_GET(ptr->SLVDATACNT);
653 #endif
654 }
655
656 /**
657 * @brief SPI slave get received data count
658 *
659 * @param ptr SPI base address
660 * @retval uint32_t data count
661 */
spi_slave_get_received_data_count(SPI_Type * ptr)662 static inline uint32_t spi_slave_get_received_data_count(SPI_Type *ptr)
663 {
664 #if defined(SPI_SOC_HAS_NEW_TRANS_COUNT) && (SPI_SOC_HAS_NEW_TRANS_COUNT == 1)
665 return ptr->SLVDATARCNT;
666 #else
667 return SPI_SLVDATACNT_RCNT_GET(ptr->SLVDATACNT);
668 #endif
669 }
670
671 /**
672 * @brief set spi clock phase
673 *
674 * @param [in] ptr SPI base address
675 * @param [in] clock_phase clock phase enum
676 */
spi_set_clock_phase(SPI_Type * ptr,spi_sclk_sampling_clk_edges_t clock_phase)677 static inline void spi_set_clock_phase(SPI_Type *ptr, spi_sclk_sampling_clk_edges_t clock_phase)
678 {
679 ptr->TRANSCTRL |= SPI_TRANSFMT_CPHA_SET(clock_phase);
680 }
681
682 /**
683 * @brief get spi clock phase
684 *
685 * @param [in] ptr SPI base address
686 * @retval spi_sclk_sampling_clk_edges_t spi_sclk_sampling_odd_clk_edges if CPHA is 0
687 */
spi_get_clock_phase(SPI_Type * ptr)688 static inline spi_sclk_sampling_clk_edges_t spi_get_clock_phase(SPI_Type *ptr)
689 {
690 return SPI_TRANSFMT_CPHA_GET(ptr->TRANSCTRL);
691 }
692
693 /**
694 * @brief set spi clock polarity
695 *
696 * @param [in] ptr SPI base address
697 * @param [in] clock_polarity clock polarity enum
698 */
spi_set_clock_polarity(SPI_Type * ptr,spi_sclk_idle_state_t clock_polarity)699 static inline void spi_set_clock_polarity(SPI_Type *ptr, spi_sclk_idle_state_t clock_polarity)
700 {
701 ptr->TRANSCTRL |= SPI_TRANSFMT_CPOL_SET(clock_polarity);
702 }
703
704 /**
705 * @brief get spi clock phase
706 *
707 * @param [in] ptr SPI base address
708 * @retval spi_sclk_idle_state_t spi_sclk_low_idle if CPOL is 0
709 */
spi_get_clock_polarity(SPI_Type * ptr)710 static inline spi_sclk_idle_state_t spi_get_clock_polarity(SPI_Type *ptr)
711 {
712 return SPI_TRANSFMT_CPOL_GET(ptr->TRANSCTRL);
713 }
714
715 /**
716 * @brief set spi the length of each data unit in bits
717 *
718 * @param [in] ptr SPI base address
719 * @param [in] nbit the actual bits number of a data
720 * @retval hpm_stat_t status_success if spi transfer without any error
721 */
spi_set_data_bits(SPI_Type * ptr,uint8_t nbits)722 static inline hpm_stat_t spi_set_data_bits(SPI_Type *ptr, uint8_t nbits)
723 {
724 if (nbits > 32) {
725 return status_invalid_argument;
726 } else {
727 ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_DATALEN_MASK) | SPI_TRANSFMT_DATALEN_SET(nbits - 1);
728 return status_success;
729 }
730 }
731
732 /**
733 * @brief SPI transmit fifo reset
734 *
735 * @param ptr SPI base address
736 */
spi_transmit_fifo_reset(SPI_Type * ptr)737 static inline void spi_transmit_fifo_reset(SPI_Type *ptr)
738 {
739 ptr->CTRL |= SPI_CTRL_TXFIFORST_MASK;
740 }
741
742 /**
743 * @brief SPI receive fifo reset
744 *
745 * @param ptr SPI base address
746 */
spi_receive_fifo_reset(SPI_Type * ptr)747 static inline void spi_receive_fifo_reset(SPI_Type *ptr)
748 {
749 ptr->CTRL |= SPI_CTRL_RXFIFORST_MASK;
750 }
751
752 /**
753 * @brief SPI reset
754 *
755 * @param ptr SPI base address
756 */
spi_reset(SPI_Type * ptr)757 static inline void spi_reset(SPI_Type *ptr)
758 {
759 ptr->CTRL |= SPI_CTRL_SPIRST_MASK;
760 }
761
762 /**
763 * @brief set spi the length of address
764 *
765 * @param [in] ptr SPI base address
766 * @param [in] addrlen address lenth enum
767 */
spi_set_address_len(SPI_Type * ptr,spi_address_len_t addrlen)768 static inline void spi_set_address_len(SPI_Type *ptr, spi_address_len_t addrlen)
769 {
770 ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_ADDRLEN_MASK) | SPI_TRANSFMT_ADDRLEN_SET(addrlen);
771 }
772
773 /**
774 * @brief Enable SPI data merge
775 *
776 * @param [in] ptr SPI base address
777 */
spi_enable_data_merge(SPI_Type * ptr)778 static inline void spi_enable_data_merge(SPI_Type *ptr)
779 {
780 ptr->TRANSFMT |= SPI_TRANSFMT_DATAMERGE_MASK;
781 }
782
783 /**
784 * @brief Disable SPI data merge
785 *
786 * @param [in] ptr SPI base address
787 */
spi_disable_data_merge(SPI_Type * ptr)788 static inline void spi_disable_data_merge(SPI_Type *ptr)
789 {
790 ptr->TRANSFMT &= ~SPI_TRANSFMT_DATAMERGE_MASK;
791 }
792
793 #if defined(SPI_SOC_SUPPORT_DIRECTIO) && (SPI_SOC_SUPPORT_DIRECTIO == 1)
794 /**
795 * @brief enable specific pin output for spi directio
796 *
797 * @note must be used spi_enable_directio API before enable output function
798 *
799 * @param [in] ptr SPI base address
800 * @param [in] pin spi_directio_pin_t enum
801 */
802 hpm_stat_t spi_directio_enable_output(SPI_Type *ptr, spi_directio_pin_t pin);
803
804 /**
805 * @brief disable specific pin output for spi directio
806 *
807 * @param [in] ptr SPI base address
808 * @param [in] pin spi_directio_pin_t enum
809 */
810 hpm_stat_t spi_directio_disable_output(SPI_Type *ptr, spi_directio_pin_t pin);
811
812 /**
813 * @brief write specified pin level for spi directio
814 *
815 * @param [in] ptr SPI base address
816 * @param [in] pin spi_directio_pin_t enum
817 * @param [in] high Pin level set to high when it is set to true
818 */
819 hpm_stat_t spi_directio_write(SPI_Type *ptr, spi_directio_pin_t pin, bool high);
820
821 /**
822 * @brief Read specified pin level for spi directio
823 *
824 * @param [in] ptr SPI base address
825 * @param pin spi_directio_pin_t enum
826 *
827 * @return Pin status
828 */
829 uint8_t spi_directio_read(SPI_Type *ptr, spi_directio_pin_t pin);
830
831 /**
832 * @brief Enable SPI directIO control function
833 *
834 * @note if SPI transmission is required, the function must be disable
835 *
836 * @param [in] ptr SPI base address
837 */
spi_enable_directio(SPI_Type * ptr)838 static inline void spi_enable_directio(SPI_Type *ptr)
839 {
840 ptr->DIRECTIO |= SPI_DIRECTIO_DIRECTIOEN_MASK;
841 }
842
843 /**
844 * @brief Disable SPI directIO control function
845 *
846 * @param [in] ptr SPI base address
847 */
spi_disable_directio(SPI_Type * ptr)848 static inline void spi_disable_directio(SPI_Type *ptr)
849 {
850 ptr->DIRECTIO &= ~SPI_DIRECTIO_DIRECTIOEN_MASK;
851 }
852
853 /**
854 * @brief get whether spi directio function is enabled
855 *
856 * @param [in] ptr SPI base address
857 *
858 * @return if pi directio function is enable, it will return 1
859 */
spi_get_directio_enable_status(SPI_Type * ptr)860 static inline uint8_t spi_get_directio_enable_status(SPI_Type *ptr)
861 {
862 return SPI_DIRECTIO_DIRECTIOEN_GET(ptr->DIRECTIO);
863 }
864
865 #endif
866
867 /**
868 * @brief Get valid data size in receive FIFO
869 *
870 * @param [in] ptr SPI base address
871 *
872 * @return rx fifo valid data size
873 */
spi_get_rx_fifo_valid_data_size(SPI_Type * ptr)874 static inline uint8_t spi_get_rx_fifo_valid_data_size(SPI_Type *ptr)
875 {
876 return ((SPI_STATUS_RXNUM_7_6_GET(ptr->STATUS) << 5) | SPI_STATUS_RXNUM_5_0_GET(ptr->STATUS));
877 }
878
879 /**
880 * @brief Get valid data size in transmit FIFO
881 *
882 * @param [in] ptr SPI base address
883 *
884 * @return tx fifo valid data size
885 */
spi_get_tx_fifo_valid_data_size(SPI_Type * ptr)886 static inline uint8_t spi_get_tx_fifo_valid_data_size(SPI_Type *ptr)
887 {
888 return ((SPI_STATUS_TXNUM_7_6_GET(ptr->STATUS) << 5) | SPI_STATUS_TXNUM_5_0_GET(ptr->STATUS));
889 }
890 /**
891 * @}
892 */
893
894 #if defined(__cplusplus)
895 }
896 #endif /* __cplusplus */
897 #endif /* HPM_SPI_DRV_H */
898