1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2021 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef _FSL_LPI2C_EDMA_H_
9 #define _FSL_LPI2C_EDMA_H_
10 
11 #include "fsl_lpi2c.h"
12 #include "fsl_edma.h"
13 
14 /*******************************************************************************
15  * Definitions
16  ******************************************************************************/
17 
18 /*! @name Driver version */
19 /*@{*/
20 /*! @brief LPI2C EDMA driver version. */
21 #define FSL_LPI2C_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 3, 0))
22 /*@}*/
23 
24 /*!
25  * @addtogroup lpi2c_master_edma_driver
26  * @{
27  */
28 
29 /* Forward declaration of the transfer descriptor and handle typedefs. */
30 typedef struct _lpi2c_master_edma_handle lpi2c_master_edma_handle_t;
31 
32 /*!
33  * @brief Master DMA completion callback function pointer type.
34  *
35  * This callback is used only for the non-blocking master transfer API. Specify the callback you wish to use
36  * in the call to LPI2C_MasterCreateEDMAHandle().
37  *
38  * @param base The LPI2C peripheral base address.
39  * @param handle Handle associated with the completed transfer.
40  * @param completionStatus Either kStatus_Success or an error code describing how the transfer completed.
41  * @param userData Arbitrary pointer-sized value passed from the application.
42  */
43 typedef void (*lpi2c_master_edma_transfer_callback_t)(LPI2C_Type *base,
44                                                       lpi2c_master_edma_handle_t *handle,
45                                                       status_t completionStatus,
46                                                       void *userData);
47 
48 /*!
49  * @brief Driver handle for master DMA APIs.
50  * @note The contents of this structure are private and subject to change.
51  */
52 struct _lpi2c_master_edma_handle
53 {
54     LPI2C_Type *base;                 /*!< LPI2C base pointer. */
55     bool isBusy;                      /*!< Transfer state machine current state. */
56     uint8_t nbytes;                   /*!< eDMA minor byte transfer count initially configured. */
57     uint16_t commandBuffer[10];       /*!< LPI2C command sequence. When all 10 command words are used:
58          Start&addr&write[1 word] + subaddr[4 words] + restart&addr&read[1 word] + receive&Size[4 words] */
59     lpi2c_master_transfer_t transfer; /*!< Copy of the current transfer info. */
60     lpi2c_master_edma_transfer_callback_t completionCallback; /*!< Callback function pointer. */
61     void *userData;                                           /*!< Application data passed to callback. */
62     edma_handle_t *rx;                                        /*!< Handle for receive DMA channel. */
63     edma_handle_t *tx;                                        /*!< Handle for transmit DMA channel. */
64     edma_tcd_t tcds[3]; /*!< Software TCD. Three are allocated to provide enough room to align to 32-bytes. */
65 };
66 
67 /*! @} */
68 
69 /*******************************************************************************
70  * API
71  ******************************************************************************/
72 
73 #if defined(__cplusplus)
74 extern "C" {
75 #endif
76 
77 /*!
78  * @addtogroup lpi2c_master_edma_driver
79  * @{
80  */
81 
82 /*! @name Master DMA */
83 /*@{*/
84 
85 /*!
86  * @brief Create a new handle for the LPI2C master DMA APIs.
87  *
88  * The creation of a handle is for use with the DMA APIs. Once a handle
89  * is created, there is not a corresponding destroy handle. If the user wants to
90  * terminate a transfer, the LPI2C_MasterTransferAbortEDMA() API shall be called.
91  *
92  * For devices where the LPI2C send and receive DMA requests are OR'd together, the @a txDmaHandle
93  * parameter is ignored and may be set to NULL.
94  *
95  * @param base The LPI2C peripheral base address.
96  * @param[out] handle Pointer to the LPI2C master driver handle.
97  * @param rxDmaHandle Handle for the eDMA receive channel. Created by the user prior to calling this function.
98  * @param txDmaHandle Handle for the eDMA transmit channel. Created by the user prior to calling this function.
99  * @param callback User provided pointer to the asynchronous callback function.
100  * @param userData User provided pointer to the application callback data.
101  */
102 void LPI2C_MasterCreateEDMAHandle(LPI2C_Type *base,
103                                   lpi2c_master_edma_handle_t *handle,
104                                   edma_handle_t *rxDmaHandle,
105                                   edma_handle_t *txDmaHandle,
106                                   lpi2c_master_edma_transfer_callback_t callback,
107                                   void *userData);
108 
109 /*!
110  * @brief Performs a non-blocking DMA-based transaction on the I2C bus.
111  *
112  * The callback specified when the @a handle was created is invoked when the transaction has
113  * completed.
114  *
115  * @param base The LPI2C peripheral base address.
116  * @param handle Pointer to the LPI2C master driver handle.
117  * @param transfer The pointer to the transfer descriptor.
118  * @retval kStatus_Success The transaction was started successfully.
119  * @retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or another DMA
120  *      transaction is already in progress.
121  */
122 status_t LPI2C_MasterTransferEDMA(LPI2C_Type *base,
123                                   lpi2c_master_edma_handle_t *handle,
124                                   lpi2c_master_transfer_t *transfer);
125 
126 /*!
127  * @brief Returns number of bytes transferred so far.
128  *
129  * @param base The LPI2C peripheral base address.
130  * @param handle Pointer to the LPI2C master driver handle.
131  * @param[out] count Number of bytes transferred so far by the non-blocking transaction.
132  * @retval kStatus_Success
133  * @retval kStatus_NoTransferInProgress There is not a DMA transaction currently in progress.
134  */
135 status_t LPI2C_MasterTransferGetCountEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle, size_t *count);
136 
137 /*!
138  * @brief Terminates a non-blocking LPI2C master transmission early.
139  *
140  * @note It is not safe to call this function from an IRQ handler that has a higher priority than the
141  *      eDMA peripheral's IRQ priority.
142  *
143  * @param base The LPI2C peripheral base address.
144  * @param handle Pointer to the LPI2C master driver handle.
145  * @retval kStatus_Success A transaction was successfully aborted.
146  * @retval #kStatus_LPI2C_Idle There is not a DMA transaction currently in progress.
147  */
148 status_t LPI2C_MasterTransferAbortEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle);
149 
150 /*@}*/
151 
152 /*! @} */
153 
154 #if defined(__cplusplus)
155 }
156 #endif
157 
158 #endif /* _FSL_LPI2C_EDMA_H_ */
159