1 /** 2 ********************************************************************************* 3 * 4 * @file ald_spi.c 5 * @brief Header file of SPI module driver. 6 * 7 * @version V1.0 8 * @date 13 Nov 2019 9 * @author AE Team 10 * @note 11 * Change Logs: 12 * Date Author Notes 13 * 13 Nov 2019 AE Team The first version 14 * 15 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. 16 * 17 * SPDX-License-Identifier: Apache-2.0 18 * 19 * Licensed under the Apache License, Version 2.0 (the License); you may 20 * not use this file except in compliance with the License. 21 * You may obtain a copy of the License at 22 * 23 * www.apache.org/licenses/LICENSE-2.0 24 * 25 * Unless required by applicable law or agreed to in writing, software 26 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 27 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 * See the License for the specific language governing permissions and 29 * limitations under the License. 30 ********************************************************************************** 31 */ 32 33 #ifndef __ALD_SPI_H__ 34 #define __ALD_SPI_H__ 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #include "utils.h" 41 #include "ald_dma.h" 42 43 /** @addtogroup ES32FXXX_ALD 44 * @{ 45 */ 46 47 /** @addtogroup SPI 48 * @{ 49 */ 50 51 /** @defgroup SPI_Public_Types SPI Public Types 52 * @{ 53 */ 54 55 /** 56 * @brief clock phase 57 */ 58 typedef enum { 59 SPI_CPHA_FIRST = 0U, /**< Transiting data in the first edge */ 60 SPI_CPHA_SECOND = 1U, /**< Transiting data in the seconde edge */ 61 } spi_cpha_t; 62 63 /** 64 * @brief clock polarity 65 */ 66 typedef enum { 67 SPI_CPOL_LOW = 0U, /**< Polarity hold low when spi-bus is idle */ 68 SPI_CPOL_HIGH = 1U, /**< Polarity hold high when spi-bus is idle */ 69 } spi_cpol_t; 70 71 /** 72 * @brief master selection 73 */ 74 typedef enum { 75 SPI_MODE_SLAVER = 0U, /**< Slave mode */ 76 SPI_MODE_MASTER = 1U, /**< Master mode */ 77 } spi_mode_t; 78 79 /** 80 * @brief baud rate control 81 */ 82 typedef enum { 83 SPI_BAUD_2 = 0U, /**< fpclk/2 */ 84 SPI_BAUD_4 = 1U, /**< fpclk/4 */ 85 SPI_BAUD_8 = 2U, /**< fpclk/8 */ 86 SPI_BAUD_16 = 3U, /**< fpclk/16 */ 87 SPI_BAUD_32 = 4U, /**< fpclk/32 */ 88 SPI_BAUD_64 = 5U, /**< fpclk/64 */ 89 SPI_BAUD_128 = 6U, /**< fpclk/128 */ 90 SPI_BAUD_256 = 7U, /**< fpclk/256 */ 91 } spi_baud_t; 92 93 /** 94 * @brief frame format 95 */ 96 typedef enum { 97 SPI_FIRSTBIT_MSB = 0U, /**< MSB transmitted first */ 98 SPI_FIRSTBIT_LSB = 1U, /**< LSB transmitted first */ 99 } spi_firstbit_t; 100 101 /** 102 * @brief data frame format 103 */ 104 typedef enum { 105 SPI_DATA_SIZE_8 = 0U, /**< 8-bit data frame format is selected for transmission/reception */ 106 SPI_DATA_SIZE_16 = 1U, /**< 16-bit data frame format is selected for transmission/reception */ 107 } spi_datasize_t; 108 109 /** 110 * @brief SPI error status 111 */ 112 typedef enum { 113 SPI_ERROR_NONE = 0U, /**< none */ 114 SPI_ERROR_MODF = 1U, /**< mode fault */ 115 SPI_ERROR_CRC = 2U, /**< crc error */ 116 SPI_ERROR_FRE = 4U, /**< frame error */ 117 SPI_ERROR_RXOV = 8U, /**< receive over error */ 118 SPI_ERROR_TXOV = 0x10U, /**< dma error */ 119 SPI_ERROR_FLAG = 0x20U, /**< interrupt flag error */ 120 } spi_error_t; 121 122 /** 123 * @brief interrupt control 124 */ 125 typedef enum { 126 SPI_IT_TXE = (1U << 0), /**< Transmit fifo empty interrupt */ 127 SPI_IT_TXOV = (1U << 2), /**< Transmit fifo overflow interrupt */ 128 SPI_IT_TXUD = (1U << 3), /**< Transmit fifo underflow interrupt */ 129 SPI_IT_TXTH = (1U << 4), /**< Transmit fifo under threshold interrupt */ 130 SPI_IT_RXF = (1U << 9), /**< Receive fifo full interrupt */ 131 SPI_IT_RXOV = (1U << 10), /**< Receive fifo overflow interrupt */ 132 SPI_IT_RXUD = (1U << 11), /**< Receive fifo underflow interrupt */ 133 SPI_IT_RXTH = (1U << 12), /**< Receive fifo over threshold interrupt */ 134 SPI_IT_CRCERR = (1U << 16), /**< Crc error interrupt */ 135 SPI_IT_MODF = (1U << 17), /**< Mode error interrupt */ 136 SPI_IT_FRE = (1U << 18), /**< Frame error interrupt */ 137 } spi_it_t; 138 139 /** 140 * @brief interrupt flag 141 */ 142 typedef enum { 143 SPI_IF_TXE = (1U << 0), /**< Transmit fifo empty interrupt flag */ 144 SPI_IF_TXOV = (1U << 2), /**< Transmit fifo overflow interrupt flag */ 145 SPI_IF_TXUD = (1U << 3), /**< Transmit fifo underflow interrupt flag */ 146 SPI_IF_TXTH = (1U << 4), /**< Transmit fifo under threshold interrupt flag */ 147 SPI_IF_RXF = (1U << 9), /**< Receive fifo full interrupt flag */ 148 SPI_IF_RXOV = (1U << 10), /**< Receive fifo overflow interrupt flag */ 149 SPI_IF_RXUD = (1U << 11), /**< Receive fifo underflow interrupt flag */ 150 SPI_IF_RXTH = (1U << 12), /**< Receive fifo over threshold interrupt flag */ 151 SPI_IF_CRCERR = (1U << 16), /**< Crc error interrupt flag */ 152 SPI_IF_MODF = (1U << 17), /**< Mode error interrupt flag */ 153 SPI_IF_FRE = (1U << 18), /**< Frame error interrupt flag */ 154 } spi_flag_t; 155 156 /** 157 * @brief SPI state structures definition 158 */ 159 typedef enum { 160 SPI_STATE_RESET = 0x00U, /**< Peripheral is not initialized */ 161 SPI_STATE_READY = 0x01U, /**< Peripheral Initialized and ready for use */ 162 SPI_STATE_BUSY = 0x02U, /**< an internal process is ongoing */ 163 SPI_STATE_BUSY_TX = 0x11U, /**< transmit is ongoing */ 164 SPI_STATE_BUSY_RX = 0x21U, /**< receive is ongoing */ 165 SPI_STATE_BUSY_TX_RX = 0x31U, /**< transmit and receive are ongoing */ 166 SPI_STATE_TIMEOUT = 0x03U, /**< Timeout state */ 167 SPI_STATE_ERROR = 0x04U, /**< Error */ 168 } spi_state_t; 169 170 171 /** 172 * @brief SPI direction definition 173 */ 174 typedef enum { 175 SPI_DIRECTION_2LINES = 0U, /**< 2 lines */ 176 SPI_DIRECTION_2LINES_RXONLY = 1U, /**< 2 lines only rx */ 177 SPI_DIRECTION_1LINE = 2U, /**< 1 line */ 178 SPI_DIRECTION_1LINE_RX = 3U, /**< 1 line only rx */ 179 } spi_direction_t; 180 181 /** 182 * @brief SPI dma request definition 183 */ 184 typedef enum { 185 SPI_DMA_REQ_TX = 0U, /**< TX dma request */ 186 SPI_DMA_REQ_RX = 1U, /**< RX dma request */ 187 } spi_dma_req_t; 188 189 /** 190 * @brief SPI crc length definition 191 */ 192 typedef enum { 193 SPI_FRAME_MOTOROLA = 0U, /**< SPI motorola mode */ 194 SPI_FRAME_TI = 1U, /**< SPI TI mode */ 195 } spi_frame_t; 196 197 /** 198 * @brief SPI status definition 199 */ 200 typedef enum { 201 SPI_STATUS_TXE = (1U << 0), /**< Transmit fifo empty status */ 202 SPI_STATUS_TXF = (1U << 1), /**< Transmit fifo full status */ 203 SPI_STATUS_TXOV = (1U << 2), /**< Transmit fifo overflow status */ 204 SPI_STATUS_TXUD = (1U << 3), /**< Transmit fifo underflow status */ 205 SPI_STATUS_TXTH = (1U << 4), /**< Transmit fifo under threshold status */ 206 SPI_STATUS_RXE = (1U << 8), /**< Receive fifo empty status */ 207 SPI_STATUS_RXF = (1U << 9), /**< Receive fifo full status */ 208 SPI_STATUS_RXOV = (1U << 10), /**< Receive fifo overflow status */ 209 SPI_STATUS_RXUD = (1U << 11), /**< Receive fifo underflow status */ 210 SPI_STATUS_RXTH = (1U << 12), /**< Receive fifo under threshold status */ 211 SPI_STATUS_BUSY = (1U << 15), /**< BUSY status */ 212 } spi_status_t; 213 214 /** 215 * @brief SPI TXE/RXNE status definition 216 */ 217 typedef enum { 218 SPI_SR_TXE = 0U, /**< SR.TXE set */ 219 SPI_SR_RXNE = 1U, /**< SR.RXTH set */ 220 SPI_SR_TXE_RXNE = 2U, /**< SR.TXE and SR.RXNE set */ 221 } spi_sr_status_t; 222 223 224 /** 225 * @brief SPI init structure definition 226 */ 227 typedef struct { 228 spi_mode_t mode; /**< SPI mode */ 229 spi_direction_t dir; /**< SPI direction */ 230 spi_datasize_t data_size; /**< SPI data size */ 231 spi_baud_t baud; /**< SPI baudrate prescaler */ 232 spi_cpha_t phase; /**< SPI clock phase */ 233 spi_cpol_t polarity; /**< SPI clock polarity */ 234 spi_firstbit_t first_bit; /**< SPI first bit */ 235 type_func_t ss_en; /**< SPI ssm enable or disable */ 236 type_func_t crc_calc; /**< SPI crc calculation */ 237 spi_frame_t frame; /**< SPI frame format */ 238 uint16_t crc_poly; /**< SPI crc polynomial */ 239 } spi_init_t; 240 241 /** 242 * @brief SPI handle structure definition 243 */ 244 typedef struct spi_handle_s { 245 SPI_I2S_TypeDef *perh; /**< SPI registers base address */ 246 spi_init_t init; /**< SPI communication parameters */ 247 uint8_t *tx_buf; /**< Pointer to SPI Tx transfer buffer */ 248 uint16_t tx_size; /**< SPI Tx transfer size */ 249 uint16_t tx_count; /**< SPI Tx transfer counter */ 250 uint8_t *rx_buf; /**< Pointer to SPI Rx transfer buffer */ 251 uint16_t rx_size; /**< SPI Rx Transfer size */ 252 uint16_t rx_count; /**< SPI Rx Transfer Counter */ 253 254 dma_handle_t hdmatx; /**< SPI Tx DMA handle parameters */ 255 dma_handle_t hdmarx; /**< SPI Rx DMA handle parameters */ 256 257 lock_state_t lock; /**< Locking object */ 258 spi_state_t state; /**< SPI communication state */ 259 uint32_t err_code; /**< SPI error code */ 260 261 void (*tx_cplt_cbk)(struct spi_handle_s *arg); /**< Tx completed callback */ 262 void (*rx_cplt_cbk)(struct spi_handle_s *arg); /**< Rx completed callback */ 263 void (*tx_rx_cplt_cbk)(struct spi_handle_s *arg); /**< Tx & Rx completed callback */ 264 void (*err_cbk)(struct spi_handle_s *arg); /**< error callback */ 265 } spi_handle_t; 266 /** 267 * @} 268 */ 269 270 /** @defgroup SPI_Public_Macros SPI Public Macros 271 * @{ 272 */ 273 #define SPI_RESET_HANDLE_STATE(x) ((x)->state = SPI_STATE_RESET) 274 #define SPI_ENABLE(x) ((x)->perh->CON1 |= (1 << SPI_CON1_SPIEN_POS)) 275 #define SPI_DISABLE(x) ((x)->perh->CON1 &= ~(1 << SPI_CON1_SPIEN_POS)) 276 #define SPI_CRC_RESET(x) \ 277 do { \ 278 CLEAR_BIT((x)->perh->CON1, SPI_CON1_CRCEN_MSK); \ 279 SET_BIT((x)->perh->CON1, SPI_CON1_CRCEN_MSK); \ 280 } while (0) 281 #define SPI_CRCNEXT_ENABLE(x) (SET_BIT((x)->perh->CON1, SPI_CON1_NXTCRC_MSK)) 282 #define SPI_CRCNEXT_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_NXTCRC_MSK)) 283 #define SPI_RXONLY_ENABLE(x) (SET_BIT((x)->perh->CON1, SPI_CON1_RXO_MSK)) 284 #define SPI_RXONLY_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_RXO_MSK)) 285 #define SPI_1LINE_TX(x) (SET_BIT((x)->perh->CON1, SPI_CON1_BIDOEN_MSK)) 286 #define SPI_1LINE_RX(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_BIDOEN_MSK)) 287 #define SPI_SSI_HIGH(x) (SET_BIT((x)->perh->CON1, SPI_CON1_SSOUT_MSK)) 288 #define SPI_SSI_LOW(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_SSOUT_MSK)) 289 #define SPI_SSOE_ENABLE(x) (SET_BIT((x)->perh->CON2, SPI_CON2_NSSOE_MSK)) 290 #define SPI_SSOE_DISABLE(x) (CLEAR_BIT((x)->perh->CON2, SPI_CON2_NSSOE_MSK)) 291 /** 292 * @} 293 */ 294 295 /** @defgroup SPI_Private_Macros SPI Private Macros 296 * @{ 297 */ 298 #define IS_SPI(x) (((x) == SPI0) || \ 299 ((x) == SPI1) || \ 300 ((x) == SPI2)) 301 #define IS_SPI_CPHA(x) (((x) == SPI_CPHA_FIRST) || \ 302 ((x) == SPI_CPHA_SECOND)) 303 #define IS_SPI_CPOL(x) (((x) == SPI_CPOL_LOW) || \ 304 ((x) == SPI_CPOL_HIGH)) 305 #define IS_SPI_MODE(x) (((x) == SPI_MODE_SLAVER) || \ 306 ((x) == SPI_MODE_MASTER)) 307 #define IS_SPI_FIRBIT(x) (((x) == SPI_FIRSTBIT_MSB) || \ 308 ((x) == SPI_FIRSTBIT_LSB)) 309 #define IS_SPI_BAUD(x) (((x) == SPI_BAUD_2) || \ 310 ((x) == SPI_BAUD_4) || \ 311 ((x) == SPI_BAUD_8) || \ 312 ((x) == SPI_BAUD_16) || \ 313 ((x) == SPI_BAUD_32) || \ 314 ((x) == SPI_BAUD_64) || \ 315 ((x) == SPI_BAUD_128) || \ 316 ((x) == SPI_BAUD_256)) 317 #define IS_SPI_DATASIZE(x) (((x) == SPI_DATA_SIZE_8) || \ 318 ((x) == SPI_DATA_SIZE_16)) 319 #define IS_SPI_BIDOE(x) (((x) == SPI_BID_RX) || \ 320 ((x) == SPI_BID_TX)) 321 #define IS_SPI_BIDMODE(x) (((x) == SPI_BIDMODE_DUAL) || \ 322 ((x) == SPI_BIDMODE_SOLE)) 323 #define IS_SPI_DIRECTION(x) (((x) == SPI_DIRECTION_2LINES) || \ 324 ((x) == SPI_DIRECTION_2LINES_RXONLY) || \ 325 ((x) == SPI_DIRECTION_1LINE) || \ 326 ((x) == SPI_DIRECTION_1LINE_RX)) 327 #define IS_SPI_DMA_REQ(x) (((x) == SPI_DMA_REQ_TX) || \ 328 ((x) == SPI_DMA_REQ_RX)) 329 #define IS_SPI_STATUS(x) (((x) == SPI_STATUS_TXE) || \ 330 ((x) == SPI_STATUS_TXF) || \ 331 ((x) == SPI_STATUS_TXOV) || \ 332 ((x) == SPI_STATUS_TXUD) || \ 333 ((x) == SPI_STATUS_TXTH) || \ 334 ((x) == SPI_STATUS_RXE) || \ 335 ((x) == SPI_STATUS_RXF) || \ 336 ((x) == SPI_STATUS_RXOV) || \ 337 ((x) == SPI_STATUS_RXUD) || \ 338 ((x) == SPI_STATUS_RXTH) || \ 339 ((x) == SPI_STATUS_BUSY)) 340 #define IS_SPI_IT(x) (((x) == SPI_IT_TXE) || \ 341 ((x) == SPI_IT_TXOV) || \ 342 ((x) == SPI_IT_TXUD) || \ 343 ((x) == SPI_IT_TXTH) || \ 344 ((x) == SPI_IT_RXF) || \ 345 ((x) == SPI_IT_RXOV) || \ 346 ((x) == SPI_IT_RXUD) || \ 347 ((x) == SPI_IT_RXTH) || \ 348 ((x) == SPI_IT_CRCERR) || \ 349 ((x) == SPI_IT_MODF) || \ 350 ((x) == SPI_IT_FRE)) 351 #define IS_SPI_IF(x) (((x) == SPI_IF_TXE) || \ 352 ((x) == SPI_IF_TXOV) || \ 353 ((x) == SPI_IF_TXUD) || \ 354 ((x) == SPI_IF_TXTH) || \ 355 ((x) == SPI_IF_RXF) || \ 356 ((x) == SPI_IF_RXOV) || \ 357 ((x) == SPI_IF_RXUD) || \ 358 ((x) == SPI_IF_RXTH) || \ 359 ((x) == SPI_IF_CRCERR) || \ 360 ((x) == SPI_IF_MODF) || \ 361 ((x) == SPI_IF_FRE)) 362 #define IS_SPI_FRAME(x) (((x) == SPI_FRAME_MOTOROLA) || \ 363 ((x) == SPI_FRAME_TI) ) 364 /** 365 * @} 366 */ 367 368 /** @addtogroup SPI_Public_Functions 369 * @{ 370 */ 371 372 /** @addtogroup SPI_Public_Functions_Group1 373 * @{ 374 */ 375 376 ald_status_t ald_spi_init(spi_handle_t *hperh); 377 void ald_spi_reset(spi_handle_t *hperh); 378 /** 379 * @} 380 */ 381 /** @addtogroup SPI_Public_Functions_Group2 382 * @{ 383 */ 384 int32_t ald_spi_send_byte_fast(spi_handle_t *hperh, uint8_t data); 385 int32_t ald_spi_send_byte_fast_1line(spi_handle_t *hperh, uint8_t data); 386 uint8_t ald_spi_recv_byte_fast(spi_handle_t *hperh, int *status); 387 ald_status_t ald_spi_send_bytes_fast(spi_handle_t *hperh, uint8_t *buf, uint32_t size, uint32_t timeout); 388 ald_status_t ald_spi_master_recv_bytes_fast(spi_handle_t *hperh, uint8_t *buf, uint32_t size); 389 ald_status_t ald_spi_slave_recv_bytes_fast(spi_handle_t *hperh, uint8_t *buf, uint32_t size, uint32_t timeout); 390 ald_status_t ald_spi_send_dbytes_fast(spi_handle_t *hperh, uint8_t *buf, uint32_t size, uint32_t timeout); 391 ald_status_t ald_spi_master_recv_dbytes_fast(spi_handle_t *hperh, uint8_t *buf, uint32_t size); 392 ald_status_t ald_spi_slave_recv_dbytes_fast(spi_handle_t *hperh, uint8_t *buf, uint32_t size, uint32_t timeout); 393 /** 394 * @} 395 */ 396 /** @addtogroup SPI_Public_Functions_Group3 397 * @{ 398 */ 399 ald_status_t ald_spi_send(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); 400 ald_status_t ald_spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); 401 ald_status_t ald_spi_send_recv(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout); 402 ald_status_t ald_spi_send_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size); 403 ald_status_t ald_spi_recv_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size); 404 ald_status_t ald_spi_send_recv_by_it(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size); 405 406 ald_status_t ald_spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); 407 ald_status_t ald_spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); 408 ald_status_t ald_spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel); 409 ald_status_t ald_spi_dma_pause(spi_handle_t *hperh); 410 ald_status_t ald_spi_dma_resume(spi_handle_t *hperh); 411 ald_status_t ald_spi_dma_stop(spi_handle_t *hperh); 412 413 /** 414 * @} 415 */ 416 /** @addtogroup SPI_Public_Functions_Group4 417 * @{ 418 */ 419 void ald_spi_irq_handler(spi_handle_t *hperh); 420 void ald_spi_interrupt_config(spi_handle_t *hperh, spi_it_t it, type_func_t state); 421 void ald_spi_speed_config(spi_handle_t *hperh, spi_baud_t speed); 422 void ald_spi_dma_req_config(spi_handle_t *hperh, spi_dma_req_t req, type_func_t state); 423 it_status_t ald_spi_get_it_status(spi_handle_t *hperh, spi_it_t it); 424 flag_status_t spi_get_status(spi_handle_t *hperh, spi_status_t status); 425 flag_status_t ald_spi_get_flag_status(spi_handle_t *hperh, spi_flag_t flag); 426 void ald_spi_clear_flag_status(spi_handle_t *hperh, spi_flag_t flag); 427 /** 428 * @} 429 */ 430 /** @addtogroup SPI_Public_Functions_Group5 431 * @{ 432 */ 433 spi_state_t ald_spi_get_state(spi_handle_t *hperh); 434 uint32_t ald_spi_get_error(spi_handle_t *hperh); 435 /** 436 * @} 437 */ 438 /** 439 * @} 440 */ 441 /** 442 * @} 443 */ 444 /** 445 * @} 446 */ 447 #ifdef __cplusplus 448 } 449 #endif 450 #endif 451