1 /* 2 * Copyright (C) 2017-2024 Alibaba Group Holding Limited 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 /****************************************************************************** 20 * @file drv/spi.h 21 * @brief Header File for SPI Driver 22 * @version V1.0 23 * @date 08. Apr 2020 24 * @model spi 25 ******************************************************************************/ 26 27 #ifndef _DRV_SPI_H_ 28 #define _DRV_SPI_H_ 29 30 #include <stdint.h> 31 #include <drv/common.h> 32 #include <drv/gpio.h> 33 #include <drv/dma.h> 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 /** 40 * \enum csi_spi_mode_t 41 * \brief Function mode of spi 42 */ 43 typedef enum { 44 SPI_MASTER, ///< SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps 45 SPI_SLAVE, ///< SPI Slave (Output on MISO, Input on MOSI) 46 } csi_spi_mode_t; 47 48 /** 49 * \enum csi_spi_frame_len_t 50 * \brief SPI data width (4bit ~ 16bit) 51 */ 52 typedef enum { 53 SPI_FRAME_LEN_4 = 4, 54 SPI_FRAME_LEN_5, 55 SPI_FRAME_LEN_6, 56 SPI_FRAME_LEN_7, 57 SPI_FRAME_LEN_8, 58 SPI_FRAME_LEN_9, 59 SPI_FRAME_LEN_10, 60 SPI_FRAME_LEN_11, 61 SPI_FRAME_LEN_12, 62 SPI_FRAME_LEN_13, 63 SPI_FRAME_LEN_14, 64 SPI_FRAME_LEN_15, 65 SPI_FRAME_LEN_16 66 } csi_spi_frame_len_t; 67 68 /** 69 * \enum csi_spi_format_t 70 * \brief Timing format of spi 71 */ 72 typedef enum { 73 SPI_FORMAT_CPOL0_CPHA0 = 0, ///< Clock Polarity 0, Clock Phase 0 74 SPI_FORMAT_CPOL0_CPHA1, ///< Clock Polarity 0, Clock Phase 1 75 SPI_FORMAT_CPOL1_CPHA0, ///< Clock Polarity 1, Clock Phase 0 76 SPI_FORMAT_CPOL1_CPHA1, ///< Clock Polarity 1, Clock Phase 1 77 } csi_spi_cp_format_t; 78 79 /** 80 * \enum csi_spi_event_t 81 * \brief Signaled event for user by driver 82 */ 83 typedef enum { 84 SPI_EVENT_SEND_COMPLETE, ///< Data Send completed. Occurs after call to csi_spi_send_async to indicate that all the data has been send over 85 SPI_EVENT_RECEIVE_COMPLETE, ///< Data Receive completed. Occurs after call to csi_spi_receive_async to indicate that all the data has been received 86 SPI_EVENT_SEND_RECEIVE_COMPLETE, ///< Data Send_receive completed. Occurs after call to csi_spi_send_receive_async to indicate that all the data has been send_received 87 SPI_EVENT_ERROR_OVERFLOW, ///< Data overflow: Receive overflow 88 SPI_EVENT_ERROR_UNDERFLOW, ///< Data underflow: Transmit underflow 89 SPI_EVENT_ERROR ///< Master Mode Fault (SS deactivated when Master).Occurs in master mode when Slave Select is deactivated and indicates Master Mode Fault 90 } csi_spi_event_t; 91 92 /** 93 * \struct csi_spi_t 94 * \brief Ctrl block of spi instance 95 */ 96 typedef struct csi_spi csi_spi_t; 97 struct csi_spi { 98 csi_dev_t dev; ///< Hw-device info 99 void (*callback)(csi_spi_t *spi, csi_spi_event_t event, void *arg); ///< User callback ,signaled by driver event 100 void *arg; ///< User private param ,passed to user callback 101 uint8_t *tx_data; ///< Output data buf 102 uint32_t tx_size; ///< Output data size specified by user 103 uint8_t *rx_data; ///< Input data buf 104 uint32_t rx_size; ///< Input data size specified by user 105 csi_error_t (*send)(csi_spi_t *spi, const void *data, uint32_t size); ///< The send_async func 106 csi_error_t (*receive)(csi_spi_t *spi, void *data, uint32_t size); ///< The receive_async func 107 csi_error_t (*send_receive)(csi_spi_t *spi, const void *data_out, void *data_in, uint32_t size); ///< The send_receive_async func 108 csi_state_t state; ///< Peripheral state 109 csi_dma_ch_t *tx_dma; 110 csi_dma_ch_t *rx_dma; 111 void *priv; 112 }; 113 114 /** 115 \brief Initialize SPI Interface 116 Initialize the resources needed for the SPI instance 117 \param[in] spi SPI handle 118 \param[in] idx SPI instance index 119 \return Error code 120 */ 121 csi_error_t csi_spi_init(csi_spi_t *spi, uint32_t idx); 122 123 /** 124 \brief De-initialize SPI Interface 125 stops Operation and releases the software resources used by the spi instance 126 \param[in] spi Handle 127 \return None 128 */ 129 void csi_spi_uninit(csi_spi_t *spi); 130 131 /** 132 \brief Attach the callback handler to SPI 133 \param[in] spi Operate handle 134 \param[in] callback Callback function 135 \param[in] arg User can define it by himself as callback's param 136 \return Error code 137 */ 138 csi_error_t csi_spi_attach_callback(csi_spi_t *spi, void *callback, void *arg); 139 140 /** 141 \brief Detach the callback handler 142 \param[in] spi Operate handle 143 \return None 144 */ 145 void csi_spi_detach_callback(csi_spi_t *spi); 146 147 /** 148 \brief Config spi mode (master or slave) 149 \param[in] spi SPI handle 150 \param[in] mode The mode of spi (master or slave) 151 \return Error code 152 */ 153 csi_error_t csi_spi_mode(csi_spi_t *spi, csi_spi_mode_t mode); 154 155 /** 156 \brief Config spi cp format 157 \param[in] spi SPI handle 158 \param[in] format SPI cp format 159 \return Error code 160 */ 161 csi_error_t csi_spi_cp_format(csi_spi_t *spi, csi_spi_cp_format_t format); 162 163 /** 164 \brief Config spi frame len 165 \param[in] spi SPI handle 166 \param[in] length SPI frame len 167 \return Error code 168 */ 169 csi_error_t csi_spi_frame_len(csi_spi_t *spi, csi_spi_frame_len_t length); 170 171 /** 172 \brief Config spi work frequence 173 \param[in] spi SPI handle 174 \param[in] baud SPI work baud 175 \return the actual config frequency 176 */ 177 uint32_t csi_spi_baud(csi_spi_t *spi, uint32_t baud); 178 179 /** 180 \brief Sending data to SPI transmitter,(received data is ignored) 181 blocking mode ,return unti all data has been sent or err happened 182 \param[in] spi Handle to operate 183 \param[in] data Pointer to buffer with data to send to SPI transmitter 184 \param[in] size Number of data to send(byte) 185 \param[in] timeout Unit in mini-second 186 \return If send successful, this function shall return the num of data witch is sent successful 187 otherwise, the function shall return Error code 188 */ 189 int32_t csi_spi_send(csi_spi_t *spi, const void *data, uint32_t size, uint32_t timeout); 190 191 /** 192 \brief Sending data to SPI transmitter,(received data is ignored) 193 non-blocking mode,transfer done event will be signaled by driver 194 \param[in] spi Handle to operate 195 \param[in] data Pointer to buffer with data to send to SPI transmitter 196 \param[in] size Number of data items to send(byte) 197 \return Error code 198 */ 199 csi_error_t csi_spi_send_async(csi_spi_t *spi, const void *data, uint32_t size); 200 201 /** 202 \brief Receiving data from SPI receiver 203 blocking mode, return untill curtain data items are readed 204 \param[in] spi Handle to operate 205 \param[out] data Pointer to buffer for data to receive from SPI receiver 206 \param[in] size Number of data items to receive(byte) 207 \param[in] timeout Unit in mini-second 208 \return If receive successful, this function shall return the num of data witch is received successful 209 otherwise, the function shall return Error code 210 */ 211 int32_t csi_spi_receive(csi_spi_t *spi, void *data, uint32_t size, uint32_t timeout); 212 213 /** 214 \brief Receiving data from SPI receiver 215 not-blocking mode, event will be signaled when receive done or err happend 216 \param[in] spi Handle to operate 217 \param[out] data Pointer to buffer for data to receive from SPI receiver 218 \param[in] size Number of data items to receive(byte) 219 \return Error code 220 */ 221 csi_error_t csi_spi_receive_async(csi_spi_t *spi, void *data, uint32_t size); 222 223 /** 224 \brief Dulplex,sending and receiving data at the same time 225 \ref csi_spi_event_t is signaled when operation completes or error happens 226 \ref csi_spi_get_state can get operation status 227 blocking mode, this function returns after operation completes or error happens 228 \param[in] spi SPI handle to operate 229 \param[in] data_out Pointer to buffer with data to send to SPI transmitter 230 \param[out] data_in Pointer to buffer for data to receive from SPI receiver 231 \param[in] size Data size(byte) 232 \return If transfer successful, this function shall return the num of data witch is transfer successful, 233 otherwise, the function shall return Error code 234 */ 235 int32_t csi_spi_send_receive(csi_spi_t *spi, const void *data_out, void *data_in, uint32_t size, uint32_t timeout); 236 237 /** 238 \brief Transmit first then receive ,receive will begin after transmit is done 239 if non-blocking mode, this function only starts the transfer, 240 \ref csi_spi_event_t is signaled when operation completes or error happens 241 \ref csi_spi_get_state can get operation status 242 \param[in] spi SPI handle to operate 243 \param[in] data_out Pointer to buffer with data to send to SPI transmitter 244 \param[out] data_in Pointer to buffer for data to receive from SPI receiver 245 \param[in] size Data size(byte) 246 \return Error code 247 */ 248 csi_error_t csi_spi_send_receive_async(csi_spi_t *spi, const void *data_out, void *data_in, uint32_t size); 249 250 /* 251 \brief Set slave select num. Only valid for master 252 \param[in] handle SPI handle to operate 253 \param[in] slave_num SPI slave num 254 \return None 255 */ 256 void csi_spi_select_slave(csi_spi_t *spi, uint32_t slave_num); 257 258 /** 259 \brief Link DMA channel to spi device 260 \param[in] spi SPI handle to operate 261 \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel 262 \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel 263 \return Error code 264 */ 265 csi_error_t csi_spi_link_dma(csi_spi_t *spi, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); 266 267 /** 268 \brief Get the state of spi device 269 \param[in] spi SPI handle to operate 270 \param[out] state The state of spi device 271 \return Error code 272 */ 273 csi_error_t csi_spi_get_state(csi_spi_t *spi, csi_state_t *state); 274 275 /** 276 \brief Enable spi power manage 277 \param[in] spi SPI handle to operate 278 \return Error code 279 */ 280 csi_error_t csi_spi_enable_pm(csi_spi_t *spi); 281 282 /** 283 \brief Disable spi power manage 284 \param[in] spi SPI handle to operate 285 \return Error code 286 */ 287 void csi_spi_disable_pm(csi_spi_t *spi); 288 289 #ifdef __cplusplus 290 } 291 #endif 292 293 #endif /* _DRV_SPI_H_ */ 294