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