1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 /**
10  * @addtogroup SPI
11  * @{
12  *
13  * @brief Defines standard APIs of the Serial Peripheral Interface (SPI) capabilities.
14  *
15  * The SPI module abstracts the SPI capabilities of different system platforms to provide stable APIs
16  * for driver development.
17  * This module can create and destroy SPI device handles, read and write SPI data,
18  * and obtain and set configuration parameters.
19  *
20  * @since 1.0
21  */
22 
23 /**
24  * @file spi_if.h
25  *
26  * @brief Defines standard SPI-specific interfaces for driver development.
27  *
28  * A driver needs to use the SPI-specific interfaces for data writing and reading
29  * before performing any operations on an SPI-compliant device.
30  *
31  * @since 1.0
32  */
33 
34 #ifndef SPI_IF_H
35 #define SPI_IF_H
36 
37 #include "platform_if.h"
38 
39 #ifdef __cplusplus
40 #if __cplusplus
41 extern "C" {
42 #endif
43 #endif /* __cplusplus */
44 
45 /**
46  * @brief Indicates the SPI clock phase. The value <b>0</b> indicates that data will be sampled on the first clock edge,
47  * and <b>1</b> indicates that data will be sampled on the second clock edge.
48  *
49  * @since 1.0
50  */
51 #define SPI_CLK_PHASE            (1 << 0)
52 /**
53  * @brief Indicates the SPI clock polarity. The value <b>0</b> indicates a low-level clock signal in the idle state,
54  * and <b>1</b> indicates a high-level clock signal in the idle state.
55  *
56  * @since 1.0
57  */
58 #define SPI_CLK_POLARITY         (1 << 1)
59 /**
60  * @brief Indicates that a single data line is used for both input and output.
61  *
62  * @since 1.0
63  */
64 #define SPI_MODE_3WIRE           (1 << 2)
65 /**
66  * @brief Indicates the SPI loopback mode.
67  *
68  * @since 1.0
69  */
70 #define SPI_MODE_LOOP            (1 << 3)
71 /**
72  * @brief Indicates the SPI data transfer order. The value <b>0</b> indicates that data is transferred from the most
73  * significant bit (MSB) to the least significant bit (LSB), and <b>1</b> indicates the opposite.
74  *
75  * @since 1.0
76  */
77 #define SPI_MODE_LSBFE           (1 << 4)
78 /**
79  * @brief Indicates that there is only one SPI device, and no chip select (CS) is required.
80  *
81  * @since 1.0
82  */
83 #define SPI_MODE_NOCS            (1 << 5)
84 /**
85  * @brief Indicates that the CS level is high when an SPI device is selected.
86  *
87  * @since 1.0
88  */
89 #define SPI_MODE_CS_HIGH         (1 << 6)
90 /**
91  * @brief Indicates that the SPI device is set to low for pausing data transfer.
92  *
93  * @since 1.0
94  */
95 #define SPI_MODE_READY           (1 << 7)
96 
97 /**
98  * @brief Enumerates transfer modes of SPI data.
99  *
100  * @attention The specific SPI controller determines which variables in this structure are supported.
101  *
102  * @since 1.0
103  */
104 enum SpiTransferMode {
105     SPI_INTERRUPT_TRANSFER = 0, /**< Interrupt transfer mode */
106     SPI_POLLING_TRANSFER,       /**< Polling transfer mode */
107     SPI_DMA_TRANSFER,           /**< Direct Memory Access (DMA) transfer mode */
108 };
109 
110 /**
111  * @brief Defines the general SPI device descriptor, which can be used as the unique identifier of an SPI device.
112  * When operating an SPI device, you need to specify a descriptor of the {@link SpiDevInfo} type, and obtain the
113  * handle of the SPI device by calling {@link SpiOpen}.
114  *
115  * @since 1.0
116  */
117 struct SpiDevInfo {
118     uint32_t busNum;       /**< SPI bus number */
119     uint32_t csNum;        /**< SPI device chip select (CS) */
120 };
121 
122 /**
123  * @brief Defines the custom SPI transfer message.
124  *
125  * @attention The specific SPI controller determines whether <b>speed</b>, <b>delayUs</b>,
126  * and <b>keepCs</b> are supported.
127  *
128  * @since 1.0
129  */
130 struct SpiMsg {
131     uint8_t *wbuf;       /**< Address of the write buffer */
132     uint8_t *rbuf;       /**< Address of the read buffer */
133     uint32_t len;        /**< Length of the read and write buffers. The read buffer and the write
134                           * buffer have the same length.
135                           */
136     uint32_t speed;      /**< Current message transfer speed */
137     uint16_t delayUs;    /**< Delay (in microseconds) before starting the next transfer.
138                           * The value <b>0</b> indicates there is no delay between transfers.
139                           */
140     uint8_t keepCs;    /**< Whether to keep CS active after current transfer has been
141                           * completed. <b>1</b> indicates to keeps CS; <b>0</b> indicates to switch off the CS.
142                           */
143 };
144 
145 /**
146  * @brief Defines the configuration of an SPI device.
147  *
148  * @attention The specific SPI controller determines which variables in this structure are supported.
149  *
150  * @since 1.0
151  */
152 struct SpiCfg {
153     uint32_t maxSpeedHz;     /**< Maximum clock frequency */
154     uint16_t mode;           /**< Input and output mode of SPI data | Description
155                               * -----------------| -----------------------
156                               * SPI_CLK_PHASE    | SPI clock phase.
157                               * SPI_CLK_POLARITY | SPI clock polarity.
158                               * SPI_MODE_3WIRE   | A single data line is used for both input and output.
159                               * SPI_MODE_LOOP    | SPI loopback mode.
160                               * SPI_MODE_LSBFE   | SPI data transfer order
161                               * SPI_MODE_NOCS    | There is only one SPI device, and no CS is required.
162                               * SPI_MODE_CS_HIGH | The CS level is high when an SPI device is selected.
163                               * SPI_MODE_READY   | The SPI device is set to low for pausing data transfer.
164                               */
165     uint8_t transferMode;    /**< Data transfer mode, as defined in {@link SpiTransferMode}. */
166     uint8_t bitsPerWord;     /**< Data transfer bit width */
167 };
168 
169 /**
170  * @brief Obtains the handle of an SPI device.
171  *
172  * @param info Indicates the pointer to the SPI device information.
173  *
174  * @return Returns the pointer to the handle of the SPI device if the operation is successful;
175  * returns <b>NULL</b> otherwise.
176  *
177  * @since 1.0
178  */
179 DevHandle SpiOpen(const struct SpiDevInfo *info);
180 
181 /**
182  * @brief Releases the handle of an SPI device.
183  *
184  * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}.
185  *
186  * @since 1.0
187  */
188 void SpiClose(DevHandle handle);
189 
190 /**
191  * @brief Launches a custom transfer to an SPI device.
192  *
193  * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}.
194  * @param msgs Indicates the pointer to the data to transfer.
195  * @param count Indicates the length of the message structure array.
196  *
197  * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
198  * @see SpiMsg
199  * @since 1.0
200  */
201 int32_t SpiTransfer(DevHandle handle, struct SpiMsg *msgs, uint32_t count);
202 
203 /**
204  * @brief Reads data of a specified length from an SPI device.
205  *
206  * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}.
207  * @param buf Indicates the pointer to the buffer for receiving the data.
208  * @param len Indicates the length of the data to read.
209  *
210  * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
211  *
212  * @since 1.0
213  */
214 int32_t SpiRead(DevHandle handle, uint8_t *buf, uint32_t len);
215 
216 /**
217  * @brief Writes data of a specified length to an SPI device.
218  *
219  * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}.
220  * @param buf Indicates the pointer to the data to write.
221  * @param len Indicates the length of the data to write.
222  *
223  * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
224  *
225  * @since 1.0
226  */
227 int32_t SpiWrite(DevHandle handle, uint8_t *buf, uint32_t len);
228 
229 /**
230  * @brief Sets configuration parameters for an SPI device.
231  *
232  * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}.
233  * @param cfg Indicates the pointer to the configuration parameters.
234  *
235  * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
236  *
237  * @since 1.0
238  */
239 int32_t SpiSetCfg(DevHandle handle, struct SpiCfg *cfg);
240 
241 /**
242  * @brief Obtains the configuration parameters of an SPI device.
243  *
244  * @param handle Indicates the pointer to the SPI device handle obtained via {@link SpiOpen}.
245  * @param cfg Indicates the pointer to the configuration parameters.
246  *
247  * @return Returns <b>0</b> if the operation is successful; returns a negative value otherwise.
248  *
249  * @since 1.0
250  */
251 int32_t SpiGetCfg(DevHandle handle, struct SpiCfg *cfg);
252 
253 /**
254  * @brief Enumerates SPI I/O commands.
255  *
256  * @since 1.0
257  */
258 enum SpiIoCmd {
259     SPI_IO_OPEN = 0,        /**< Open the SPI device. */
260     SPI_IO_CLOSE,           /**< Close the SPI device. */
261     SPI_IO_TRANSFER,        /**< Execute one or more SPI messages. */
262     SPI_IO_SET_CONFIG,      /**< Set the configurations. */
263     SPI_IO_GET_CONFIG,      /**< Get the configurations. */
264 };
265 
266 #ifdef __cplusplus
267 #if __cplusplus
268 }
269 #endif
270 #endif /* __cplusplus */
271 
272 #endif /* SPI_IF_H */
273 /** @} */
274