1 /* 2 * Copyright 2021-2022 NXP 3 * All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef _SRTM_PDM_SDMA_ADAPTER_H_ 9 #define _SRTM_PDM_SDMA_ADAPTER_H_ 10 11 #include "srtm_audio_service.h" 12 #include "fsl_pdm_sdma.h" 13 14 /*! 15 * @addtogroup srtm_service 16 * @{ 17 */ 18 19 /******************************************************************************* 20 * Definitions 21 ******************************************************************************/ 22 #ifndef SRTM_PDM_SDMA_ADAPTER_USE_HWVAD 23 #define SRTM_PDM_SDMA_ADAPTER_USE_HWVAD (1U) 24 #endif 25 #ifndef SRTM_PDM_SDMA_ADAPTER_USE_EXTRA_BUFFER 26 #define SRTM_PDM_SDMA_ADAPTER_USE_EXTRA_BUFFER (1U) 27 #endif 28 29 /* Compile option to force usage of local and extra buffers. 30 * Help saving code space by removing code needed when one of 31 * these buffers is not used. 32 * Will generate errors if application does not configure them. 33 */ 34 #ifndef SRTM_PDM_SDMA_ADAPTER_FORCE_LOCAL_AND_EXTRA_BUFFERS 35 #define SRTM_PDM_SDMA_ADAPTER_FORCE_LOCAL_AND_EXTRA_BUFFERS 0 36 #endif 37 38 #define SRTM_PDM_SDMA_MAX_LOCAL_PERIOD_ALIGNMENT (4U) 39 40 /*! @brief Extra device intitialize function for PDM SDMA adapter. */ 41 typedef void (*pdm_dev_init)(bool enable); 42 /*! @brief Extra device configuration function based on format and sample rate, return PMD clock source in HZ. */ 43 typedef uint32_t (*pdm_dev_conf)(srtm_audio_format_type_t format, uint32_t srate); 44 45 /*! @brief Misc configuration structure. */ 46 typedef struct _pdm_misc_set 47 { 48 pdm_dev_init audioDevInit; /*!< Audio device init function. */ 49 pdm_dev_conf audioDevConf; /*!< config audio device based on format and sample rate, return source clock in HZ */ 50 } pdm_misc_set_t; 51 52 /*! @brief PDM SDMA configuration. */ 53 typedef struct _srtm_pdm_sdma_config 54 { 55 pdm_config_t config; /*!< PDM user configuration. */ 56 pdm_channel_config_t channelConfig; /*!< PDM channel configurations. */ 57 uint32_t pdmSrcClk; /*!< PDM source clock in Hz. */ 58 uint32_t dmaChannel; /*!< DMA channel. */ 59 uint8_t channelPriority; /*!< The priority of DMA channel. */ 60 bool stopOnSuspend; /*!< Stop capture when received suspend command. */ 61 uint32_t eventSource; /*!< DMA request source. */ 62 63 sdma_context_data_t rxContext; 64 pdm_misc_set_t extendConfig; 65 } srtm_pdm_sdma_config_t; 66 67 /*! @brief PDM SDMA local buffer. */ 68 typedef struct _srtm_pdm_sdma_local_buf 69 { 70 uint8_t *buf; /*!< Pointer of the buffer */ 71 uint32_t bufSize; /*!< bytes of the whole local buffer */ 72 uint32_t periods; /*!< periods in local buffer */ 73 uint32_t samplesPerPeriod; /*!< number of samples per period (ignored if set to 0 - otherwise "periods" field is 74 re-computed based on the value and bufSize) */ 75 uint32_t threshold; /*!< Threshold period number: under which will trigger copy from local buffer to extra buffer if 76 extra buffer is used. Otherwise the local buffer is overwritten.*/ 77 } srtm_pdm_sdma_local_buf_t; 78 79 #if SRTM_PDM_SDMA_ADAPTER_USE_EXTRA_BUFFER 80 /*! @brief PDM SDMA extra buffer. When the local buffer is full, the data can be copied to extra buffer. */ 81 typedef struct _srtm_pdm_sdma_ext_buf 82 { 83 uint8_t *buf; /*!< Pointer of the buffer */ 84 uint32_t bufSize; /*!< bytes of the whole extra buffer */ 85 uint32_t periods; /*!< periods in the buffer, it will be recalculated by the driver using given bufSize and local 86 buffer configuration. */ 87 uint32_t bufWriteDmaChannel; /*!< The extra buffer write DMA channel. */ 88 uint32_t bufReadDmaChannel; /*!< The extra buffer read DMA channel. */ 89 uint8_t channelPriority; /*!< The priority of DMA channel. */ 90 } srtm_pdm_sdma_ext_buf_t; 91 #endif 92 93 #if SRTM_PDM_SDMA_ADAPTER_USE_HWVAD 94 typedef enum _srtm_pdm_hwvad_mode 95 { 96 kSRTM_PDM_Hwvad_Disabled = 0U, 97 kSRTM_PDM_Hwvad_EnergyBasedMode = 1U, 98 kSRTM_PDM_Hwvad_EnvelopeBasedMode = 2U, 99 } srtm_pdm_hwvad_mode_t; 100 101 typedef struct _srtm_pdm_hwvad_config 102 { 103 srtm_pdm_hwvad_mode_t mode; 104 pdm_hwvad_config_t hwvadConfig; 105 pdm_hwvad_noise_filter_t noiseFilterConfig; 106 pdm_hwvad_zero_cross_detector_t zcdConfig; 107 uint32_t signalGain; 108 } srtm_pdm_hwvad_config_t; 109 110 /*! @brief HWVAD callback function pointer. The callback is called when voice activity is detected by HWVAD. 111 */ 112 typedef void (*srtm_pdm_sdma_hwvad_callback_t)(srtm_sai_adapter_t adapter, void *params); 113 #endif /* SRTM_PDM_SDMA_ADAPTER_USE_HWVAD */ 114 115 /*! @brief The callback function pointer. Voice data can be passed to application via callback when the host side is 116 * suspend. The callback is also a notification to the application for the host side resumes from suspend when the data 117 * and bytes are 0(NULL). */ 118 typedef void (*srtm_pdm_sdma_data_callback_t)(srtm_sai_adapter_t adapter, void *data, uint32_t bytes, void *params); 119 120 /******************************************************************************* 121 * API 122 ******************************************************************************/ 123 #ifdef __cplusplus 124 extern "C" { 125 #endif 126 127 /*! 128 * @brief Create PDM SDMA adapter. 129 * 130 * @param pdm PDM base address. 131 * @param dma DMA base address. 132 * @param rxConfig PDM Rx channel configuration. 133 * @return SRTM PDM SDMA adapter on success or NULL on failure. 134 */ 135 srtm_sai_adapter_t SRTM_PdmSdmaAdapter_Create(PDM_Type *pdm, SDMAARM_Type *dma, srtm_pdm_sdma_config_t *rxConfig); 136 137 /*! 138 * @brief Destroy PDM SDMA adapter. 139 * 140 * @param adapter PDM SDMA adapter to destroy. 141 */ 142 void SRTM_PdmSdmaAdapter_Destroy(srtm_sai_adapter_t adapter); 143 144 /*! 145 * @brief Get the audio service status. 146 * @param adapter PDM SDMA adapter. 147 * @param pRxState status pointer. 148 */ 149 void SRTM_PdmSdmaAdapter_GetAudioServiceState(srtm_sai_adapter_t adapter, srtm_audio_state_t *pRxState); 150 151 /*! 152 * @brief Set local buffer to use in DMA transfer. If local buffer is set, the audio data will be captured 153 * and transfered to local buffer, then copied to share buffer. Otherwise the data will be 154 * transfered from PDM interface to shared buffer directly. 155 * NOTE: it must be called before service start. 156 * 157 * @param adapter PDM SDMA adapter to set. 158 * @param localBuf Local buffer information to be set to the adapter RX path. 159 */ 160 void SRTM_PdmSdmaAdapter_SetRxLocalBuf(srtm_sai_adapter_t adapter, srtm_pdm_sdma_local_buf_t *localBuf); 161 162 #if SRTM_PDM_SDMA_ADAPTER_USE_EXTRA_BUFFER 163 /*! 164 * @brief Set extra buffer to be used when local buffer is full. The extra buffer could be in external memory. 165 * If extra buffer is set, once the local buffer is full it will not be overwritten, instead the audio data in the local 166 * buffer will be copied to the extra buffer, then copied to the shared buffer. 167 * NOTE: It used only if local buffer is set by SRTM_PdmSdmaAdapter_SetRxLocalBuf and it must be called before service 168 * start. 169 * 170 * @param adapter PDM SDMA adapter to set. 171 * @param extBuf extra buffer information to be set to the adapter RX path. 172 */ 173 void SRTM_PdmSdmaAdapter_SetRxExtBuf(srtm_sai_adapter_t adapter, srtm_pdm_sdma_ext_buf_t *extBuf); 174 #endif /* SRTM_PDM_SDMA_ADAPTER_USE_EXTRA_BUFFER */ 175 176 /*! 177 * @brief When the host driver suspends, voice data can be passed to application via callback. 178 * When the host driver is waking up, the notfication is sent via callback. 179 * The callback is called in SRTM dispatcher task context and should not cost much time. 180 * 181 * @param adapter PDM SDMA adapter instance. 182 * @param cb Callback function pointer. 183 * @param param Callback function argument to be passed back to applicaiton. 184 */ 185 void SRTM_PdmSdmaAdapter_SetDataHandlerOnHostSuspend(srtm_sai_adapter_t adapter, 186 srtm_pdm_sdma_data_callback_t cb, 187 void *param); 188 189 /*! 190 * @brief When key word detected, voice data will be sent to host again. 191 * 192 * @param adapter PDM SDMA adapter instance. 193 */ 194 void SRTM_PdmSdmaAdapter_ResumeHost(srtm_sai_adapter_t adapter); 195 196 /*! 197 * @brief get audio format currently configured on an adapter. 198 * 199 * @return audio format setting 200 */ 201 srtm_audio_format_type_t SRTM_PdmSdmaAdapter_GetDataFormat(srtm_sai_adapter_t adapter); 202 203 #if SRTM_PDM_SDMA_ADAPTER_USE_HWVAD 204 205 /* clang-format off */ 206 /*! 207 * @brief Setup HWVAD. This function is used to configure the HWVAD function of PDM module, the API should be called 208 * before the start of PDM capture. Once successfully configured and HWVAD mode is not kSRTM_PDM_Hwvad_Disabled mode, 209 * the HWVAD will be enabled when the PDM capture starts. SRTM_PdmSdmaAdapter_EnableHwvad can be used to disable or 210 * re-enable the HWVAD function during capture. 211 * Sample configurations for EnvelopeBasedMode, 212 * code 213 * static srtm_pdm_hwvad_config_t pdm_hwvad_config = { 214 * .mode = kSRTM_PDM_Hwvad_EnvelopeBasedMode, 215 * .hwvadConfig.channel = 0U, 216 * .hwvadConfig.initializeTime = 10U, 217 * .hwvadConfig.cicOverSampleRate = 0U, 218 * .hwvadConfig.inputGain = 0U, 219 * .hwvadConfig.frameTime = 10U, 220 * .hwvadConfig.cutOffFreq = kPDM_HwvadHpfBypassed, 221 * .hwvadConfig.enableFrameEnergy = false, 222 * .hwvadConfig.enablePreFilter = true, 223 * .noiseFilterConfig.enableAutoNoiseFilter = false, 224 * .noiseFilterConfig.enableNoiseMin = true, 225 * .noiseFilterConfig.enableNoiseDecimation = true, 226 * .noiseFilterConfig.noiseFilterAdjustment = 0U, 227 * .noiseFilterConfig.noiseGain = 7U, 228 * .noiseFilterConfig.enableNoiseDetectOR = true, 229 * .signalGain = 0U, 230 * }; 231 * code 232 * @param adapter PDM SDMA adapter instance. 233 * @param hwvadConfig The HWVAD configuration structure. 234 * @param cb The callback function pointer. 235 * @param param Callback function argument to be passed back to applicaiton. 236 * @return Configured the HWVAD successfully or with failure. 237 */ 238 /* clang-format on */ 239 srtm_status_t SRTM_PdmSdmaAdapter_ConfigHwvad(srtm_sai_adapter_t adapter, 240 const srtm_pdm_hwvad_config_t *hwvadConfig, 241 srtm_pdm_sdma_hwvad_callback_t cb, 242 void *param); 243 244 /*! 245 * @brief Enable/Disable the HWVAD, this API is used to enable/disable the HWVAD during PDM capture. 246 * 247 * @param adapter PDM SDMA adapter instance. 248 * @param enable Enable or disable the HWVAD. 249 */ 250 void SRTM_PdmSdmaAdapter_EnableHwvad(srtm_sai_adapter_t adapter, bool enable); 251 #endif /* SRTM_PDM_SDMA_ADAPTER_USE_HWVAD */ 252 /******************************************************************************* 253 * Definitions from other files 254 ******************************************************************************/ 255 256 #ifdef __cplusplus 257 } 258 #endif 259 260 /*! @} */ 261 262 #endif /* __SRTM_SAI_SDMA_ADAPTER_H__ */ 263