Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:00

0001 /*
0002  * Copyright (c) 2018, Freescale Semiconductor, Inc.
0003  * Copyright 2019-2020 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #ifndef _FSL_PDM_H_
0010 #define _FSL_PDM_H_
0011 
0012 #include "fsl_common.h"
0013 
0014 /*!
0015  * @addtogroup pdm_driver PDM Driver
0016  * @{
0017  */
0018 
0019 /*******************************************************************************
0020  * Definitions
0021  ******************************************************************************/
0022 
0023 /*! @name Driver version */
0024 /*@{*/
0025 #define FSL_PDM_DRIVER_VERSION (MAKE_VERSION(2, 8, 0)) /*!< Version 2.8.0 */
0026 /*@}*/
0027 
0028 /*! @brief PDM XFER QUEUE SIZE */
0029 #define PDM_XFER_QUEUE_SIZE (4U)
0030 
0031 /*! @brief PDM return status*/
0032 enum
0033 {
0034     kStatus_PDM_Busy = MAKE_STATUS(kStatusGroup_PDM, 0), /*!< PDM is busy. */
0035 #if (defined(FSL_FEATURE_PDM_HAS_STATUS_LOW_FREQ) && (FSL_FEATURE_PDM_HAS_STATUS_LOW_FREQ == 1U))
0036     kStatus_PDM_CLK_LOW = MAKE_STATUS(kStatusGroup_PDM, 1), /*!< PDM clock frequency low */
0037 #endif
0038     kStatus_PDM_FIFO_ERROR           = MAKE_STATUS(kStatusGroup_PDM, 2), /*!< PDM FIFO underrun or overflow */
0039     kStatus_PDM_QueueFull            = MAKE_STATUS(kStatusGroup_PDM, 3), /*!< PDM FIFO underrun or overflow */
0040     kStatus_PDM_Idle                 = MAKE_STATUS(kStatusGroup_PDM, 4), /*!< PDM is idle */
0041     kStatus_PDM_Output_ERROR         = MAKE_STATUS(kStatusGroup_PDM, 5), /*!< PDM is output error */
0042     kStatus_PDM_ChannelConfig_Failed = MAKE_STATUS(kStatusGroup_PDM, 6), /*!< PDM channel config failed */
0043 #if !(defined(FSL_FEATURE_PDM_HAS_NO_HWVAD) && FSL_FEATURE_PDM_HAS_NO_HWVAD)
0044     kStatus_PDM_HWVAD_VoiceDetected = MAKE_STATUS(kStatusGroup_PDM, 7), /*!< PDM hwvad voice detected */
0045     kStatus_PDM_HWVAD_Error         = MAKE_STATUS(kStatusGroup_PDM, 8), /*!< PDM hwvad error */
0046 #endif
0047 };
0048 
0049 /*! @brief The PDM interrupt enable flag */
0050 enum _pdm_interrupt_enable
0051 {
0052     kPDM_ErrorInterruptEnable = PDM_CTRL_1_ERREN_MASK, /*!< PDM channel error interrupt enable. */
0053     kPDM_FIFOInterruptEnable  = PDM_CTRL_1_DISEL(2U),  /*!< PDM channel FIFO interrupt */
0054 };
0055 
0056 /*! @brief The PDM status */
0057 enum _pdm_internal_status
0058 {
0059     kPDM_StatusDfBusyFlag = (int)PDM_STAT_BSY_FIL_MASK, /*!< Decimation filter is busy processing data */
0060 #if !(defined(FSL_FEATURE_PDM_HAS_NO_FIR_RDY) && FSL_FEATURE_PDM_HAS_NO_FIR_RDY)
0061     kPDM_StatusFIRFilterReady = PDM_STAT_FIR_RDY_MASK, /*!< FIR filter data is ready */
0062 #endif
0063 #if (defined(FSL_FEATURE_PDM_HAS_STATUS_LOW_FREQ) && (FSL_FEATURE_PDM_HAS_STATUS_LOW_FREQ == 1U))
0064     kPDM_StatusFrequencyLow = PDM_STAT_LOWFREQF_MASK, /*!< Mic app clock frequency not high enough */
0065 #endif
0066     kPDM_StatusCh0FifoDataAvaliable = PDM_STAT_CH0F_MASK, /*!< channel 0 fifo data reached watermark level */
0067     kPDM_StatusCh1FifoDataAvaliable = PDM_STAT_CH1F_MASK, /*!< channel 1 fifo data reached watermark level */
0068     kPDM_StatusCh2FifoDataAvaliable = PDM_STAT_CH2F_MASK, /*!< channel 2 fifo data reached watermark level */
0069     kPDM_StatusCh3FifoDataAvaliable = PDM_STAT_CH3F_MASK, /*!< channel 3 fifo data reached watermark level */
0070 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0071     kPDM_StatusCh4FifoDataAvaliable = PDM_STAT_CH4F_MASK, /*!< channel 4 fifo data reached watermark level */
0072     kPDM_StatusCh5FifoDataAvaliable = PDM_STAT_CH5F_MASK, /*!< channel 5 fifo data reached watermark level */
0073     kPDM_StatusCh6FifoDataAvaliable = PDM_STAT_CH6F_MASK, /*!< channel 6 fifo data reached watermark level */
0074     kPDM_StatusCh7FifoDataAvaliable = PDM_STAT_CH7F_MASK, /*!< channel 7 fifo data reached watermark level */
0075 #endif
0076 };
0077 
0078 /*! @brief PDM channel enable mask */
0079 enum _pdm_channel_enable_mask
0080 {
0081     kPDM_EnableChannel0 = PDM_STAT_CH0F_MASK, /*!< channgel 0 enable mask */
0082     kPDM_EnableChannel1 = PDM_STAT_CH1F_MASK, /*!< channgel 1 enable mask */
0083     kPDM_EnableChannel2 = PDM_STAT_CH2F_MASK, /*!< channgel 2 enable mask */
0084     kPDM_EnableChannel3 = PDM_STAT_CH3F_MASK, /*!< channgel 3 enable mask */
0085 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0086     kPDM_EnableChannel4 = PDM_STAT_CH4F_MASK, /*!< channgel 4 enable mask */
0087     kPDM_EnableChannel5 = PDM_STAT_CH5F_MASK, /*!< channgel 5 enable mask */
0088     kPDM_EnableChannel6 = PDM_STAT_CH6F_MASK, /*!< channgel 6 enable mask */
0089     kPDM_EnableChannel7 = PDM_STAT_CH7F_MASK, /*!< channgel 7 enable mask */
0090 
0091     kPDM_EnableChannelAll = kPDM_EnableChannel0 | kPDM_EnableChannel1 | kPDM_EnableChannel2 | kPDM_EnableChannel3 |
0092                             kPDM_EnableChannel4 | kPDM_EnableChannel5 | kPDM_EnableChannel6 | kPDM_EnableChannel7,
0093 #else
0094     kPDM_EnableChannelAll = kPDM_EnableChannel0 | kPDM_EnableChannel1 | kPDM_EnableChannel2 | kPDM_EnableChannel3,
0095 #endif
0096 };
0097 
0098 /*! @brief The PDM fifo status */
0099 enum _pdm_fifo_status
0100 {
0101     kPDM_FifoStatusUnderflowCh0 = PDM_FIFO_STAT_FIFOUND0_MASK, /*!< channel0 fifo status underflow */
0102     kPDM_FifoStatusUnderflowCh1 = PDM_FIFO_STAT_FIFOUND1_MASK, /*!< channel1 fifo status underflow */
0103     kPDM_FifoStatusUnderflowCh2 = PDM_FIFO_STAT_FIFOUND2_MASK, /*!< channel2 fifo status underflow */
0104     kPDM_FifoStatusUnderflowCh3 = PDM_FIFO_STAT_FIFOUND3_MASK, /*!< channel3 fifo status underflow */
0105 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0106     kPDM_FifoStatusUnderflowCh4 = PDM_FIFO_STAT_FIFOUND4_MASK, /*!< channel4 fifo status underflow */
0107     kPDM_FifoStatusUnderflowCh5 = PDM_FIFO_STAT_FIFOUND5_MASK, /*!< channel5 fifo status underflow */
0108     kPDM_FifoStatusUnderflowCh6 = PDM_FIFO_STAT_FIFOUND6_MASK, /*!< channel6 fifo status underflow */
0109     kPDM_FifoStatusUnderflowCh7 = PDM_FIFO_STAT_FIFOUND6_MASK, /*!< channel7 fifo status underflow */
0110 #endif
0111 
0112     kPDM_FifoStatusOverflowCh0 = PDM_FIFO_STAT_FIFOOVF0_MASK, /*!< channel0 fifo status overflow */
0113     kPDM_FifoStatusOverflowCh1 = PDM_FIFO_STAT_FIFOOVF1_MASK, /*!< channel1 fifo status overflow */
0114     kPDM_FifoStatusOverflowCh2 = PDM_FIFO_STAT_FIFOOVF2_MASK, /*!< channel2 fifo status overflow */
0115     kPDM_FifoStatusOverflowCh3 = PDM_FIFO_STAT_FIFOOVF3_MASK, /*!< channel3 fifo status overflow */
0116 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0117     kPDM_FifoStatusOverflowCh4 = PDM_FIFO_STAT_FIFOOVF4_MASK, /*!< channel4 fifo status overflow */
0118     kPDM_FifoStatusOverflowCh5 = PDM_FIFO_STAT_FIFOOVF5_MASK, /*!< channel5 fifo status overflow */
0119     kPDM_FifoStatusOverflowCh6 = PDM_FIFO_STAT_FIFOOVF6_MASK, /*!< channel6 fifo status overflow */
0120     kPDM_FifoStatusOverflowCh7 = PDM_FIFO_STAT_FIFOOVF7_MASK, /*!< channel7 fifo status overflow */
0121 #endif
0122 };
0123 
0124 #if defined(FSL_FEATURE_PDM_HAS_RANGE_CTRL) && FSL_FEATURE_PDM_HAS_RANGE_CTRL
0125 /*! @brief The PDM output status */
0126 enum _pdm_range_status
0127 {
0128     kPDM_RangeStatusUnderFlowCh0 = PDM_RANGE_STAT_RANGEUNF0_MASK, /*!< channel0 range status underflow */
0129     kPDM_RangeStatusUnderFlowCh1 = PDM_RANGE_STAT_RANGEUNF1_MASK, /*!< channel1 range status underflow */
0130     kPDM_RangeStatusUnderFlowCh2 = PDM_RANGE_STAT_RANGEUNF2_MASK, /*!< channel2 range status underflow */
0131     kPDM_RangeStatusUnderFlowCh3 = PDM_RANGE_STAT_RANGEUNF3_MASK, /*!< channel3 range status underflow */
0132 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0133     kPDM_RangeStatusUnderFlowCh4 = PDM_RANGE_STAT_RANGEUNF4_MASK, /*!< channel4 range status underflow */
0134     kPDM_RangeStatusUnderFlowCh5 = PDM_RANGE_STAT_RANGEUNF5_MASK, /*!< channel5 range status underflow */
0135     kPDM_RangeStatusUnderFlowCh6 = PDM_RANGE_STAT_RANGEUNF6_MASK, /*!< channel6 range status underflow */
0136     kPDM_RangeStatusUnderFlowCh7 = PDM_RANGE_STAT_RANGEUNF7_MASK, /*!< channel7 range status underflow */
0137 #endif
0138     kPDM_RangeStatusOverFlowCh0 = PDM_RANGE_STAT_RANGEOVF0_MASK, /*!< channel0 range status overflow */
0139     kPDM_RangeStatusOverFlowCh1 = PDM_RANGE_STAT_RANGEOVF1_MASK, /*!< channel1 range status overflow */
0140     kPDM_RangeStatusOverFlowCh2 = PDM_RANGE_STAT_RANGEOVF2_MASK, /*!< channel2 range status overflow */
0141     kPDM_RangeStatusOverFlowCh3 = PDM_RANGE_STAT_RANGEOVF3_MASK, /*!< channel3 range status overflow */
0142 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0143     kPDM_RangeStatusOverFlowCh4 = PDM_RANGE_STAT_RANGEOVF4_MASK, /*!< channel4 range status overflow */
0144     kPDM_RangeStatusOverFlowCh5 = PDM_RANGE_STAT_RANGEOVF5_MASK, /*!< channel5 range status overflow */
0145     kPDM_RangeStatusOverFlowCh6 = PDM_RANGE_STAT_RANGEOVF6_MASK, /*!< channel6 range status overflow */
0146     kPDM_RangeStatusOverFlowCh7 = PDM_RANGE_STAT_RANGEOVF7_MASK, /*!< channel7 range status overflow */
0147 #endif
0148 };
0149 #else
0150 /*! @brief The PDM output status */
0151 enum _pdm_output_status
0152 {
0153     kPDM_OutputStatusUnderFlowCh0 = PDM_OUT_STAT_OUTUNF0_MASK, /*!< channel0 output status underflow */
0154     kPDM_OutputStatusUnderFlowCh1 = PDM_OUT_STAT_OUTUNF1_MASK, /*!< channel1 output status underflow */
0155     kPDM_OutputStatusUnderFlowCh2 = PDM_OUT_STAT_OUTUNF2_MASK, /*!< channel2 output status underflow */
0156     kPDM_OutputStatusUnderFlowCh3 = PDM_OUT_STAT_OUTUNF3_MASK, /*!< channel3 output status underflow */
0157 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0158     kPDM_OutputStatusUnderFlowCh4 = PDM_OUT_STAT_OUTUNF4_MASK, /*!< channel4 output status underflow */
0159     kPDM_OutputStatusUnderFlowCh5 = PDM_OUT_STAT_OUTUNF5_MASK, /*!< channel5 output status underflow */
0160     kPDM_OutputStatusUnderFlowCh6 = PDM_OUT_STAT_OUTUNF6_MASK, /*!< channel6 output status underflow */
0161     kPDM_OutputStatusUnderFlowCh7 = PDM_OUT_STAT_OUTUNF7_MASK, /*!< channel7 output status underflow */
0162 #endif
0163     kPDM_OutputStatusOverFlowCh0 = PDM_OUT_STAT_OUTOVF0_MASK,  /*!< channel0 output status overflow */
0164     kPDM_OutputStatusOverFlowCh1 = PDM_OUT_STAT_OUTOVF1_MASK,  /*!< channel1 output status overflow */
0165     kPDM_OutputStatusOverFlowCh2 = PDM_OUT_STAT_OUTOVF2_MASK,  /*!< channel2 output status overflow */
0166     kPDM_OutputStatusOverFlowCh3 = PDM_OUT_STAT_OUTOVF3_MASK,  /*!< channel3 output status overflow */
0167 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0168     kPDM_OutputStatusOverFlowCh4 = PDM_OUT_STAT_OUTOVF4_MASK,  /*!< channel4 output status overflow */
0169     kPDM_OutputStatusOverFlowCh5 = PDM_OUT_STAT_OUTOVF5_MASK,  /*!< channel5 output status overflow */
0170     kPDM_OutputStatusOverFlowCh6 = PDM_OUT_STAT_OUTOVF6_MASK,  /*!< channel6 output status overflow */
0171     kPDM_OutputStatusOverFlowCh7 = PDM_OUT_STAT_OUTOVF7_MASK,  /*!< channel7 output status overflow */
0172 #endif
0173 };
0174 #endif
0175 
0176 #if (defined(FSL_FEATURE_PDM_HAS_DC_OUT_CTRL) && (FSL_FEATURE_PDM_HAS_DC_OUT_CTRL))
0177 /*! @brief PDM DC remover configurations */
0178 typedef enum _pdm_dc_remover
0179 {
0180     kPDM_DcRemoverCutOff20Hz = 0U, /*!< DC remover cut off 20HZ */
0181     kPDM_DcRemoverCutOff13Hz = 1U, /*!< DC remover cut off 13.3HZ */
0182     kPDM_DcRemoverCutOff40Hz = 2U, /*!< DC remover cut off 40HZ */
0183     kPDM_DcRemoverBypass     = 3U, /*!< DC remover bypass */
0184 } pdm_dc_remover_t;
0185 #else
0186 /*! @brief PDM DC remover configurations */
0187 typedef enum _pdm_dc_remover
0188 {
0189     kPDM_DcRemoverCutOff21Hz = 0U,  /*!< DC remover cut off 21HZ */
0190     kPDM_DcRemoverCutOff83Hz = 1U,  /*!< DC remover cut off 83HZ */
0191     kPDM_DcRemoverCutOff152Hz = 2U, /*!< DC remover cut off 152HZ */
0192     kPDM_DcRemoverBypass = 3U,      /*!< DC remover bypass */
0193 } pdm_dc_remover_t;
0194 #endif
0195 
0196 /*! @brief PDM decimation filter quality mode */
0197 typedef enum _pdm_df_quality_mode
0198 {
0199     kPDM_QualityModeMedium   = 0U, /*!< quality mode memdium */
0200     kPDM_QualityModeHigh     = 1U, /*!< quality mode high */
0201     kPDM_QualityModeLow      = 7U, /*!< quality mode low */
0202     kPDM_QualityModeVeryLow0 = 6U, /*!< quality mode very low0 */
0203     kPDM_QualityModeVeryLow1 = 5U, /*!< quality mode very low1 */
0204     kPDM_QualityModeVeryLow2 = 4U, /*!< quality mode very low2 */
0205 } pdm_df_quality_mode_t;
0206 
0207 /*! @brief PDM  quality mode K factor */
0208 enum _pdm_qulaity_mode_k_factor
0209 {
0210     kPDM_QualityModeHighKFactor     = 1U, /*!< high quality mode K factor = 1 / 2 */
0211     kPDM_QualityModeMediumKFactor   = 2U, /*!< medium/very low0 quality mode K factor = 2 / 2 */
0212     kPDM_QualityModeLowKFactor      = 4U, /*!< low/very low1 quality mode K factor = 4 / 2 */
0213     kPDM_QualityModeVeryLow2KFactor = 8U, /*!< very low2 quality mode K factor = 8 / 2 */
0214 };
0215 
0216 /*! @brief PDM decimation filter output gain */
0217 typedef enum _pdm_df_output_gain
0218 {
0219     kPDM_DfOutputGain0  = 0U,   /*!< Decimation filter output gain 0 */
0220     kPDM_DfOutputGain1  = 1U,   /*!< Decimation filter output gain 1 */
0221     kPDM_DfOutputGain2  = 2U,   /*!< Decimation filter output gain 2 */
0222     kPDM_DfOutputGain3  = 3U,   /*!< Decimation filter output gain 3 */
0223     kPDM_DfOutputGain4  = 4U,   /*!< Decimation filter output gain 4 */
0224     kPDM_DfOutputGain5  = 5U,   /*!< Decimation filter output gain 5 */
0225     kPDM_DfOutputGain6  = 6U,   /*!< Decimation filter output gain 6 */
0226     kPDM_DfOutputGain7  = 7U,   /*!< Decimation filter output gain 7 */
0227     kPDM_DfOutputGain8  = 8U,   /*!< Decimation filter output gain 8 */
0228     kPDM_DfOutputGain9  = 9U,   /*!< Decimation filter output gain 9 */
0229     kPDM_DfOutputGain10 = 0xAU, /*!< Decimation filter output gain 10 */
0230     kPDM_DfOutputGain11 = 0xBU, /*!< Decimation filter output gain 11 */
0231     kPDM_DfOutputGain12 = 0xCU, /*!< Decimation filter output gain 12 */
0232     kPDM_DfOutputGain13 = 0xDU, /*!< Decimation filter output gain 13 */
0233     kPDM_DfOutputGain14 = 0xEU, /*!< Decimation filter output gain 14 */
0234     kPDM_DfOutputGain15 = 0xFU, /*!< Decimation filter output gain 15 */
0235 } pdm_df_output_gain_t;
0236 
0237 /*! @brief PDM data width */
0238 enum _pdm_data_width
0239 {
0240 #if defined(FSL_FEATURE_PDM_FIFO_WIDTH) && (FSL_FEATURE_PDM_FIFO_WIDTH != 2U)
0241     kPDM_DataWwidth24 = 3U, /*!< PDM data width 24bit */
0242     kPDM_DataWwidth32 = 4U, /*!< PDM data width 32bit */
0243 #else
0244     kPDM_DataWdith16 = 2U, /*!< PDM data width 16bit */
0245 #endif
0246 };
0247 
0248 /*! @brief PDM channel configurations */
0249 typedef struct _pdm_channel_config
0250 {
0251 #if (defined(FSL_FEATURE_PDM_HAS_DC_OUT_CTRL) && (FSL_FEATURE_PDM_HAS_DC_OUT_CTRL))
0252     pdm_dc_remover_t outputCutOffFreq; /*!< PDM output DC remover cut off frequency */
0253 #endif
0254 
0255 #if !(defined(FSL_FEATURE_PDM_DC_CTRL_VALUE_FIXED) && (FSL_FEATURE_PDM_DC_CTRL_VALUE_FIXED))
0256     pdm_dc_remover_t cutOffFreq; /*!< DC remover cut off frequency */
0257 #endif
0258 
0259     pdm_df_output_gain_t gain; /*!< Decimation Filter Output Gain */
0260 } pdm_channel_config_t;
0261 
0262 /*! @brief PDM user configuration structure */
0263 typedef struct _pdm_config
0264 {
0265     bool
0266         enableDoze; /*!< This module will enter disable/low leakage mode if DOZEN is active with ipg_doze is asserted */
0267     uint8_t fifoWatermark;             /*!< Watermark value for FIFO */
0268     pdm_df_quality_mode_t qualityMode; /*!< Quality mode */
0269     uint8_t cicOverSampleRate;         /*!< CIC filter over sampling rate */
0270 } pdm_config_t;
0271 
0272 #if !(defined(FSL_FEATURE_PDM_HAS_NO_HWVAD) && FSL_FEATURE_PDM_HAS_NO_HWVAD)
0273 /*! @brief PDM voice activity detector interrupt type */
0274 enum _pdm_hwvad_interrupt_enable
0275 {
0276     kPDM_HwvadErrorInterruptEnable = PDM_VAD0_CTRL_1_VADERIE_MASK, /*!< PDM channel HWVAD error interrupt enable. */
0277     kPDM_HwvadInterruptEnable      = PDM_VAD0_CTRL_1_VADIE_MASK,   /*!< PDM channel HWVAD interrupt */
0278 };
0279 
0280 /*! @brief The PDM hwvad interrupt status flag */
0281 enum _pdm_hwvad_int_status
0282 {
0283     kPDM_HwvadStatusInputSaturation = PDM_VAD0_STAT_VADINSATF_MASK, /*!< HWVAD saturation condition */
0284     kPDM_HwvadStatusVoiceDetectFlag = PDM_VAD0_STAT_VADIF_MASK,     /*!< HWVAD voice detect interrupt triggered */
0285 };
0286 
0287 /*! @brief High pass filter configure cut-off frequency*/
0288 typedef enum _pdm_hwvad_hpf_config
0289 {
0290     kPDM_HwvadHpfBypassed         = 0x0U, /*!< High-pass filter bypass */
0291     kPDM_HwvadHpfCutOffFreq1750Hz = 0x1U, /*!< High-pass filter cut off frequency 1750HZ */
0292     kPDM_HwvadHpfCutOffFreq215Hz  = 0x2U, /*!< High-pass filter cut off frequency 215HZ */
0293     kPDM_HwvadHpfCutOffFreq102Hz  = 0x3U, /*!< High-pass filter cut off frequency 102HZ */
0294 } pdm_hwvad_hpf_config_t;
0295 
0296 /*! @brief HWVAD internal filter status */
0297 typedef enum _pdm_hwvad_filter_status
0298 {
0299     kPDM_HwvadInternalFilterNormalOperation = 0U, /*!< internal filter ready for normal operation */
0300     kPDM_HwvadInternalFilterInitial         = PDM_VAD0_CTRL_1_VADST10_MASK, /*!< interla filter are initial */
0301 } pdm_hwvad_filter_status_t;
0302 
0303 /*! @brief PDM voice activity detector user configuration structure */
0304 typedef struct _pdm_hwvad_config
0305 {
0306     uint8_t channel;           /*!< Which channel uses voice activity detector */
0307     uint8_t initializeTime;    /*!< Number of frames or samples to initialize voice activity detector. */
0308     uint8_t cicOverSampleRate; /*!< CIC filter over sampling rate */
0309 
0310     uint8_t inputGain;                 /*!< Voice activity detector input gain */
0311     uint32_t frameTime;                /*!< Voice activity frame time */
0312     pdm_hwvad_hpf_config_t cutOffFreq; /*!< High pass filter cut off frequency */
0313     bool enableFrameEnergy;            /*!< If frame energy enabled, true means enable */
0314     bool enablePreFilter;              /*!< If pre-filter enabled */
0315 } pdm_hwvad_config_t;
0316 
0317 /*! @brief PDM voice activity detector noise filter user configuration structure */
0318 typedef struct _pdm_hwvad_noise_filter
0319 {
0320     bool enableAutoNoiseFilter;     /*!< If noise fileter automatically activated, true means enable */
0321     bool enableNoiseMin;            /*!< If Noise minimum block enabled, true means enabled */
0322     bool enableNoiseDecimation;     /*!< If enable noise input decimation */
0323     bool enableNoiseDetectOR;       /*!< Enables a OR logic in the output of minimum noise estimator block */
0324     uint32_t noiseFilterAdjustment; /*!< The adjustment value of the noise filter */
0325     uint32_t noiseGain;             /*!< Gain value for the noise energy or envelope estimated */
0326 } pdm_hwvad_noise_filter_t;
0327 
0328 /*! @brief PDM voice activity detector zero cross detector result */
0329 typedef enum _pdm_hwvad_zcd_result
0330 {
0331     kPDM_HwvadResultOREnergyBasedDetection =
0332         0U, /*!< zero cross detector result will be OR with energy based detection */
0333     kPDM_HwvadResultANDEnergyBasedDetection =
0334         1U, /*!< zero cross detector result will be AND with energy based detection */
0335 } pdm_hwvad_zcd_result_t;
0336 
0337 /*! @brief PDM voice activity detector zero cross detector configuration structure */
0338 typedef struct _pdm_hwvad_zero_cross_detector
0339 {
0340     bool enableAutoThreshold;      /*!< If ZCD auto-threshold enabled, true means enabled. */
0341     pdm_hwvad_zcd_result_t zcdAnd; /*!< Is ZCD result is AND'ed with energy-based detection, false means OR'ed */
0342     uint32_t threshold;            /*!< The adjustment value of the noise filter */
0343     uint32_t adjustmentThreshold;  /*!< Gain value for the noise energy or envelope estimated */
0344 } pdm_hwvad_zero_cross_detector_t;
0345 #endif
0346 
0347 /*! @brief PDM SDMA transfer structure */
0348 typedef struct _pdm_transfer
0349 {
0350     volatile uint8_t *data;   /*!< Data start address to transfer. */
0351     volatile size_t dataSize; /*!< Total Transfer bytes size. */
0352 } pdm_transfer_t;
0353 
0354 /*! @brief PDM handle */
0355 typedef struct _pdm_handle pdm_handle_t;
0356 
0357 /*! @brief PDM transfer callback prototype */
0358 typedef void (*pdm_transfer_callback_t)(PDM_Type *base, pdm_handle_t *handle, status_t status, void *userData);
0359 
0360 #if !(defined(FSL_FEATURE_PDM_HAS_NO_HWVAD) && FSL_FEATURE_PDM_HAS_NO_HWVAD)
0361 /*! @brief PDM HWVAD callback prototype */
0362 typedef void (*pdm_hwvad_callback_t)(status_t status, void *userData);
0363 /*! @brief PDM HWVAD notification structure */
0364 typedef struct _pdm_hwvad_notification
0365 {
0366     pdm_hwvad_callback_t callback;
0367     void *userData;
0368 } pdm_hwvad_notification_t;
0369 #endif
0370 
0371 /*! @brief PDM handle structure */
0372 struct _pdm_handle
0373 {
0374     uint32_t state;                   /*!< Transfer status */
0375     pdm_transfer_callback_t callback; /*!< Callback function called at transfer event*/
0376     void *userData;                   /*!< Callback parameter passed to callback function*/
0377 
0378     pdm_transfer_t pdmQueue[PDM_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */
0379     size_t transferSize[PDM_XFER_QUEUE_SIZE];     /*!< Data bytes need to transfer */
0380     volatile uint8_t queueUser;                   /*!< Index for user to queue transfer */
0381     volatile uint8_t queueDriver;                 /*!< Index for driver to get the transfer data and size */
0382 
0383     uint32_t format;      /*!< data format */
0384     uint8_t watermark;    /*!< Watermark value */
0385     uint8_t startChannel; /*!< end channel */
0386     uint8_t channelNums;  /*!< Enabled channel number */
0387 };
0388 
0389 /*******************************************************************************
0390  * API
0391  ******************************************************************************/
0392 
0393 #if defined(__cplusplus)
0394 extern "C" {
0395 #endif /*_cplusplus*/
0396 
0397 /*!
0398  * @name Initialization and deinitialization
0399  * @{
0400  */
0401 
0402 /*!
0403  * @brief Initializes the PDM peripheral.
0404  *
0405  * Ungates the PDM clock, resets the module, and configures PDM with a configuration structure.
0406  * The configuration structure can be custom filled or set with default values by
0407  * PDM_GetDefaultConfig().
0408  *
0409  * @note  This API should be called at the beginning of the application to use
0410  * the PDM driver. Otherwise, accessing the PDM module can cause a hard fault
0411  * because the clock is not enabled.
0412  *
0413  * @param base PDM base pointer
0414  * @param config PDM configuration structure.
0415  */
0416 void PDM_Init(PDM_Type *base, const pdm_config_t *config);
0417 
0418 /*!
0419  * @brief De-initializes the PDM peripheral.
0420  *
0421  * This API gates the PDM clock. The PDM module can't operate unless PDM_Init
0422  * is called to enable the clock.
0423  *
0424  * @param base PDM base pointer
0425  */
0426 void PDM_Deinit(PDM_Type *base);
0427 
0428 /*!
0429  * @brief Resets the PDM module.
0430  *
0431  * @param base PDM base pointer
0432  */
0433 static inline void PDM_Reset(PDM_Type *base)
0434 {
0435     base->CTRL_1 |= PDM_CTRL_1_SRES_MASK;
0436 }
0437 
0438 /*!
0439  * @brief Enables/disables PDM interface.
0440  *
0441  * @param base PDM base pointer
0442  * @param enable True means PDM interface is enabled, false means PDM interface is disabled.
0443  */
0444 static inline void PDM_Enable(PDM_Type *base, bool enable)
0445 {
0446     if (enable)
0447     {
0448         base->CTRL_1 |= PDM_CTRL_1_PDMIEN_MASK;
0449     }
0450     else
0451     {
0452         base->CTRL_1 &= ~PDM_CTRL_1_PDMIEN_MASK;
0453     }
0454 }
0455 
0456 /*!
0457  * @brief Enables/disables DOZE.
0458  *
0459  * @param base PDM base pointer
0460  * @param enable True means the module will enter Disable/Low Leakage mode when ipg_doze is asserted, false means the
0461  * module will not enter Disable/Low Leakage mode when ipg_doze is asserted.
0462  */
0463 static inline void PDM_EnableDoze(PDM_Type *base, bool enable)
0464 {
0465     if (enable)
0466     {
0467         base->CTRL_1 |= PDM_CTRL_1_DOZEN_MASK;
0468     }
0469     else
0470     {
0471         base->CTRL_1 &= ~PDM_CTRL_1_DOZEN_MASK;
0472     }
0473 }
0474 
0475 /*!
0476  * @brief Enables/disables debug mode for PDM.
0477  * The PDM interface cannot enter debug mode once in Disable/Low Leakage or Low Power mode.
0478  * @param base PDM base pointer
0479  * @param enable True means PDM interface enter debug mode, false means PDM interface in normal mode.
0480  */
0481 static inline void PDM_EnableDebugMode(PDM_Type *base, bool enable)
0482 {
0483     if (enable)
0484     {
0485         base->CTRL_1 |= PDM_CTRL_1_DBG_MASK;
0486     }
0487     else
0488     {
0489         base->CTRL_1 &= ~PDM_CTRL_1_DBG_MASK;
0490     }
0491 }
0492 
0493 /*!
0494  * @brief Enables/disables PDM interface in debug mode.
0495  *
0496  * @param base PDM base pointer
0497  * @param enable True means PDM interface is enabled debug mode, false means PDM interface is disabled after
0498  * after completing the current frame in debug mode.
0499  */
0500 static inline void PDM_EnableInDebugMode(PDM_Type *base, bool enable)
0501 {
0502     if (enable)
0503     {
0504         base->CTRL_1 |= PDM_CTRL_1_DBGE_MASK;
0505     }
0506     else
0507     {
0508         base->CTRL_1 &= ~PDM_CTRL_1_DBGE_MASK;
0509     }
0510 }
0511 
0512 /*!
0513  * @brief Enables/disables PDM interface disable/Low Leakage mode.
0514  *
0515  * @param base PDM base pointer
0516  * @param enable True means PDM interface is in disable/low leakage mode, False means PDM interface is in normal mode.
0517  */
0518 static inline void PDM_EnterLowLeakageMode(PDM_Type *base, bool enable)
0519 {
0520     if (enable)
0521     {
0522         base->CTRL_1 |= PDM_CTRL_1_MDIS_MASK;
0523     }
0524     else
0525     {
0526         base->CTRL_1 &= ~PDM_CTRL_1_MDIS_MASK;
0527     }
0528 }
0529 
0530 /*!
0531  * @brief Enables/disables the PDM channel.
0532  *
0533  * @param base PDM base pointer
0534  * @param channel PDM channel number need to enable or disable.
0535  * @param enable True means enable PDM channel, false means disable.
0536  */
0537 static inline void PDM_EnableChannel(PDM_Type *base, uint8_t channel, bool enable)
0538 {
0539     if (enable)
0540     {
0541         base->CTRL_1 |= (1UL << channel);
0542     }
0543     else
0544     {
0545         base->CTRL_1 &= ~(1UL << channel);
0546     }
0547 }
0548 
0549 /*!
0550  * @brief PDM one channel configurations.
0551  *
0552  * @param base PDM base pointer
0553  * @param config PDM channel configurations.
0554  * @param channel channel number.
0555  * after completing the current frame in debug mode.
0556  */
0557 void PDM_SetChannelConfig(PDM_Type *base, uint32_t channel, const pdm_channel_config_t *config);
0558 
0559 /*!
0560  * @brief PDM set sample rate.
0561  *
0562  * @note This function is depend on the configuration of the PDM and PDM channel, so the correct call sequence is
0563  * @code
0564  * PDM_Init(base, pdmConfig)
0565  * PDM_SetChannelConfig(base, channel, &channelConfig)
0566  * PDM_SetSampleRateConfig(base, source, sampleRate)
0567  * @endcode
0568  * @param base PDM base pointer
0569  * @param sourceClock_HZ PDM source clock frequency.
0570  * @param sampleRate_HZ PDM sample rate.
0571  */
0572 status_t PDM_SetSampleRateConfig(PDM_Type *base, uint32_t sourceClock_HZ, uint32_t sampleRate_HZ);
0573 
0574 /*!
0575  * @brief PDM set sample rate.
0576  *
0577  * @deprecated Do not use this function.  It has been superceded by @ref PDM_SetSampleRateConfig
0578  * @param base PDM base pointer
0579  * @param enableChannelMask PDM channel enable mask.
0580  * @param qualityMode quality mode.
0581  * @param osr cic oversample rate
0582  * @param clkDiv clock divider
0583  */
0584 status_t PDM_SetSampleRate(
0585     PDM_Type *base, uint32_t enableChannelMask, pdm_df_quality_mode_t qualityMode, uint8_t osr, uint32_t clkDiv);
0586 
0587 /*!
0588  * @brief Get the instance number for PDM.
0589  *
0590  * @param base PDM base pointer.
0591  */
0592 uint32_t PDM_GetInstance(PDM_Type *base);
0593 /*! @} */
0594 
0595 /*!
0596  * @name Status
0597  * @{
0598  */
0599 
0600 /*!
0601  * @brief Gets the PDM internal status flag.
0602  * Use the Status Mask in _pdm_internal_status to get the status value needed
0603  * @param base PDM base pointer
0604  * @return PDM status flag value.
0605  */
0606 static inline uint32_t PDM_GetStatus(PDM_Type *base)
0607 {
0608     return base->STAT;
0609 }
0610 
0611 /*!
0612  * @brief Gets the PDM FIFO status flag.
0613  * Use the Status Mask in _pdm_fifo_status to get the status value needed
0614  * @param base PDM base pointer
0615  * @return FIFO status.
0616  */
0617 static inline uint32_t PDM_GetFifoStatus(PDM_Type *base)
0618 {
0619     return base->FIFO_STAT;
0620 }
0621 
0622 #if defined(FSL_FEATURE_PDM_HAS_RANGE_CTRL) && FSL_FEATURE_PDM_HAS_RANGE_CTRL
0623 /*!
0624  * @brief Gets the PDM Range status flag.
0625  * Use the Status Mask in _pdm_range_status to get the status value needed
0626  * @param base PDM base pointer
0627  * @return output status.
0628  */
0629 static inline uint32_t PDM_GetRangeStatus(PDM_Type *base)
0630 {
0631     return base->RANGE_STAT;
0632 }
0633 #else
0634 /*!
0635  * @brief Gets the PDM output status flag.
0636  * Use the Status Mask in _pdm_output_status to get the status value needed
0637  * @param base PDM base pointer
0638  * @return output status.
0639  */
0640 static inline uint32_t PDM_GetOutputStatus(PDM_Type *base)
0641 {
0642     return base->OUT_STAT;
0643 }
0644 #endif
0645 
0646 /*!
0647  * @brief Clears the PDM Tx status.
0648  *
0649  * @param base PDM base pointer
0650  * @param mask State mask. It can be a combination of the status between kPDM_StatusFrequencyLow and
0651  * kPDM_StatusCh7FifoDataAvaliable.
0652  */
0653 static inline void PDM_ClearStatus(PDM_Type *base, uint32_t mask)
0654 {
0655     base->STAT = mask;
0656 }
0657 
0658 /*!
0659  * @brief Clears the PDM Tx status.
0660  *
0661  * @param base PDM base pointer
0662  * @param mask State mask.It can be a combination of the status in _pdm_fifo_status.
0663  */
0664 static inline void PDM_ClearFIFOStatus(PDM_Type *base, uint32_t mask)
0665 {
0666     base->FIFO_STAT = mask;
0667 }
0668 
0669 #if defined(FSL_FEATURE_PDM_HAS_RANGE_CTRL) && FSL_FEATURE_PDM_HAS_RANGE_CTRL
0670 /*!
0671  * @brief Clears the PDM range status.
0672  *
0673  * @param base PDM base pointer
0674  * @param mask State mask. It can be a combination of the status in _pdm_range_status.
0675  */
0676 static inline void PDM_ClearRangeStatus(PDM_Type *base, uint32_t mask)
0677 {
0678     base->RANGE_STAT = mask;
0679 }
0680 #else
0681 /*!
0682  * @brief Clears the PDM output status.
0683  *
0684  * @param base PDM base pointer
0685  * @param mask State mask. It can be a combination of the status in _pdm_output_status.
0686  */
0687 static inline void PDM_ClearOutputStatus(PDM_Type *base, uint32_t mask)
0688 {
0689     base->OUT_STAT = mask;
0690 }
0691 #endif
0692 
0693 /*! @} */
0694 
0695 /*!
0696  * @name Interrupts
0697  * @{
0698  */
0699 
0700 /*!
0701  * @brief Enables the PDM interrupt requests.
0702  *
0703  * @param base PDM base pointer
0704  * @param mask interrupt source
0705  *     The parameter can be a combination of the following sources if defined.
0706  *     @arg kPDM_ErrorInterruptEnable
0707  *     @arg kPDM_FIFOInterruptEnable
0708  */
0709 void PDM_EnableInterrupts(PDM_Type *base, uint32_t mask);
0710 
0711 /*!
0712  * @brief Disables the PDM interrupt requests.
0713  *
0714  * @param base PDM base pointer
0715  * @param mask interrupt source
0716  *     The parameter can be a combination of the following sources if defined.
0717  *     @arg kPDM_ErrorInterruptEnable
0718  *     @arg kPDM_FIFOInterruptEnable
0719  */
0720 static inline void PDM_DisableInterrupts(PDM_Type *base, uint32_t mask)
0721 {
0722     base->CTRL_1 &= ~mask;
0723 }
0724 
0725 /*! @} */
0726 
0727 /*!
0728  * @name DMA Control
0729  * @{
0730  */
0731 
0732 /*!
0733  * @brief Enables/disables the PDM DMA requests.
0734  *
0735  * @param base PDM base pointer
0736  * @param enable True means enable DMA, false means disable DMA.
0737  */
0738 static inline void PDM_EnableDMA(PDM_Type *base, bool enable)
0739 {
0740     if (enable)
0741     {
0742         base->CTRL_1 = (base->CTRL_1 & (~PDM_CTRL_1_DISEL_MASK)) | PDM_CTRL_1_DISEL(0x1U);
0743     }
0744     else
0745     {
0746         base->CTRL_1 &= ~PDM_CTRL_1_DISEL_MASK;
0747     }
0748 }
0749 
0750 /*!
0751  * @brief  Gets the PDM data register address.
0752  *
0753  * This API is used to provide a transfer address for the PDM DMA transfer configuration.
0754  *
0755  * @param base PDM base pointer.
0756  * @param channel Which data channel used.
0757  * @return data register address.
0758  */
0759 static inline uint32_t PDM_GetDataRegisterAddress(PDM_Type *base, uint32_t channel)
0760 {
0761     return (uint32_t)(&(base->DATACH)[channel]);
0762 }
0763 
0764 /*! @} */
0765 
0766 /*!
0767  * @name Bus Operations
0768  * @{
0769  */
0770 #if defined(FSL_FEATURE_PDM_FIFO_WIDTH) && (FSL_FEATURE_PDM_FIFO_WIDTH == 2U)
0771 /*!
0772  * @brief Reads data from the PDM FIFO.
0773  *
0774  * @param base PDM base pointer.
0775  * @param channel Data channel used.
0776  * @return Data in PDM FIFO.
0777  */
0778 static inline int16_t PDM_ReadData(PDM_Type *base, uint32_t channel)
0779 {
0780     return (int16_t)(base->DATACH[channel]);
0781 }
0782 
0783 /*!
0784  * @brief PDM read data non blocking.
0785  * So the actually read data byte size in this function is (size * 2 * channelNums).
0786  * @param base PDM base pointer.
0787  * @param startChannel start channel number.
0788  * @param channelNums total enabled channelnums.
0789  * @param buffer received buffer address.
0790  * @param size number of 16bit data to read.
0791  */
0792 void PDM_ReadNonBlocking(PDM_Type *base, uint32_t startChannel, uint32_t channelNums, int16_t *buffer, size_t size);
0793 #endif
0794 
0795 /*!
0796  * @brief PDM read fifo.
0797  * @note: This function support 16 bit only for IP version that only supports 16bit.
0798  *
0799  * @param base PDM base pointer.
0800  * @param startChannel start channel number.
0801  * @param channelNums total enabled channelnums.
0802  * @param buffer received buffer address.
0803  * @param size number of samples to read.
0804  * @param dataWidth sample width.
0805  */
0806 void PDM_ReadFifo(
0807     PDM_Type *base, uint32_t startChannel, uint32_t channelNums, void *buffer, size_t size, uint32_t dataWidth);
0808 
0809 #if defined(FSL_FEATURE_PDM_FIFO_WIDTH) && (FSL_FEATURE_PDM_FIFO_WIDTH == 4U)
0810 /*!
0811  * @brief Reads data from the PDM FIFO.
0812  *
0813  * @param base PDM base pointer.
0814  * @param channel Data channel used.
0815  * @return Data in PDM FIFO.
0816  */
0817 static inline uint32_t PDM_ReadData(PDM_Type *base, uint32_t channel)
0818 {
0819     return base->DATACH[channel];
0820 }
0821 #endif
0822 
0823 /*!
0824  * @brief Set the PDM channel gain.
0825  *
0826  * Please note for different quality mode, the valid gain value is different, reference RM for detail.
0827  * @param base PDM base pointer.
0828  * @param channel PDM channel index.
0829  * @param gain channel gain, the register gain value range is 0 - 15.
0830  */
0831 void PDM_SetChannelGain(PDM_Type *base, uint32_t channel, pdm_df_output_gain_t gain);
0832 
0833 #if !(defined(FSL_FEATURE_PDM_HAS_NO_HWVAD) && FSL_FEATURE_PDM_HAS_NO_HWVAD)
0834 /*! @} */
0835 
0836 /*!
0837  * @name Voice Activity Detector
0838  * @{
0839  */
0840 
0841 /*!
0842  * @brief Configure voice activity detector.
0843  *
0844  * @param base PDM base pointer
0845  * @param config Voice activity detector configure structure pointer .
0846  */
0847 void PDM_SetHwvadConfig(PDM_Type *base, const pdm_hwvad_config_t *config);
0848 
0849 /*!
0850  * @brief PDM hwvad force output disable.
0851  *
0852  * @param base PDM base pointer
0853  * @param enable true is output force disable, false is output not force.
0854  */
0855 static inline void PDM_ForceHwvadOutputDisable(PDM_Type *base, bool enable)
0856 {
0857     if (enable)
0858     {
0859         base->VAD0_CTRL_2 &= ~PDM_VAD0_CTRL_2_VADFOUTDIS_MASK;
0860     }
0861     else
0862     {
0863         base->VAD0_CTRL_2 |= PDM_VAD0_CTRL_2_VADFOUTDIS_MASK;
0864     }
0865 }
0866 
0867 /*!
0868  * @brief PDM hwvad reset.
0869  * It will reset VADNDATA register and will clean all internal buffers, should be called when the PDM isn't running.
0870  *
0871  * @param base PDM base pointer
0872  */
0873 static inline void PDM_ResetHwvad(PDM_Type *base)
0874 {
0875     base->VAD0_CTRL_1 |= PDM_VAD0_CTRL_1_VADRST_MASK;
0876 }
0877 /*!
0878  * @brief Enable/Disable Voice activity detector.
0879  * Should be called when the PDM isn't running.
0880  * @param base PDM base pointer.
0881  * @param enable True means enable voice activity detector, false means disable.
0882  */
0883 static inline void PDM_EnableHwvad(PDM_Type *base, bool enable)
0884 {
0885     if (enable)
0886     {
0887         base->VAD0_CTRL_1 |= PDM_VAD0_CTRL_1_VADEN_MASK;
0888     }
0889     else
0890     {
0891         base->VAD0_CTRL_1 &= ~PDM_VAD0_CTRL_1_VADEN_MASK;
0892     }
0893 }
0894 
0895 /*!
0896  * @brief Enables the PDM Voice Detector interrupt requests.
0897  *
0898  * @param base PDM base pointer
0899  * @param mask interrupt source
0900  *     The parameter can be a combination of the following sources if defined.
0901  *     @arg kPDM_HWVADErrorInterruptEnable
0902  *     @arg kPDM_HWVADInterruptEnable
0903  */
0904 static inline void PDM_EnableHwvadInterrupts(PDM_Type *base, uint32_t mask)
0905 {
0906     base->VAD0_CTRL_1 |= mask;
0907 }
0908 
0909 /*!
0910  * @brief Disables the PDM Voice Detector interrupt requests.
0911  *
0912  * @param base PDM base pointer
0913  * @param mask interrupt source
0914  *     The parameter can be a combination of the following sources if defined.
0915  *     @arg kPDM_HWVADErrorInterruptEnable
0916  *     @arg kPDM_HWVADInterruptEnable
0917  */
0918 static inline void PDM_DisableHwvadInterrupts(PDM_Type *base, uint32_t mask)
0919 {
0920     base->VAD0_CTRL_1 &= ~mask;
0921 }
0922 
0923 /*!
0924  * @brief Clears the PDM voice activity detector status flags.
0925  *
0926  * @param base PDM base pointer
0927  * @param mask State mask,reference _pdm_hwvad_int_status.
0928  */
0929 static inline void PDM_ClearHwvadInterruptStatusFlags(PDM_Type *base, uint32_t mask)
0930 {
0931     base->VAD0_STAT = mask;
0932 }
0933 
0934 /*!
0935  * @brief Clears the PDM voice activity detector status flags.
0936  *
0937  * @param base PDM base pointer
0938  * @return status, reference _pdm_hwvad_int_status
0939  */
0940 static inline uint32_t PDM_GetHwvadInterruptStatusFlags(PDM_Type *base)
0941 {
0942     return base->VAD0_STAT & (PDM_VAD0_STAT_VADIF_MASK | PDM_VAD0_STAT_VADINSATF_MASK);
0943 }
0944 
0945 /*!
0946  * @brief Get the PDM voice activity detector initial flags.
0947  *
0948  * @param base PDM base pointer
0949  * @return initial flag.
0950  */
0951 static inline uint32_t PDM_GetHwvadInitialFlag(PDM_Type *base)
0952 {
0953     return base->VAD0_STAT & PDM_VAD0_STAT_VADINITF_MASK;
0954 }
0955 
0956 #if !(defined(FSL_FEATURE_PDM_HAS_NO_VADEF) && (FSL_FEATURE_PDM_HAS_NO_VADEF))
0957 /*!
0958  * @brief Get the PDM voice activity detector voice detected flags.
0959  * NOte: this flag is auto cleared when voice gone.
0960  * @param base PDM base pointer
0961  * @return voice detected flag.
0962  */
0963 static inline uint32_t PDM_GetHwvadVoiceDetectedFlag(PDM_Type *base)
0964 {
0965     return base->VAD0_STAT & PDM_VAD0_STAT_VADEF_MASK;
0966 }
0967 #endif
0968 
0969 /*!
0970  * @brief Enables/disables voice activity detector signal filter.
0971  *
0972  * @param base PDM base pointer
0973  * @param enable True means enable signal filter, false means disable.
0974  */
0975 static inline void PDM_EnableHwvadSignalFilter(PDM_Type *base, bool enable)
0976 {
0977     if (enable)
0978     {
0979         base->VAD0_SCONFIG |= PDM_VAD0_SCONFIG_VADSFILEN_MASK;
0980     }
0981     else
0982     {
0983         base->VAD0_SCONFIG &= ~PDM_VAD0_SCONFIG_VADSFILEN_MASK;
0984     }
0985 }
0986 
0987 /*!
0988  * @brief Configure voice activity detector signal filter.
0989  *
0990  * @param base PDM base pointer
0991  * @param enableMaxBlock If signal maximum block enabled.
0992  * @param signalGain Gain value for the signal energy.
0993  */
0994 void PDM_SetHwvadSignalFilterConfig(PDM_Type *base, bool enableMaxBlock, uint32_t signalGain);
0995 
0996 /*!
0997  * @brief Configure voice activity detector noise filter.
0998  *
0999  * @param base PDM base pointer
1000  * @param config Voice activity detector noise filter configure structure pointer .
1001  */
1002 void PDM_SetHwvadNoiseFilterConfig(PDM_Type *base, const pdm_hwvad_noise_filter_t *config);
1003 
1004 /*!
1005  * @brief Enables/disables voice activity detector zero cross detector.
1006  *
1007  * @param base PDM base pointer
1008  * @param enable True means enable zero cross detector, false means disable.
1009  */
1010 static inline void PDM_EnableHwvadZeroCrossDetector(PDM_Type *base, bool enable)
1011 {
1012     if (enable)
1013     {
1014         base->VAD0_ZCD |= PDM_VAD0_ZCD_VADZCDEN_MASK;
1015     }
1016     else
1017     {
1018         base->VAD0_ZCD &= ~PDM_VAD0_ZCD_VADZCDEN_MASK;
1019     }
1020 }
1021 
1022 /*!
1023  * @brief Configure voice activity detector zero cross detector.
1024  *
1025  * @param base PDM base pointer
1026  * @param config Voice activity detector zero cross detector configure structure pointer .
1027  */
1028 void PDM_SetHwvadZeroCrossDetectorConfig(PDM_Type *base, const pdm_hwvad_zero_cross_detector_t *config);
1029 
1030 /*!
1031  * @brief Reads noise data.
1032  *
1033  * @param base PDM base pointer.
1034  * @return Data in PDM noise data register.
1035  */
1036 static inline uint16_t PDM_GetNoiseData(PDM_Type *base)
1037 {
1038     return (uint16_t)base->VAD0_NDATA;
1039 }
1040 
1041 /*!
1042  * @brief set hwvad internal filter status .
1043  * Note: filter initial status should be asserted for two more cycles, then set it to normal operation.
1044  * @param base PDM base pointer.
1045  * @param status internal filter status.
1046  */
1047 static inline void PDM_SetHwvadInternalFilterStatus(PDM_Type *base, pdm_hwvad_filter_status_t status)
1048 {
1049     base->VAD0_CTRL_1 = (base->VAD0_CTRL_1 & (~PDM_VAD0_CTRL_1_VADST10_MASK)) | (uint32_t)status;
1050 }
1051 
1052 /*!
1053  * @brief set HWVAD in envelope based mode .
1054  * Recommand configurations,
1055  * @code
1056  * static const pdm_hwvad_config_t hwvadConfig = {
1057  *   .channel           = 0,
1058  *   .initializeTime    = 10U,
1059  *   .cicOverSampleRate = 0U,
1060  *   .inputGain         = 0U,
1061  *   .frameTime         = 10U,
1062  *   .cutOffFreq        = kPDM_HwvadHpfBypassed,
1063  *   .enableFrameEnergy = false,
1064  *   .enablePreFilter   = true,
1065 };
1066 
1067  * static const pdm_hwvad_noise_filter_t noiseFilterConfig = {
1068  *   .enableAutoNoiseFilter = false,
1069  *   .enableNoiseMin        = true,
1070  *   .enableNoiseDecimation = true,
1071  *   .noiseFilterAdjustment = 0U,
1072  *   .noiseGain             = 7U,
1073  *   .enableNoiseDetectOR   = true,
1074  * };
1075  * @endcode
1076  * @param base PDM base pointer.
1077  * @param hwvadConfig internal filter status.
1078  * @param noiseConfig Voice activity detector noise filter configure structure pointer.
1079  * @param zcdConfig Voice activity detector zero cross detector configure structure pointer .
1080  * @param signalGain signal gain value.
1081  */
1082 void PDM_SetHwvadInEnvelopeBasedMode(PDM_Type *base,
1083                                      const pdm_hwvad_config_t *hwvadConfig,
1084                                      const pdm_hwvad_noise_filter_t *noiseConfig,
1085                                      const pdm_hwvad_zero_cross_detector_t *zcdConfig,
1086                                      uint32_t signalGain);
1087 
1088 /*!
1089  * brief set HWVAD in energy based mode .
1090  * Recommand configurations,
1091  * code
1092  * static const pdm_hwvad_config_t hwvadConfig = {
1093  *   .channel           = 0,
1094  *   .initializeTime    = 10U,
1095  *   .cicOverSampleRate = 0U,
1096  *   .inputGain         = 0U,
1097  *   .frameTime         = 10U,
1098  *   .cutOffFreq        = kPDM_HwvadHpfBypassed,
1099  *   .enableFrameEnergy = true,
1100  *   .enablePreFilter   = true,
1101 };
1102 
1103  * static const pdm_hwvad_noise_filter_t noiseFilterConfig = {
1104  *   .enableAutoNoiseFilter = true,
1105  *   .enableNoiseMin        = false,
1106  *   .enableNoiseDecimation = false,
1107  *   .noiseFilterAdjustment = 0U,
1108  *   .noiseGain             = 7U,
1109  *   .enableNoiseDetectOR   = false,
1110  * };
1111  * code
1112  * param base PDM base pointer.
1113  * param hwvadConfig internal filter status.
1114  * param noiseConfig Voice activity detector noise filter configure structure pointer.
1115  * param zcdConfig Voice activity detector zero cross detector configure structure pointer .
1116  * param signalGain signal gain value, signal gain value should be properly according to application.
1117  */
1118 void PDM_SetHwvadInEnergyBasedMode(PDM_Type *base,
1119                                    const pdm_hwvad_config_t *hwvadConfig,
1120                                    const pdm_hwvad_noise_filter_t *noiseConfig,
1121                                    const pdm_hwvad_zero_cross_detector_t *zcdConfig,
1122                                    uint32_t signalGain);
1123 
1124 /*!
1125  * @brief   Enable/Disable  hwvad callback.
1126 
1127  * This function enable/disable the hwvad interrupt for the selected PDM peripheral.
1128  *
1129  * @param base Base address of the PDM peripheral.
1130  * @param vadCallback callback Pointer to store callback function, should be NULL when disable.
1131  * @param userData user data.
1132  * @param enable true is enable, false is disable.
1133  * @retval None.
1134  */
1135 void PDM_EnableHwvadInterruptCallback(PDM_Type *base, pdm_hwvad_callback_t vadCallback, void *userData, bool enable);
1136 /*! @} */
1137 #endif
1138 
1139 /*!
1140  * @name Transactional
1141  * @{
1142  */
1143 
1144 /*!
1145  * @brief Initializes the PDM handle.
1146  *
1147  * This function initializes the handle for the PDM transactional APIs. Call
1148  * this function once to get the handle initialized.
1149  *
1150  * @param base PDM base pointer.
1151  * @param handle PDM handle pointer.
1152  * @param callback Pointer to the user callback function.
1153  * @param userData User parameter passed to the callback function.
1154  */
1155 void PDM_TransferCreateHandle(PDM_Type *base, pdm_handle_t *handle, pdm_transfer_callback_t callback, void *userData);
1156 
1157 /*!
1158  * @brief PDM set channel transfer config.
1159  *
1160  * @param base PDM base pointer.
1161  * @param handle PDM handle pointer.
1162  * @param channel PDM channel.
1163  * @param config channel config.
1164  * @param format data format, support data width configurations,_pdm_data_width.
1165  * @retval kStatus_PDM_ChannelConfig_Failed or kStatus_Success.
1166  */
1167 status_t PDM_TransferSetChannelConfig(
1168     PDM_Type *base, pdm_handle_t *handle, uint32_t channel, const pdm_channel_config_t *config, uint32_t format);
1169 
1170 /*!
1171  * @brief Performs an interrupt non-blocking receive transfer on PDM.
1172  *
1173  * @note This API returns immediately after the transfer initiates.
1174  * Call the PDM_RxGetTransferStatusIRQ to poll the transfer status and check whether
1175  * the transfer is finished. If the return status is not kStatus_PDM_Busy, the transfer
1176  * is finished.
1177  *
1178  * @param base PDM base pointer
1179  * @param handle Pointer to the pdm_handle_t structure which stores the transfer state.
1180  * @param xfer Pointer to the pdm_transfer_t structure.
1181  * @retval kStatus_Success Successfully started the data receive.
1182  * @retval kStatus_PDM_Busy Previous receive still not finished.
1183  */
1184 status_t PDM_TransferReceiveNonBlocking(PDM_Type *base, pdm_handle_t *handle, pdm_transfer_t *xfer);
1185 
1186 /*!
1187  * @brief Aborts the current IRQ receive.
1188  *
1189  * @note This API can be called when an interrupt non-blocking transfer initiates
1190  * to abort the transfer early.
1191  *
1192  * @param base PDM base pointer
1193  * @param handle Pointer to the pdm_handle_t structure which stores the transfer state.
1194  */
1195 void PDM_TransferAbortReceive(PDM_Type *base, pdm_handle_t *handle);
1196 
1197 /*!
1198  * @brief Tx interrupt handler.
1199  *
1200  * @param base PDM base pointer.
1201  * @param handle Pointer to the pdm_handle_t structure.
1202  */
1203 void PDM_TransferHandleIRQ(PDM_Type *base, pdm_handle_t *handle);
1204 
1205 /*! @} */
1206 
1207 #if defined(__cplusplus)
1208 }
1209 #endif /*_cplusplus*/
1210 
1211 /*! @} */
1212 
1213 #endif /* _FSL_PDM_H_ */