1 /*
2 * Copyright (c) 2022 ASR Microelectronics (Shanghai) Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef __DUET_SPI_H
17 #define __DUET_SPI_H
18
19 #include "duet.h"
20 #include <errno.h>
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #define DUET_SPI0_INDEX 0
27 #define DUET_SPI1_INDEX 1
28 #define DUET_SPI2_INDEX 2
29 #define DUET_SPI_NUM 3
30
31 #define SPI_ROLE_MASTER (0x0)
32 #define SPI_ROLE_SLAVE (0x4)
33 #define SPI_ROLE_MASTER_SLAVE SPI_ROLE_MASTER
34
35 #define SPI_CPOL_CPHA_MODE 0
36 #define SPI_DMA_RX_CONFIG DISABLE
37 #define SPI_DMA_TX_CONFIG DISABLE
38
39 #define SPI_CLK (52000000)
40 #define SPI_FIFO_DEPTH (8)
41
42 #define SPI_FRAME_FORMAT_SPI (0x0)
43
44 #define SPI_SLAVE_OUTPUT_DISABLE (1 << 3)
45
46 #define SPI_CLK_POLARITY_POS (0x6)
47 #define SPI_CLK_POLARITY_LOW (0x0)
48 #define SPI_CLK_POLARITY_HIGH (0x1 << SPI_CLK_POLARITY_POS)
49
50 #define SPI_CLK_PHASE_POS (0x7)
51 #define SPI_CLK_PHASE_1EDGE (0x0)
52 #define SPI_CLK_PHASE_2EDGE (0x1 << SPI_CLK_PHASE_POS)
53
54 #define SPI_DATA_SIZE_4BIT (0x3)
55 #define SPI_DATA_SIZE_8BIT (0x7)
56 #define SPI_DATA_SIZE_16BIT (0xF)
57
58 /* SPI flags */
59 #define SPI_FLAG_TX_FIFO_EMPTY (0x1)
60 #define SPI_FLAG_TX_FIFO_NOT_FULL (1 << 1)
61 #define SPI_FLAG_RX_FIFO_NOT_EMPTY (1 << 2)
62 #define SPI_FLAG_RX_FIFO_FULL (1 << 3)
63 #define SPI_FLAG_BUSY (1 << 4
64
65 /* SPI interrupts */
66 #define SPI_INTERRUPT_RX_FIFO_OVERRUN (1 << 0)
67 #define SPI_INTERRUPT_RX_TIMEOUT (1 << 1)
68 #define SPI_INTERRUPT_RX_FIFO_TRIGGER (1 << 2) // there are four or more entries in rx fifo
69 #define SPI_INTERRUPT_TX_FIFO_TRIGGER (1 << 3) // there are four or fewer entries in tx fifo. what happens when fifo level is exactly 4??
70 #define SPI_INTERRUPT_ALL (0xf)
71 #define SPI_DISABLE_INTERRUPT_ALL (0x0)
72
73 #define SPI_DMA_TX_EN (1<<1)
74 #define SPI_DMA_RX_EN (1)
75
76 typedef struct {
77 uint32_t mode; /* spi communication mode */
78 uint32_t freq; /* communication frequency Hz */
79 } duet_spi_config_t;
80
81 typedef struct {
82 uint8_t port; /* spi port */
83 duet_spi_config_t config; /* spi config */
84 void *priv; /* priv data */
85 } duet_spi_dev_t;
86
87 typedef void (*duet_spi_callback_func)(uint8_t);
88 extern duet_spi_callback_func g_duet_spi_callback_handler[DUET_SPI_NUM];
89
duet_spi_interrupt_clear(SPI_TypeDef * SPIx,uint8_t spi_interrupt)90 __STATIC_INLINE void duet_spi_interrupt_clear(SPI_TypeDef *SPIx, uint8_t spi_interrupt)
91 {
92 SPIx->ICR |= spi_interrupt;
93 }
94
duet_spi_get_flag_status(SPI_TypeDef * SPIx,uint8_t spi_flag)95 __STATIC_INLINE ITstatus duet_spi_get_flag_status(SPI_TypeDef *SPIx, uint8_t spi_flag)
96 {
97 return SPIx->SR & spi_flag;
98 }
99
duet_spi_get_interrupt_status(SPI_TypeDef * SPIx,uint8_t spi_interrupt)100 __STATIC_INLINE ITstatus duet_spi_get_interrupt_status(SPI_TypeDef *SPIx, uint8_t spi_interrupt)
101 {
102 return SPIx->MIS & spi_interrupt;
103 }
104
duet_spi_get_raw_interrupt_status(SPI_TypeDef * SPIx,uint8_t spi_interrupt)105 __STATIC_INLINE ITstatus duet_spi_get_raw_interrupt_status(SPI_TypeDef *SPIx, uint8_t spi_interrupt)
106 {
107 return SPIx->RIS & spi_interrupt;
108 }
109
110 void duet_spi_interrupt_config(SPI_TypeDef *SPIx, uint8_t spi_interrupt, uint8_t new_state);
111 int32_t duet_spi_dma_config(duet_spi_dev_t *spi, uint8_t dma_tx_rx_sel, uint8_t new_state);
112 int32_t duet_spi_cpol_cpha_config(duet_spi_dev_t *spi, uint8_t mode);
113 void duet_spi_cmd(SPI_TypeDef *SPIx, uint8_t new_state);
114 void duet_spi_struct_init(duet_spi_dev_t *init_struct);
115
116 /**
117 * Initialises the SPI interface for a given SPI device
118 *
119 * @param[in] spi the spi device
120 *
121 * @return 0 : on success, EIO : if the SPI device could not be initialised
122 */
123 int32_t duet_spi_init(duet_spi_dev_t *spi);
124
125 /**
126 * Spi send
127 *
128 * @param[in] spi the spi device
129 * @param[in] data spi send data
130 * @param[in] size spi send data size
131 * @param[in] timeout timeout in ms
132 *
133 * @return 0 : on success, EIO : if the SPI device could not be initialised
134 */
135 int32_t duet_spi_send(duet_spi_dev_t *spi, const uint8_t *data, uint16_t size, uint32_t timeout);
136
137 /**
138 * De-initialises a SPI interface
139 *
140 *
141 * @param[in] spi the SPI device to be de-initialised
142 *
143 * @return 0 : on success, EIO : if an error occurred
144 */
145 int32_t duet_spi_finalize(duet_spi_dev_t *spi);
146
147 #ifdef __cplusplus
148 }
149 #endif
150
151 #endif /* __DUET_SPI_H */
152