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