• 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 data length in bit
42  */
43 typedef enum {
44     spi_data_length_8_bits = 7,
45     spi_data_length_16_bits = 15,
46     spi_data_length_31_bits = 30
47 } spi_data_length_in_bits_t;
48 
49 /**
50  * @brief spi mode selection
51  */
52 typedef enum {
53     spi_master_mode = 0,
54     spi_slave_mode
55 } spi_mode_selection_t;
56 
57 /**
58  * @brief spi clock polarity
59  */
60 typedef enum {
61     spi_sclk_low_idle = 0,
62     spi_sclk_high_idle
63 } spi_sclk_idle_state_t;
64 
65 /**
66  * @brief spi clock phase
67  */
68 typedef enum {
69     spi_sclk_sampling_odd_clk_edges = 0,
70     spi_sclk_sampling_even_clk_edges
71 } spi_sclk_sampling_clk_edges_t;
72 
73 /**
74  * @brief spi cs to sclk edge duration
75  */
76 typedef enum {
77     spi_cs2sclk_half_sclk_1 = 0,
78     spi_cs2sclk_half_sclk_2,
79     spi_cs2sclk_half_sclk_3,
80     spi_cs2sclk_half_sclk_4
81 } spi_cs2sclk_duration_t;
82 
83 /**
84  * @brief spi cs high level duration
85  */
86 typedef enum {
87     spi_csht_half_sclk_1 = 0,
88     spi_csht_half_sclk_2,
89     spi_csht_half_sclk_3,
90     spi_csht_half_sclk_4,
91     spi_csht_half_sclk_5,
92     spi_csht_half_sclk_6,
93     spi_csht_half_sclk_7,
94     spi_csht_half_sclk_8,
95     spi_csht_half_sclk_9,
96     spi_csht_half_sclk_10,
97     spi_csht_half_sclk_11,
98     spi_csht_half_sclk_12,
99     spi_csht_half_sclk_13,
100     spi_csht_half_sclk_14,
101     spi_csht_half_sclk_15,
102     spi_csht_half_sclk_16,
103 } spi_csht_duration_t;
104 
105 /**
106  * @brief spi address phase format
107  */
108 typedef enum {
109     spi_address_phase_format_single_io_mode = 0,
110     spi_address_phase_format_dualquad_io_mode
111 } spi_addr_phase_format_t;
112 
113 /**
114  * @brief spi transfer mode
115  */
116 typedef enum {
117     spi_trans_write_read_together = 0,
118     spi_trans_write_only,
119     spi_trans_read_only,
120     spi_trans_write_read,
121     spi_trans_read_write,
122     spi_trans_write_dummy_read,
123     spi_trans_read_dummy_write,
124     spi_trans_no_data,
125     spi_trans_dummy_write,
126     spi_trans_dummy_read
127 } spi_trans_mode_t;
128 
129 /**
130  * @brief spi data phase format
131  */
132 typedef enum {
133     spi_single_io_mode = 0,
134     spi_dual_io_mode,
135     spi_quad_io_mode,
136 } spi_data_phase_format_t;
137 
138 /**
139  * @brief spi token value
140  */
141 typedef enum {
142     spi_token_value_0x00 = 0,
143     spi_token_value_0x69
144 } spi_token_value_t;
145 
146 /**
147  * @brief spi dummy count
148  */
149 typedef enum {
150     spi_dummy_count_1 = 0,
151     spi_dummy_count_2,
152     spi_dummy_count_3,
153     spi_dummy_count_4
154 } spi_dummy_count_t;
155 
156 /**
157  * @brief spi master interface timing config structure
158  */
159 typedef struct {
160     uint32_t clk_src_freq_in_hz;
161     uint32_t sclk_freq_in_hz;
162     uint8_t cs2sclk;
163     uint8_t csht;
164 } spi_master_timing_config_t;
165 
166 /**
167  * @brief spi interface timing config structure
168  */
169 typedef struct {
170     spi_master_timing_config_t master_config;
171 } spi_timing_config_t;
172 
173 /**
174  * @brief spi master transfer format config structure
175  */
176 typedef struct {
177     uint8_t addr_len_in_bytes;
178 } spi_master_format_config_t;
179 
180 /**
181  * @brief spi common format config structure
182  */
183 typedef struct {
184     uint8_t data_len_in_bits;
185     bool data_merge;
186     bool mosi_bidir;
187     bool lsb;
188     uint8_t mode;
189     uint8_t cpol;
190     uint8_t cpha;
191 } spi_common_format_config_t;
192 
193 /**
194  * @brief spi format config structure
195  */
196 typedef struct {
197     spi_master_format_config_t master_config;
198     spi_common_format_config_t common_config;
199 } spi_format_config_t;
200 
201 /**
202  * @brief spi master transfer control config structure
203  */
204 typedef struct {
205     bool cmd_enable;
206     bool addr_enable;
207     uint8_t addr_phase_fmt;
208     bool token_enable;
209     uint8_t token_value;
210 } spi_master_control_config_t;
211 
212 /**
213  * @brief spi slave transfer control config structure
214  */
215 typedef struct {
216     bool slave_data_only;
217 } spi_slave_control_config_t;
218 
219 /**
220  * @brief spi common transfer control config structure
221  */
222 typedef struct {
223     bool tx_dma_enable;
224     bool rx_dma_enable;
225     uint8_t trans_mode;
226     uint8_t data_phase_fmt;
227     uint8_t dummy_cnt;
228 } spi_common_control_config_t;
229 
230 /**
231  * @brief spi control config structure
232  */
233 typedef struct {
234     spi_master_control_config_t master_config;
235     spi_slave_control_config_t  slave_config;
236     spi_common_control_config_t common_config;
237 } spi_control_config_t;
238 
239 #if defined(__cplusplus)
240 extern "C" {
241 #endif /* __cplusplus */
242 
243 /**
244  * @brief spi master get default timing config
245  *
246  * @param [out] config spi_timing_config_t
247  */
248 void spi_master_get_default_timing_config(spi_timing_config_t *config);
249 
250 /**
251  * @brief spi master get default format config
252  *
253  * @param [out] config spi_format_config_t
254  */
255 void spi_master_get_default_format_config(spi_format_config_t *config);
256 
257 /**
258  * @brief spi master get default control config
259  *
260  * @param [out] config spi_control_config_t
261  */
262 void spi_master_get_default_control_config(spi_control_config_t *config);
263 
264 /**
265  * @brief spi slave get default format config
266  *
267  * @param [out] config spi_format_config_t
268  */
269 void spi_slave_get_default_format_config(spi_format_config_t *config);
270 
271 /**
272  * @brief spi slave get default control config
273  *
274  * @param [out] config spi_control_config_t
275  */
276 void spi_slave_get_default_control_config(spi_control_config_t *config);
277 
278 /**
279  * @brief spi master timing initialization
280  *
281  * @param [in] ptr SPI base address
282  * @param [in] config spi_timing_config_t
283  * @retval hpm_stat_t status_invalid_argument or status_success
284  */
285 hpm_stat_t spi_master_timing_init(SPI_Type *ptr, spi_timing_config_t *config);
286 
287 /**
288  * @brief spi format initialization
289  *
290  * @param [in] ptr SPI base address
291  * @param [in] config spi_format_config_t
292  */
293 void spi_format_init(SPI_Type *ptr, spi_format_config_t *config);
294 
295 /**
296  * @brief spi transfer
297  *
298  * @param [in] ptr SPI base address
299  * @param [in] config spi_control_config_t
300  * @param [in] cmd spi transfer mode
301  * @param [in] addr spi transfer target address
302  * @param [in] wbuff spi sent data buff address
303  * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
304  * @param [in] rbuff spi receive data buff address
305  * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
306  * @retval hpm_stat_t status_success if spi transfer without any error
307  */
308 hpm_stat_t spi_transfer(SPI_Type *ptr,
309                         spi_control_config_t *config,
310                         uint8_t *cmd, uint32_t *addr,
311                         uint8_t *wbuff, uint32_t wcount,  uint8_t *rbuff, uint32_t rcount);
312 
313 /**
314  * @brief spi setup dma transfer
315  *
316  * @param [in] ptr SPI base address
317  * @param [in] config spi_control_config_t
318  * @param [in] cmd spi transfer mode
319  * @param [in] addr spi transfer target address
320  * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
321  * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
322  * @retval hpm_stat_t status_success if spi setup dma transfer without any error
323  */
324 hpm_stat_t spi_setup_dma_transfer(SPI_Type *ptr,
325                         spi_control_config_t *config,
326                         uint8_t *cmd, uint32_t *addr,
327                         uint32_t wcount, uint32_t rcount);
328 
329 /**
330  * @brief spi wait for idle status
331  *
332  * @param [in] ptr SPI base address
333  * @retval hpm_stat_t status_success if spi in idle status
334  */
335 hpm_stat_t spi_wait_for_idle_status(SPI_Type *ptr);
336 
337 /**
338  * @brief spi wait for busy status
339  *
340  * @param [in] ptr SPI base address
341  * @retval hpm_stat_t status_success if spi in busy status
342  */
343 hpm_stat_t spi_wait_for_busy_status(SPI_Type *ptr);
344 
345 /**
346  * @brief Enables the SPI DMA request.
347  *
348  * This function configures the Rx and Tx DMA mask of the SPI. The parameters are base and a DMA mask.
349  *
350  * @param base SPI base address.
351  * @param mask The dma enable mask; Use the spi_dma_enable_t.
352  */
spi_enable_dma(SPI_Type * ptr,uint32_t mask)353 static inline void spi_enable_dma(SPI_Type *ptr, uint32_t mask)
354 {
355     ptr->CTRL |= mask;
356 }
357 
358 /*!
359  * @brief Disables the SPI DMA request.
360  *
361  * This function configures the Rx and Tx DMA mask of the SPI.  The parameters are base and a DMA mask.
362  *
363  * @param base SPI base address.
364  * @param mask The dma enable mask; Use the spi_dma_enable_t.
365  */
spi_disable_dma(SPI_Type * ptr,uint32_t mask)366 static inline void spi_disable_dma(SPI_Type *ptr, uint32_t mask)
367 {
368     ptr->CTRL &= ~mask;
369 }
370 
371 /**
372  * @brief Get the SPI interrupt status.
373  *
374  * This function gets interrupt status of the SPI.
375  *
376  * @param base SPI base address.
377  * @retval SPI interrupt status register value
378  */
spi_get_interrupt_status(SPI_Type * ptr)379 static inline uint32_t spi_get_interrupt_status(SPI_Type *ptr)
380 {
381     return ptr->INTRST;
382 }
383 
384 /**
385  * @brief Clear the SPI interrupt status.
386  *
387  * This function clears interrupt status of the SPI.
388  *
389  * @param base SPI base address.
390  * @param mask The interrupt mask; Use the spi_interrupt_t.
391  *
392  */
spi_clear_interrupt_status(SPI_Type * ptr,uint32_t mask)393 static inline void spi_clear_interrupt_status(SPI_Type *ptr, uint32_t mask)
394 {
395     /* write 1 to clear */
396     ptr->INTRST |= mask;
397 }
398 
399 /**
400  * @brief Enables the SPI interrupt.
401  *
402  * This function configures interrupt of the SPI. The parameters are base and a interrupt mask.
403  *
404  * @param base SPI base address.
405  * @param mask The interrupt mask; Use the spi_interrupt_t.
406  */
spi_enable_interrupt(SPI_Type * ptr,uint32_t mask)407 static inline void spi_enable_interrupt(SPI_Type *ptr, uint32_t mask)
408 {
409     ptr->INTREN |= mask;
410 }
411 
412 /*!
413  * @brief Disables the SPI interrupt.
414  *
415  * This function configures interrupt of the SPI. The parameters are base and a interrupt mask.
416  *
417  * @param base SPI base address.
418  * @param mask The interrupt mask; Use the spi_interrupt_t.
419  */
spi_disable_interrupt(SPI_Type * ptr,uint32_t mask)420 static inline void spi_disable_interrupt(SPI_Type *ptr, uint32_t mask)
421 {
422     ptr->INTREN &= ~mask;
423 }
424 
425 /**
426  * @brief spi write and read data
427  *
428  * @note Call this function after SPI CONTROL is configured by spi_control_init.
429  * The order of reading and writing is controlled by spi_control_init.
430  *
431  * @param [in] ptr SPI base address
432  * @param [in] datalen data length in bit, use the spi_data_length_in_bits_t
433  * @param [in] wbuff spi sent data buff address
434  * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
435  * @param [in] rbuff spi receive data buff address
436  * @param [in] rcount spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
437  * @retval hpm_stat_t status_success if spi transfer without any error
438  */
439 hpm_stat_t spi_write_read_data(SPI_Type *ptr, uint8_t datalen, uint8_t *wbuff, uint32_t wcount, uint8_t *rbuff, uint32_t rcount);
440 
441 /**
442  * @brief spi read data
443  *
444  * @note Call this function after SPI CONTROL is configured by spi_control_init.
445  *
446  * @param [in] ptr SPI base address
447  * @param [in] datalen data length in bit, use the spi_data_length_in_bits_t
448  * @param [in] buff spi receive data buff address
449  * @param [in] count spi receive data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
450  * @retval hpm_stat_t status_success if spi transfer without any error
451  */
452 hpm_stat_t spi_read_data(SPI_Type *ptr, uint8_t datalen, uint8_t *buff, uint32_t count);
453 
454 /**
455  * @brief spi write data
456  *
457  * @note Call this function after SPI CONTROL is configured by spi_control_init.
458  *
459  * @param [in] ptr SPI base address
460  * @param [in] datalen data length in bit, use the spi_data_length_in_bits_t
461  * @param [in] buff spi sent data buff address
462  * @param [in] count spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
463  * @retval hpm_stat_t status_success if spi transfer without any error
464  */
465 hpm_stat_t spi_write_data(SPI_Type *ptr, uint8_t datalen, uint8_t *buff, uint32_t count);
466 
467 /**
468  * @brief spi write command
469  *
470  * @note Call this function after SPI CONTROL is configured by spi_control_init.
471  *
472  * @param [in] ptr SPI base address
473  * @param [in] mode spi mode, use the spi_mode_selection_t
474  * @param [in] config point to spi_control_config_t
475  * @param [in] cmd command data address
476  * @retval hpm_stat_t status_success if spi transfer without any error
477  */
478 hpm_stat_t spi_write_command(SPI_Type *ptr, spi_mode_selection_t mode, spi_control_config_t *config, uint8_t *cmd);
479 
480 /**
481  * @brief spi control initialization
482  *
483  * @param [in] ptr SPI base address
484  * @param [in] config point to spi_control_config_t
485  * @param [in] wcount spi sent data count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
486  * @param [in] rcount spi receive count, not greater than SPI_SOC_TRANSFER_COUNT_MAX
487  * @retval hpm_stat_t status_success if spi transfer without any error
488  */
489 hpm_stat_t spi_control_init(SPI_Type *ptr, spi_control_config_t *config, uint32_t wcount, uint32_t rcount);
490 
491 /**
492  * @}
493  */
494 
495 #if defined(__cplusplus)
496 }
497 #endif /* __cplusplus */
498 #endif /* HPM_SPI_DRV_H */
499