fsl_dmic.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_dmic.h"
  31. /*******************************************************************************
  32. * Variables
  33. ******************************************************************************/
  34. /* Array of DMIC peripheral base address. */
  35. static DMIC_Type *const s_dmicBases[FSL_FEATURE_SOC_DMIC_COUNT] = DMIC_BASE_PTRS;
  36. /* Array of DMIC clock name. */
  37. static const clock_ip_name_t s_dmicClock[FSL_FEATURE_SOC_DMIC_COUNT] = DMIC_CLOCKS;
  38. /* Array of DMIC IRQ number. */
  39. static const IRQn_Type s_dmicIRQ[FSL_FEATURE_SOC_DMIC_COUNT] = DMIC_IRQS;
  40. /*! @brief Callback function array for DMIC(s). */
  41. static dmic_callback_t s_dmicCallback[FSL_FEATURE_SOC_DMIC_COUNT];
  42. /* Array of HWVAD IRQ number. */
  43. static const IRQn_Type s_dmicHwvadIRQ[FSL_FEATURE_SOC_DMIC_COUNT] = DMIC_HWVAD_IRQS;
  44. /*! @brief Callback function array for HWVAD(s). */
  45. static dmic_hwvad_callback_t s_dmicHwvadCallback[FSL_FEATURE_SOC_DMIC_COUNT];
  46. /*******************************************************************************
  47. * Prototypes
  48. ******************************************************************************/
  49. /*!
  50. * @brief Get the DMIC instance from peripheral base address.
  51. *
  52. * @param base DMIC peripheral base address.
  53. * @return DMIC instance.
  54. */
  55. uint32_t DMIC_GetInstance(DMIC_Type *base)
  56. {
  57. uint32_t instance;
  58. /* Find the instance index from base address mappings. */
  59. for (instance = 0; instance < ARRAY_SIZE(s_dmicBases); instance++)
  60. {
  61. if (s_dmicBases[instance] == base)
  62. {
  63. break;
  64. }
  65. }
  66. assert(instance < ARRAY_SIZE(s_dmicBases));
  67. return instance;
  68. }
  69. void DMIC_Init(DMIC_Type *base)
  70. {
  71. assert(base);
  72. /* Enable the clock to the register interface */
  73. CLOCK_EnableClock(s_dmicClock[DMIC_GetInstance(base)]);
  74. /* Reset the peripheral */
  75. RESET_PeripheralReset(kDMIC_RST_SHIFT_RSTn);
  76. /* Disable DMA request*/
  77. base->CHANNEL[0].FIFO_CTRL &= ~DMIC_CHANNEL_FIFO_CTRL_DMAEN(1);
  78. base->CHANNEL[1].FIFO_CTRL &= ~DMIC_CHANNEL_FIFO_CTRL_DMAEN(1);
  79. /* Disable DMIC interrupt. */
  80. base->CHANNEL[0].FIFO_CTRL &= ~DMIC_CHANNEL_FIFO_CTRL_INTEN(1);
  81. base->CHANNEL[1].FIFO_CTRL &= ~DMIC_CHANNEL_FIFO_CTRL_INTEN(1);
  82. }
  83. void DMIC_DeInit(DMIC_Type *base)
  84. {
  85. assert(base);
  86. /* Disable the clock to the register interface */
  87. CLOCK_DisableClock(s_dmicClock[DMIC_GetInstance(base)]);
  88. }
  89. void DMIC_ConfigIO(DMIC_Type *base, dmic_io_t config)
  90. {
  91. base->IOCFG = config;
  92. }
  93. void DMIC_SetOperationMode(DMIC_Type *base, operation_mode_t mode)
  94. {
  95. if (mode == kDMIC_OperationModeInterrupt)
  96. {
  97. /* Enable DMIC interrupt. */
  98. base->CHANNEL[0].FIFO_CTRL |= DMIC_CHANNEL_FIFO_CTRL_INTEN(1);
  99. base->CHANNEL[1].FIFO_CTRL |= DMIC_CHANNEL_FIFO_CTRL_INTEN(1);
  100. }
  101. if (mode == kDMIC_OperationModeDma)
  102. {
  103. /* enable DMA request*/
  104. base->CHANNEL[0].FIFO_CTRL |= DMIC_CHANNEL_FIFO_CTRL_DMAEN(1);
  105. base->CHANNEL[1].FIFO_CTRL |= DMIC_CHANNEL_FIFO_CTRL_DMAEN(1);
  106. }
  107. }
  108. void DMIC_ConfigChannel(DMIC_Type *base,
  109. dmic_channel_t channel,
  110. stereo_side_t side,
  111. dmic_channel_config_t *channel_config)
  112. {
  113. base->CHANNEL[channel].DIVHFCLK = channel_config->divhfclk;
  114. base->CHANNEL[channel].OSR = channel_config->osr;
  115. base->CHANNEL[channel].GAINSHIFT = channel_config->gainshft;
  116. base->CHANNEL[channel].PREAC2FSCOEF = channel_config->preac2coef;
  117. base->CHANNEL[channel].PREAC4FSCOEF = channel_config->preac4coef;
  118. base->CHANNEL[channel].PHY_CTRL =
  119. DMIC_CHANNEL_PHY_CTRL_PHY_FALL(side) | DMIC_CHANNEL_PHY_CTRL_PHY_HALF(channel_config->sample_rate);
  120. base->CHANNEL[channel].DC_CTRL = DMIC_CHANNEL_DC_CTRL_DCPOLE(channel_config->dc_cut_level) |
  121. DMIC_CHANNEL_DC_CTRL_DCGAIN(channel_config->post_dc_gain_reduce) |
  122. DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT(channel_config->saturate16bit);
  123. }
  124. void DMIC_CfgChannelDc(DMIC_Type *base,
  125. dmic_channel_t channel,
  126. dc_removal_t dc_cut_level,
  127. uint32_t post_dc_gain_reduce,
  128. bool saturate16bit)
  129. {
  130. base->CHANNEL[channel].DC_CTRL = DMIC_CHANNEL_DC_CTRL_DCPOLE(dc_cut_level) |
  131. DMIC_CHANNEL_DC_CTRL_DCGAIN(post_dc_gain_reduce) |
  132. DMIC_CHANNEL_DC_CTRL_SATURATEAT16BIT(saturate16bit);
  133. }
  134. void DMIC_Use2fs(DMIC_Type *base, bool use2fs)
  135. {
  136. base->USE2FS = (use2fs) ? 0x1 : 0x0;
  137. }
  138. void DMIC_EnableChannnel(DMIC_Type *base, uint32_t channelmask)
  139. {
  140. base->CHANEN = channelmask;
  141. }
  142. void DMIC_FifoChannel(DMIC_Type *base, uint32_t channel, uint32_t trig_level, uint32_t enable, uint32_t resetn)
  143. {
  144. base->CHANNEL[channel].FIFO_CTRL |=
  145. (base->CHANNEL[channel].FIFO_CTRL & (DMIC_CHANNEL_FIFO_CTRL_INTEN_MASK | DMIC_CHANNEL_FIFO_CTRL_DMAEN_MASK)) |
  146. DMIC_CHANNEL_FIFO_CTRL_TRIGLVL(trig_level) | DMIC_CHANNEL_FIFO_CTRL_ENABLE(enable) |
  147. DMIC_CHANNEL_FIFO_CTRL_RESETN(resetn);
  148. }
  149. void DMIC_EnableIntCallback(DMIC_Type *base, dmic_callback_t cb)
  150. {
  151. uint32_t instance;
  152. instance = DMIC_GetInstance(base);
  153. NVIC_ClearPendingIRQ(s_dmicIRQ[instance]);
  154. /* Save callback pointer */
  155. s_dmicCallback[instance] = cb;
  156. EnableIRQ(s_dmicIRQ[instance]);
  157. }
  158. void DMIC_DisableIntCallback(DMIC_Type *base, dmic_callback_t cb)
  159. {
  160. uint32_t instance;
  161. instance = DMIC_GetInstance(base);
  162. DisableIRQ(s_dmicIRQ[instance]);
  163. s_dmicCallback[instance] = NULL;
  164. NVIC_ClearPendingIRQ(s_dmicIRQ[instance]);
  165. }
  166. void DMIC_HwvadEnableIntCallback(DMIC_Type *base, dmic_hwvad_callback_t vadcb)
  167. {
  168. uint32_t instance;
  169. instance = DMIC_GetInstance(base);
  170. NVIC_ClearPendingIRQ(s_dmicHwvadIRQ[instance]);
  171. /* Save callback pointer */
  172. s_dmicHwvadCallback[instance] = vadcb;
  173. EnableIRQ(s_dmicHwvadIRQ[instance]);
  174. }
  175. void DMIC_HwvadDisableIntCallback(DMIC_Type *base, dmic_hwvad_callback_t vadcb)
  176. {
  177. uint32_t instance;
  178. instance = DMIC_GetInstance(base);
  179. DisableIRQ(s_dmicHwvadIRQ[instance]);
  180. s_dmicHwvadCallback[instance] = NULL;
  181. NVIC_ClearPendingIRQ(s_dmicHwvadIRQ[instance]);
  182. }
  183. /* IRQ handler functions overloading weak symbols in the startup */
  184. #if defined(DMIC0)
  185. /*DMIC0 IRQ handler */
  186. void DMIC0_DriverIRQHandler(void)
  187. {
  188. if (s_dmicCallback[0] != NULL)
  189. {
  190. s_dmicCallback[0]();
  191. }
  192. }
  193. /*DMIC0 HWVAD IRQ handler */
  194. void HWVAD0_IRQHandler(void)
  195. {
  196. if (s_dmicHwvadCallback[0] != NULL)
  197. {
  198. s_dmicHwvadCallback[0]();
  199. }
  200. }
  201. #endif