1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef FSL_DSPI_EDMA_H_
9 #define FSL_DSPI_EDMA_H_
10 
11 #include "fsl_dspi.h"
12 #include "fsl_edma.h"
13 /*!
14  * @addtogroup dspi_edma_driver
15  * @{
16  */
17 
18 /***********************************************************************************************************************
19  * Definitions
20  **********************************************************************************************************************/
21 
22 /*! @name Driver version */
23 /*! @{ */
24 /*! @brief DSPI EDMA driver version 2.2.6 */
25 #define FSL_DSPI_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 2, 6))
26 /*! @} */
27 
28 /*! @brief DSPI EDMA max transfer data size calculate
29  * @param base DSPI peripheral base address.
30  * @param width Transfer width
31  */
32 #define DSPI_EDMA_MAX_TRANSFER_SIZE(base, width)                                                    \
33     ((1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) ? ((width > 8U) ? 65534U : 32767U) : \
34                                                                  ((width > 8U) ? 1022U : 511U))
35 
36 /*!
37  * @brief Forward declaration of the DSPI eDMA master handle typedefs.
38  */
39 typedef struct _dspi_master_edma_handle dspi_master_edma_handle_t;
40 
41 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
42 /*!
43  * @brief Forward declaration of the DSPI eDMA slave handle typedefs.
44  */
45 typedef struct _dspi_slave_edma_handle dspi_slave_edma_handle_t;
46 #endif
47 
48 /*!
49  * @brief Completion callback function pointer type.
50  *
51  * @param base DSPI peripheral base address.
52  * @param handle A pointer to the handle for the DSPI master.
53  * @param status Success or error code describing whether the transfer completed.
54  * @param userData An arbitrary pointer-dataSized value passed from the application.
55  */
56 typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base,
57                                                      dspi_master_edma_handle_t *handle,
58                                                      status_t status,
59                                                      void *userData);
60 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
61 /*!
62  * @brief Completion callback function pointer type.
63  *
64  * @param base DSPI peripheral base address.
65  * @param handle A pointer to the handle for the DSPI slave.
66  * @param status Success or error code describing whether the transfer completed.
67  * @param userData An arbitrary pointer-dataSized value passed from the application.
68  */
69 typedef void (*dspi_slave_edma_transfer_callback_t)(SPI_Type *base,
70                                                     dspi_slave_edma_handle_t *handle,
71                                                     status_t status,
72                                                     void *userData);
73 #endif
74 
75 /*! @brief DSPI master eDMA transfer handle structure used for the transactional API. */
76 struct _dspi_master_edma_handle
77 {
78     uint32_t bitsPerFrame;         /*!< The desired number of bits per frame. */
79     volatile uint32_t command;     /*!< The desired data command. */
80     volatile uint32_t lastCommand; /*!< The desired last data command. */
81 
82     uint8_t fifoSize; /*!< FIFO dataSize. */
83 
84     volatile bool
85         isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal keeps active after the last frame transfer.*/
86 
87     uint8_t nbytes;         /*!< eDMA minor byte transfer count initially configured. */
88     volatile uint8_t state; /*!< DSPI transfer state, see @ref _dspi_transfer_state.*/
89 
90     const uint8_t *volatile txData; /*!< Send buffer. */
91     uint8_t *volatile rxData;                  /*!< Receive buffer. */
92     volatile size_t remainingSendByteCount;    /*!< A number of bytes remaining to send.*/
93     volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
94     size_t totalByteCount;                     /*!< A number of transfer bytes*/
95 
96     uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/
97     uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
98 
99     dspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */
100     void *userData;                                /*!< Callback user data. */
101 
102     edma_handle_t *edmaRxRegToRxDataHandle;        /*!<edma_handle_t handle point used for RxReg to RxData buff*/
103     edma_handle_t *edmaTxDataToIntermediaryHandle; /*!<edma_handle_t handle point used for TxData to Intermediary*/
104     edma_handle_t *edmaIntermediaryToTxRegHandle;  /*!<edma_handle_t handle point used for Intermediary to TxReg*/
105 
106     edma_tcd_t dspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/
107 };
108 
109 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
110 /*! @brief DSPI slave eDMA transfer handle structure used for the transactional API.*/
111 struct _dspi_slave_edma_handle
112 {
113     uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */
114 
115     const uint8_t *volatile txData;            /*!< Send buffer. */
116     uint8_t *volatile rxData;                  /*!< Receive buffer. */
117     volatile size_t remainingSendByteCount;    /*!< A number of bytes remaining to send.*/
118     volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
119     size_t totalByteCount;                     /*!< A number of transfer bytes*/
120 
121     uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/
122     uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
123     uint32_t txLastData;   /*!< Used if there is an extra byte when 16bits per frame for DMA purpose.*/
124 
125     uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
126 
127     volatile uint8_t state; /*!< DSPI transfer state.*/
128 
129     dspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */
130     void *userData;                               /*!< Callback user data. */
131 
132     edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
133     edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg*/
134 };
135 #endif
136 
137 /***********************************************************************************************************************
138  * API
139  **********************************************************************************************************************/
140 #if defined(__cplusplus)
141 extern "C" {
142 #endif /*_cplusplus*/
143 
144 /*! @name Transactional APIs
145  * @{
146  */
147 
148 /*!
149  * @brief Initializes the DSPI master eDMA handle.
150  *
151  * This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs.  Usually, for a
152  * specified DSPI instance, call this API once to get the initialized handle.
153  *
154  * @note DSPI eDMA has separated (RX and TX as two sources) or shared (RX  and TX are the same source) DMA request
155  * source.
156  * - For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
157  *   TX DMAMUX source for edmaIntermediaryToTxRegHandle.
158  * - For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
159  *
160  * @param base DSPI peripheral base address.
161  * @param handle DSPI handle pointer to @ref _dspi_master_edma_handle.
162  * @param callback DSPI callback.
163  * @param userData A callback function parameter.
164  * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
165  * @param edmaTxDataToIntermediaryHandle edmaTxDataToIntermediaryHandle pointer to edma_handle_t.
166  * @param edmaIntermediaryToTxRegHandle edmaIntermediaryToTxRegHandle pointer to edma_handle_t.
167  */
168 void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
169                                          dspi_master_edma_handle_t *handle,
170                                          dspi_master_edma_transfer_callback_t callback,
171                                          void *userData,
172                                          edma_handle_t *edmaRxRegToRxDataHandle,
173                                          edma_handle_t *edmaTxDataToIntermediaryHandle,
174                                          edma_handle_t *edmaIntermediaryToTxRegHandle);
175 
176 /*!
177  * @brief DSPI master transfer data using eDMA.
178  *
179  * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
180  * is transferred, the callback function is called.
181  *
182  * @note The max transfer size of each transfer depends on whether the instance's Tx/Rx shares the same DMA request. If
183  * <b>FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x)</b> is true, then the max transfer size is 32767 datawidth of
184  * data, otherwise is 511.
185  *
186  * @param base DSPI peripheral base address.
187  * @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state.
188  * @param transfer A pointer to the @ref dspi_transfer_t structure.
189  * @return status of status_t.
190  */
191 status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer);
192 
193 /*!
194  * @brief Transfers a block of data using a eDMA method.
195  *
196  * This function transfers data using eDNA, the transfer mechanism is half-duplex. This is a non-blocking function,
197  * which returns right away. When all data is transferred, the callback function is called.
198  *
199  * @param base DSPI base pointer
200  * @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state.
201  * @param xfer A pointer to the @ref dspi_half_duplex_transfer_t structure.
202  * @return status of status_t.
203  */
204 status_t DSPI_MasterHalfDuplexTransferEDMA(SPI_Type *base,
205                                            dspi_master_edma_handle_t *handle,
206                                            dspi_half_duplex_transfer_t *xfer);
207 
208 /*!
209  * @brief DSPI master aborts a transfer which is using eDMA.
210  *
211  * This function aborts a transfer which is using eDMA.
212  *
213  * @param base DSPI peripheral base address.
214  * @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state.
215  */
216 void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle);
217 
218 /*!
219  * @brief Gets the master eDMA transfer count.
220  *
221  * This function gets the master eDMA transfer count.
222  *
223  * @param base DSPI peripheral base address.
224  * @param handle A pointer to the @ref _dspi_master_edma_handle structure which stores the transfer state.
225  * @param count A number of bytes transferred by the non-blocking transaction.
226  * @return status of status_t.
227  */
228 status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, size_t *count);
229 
230 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
231 /*!
232  * @brief Initializes the DSPI slave eDMA handle.
233  *
234  * This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs.  Usually, for a
235  * specified DSPI instance, call this API once to get the initialized handle.
236  *
237  * @note DSPI eDMA has separated (RN and TX in 2 sources) or shared (RX  and TX are the same source) DMA request
238  * source.
239  * - For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
240  *   TX DMAMUX source for edmaTxDataToTxRegHandle.
241  * - For the shared DMA request source,  enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
242  *
243  * @param base DSPI peripheral base address.
244  * @param handle DSPI handle pointer to @ref _dspi_slave_edma_handle.
245  * @param callback DSPI callback.
246  * @param userData A callback function parameter.
247  * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
248  * @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
249  */
250 void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
251                                         dspi_slave_edma_handle_t *handle,
252                                         dspi_slave_edma_transfer_callback_t callback,
253                                         void *userData,
254                                         edma_handle_t *edmaRxRegToRxDataHandle,
255                                         edma_handle_t *edmaTxDataToTxRegHandle);
256 #endif
257 
258 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
259 /*!
260  * @brief DSPI slave transfer data using eDMA.
261  *
262  * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
263  * is transferred, the callback function is called.
264  * Note that the slave eDMA transfer doesn't support transfer_size is 1 when the bitsPerFrame is greater
265  * than eight.
266  *
267  * @note The max transfer size of each transfer depends on whether the instance's Tx/Rx shares the same DMA request. If
268  * <b>FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x)</b> is true, then the max transfer size is 32767 datawidth of
269  * data, otherwise is 511.
270  *
271  * @param base DSPI peripheral base address.
272  * @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state.
273  * @param transfer A pointer to the @ref dspi_transfer_t structure.
274  * @return status of status_t.
275  */
276 status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer);
277 #endif
278 
279 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
280 /*!
281  * @brief DSPI slave aborts a transfer which is using eDMA.
282  *
283  * This function aborts a transfer which is using eDMA.
284  *
285  * @param base DSPI peripheral base address.
286  * @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state.
287  */
288 void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle);
289 #endif
290 
291 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
292 /*!
293  * @brief Gets the slave eDMA transfer count.
294  *
295  * This function gets the slave eDMA transfer count.
296  *
297  * @param base DSPI peripheral base address.
298  * @param handle A pointer to the @ref _dspi_slave_edma_handle structure which stores the transfer state.
299  * @param count A number of bytes transferred so far by the non-blocking transaction.
300  * @return status of status_t.
301  */
302 status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count);
303 #endif
304 
305 /*!@}*/
306 
307 #if defined(__cplusplus)
308 }
309 #endif /*_cplusplus*/
310 /*!
311  *@}
312  */
313 
314 #endif /*FSL_DSPI_EDMA_H_*/
315