summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/include/fsl_lpspi_edma.h
blob: 49e1ae8e8b76afe1634a1adb2f7fc7e1610cb262 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * Copyright 2016-2019 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#ifndef _FSL_LPSPI_EDMA_H_
#define _FSL_LPSPI_EDMA_H_

#include "fsl_lpspi.h"
#include "fsl_edma.h"

/*!
 * @addtogroup lpspi_edma_driver
 * @{
 */

/***********************************************************************************************************************
 * Definitions
 **********************************************************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief LPSPI EDMA driver version 2.0.5. */
#define FSL_LPSPI_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 5))
/*@}*/

/*!
 * @brief Forward declaration of the _lpspi_master_edma_handle typedefs.
 */
typedef struct _lpspi_master_edma_handle lpspi_master_edma_handle_t;

/*!
 * @brief Forward declaration of the _lpspi_slave_edma_handle typedefs.
 */
typedef struct _lpspi_slave_edma_handle lpspi_slave_edma_handle_t;

/*!
 * @brief Completion callback function pointer type.
 *
 * @param base LPSPI peripheral base address.
 * @param handle Pointer to the handle for the LPSPI master.
 * @param status Success or error code describing whether the transfer completed.
 * @param userData Arbitrary pointer-dataSized value passed from the application.
 */
typedef void (*lpspi_master_edma_transfer_callback_t)(LPSPI_Type *base,
                                                      lpspi_master_edma_handle_t *handle,
                                                      status_t status,
                                                      void *userData);
/*!
 * @brief Completion callback function pointer type.
 *
 * @param base LPSPI peripheral base address.
 * @param handle Pointer to the handle for the LPSPI slave.
 * @param status Success or error code describing whether the transfer completed.
 * @param userData Arbitrary pointer-dataSized value passed from the application.
 */
typedef void (*lpspi_slave_edma_transfer_callback_t)(LPSPI_Type *base,
                                                     lpspi_slave_edma_handle_t *handle,
                                                     status_t status,
                                                     void *userData);

/*! @brief LPSPI master eDMA transfer handle structure used for transactional API. */
struct _lpspi_master_edma_handle
{
    volatile bool isPcsContinuous; /*!< Is PCS continuous in transfer. */

    volatile bool isByteSwap; /*!< A flag that whether should byte swap. */

    volatile uint8_t fifoSize; /*!< FIFO dataSize. */

    volatile uint8_t rxWatermark; /*!< Rx watermark. */

    volatile uint8_t bytesEachWrite; /*!< Bytes for each write TDR. */
    volatile uint8_t bytesEachRead;  /*!< Bytes for each read RDR. */

    volatile uint8_t bytesLastRead;    /*!< Bytes for last read RDR. */
    volatile bool isThereExtraRxBytes; /*!< Is there extra RX byte. */

    uint8_t *volatile txData;             /*!< Send buffer. */
    uint8_t *volatile rxData;             /*!< Receive buffer. */
    volatile size_t txRemainingByteCount; /*!< Number of bytes remaining to send.*/
    volatile size_t rxRemainingByteCount; /*!< Number of bytes remaining to receive.*/

    volatile uint32_t writeRegRemainingTimes; /*!< Write TDR register remaining times. */
    volatile uint32_t readRegRemainingTimes;  /*!< Read RDR register remaining times. */

    uint32_t totalByteCount; /*!< Number of transfer bytes*/

    uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
    uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/

    uint32_t transmitCommand; /*!< Used to write TCR for DMA purpose.*/

    volatile uint8_t state; /*!< LPSPI transfer state , _lpspi_transfer_state.*/

    uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */

    lpspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */
    void *userData;                                 /*!< Callback user data. */

    edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
    edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg buff*/

    edma_tcd_t lpspiSoftwareTCD[3]; /*!<SoftwareTCD, internal used*/
};

/*! @brief LPSPI slave eDMA transfer handle structure used for transactional API.*/
struct _lpspi_slave_edma_handle
{
    volatile bool isByteSwap; /*!< A flag that whether should byte swap. */

    volatile uint8_t fifoSize; /*!< FIFO dataSize. */

    volatile uint8_t rxWatermark; /*!< Rx watermark. */

    volatile uint8_t bytesEachWrite; /*!< Bytes for each write TDR. */
    volatile uint8_t bytesEachRead;  /*!< Bytes for each read RDR. */

    volatile uint8_t bytesLastRead;    /*!< Bytes for last read RDR. */
    volatile bool isThereExtraRxBytes; /*!< Is there extra RX byte. */

    uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */

    uint8_t *volatile txData;             /*!< Send buffer. */
    uint8_t *volatile rxData;             /*!< Receive buffer. */
    volatile size_t txRemainingByteCount; /*!< Number of bytes remaining to send.*/
    volatile size_t rxRemainingByteCount; /*!< Number of bytes remaining to receive.*/

    volatile uint32_t writeRegRemainingTimes; /*!< Write TDR register remaining times. */
    volatile uint32_t readRegRemainingTimes;  /*!< Read RDR register remaining times. */

    uint32_t totalByteCount; /*!< Number of transfer bytes*/

    uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/
    uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/

    volatile uint8_t state; /*!< LPSPI transfer state.*/

    uint32_t errorCount; /*!< Error count for slave transfer.*/

    lpspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */
    void *userData;                                /*!< Callback user data. */

    edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
    edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg*/

    edma_tcd_t lpspiSoftwareTCD[2]; /*!<SoftwareTCD, internal used*/
};

/***********************************************************************************************************************
 * API
 **********************************************************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/

/*Transactional APIs*/

/*!
 * @brief Initializes the LPSPI master eDMA handle.
 *
 * This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs.  Usually, for a
 * specified LPSPI instance, call this API once to get the initialized handle.
 *
 * Note that the LPSPI eDMA has a separated (Rx and Rx as two sources) or shared (Rx  and Tx are the same source) DMA
 * request source.
 * (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and
 * Tx DMAMUX source for edmaIntermediaryToTxRegHandle.
 * (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle.
 *
 * @param base LPSPI peripheral base address.
 * @param handle LPSPI handle pointer to lpspi_master_edma_handle_t.
 * @param callback LPSPI callback.
 * @param userData callback function parameter.
 * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
 * @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
 */
void LPSPI_MasterTransferCreateHandleEDMA(LPSPI_Type *base,
                                          lpspi_master_edma_handle_t *handle,
                                          lpspi_master_edma_transfer_callback_t callback,
                                          void *userData,
                                          edma_handle_t *edmaRxRegToRxDataHandle,
                                          edma_handle_t *edmaTxDataToTxRegHandle);

/*!
 * @brief LPSPI master transfer data using eDMA.
 *
 * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
 * is transferred, the callback function is called.
 *
 * Note:
 * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
 * For bytesPerFrame greater than 4:
 * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
 * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
 *
 * @param base LPSPI peripheral base address.
 * @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
 * @param transfer pointer to lpspi_transfer_t structure.
 * @return status of status_t.
 */
status_t LPSPI_MasterTransferEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, lpspi_transfer_t *transfer);

/*!
 * @brief LPSPI master aborts a transfer which is using eDMA.
 *
 * This function aborts a transfer which is using eDMA.
 *
 * @param base LPSPI peripheral base address.
 * @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
 */
void LPSPI_MasterTransferAbortEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle);

/*!
 * @brief Gets the master eDMA transfer remaining bytes.
 *
 * This function gets the master eDMA transfer remaining bytes.
 *
 * @param base LPSPI peripheral base address.
 * @param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state.
 * @param count Number of bytes transferred so far by the EDMA transaction.
 * @return status of status_t.
 */
status_t LPSPI_MasterTransferGetCountEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, size_t *count);

/*!
 * @brief Initializes the LPSPI slave eDMA handle.
 *
 * This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs.  Usually, for a
 * specified LPSPI instance, call this API once to get the initialized handle.
 *
 * Note that LPSPI eDMA has a separated (Rx and Tx as two sources) or shared (Rx  and Tx as the same source) DMA request
 * source.
 *
 * (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and
 * Tx DMAMUX source for edmaTxDataToTxRegHandle.
 * (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle .
 *
 * @param base LPSPI peripheral base address.
 * @param handle LPSPI handle pointer to lpspi_slave_edma_handle_t.
 * @param callback LPSPI callback.
 * @param userData callback function parameter.
 * @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
 * @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
 */
void LPSPI_SlaveTransferCreateHandleEDMA(LPSPI_Type *base,
                                         lpspi_slave_edma_handle_t *handle,
                                         lpspi_slave_edma_transfer_callback_t callback,
                                         void *userData,
                                         edma_handle_t *edmaRxRegToRxDataHandle,
                                         edma_handle_t *edmaTxDataToTxRegHandle);

/*!
 * @brief LPSPI slave transfers data using eDMA.
 *
 * This function transfers data using eDMA. This is a non-blocking function, which return right away. When all data
 * is transferred, the callback function is called.
 *
 * Note:
 * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4.
 * For bytesPerFrame greater than 4:
 * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4.
 * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame.
 *
 * @param base LPSPI peripheral base address.
 * @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
 * @param transfer pointer to lpspi_transfer_t structure.
 * @return status of status_t.
 */
status_t LPSPI_SlaveTransferEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, lpspi_transfer_t *transfer);

/*!
 * @brief LPSPI slave aborts a transfer which is using eDMA.
 *
 * This function aborts a transfer which is using eDMA.
 *
 * @param base LPSPI peripheral base address.
 * @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
 */
void LPSPI_SlaveTransferAbortEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle);

/*!
 * @brief Gets the slave eDMA transfer remaining bytes.
 *
 * This function gets the slave eDMA transfer remaining bytes.
 *
 * @param base LPSPI peripheral base address.
 * @param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state.
 * @param count Number of bytes transferred so far by the eDMA transaction.
 * @return status of status_t.
 */
status_t LPSPI_SlaveTransferGetCountEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, size_t *count);

#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /*_FSL_LPSPI_EDMA_H_*/