![]() |
|
|||
File indexing completed on 2025-05-11 08:23:00
0001 /* 0002 * Copyright 2019 - 2020, NXP 0003 * All rights reserved. 0004 * 0005 * SPDX-License-Identifier: BSD-3-Clause 0006 */ 0007 #ifndef _FSL_PDM_EDMA_H_ 0008 #define _FSL_PDM_EDMA_H_ 0009 0010 #include "fsl_edma.h" 0011 #include "fsl_pdm.h" 0012 0013 /*! 0014 * @addtogroup pdm_edma PDM EDMA Driver 0015 * @ingroup pdm 0016 * @{ 0017 */ 0018 0019 /******************************************************************************* 0020 * Definitions 0021 ******************************************************************************/ 0022 0023 /*! @name Driver version */ 0024 /*@{*/ 0025 #define FSL_PDM_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 6, 1)) /*!< Version 2.6.1 */ 0026 /*@}*/ 0027 0028 /*! @brief PDM edma handler */ 0029 typedef struct _pdm_edma_handle pdm_edma_handle_t; 0030 0031 /*!@brief pdm multi channel interleave type */ 0032 typedef enum _pdm_edma_multi_channel_interleave 0033 { 0034 kPDM_EDMAMultiChannelInterleavePerChannelSample = 0035 0U, /*!< multi channel PDM data interleave per channel sample 0036 * ------------------------------------------------------------------------- 0037 * |CHANNEL0 | CHANNEL1 | CHANNEL0 | CHANNEL1 | CHANNEL0 | CHANNEL 1 | ....| 0038 * ------------------------------------------------------------------------- 0039 */ 0040 kPDM_EDMAMultiChannelInterleavePerChannelBlock = 0041 1U, /*!< multi channel PDM data interleave per channel block 0042 * ---------------------------------------------------------------------------------------------------------------------------- 0043 * |CHANNEL0 | CHANNEL0 | CHANNEL0 | ...... | CHANNEL1 | CHANNEL 1 | CHANNEL 1 | ....| CHANNEL2 | CHANNEL 2 0044 * | CHANNEL 2 | ....| 0045 * ---------------------------------------------------------------------------------------------------------------------------- 0046 */ 0047 } pdm_edma_multi_channel_interleave_t; 0048 0049 /*! @brief PDM edma transfer */ 0050 typedef struct _pdm_edma_transfer 0051 { 0052 volatile uint8_t *data; /*!< Data start address to transfer. */ 0053 volatile size_t dataSize; /*!< Total Transfer bytes size. */ 0054 struct _pdm_edma_transfer *linkTransfer; /*!< linked transfer configurations */ 0055 } pdm_edma_transfer_t; 0056 0057 /*! @brief PDM eDMA transfer callback function for finish and error */ 0058 typedef void (*pdm_edma_callback_t)(PDM_Type *base, pdm_edma_handle_t *handle, status_t status, void *userData); 0059 0060 /*! @brief PDM DMA transfer handle, users should not touch the content of the handle.*/ 0061 struct _pdm_edma_handle 0062 { 0063 edma_handle_t *dmaHandle; /*!< DMA handler for PDM send */ 0064 uint8_t count; /*!< The transfer data count in a DMA request */ 0065 uint32_t receivedBytes; /*!< total transfer count */ 0066 uint32_t state; /*!< Internal state for PDM eDMA transfer */ 0067 pdm_edma_callback_t callback; /*!< Callback for users while transfer finish or error occurs */ 0068 bool isLoopTransfer; /*!< loop transfer */ 0069 void *userData; /*!< User callback parameter */ 0070 edma_tcd_t *tcd; /*!< TCD pool for eDMA transfer. */ 0071 uint32_t tcdNum; /*!< TCD number */ 0072 uint32_t tcdUser; /*!< Index for user to queue transfer. */ 0073 uint32_t tcdDriver; /*!< Index for driver to get the transfer data and size */ 0074 volatile uint32_t tcdUsedNum; /*!< Index for user to queue transfer. */ 0075 0076 pdm_edma_multi_channel_interleave_t interleaveType; /*!< multi channel transfer interleave type */ 0077 0078 uint8_t endChannel; /*!< The last enabled channel */ 0079 uint8_t channelNums; /*!< total channel numbers */ 0080 }; 0081 0082 /******************************************************************************* 0083 * APIs 0084 ******************************************************************************/ 0085 #if defined(__cplusplus) 0086 extern "C" { 0087 #endif 0088 0089 /*! 0090 * @name PDM eDMA Transactional 0091 * @{ 0092 */ 0093 0094 /*! 0095 * @brief Install EDMA descriptor memory. 0096 * 0097 * @param handle Pointer to EDMA channel transfer handle. 0098 * @param tcdAddr EDMA head descriptor address. 0099 * @param tcdNum EDMA link descriptor address. 0100 */ 0101 void PDM_TransferInstallEDMATCDMemory(pdm_edma_handle_t *handle, void *tcdAddr, size_t tcdNum); 0102 0103 /*! 0104 * @brief Initializes the PDM Rx eDMA handle. 0105 * 0106 * This function initializes the PDM slave DMA handle, which can be used for other PDM master transactional APIs. 0107 * Usually, for a specified PDM instance, call this API once to get the initialized handle. 0108 * 0109 * @param base PDM base pointer. 0110 * @param handle PDM eDMA handle pointer. 0111 * @param callback Pointer to user callback function. 0112 * @param userData User parameter passed to the callback function. 0113 * @param dmaHandle eDMA handle pointer, this handle shall be static allocated by users. 0114 */ 0115 void PDM_TransferCreateHandleEDMA( 0116 PDM_Type *base, pdm_edma_handle_t *handle, pdm_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle); 0117 0118 /*! 0119 * @brief Initializes the multi PDM channel interleave type. 0120 * 0121 * This function initializes the PDM DMA handle member interleaveType, it shall be called only when application would 0122 * like to use type kPDM_EDMAMultiChannelInterleavePerChannelBlock, since the default interleaveType is 0123 * kPDM_EDMAMultiChannelInterleavePerChannelSample always 0124 * 0125 * @param handle PDM eDMA handle pointer. 0126 * @param multiChannelInterleaveType Multi channel interleave type. 0127 */ 0128 void PDM_TransferSetMultiChannelInterleaveType(pdm_edma_handle_t *handle, 0129 pdm_edma_multi_channel_interleave_t multiChannelInterleaveType); 0130 0131 /*! 0132 * @brief Configures the PDM channel. 0133 * 0134 * @param base PDM base pointer. 0135 * @param handle PDM eDMA handle pointer. 0136 * @param channel channel index. 0137 * @param config pdm channel configurations. 0138 */ 0139 void PDM_TransferSetChannelConfigEDMA(PDM_Type *base, 0140 pdm_edma_handle_t *handle, 0141 uint32_t channel, 0142 const pdm_channel_config_t *config); 0143 0144 /*! 0145 * @brief Performs a non-blocking PDM receive using eDMA. 0146 * 0147 * @note This interface returns immediately after the transfer initiates. Call 0148 * the PDM_GetReceiveRemainingBytes to poll the transfer status and check whether the PDM transfer is finished. 0149 * 0150 * 1. Scatter gather case: 0151 * This functio support dynamic scatter gather and staic scatter gather, 0152 * a. for the dynamic scatter gather case: 0153 * Application should call PDM_TransferReceiveEDMA function continuously to make sure new receive request is submit 0154 * before the previous one finish. b. for the static scatter gather case: Application should use the link transfer 0155 * feature and make sure a loop link transfer is provided, such as: 0156 * @code pdm_edma_transfer_t pdmXfer[2] = 0157 * { 0158 * { 0159 * .data = s_buffer, 0160 * .dataSize = BUFFER_SIZE, 0161 * .linkTransfer = &pdmXfer[1], 0162 * }, 0163 * 0164 * { 0165 * .data = &s_buffer[BUFFER_SIZE], 0166 * .dataSize = BUFFER_SIZE, 0167 * .linkTransfer = &pdmXfer[0] 0168 * }, 0169 * }; 0170 * @endcode 0171 * 0172 * 2. Multi channel case: 0173 * This function support receive multi pdm channel data, for example, if two channel is requested, 0174 * @code 0175 * PDM_TransferSetChannelConfigEDMA(DEMO_PDM, &s_pdmRxHandle_0, DEMO_PDM_ENABLE_CHANNEL_0, &channelConfig); 0176 * PDM_TransferSetChannelConfigEDMA(DEMO_PDM, &s_pdmRxHandle_0, DEMO_PDM_ENABLE_CHANNEL_1, &channelConfig); 0177 * PDM_TransferReceiveEDMA(DEMO_PDM, &s_pdmRxHandle_0, pdmXfer); 0178 * @endcode 0179 * The output data will be formatted as below if handle->interleaveType = 0180 * kPDM_EDMAMultiChannelInterleavePerChannelSample : 0181 * ------------------------------------------------------------------------- 0182 * |CHANNEL0 | CHANNEL1 | CHANNEL0 | CHANNEL1 | CHANNEL0 | CHANNEL 1 | ....| 0183 * ------------------------------------------------------------------------- 0184 * 0185 * The output data will be formatted as below if handle->interleaveType = kPDM_EDMAMultiChannelInterleavePerChannelBlock 0186 * : 0187 * ---------------------------------------------------------------------------------------------------------------------- 0188 * |CHANNEL3 | CHANNEL3 | CHANNEL3 | .... | CHANNEL4 | CHANNEL 4 | CHANNEL4 |....| CHANNEL5 | CHANNEL 5 | CHANNEL5 0189 * |....| 0190 * ---------------------------------------------------------------------------------------------------------------------- 0191 * Note: the dataSize of xfer is the total data size, while application using 0192 * kPDM_EDMAMultiChannelInterleavePerChannelBlock, the buffer size for each PDM channel is channelSize = dataSize / 0193 * channelNums, then there are limitation for this feature, 0194 * 1. 3 DMIC array: the dataSize shall be 4 * (channelSize) 0195 * The addtional buffer is mandantory for edma modulo feature. 0196 * 2. The kPDM_EDMAMultiChannelInterleavePerChannelBlock feature support below dmic array only, 0197 * 2 DMIC array: CHANNEL3, CHANNEL4 0198 * 3 DMIC array: CHANNEL3, CHANNEL4, CHANNEL5 0199 * 4 DMIC array: CHANNEL3, CHANNEL4, CHANNEL5, CHANNEL6 0200 * Any other combinations is not support, that is to SAY, THE FEATURE SUPPORT RECEIVE START FROM CHANNEL3 ONLY AND 4 0201 * MAXIMUM DMIC CHANNELS. 0202 * 0203 * @param base PDM base pointer 0204 * @param handle PDM eDMA handle pointer. 0205 * @param xfer Pointer to DMA transfer structure. 0206 * @retval kStatus_Success Start a PDM eDMA receive successfully. 0207 * @retval kStatus_InvalidArgument The input argument is invalid. 0208 * @retval kStatus_RxBusy PDM is busy receiving data. 0209 */ 0210 status_t PDM_TransferReceiveEDMA(PDM_Type *base, pdm_edma_handle_t *handle, pdm_edma_transfer_t *xfer); 0211 0212 /*! 0213 * @brief Terminate all PDM receive. 0214 * 0215 * This function will clear all transfer slots buffered in the pdm queue. If users only want to abort the 0216 * current transfer slot, please call PDM_TransferAbortReceiveEDMA. 0217 * 0218 * @param base PDM base pointer. 0219 * @param handle PDM eDMA handle pointer. 0220 */ 0221 void PDM_TransferTerminateReceiveEDMA(PDM_Type *base, pdm_edma_handle_t *handle); 0222 0223 /*! 0224 * @brief Aborts a PDM receive using eDMA. 0225 * 0226 * This function only aborts the current transfer slots, the other transfer slots' information still kept 0227 * in the handler. If users want to terminate all transfer slots, just call PDM_TransferTerminateReceiveEDMA. 0228 * 0229 * @param base PDM base pointer 0230 * @param handle PDM eDMA handle pointer. 0231 */ 0232 void PDM_TransferAbortReceiveEDMA(PDM_Type *base, pdm_edma_handle_t *handle); 0233 0234 /*! 0235 * @brief Gets byte count received by PDM. 0236 * 0237 * @param base PDM base pointer 0238 * @param handle PDM eDMA handle pointer. 0239 * @param count Bytes count received by PDM. 0240 * @retval kStatus_Success Succeed get the transfer count. 0241 * @retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress. 0242 */ 0243 status_t PDM_TransferGetReceiveCountEDMA(PDM_Type *base, pdm_edma_handle_t *handle, size_t *count); 0244 0245 /*! @} */ 0246 0247 #if defined(__cplusplus) 0248 } 0249 #endif 0250 0251 /*! 0252 * @} 0253 */ 0254 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |