1 /* 2 * Copyright 2022-2023 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, 4)) 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 }; 64 65 /*! @} */ 66 67 /*! 68 * @addtogroup i3c_slave_dma_driver 69 * @{ 70 */ 71 /* Forward declaration of the transfer descriptor and handle typedefs. */ 72 typedef struct _i3c_slave_dma_handle i3c_slave_dma_handle_t; 73 74 /*! @brief I3C slave transfer structure */ 75 typedef struct _i3c_slave_dma_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_dma_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_dma_callback_t)(I3C_Type *base, i3c_slave_dma_transfer_t *transfer, void *userData); 97 /*! 98 * @brief I3C slave dma handle structure. 99 * @note The contents of this structure are private and subject to change. 100 */ 101 struct _i3c_slave_dma_handle 102 { 103 I3C_Type *base; /*!< I3C base pointer. */ 104 i3c_slave_dma_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_dma_callback_t callback; /*!< Callback function called at transfer event. */ 109 dma_handle_t *rxDmaHandle; /*!< Handle for receive DMA channel. */ 110 dma_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_dma_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_MasterTransferCreateHandleDMA(I3C_Type *base, 148 i3c_master_dma_handle_t *handle, 149 const i3c_master_dma_callback_t *callback, 150 void *userData, 151 dma_handle_t *rxDmaHandle, 152 dma_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_MasterTransferDMA(I3C_Type *base, i3c_master_dma_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_MasterTransferGetCountDMA(I3C_Type *base, i3c_master_dma_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_MasterTransferAbortDMA(I3C_Type *base, i3c_master_dma_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_MasterTransferDMAHandleIRQ(I3C_Type *base, void *i3cHandle); 199 /*! @} */ 200 201 /*! @} */ 202 203 /*! 204 * @addtogroup i3c_slave_dma_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_SlaveTransferCreateHandleDMA(I3C_Type *base, 228 i3c_slave_dma_handle_t *handle, 229 i3c_slave_dma_callback_t callback, 230 void *userData, 231 dma_handle_t *rxDmaHandle, 232 dma_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 */ 251 status_t I3C_SlaveTransferDMA(I3C_Type *base, 252 i3c_slave_dma_handle_t *handle, 253 i3c_slave_dma_transfer_t *transfer, 254 uint32_t eventMask); 255 /*! 256 * @brief Abort a slave dma non-blocking transfer in a early time 257 * 258 * @param base I3C peripheral base address 259 * @param handle pointer to i3c_slave_dma_handle_t structure 260 */ 261 void I3C_SlaveTransferAbortDMA(I3C_Type *base, i3c_slave_dma_handle_t *handle); 262 263 /*! 264 * @brief Reusable routine to handle slave interrupts. 265 * @note This function does not need to be called unless you are reimplementing the 266 * nonblocking API's interrupt handler routines to add special functionality. 267 * @param base The I3C peripheral base address. 268 * @param handle Pointer to the I3C slave DMA driver handle. 269 */ 270 void I3C_SlaveTransferDMAHandleIRQ(I3C_Type *base, void *i3cHandle); 271 /*! @} */ 272 273 /*! @} */ 274 #if defined(__cplusplus) 275 } 276 #endif 277 278 #endif /* FSL_I3C_DMA_H_ */ 279