1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef _FSL_LPSPI_EDMA_H_
9 #define _FSL_LPSPI_EDMA_H_
10 
11 #include "fsl_lpspi.h"
12 #include "fsl_edma.h"
13 
14 /*!
15  * @addtogroup lpspi_edma_driver
16  * @{
17  */
18 
19 /***********************************************************************************************************************
20  * Definitions
21  **********************************************************************************************************************/
22 
23 /*!
24 * @brief Forward declaration of the _lpspi_master_edma_handle typedefs.
25 */
26 typedef struct _lpspi_master_edma_handle lpspi_master_edma_handle_t;
27 
28 /*!
29 * @brief Forward declaration of the _lpspi_slave_edma_handle typedefs.
30 */
31 typedef struct _lpspi_slave_edma_handle lpspi_slave_edma_handle_t;
32 
33 /*!
34  * @brief Completion callback function pointer type.
35  *
36  * @param base LPSPI peripheral base address.
37  * @param handle Pointer to the handle for the LPSPI master.
38  * @param status Success or error code describing whether the transfer completed.
39  * @param userData Arbitrary pointer-dataSized value passed from the application.
40  */
41 typedef void (*lpspi_master_edma_transfer_callback_t)(LPSPI_Type *base,
42                                                       lpspi_master_edma_handle_t *handle,
43                                                       status_t status,
44                                                       void *userData);
45 /*!
46  * @brief Completion callback function pointer type.
47  *
48  * @param base LPSPI peripheral base address.
49  * @param handle Pointer to the handle for the LPSPI slave.
50  * @param status Success or error code describing whether the transfer completed.
51  * @param userData Arbitrary pointer-dataSized value passed from the application.
52  */
53 typedef void (*lpspi_slave_edma_transfer_callback_t)(LPSPI_Type *base,
54                                                      lpspi_slave_edma_handle_t *handle,
55                                                      status_t status,
56                                                      void *userData);
57 
58 /*! @brief LPSPI master eDMA transfer handle structure used for transactional API. */
59 struct _lpspi_master_edma_handle
60 {
61     volatile bool isPcsContinuous; /*!< Is PCS continuous in transfer. */
62 
63     volatile bool isByteSwap; /*!< A flag that whether should byte swap. */
64 
65     volatile uint8_t fifoSize; /*!< FIFO dataSize. */
66 
67     volatile uint8_t rxWatermark; /*!< Rx watermark. */
68 
69     volatile uint8_t bytesEachWrite; /*!< Bytes for each write TDR . */
70     volatile uint8_t bytesEachRead;  /*!< Bytes for each read RDR . */
71 
72     volatile uint8_t bytesLastRead;       /*!< Bytes for last read RDR . */
73     volatile uint8_t isThereExtraRxBytes; /*!< Is there extra RX byte. */
74 
75     uint8_t *volatile txData;             /*!< Send buffer. */
76     uint8_t *volatile rxData;             /*!< Receive buffer. */
77     volatile size_t txRemainingByteCount; /*!< Number of bytes remaining to send.*/
78     volatile size_t rxRemainingByteCount; /*!< Number of bytes remaining to receive.*/
79 
80     volatile uint32_t writeRegRemainingTimes; /*!< Write TDR register remaining times. */
81     volatile uint32_t readRegRemainingTimes;  /*!< Read RDR register remaining times. */
82 
83     uint32_t totalByteCount; /*!< Number of transfer bytes*/
84 
85     uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
86     uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/
87 
88     uint32_t transmitCommand; /*!< Used to write TCR for DMA purpose.*/
89 
90     volatile uint8_t state; /*!< LPSPI transfer state , _lpspi_transfer_state.*/
91 
92     uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
93 
94     lpspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */
95     void *userData;                                 /*!< Callback user data. */
96 
97     edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
98     edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg buff*/
99 
100     edma_tcd_t lpspiSoftwareTCD[3]; /*!<SoftwareTCD , internal used*/
101 };
102 
103 /*! @brief LPSPI slave eDMA transfer handle structure used for transactional API.*/
104 struct _lpspi_slave_edma_handle
105 {
106     volatile bool isByteSwap; /*!< A flag that whether should byte swap. */
107 
108     volatile uint8_t fifoSize; /*!< FIFO dataSize. */
109 
110     volatile uint8_t rxWatermark; /*!< Rx watermark. */
111 
112     volatile uint8_t bytesEachWrite; /*!< Bytes for each write TDR . */
113     volatile uint8_t bytesEachRead;  /*!< Bytes for each read RDR . */
114 
115     volatile uint8_t bytesLastRead;       /*!< Bytes for last read RDR . */
116     volatile uint8_t isThereExtraRxBytes; /*!< Is there extra RX byte. */
117 
118     uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
119 
120     uint8_t *volatile txData;             /*!< Send buffer. */
121     uint8_t *volatile rxData;             /*!< Receive buffer. */
122     volatile size_t txRemainingByteCount; /*!< Number of bytes remaining to send.*/
123     volatile size_t rxRemainingByteCount; /*!< Number of bytes remaining to receive.*/
124 
125     volatile uint32_t writeRegRemainingTimes; /*!< Write TDR register remaining times . */
126     volatile uint32_t readRegRemainingTimes;  /*!< Read RDR register remaining times . */
127 
128     uint32_t totalByteCount; /*!< Number of transfer bytes*/
129 
130     uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
131     uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/
132 
133     volatile uint8_t state; /*!< LPSPI transfer state.*/
134 
135     uint32_t errorCount; /*!< Error count for slave transfer.*/
136 
137     lpspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */
138     void *userData;                                /*!< Callback user data. */
139 
140     edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
141     edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg*/
142 
143     edma_tcd_t lpspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/
144 };
145 
146 /***********************************************************************************************************************
147  * API
148  **********************************************************************************************************************/
149 #if defined(__cplusplus)
150 extern "C" {
151 #endif /*_cplusplus*/
152 
153 /*Transactional APIs*/
154 
155 /*!
156  * @brief Initializes the LPSPI master eDMA handle.
157  *
158  * This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs.  Usually, for a
159  * specified LPSPI instance, call this API once to get the initialized handle.
160  *
161  * Note that the LPSPI eDMA has a separated (Rx and Rx as two sources) or shared (Rx  and Tx are the same source) DMA
162  * request source.
163  * (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and
164  * Tx DMAMUX source for edmaIntermediaryToTxRegHandle.
165  * (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle.
166  *
167  * @param base LPSPI peripheral base address.
168  * @param handle LPSPI handle pointer to lpspi_master_edma_handle_t.
169  * @param callback LPSPI callback.
170  * @param userData callback function parameter.
171  * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
172  * @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
173  */
174 void LPSPI_MasterTransferCreateHandleEDMA(LPSPI_Type *base,
175                                           lpspi_master_edma_handle_t *handle,
176                                           lpspi_master_edma_transfer_callback_t callback,
177                                           void *userData,
178                                           edma_handle_t *edmaRxRegToRxDataHandle,
179                                           edma_handle_t *edmaTxDataToTxRegHandle);
180 
181 /*!
182  * @brief LPSPI master transfer data using eDMA.
183  *
184  * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
185  * is transferred, the callback function is called.
186  *
187  * Note:
188  * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
189  * For bytesPerFrame greater than 4:
190  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
191  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
192  *
193  * @param base LPSPI peripheral base address.
194  * @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
195  * @param transfer pointer to lpspi_transfer_t structure.
196  * @return status of status_t.
197  */
198 status_t LPSPI_MasterTransferEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, lpspi_transfer_t *transfer);
199 
200 /*!
201  * @brief LPSPI master aborts a transfer which is using eDMA.
202  *
203  * This function aborts a transfer which is using eDMA.
204  *
205  * @param base LPSPI peripheral base address.
206  * @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
207  */
208 void LPSPI_MasterTransferAbortEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle);
209 
210 /*!
211  * @brief Gets the master eDMA transfer remaining bytes.
212  *
213  * This function gets the master eDMA transfer remaining bytes.
214  *
215  * @param base LPSPI peripheral base address.
216  * @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
217  * @param count Number of bytes transferred so far by the EDMA transaction.
218  * @return status of status_t.
219  */
220 status_t LPSPI_MasterTransferGetCountEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, size_t *count);
221 
222 /*!
223  * @brief Initializes the LPSPI slave eDMA handle.
224  *
225  * This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs.  Usually, for a
226  * specified LPSPI instance, call this API once to get the initialized handle.
227  *
228  * Note that LPSPI eDMA has a separated (Rx and Tx as two sources) or shared (Rx  and Tx as the same source) DMA request
229  * source.
230  *
231  * (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and
232  * Tx DMAMUX source for edmaTxDataToTxRegHandle.
233  * (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle .
234  *
235  * @param base LPSPI peripheral base address.
236  * @param handle LPSPI handle pointer to lpspi_slave_edma_handle_t.
237  * @param callback LPSPI callback.
238  * @param userData callback function parameter.
239  * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
240  * @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
241  */
242 void LPSPI_SlaveTransferCreateHandleEDMA(LPSPI_Type *base,
243                                          lpspi_slave_edma_handle_t *handle,
244                                          lpspi_slave_edma_transfer_callback_t callback,
245                                          void *userData,
246                                          edma_handle_t *edmaRxRegToRxDataHandle,
247                                          edma_handle_t *edmaTxDataToTxRegHandle);
248 
249 /*!
250  * @brief LPSPI slave transfers data using eDMA.
251  *
252  * This function transfers data using eDMA. This is a non-blocking function, which return right away. When all data
253  * is transferred, the callback function is called.
254  *
255  * Note:
256  * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
257  * For bytesPerFrame greater than 4:
258  * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
259  * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
260  *
261  * @param base LPSPI peripheral base address.
262  * @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
263  * @param transfer pointer to lpspi_transfer_t structure.
264  * @return status of status_t.
265  */
266 status_t LPSPI_SlaveTransferEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, lpspi_transfer_t *transfer);
267 
268 /*!
269  * @brief LPSPI slave aborts a transfer which is using eDMA.
270  *
271  * This function aborts a transfer which is using eDMA.
272  *
273  * @param base LPSPI peripheral base address.
274  * @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
275  */
276 void LPSPI_SlaveTransferAbortEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle);
277 
278 /*!
279  * @brief Gets the slave eDMA transfer remaining bytes.
280  *
281  * This function gets the slave eDMA transfer remaining bytes.
282  *
283  * @param base LPSPI peripheral base address.
284  * @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
285  * @param count Number of bytes transferred so far by the eDMA transaction.
286  * @return status of status_t.
287  */
288 status_t LPSPI_SlaveTransferGetCountEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, size_t *count);
289 
290 #if defined(__cplusplus)
291 }
292 #endif /*_cplusplus*/
293        /*!
294         *@}
295         */
296 
297 #endif /*_FSL_LPSPI_EDMA_H_*/
298