rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
fsl_lpuart_edma.c
Go to the documentation of this file.
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
9#include "hal.h"
10#include "fsl_lpuart_edma.h"
11
12/*******************************************************************************
13 * Definitions
14 ******************************************************************************/
15
16/* Component ID definition, used by tools. */
17#ifndef FSL_COMPONENT_ID
18#define FSL_COMPONENT_ID "platform.drivers.lpuart_edma"
19#endif
20
21/*<! Structure definition for lpuart_edma_private_handle_t. The structure is private. */
22typedef struct _lpuart_edma_private_handle
23{
24 LPUART_Type *base;
27
28/* LPUART EDMA transfer handle. */
30{
31 kLPUART_TxIdle, /* TX idle. */
32 kLPUART_TxBusy, /* TX busy. */
33 kLPUART_RxIdle, /* RX idle. */
34 kLPUART_RxBusy /* RX busy. */
35};
36
37/*******************************************************************************
38 * Variables
39 ******************************************************************************/
40
41/* Array of LPUART handle. */
42#if (defined(LPUART8))
43#define LPUART_HANDLE_ARRAY_SIZE 9
44#else /* LPUART8 */
45#if (defined(LPUART7))
46#define LPUART_HANDLE_ARRAY_SIZE 8
47#else /* LPUART7 */
48#if (defined(LPUART6))
49#define LPUART_HANDLE_ARRAY_SIZE 7
50#else /* LPUART6 */
51#if (defined(LPUART5))
52#define LPUART_HANDLE_ARRAY_SIZE 6
53#else /* LPUART5 */
54#if (defined(LPUART4))
55#define LPUART_HANDLE_ARRAY_SIZE 5
56#else /* LPUART4 */
57#if (defined(LPUART3))
58#define LPUART_HANDLE_ARRAY_SIZE 4
59#else /* LPUART3 */
60#if (defined(LPUART2))
61#define LPUART_HANDLE_ARRAY_SIZE 3
62#else /* LPUART2 */
63#if (defined(LPUART1))
64#define LPUART_HANDLE_ARRAY_SIZE 2
65#else /* LPUART1 */
66#if (defined(LPUART0))
67#define LPUART_HANDLE_ARRAY_SIZE 1
68#else /* LPUART0 */
69#define LPUART_HANDLE_ARRAY_SIZE FSL_FEATURE_SOC_LPUART_COUNT
70#endif /* LPUART 0 */
71#endif /* LPUART 1 */
72#endif /* LPUART 2 */
73#endif /* LPUART 3 */
74#endif /* LPUART 4 */
75#endif /* LPUART 5 */
76#endif /* LPUART 6 */
77#endif /* LPUART 7 */
78#endif /* LPUART 8 */
79
80/*<! Private handle only used for internally. */
81static lpuart_edma_private_handle_t s_edmaPrivateHandle[LPUART_HANDLE_ARRAY_SIZE];
82
83/*******************************************************************************
84 * Prototypes
85 ******************************************************************************/
86
87/*!
88 * @brief LPUART EDMA send finished callback function.
89 *
90 * This function is called when LPUART EDMA send finished. It disables the LPUART
91 * TX EDMA request and sends @ref kStatus_LPUART_TxIdle to LPUART callback.
92 *
93 * @param handle The EDMA handle.
94 * @param param Callback function parameter.
95 */
96static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
97
98/*!
99 * @brief LPUART EDMA receive finished callback function.
100 *
101 * This function is called when LPUART EDMA receive finished. It disables the LPUART
102 * RX EDMA request and sends @ref kStatus_LPUART_RxIdle to LPUART callback.
103 *
104 * @param handle The EDMA handle.
105 * @param param Callback function parameter.
106 */
107static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
108
109/*******************************************************************************
110 * Code
111 ******************************************************************************/
112
113static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
114{
115 assert(param);
116
118
119 /* Avoid the warning for unused variables. */
120 handle = handle;
121 tcds = tcds;
122
123 if (transferDone)
124 {
125 LPUART_TransferAbortSendEDMA(lpuartPrivateHandle->base, lpuartPrivateHandle->handle);
126
127 if (lpuartPrivateHandle->handle->callback)
128 {
129 lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle,
130 kStatus_LPUART_TxIdle, lpuartPrivateHandle->handle->userData);
131 }
132 }
133}
134
135static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
136{
137 assert(param);
138
140
141 /* Avoid warning for unused parameters. */
142 handle = handle;
143 tcds = tcds;
144
145 if (transferDone)
146 {
147 /* Disable transfer. */
148 LPUART_TransferAbortReceiveEDMA(lpuartPrivateHandle->base, lpuartPrivateHandle->handle);
149
150 if (lpuartPrivateHandle->handle->callback)
151 {
152 lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle,
153 kStatus_LPUART_RxIdle, lpuartPrivateHandle->handle->userData);
154 }
155 }
156}
157
158/*!
159 * brief Initializes the LPUART handle which is used in transactional functions.
160 * param base LPUART peripheral base address.
161 * param handle Pointer to lpuart_edma_handle_t structure.
162 * param callback Callback function.
163 * param userData User data.
164 * param txEdmaHandle User requested DMA handle for TX DMA transfer.
165 * param rxEdmaHandle User requested DMA handle for RX DMA transfer.
166 */
167void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
168 lpuart_edma_handle_t *handle,
170 void *userData,
171 edma_handle_t *txEdmaHandle,
172 edma_handle_t *rxEdmaHandle)
173{
174 assert(handle);
175
176 uint32_t instance = LPUART_GetInstance(base);
177
178 s_edmaPrivateHandle[instance].base = base;
179 s_edmaPrivateHandle[instance].handle = handle;
180
181 memset(handle, 0, sizeof(*handle));
182
183 handle->rxState = kLPUART_RxIdle;
184 handle->txState = kLPUART_TxIdle;
185
186 handle->rxEdmaHandle = rxEdmaHandle;
187 handle->txEdmaHandle = txEdmaHandle;
188
189 handle->callback = callback;
190 handle->userData = userData;
191
192#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
193 /* Note:
194 Take care of the RX FIFO, EDMA request only assert when received bytes
195 equal or more than RX water mark, there is potential issue if RX water
196 mark larger than 1.
197 For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
198 5 bytes are received. the last byte will be saved in FIFO but not trigger
199 EDMA transfer because the water mark is 2.
200 */
201 if (rxEdmaHandle)
202 {
203 base->WATER &= (~LPUART_WATER_RXWATER_MASK);
204 }
205#endif
206
207 /* Configure TX. */
208 if (txEdmaHandle)
209 {
211 }
212
213 /* Configure RX. */
214 if (rxEdmaHandle)
215 {
217 }
218}
219
220/*!
221 * brief Sends data using eDMA.
222 *
223 * This function sends data using eDMA. This is a non-blocking function, which returns
224 * right away. When all data is sent, the send callback function is called.
225 *
226 * param base LPUART peripheral base address.
227 * param handle LPUART handle pointer.
228 * param xfer LPUART eDMA transfer structure. See #lpuart_transfer_t.
229 * retval kStatus_Success if succeed, others failed.
230 * retval kStatus_LPUART_TxBusy Previous transfer on going.
231 * retval kStatus_InvalidArgument Invalid argument.
232 */
234{
235 assert(handle);
236 assert(handle->txEdmaHandle);
237 assert(xfer);
238 assert(xfer->data);
239 assert(xfer->dataSize);
240
241 edma_transfer_config_t xferConfig;
242 status_t status;
243
244 /* If previous TX not finished. */
245 if (kLPUART_TxBusy == handle->txState)
246 {
247 status = kStatus_LPUART_TxBusy;
248 }
249 else
250 {
251 handle->txState = kLPUART_TxBusy;
252 handle->txDataSizeAll = xfer->dataSize;
253
254 /* Prepare transfer. */
255 EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base),
256 sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral);
257
258 /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
259 handle->nbytes = sizeof(uint8_t);
260
261 /* Submit transfer. */
262 EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig);
264
265 /* Enable LPUART TX EDMA. */
266 LPUART_EnableTxDMA(base, true);
267
268 status = kStatus_Success;
269 }
270
271 return status;
272}
273
274/*!
275 * brief Receives data using eDMA.
276 *
277 * This function receives data using eDMA. This is non-blocking function, which returns
278 * right away. When all data is received, the receive callback function is called.
279 *
280 * param base LPUART peripheral base address.
281 * param handle Pointer to lpuart_edma_handle_t structure.
282 * param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t.
283 * retval kStatus_Success if succeed, others fail.
284 * retval kStatus_LPUART_RxBusy Previous transfer ongoing.
285 * retval kStatus_InvalidArgument Invalid argument.
286 */
288{
289 assert(handle);
290 assert(handle->rxEdmaHandle);
291 assert(xfer);
292 assert(xfer->data);
293 assert(xfer->dataSize);
294
295 edma_transfer_config_t xferConfig;
296 status_t status;
297
298 /* If previous RX not finished. */
299 if (kLPUART_RxBusy == handle->rxState)
300 {
301 status = kStatus_LPUART_RxBusy;
302 }
303 else
304 {
305 handle->rxState = kLPUART_RxBusy;
306 handle->rxDataSizeAll = xfer->dataSize;
307
308 /* Prepare transfer. */
309 EDMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data,
310 sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory);
311
312 /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */
313 handle->nbytes = sizeof(uint8_t);
314
315 /* Submit transfer. */
316 EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig);
318
319 /* Enable LPUART RX EDMA. */
320 LPUART_EnableRxDMA(base, true);
321
322 status = kStatus_Success;
323 }
324
325 return status;
326}
327
328/*!
329 * brief Aborts the sent data using eDMA.
330 *
331 * This function aborts the sent data using eDMA.
332 *
333 * param base LPUART peripheral base address.
334 * param handle Pointer to lpuart_edma_handle_t structure.
335 */
337{
338 assert(handle);
339 assert(handle->txEdmaHandle);
340
341 /* Disable LPUART TX EDMA. */
342 LPUART_EnableTxDMA(base, false);
343
344 /* Stop transfer. */
346
347 handle->txState = kLPUART_TxIdle;
348}
349
350/*!
351 * brief Aborts the received data using eDMA.
352 *
353 * This function aborts the received data using eDMA.
354 *
355 * param base LPUART peripheral base address.
356 * param handle Pointer to lpuart_edma_handle_t structure.
357 */
359{
360 assert(handle);
361 assert(handle->rxEdmaHandle);
362
363 /* Disable LPUART RX EDMA. */
364 LPUART_EnableRxDMA(base, false);
365
366 /* Stop transfer. */
368
369 handle->rxState = kLPUART_RxIdle;
370}
371
372/*!
373 * brief Gets the number of received bytes.
374 *
375 * This function gets the number of received bytes.
376 *
377 * param base LPUART peripheral base address.
378 * param handle LPUART handle pointer.
379 * param count Receive bytes count.
380 * retval kStatus_NoTransferInProgress No receive in progress.
381 * retval kStatus_InvalidArgument Parameter is invalid.
382 * retval kStatus_Success Get successfully through the parameter \p count;
383 */
385{
386 assert(handle);
387 assert(handle->rxEdmaHandle);
388 assert(count);
389
390 if (kLPUART_RxIdle == handle->rxState)
391 {
393 }
394
395 *count = handle->rxDataSizeAll -
396 (uint32_t)handle->nbytes *
398
399 return kStatus_Success;
400}
401
402/*!
403 * brief Gets the number of bytes written to the LPUART TX register.
404 *
405 * This function gets the number of bytes written to the LPUART TX
406 * register by DMA.
407 *
408 * param base LPUART peripheral base address.
409 * param handle LPUART handle pointer.
410 * param count Send bytes count.
411 * retval kStatus_NoTransferInProgress No send in progress.
412 * retval kStatus_InvalidArgument Parameter is invalid.
413 * retval kStatus_Success Get successfully through the parameter \p count;
414 */
416{
417 assert(handle);
418 assert(handle->txEdmaHandle);
419 assert(count);
420
421 if (kLPUART_TxIdle == handle->txState)
422 {
424 }
425
426 *count = handle->txDataSizeAll -
427 (uint32_t)handle->nbytes *
429
430 return kStatus_Success;
431}
static BenchController instance
static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
LPUART EDMA receive finished callback function.
_lpuart_edma_tansfer_states
@ kLPUART_TxIdle
@ kLPUART_RxBusy
@ kLPUART_TxBusy
@ kLPUART_RxIdle
static lpuart_edma_private_handle_t s_edmaPrivateHandle[LPUART_HANDLE_ARRAY_SIZE]
static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
LPUART EDMA send finished callback function.
struct _lpuart_edma_private_handle lpuart_edma_private_handle_t
uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel)
Gets the remaining major loop count from the eDMA current channel TCD.
Definition fsl_edma.c:648
void EDMA_AbortTransfer(edma_handle_t *handle)
eDMA aborts transfer.
Definition fsl_edma.c:1164
DMA_Type * base
Definition fsl_edma.h:249
status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config)
Submits the eDMA transfer request.
Definition fsl_edma.c:956
void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData)
Installs a callback function for the eDMA transfer.
Definition fsl_edma.c:836
void EDMA_PrepareTransfer(edma_transfer_config_t *config, void *srcAddr, uint32_t srcWidth, void *destAddr, uint32_t destWidth, uint32_t bytesEachRequest, uint32_t transferBytes, edma_transfer_type_t type)
Prepares the eDMA transfer structure.
Definition fsl_edma.c:861
void EDMA_StartTransfer(edma_handle_t *handle)
eDMA starts transfer.
Definition fsl_edma.c:1103
uint8_t channel
Definition fsl_edma.h:251
@ kEDMA_PeripheralToMemory
Definition fsl_edma.h:139
@ kEDMA_MemoryToPeripheral
Definition fsl_edma.h:140
int32_t status_t
Type used for all status and error return values.
Definition fsl_common.h:169
@ kStatus_Success
Definition fsl_common.h:159
@ kStatus_NoTransferInProgress
Definition fsl_common.h:165
static void LPUART_EnableTxDMA(LPUART_Type *base, bool enable)
Enables or disables the LPUART transmitter DMA request.
Definition fsl_lpuart.h:490
uint32_t LPUART_GetInstance(LPUART_Type *base)
Get the LPUART instance from peripheral base address.
Definition fsl_lpuart.c:111
static void LPUART_EnableRxDMA(LPUART_Type *base, bool enable)
Enables or disables the LPUART receiver DMA.
Definition fsl_lpuart.h:510
static uint32_t LPUART_GetDataRegisterAddress(LPUART_Type *base)
Gets the LPUART data register address.
Definition fsl_lpuart.h:477
@ kStatus_LPUART_RxIdle
Definition fsl_lpuart.h:34
@ kStatus_LPUART_TxIdle
Definition fsl_lpuart.h:33
@ kStatus_LPUART_RxBusy
Definition fsl_lpuart.h:32
@ kStatus_LPUART_TxBusy
Definition fsl_lpuart.h:31
status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count)
Gets the number of bytes written to the LPUART TX register.
status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer)
Sends data using eDMA.
lpuart_edma_transfer_callback_t callback
status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count)
Gets the number of received bytes.
void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
Aborts the sent data using eDMA.
void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_edma_transfer_callback_t callback, void *userData, edma_handle_t *txEdmaHandle, edma_handle_t *rxEdmaHandle)
Initializes the LPUART handle which is used in transactional functions.
void(* lpuart_edma_transfer_callback_t)(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData)
LPUART transfer callback function.
status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer)
Receives data using eDMA.
volatile uint8_t rxState
edma_handle_t * rxEdmaHandle
edma_handle_t * txEdmaHandle
volatile uint8_t txState
void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
Aborts the received data using eDMA.
eDMA transfer handle structure
Definition fsl_edma.h:246
eDMA transfer configuration
Definition fsl_edma.h:171
LPUART eDMA handle.
LPUART transfer structure.
Definition fsl_lpuart.h:216
uint16_t count
Definition tunerstudio.h:1
static tstrWifiInitParam param