nrf_drv_pdm.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. #include "nrf_drv_pdm.h"
  13. #include "nrf_assert.h"
  14. #include "nrf_drv_common.h"
  15. #include "nrf_gpio.h"
  16. /** @brief PDM interface status. */
  17. typedef enum
  18. {
  19. NRF_PDM_STATE_IDLE,
  20. NRF_PDM_STATE_RUNNING,
  21. NRF_PDM_STATE_TRANSITION
  22. } nrf_drv_pdm_state_t;
  23. /** @brief PDM interface control block.*/
  24. typedef struct
  25. {
  26. nrf_drv_state_t drv_state; ///< Driver state.
  27. nrf_drv_pdm_state_t status; ///< Sampling state.
  28. nrf_drv_pdm_event_handler_t event_handler; ///< Event handler function pointer.
  29. uint16_t buffer_length; ///< Length of a single buffer in 16-bit words.
  30. uint32_t * buffers[2]; ///< Sample buffers.
  31. } nrf_drv_pdm_cb_t;
  32. static nrf_drv_pdm_cb_t m_cb;
  33. void PDM_IRQHandler(void)
  34. {
  35. if (nrf_pdm_event_check(NRF_PDM_EVENT_END))
  36. {
  37. nrf_pdm_event_clear(NRF_PDM_EVENT_END);
  38. //Buffer is ready to process.
  39. if (nrf_pdm_buffer_get() == m_cb.buffers[0])
  40. {
  41. m_cb.event_handler(m_cb.buffers[1], m_cb.buffer_length);
  42. }
  43. else
  44. {
  45. m_cb.event_handler(m_cb.buffers[0], m_cb.buffer_length);
  46. }
  47. }
  48. else if (nrf_pdm_event_check(NRF_PDM_EVENT_STARTED))
  49. {
  50. nrf_pdm_event_clear(NRF_PDM_EVENT_STARTED);
  51. m_cb.status = NRF_PDM_STATE_RUNNING;
  52. //Swap buffer.
  53. if (nrf_pdm_buffer_get() == m_cb.buffers[0])
  54. {
  55. nrf_pdm_buffer_set(m_cb.buffers[1],m_cb.buffer_length);
  56. }
  57. else
  58. {
  59. nrf_pdm_buffer_set(m_cb.buffers[0],m_cb.buffer_length);
  60. }
  61. }
  62. else if (nrf_pdm_event_check(NRF_PDM_EVENT_STOPPED))
  63. {
  64. nrf_pdm_event_clear(NRF_PDM_EVENT_STOPPED);
  65. nrf_pdm_disable();
  66. m_cb.status = NRF_PDM_STATE_IDLE;
  67. }
  68. }
  69. ret_code_t nrf_drv_pdm_init(nrf_drv_pdm_config_t const * p_config,
  70. nrf_drv_pdm_event_handler_t event_handler)
  71. {
  72. if (m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED)
  73. {
  74. return NRF_ERROR_INVALID_STATE;
  75. }
  76. if ((p_config == NULL)
  77. || (event_handler == NULL))
  78. {
  79. return NRF_ERROR_INVALID_PARAM;
  80. }
  81. if (p_config->gain_l > NRF_PDM_GAIN_MAXIMUM
  82. || p_config->gain_r > NRF_PDM_GAIN_MAXIMUM
  83. || p_config->buffer_length > NRF_PDM_MAX_BUFFER_SIZE)
  84. {
  85. return NRF_ERROR_INVALID_PARAM;
  86. }
  87. m_cb.buffers[0] = (uint32_t*)p_config->buffer_a;
  88. m_cb.buffers[1] = (uint32_t*)p_config->buffer_b;
  89. m_cb.buffer_length = p_config->buffer_length;
  90. m_cb.event_handler = event_handler;
  91. m_cb.status = NRF_PDM_STATE_IDLE;
  92. nrf_pdm_buffer_set(m_cb.buffers[0],m_cb.buffer_length);
  93. nrf_pdm_clock_set(p_config->clock_freq);
  94. nrf_pdm_mode_set(p_config->mode, p_config->edge);
  95. nrf_pdm_gain_set(p_config->gain_l, p_config->gain_r);
  96. nrf_gpio_cfg_output(p_config->pin_clk);
  97. nrf_gpio_pin_clear(p_config->pin_clk);
  98. nrf_gpio_cfg_input(p_config->pin_din, NRF_GPIO_PIN_NOPULL);
  99. nrf_pdm_psel_connect(p_config->pin_clk, p_config->pin_din);
  100. m_cb.drv_state = NRF_DRV_STATE_INITIALIZED;
  101. nrf_pdm_int_enable(NRF_PDM_INT_STARTED | NRF_PDM_INT_END | NRF_PDM_INT_STOPPED);
  102. nrf_drv_common_irq_enable(PDM_IRQn, p_config->interrupt_priority);
  103. return NRF_SUCCESS;
  104. }
  105. void nrf_drv_pdm_uninit(void)
  106. {
  107. nrf_pdm_disable();
  108. nrf_pdm_psel_disconnect();
  109. m_cb.drv_state = NRF_DRV_STATE_UNINITIALIZED;
  110. }
  111. ret_code_t nrf_drv_pdm_start(void)
  112. {
  113. ASSERT(m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED);
  114. if (m_cb.status != NRF_PDM_STATE_IDLE)
  115. {
  116. if (m_cb.status == NRF_PDM_STATE_RUNNING)
  117. {
  118. return NRF_SUCCESS;
  119. }
  120. return NRF_ERROR_BUSY;
  121. }
  122. m_cb.status = NRF_PDM_STATE_TRANSITION;
  123. m_cb.drv_state = NRF_DRV_STATE_POWERED_ON;
  124. nrf_pdm_enable();
  125. nrf_pdm_event_clear(NRF_PDM_EVENT_STARTED);
  126. nrf_pdm_task_trigger(NRF_PDM_TASK_START);
  127. return NRF_SUCCESS;
  128. }
  129. ret_code_t nrf_drv_pdm_stop(void)
  130. {
  131. ASSERT(m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED);
  132. if (m_cb.status != NRF_PDM_STATE_RUNNING)
  133. {
  134. if (m_cb.status == NRF_PDM_STATE_IDLE)
  135. {
  136. nrf_pdm_disable();
  137. return NRF_SUCCESS;
  138. }
  139. return NRF_ERROR_BUSY;
  140. }
  141. m_cb.status = NRF_PDM_STATE_TRANSITION;
  142. m_cb.drv_state = NRF_DRV_STATE_INITIALIZED;
  143. nrf_pdm_task_trigger(NRF_PDM_TASK_STOP);
  144. return NRF_SUCCESS;
  145. }