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