• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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