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 typedef enum {
148     msb_first = 0,
149     lsb_first,
150 } spi_shift_direction_t;
151 
152 /**
153  * @brief spi master interface timing config structure
154  */
155 typedef struct {
156     uint32_t clk_src_freq_in_hz;
157     uint32_t sclk_freq_in_hz;
158     uint8_t cs2sclk;
159     uint8_t csht;
160 } spi_master_timing_config_t;
161 
162 /**
163  * @brief spi interface timing config structure
164  */
165 typedef struct {
166     spi_master_timing_config_t master_config;
167 } spi_timing_config_t;
168 
169 /**
170  * @brief spi master transfer format config structure
171  */
172 typedef struct {
173     uint8_t addr_len_in_bytes;
174 } spi_master_format_config_t;
175 
176 /**
177  * @brief spi common format config structure
178  */
179 typedef struct {
180     uint8_t data_len_in_bits;
181     bool data_merge;
182     bool mosi_bidir;
183     bool lsb;
184     uint8_t mode;
185     uint8_t cpol;
186     uint8_t cpha;
187 } spi_common_format_config_t;
188 
189 /**
190  * @brief spi format config structure
191  */
192 typedef struct {
193     spi_master_format_config_t master_config;
194     spi_common_format_config_t common_config;
195 } spi_format_config_t;
196 
197 /**
198  * @brief spi master transfer control config structure
199  */
200 typedef struct {
201     bool cmd_enable;
202     bool addr_enable;
203     uint8_t addr_phase_fmt;
204     bool token_enable;
205     uint8_t token_value;
206 } spi_master_control_config_t;
207 
208 /**
209  * @brief spi slave transfer control config structure
210  */
211 typedef struct {
212     bool slave_data_only;
213 } spi_slave_control_config_t;
214 
215 /**
216  * @brief spi common transfer control config structure
217  */
218 typedef struct {
219     bool tx_dma_enable;
220     bool rx_dma_enable;
221     uint8_t trans_mode;
222     uint8_t data_phase_fmt;
223     uint8_t dummy_cnt;
224 #if defined(HPM_IP_FEATURE_SPI_CS_SELECT) && (HPM_IP_FEATURE_SPI_CS_SELECT == 1)
225     uint8_t cs_index;
226 #endif
227 } spi_common_control_config_t; /*!< value in spi_cs_index_t */
228 
229 /**
230  * @brief spi control config structure
231  */
232 typedef struct {
233     spi_master_control_config_t master_config;
234     spi_slave_control_config_t  slave_config;
235     spi_common_control_config_t common_config;
236 } spi_control_config_t;
237 
238 #if defined(HPM_IP_FEATURE_SPI_CS_SELECT) && (HPM_IP_FEATURE_SPI_CS_SELECT == 1)
239 typedef enum {
240     spi_cs_0 = 1,
241     spi_cs_1 = 2,
242     spi_cs_2 = 4,
243     spi_cs_3 = 8,
244 } spi_cs_index_t;
245 #endif
246 
247 typedef enum {
248     addrlen_8bit = 0,
249     addrlen_16bit,
250     addrlen_24bit,
251     addrlen_32bit
252 } spi_address_len_t;
253 
254 #if defined(HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO) && (HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO == 1)
255 typedef enum {
256     hold_pin = 0,
257     wp_pin,
258     miso_pin,
259     mosi_pin,
260     sclk_pin,
261     cs_pin
262 } spi_directio_pin_t;
263 
264 #endif
265 
266 
267 
268 #if defined(__cplusplus)
269 extern "C" {
270 #endif /* __cplusplus */
271 
272 /**
273  * @brief spi master get default timing config
274  *
275  * @param [out] config spi_timing_config_t
276  */
277 void spi_master_get_default_timing_config(spi_timing_config_t *config);
278 
279 /**
280  * @brief spi master get default format config
281  *
282  * @param [out] config spi_format_config_t
283  */
284 void spi_master_get_default_format_config(spi_format_config_t *config);
285 
286 /**
287  * @brief spi master get default control config
288  *
289  * @param [out] config spi_control_config_t
290  */
291 void spi_master_get_default_control_config(spi_control_config_t *config);
292 
293 /**
294  * @brief spi slave get default format config
295  *
296  * @param [out] config spi_format_config_t
297  */
298 void spi_slave_get_default_format_config(spi_format_config_t *config);
299 
300 /**
301  * @brief spi slave get default control config
302  *
303  * @param [out] config spi_control_config_t
304  */
305 void spi_slave_get_default_control_config(spi_control_config_t *config);
306 
307 /**
308  * @brief spi master timing initialization
309  *
310  * @param [in] ptr SPI base address
311  * @param [in] config spi_timing_config_t
312  * @retval hpm_stat_t status_invalid_argument or status_success
313  */
314 hpm_stat_t spi_master_timing_init(SPI_Type *ptr, spi_timing_config_t *config);
315 
316 /**
317  * @brief spi format initialization
318  *
319  * @param [in] ptr SPI base address
320  * @param [in] config spi_format_config_t
321  */
322 void spi_format_init(SPI_Type *ptr, spi_format_config_t *config);
323 
324 /**
325  * @brief spi transfer
326  *
327  * @param [in] ptr SPI base address
328  * @param [in] config spi_control_config_t
329  * @param [in,out] cmd spi transfer command address
330  * @param [in] addr spi transfer target address
331  * @param [in] wbuff spi sent data buff address
332  * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
333  * @param [out] rbuff spi receive data buff address
334  * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
335  * @retval hpm_stat_t status_success if spi transfer without any error
336  */
337 hpm_stat_t spi_transfer(SPI_Type *ptr,
338                         spi_control_config_t *config,
339                         uint8_t *cmd, uint32_t *addr,
340                         uint8_t *wbuff, uint32_t wcount,  uint8_t *rbuff, uint32_t rcount);
341 
342 /**
343  * @brief spi setup dma transfer
344  *
345  * @param [in] ptr SPI base address
346  * @param [in] config spi_control_config_t
347  * @param [in] cmd spi transfer command address
348  * @param [in] addr spi transfer target address
349  * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
350  * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
351  * @retval hpm_stat_t status_success if spi setup dma transfer without any error
352  */
353 hpm_stat_t spi_setup_dma_transfer(SPI_Type *ptr,
354                         spi_control_config_t *config,
355                         uint8_t *cmd, uint32_t *addr,
356                         uint32_t wcount, uint32_t rcount);
357 
358 /**
359  * @brief spi wait for idle status
360  *
361  * @note on slave mode, if CS signal is asserted, take it as busy; if SPI CS signal is de-asserted, take it as idle.
362  *
363  * @param [in] ptr SPI base address
364  * @retval hpm_stat_t status_success if spi in idle status
365  */
366 hpm_stat_t spi_wait_for_idle_status(SPI_Type *ptr);
367 
368 /**
369  * @brief spi wait for busy status
370  *
371  * @note on slave mode, if CS signal is asserted, take it as busy; if SPI CS signal is de-asserted, take it as idle.
372  *
373  * @param [in] ptr SPI base address
374  * @retval hpm_stat_t status_success if spi in busy status
375  */
376 hpm_stat_t spi_wait_for_busy_status(SPI_Type *ptr);
377 
378 /**
379  * @brief SPI set TX FIFO threshold
380  *
381  * This function configures SPI TX FIFO threshold.
382  *
383  * @param ptr SPI base address.
384  * @param threshold The FIFO threshold value, the value should not greater than FIFO size.
385  */
spi_set_tx_fifo_threshold(SPI_Type * ptr,uint32_t threshold)386 static inline void spi_set_tx_fifo_threshold(SPI_Type *ptr, uint32_t threshold)
387 {
388     ptr->CTRL = (ptr->CTRL & ~SPI_CTRL_TXTHRES_MASK) | SPI_CTRL_TXTHRES_SET(threshold);
389 }
390 
391 /**
392  * @brief SPI set RX FIFO threshold
393  *
394  * This function configures SPI RX FIFO threshold.
395  *
396  * @param ptr SPI base address.
397  * @param threshold The FIFO threshold value, the value should not greater than FIFO size.
398  */
spi_set_rx_fifo_threshold(SPI_Type * ptr,uint32_t threshold)399 static inline void spi_set_rx_fifo_threshold(SPI_Type *ptr, uint32_t threshold)
400 {
401     ptr->CTRL = (ptr->CTRL & ~SPI_CTRL_RXTHRES_MASK) | SPI_CTRL_RXTHRES_SET(threshold);
402 }
403 
404 /**
405  * @brief Enables the SPI DMA request.
406  *
407  * This function configures the Rx and Tx DMA mask of the SPI. The parameters are base and a DMA mask.
408  *
409  * @param ptr SPI base address.
410  * @param mask The dma enable mask; Use the spi_dma_enable_t.
411  */
spi_enable_dma(SPI_Type * ptr,uint32_t mask)412 static inline void spi_enable_dma(SPI_Type *ptr, uint32_t mask)
413 {
414     ptr->CTRL |= mask;
415 }
416 
417 /*!
418  * @brief Disables the SPI DMA request.
419  *
420  * This function configures the Rx and Tx DMA mask of the SPI.  The parameters are base and a DMA mask.
421  *
422  * @param ptr SPI base address.
423  * @param mask The dma enable mask; Use the spi_dma_enable_t.
424  */
spi_disable_dma(SPI_Type * ptr,uint32_t mask)425 static inline void spi_disable_dma(SPI_Type *ptr, uint32_t mask)
426 {
427     ptr->CTRL &= ~mask;
428 }
429 
430 /**
431  * @brief Get the SPI interrupt status.
432  *
433  * This function gets interrupt status of the SPI.
434  *
435  * @param ptr SPI base address.
436  * @retval SPI interrupt status register value
437  */
spi_get_interrupt_status(SPI_Type * ptr)438 static inline uint32_t spi_get_interrupt_status(SPI_Type *ptr)
439 {
440     return ptr->INTRST;
441 }
442 
443 /**
444  * @brief Clear the SPI interrupt status.
445  *
446  * This function clears interrupt status of the SPI.
447  *
448  * @param ptr SPI base address.
449  * @param mask The interrupt mask; Use the spi_interrupt_t.
450  *
451  */
spi_clear_interrupt_status(SPI_Type * ptr,uint32_t mask)452 static inline void spi_clear_interrupt_status(SPI_Type *ptr, uint32_t mask)
453 {
454     /* write 1 to clear */
455     ptr->INTRST = mask;
456 }
457 
458 /**
459  * @brief Enables the SPI interrupt.
460  *
461  * This function configures interrupt of the SPI. The parameters are base and a interrupt mask.
462  *
463  * @param ptr SPI base address.
464  * @param mask The interrupt mask; Use the spi_interrupt_t.
465  */
spi_enable_interrupt(SPI_Type * ptr,uint32_t mask)466 static inline void spi_enable_interrupt(SPI_Type *ptr, uint32_t mask)
467 {
468     ptr->INTREN |= mask;
469 }
470 
471 /*!
472  * @brief Disables the SPI interrupt.
473  *
474  * This function configures interrupt of the SPI. The parameters are base and a interrupt mask.
475  *
476  * @param ptr SPI base address.
477  * @param mask The interrupt mask; Use the spi_interrupt_t.
478  */
spi_disable_interrupt(SPI_Type * ptr,uint32_t mask)479 static inline void spi_disable_interrupt(SPI_Type *ptr, uint32_t mask)
480 {
481     ptr->INTREN &= ~mask;
482 }
483 
484 /**
485  * @brief spi write and read data
486  *
487  * @note Call this function after SPI CONTROL is configured by spi_control_init.
488  * The order of reading and writing is controlled by spi_control_init.
489  *
490  * @param [in] ptr SPI base address
491  * @param [in] data_len_in_bytes data length in bytes
492  * @param [in] wbuff spi sent data buff address
493  * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
494  * @param [out] rbuff spi receive data buff address
495  * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
496  * @retval hpm_stat_t status_success if spi transfer without any error
497  */
498 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);
499 
500 /**
501  * @brief spi read data
502  *
503  * @note Call this function after SPI CONTROL is configured by spi_control_init.
504  *
505  * @param [in] ptr SPI base address
506  * @param [in] data_len_in_bytes data length in bytes
507  * @param [out] buff spi receive data buff address
508  * @param [in] count spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
509  * @retval hpm_stat_t status_success if spi transfer without any error
510  */
511 hpm_stat_t spi_read_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *buff, uint32_t count);
512 
513 /**
514  * @brief spi write data
515  *
516  * @note Call this function after SPI CONTROL is configured by spi_control_init.
517  *
518  * @param [in] ptr SPI base address
519  * @param [in] data_len_in_bytes data length in bytes
520  * @param [in] buff spi sent data buff address
521  * @param [in] count spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
522  * @retval hpm_stat_t status_success if spi transfer without any error
523  */
524 hpm_stat_t spi_write_data(SPI_Type *ptr, uint8_t data_len_in_bytes, uint8_t *buff, uint32_t count);
525 
526 /**
527  * @brief spi write command
528  *
529  * Writing operations on this register will trigger SPI transfers, call this function on master mode.
530  *
531  * @param [in] ptr SPI base address
532  * @param [in] mode spi mode, use the spi_mode_selection_t
533  * @param [in] config point to spi_control_config_t
534  * @param [in] cmd command data address
535  * @retval hpm_stat_t status_success if spi transfer without any error
536  */
537 hpm_stat_t spi_write_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd);
538 
539 /**
540  * @brief spi read command
541  *
542  * On slave mode, the command field of the last received SPI transaction is stored in this SPI Command Register
543  *
544  * @param [in] ptr SPI base address
545  * @param [in] mode spi mode, use the spi_mode_selection_t
546  * @param [in] config point to spi_control_config_t
547  * @param [out] cmd command data address
548  * @retval hpm_stat_t status_success if spi transfer without any error
549  */
550 hpm_stat_t spi_read_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd);
551 
552 /**
553  * @brief spi write address
554  *
555  * @note Call this function on master mode.
556  *
557  * @param [in] ptr SPI base address
558  * @param [in] mode spi mode, use the spi_mode_selection_t
559  * @param [in] config point to spi_control_config_t
560  * @param [in] addr point to address
561  * @retval hpm_stat_t status_success if spi transfer without any error
562  */
563 hpm_stat_t spi_write_address(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint32_t *addr);
564 
565 /**
566  * @brief spi control initialization
567  *
568  * @param [in] ptr SPI base address
569  * @param [in] config point to spi_control_config_t
570  * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
571  * @param [in] rcount spi receive count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
572  * @retval hpm_stat_t status_success if spi transfer without any error
573  */
574 hpm_stat_t spi_control_init(SPI_Type *ptr, spi_control_config_t *config, uint32_t wcount, uint32_t rcount);
575 
576 /**
577  * @brief Get the SPI data length in bits.
578  *
579  * @param ptr SPI base address.
580  * @retval SPI data length in bits
581  */
spi_get_data_length_in_bits(SPI_Type * ptr)582 static inline uint8_t spi_get_data_length_in_bits(SPI_Type *ptr)
583 {
584     return ((ptr->TRANSFMT & SPI_TRANSFMT_DATALEN_MASK) >> SPI_TRANSFMT_DATALEN_SHIFT) + 1;
585 }
586 
587 /**
588  * @brief Get the SPI data length in bytes.
589  *
590  * @param ptr SPI base address.
591  * @retval SPI data length in bytes
592  */
spi_get_data_length_in_bytes(SPI_Type * ptr)593 static inline uint8_t spi_get_data_length_in_bytes(SPI_Type *ptr)
594 {
595     return ((spi_get_data_length_in_bits(ptr) + 7U) / 8U);
596 }
597 
598 /**
599  * @brief SPI get active status.
600  *
601  * @param ptr SPI base address.
602  * @retval bool true for active, false for inactive
603  */
spi_is_active(SPI_Type * ptr)604 static inline bool spi_is_active(SPI_Type *ptr)
605 {
606     return ((ptr->STATUS & SPI_STATUS_SPIACTIVE_MASK) == SPI_STATUS_SPIACTIVE_MASK) ? true : false;
607 }
608 
609 /**
610  * @brief SPI enable tx dma
611  *
612  * @param ptr SPI base address
613  */
spi_enable_tx_dma(SPI_Type * ptr)614 static inline void spi_enable_tx_dma(SPI_Type *ptr)
615 {
616     ptr->CTRL |= SPI_CTRL_TXDMAEN_MASK;
617 }
618 
619 /**
620  * @brief SPI disable tx dma
621  *
622  * @param ptr SPI base address
623  */
spi_disable_tx_dma(SPI_Type * ptr)624 static inline void spi_disable_tx_dma(SPI_Type *ptr)
625 {
626     ptr->CTRL &= ~SPI_CTRL_TXDMAEN_MASK;
627 }
628 
629 /**
630  * @brief SPI enable rx dma
631  *
632  * @param ptr SPI base address
633  */
spi_enable_rx_dma(SPI_Type * ptr)634 static inline void spi_enable_rx_dma(SPI_Type *ptr)
635 {
636     ptr->CTRL |= SPI_CTRL_RXDMAEN_MASK;
637 }
638 
639 /**
640  * @brief SPI disable rx dma
641  *
642  * @param ptr SPI base address
643  */
spi_disable_rx_dma(SPI_Type * ptr)644 static inline void spi_disable_rx_dma(SPI_Type *ptr)
645 {
646     ptr->CTRL &= ~SPI_CTRL_RXDMAEN_MASK;
647 }
648 
649 /**
650  * @brief SPI slave get sent data count
651  *
652  * @param ptr SPI base address
653  * @retval uint32_t data count
654  */
spi_slave_get_sent_data_count(SPI_Type * ptr)655 static inline uint32_t spi_slave_get_sent_data_count(SPI_Type *ptr)
656 {
657 #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
658     return ptr->SLVDATAWCNT;
659 #else
660     return SPI_SLVDATACNT_WCNT_GET(ptr->SLVDATACNT);
661 #endif
662 }
663 
664 /**
665  * @brief SPI slave get received data count
666  *
667  * @param ptr SPI base address
668  * @retval uint32_t data count
669  */
spi_slave_get_received_data_count(SPI_Type * ptr)670 static inline uint32_t spi_slave_get_received_data_count(SPI_Type *ptr)
671 {
672 #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
673     return ptr->SLVDATARCNT;
674 #else
675     return SPI_SLVDATACNT_RCNT_GET(ptr->SLVDATACNT);
676 #endif
677 }
678 
679 /**
680  * @brief set spi clock phase
681  *
682  * @param [in] ptr SPI base address
683  * @param [in] clock_phase clock phase enum
684  */
spi_set_clock_phase(SPI_Type * ptr,spi_sclk_sampling_clk_edges_t clock_phase)685 static inline void spi_set_clock_phase(SPI_Type *ptr, spi_sclk_sampling_clk_edges_t clock_phase)
686 {
687     ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_CPHA_MASK) | SPI_TRANSFMT_CPHA_SET(clock_phase);
688 }
689 
690 /**
691  * @brief get spi clock phase
692  *
693  * @param [in] ptr SPI base address
694  * @retval spi_sclk_sampling_clk_edges_t spi_sclk_sampling_odd_clk_edges if CPHA is 0
695  */
spi_get_clock_phase(SPI_Type * ptr)696 static inline spi_sclk_sampling_clk_edges_t spi_get_clock_phase(SPI_Type *ptr)
697 {
698     return (spi_sclk_sampling_clk_edges_t)SPI_TRANSFMT_CPHA_GET(ptr->TRANSFMT);
699 }
700 
701 /**
702  * @brief set spi clock polarity
703  *
704  * @param [in] ptr SPI base address
705  * @param [in] clock_polarity clock polarity enum
706  */
spi_set_clock_polarity(SPI_Type * ptr,spi_sclk_idle_state_t clock_polarity)707 static inline void spi_set_clock_polarity(SPI_Type *ptr, spi_sclk_idle_state_t clock_polarity)
708 {
709     ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_CPOL_MASK) | SPI_TRANSFMT_CPOL_SET(clock_polarity);
710 }
711 
712 /**
713  * @brief get spi clock phase
714  *
715  * @param [in] ptr SPI base address
716  * @retval spi_sclk_idle_state_t spi_sclk_low_idle if CPOL is 0
717  */
spi_get_clock_polarity(SPI_Type * ptr)718 static inline spi_sclk_idle_state_t spi_get_clock_polarity(SPI_Type *ptr)
719 {
720     return (spi_sclk_idle_state_t)SPI_TRANSFMT_CPOL_GET(ptr->TRANSFMT);
721 }
722 
723 /**
724  * @brief set spi the length of each data unit in bits
725  *
726  * @param [in] ptr SPI base address
727  * @param [in] nbits the actual bits number of a data
728  * @retval hpm_stat_t status_success if spi transfer without any error
729  */
spi_set_data_bits(SPI_Type * ptr,uint8_t nbits)730 static inline hpm_stat_t spi_set_data_bits(SPI_Type *ptr, uint8_t nbits)
731 {
732     if (nbits > 32) {
733         return status_invalid_argument;
734     } else {
735         ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_DATALEN_MASK) | SPI_TRANSFMT_DATALEN_SET(nbits - 1);
736         return status_success;
737     }
738 }
739 
740 /**
741  * @brief SPI transmit fifo reset
742  *
743  * @param ptr SPI base address
744  */
spi_transmit_fifo_reset(SPI_Type * ptr)745 static inline void spi_transmit_fifo_reset(SPI_Type *ptr)
746 {
747     ptr->CTRL |= SPI_CTRL_TXFIFORST_MASK;
748 }
749 
750 /**
751  * @brief SPI receive fifo reset
752  *
753  * @param ptr SPI base address
754  */
spi_receive_fifo_reset(SPI_Type * ptr)755 static inline void spi_receive_fifo_reset(SPI_Type *ptr)
756 {
757     ptr->CTRL |= SPI_CTRL_RXFIFORST_MASK;
758 }
759 
760 /**
761  * @brief SPI reset
762  *
763  * @param ptr SPI base address
764  */
spi_reset(SPI_Type * ptr)765 static inline void spi_reset(SPI_Type *ptr)
766 {
767     ptr->CTRL |= SPI_CTRL_SPIRST_MASK;
768 }
769 
770 /**
771  * @brief set spi the length of address
772  *
773  * @param [in] ptr SPI base address
774  * @param [in] addrlen address lenth enum
775  */
spi_set_address_len(SPI_Type * ptr,spi_address_len_t addrlen)776 static inline void spi_set_address_len(SPI_Type *ptr, spi_address_len_t addrlen)
777 {
778     ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_ADDRLEN_MASK) | SPI_TRANSFMT_ADDRLEN_SET(addrlen);
779 }
780 
781 /**
782  * @brief   Enable SPI data merge
783  *
784  * @param [in] ptr SPI base address
785  */
spi_enable_data_merge(SPI_Type * ptr)786 static inline void spi_enable_data_merge(SPI_Type *ptr)
787 {
788     ptr->TRANSFMT |= SPI_TRANSFMT_DATAMERGE_MASK;
789 }
790 
791 /**
792  * @brief   Disable SPI data merge
793  *
794  * @param [in] ptr SPI base address
795  */
spi_disable_data_merge(SPI_Type * ptr)796 static inline void spi_disable_data_merge(SPI_Type *ptr)
797 {
798     ptr->TRANSFMT &= ~SPI_TRANSFMT_DATAMERGE_MASK;
799 }
800 
801 #if defined(HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO) && (HPM_IP_FEATURE_SPI_SUPPORT_DIRECTIO == 1)
802 /**
803  * @brief enable specific pin output for spi directio
804  *
805  * @note must be used spi_enable_directio API before enable output function
806  *
807  * @param [in] ptr SPI base address
808  * @param [in] pin spi_directio_pin_t enum
809  */
810 hpm_stat_t spi_directio_enable_output(SPI_Type *ptr, spi_directio_pin_t pin);
811 
812 /**
813  * @brief disable specific pin output for spi directio
814  *
815  * @param [in] ptr SPI base address
816  * @param [in] pin spi_directio_pin_t enum
817  */
818 hpm_stat_t spi_directio_disable_output(SPI_Type *ptr, spi_directio_pin_t pin);
819 
820 /**
821  * @brief write specified pin level  for spi directio
822  *
823  * @param [in] ptr SPI base address
824  * @param [in] pin spi_directio_pin_t enum
825  * @param [in] high Pin level set to high when it is set to true
826  */
827 hpm_stat_t spi_directio_write(SPI_Type *ptr, spi_directio_pin_t pin, bool high);
828 
829 /**
830  * @brief   Read specified pin level for spi directio
831  *
832  * @param [in] ptr SPI base address
833  * @param pin spi_directio_pin_t enum
834  *
835  * @return Pin status
836  */
837 uint8_t spi_directio_read(SPI_Type *ptr, spi_directio_pin_t pin);
838 
839 /**
840  * @brief   Enable SPI directIO control function
841  *
842  * @note if SPI transmission is required, the function must be disable
843  *
844  * @param [in] ptr SPI base address
845  */
spi_enable_directio(SPI_Type * ptr)846 static inline void spi_enable_directio(SPI_Type *ptr)
847 {
848     ptr->DIRECTIO |= SPI_DIRECTIO_DIRECTIOEN_MASK;
849 }
850 
851 /**
852  * @brief   Disable SPI directIO control function
853  *
854  * @param [in] ptr SPI base address
855  */
spi_disable_directio(SPI_Type * ptr)856 static inline void spi_disable_directio(SPI_Type *ptr)
857 {
858     ptr->DIRECTIO &= ~SPI_DIRECTIO_DIRECTIOEN_MASK;
859 }
860 
861 /**
862  * @brief  get whether spi directio function is enabled
863  *
864  * @param [in] ptr SPI base address
865  *
866  * @return if pi directio function is enable, it will return 1
867  */
spi_get_directio_enable_status(SPI_Type * ptr)868 static inline uint8_t spi_get_directio_enable_status(SPI_Type *ptr)
869 {
870     return SPI_DIRECTIO_DIRECTIOEN_GET(ptr->DIRECTIO);
871 }
872 
873 #endif
874 
875 /**
876  * @brief  Get valid data size in receive FIFO
877  *
878  * @param [in] ptr SPI base address
879  *
880  * @return rx fifo valid data size
881  */
spi_get_rx_fifo_valid_data_size(SPI_Type * ptr)882 static inline uint8_t spi_get_rx_fifo_valid_data_size(SPI_Type *ptr)
883 {
884     return ((SPI_STATUS_RXNUM_7_6_GET(ptr->STATUS) << 5) | SPI_STATUS_RXNUM_5_0_GET(ptr->STATUS));
885 }
886 
887 /**
888  * @brief  Get valid data size in transmit FIFO
889  *
890  * @param [in] ptr SPI base address
891  *
892  * @return tx fifo valid data size
893  */
spi_get_tx_fifo_valid_data_size(SPI_Type * ptr)894 static inline uint8_t spi_get_tx_fifo_valid_data_size(SPI_Type *ptr)
895 {
896     return ((SPI_STATUS_TXNUM_7_6_GET(ptr->STATUS) << 5) | SPI_STATUS_TXNUM_5_0_GET(ptr->STATUS));
897 }
898 
899 /**
900  * @brief  Get SPI RXFIFO size
901  *
902  * @param [in] ptr SPI base address
903  *
904  * @return RXFIFO size, the unit is word
905  */
spi_get_rx_fifo_size(SPI_Type * ptr)906 static inline uint8_t spi_get_rx_fifo_size(SPI_Type *ptr)
907 {
908     uint8_t size = SPI_CONFIG_RXFIFOSIZE_GET(ptr->CONFIG);
909     return (2 << size);
910 }
911 
912 /**
913  * @brief  Get SPI TXFIFO size
914  *
915  * @param [in] ptr SPI base address
916  *
917  * @return TXFIFO size, the unit is word
918  */
spi_get_tx_fifo_size(SPI_Type * ptr)919 static inline uint8_t spi_get_tx_fifo_size(SPI_Type *ptr)
920 {
921     uint8_t size = SPI_CONFIG_TXFIFOSIZE_GET(ptr->CONFIG);
922     return (2 << size);
923 }
924 
925 /**
926  * @brief SPI slave enable only date mode
927  *
928  * @note This mode only works in the uni-directional regular (single) mode
929  * @param [in] ptr SPI base address
930  */
spi_slave_enable_data_only(SPI_Type * ptr)931 static inline void spi_slave_enable_data_only(SPI_Type *ptr)
932 {
933     ptr->TRANSCTRL |= SPI_TRANSCTRL_SLVDATAONLY_MASK;
934 }
935 
936 /**
937  * @brief SPI slave disable only date mode
938  *
939  * @param [in] ptr SPI base address
940  */
spi_slave_disable_data_only(SPI_Type * ptr)941 static inline void spi_slave_disable_data_only(SPI_Type *ptr)
942 {
943     ptr->TRANSCTRL &= ~SPI_TRANSCTRL_SLVDATAONLY_MASK;
944 }
945 
946 /**
947  * @brief SPI master enable command phase
948  *
949  * @param [in] ptr SPI base address
950  */
spi_master_enable_command_phase(SPI_Type * ptr)951 static inline void spi_master_enable_command_phase(SPI_Type *ptr)
952 {
953     ptr->TRANSCTRL |= SPI_TRANSCTRL_CMDEN_MASK;
954 }
955 
956 /**
957  * @brief SPI master disable command phase
958  *
959  * @param [in] ptr SPI base address
960  */
spi_master_disable_command_phase(SPI_Type * ptr)961 static inline void spi_master_disable_command_phase(SPI_Type *ptr)
962 {
963     ptr->TRANSCTRL &= ~SPI_TRANSCTRL_CMDEN_MASK;
964 }
965 
966 /**
967  * @brief SPI master enable address phase
968  *
969  * @param [in] ptr SPI base address
970  */
spi_master_enable_address_phase(SPI_Type * ptr)971 static inline void spi_master_enable_address_phase(SPI_Type *ptr)
972 {
973     ptr->TRANSCTRL |= SPI_TRANSCTRL_ADDREN_MASK;
974 }
975 
976 /**
977  * @brief SPI master disable address phase
978  *
979  * @param [in] ptr SPI base address
980  */
spi_master_disable_address_phase(SPI_Type * ptr)981 static inline void spi_master_disable_address_phase(SPI_Type *ptr)
982 {
983     ptr->TRANSCTRL &= ~SPI_TRANSCTRL_ADDREN_MASK;
984 }
985 
986 /**
987  * @brief SPI master set address phase format
988  *
989  * @param [in] ptr SPI base address
990  * @param [in] format spi_addr_phase_format_t enum
991  */
spi_master_set_address_phase_format(SPI_Type * ptr,spi_addr_phase_format_t format)992 static inline void spi_master_set_address_phase_format(SPI_Type *ptr, spi_addr_phase_format_t format)
993 {
994     ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_ADDRFMT_MASK) | SPI_TRANSCTRL_ADDRFMT_SET(format);
995 }
996 
997 /**
998  * @brief SPI master set transfer mode
999  *
1000  * @param [in] ptr SPI base address
1001  * @param [in] mode spi_trans_mode_t enum
1002  */
spi_set_transfer_mode(SPI_Type * ptr,spi_trans_mode_t mode)1003 static inline void spi_set_transfer_mode(SPI_Type *ptr, spi_trans_mode_t mode)
1004 {
1005     ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_TRANSMODE_MASK) | SPI_TRANSCTRL_TRANSMODE_SET(mode);
1006 }
1007 
1008 /**
1009  * @brief SPI master enable token transfer
1010  *
1011  * @param [in] ptr SPI base address
1012  */
spi_master_enable_token_transfer(SPI_Type * ptr)1013 static inline void spi_master_enable_token_transfer(SPI_Type *ptr)
1014 {
1015     ptr->TRANSCTRL |= SPI_TRANSCTRL_TOKENEN_MASK;
1016 }
1017 
1018 /**
1019  * @brief SPI master disable token transfer
1020  *
1021  * @param [in] ptr SPI base address
1022  */
spi_master_disable_token_transfer(SPI_Type * ptr)1023 static inline void spi_master_disable_token_transfer(SPI_Type *ptr)
1024 {
1025     ptr->TRANSCTRL &= ~SPI_TRANSCTRL_TOKENEN_MASK;
1026 }
1027 
1028 /**
1029  * @brief SPI master set transfer count for write data
1030  *
1031  * @param [in] ptr SPI base address
1032  * @param [in] count the number of units of data to be transmitted to the SPI bus from the Data
1033  */
spi_set_write_data_count(SPI_Type * ptr,uint32_t count)1034 static inline void spi_set_write_data_count(SPI_Type *ptr, uint32_t count)
1035 {
1036 #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
1037     ptr->WR_TRANS_CNT = (count - 1);
1038 #else
1039     ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_WRTRANCNT_MASK) | SPI_TRANSCTRL_WRTRANCNT_SET(count - 1);
1040 #endif
1041 }
1042 
1043 /**
1044  * @brief SPI master set transfer count for read data
1045  *
1046  * @param [in] ptr SPI base address
1047  * @param [in] count  the number of units of data to be received from SPI bus and stored to the Data
1048  */
spi_set_read_data_count(SPI_Type * ptr,uint32_t count)1049 static inline void spi_set_read_data_count(SPI_Type *ptr, uint32_t count)
1050 {
1051 #if defined(HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT) && (HPM_IP_FEATURE_SPI_NEW_TRANS_COUNT == 1)
1052     ptr->RD_TRANS_CNT = (count - 1);
1053 #else
1054     ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_RDTRANCNT_MASK) | SPI_TRANSCTRL_RDTRANCNT_SET(count - 1);
1055 #endif
1056 }
1057 
1058 /**
1059  * @brief SPI master set the value of the one-byte special token following the address phase for SPI read transfers
1060  *
1061  * @param [in] ptr SPI base address
1062  * @param [in] value spi_token_value_t enum
1063  */
spi_master_set_token_value(SPI_Type * ptr,spi_token_value_t value)1064 static inline void spi_master_set_token_value(SPI_Type *ptr, spi_token_value_t value)
1065 {
1066     ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_TOKENVALUE_MASK) | SPI_TRANSCTRL_TOKENVALUE_SET(value);
1067 }
1068 
1069 /**
1070  * @brief SPI master set dummy data count
1071  *
1072  * @param [in] ptr SPI base address
1073  * @param [in] count spi_dummy_count_t enum
1074  */
spi_set_dummy_count(SPI_Type * ptr,spi_dummy_count_t count)1075 static inline void spi_set_dummy_count(SPI_Type *ptr, spi_dummy_count_t count)
1076 {
1077     ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_DUMMYCNT_MASK) | SPI_TRANSCTRL_DUMMYCNT_SET(count);
1078 }
1079 
1080 /**
1081  * @brief SPI master set the minimum time between the edges of SPI CS and the edges of SCLK
1082  *
1083  * @param [in] ptr SPI base address
1084  * @param [in] duration spi_cs2sclk_duration_t enum
1085  */
spi_master_set_cs2sclk_timing(SPI_Type * ptr,spi_cs2sclk_duration_t duration)1086 static inline void spi_master_set_cs2sclk_timing(SPI_Type *ptr, spi_cs2sclk_duration_t duration)
1087 {
1088     ptr->TIMING = (ptr->TIMING & ~SPI_TIMING_CS2SCLK_MASK) | SPI_TIMING_CS2SCLK_SET(duration);
1089 }
1090 
1091 /**
1092  * @brief SPI master get the minimum time between the edges of SPI CS and the edges of SCLK
1093  *
1094  * @param [in] ptr SPI base address
1095  * @retval spi_cs2sclk_duration_t enum
1096  */
spi_master_get_cs2sclk_timing(SPI_Type * ptr)1097 static inline spi_cs2sclk_duration_t spi_master_get_cs2sclk_timing(SPI_Type *ptr)
1098 {
1099     return (spi_cs2sclk_duration_t)SPI_TIMING_CS2SCLK_GET(ptr->TIMING);
1100 }
1101 
1102 /**
1103  * @brief SPI master set the minimum time that SPI CS should stay HIGH.
1104  *
1105  * @param [in] ptr SPI base address
1106  * @param [in] duration spi_csht_duration_t enum
1107  */
spi_master_set_csht_timing(SPI_Type * ptr,spi_csht_duration_t duration)1108 static inline void spi_master_set_csht_timing(SPI_Type *ptr, spi_csht_duration_t duration)
1109 {
1110     ptr->TIMING = (ptr->TIMING & ~SPI_TIMING_CSHT_MASK) | SPI_TIMING_CSHT_SET(duration);
1111 }
1112 
1113 /**
1114  * @brief SPI master get the minimum time that SPI CS should stay HIGH.
1115  *
1116  * @param [in] ptr SPI base address
1117  * @retval spi_csht_duration_t enum
1118  */
spi_master_get_csht_timing(SPI_Type * ptr)1119 static inline spi_csht_duration_t spi_master_get_csht_timing(SPI_Type *ptr)
1120 {
1121     return (spi_csht_duration_t)SPI_TIMING_CSHT_GET(ptr->TIMING);
1122 }
1123 
1124 /**
1125  * @brief SPI master set the clock frequency ratio between the clock source and SPI SCLK
1126  *
1127  * @param [in] ptr SPI base address
1128  * @param [in] div the frequency ratio value
1129  */
spi_master_set_sclk_div(SPI_Type * ptr,uint8_t div)1130 static inline void spi_master_set_sclk_div(SPI_Type *ptr, uint8_t div)
1131 {
1132     ptr->TIMING = (ptr->TIMING & ~SPI_TIMING_SCLK_DIV_MASK) | SPI_TIMING_SCLK_DIV_SET(div);
1133 }
1134 
1135 /**
1136  * @brief SPI master get the clock frequency ratio between the clock source and SPI SCLK
1137  *
1138  * @param [in] ptr SPI base address
1139  *
1140  * @retval return the frequency ratio value
1141  */
spi_master_get_sclk_div(SPI_Type * ptr)1142 static inline uint8_t spi_master_get_sclk_div(SPI_Type *ptr)
1143 {
1144     return SPI_TIMING_SCLK_DIV_GET(ptr->TIMING);
1145 }
1146 
1147 /**
1148  * @brief SPI slave set the user defined status flags
1149  *
1150  * @note in Non-SlvDataOnly, the command is read status command, such as 0x05\0x15\0x25 command
1151  *
1152  * @param [in] ptr SPI base address
1153  * @param [in] user_status user status value
1154  */
spi_slave_set_user_status(SPI_Type * ptr,uint16_t user_status)1155 static inline void spi_slave_set_user_status(SPI_Type *ptr, uint16_t user_status)
1156 {
1157     ptr->SLVST = (ptr->SLVST & ~SPI_SLVST_USR_STATUS_MASK) | SPI_SLVST_USR_STATUS_SET(user_status);
1158 }
1159 
1160 /**
1161  * @brief SPI master set data phase format
1162  *
1163  * @param [in] ptr SPI base address
1164  * @param [in] format spi_data_phase_format_t enum
1165  */
spi_master_set_data_phase_format(SPI_Type * ptr,spi_data_phase_format_t format)1166 static inline void spi_master_set_data_phase_format(SPI_Type *ptr, spi_data_phase_format_t format)
1167 {
1168     ptr->TRANSCTRL = (ptr->TRANSCTRL & ~SPI_TRANSCTRL_DUALQUAD_MASK) | SPI_TRANSCTRL_DUALQUAD_SET(format);
1169 }
1170 
1171 /**
1172  * @brief SPI master get data phase format
1173  *
1174  * @param [in] ptr SPI base address
1175  *
1176  * @retval return the data phase format
1177  */
spi_master_get_data_phase_format(SPI_Type * ptr)1178 static inline spi_data_phase_format_t spi_master_get_data_phase_format(SPI_Type *ptr)
1179 {
1180     return (spi_data_phase_format_t)SPI_TRANSCTRL_DUALQUAD_GET(ptr->TRANSCTRL);
1181 }
1182 
1183 /**
1184  * @brief set spi shift direction
1185  *
1186  * @param [in] ptr SPI base address
1187  * @param [in] shift_direction shift direction enum
1188  */
spi_set_shift_direction(SPI_Type * ptr,spi_shift_direction_t shift_direction)1189 static inline void spi_set_shift_direction(SPI_Type *ptr, spi_shift_direction_t shift_direction)
1190 {
1191     ptr->TRANSFMT = (ptr->TRANSFMT & ~SPI_TRANSFMT_LSB_MASK) | SPI_TRANSFMT_LSB_SET(shift_direction);
1192 }
1193 
1194 /**
1195  * @brief get spi shift direction
1196  *
1197  * @param [in] ptr SPI base address
1198  * @retval spi_shift_direction_t msb_first if frist MSB
1199  */
spi_get_shift_direction(SPI_Type * ptr)1200 static inline spi_shift_direction_t spi_get_shift_direction(SPI_Type *ptr)
1201 {
1202     return (spi_shift_direction_t)SPI_TRANSFMT_LSB_GET(ptr->TRANSFMT);
1203 }
1204 
1205 /**
1206  * @}
1207  */
1208 
1209 #if defined(__cplusplus)
1210 }
1211 #endif /* __cplusplus */
1212 #endif /* HPM_SPI_DRV_H */
1213