fsl_pdm.h 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191
  1. /*
  2. * Copyright (c) 2018, Freescale Semiconductor, Inc.
  3. * Copyright 2019-2020 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #ifndef _FSL_PDM_H_
  9. #define _FSL_PDM_H_
  10. #include "fsl_common.h"
  11. /*!
  12. * @addtogroup pdm_driver PDM Driver
  13. * @{
  14. */
  15. /*******************************************************************************
  16. * Definitions
  17. ******************************************************************************/
  18. /*! @name Driver version */
  19. /*@{*/
  20. #define FSL_PDM_DRIVER_VERSION (MAKE_VERSION(2, 7, 0)) /*!< Version 2.7.0 */
  21. /*@}*/
  22. /*! @brief PDM XFER QUEUE SIZE */
  23. #define PDM_XFER_QUEUE_SIZE (4U)
  24. /*! @brief PDM return status*/
  25. enum
  26. {
  27. kStatus_PDM_Busy = MAKE_STATUS(kStatusGroup_PDM, 0), /*!< PDM is busy. */
  28. #if (defined(FSL_FEATURE_PDM_HAS_STATUS_LOW_FREQ) && (FSL_FEATURE_PDM_HAS_STATUS_LOW_FREQ == 1U))
  29. kStatus_PDM_CLK_LOW = MAKE_STATUS(kStatusGroup_PDM, 1), /*!< PDM clock frequency low */
  30. #endif
  31. kStatus_PDM_FIFO_ERROR = MAKE_STATUS(kStatusGroup_PDM, 2), /*!< PDM FIFO underrun or overflow */
  32. kStatus_PDM_QueueFull = MAKE_STATUS(kStatusGroup_PDM, 3), /*!< PDM FIFO underrun or overflow */
  33. kStatus_PDM_Idle = MAKE_STATUS(kStatusGroup_PDM, 4), /*!< PDM is idle */
  34. kStatus_PDM_Output_ERROR = MAKE_STATUS(kStatusGroup_PDM, 5), /*!< PDM is output error */
  35. kStatus_PDM_ChannelConfig_Failed = MAKE_STATUS(kStatusGroup_PDM, 6), /*!< PDM channel config failed */
  36. kStatus_PDM_HWVAD_VoiceDetected = MAKE_STATUS(kStatusGroup_PDM, 7), /*!< PDM hwvad voice detected */
  37. kStatus_PDM_HWVAD_Error = MAKE_STATUS(kStatusGroup_PDM, 8), /*!< PDM hwvad error */
  38. };
  39. /*! @brief The PDM interrupt enable flag */
  40. enum _pdm_interrupt_enable
  41. {
  42. kPDM_ErrorInterruptEnable = PDM_CTRL_1_ERREN_MASK, /*!< PDM channel error interrupt enable. */
  43. kPDM_FIFOInterruptEnable = PDM_CTRL_1_DISEL(2U), /*!< PDM channel FIFO interrupt */
  44. };
  45. /*! @brief The PDM status */
  46. enum _pdm_internal_status
  47. {
  48. kPDM_StatusDfBusyFlag = (int)PDM_STAT_BSY_FIL_MASK, /*!< Decimation filter is busy processing data */
  49. kPDM_StatusFIRFilterReady = PDM_STAT_FIR_RDY_MASK, /*!< FIR filter data is ready */
  50. #if (defined(FSL_FEATURE_PDM_HAS_STATUS_LOW_FREQ) && (FSL_FEATURE_PDM_HAS_STATUS_LOW_FREQ == 1U))
  51. kPDM_StatusFrequencyLow = PDM_STAT_LOWFREQF_MASK, /*!< Mic app clock frequency not high enough */
  52. #endif
  53. kPDM_StatusCh0FifoDataAvaliable = PDM_STAT_CH0F_MASK, /*!< channel 0 fifo data reached watermark level */
  54. kPDM_StatusCh1FifoDataAvaliable = PDM_STAT_CH1F_MASK, /*!< channel 1 fifo data reached watermark level */
  55. kPDM_StatusCh2FifoDataAvaliable = PDM_STAT_CH2F_MASK, /*!< channel 2 fifo data reached watermark level */
  56. kPDM_StatusCh3FifoDataAvaliable = PDM_STAT_CH3F_MASK, /*!< channel 3 fifo data reached watermark level */
  57. #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
  58. kPDM_StatusCh4FifoDataAvaliable = PDM_STAT_CH4F_MASK, /*!< channel 4 fifo data reached watermark level */
  59. kPDM_StatusCh5FifoDataAvaliable = PDM_STAT_CH5F_MASK, /*!< channel 5 fifo data reached watermark level */
  60. kPDM_StatusCh6FifoDataAvaliable = PDM_STAT_CH6F_MASK, /*!< channel 6 fifo data reached watermark level */
  61. kPDM_StatusCh7FifoDataAvaliable = PDM_STAT_CH7F_MASK, /*!< channel 7 fifo data reached watermark level */
  62. #endif
  63. };
  64. /*! @brief PDM channel enable mask */
  65. enum _pdm_channel_enable_mask
  66. {
  67. kPDM_EnableChannel0 = PDM_STAT_CH0F_MASK, /*!< channgel 0 enable mask */
  68. kPDM_EnableChannel1 = PDM_STAT_CH1F_MASK, /*!< channgel 1 enable mask */
  69. kPDM_EnableChannel2 = PDM_STAT_CH2F_MASK, /*!< channgel 2 enable mask */
  70. kPDM_EnableChannel3 = PDM_STAT_CH3F_MASK, /*!< channgel 3 enable mask */
  71. #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
  72. kPDM_EnableChannel4 = PDM_STAT_CH4F_MASK, /*!< channgel 4 enable mask */
  73. kPDM_EnableChannel5 = PDM_STAT_CH5F_MASK, /*!< channgel 5 enable mask */
  74. kPDM_EnableChannel6 = PDM_STAT_CH6F_MASK, /*!< channgel 6 enable mask */
  75. kPDM_EnableChannel7 = PDM_STAT_CH7F_MASK, /*!< channgel 7 enable mask */
  76. kPDM_EnableChannelAll = kPDM_EnableChannel0 | kPDM_EnableChannel1 | kPDM_EnableChannel2 | kPDM_EnableChannel3 |
  77. kPDM_EnableChannel4 | kPDM_EnableChannel5 | kPDM_EnableChannel6 | kPDM_EnableChannel7,
  78. #else
  79. kPDM_EnableChannelAll = kPDM_EnableChannel0 | kPDM_EnableChannel1 | kPDM_EnableChannel2 | kPDM_EnableChannel3,
  80. #endif
  81. };
  82. /*! @brief The PDM fifo status */
  83. enum _pdm_fifo_status
  84. {
  85. kPDM_FifoStatusUnderflowCh0 = PDM_FIFO_STAT_FIFOUND0_MASK, /*!< channel0 fifo status underflow */
  86. kPDM_FifoStatusUnderflowCh1 = PDM_FIFO_STAT_FIFOUND1_MASK, /*!< channel1 fifo status underflow */
  87. kPDM_FifoStatusUnderflowCh2 = PDM_FIFO_STAT_FIFOUND2_MASK, /*!< channel2 fifo status underflow */
  88. kPDM_FifoStatusUnderflowCh3 = PDM_FIFO_STAT_FIFOUND3_MASK, /*!< channel3 fifo status underflow */
  89. #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
  90. kPDM_FifoStatusUnderflowCh4 = PDM_FIFO_STAT_FIFOUND4_MASK, /*!< channel4 fifo status underflow */
  91. kPDM_FifoStatusUnderflowCh5 = PDM_FIFO_STAT_FIFOUND5_MASK, /*!< channel5 fifo status underflow */
  92. kPDM_FifoStatusUnderflowCh6 = PDM_FIFO_STAT_FIFOUND6_MASK, /*!< channel6 fifo status underflow */
  93. kPDM_FifoStatusUnderflowCh7 = PDM_FIFO_STAT_FIFOUND6_MASK, /*!< channel7 fifo status underflow */
  94. #endif
  95. kPDM_FifoStatusOverflowCh0 = PDM_FIFO_STAT_FIFOOVF0_MASK, /*!< channel0 fifo status overflow */
  96. kPDM_FifoStatusOverflowCh1 = PDM_FIFO_STAT_FIFOOVF1_MASK, /*!< channel1 fifo status overflow */
  97. kPDM_FifoStatusOverflowCh2 = PDM_FIFO_STAT_FIFOOVF2_MASK, /*!< channel2 fifo status overflow */
  98. kPDM_FifoStatusOverflowCh3 = PDM_FIFO_STAT_FIFOOVF3_MASK, /*!< channel3 fifo status overflow */
  99. #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
  100. kPDM_FifoStatusOverflowCh4 = PDM_FIFO_STAT_FIFOOVF4_MASK, /*!< channel4 fifo status overflow */
  101. kPDM_FifoStatusOverflowCh5 = PDM_FIFO_STAT_FIFOOVF5_MASK, /*!< channel5 fifo status overflow */
  102. kPDM_FifoStatusOverflowCh6 = PDM_FIFO_STAT_FIFOOVF6_MASK, /*!< channel6 fifo status overflow */
  103. kPDM_FifoStatusOverflowCh7 = PDM_FIFO_STAT_FIFOOVF7_MASK, /*!< channel7 fifo status overflow */
  104. #endif
  105. };
  106. #if defined(FSL_FEATURE_PDM_HAS_RANGE_CTRL) && FSL_FEATURE_PDM_HAS_RANGE_CTRL
  107. /*! @brief The PDM output status */
  108. enum _pdm_range_status
  109. {
  110. kPDM_RangeStatusUnderFlowCh0 = PDM_RANGE_STAT_RANGEUNF0_MASK, /*!< channel0 range status underflow */
  111. kPDM_RangeStatusUnderFlowCh1 = PDM_RANGE_STAT_RANGEUNF1_MASK, /*!< channel1 range status underflow */
  112. kPDM_RangeStatusUnderFlowCh2 = PDM_RANGE_STAT_RANGEUNF2_MASK, /*!< channel2 range status underflow */
  113. kPDM_RangeStatusUnderFlowCh3 = PDM_RANGE_STAT_RANGEUNF3_MASK, /*!< channel3 range status underflow */
  114. #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
  115. kPDM_RangeStatusUnderFlowCh4 = PDM_RANGE_STAT_RANGEUNF4_MASK, /*!< channel4 range status underflow */
  116. kPDM_RangeStatusUnderFlowCh5 = PDM_RANGE_STAT_RANGEUNF5_MASK, /*!< channel5 range status underflow */
  117. kPDM_RangeStatusUnderFlowCh6 = PDM_RANGE_STAT_RANGEUNF6_MASK, /*!< channel6 range status underflow */
  118. kPDM_RangeStatusUnderFlowCh7 = PDM_RANGE_STAT_RANGEUNF7_MASK, /*!< channel7 range status underflow */
  119. #endif
  120. kPDM_RangeStatusOverFlowCh0 = PDM_RANGE_STAT_RANGEOVF0_MASK, /*!< channel0 range status overflow */
  121. kPDM_RangeStatusOverFlowCh1 = PDM_RANGE_STAT_RANGEOVF1_MASK, /*!< channel1 range status overflow */
  122. kPDM_RangeStatusOverFlowCh2 = PDM_RANGE_STAT_RANGEOVF2_MASK, /*!< channel2 range status overflow */
  123. kPDM_RangeStatusOverFlowCh3 = PDM_RANGE_STAT_RANGEOVF3_MASK, /*!< channel3 range status overflow */
  124. #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
  125. kPDM_RangeStatusOverFlowCh4 = PDM_RANGE_STAT_RANGEOVF4_MASK, /*!< channel4 range status overflow */
  126. kPDM_RangeStatusOverFlowCh5 = PDM_RANGE_STAT_RANGEOVF5_MASK, /*!< channel5 range status overflow */
  127. kPDM_RangeStatusOverFlowCh6 = PDM_RANGE_STAT_RANGEOVF6_MASK, /*!< channel6 range status overflow */
  128. kPDM_RangeStatusOverFlowCh7 = PDM_RANGE_STAT_RANGEOVF7_MASK, /*!< channel7 range status overflow */
  129. #endif
  130. };
  131. #else
  132. /*! @brief The PDM output status */
  133. enum _pdm_output_status
  134. {
  135. kPDM_OutputStatusUnderFlowCh0 = PDM_OUT_STAT_OUTUNF0_MASK, /*!< channel0 output status underflow */
  136. kPDM_OutputStatusUnderFlowCh1 = PDM_OUT_STAT_OUTUNF1_MASK, /*!< channel1 output status underflow */
  137. kPDM_OutputStatusUnderFlowCh2 = PDM_OUT_STAT_OUTUNF2_MASK, /*!< channel2 output status underflow */
  138. kPDM_OutputStatusUnderFlowCh3 = PDM_OUT_STAT_OUTUNF3_MASK, /*!< channel3 output status underflow */
  139. #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
  140. kPDM_OutputStatusUnderFlowCh4 = PDM_OUT_STAT_OUTUNF4_MASK, /*!< channel4 output status underflow */
  141. kPDM_OutputStatusUnderFlowCh5 = PDM_OUT_STAT_OUTUNF5_MASK, /*!< channel5 output status underflow */
  142. kPDM_OutputStatusUnderFlowCh6 = PDM_OUT_STAT_OUTUNF6_MASK, /*!< channel6 output status underflow */
  143. kPDM_OutputStatusUnderFlowCh7 = PDM_OUT_STAT_OUTUNF7_MASK, /*!< channel7 output status underflow */
  144. #endif
  145. kPDM_OutputStatusOverFlowCh0 = PDM_OUT_STAT_OUTOVF0_MASK, /*!< channel0 output status overflow */
  146. kPDM_OutputStatusOverFlowCh1 = PDM_OUT_STAT_OUTOVF1_MASK, /*!< channel1 output status overflow */
  147. kPDM_OutputStatusOverFlowCh2 = PDM_OUT_STAT_OUTOVF2_MASK, /*!< channel2 output status overflow */
  148. kPDM_OutputStatusOverFlowCh3 = PDM_OUT_STAT_OUTOVF3_MASK, /*!< channel3 output status overflow */
  149. #if !defined(FSL_FEATURE_PDM_CHANNEL_NUM) || (FSL_FEATURE_PDM_CHANNEL_NUM == 8U)
  150. kPDM_OutputStatusOverFlowCh4 = PDM_OUT_STAT_OUTOVF4_MASK, /*!< channel4 output status overflow */
  151. kPDM_OutputStatusOverFlowCh5 = PDM_OUT_STAT_OUTOVF5_MASK, /*!< channel5 output status overflow */
  152. kPDM_OutputStatusOverFlowCh6 = PDM_OUT_STAT_OUTOVF6_MASK, /*!< channel6 output status overflow */
  153. kPDM_OutputStatusOverFlowCh7 = PDM_OUT_STAT_OUTOVF7_MASK, /*!< channel7 output status overflow */
  154. #endif
  155. };
  156. #endif
  157. #if (defined(FSL_FEATURE_PDM_HAS_DC_OUT_CTRL) && (FSL_FEATURE_PDM_HAS_DC_OUT_CTRL))
  158. /*! @brief PDM DC remover configurations */
  159. typedef enum _pdm_dc_remover
  160. {
  161. kPDM_DcRemoverCutOff20Hz = 0U, /*!< DC remover cut off 20HZ */
  162. kPDM_DcRemoverCutOff13Hz = 1U, /*!< DC remover cut off 13.3HZ */
  163. kPDM_DcRemoverCutOff40Hz = 2U, /*!< DC remover cut off 40HZ */
  164. kPDM_DcRemoverBypass = 3U, /*!< DC remover bypass */
  165. } pdm_dc_remover_t;
  166. #else
  167. /*! @brief PDM DC remover configurations */
  168. typedef enum _pdm_dc_remover
  169. {
  170. kPDM_DcRemoverCutOff21Hz = 0U, /*!< DC remover cut off 21HZ */
  171. kPDM_DcRemoverCutOff83Hz = 1U, /*!< DC remover cut off 83HZ */
  172. kPDM_DcRemoverCutOff152Hz = 2U, /*!< DC remover cut off 152HZ */
  173. kPDM_DcRemoverBypass = 3U, /*!< DC remover bypass */
  174. } pdm_dc_remover_t;
  175. #endif
  176. /*! @brief PDM decimation filter quality mode */
  177. typedef enum _pdm_df_quality_mode
  178. {
  179. kPDM_QualityModeMedium = 0U, /*!< quality mode memdium */
  180. kPDM_QualityModeHigh = 1U, /*!< quality mode high */
  181. kPDM_QualityModeLow = 7U, /*!< quality mode low */
  182. kPDM_QualityModeVeryLow0 = 6U, /*!< quality mode very low0 */
  183. kPDM_QualityModeVeryLow1 = 5U, /*!< quality mode very low1 */
  184. kPDM_QualityModeVeryLow2 = 4U, /*!< quality mode very low2 */
  185. } pdm_df_quality_mode_t;
  186. /*! @brief PDM quality mode K factor */
  187. enum _pdm_qulaity_mode_k_factor
  188. {
  189. kPDM_QualityModeHighKFactor = 1U, /*!< high quality mode K factor = 1 / 2 */
  190. kPDM_QualityModeMediumKFactor = 2U, /*!< medium/very low0 quality mode K factor = 2 / 2 */
  191. kPDM_QualityModeLowKFactor = 4U, /*!< low/very low1 quality mode K factor = 4 / 2 */
  192. kPDM_QualityModeVeryLow2KFactor = 8U, /*!< very low2 quality mode K factor = 8 / 2 */
  193. };
  194. /*! @brief PDM decimation filter output gain */
  195. typedef enum _pdm_df_output_gain
  196. {
  197. kPDM_DfOutputGain0 = 0U, /*!< Decimation filter output gain 0 */
  198. kPDM_DfOutputGain1 = 1U, /*!< Decimation filter output gain 1 */
  199. kPDM_DfOutputGain2 = 2U, /*!< Decimation filter output gain 2 */
  200. kPDM_DfOutputGain3 = 3U, /*!< Decimation filter output gain 3 */
  201. kPDM_DfOutputGain4 = 4U, /*!< Decimation filter output gain 4 */
  202. kPDM_DfOutputGain5 = 5U, /*!< Decimation filter output gain 5 */
  203. kPDM_DfOutputGain6 = 6U, /*!< Decimation filter output gain 6 */
  204. kPDM_DfOutputGain7 = 7U, /*!< Decimation filter output gain 7 */
  205. kPDM_DfOutputGain8 = 8U, /*!< Decimation filter output gain 8 */
  206. kPDM_DfOutputGain9 = 9U, /*!< Decimation filter output gain 9 */
  207. kPDM_DfOutputGain10 = 0xAU, /*!< Decimation filter output gain 10 */
  208. kPDM_DfOutputGain11 = 0xBU, /*!< Decimation filter output gain 11 */
  209. kPDM_DfOutputGain12 = 0xCU, /*!< Decimation filter output gain 12 */
  210. kPDM_DfOutputGain13 = 0xDU, /*!< Decimation filter output gain 13 */
  211. kPDM_DfOutputGain14 = 0xEU, /*!< Decimation filter output gain 14 */
  212. kPDM_DfOutputGain15 = 0xFU, /*!< Decimation filter output gain 15 */
  213. } pdm_df_output_gain_t;
  214. /*! @brief PDM data width */
  215. enum _pdm_data_width
  216. {
  217. #if defined(FSL_FEATURE_PDM_FIFO_WIDTH) && (FSL_FEATURE_PDM_FIFO_WIDTH != 2U)
  218. kPDM_DataWwidth24 = 3U, /*!< PDM data width 24bit */
  219. kPDM_DataWwidth32 = 4U, /*!< PDM data width 32bit */
  220. #else
  221. kPDM_DataWdith16 = 2U, /*!< PDM data width 16bit */
  222. #endif
  223. };
  224. /*! @brief PDM channel configurations */
  225. typedef struct _pdm_channel_config
  226. {
  227. #if (defined(FSL_FEATURE_PDM_HAS_DC_OUT_CTRL) && (FSL_FEATURE_PDM_HAS_DC_OUT_CTRL))
  228. pdm_dc_remover_t outputCutOffFreq; /*!< PDM output DC remover cut off frequency */
  229. #endif
  230. #if !(defined(FSL_FEATURE_PDM_DC_CTRL_VALUE_FIXED) && (FSL_FEATURE_PDM_DC_CTRL_VALUE_FIXED))
  231. pdm_dc_remover_t cutOffFreq; /*!< DC remover cut off frequency */
  232. #endif
  233. pdm_df_output_gain_t gain; /*!< Decimation Filter Output Gain */
  234. } pdm_channel_config_t;
  235. /*! @brief PDM user configuration structure */
  236. typedef struct _pdm_config
  237. {
  238. bool
  239. enableDoze; /*!< This module will enter disable/low leakage mode if DOZEN is active with ipg_doze is asserted */
  240. uint8_t fifoWatermark; /*!< Watermark value for FIFO */
  241. pdm_df_quality_mode_t qualityMode; /*!< Quality mode */
  242. uint8_t cicOverSampleRate; /*!< CIC filter over sampling rate */
  243. } pdm_config_t;
  244. /*! @brief PDM voice activity detector interrupt type */
  245. enum _pdm_hwvad_interrupt_enable
  246. {
  247. kPDM_HwvadErrorInterruptEnable = PDM_VAD0_CTRL_1_VADERIE_MASK, /*!< PDM channel HWVAD error interrupt enable. */
  248. kPDM_HwvadInterruptEnable = PDM_VAD0_CTRL_1_VADIE_MASK, /*!< PDM channel HWVAD interrupt */
  249. };
  250. /*! @brief The PDM hwvad interrupt status flag */
  251. enum _pdm_hwvad_int_status
  252. {
  253. kPDM_HwvadStatusInputSaturation = PDM_VAD0_STAT_VADINSATF_MASK, /*!< HWVAD saturation condition */
  254. kPDM_HwvadStatusVoiceDetectFlag = PDM_VAD0_STAT_VADIF_MASK, /*!< HWVAD voice detect interrupt triggered */
  255. };
  256. /*! @brief High pass filter configure cut-off frequency*/
  257. typedef enum _pdm_hwvad_hpf_config
  258. {
  259. kPDM_HwvadHpfBypassed = 0x0U, /*!< High-pass filter bypass */
  260. kPDM_HwvadHpfCutOffFreq1750Hz = 0x1U, /*!< High-pass filter cut off frequency 1750HZ */
  261. kPDM_HwvadHpfCutOffFreq215Hz = 0x2U, /*!< High-pass filter cut off frequency 215HZ */
  262. kPDM_HwvadHpfCutOffFreq102Hz = 0x3U, /*!< High-pass filter cut off frequency 102HZ */
  263. } pdm_hwvad_hpf_config_t;
  264. /*! @brief HWVAD internal filter status */
  265. typedef enum _pdm_hwvad_filter_status
  266. {
  267. kPDM_HwvadInternalFilterNormalOperation = 0U, /*!< internal filter ready for normal operation */
  268. kPDM_HwvadInternalFilterInitial = PDM_VAD0_CTRL_1_VADST10_MASK, /*!< interla filter are initial */
  269. } pdm_hwvad_filter_status_t;
  270. /*! @brief PDM voice activity detector user configuration structure */
  271. typedef struct _pdm_hwvad_config
  272. {
  273. uint8_t channel; /*!< Which channel uses voice activity detector */
  274. uint8_t initializeTime; /*!< Number of frames or samples to initialize voice activity detector. */
  275. uint8_t cicOverSampleRate; /*!< CIC filter over sampling rate */
  276. uint8_t inputGain; /*!< Voice activity detector input gain */
  277. uint32_t frameTime; /*!< Voice activity frame time */
  278. pdm_hwvad_hpf_config_t cutOffFreq; /*!< High pass filter cut off frequency */
  279. bool enableFrameEnergy; /*!< If frame energy enabled, true means enable */
  280. bool enablePreFilter; /*!< If pre-filter enabled */
  281. } pdm_hwvad_config_t;
  282. /*! @brief PDM voice activity detector noise filter user configuration structure */
  283. typedef struct _pdm_hwvad_noise_filter
  284. {
  285. bool enableAutoNoiseFilter; /*!< If noise fileter automatically activated, true means enable */
  286. bool enableNoiseMin; /*!< If Noise minimum block enabled, true means enabled */
  287. bool enableNoiseDecimation; /*!< If enable noise input decimation */
  288. bool enableNoiseDetectOR; /*!< Enables a OR logic in the output of minimum noise estimator block */
  289. uint32_t noiseFilterAdjustment; /*!< The adjustment value of the noise filter */
  290. uint32_t noiseGain; /*!< Gain value for the noise energy or envelope estimated */
  291. } pdm_hwvad_noise_filter_t;
  292. /*! @brief PDM voice activity detector zero cross detector result */
  293. typedef enum _pdm_hwvad_zcd_result
  294. {
  295. kPDM_HwvadResultOREnergyBasedDetection =
  296. 0U, /*!< zero cross detector result will be OR with energy based detection */
  297. kPDM_HwvadResultANDEnergyBasedDetection =
  298. 1U, /*!< zero cross detector result will be AND with energy based detection */
  299. } pdm_hwvad_zcd_result_t;
  300. /*! @brief PDM voice activity detector zero cross detector configuration structure */
  301. typedef struct _pdm_hwvad_zero_cross_detector
  302. {
  303. bool enableAutoThreshold; /*!< If ZCD auto-threshold enabled, true means enabled. */
  304. pdm_hwvad_zcd_result_t zcdAnd; /*!< Is ZCD result is AND'ed with energy-based detection, false means OR'ed */
  305. uint32_t threshold; /*!< The adjustment value of the noise filter */
  306. uint32_t adjustmentThreshold; /*!< Gain value for the noise energy or envelope estimated */
  307. } pdm_hwvad_zero_cross_detector_t;
  308. /*! @brief PDM SDMA transfer structure */
  309. typedef struct _pdm_transfer
  310. {
  311. volatile uint8_t *data; /*!< Data start address to transfer. */
  312. volatile size_t dataSize; /*!< Total Transfer bytes size. */
  313. } pdm_transfer_t;
  314. /*! @brief PDM handle */
  315. typedef struct _pdm_handle pdm_handle_t;
  316. /*! @brief PDM transfer callback prototype */
  317. typedef void (*pdm_transfer_callback_t)(PDM_Type *base, pdm_handle_t *handle, status_t status, void *userData);
  318. /*! @brief PDM HWVAD callback prototype */
  319. typedef void (*pdm_hwvad_callback_t)(status_t status, void *userData);
  320. /*! @brief PDM HWVAD notification structure */
  321. typedef struct _pdm_hwvad_notification
  322. {
  323. pdm_hwvad_callback_t callback;
  324. void *userData;
  325. } pdm_hwvad_notification_t;
  326. /*! @brief PDM handle structure */
  327. struct _pdm_handle
  328. {
  329. uint32_t state; /*!< Transfer status */
  330. pdm_transfer_callback_t callback; /*!< Callback function called at transfer event*/
  331. void *userData; /*!< Callback parameter passed to callback function*/
  332. pdm_transfer_t pdmQueue[PDM_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */
  333. size_t transferSize[PDM_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */
  334. volatile uint8_t queueUser; /*!< Index for user to queue transfer */
  335. volatile uint8_t queueDriver; /*!< Index for driver to get the transfer data and size */
  336. uint32_t format; /*!< data format */
  337. uint8_t watermark; /*!< Watermark value */
  338. uint8_t startChannel; /*!< end channel */
  339. uint8_t channelNums; /*!< Enabled channel number */
  340. };
  341. /*******************************************************************************
  342. * API
  343. ******************************************************************************/
  344. #if defined(__cplusplus)
  345. extern "C" {
  346. #endif /*_cplusplus*/
  347. /*!
  348. * @name Initialization and deinitialization
  349. * @{
  350. */
  351. /*!
  352. * @brief Initializes the PDM peripheral.
  353. *
  354. * Ungates the PDM clock, resets the module, and configures PDM with a configuration structure.
  355. * The configuration structure can be custom filled or set with default values by
  356. * PDM_GetDefaultConfig().
  357. *
  358. * @note This API should be called at the beginning of the application to use
  359. * the PDM driver. Otherwise, accessing the PDM module can cause a hard fault
  360. * because the clock is not enabled.
  361. *
  362. * @param base PDM base pointer
  363. * @param config PDM configuration structure.
  364. */
  365. void PDM_Init(PDM_Type *base, const pdm_config_t *config);
  366. /*!
  367. * @brief De-initializes the PDM peripheral.
  368. *
  369. * This API gates the PDM clock. The PDM module can't operate unless PDM_Init
  370. * is called to enable the clock.
  371. *
  372. * @param base PDM base pointer
  373. */
  374. void PDM_Deinit(PDM_Type *base);
  375. /*!
  376. * @brief Resets the PDM module.
  377. *
  378. * @param base PDM base pointer
  379. */
  380. static inline void PDM_Reset(PDM_Type *base)
  381. {
  382. base->CTRL_1 |= PDM_CTRL_1_SRES_MASK;
  383. }
  384. /*!
  385. * @brief Enables/disables PDM interface.
  386. *
  387. * @param base PDM base pointer
  388. * @param enable True means PDM interface is enabled, false means PDM interface is disabled.
  389. */
  390. static inline void PDM_Enable(PDM_Type *base, bool enable)
  391. {
  392. if (enable)
  393. {
  394. base->CTRL_1 |= PDM_CTRL_1_PDMIEN_MASK;
  395. }
  396. else
  397. {
  398. base->CTRL_1 &= ~PDM_CTRL_1_PDMIEN_MASK;
  399. }
  400. }
  401. /*!
  402. * @brief Enables/disables DOZE.
  403. *
  404. * @param base PDM base pointer
  405. * @param enable True means the module will enter Disable/Low Leakage mode when ipg_doze is asserted, false means the
  406. * module will not enter Disable/Low Leakage mode when ipg_doze is asserted.
  407. */
  408. static inline void PDM_EnableDoze(PDM_Type *base, bool enable)
  409. {
  410. if (enable)
  411. {
  412. base->CTRL_1 |= PDM_CTRL_1_DOZEN_MASK;
  413. }
  414. else
  415. {
  416. base->CTRL_1 &= ~PDM_CTRL_1_DOZEN_MASK;
  417. }
  418. }
  419. /*!
  420. * @brief Enables/disables debug mode for PDM.
  421. * The PDM interface cannot enter debug mode once in Disable/Low Leakage or Low Power mode.
  422. * @param base PDM base pointer
  423. * @param enable True means PDM interface enter debug mode, false means PDM interface in normal mode.
  424. */
  425. static inline void PDM_EnableDebugMode(PDM_Type *base, bool enable)
  426. {
  427. if (enable)
  428. {
  429. base->CTRL_1 |= PDM_CTRL_1_DBG_MASK;
  430. }
  431. else
  432. {
  433. base->CTRL_1 &= ~PDM_CTRL_1_DBG_MASK;
  434. }
  435. }
  436. /*!
  437. * @brief Enables/disables PDM interface in debug mode.
  438. *
  439. * @param base PDM base pointer
  440. * @param enable True means PDM interface is enabled debug mode, false means PDM interface is disabled after
  441. * after completing the current frame in debug mode.
  442. */
  443. static inline void PDM_EnableInDebugMode(PDM_Type *base, bool enable)
  444. {
  445. if (enable)
  446. {
  447. base->CTRL_1 |= PDM_CTRL_1_DBGE_MASK;
  448. }
  449. else
  450. {
  451. base->CTRL_1 &= ~PDM_CTRL_1_DBGE_MASK;
  452. }
  453. }
  454. /*!
  455. * @brief Enables/disables PDM interface disable/Low Leakage mode.
  456. *
  457. * @param base PDM base pointer
  458. * @param enable True means PDM interface is in disable/low leakage mode, False means PDM interface is in normal mode.
  459. */
  460. static inline void PDM_EnterLowLeakageMode(PDM_Type *base, bool enable)
  461. {
  462. if (enable)
  463. {
  464. base->CTRL_1 |= PDM_CTRL_1_MDIS_MASK;
  465. }
  466. else
  467. {
  468. base->CTRL_1 &= ~PDM_CTRL_1_MDIS_MASK;
  469. }
  470. }
  471. /*!
  472. * @brief Enables/disables the PDM channel.
  473. *
  474. * @param base PDM base pointer
  475. * @param channel PDM channel number need to enable or disable.
  476. * @param enable True means enable PDM channel, false means disable.
  477. */
  478. static inline void PDM_EnableChannel(PDM_Type *base, uint8_t channel, bool enable)
  479. {
  480. if (enable)
  481. {
  482. base->CTRL_1 |= (1UL << channel);
  483. }
  484. else
  485. {
  486. base->CTRL_1 &= ~(1UL << channel);
  487. }
  488. }
  489. /*!
  490. * @brief PDM one channel configurations.
  491. *
  492. * @param base PDM base pointer
  493. * @param config PDM channel configurations.
  494. * @param channel channel number.
  495. * after completing the current frame in debug mode.
  496. */
  497. void PDM_SetChannelConfig(PDM_Type *base, uint32_t channel, const pdm_channel_config_t *config);
  498. /*!
  499. * @brief PDM set sample rate.
  500. *
  501. * @note This function is depend on the configuration of the PDM and PDM channel, so the correct call sequence is
  502. * @code
  503. * PDM_Init(base, pdmConfig)
  504. * PDM_SetChannelConfig(base, channel, &channelConfig)
  505. * PDM_SetSampleRateConfig(base, source, sampleRate)
  506. * @endcode
  507. * @param base PDM base pointer
  508. * @param sourceClock_HZ PDM source clock frequency.
  509. * @param sampleRate_HZ PDM sample rate.
  510. */
  511. status_t PDM_SetSampleRateConfig(PDM_Type *base, uint32_t sourceClock_HZ, uint32_t sampleRate_HZ);
  512. /*!
  513. * @brief PDM set sample rate.
  514. *
  515. * @deprecated Do not use this function. It has been superceded by @ref PDM_SetSampleRateConfig
  516. * @param base PDM base pointer
  517. * @param enableChannelMask PDM channel enable mask.
  518. * @param qualityMode quality mode.
  519. * @param osr cic oversample rate
  520. * @param clkDiv clock divider
  521. */
  522. status_t PDM_SetSampleRate(
  523. PDM_Type *base, uint32_t enableChannelMask, pdm_df_quality_mode_t qualityMode, uint8_t osr, uint32_t clkDiv);
  524. /*!
  525. * @brief Get the instance number for PDM.
  526. *
  527. * @param base PDM base pointer.
  528. */
  529. uint32_t PDM_GetInstance(PDM_Type *base);
  530. /*! @} */
  531. /*!
  532. * @name Status
  533. * @{
  534. */
  535. /*!
  536. * @brief Gets the PDM internal status flag.
  537. * Use the Status Mask in _pdm_internal_status to get the status value needed
  538. * @param base PDM base pointer
  539. * @return PDM status flag value.
  540. */
  541. static inline uint32_t PDM_GetStatus(PDM_Type *base)
  542. {
  543. return base->STAT;
  544. }
  545. /*!
  546. * @brief Gets the PDM FIFO status flag.
  547. * Use the Status Mask in _pdm_fifo_status to get the status value needed
  548. * @param base PDM base pointer
  549. * @return FIFO status.
  550. */
  551. static inline uint32_t PDM_GetFifoStatus(PDM_Type *base)
  552. {
  553. return base->FIFO_STAT;
  554. }
  555. #if defined(FSL_FEATURE_PDM_HAS_RANGE_CTRL) && FSL_FEATURE_PDM_HAS_RANGE_CTRL
  556. /*!
  557. * @brief Gets the PDM Range status flag.
  558. * Use the Status Mask in _pdm_range_status to get the status value needed
  559. * @param base PDM base pointer
  560. * @return output status.
  561. */
  562. static inline uint32_t PDM_GetRangeStatus(PDM_Type *base)
  563. {
  564. return base->RANGE_STAT;
  565. }
  566. #else
  567. /*!
  568. * @brief Gets the PDM output status flag.
  569. * Use the Status Mask in _pdm_output_status to get the status value needed
  570. * @param base PDM base pointer
  571. * @return output status.
  572. */
  573. static inline uint32_t PDM_GetOutputStatus(PDM_Type *base)
  574. {
  575. return base->OUT_STAT;
  576. }
  577. #endif
  578. /*!
  579. * @brief Clears the PDM Tx status.
  580. *
  581. * @param base PDM base pointer
  582. * @param mask State mask. It can be a combination of the status between kPDM_StatusFrequencyLow and
  583. * kPDM_StatusCh7FifoDataAvaliable.
  584. */
  585. static inline void PDM_ClearStatus(PDM_Type *base, uint32_t mask)
  586. {
  587. base->STAT = mask;
  588. }
  589. /*!
  590. * @brief Clears the PDM Tx status.
  591. *
  592. * @param base PDM base pointer
  593. * @param mask State mask.It can be a combination of the status in _pdm_fifo_status.
  594. */
  595. static inline void PDM_ClearFIFOStatus(PDM_Type *base, uint32_t mask)
  596. {
  597. base->FIFO_STAT = mask;
  598. }
  599. #if defined(FSL_FEATURE_PDM_HAS_RANGE_CTRL) && FSL_FEATURE_PDM_HAS_RANGE_CTRL
  600. /*!
  601. * @brief Clears the PDM range status.
  602. *
  603. * @param base PDM base pointer
  604. * @param mask State mask. It can be a combination of the status in _pdm_range_status.
  605. */
  606. static inline void PDM_ClearRangeStatus(PDM_Type *base, uint32_t mask)
  607. {
  608. base->RANGE_STAT = mask;
  609. }
  610. #else
  611. /*!
  612. * @brief Clears the PDM output status.
  613. *
  614. * @param base PDM base pointer
  615. * @param mask State mask. It can be a combination of the status in _pdm_output_status.
  616. */
  617. static inline void PDM_ClearOutputStatus(PDM_Type *base, uint32_t mask)
  618. {
  619. base->OUT_STAT = mask;
  620. }
  621. #endif
  622. /*! @} */
  623. /*!
  624. * @name Interrupts
  625. * @{
  626. */
  627. /*!
  628. * @brief Enables the PDM interrupt requests.
  629. *
  630. * @param base PDM base pointer
  631. * @param mask interrupt source
  632. * The parameter can be a combination of the following sources if defined.
  633. * @arg kPDM_ErrorInterruptEnable
  634. * @arg kPDM_FIFOInterruptEnable
  635. */
  636. void PDM_EnableInterrupts(PDM_Type *base, uint32_t mask);
  637. /*!
  638. * @brief Disables the PDM interrupt requests.
  639. *
  640. * @param base PDM base pointer
  641. * @param mask interrupt source
  642. * The parameter can be a combination of the following sources if defined.
  643. * @arg kPDM_ErrorInterruptEnable
  644. * @arg kPDM_FIFOInterruptEnable
  645. */
  646. static inline void PDM_DisableInterrupts(PDM_Type *base, uint32_t mask)
  647. {
  648. base->CTRL_1 &= ~mask;
  649. }
  650. /*! @} */
  651. /*!
  652. * @name DMA Control
  653. * @{
  654. */
  655. /*!
  656. * @brief Enables/disables the PDM DMA requests.
  657. *
  658. * @param base PDM base pointer
  659. * @param enable True means enable DMA, false means disable DMA.
  660. */
  661. static inline void PDM_EnableDMA(PDM_Type *base, bool enable)
  662. {
  663. if (enable)
  664. {
  665. base->CTRL_1 = (base->CTRL_1 & (~PDM_CTRL_1_DISEL_MASK)) | PDM_CTRL_1_DISEL(0x1U);
  666. }
  667. else
  668. {
  669. base->CTRL_1 &= ~PDM_CTRL_1_DISEL_MASK;
  670. }
  671. }
  672. /*!
  673. * @brief Gets the PDM data register address.
  674. *
  675. * This API is used to provide a transfer address for the PDM DMA transfer configuration.
  676. *
  677. * @param base PDM base pointer.
  678. * @param channel Which data channel used.
  679. * @return data register address.
  680. */
  681. static inline uint32_t PDM_GetDataRegisterAddress(PDM_Type *base, uint32_t channel)
  682. {
  683. return (uint32_t)(&(base->DATACH)[channel]);
  684. }
  685. /*! @} */
  686. /*!
  687. * @name Bus Operations
  688. * @{
  689. */
  690. #if defined(FSL_FEATURE_PDM_FIFO_WIDTH) && (FSL_FEATURE_PDM_FIFO_WIDTH == 2U)
  691. /*!
  692. * @brief Reads data from the PDM FIFO.
  693. *
  694. * @param base PDM base pointer.
  695. * @param channel Data channel used.
  696. * @return Data in PDM FIFO.
  697. */
  698. static inline int16_t PDM_ReadData(PDM_Type *base, uint32_t channel)
  699. {
  700. return (int16_t)(base->DATACH[channel]);
  701. }
  702. /*!
  703. * @brief PDM read data non blocking.
  704. * So the actually read data byte size in this function is (size * 2 * channelNums).
  705. * @param base PDM base pointer.
  706. * @param startChannel start channel number.
  707. * @param channelNums total enabled channelnums.
  708. * @param buffer received buffer address.
  709. * @param size number of 16bit data to read.
  710. */
  711. void PDM_ReadNonBlocking(PDM_Type *base, uint32_t startChannel, uint32_t channelNums, int16_t *buffer, size_t size);
  712. #endif
  713. /*!
  714. * @brief PDM read fifo.
  715. * @note: This function support 16 bit only for IP version that only supports 16bit.
  716. *
  717. * @param base PDM base pointer.
  718. * @param startChannel start channel number.
  719. * @param channelNums total enabled channelnums.
  720. * @param buffer received buffer address.
  721. * @param size number of samples to read.
  722. * @param dataWidth sample width.
  723. */
  724. void PDM_ReadFifo(
  725. PDM_Type *base, uint32_t startChannel, uint32_t channelNums, void *buffer, size_t size, uint32_t dataWidth);
  726. #if defined(FSL_FEATURE_PDM_FIFO_WIDTH) && (FSL_FEATURE_PDM_FIFO_WIDTH == 4U)
  727. /*!
  728. * @brief Reads data from the PDM FIFO.
  729. *
  730. * @param base PDM base pointer.
  731. * @param channel Data channel used.
  732. * @return Data in PDM FIFO.
  733. */
  734. static inline uint32_t PDM_ReadData(PDM_Type *base, uint32_t channel)
  735. {
  736. return base->DATACH[channel];
  737. }
  738. #endif
  739. /*! @} */
  740. /*!
  741. * @name Voice Activity Detector
  742. * @{
  743. */
  744. /*!
  745. * @brief Configure voice activity detector.
  746. *
  747. * @param base PDM base pointer
  748. * @param config Voice activity detector configure structure pointer .
  749. */
  750. void PDM_SetHwvadConfig(PDM_Type *base, const pdm_hwvad_config_t *config);
  751. /*!
  752. * @brief PDM hwvad force output disable.
  753. *
  754. * @param base PDM base pointer
  755. * @param enable true is output force disable, false is output not force.
  756. */
  757. static inline void PDM_ForceHwvadOutputDisable(PDM_Type *base, bool enable)
  758. {
  759. if (enable)
  760. {
  761. base->VAD0_CTRL_2 &= ~PDM_VAD0_CTRL_2_VADFOUTDIS_MASK;
  762. }
  763. else
  764. {
  765. base->VAD0_CTRL_2 |= PDM_VAD0_CTRL_2_VADFOUTDIS_MASK;
  766. }
  767. }
  768. /*!
  769. * @brief PDM hwvad reset.
  770. * It will reset VADNDATA register and will clean all internal buffers, should be called when the PDM isn't running.
  771. *
  772. * @param base PDM base pointer
  773. */
  774. static inline void PDM_ResetHwvad(PDM_Type *base)
  775. {
  776. base->VAD0_CTRL_1 |= PDM_VAD0_CTRL_1_VADRST_MASK;
  777. }
  778. /*!
  779. * @brief Enable/Disable Voice activity detector.
  780. * Should be called when the PDM isn't running.
  781. * @param base PDM base pointer.
  782. * @param enable True means enable voice activity detector, false means disable.
  783. */
  784. static inline void PDM_EnableHwvad(PDM_Type *base, bool enable)
  785. {
  786. if (enable)
  787. {
  788. base->VAD0_CTRL_1 |= PDM_VAD0_CTRL_1_VADEN_MASK;
  789. }
  790. else
  791. {
  792. base->VAD0_CTRL_1 &= ~PDM_VAD0_CTRL_1_VADEN_MASK;
  793. }
  794. }
  795. /*!
  796. * @brief Enables the PDM Voice Detector interrupt requests.
  797. *
  798. * @param base PDM base pointer
  799. * @param mask interrupt source
  800. * The parameter can be a combination of the following sources if defined.
  801. * @arg kPDM_HWVADErrorInterruptEnable
  802. * @arg kPDM_HWVADInterruptEnable
  803. */
  804. static inline void PDM_EnableHwvadInterrupts(PDM_Type *base, uint32_t mask)
  805. {
  806. base->VAD0_CTRL_1 |= mask;
  807. }
  808. /*!
  809. * @brief Disables the PDM Voice Detector interrupt requests.
  810. *
  811. * @param base PDM base pointer
  812. * @param mask interrupt source
  813. * The parameter can be a combination of the following sources if defined.
  814. * @arg kPDM_HWVADErrorInterruptEnable
  815. * @arg kPDM_HWVADInterruptEnable
  816. */
  817. static inline void PDM_DisableHwvadInterrupts(PDM_Type *base, uint32_t mask)
  818. {
  819. base->VAD0_CTRL_1 &= ~mask;
  820. }
  821. /*!
  822. * @brief Clears the PDM voice activity detector status flags.
  823. *
  824. * @param base PDM base pointer
  825. * @param mask State mask,reference _pdm_hwvad_int_status.
  826. */
  827. static inline void PDM_ClearHwvadInterruptStatusFlags(PDM_Type *base, uint32_t mask)
  828. {
  829. base->VAD0_STAT = mask;
  830. }
  831. /*!
  832. * @brief Clears the PDM voice activity detector status flags.
  833. *
  834. * @param base PDM base pointer
  835. * @return status, reference _pdm_hwvad_int_status
  836. */
  837. static inline uint32_t PDM_GetHwvadInterruptStatusFlags(PDM_Type *base)
  838. {
  839. return base->VAD0_STAT & (PDM_VAD0_STAT_VADIF_MASK | PDM_VAD0_STAT_VADINSATF_MASK);
  840. }
  841. /*!
  842. * @brief Get the PDM voice activity detector initial flags.
  843. *
  844. * @param base PDM base pointer
  845. * @return initial flag.
  846. */
  847. static inline uint32_t PDM_GetHwvadInitialFlag(PDM_Type *base)
  848. {
  849. return base->VAD0_STAT & PDM_VAD0_STAT_VADINITF_MASK;
  850. }
  851. /*!
  852. * @brief Get the PDM voice activity detector voice detected flags.
  853. * NOte: this flag is auto cleared when voice gone.
  854. * @param base PDM base pointer
  855. * @return voice detected flag.
  856. */
  857. static inline uint32_t PDM_GetHwvadVoiceDetectedFlag(PDM_Type *base)
  858. {
  859. return base->VAD0_STAT & PDM_VAD0_STAT_VADEF_MASK;
  860. }
  861. /*!
  862. * @brief Enables/disables voice activity detector signal filter.
  863. *
  864. * @param base PDM base pointer
  865. * @param enable True means enable signal filter, false means disable.
  866. */
  867. static inline void PDM_EnableHwvadSignalFilter(PDM_Type *base, bool enable)
  868. {
  869. if (enable)
  870. {
  871. base->VAD0_SCONFIG |= PDM_VAD0_SCONFIG_VADSFILEN_MASK;
  872. }
  873. else
  874. {
  875. base->VAD0_SCONFIG &= ~PDM_VAD0_SCONFIG_VADSFILEN_MASK;
  876. }
  877. }
  878. /*!
  879. * @brief Configure voice activity detector signal filter.
  880. *
  881. * @param base PDM base pointer
  882. * @param enableMaxBlock If signal maximum block enabled.
  883. * @param signalGain Gain value for the signal energy.
  884. */
  885. void PDM_SetHwvadSignalFilterConfig(PDM_Type *base, bool enableMaxBlock, uint32_t signalGain);
  886. /*!
  887. * @brief Configure voice activity detector noise filter.
  888. *
  889. * @param base PDM base pointer
  890. * @param config Voice activity detector noise filter configure structure pointer .
  891. */
  892. void PDM_SetHwvadNoiseFilterConfig(PDM_Type *base, const pdm_hwvad_noise_filter_t *config);
  893. /*!
  894. * @brief Enables/disables voice activity detector zero cross detector.
  895. *
  896. * @param base PDM base pointer
  897. * @param enable True means enable zero cross detector, false means disable.
  898. */
  899. static inline void PDM_EnableHwvadZeroCrossDetector(PDM_Type *base, bool enable)
  900. {
  901. if (enable)
  902. {
  903. base->VAD0_ZCD |= PDM_VAD0_ZCD_VADZCDEN_MASK;
  904. }
  905. else
  906. {
  907. base->VAD0_ZCD &= ~PDM_VAD0_ZCD_VADZCDEN_MASK;
  908. }
  909. }
  910. /*!
  911. * @brief Configure voice activity detector zero cross detector.
  912. *
  913. * @param base PDM base pointer
  914. * @param config Voice activity detector zero cross detector configure structure pointer .
  915. */
  916. void PDM_SetHwvadZeroCrossDetectorConfig(PDM_Type *base, const pdm_hwvad_zero_cross_detector_t *config);
  917. /*!
  918. * @brief Reads noise data.
  919. *
  920. * @param base PDM base pointer.
  921. * @return Data in PDM noise data register.
  922. */
  923. static inline uint16_t PDM_GetNoiseData(PDM_Type *base)
  924. {
  925. return (uint16_t)base->VAD0_NDATA;
  926. }
  927. /*!
  928. * @brief set hwvad internal filter status .
  929. * Note: filter initial status should be asserted for two more cycles, then set it to normal operation.
  930. * @param base PDM base pointer.
  931. * @param status internal filter status.
  932. */
  933. static inline void PDM_SetHwvadInternalFilterStatus(PDM_Type *base, pdm_hwvad_filter_status_t status)
  934. {
  935. base->VAD0_CTRL_1 = (base->VAD0_CTRL_1 & (~PDM_VAD0_CTRL_1_VADST10_MASK)) | (uint32_t)status;
  936. }
  937. /*!
  938. * @brief set HWVAD in envelope based mode .
  939. * Recommand configurations,
  940. * @code
  941. * static const pdm_hwvad_config_t hwvadConfig = {
  942. * .channel = 0,
  943. * .initializeTime = 10U,
  944. * .cicOverSampleRate = 0U,
  945. * .inputGain = 0U,
  946. * .frameTime = 10U,
  947. * .cutOffFreq = kPDM_HwvadHpfBypassed,
  948. * .enableFrameEnergy = false,
  949. * .enablePreFilter = true,
  950. };
  951. * static const pdm_hwvad_noise_filter_t noiseFilterConfig = {
  952. * .enableAutoNoiseFilter = false,
  953. * .enableNoiseMin = true,
  954. * .enableNoiseDecimation = true,
  955. * .noiseFilterAdjustment = 0U,
  956. * .noiseGain = 7U,
  957. * .enableNoiseDetectOR = true,
  958. * };
  959. * @endcode
  960. * @param base PDM base pointer.
  961. * @param hwvadConfig internal filter status.
  962. * @param noiseConfig Voice activity detector noise filter configure structure pointer.
  963. * @param zcdConfig Voice activity detector zero cross detector configure structure pointer .
  964. * @param signalGain signal gain value.
  965. */
  966. void PDM_SetHwvadInEnvelopeBasedMode(PDM_Type *base,
  967. const pdm_hwvad_config_t *hwvadConfig,
  968. const pdm_hwvad_noise_filter_t *noiseConfig,
  969. const pdm_hwvad_zero_cross_detector_t *zcdConfig,
  970. uint32_t signalGain);
  971. /*!
  972. * brief set HWVAD in energy based mode .
  973. * Recommand configurations,
  974. * code
  975. * static const pdm_hwvad_config_t hwvadConfig = {
  976. * .channel = 0,
  977. * .initializeTime = 10U,
  978. * .cicOverSampleRate = 0U,
  979. * .inputGain = 0U,
  980. * .frameTime = 10U,
  981. * .cutOffFreq = kPDM_HwvadHpfBypassed,
  982. * .enableFrameEnergy = true,
  983. * .enablePreFilter = true,
  984. };
  985. * static const pdm_hwvad_noise_filter_t noiseFilterConfig = {
  986. * .enableAutoNoiseFilter = true,
  987. * .enableNoiseMin = false,
  988. * .enableNoiseDecimation = false,
  989. * .noiseFilterAdjustment = 0U,
  990. * .noiseGain = 7U,
  991. * .enableNoiseDetectOR = false,
  992. * };
  993. * code
  994. * param base PDM base pointer.
  995. * param hwvadConfig internal filter status.
  996. * param noiseConfig Voice activity detector noise filter configure structure pointer.
  997. * param zcdConfig Voice activity detector zero cross detector configure structure pointer .
  998. * param signalGain signal gain value, signal gain value should be properly according to application.
  999. */
  1000. void PDM_SetHwvadInEnergyBasedMode(PDM_Type *base,
  1001. const pdm_hwvad_config_t *hwvadConfig,
  1002. const pdm_hwvad_noise_filter_t *noiseConfig,
  1003. const pdm_hwvad_zero_cross_detector_t *zcdConfig,
  1004. uint32_t signalGain);
  1005. /*!
  1006. * @brief Enable/Disable hwvad callback.
  1007. * This function enable/disable the hwvad interrupt for the selected PDM peripheral.
  1008. *
  1009. * @param base Base address of the PDM peripheral.
  1010. * @param vadCallback callback Pointer to store callback function, should be NULL when disable.
  1011. * @param userData user data.
  1012. * @param enable true is enable, false is disable.
  1013. * @retval None.
  1014. */
  1015. void PDM_EnableHwvadInterruptCallback(PDM_Type *base, pdm_hwvad_callback_t vadCallback, void *userData, bool enable);
  1016. /*! @} */
  1017. /*!
  1018. * @name Transactional
  1019. * @{
  1020. */
  1021. /*!
  1022. * @brief Initializes the PDM handle.
  1023. *
  1024. * This function initializes the handle for the PDM transactional APIs. Call
  1025. * this function once to get the handle initialized.
  1026. *
  1027. * @param base PDM base pointer.
  1028. * @param handle PDM handle pointer.
  1029. * @param callback Pointer to the user callback function.
  1030. * @param userData User parameter passed to the callback function.
  1031. */
  1032. void PDM_TransferCreateHandle(PDM_Type *base, pdm_handle_t *handle, pdm_transfer_callback_t callback, void *userData);
  1033. /*!
  1034. * @brief PDM set channel transfer config.
  1035. *
  1036. * @param base PDM base pointer.
  1037. * @param handle PDM handle pointer.
  1038. * @param channel PDM channel.
  1039. * @param config channel config.
  1040. * @param format data format, support data width configurations,_pdm_data_width.
  1041. * @retval kStatus_PDM_ChannelConfig_Failed or kStatus_Success.
  1042. */
  1043. status_t PDM_TransferSetChannelConfig(
  1044. PDM_Type *base, pdm_handle_t *handle, uint32_t channel, const pdm_channel_config_t *config, uint32_t format);
  1045. /*!
  1046. * @brief Performs an interrupt non-blocking receive transfer on PDM.
  1047. *
  1048. * @note This API returns immediately after the transfer initiates.
  1049. * Call the PDM_RxGetTransferStatusIRQ to poll the transfer status and check whether
  1050. * the transfer is finished. If the return status is not kStatus_PDM_Busy, the transfer
  1051. * is finished.
  1052. *
  1053. * @param base PDM base pointer
  1054. * @param handle Pointer to the pdm_handle_t structure which stores the transfer state.
  1055. * @param xfer Pointer to the pdm_transfer_t structure.
  1056. * @retval kStatus_Success Successfully started the data receive.
  1057. * @retval kStatus_PDM_Busy Previous receive still not finished.
  1058. */
  1059. status_t PDM_TransferReceiveNonBlocking(PDM_Type *base, pdm_handle_t *handle, pdm_transfer_t *xfer);
  1060. /*!
  1061. * @brief Aborts the current IRQ receive.
  1062. *
  1063. * @note This API can be called when an interrupt non-blocking transfer initiates
  1064. * to abort the transfer early.
  1065. *
  1066. * @param base PDM base pointer
  1067. * @param handle Pointer to the pdm_handle_t structure which stores the transfer state.
  1068. */
  1069. void PDM_TransferAbortReceive(PDM_Type *base, pdm_handle_t *handle);
  1070. /*!
  1071. * @brief Tx interrupt handler.
  1072. *
  1073. * @param base PDM base pointer.
  1074. * @param handle Pointer to the pdm_handle_t structure.
  1075. */
  1076. void PDM_TransferHandleIRQ(PDM_Type *base, pdm_handle_t *handle);
  1077. /*! @} */
  1078. #if defined(__cplusplus)
  1079. }
  1080. #endif /*_cplusplus*/
  1081. /*! @} */
  1082. #endif /* _FSL_PDM_H_ */