File indexing completed on 2025-05-11 08:23:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _FSL_PDM_H_
0010 #define _FSL_PDM_H_
0011
0012 #include "fsl_common.h"
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #define FSL_PDM_DRIVER_VERSION (MAKE_VERSION(2, 8, 0))
0026
0027
0028
0029 #define PDM_XFER_QUEUE_SIZE (4U)
0030
0031
0032 enum
0033 {
0034 kStatus_PDM_Busy = MAKE_STATUS(kStatusGroup_PDM, 0),
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),
0037 #endif
0038 kStatus_PDM_FIFO_ERROR = MAKE_STATUS(kStatusGroup_PDM, 2),
0039 kStatus_PDM_QueueFull = MAKE_STATUS(kStatusGroup_PDM, 3),
0040 kStatus_PDM_Idle = MAKE_STATUS(kStatusGroup_PDM, 4),
0041 kStatus_PDM_Output_ERROR = MAKE_STATUS(kStatusGroup_PDM, 5),
0042 kStatus_PDM_ChannelConfig_Failed = MAKE_STATUS(kStatusGroup_PDM, 6),
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),
0045 kStatus_PDM_HWVAD_Error = MAKE_STATUS(kStatusGroup_PDM, 8),
0046 #endif
0047 };
0048
0049
0050 enum _pdm_interrupt_enable
0051 {
0052 kPDM_ErrorInterruptEnable = PDM_CTRL_1_ERREN_MASK,
0053 kPDM_FIFOInterruptEnable = PDM_CTRL_1_DISEL(2U),
0054 };
0055
0056
0057 enum _pdm_internal_status
0058 {
0059 kPDM_StatusDfBusyFlag = (int)PDM_STAT_BSY_FIL_MASK,
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,
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,
0065 #endif
0066 kPDM_StatusCh0FifoDataAvaliable = PDM_STAT_CH0F_MASK,
0067 kPDM_StatusCh1FifoDataAvaliable = PDM_STAT_CH1F_MASK,
0068 kPDM_StatusCh2FifoDataAvaliable = PDM_STAT_CH2F_MASK,
0069 kPDM_StatusCh3FifoDataAvaliable = PDM_STAT_CH3F_MASK,
0070 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0071 kPDM_StatusCh4FifoDataAvaliable = PDM_STAT_CH4F_MASK,
0072 kPDM_StatusCh5FifoDataAvaliable = PDM_STAT_CH5F_MASK,
0073 kPDM_StatusCh6FifoDataAvaliable = PDM_STAT_CH6F_MASK,
0074 kPDM_StatusCh7FifoDataAvaliable = PDM_STAT_CH7F_MASK,
0075 #endif
0076 };
0077
0078
0079 enum _pdm_channel_enable_mask
0080 {
0081 kPDM_EnableChannel0 = PDM_STAT_CH0F_MASK,
0082 kPDM_EnableChannel1 = PDM_STAT_CH1F_MASK,
0083 kPDM_EnableChannel2 = PDM_STAT_CH2F_MASK,
0084 kPDM_EnableChannel3 = PDM_STAT_CH3F_MASK,
0085 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0086 kPDM_EnableChannel4 = PDM_STAT_CH4F_MASK,
0087 kPDM_EnableChannel5 = PDM_STAT_CH5F_MASK,
0088 kPDM_EnableChannel6 = PDM_STAT_CH6F_MASK,
0089 kPDM_EnableChannel7 = PDM_STAT_CH7F_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
0099 enum _pdm_fifo_status
0100 {
0101 kPDM_FifoStatusUnderflowCh0 = PDM_FIFO_STAT_FIFOUND0_MASK,
0102 kPDM_FifoStatusUnderflowCh1 = PDM_FIFO_STAT_FIFOUND1_MASK,
0103 kPDM_FifoStatusUnderflowCh2 = PDM_FIFO_STAT_FIFOUND2_MASK,
0104 kPDM_FifoStatusUnderflowCh3 = PDM_FIFO_STAT_FIFOUND3_MASK,
0105 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0106 kPDM_FifoStatusUnderflowCh4 = PDM_FIFO_STAT_FIFOUND4_MASK,
0107 kPDM_FifoStatusUnderflowCh5 = PDM_FIFO_STAT_FIFOUND5_MASK,
0108 kPDM_FifoStatusUnderflowCh6 = PDM_FIFO_STAT_FIFOUND6_MASK,
0109 kPDM_FifoStatusUnderflowCh7 = PDM_FIFO_STAT_FIFOUND6_MASK,
0110 #endif
0111
0112 kPDM_FifoStatusOverflowCh0 = PDM_FIFO_STAT_FIFOOVF0_MASK,
0113 kPDM_FifoStatusOverflowCh1 = PDM_FIFO_STAT_FIFOOVF1_MASK,
0114 kPDM_FifoStatusOverflowCh2 = PDM_FIFO_STAT_FIFOOVF2_MASK,
0115 kPDM_FifoStatusOverflowCh3 = PDM_FIFO_STAT_FIFOOVF3_MASK,
0116 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0117 kPDM_FifoStatusOverflowCh4 = PDM_FIFO_STAT_FIFOOVF4_MASK,
0118 kPDM_FifoStatusOverflowCh5 = PDM_FIFO_STAT_FIFOOVF5_MASK,
0119 kPDM_FifoStatusOverflowCh6 = PDM_FIFO_STAT_FIFOOVF6_MASK,
0120 kPDM_FifoStatusOverflowCh7 = PDM_FIFO_STAT_FIFOOVF7_MASK,
0121 #endif
0122 };
0123
0124 #if defined(FSL_FEATURE_PDM_HAS_RANGE_CTRL) && FSL_FEATURE_PDM_HAS_RANGE_CTRL
0125
0126 enum _pdm_range_status
0127 {
0128 kPDM_RangeStatusUnderFlowCh0 = PDM_RANGE_STAT_RANGEUNF0_MASK,
0129 kPDM_RangeStatusUnderFlowCh1 = PDM_RANGE_STAT_RANGEUNF1_MASK,
0130 kPDM_RangeStatusUnderFlowCh2 = PDM_RANGE_STAT_RANGEUNF2_MASK,
0131 kPDM_RangeStatusUnderFlowCh3 = PDM_RANGE_STAT_RANGEUNF3_MASK,
0132 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0133 kPDM_RangeStatusUnderFlowCh4 = PDM_RANGE_STAT_RANGEUNF4_MASK,
0134 kPDM_RangeStatusUnderFlowCh5 = PDM_RANGE_STAT_RANGEUNF5_MASK,
0135 kPDM_RangeStatusUnderFlowCh6 = PDM_RANGE_STAT_RANGEUNF6_MASK,
0136 kPDM_RangeStatusUnderFlowCh7 = PDM_RANGE_STAT_RANGEUNF7_MASK,
0137 #endif
0138 kPDM_RangeStatusOverFlowCh0 = PDM_RANGE_STAT_RANGEOVF0_MASK,
0139 kPDM_RangeStatusOverFlowCh1 = PDM_RANGE_STAT_RANGEOVF1_MASK,
0140 kPDM_RangeStatusOverFlowCh2 = PDM_RANGE_STAT_RANGEOVF2_MASK,
0141 kPDM_RangeStatusOverFlowCh3 = PDM_RANGE_STAT_RANGEOVF3_MASK,
0142 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0143 kPDM_RangeStatusOverFlowCh4 = PDM_RANGE_STAT_RANGEOVF4_MASK,
0144 kPDM_RangeStatusOverFlowCh5 = PDM_RANGE_STAT_RANGEOVF5_MASK,
0145 kPDM_RangeStatusOverFlowCh6 = PDM_RANGE_STAT_RANGEOVF6_MASK,
0146 kPDM_RangeStatusOverFlowCh7 = PDM_RANGE_STAT_RANGEOVF7_MASK,
0147 #endif
0148 };
0149 #else
0150
0151 enum _pdm_output_status
0152 {
0153 kPDM_OutputStatusUnderFlowCh0 = PDM_OUT_STAT_OUTUNF0_MASK,
0154 kPDM_OutputStatusUnderFlowCh1 = PDM_OUT_STAT_OUTUNF1_MASK,
0155 kPDM_OutputStatusUnderFlowCh2 = PDM_OUT_STAT_OUTUNF2_MASK,
0156 kPDM_OutputStatusUnderFlowCh3 = PDM_OUT_STAT_OUTUNF3_MASK,
0157 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0158 kPDM_OutputStatusUnderFlowCh4 = PDM_OUT_STAT_OUTUNF4_MASK,
0159 kPDM_OutputStatusUnderFlowCh5 = PDM_OUT_STAT_OUTUNF5_MASK,
0160 kPDM_OutputStatusUnderFlowCh6 = PDM_OUT_STAT_OUTUNF6_MASK,
0161 kPDM_OutputStatusUnderFlowCh7 = PDM_OUT_STAT_OUTUNF7_MASK,
0162 #endif
0163 kPDM_OutputStatusOverFlowCh0 = PDM_OUT_STAT_OUTOVF0_MASK,
0164 kPDM_OutputStatusOverFlowCh1 = PDM_OUT_STAT_OUTOVF1_MASK,
0165 kPDM_OutputStatusOverFlowCh2 = PDM_OUT_STAT_OUTOVF2_MASK,
0166 kPDM_OutputStatusOverFlowCh3 = PDM_OUT_STAT_OUTOVF3_MASK,
0167 #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
0168 kPDM_OutputStatusOverFlowCh4 = PDM_OUT_STAT_OUTOVF4_MASK,
0169 kPDM_OutputStatusOverFlowCh5 = PDM_OUT_STAT_OUTOVF5_MASK,
0170 kPDM_OutputStatusOverFlowCh6 = PDM_OUT_STAT_OUTOVF6_MASK,
0171 kPDM_OutputStatusOverFlowCh7 = PDM_OUT_STAT_OUTOVF7_MASK,
0172 #endif
0173 };
0174 #endif
0175
0176 #if (defined(FSL_FEATURE_PDM_HAS_DC_OUT_CTRL) && (FSL_FEATURE_PDM_HAS_DC_OUT_CTRL))
0177
0178 typedef enum _pdm_dc_remover
0179 {
0180 kPDM_DcRemoverCutOff20Hz = 0U,
0181 kPDM_DcRemoverCutOff13Hz = 1U,
0182 kPDM_DcRemoverCutOff40Hz = 2U,
0183 kPDM_DcRemoverBypass = 3U,
0184 } pdm_dc_remover_t;
0185 #else
0186
0187 typedef enum _pdm_dc_remover
0188 {
0189 kPDM_DcRemoverCutOff21Hz = 0U,
0190 kPDM_DcRemoverCutOff83Hz = 1U,
0191 kPDM_DcRemoverCutOff152Hz = 2U,
0192 kPDM_DcRemoverBypass = 3U,
0193 } pdm_dc_remover_t;
0194 #endif
0195
0196
0197 typedef enum _pdm_df_quality_mode
0198 {
0199 kPDM_QualityModeMedium = 0U,
0200 kPDM_QualityModeHigh = 1U,
0201 kPDM_QualityModeLow = 7U,
0202 kPDM_QualityModeVeryLow0 = 6U,
0203 kPDM_QualityModeVeryLow1 = 5U,
0204 kPDM_QualityModeVeryLow2 = 4U,
0205 } pdm_df_quality_mode_t;
0206
0207
0208 enum _pdm_qulaity_mode_k_factor
0209 {
0210 kPDM_QualityModeHighKFactor = 1U,
0211 kPDM_QualityModeMediumKFactor = 2U,
0212 kPDM_QualityModeLowKFactor = 4U,
0213 kPDM_QualityModeVeryLow2KFactor = 8U,
0214 };
0215
0216
0217 typedef enum _pdm_df_output_gain
0218 {
0219 kPDM_DfOutputGain0 = 0U,
0220 kPDM_DfOutputGain1 = 1U,
0221 kPDM_DfOutputGain2 = 2U,
0222 kPDM_DfOutputGain3 = 3U,
0223 kPDM_DfOutputGain4 = 4U,
0224 kPDM_DfOutputGain5 = 5U,
0225 kPDM_DfOutputGain6 = 6U,
0226 kPDM_DfOutputGain7 = 7U,
0227 kPDM_DfOutputGain8 = 8U,
0228 kPDM_DfOutputGain9 = 9U,
0229 kPDM_DfOutputGain10 = 0xAU,
0230 kPDM_DfOutputGain11 = 0xBU,
0231 kPDM_DfOutputGain12 = 0xCU,
0232 kPDM_DfOutputGain13 = 0xDU,
0233 kPDM_DfOutputGain14 = 0xEU,
0234 kPDM_DfOutputGain15 = 0xFU,
0235 } pdm_df_output_gain_t;
0236
0237
0238 enum _pdm_data_width
0239 {
0240 #if defined(FSL_FEATURE_PDM_FIFO_WIDTH) && (FSL_FEATURE_PDM_FIFO_WIDTH != 2U)
0241 kPDM_DataWwidth24 = 3U,
0242 kPDM_DataWwidth32 = 4U,
0243 #else
0244 kPDM_DataWdith16 = 2U,
0245 #endif
0246 };
0247
0248
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;
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;
0257 #endif
0258
0259 pdm_df_output_gain_t gain;
0260 } pdm_channel_config_t;
0261
0262
0263 typedef struct _pdm_config
0264 {
0265 bool
0266 enableDoze;
0267 uint8_t fifoWatermark;
0268 pdm_df_quality_mode_t qualityMode;
0269 uint8_t cicOverSampleRate;
0270 } pdm_config_t;
0271
0272 #if !(defined(FSL_FEATURE_PDM_HAS_NO_HWVAD) && FSL_FEATURE_PDM_HAS_NO_HWVAD)
0273
0274 enum _pdm_hwvad_interrupt_enable
0275 {
0276 kPDM_HwvadErrorInterruptEnable = PDM_VAD0_CTRL_1_VADERIE_MASK,
0277 kPDM_HwvadInterruptEnable = PDM_VAD0_CTRL_1_VADIE_MASK,
0278 };
0279
0280
0281 enum _pdm_hwvad_int_status
0282 {
0283 kPDM_HwvadStatusInputSaturation = PDM_VAD0_STAT_VADINSATF_MASK,
0284 kPDM_HwvadStatusVoiceDetectFlag = PDM_VAD0_STAT_VADIF_MASK,
0285 };
0286
0287
0288 typedef enum _pdm_hwvad_hpf_config
0289 {
0290 kPDM_HwvadHpfBypassed = 0x0U,
0291 kPDM_HwvadHpfCutOffFreq1750Hz = 0x1U,
0292 kPDM_HwvadHpfCutOffFreq215Hz = 0x2U,
0293 kPDM_HwvadHpfCutOffFreq102Hz = 0x3U,
0294 } pdm_hwvad_hpf_config_t;
0295
0296
0297 typedef enum _pdm_hwvad_filter_status
0298 {
0299 kPDM_HwvadInternalFilterNormalOperation = 0U,
0300 kPDM_HwvadInternalFilterInitial = PDM_VAD0_CTRL_1_VADST10_MASK,
0301 } pdm_hwvad_filter_status_t;
0302
0303
0304 typedef struct _pdm_hwvad_config
0305 {
0306 uint8_t channel;
0307 uint8_t initializeTime;
0308 uint8_t cicOverSampleRate;
0309
0310 uint8_t inputGain;
0311 uint32_t frameTime;
0312 pdm_hwvad_hpf_config_t cutOffFreq;
0313 bool enableFrameEnergy;
0314 bool enablePreFilter;
0315 } pdm_hwvad_config_t;
0316
0317
0318 typedef struct _pdm_hwvad_noise_filter
0319 {
0320 bool enableAutoNoiseFilter;
0321 bool enableNoiseMin;
0322 bool enableNoiseDecimation;
0323 bool enableNoiseDetectOR;
0324 uint32_t noiseFilterAdjustment;
0325 uint32_t noiseGain;
0326 } pdm_hwvad_noise_filter_t;
0327
0328
0329 typedef enum _pdm_hwvad_zcd_result
0330 {
0331 kPDM_HwvadResultOREnergyBasedDetection =
0332 0U,
0333 kPDM_HwvadResultANDEnergyBasedDetection =
0334 1U,
0335 } pdm_hwvad_zcd_result_t;
0336
0337
0338 typedef struct _pdm_hwvad_zero_cross_detector
0339 {
0340 bool enableAutoThreshold;
0341 pdm_hwvad_zcd_result_t zcdAnd;
0342 uint32_t threshold;
0343 uint32_t adjustmentThreshold;
0344 } pdm_hwvad_zero_cross_detector_t;
0345 #endif
0346
0347
0348 typedef struct _pdm_transfer
0349 {
0350 volatile uint8_t *data;
0351 volatile size_t dataSize;
0352 } pdm_transfer_t;
0353
0354
0355 typedef struct _pdm_handle pdm_handle_t;
0356
0357
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
0362 typedef void (*pdm_hwvad_callback_t)(status_t status, void *userData);
0363
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
0372 struct _pdm_handle
0373 {
0374 uint32_t state;
0375 pdm_transfer_callback_t callback;
0376 void *userData;
0377
0378 pdm_transfer_t pdmQueue[PDM_XFER_QUEUE_SIZE];
0379 size_t transferSize[PDM_XFER_QUEUE_SIZE];
0380 volatile uint8_t queueUser;
0381 volatile uint8_t queueDriver;
0382
0383 uint32_t format;
0384 uint8_t watermark;
0385 uint8_t startChannel;
0386 uint8_t channelNums;
0387 };
0388
0389
0390
0391
0392
0393 #if defined(__cplusplus)
0394 extern "C" {
0395 #endif
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416 void PDM_Init(PDM_Type *base, const pdm_config_t *config);
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426 void PDM_Deinit(PDM_Type *base);
0427
0428
0429
0430
0431
0432
0433 static inline void PDM_Reset(PDM_Type *base)
0434 {
0435 base->CTRL_1 |= PDM_CTRL_1_SRES_MASK;
0436 }
0437
0438
0439
0440
0441
0442
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
0458
0459
0460
0461
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
0477
0478
0479
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
0495
0496
0497
0498
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
0514
0515
0516
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
0532
0533
0534
0535
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
0551
0552
0553
0554
0555
0556
0557 void PDM_SetChannelConfig(PDM_Type *base, uint32_t channel, const pdm_channel_config_t *config);
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 status_t PDM_SetSampleRateConfig(PDM_Type *base, uint32_t sourceClock_HZ, uint32_t sampleRate_HZ);
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
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
0589
0590
0591
0592 uint32_t PDM_GetInstance(PDM_Type *base);
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606 static inline uint32_t PDM_GetStatus(PDM_Type *base)
0607 {
0608 return base->STAT;
0609 }
0610
0611
0612
0613
0614
0615
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
0625
0626
0627
0628
0629 static inline uint32_t PDM_GetRangeStatus(PDM_Type *base)
0630 {
0631 return base->RANGE_STAT;
0632 }
0633 #else
0634
0635
0636
0637
0638
0639
0640 static inline uint32_t PDM_GetOutputStatus(PDM_Type *base)
0641 {
0642 return base->OUT_STAT;
0643 }
0644 #endif
0645
0646
0647
0648
0649
0650
0651
0652
0653 static inline void PDM_ClearStatus(PDM_Type *base, uint32_t mask)
0654 {
0655 base->STAT = mask;
0656 }
0657
0658
0659
0660
0661
0662
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
0672
0673
0674
0675
0676 static inline void PDM_ClearRangeStatus(PDM_Type *base, uint32_t mask)
0677 {
0678 base->RANGE_STAT = mask;
0679 }
0680 #else
0681
0682
0683
0684
0685
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
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709 void PDM_EnableInterrupts(PDM_Type *base, uint32_t mask);
0710
0711
0712
0713
0714
0715
0716
0717
0718
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
0729
0730
0731
0732
0733
0734
0735
0736
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
0752
0753
0754
0755
0756
0757
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
0768
0769
0770 #if defined(FSL_FEATURE_PDM_FIFO_WIDTH) && (FSL_FEATURE_PDM_FIFO_WIDTH == 2U)
0771
0772
0773
0774
0775
0776
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
0785
0786
0787
0788
0789
0790
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
0797
0798
0799
0800
0801
0802
0803
0804
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
0812
0813
0814
0815
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
0825
0826
0827
0828
0829
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
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847 void PDM_SetHwvadConfig(PDM_Type *base, const pdm_hwvad_config_t *config);
0848
0849
0850
0851
0852
0853
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
0869
0870
0871
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
0879
0880
0881
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
0897
0898
0899
0900
0901
0902
0903
0904 static inline void PDM_EnableHwvadInterrupts(PDM_Type *base, uint32_t mask)
0905 {
0906 base->VAD0_CTRL_1 |= mask;
0907 }
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918 static inline void PDM_DisableHwvadInterrupts(PDM_Type *base, uint32_t mask)
0919 {
0920 base->VAD0_CTRL_1 &= ~mask;
0921 }
0922
0923
0924
0925
0926
0927
0928
0929 static inline void PDM_ClearHwvadInterruptStatusFlags(PDM_Type *base, uint32_t mask)
0930 {
0931 base->VAD0_STAT = mask;
0932 }
0933
0934
0935
0936
0937
0938
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
0947
0948
0949
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
0959
0960
0961
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
0971
0972
0973
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
0989
0990
0991
0992
0993
0994 void PDM_SetHwvadSignalFilterConfig(PDM_Type *base, bool enableMaxBlock, uint32_t signalGain);
0995
0996
0997
0998
0999
1000
1001
1002 void PDM_SetHwvadNoiseFilterConfig(PDM_Type *base, const pdm_hwvad_noise_filter_t *config);
1003
1004
1005
1006
1007
1008
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
1024
1025
1026
1027
1028 void PDM_SetHwvadZeroCrossDetectorConfig(PDM_Type *base, const pdm_hwvad_zero_cross_detector_t *config);
1029
1030
1031
1032
1033
1034
1035
1036 static inline uint16_t PDM_GetNoiseData(PDM_Type *base)
1037 {
1038 return (uint16_t)base->VAD0_NDATA;
1039 }
1040
1041
1042
1043
1044
1045
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
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
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
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
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
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135 void PDM_EnableHwvadInterruptCallback(PDM_Type *base, pdm_hwvad_callback_t vadCallback, void *userData, bool enable);
1136
1137 #endif
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 void PDM_TransferCreateHandle(PDM_Type *base, pdm_handle_t *handle, pdm_transfer_callback_t callback, void *userData);
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
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
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184 status_t PDM_TransferReceiveNonBlocking(PDM_Type *base, pdm_handle_t *handle, pdm_transfer_t *xfer);
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195 void PDM_TransferAbortReceive(PDM_Type *base, pdm_handle_t *handle);
1196
1197
1198
1199
1200
1201
1202
1203 void PDM_TransferHandleIRQ(PDM_Type *base, pdm_handle_t *handle);
1204
1205
1206
1207 #if defined(__cplusplus)
1208 }
1209 #endif
1210
1211
1212
1213 #endif