1 /* 2 * Copyright 2022-2023 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #ifndef FSL_I3C_EDMA_H_ 7 #define FSL_I3C_EDMA_H_ 8 9 #include "fsl_i3c.h" 10 #include "fsl_edma.h" 11 12 /******************************************************************************* 13 * Definitions 14 ******************************************************************************/ 15 16 /*! @name Driver version */ 17 /*@{*/ 18 /*! @brief I3C EDMA driver version. */ 19 #define FSL_I3C_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 2, 8)) 20 /*@}*/ 21 22 /*! 23 * @addtogroup i3c_master_edma_driver 24 * @{ 25 */ 26 27 /* Forward declaration of the transfer descriptor and handle typedefs. */ 28 typedef struct _i3c_master_edma_handle i3c_master_edma_handle_t; 29 30 /*! @brief i3c master callback functions. */ 31 typedef struct _i3c_master_edma_callback 32 { 33 void (*slave2Master)(I3C_Type *base, void *userData); /*!< Transfer complete callback */ 34 void (*ibiCallback)(I3C_Type *base, 35 i3c_master_edma_handle_t *handle, 36 i3c_ibi_type_t ibiType, 37 i3c_ibi_state_t ibiState); /*!< IBI event callback */ 38 void (*transferComplete)(I3C_Type *base, 39 i3c_master_edma_handle_t *handle, 40 status_t status, 41 void *userData); /*!< Transfer complete callback */ 42 } i3c_master_edma_callback_t; 43 /*! 44 * @brief Driver handle for master EDMA APIs. 45 * @note The contents of this structure are private and subject to change. 46 */ 47 struct _i3c_master_edma_handle 48 { 49 I3C_Type *base; /*!< I3C base pointer. */ 50 uint8_t state; /*!< Transfer state machine current state. */ 51 uint32_t transferCount; /*!< Indicates progress of the transfer */ 52 uint8_t subaddressBuffer[4]; /*!< Saving subaddress command. */ 53 uint8_t subaddressCount; /*!< Saving command count. */ 54 i3c_master_transfer_t transfer; /*!< Copy of the current transfer info. */ 55 i3c_master_edma_callback_t callback; /*!< Callback function pointer. */ 56 void *userData; /*!< Application data passed to callback. */ 57 edma_handle_t *rxDmaHandle; /*!< Handle for receive DMA channel. */ 58 edma_handle_t *txDmaHandle; /*!< Handle for transmit DMA channel. */ 59 uint8_t ibiAddress; /*!< Slave address which request IBI. */ 60 uint8_t *ibiBuff; /*!< Pointer to IBI buffer to keep ibi bytes. */ 61 size_t ibiPayloadSize; /*!< IBI payload size. */ 62 i3c_ibi_type_t ibiType; /*!< IBI type. */ 63 }; 64 65 /*! @} */ 66 67 /*! 68 * @addtogroup i3c_slave_edma_driver 69 * @{ 70 */ 71 /* Forward declaration of the transfer descriptor and handle typedefs. */ 72 typedef struct _i3c_slave_edma_handle i3c_slave_edma_handle_t; 73 74 /*! @brief I3C slave transfer structure */ 75 typedef struct _i3c_slave_edma_transfer 76 { 77 uint32_t event; /*!< Reason the callback is being invoked. */ 78 uint8_t *txData; /*!< Transfer buffer */ 79 size_t txDataSize; /*!< Transfer size */ 80 uint8_t *rxData; /*!< Transfer buffer */ 81 size_t rxDataSize; /*!< Transfer size */ 82 status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for 83 #kI3C_SlaveCompletionEvent. */ 84 } i3c_slave_edma_transfer_t; 85 86 /*! 87 * @brief Slave event callback function pointer type. 88 * 89 * This callback is used only for the slave DMA transfer API. 90 * 91 * @param base Base address for the I3C instance on which the event occurred. 92 * @param handle Pointer to slave DMA transfer handle. 93 * @param transfer Pointer to transfer descriptor containing values passed to and/or from the callback. 94 * @param userData Arbitrary pointer-sized value passed from the application. 95 */ 96 typedef void (*i3c_slave_edma_callback_t)(I3C_Type *base, i3c_slave_edma_transfer_t *transfer, void *userData); 97 /*! 98 * @brief I3C slave edma handle structure. 99 * @note The contents of this structure are private and subject to change. 100 */ 101 struct _i3c_slave_edma_handle 102 { 103 I3C_Type *base; /*!< I3C base pointer. */ 104 i3c_slave_edma_transfer_t transfer; /*!< I3C slave transfer copy. */ 105 bool isBusy; /*!< Whether transfer is busy. */ 106 bool wasTransmit; /*!< Whether the last transfer was a transmit. */ 107 uint32_t eventMask; /*!< Mask of enabled events. */ 108 i3c_slave_edma_callback_t callback; /*!< Callback function called at transfer event. */ 109 edma_handle_t *rxDmaHandle; /*!< Handle for receive DMA channel. */ 110 edma_handle_t *txDmaHandle; /*!< Handle for transmit DMA channel. */ 111 void *userData; /*!< Callback parameter passed to callback. */ 112 }; 113 /*! @} */ 114 /******************************************************************************* 115 * API 116 ******************************************************************************/ 117 118 #if defined(__cplusplus) 119 extern "C" { 120 #endif 121 122 /*! 123 * @addtogroup i3c_master_edma_driver 124 * @{ 125 */ 126 127 /*! @name Master DMA */ 128 /*@{*/ 129 130 /*! 131 * @brief Create a new handle for the I3C master DMA APIs. 132 * 133 * The creation of a handle is for use with the DMA APIs. Once a handle 134 * is created, there is not a corresponding destroy handle. If the user wants to 135 * terminate a transfer, the I3C_MasterTransferAbortDMA() API shall be called. 136 * 137 * For devices where the I3C send and receive DMA requests are OR'd together, the @a txDmaHandle 138 * parameter is ignored and may be set to NULL. 139 * 140 * @param base The I3C peripheral base address. 141 * @param handle Pointer to the I3C master driver handle. 142 * @param callback User provided pointer to the asynchronous callback function. 143 * @param userData User provided pointer to the application callback data. 144 * @param rxDmaHandle Handle for the DMA receive channel. Created by the user prior to calling this function. 145 * @param txDmaHandle Handle for the DMA transmit channel. Created by the user prior to calling this function. 146 */ 147 void I3C_MasterTransferCreateHandleEDMA(I3C_Type *base, 148 i3c_master_edma_handle_t *handle, 149 const i3c_master_edma_callback_t *callback, 150 void *userData, 151 edma_handle_t *rxDmaHandle, 152 edma_handle_t *txDmaHandle); 153 154 /*! 155 * @brief Performs a non-blocking DMA-based transaction on the I3C bus. 156 * 157 * The callback specified when the @a handle was created is invoked when the transaction has 158 * completed. 159 * 160 * @param base The I3C peripheral base address. 161 * @param handle Pointer to the I3C master driver handle. 162 * @param transfer The pointer to the transfer descriptor. 163 * @retval kStatus_Success The transaction was started successfully. 164 * @retval #kStatus_I3C_Busy Either another master is currently utilizing the bus, or another DMA 165 * transaction is already in progress. 166 */ 167 status_t I3C_MasterTransferEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle, i3c_master_transfer_t *transfer); 168 169 /*! 170 * @brief Returns number of bytes transferred so far. 171 * 172 * @param base The I3C peripheral base address. 173 * @param handle Pointer to the I3C master driver handle. 174 * @param[out] count Number of bytes transferred so far by the non-blocking transaction. 175 * @retval kStatus_Success 176 * @retval kStatus_NoTransferInProgress There is not a DMA transaction currently in progress. 177 */ 178 status_t I3C_MasterTransferGetCountEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle, size_t *count); 179 180 /*! 181 * @brief Terminates a non-blocking I3C master transmission early. 182 * 183 * @note It is not safe to call this function from an IRQ handler that has a higher priority than the 184 * DMA peripheral's IRQ priority. 185 * 186 * @param base The I3C peripheral base address. 187 * @param handle Pointer to the I3C master driver handle. 188 */ 189 void I3C_MasterTransferAbortEDMA(I3C_Type *base, i3c_master_edma_handle_t *handle); 190 191 /*! 192 * @brief Reusable routine to handle master interrupts. 193 * @note This function does not need to be called unless you are reimplementing the 194 * nonblocking API's interrupt handler routines to add special functionality. 195 * @param base The I3C peripheral base address. 196 * @param handle Pointer to the I3C master DMA driver handle. 197 */ 198 void I3C_MasterTransferEDMAHandleIRQ(I3C_Type *base, void *i3cHandle); 199 /*@}*/ 200 201 /*! @} */ 202 203 /*! 204 * @addtogroup i3c_slave_edma_driver 205 * @{ 206 */ 207 208 /*! @name Slave DMA */ 209 /*@{*/ 210 /*! 211 * @brief Create a new handle for the I3C slave DMA APIs. 212 * 213 * The creation of a handle is for use with the DMA APIs. Once a handle 214 * is created, there is not a corresponding destroy handle. If the user wants to 215 * terminate a transfer, the I3C_SlaveTransferAbortDMA() API shall be called. 216 * 217 * For devices where the I3C send and receive DMA requests are OR'd together, the @a txDmaHandle 218 * parameter is ignored and may be set to NULL. 219 * 220 * @param base The I3C peripheral base address. 221 * @param handle Pointer to the I3C slave driver handle. 222 * @param callback User provided pointer to the asynchronous callback function. 223 * @param userData User provided pointer to the application callback data. 224 * @param rxDmaHandle Handle for the DMA receive channel. Created by the user prior to calling this function. 225 * @param txDmaHandle Handle for the DMA transmit channel. Created by the user prior to calling this function. 226 */ 227 void I3C_SlaveTransferCreateHandleEDMA(I3C_Type *base, 228 i3c_slave_edma_handle_t *handle, 229 i3c_slave_edma_callback_t callback, 230 void *userData, 231 edma_handle_t *rxDmaHandle, 232 edma_handle_t *txDmaHandle); 233 234 /*! 235 * @brief Prepares for a non-blocking DMA-based transaction on the I3C bus. 236 * 237 * The API will do DMA configuration according to the input transfer descriptor, and the data will be transferred when 238 * there's bus master requesting transfer from/to this slave. So the timing of call to this API need be aligned 239 * with master application to ensure the transfer is executed as expected. 240 * Callback specified when the @a handle was created is invoked when the transaction has completed. 241 * 242 * @param base The I3C peripheral base address. 243 * @param handle Pointer to the I3C slave driver handle. 244 * @param transfer The pointer to the transfer descriptor. 245 * @param eventMask Bit mask formed by OR'ing together #i3c_slave_transfer_event_t enumerators to specify 246 * which events to send to the callback. The transmit and receive events is not allowed to be enabled. 247 * @retval kStatus_Success The transaction was started successfully. 248 * @retval #kStatus_I3C_Busy Either another master is currently utilizing the bus, or another DMA 249 * transaction is already in progress. 250 * @retval #kStatus_Fail The transaction can't be set. 251 */ 252 status_t I3C_SlaveTransferEDMA(I3C_Type *base, 253 i3c_slave_edma_handle_t *handle, 254 i3c_slave_edma_transfer_t *transfer, 255 uint32_t eventMask); 256 /*! 257 * @brief Abort a slave edma non-blocking transfer in a early time 258 * 259 * @param base I3C peripheral base address 260 * @param handle pointer to i3c_slave_edma_handle_t structure 261 */ 262 void I3C_SlaveTransferAbortEDMA(I3C_Type *base, i3c_slave_edma_handle_t *handle); 263 264 /*! 265 * @brief Reusable routine to handle slave interrupts. 266 * @note This function does not need to be called unless you are reimplementing the 267 * nonblocking API's interrupt handler routines to add special functionality. 268 * @param base The I3C peripheral base address. 269 * @param handle Pointer to the I3C slave DMA driver handle. 270 */ 271 void I3C_SlaveTransferEDMAHandleIRQ(I3C_Type *base, void *i3cHandle); 272 /*@}*/ 273 274 /*! @} */ 275 #if defined(__cplusplus) 276 } 277 #endif 278 279 #endif /* FSL_I3C_EDMA_H_ */