i2s_private.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include "freertos/FreeRTOS.h"
  8. #include "soc/lldesc.h"
  9. #include "soc/soc_caps.h"
  10. #include "hal/i2s_types.h"
  11. #include "driver/i2s_types.h"
  12. #include "freertos/semphr.h"
  13. #include "freertos/queue.h"
  14. #if SOC_GDMA_SUPPORTED
  15. #include "esp_private/gdma.h"
  16. #endif
  17. #include "esp_pm.h"
  18. #include "esp_err.h"
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. #define I2S_NULL_POINTER_CHECK(tag, p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, tag, "input parameter '"#p"' is NULL")
  23. /**
  24. * @brief i2s channel state for checking if the operation in under right driver state
  25. */
  26. typedef enum {
  27. I2S_CHAN_STATE_REGISTER, /*!< i2s channel is registered (not initialized) */
  28. I2S_CHAN_STATE_READY, /*!< i2s channel is disabled (initialized) */
  29. I2S_CHAN_STATE_RUNNING, /*!< i2s channel is idling (initialized and enabled) */
  30. } i2s_state_t;
  31. /**
  32. * @brief i2s channel level configurations
  33. * @note It performs as channel handle
  34. */
  35. typedef struct {
  36. #if SOC_GDMA_SUPPORTED
  37. gdma_channel_handle_t dma_chan; /*!< gdma channel handle */
  38. #else
  39. intr_handle_t dma_chan; /*!< interrupt channel handle */
  40. #endif
  41. uint32_t desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */
  42. uint32_t frame_num; /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots */
  43. uint32_t buf_size; /*!< dma buffer size */
  44. bool auto_clear; /*!< Set to auto clear DMA TX descriptor, i2s will always send zero automatically if no data to send */
  45. uint32_t rw_pos; /*!< reading/writing pointer position */
  46. void *curr_ptr; /*!< Pointer to current dma buffer */
  47. lldesc_t **desc; /*!< dma descriptor array */
  48. uint8_t **bufs; /*!< dma buffer array */
  49. } i2s_dma_t;
  50. /**
  51. * @brief i2s controller level configurations
  52. * @note Both i2s rx and tx channel are under its control
  53. */
  54. typedef struct {
  55. i2s_port_t id; /*!< i2s port id */
  56. i2s_hal_context_t hal; /*!< hal context */
  57. uint32_t chan_occupancy; /*!< channel occupancy (rx/tx) */
  58. bool full_duplex; /*!< is full_duplex */
  59. i2s_chan_handle_t tx_chan; /*!< tx channel handler */
  60. i2s_chan_handle_t rx_chan; /*!< rx channel handler */
  61. int mclk; /*!< MCK out pin, shared by tx/rx*/
  62. } i2s_controller_t;
  63. struct i2s_channel_t {
  64. /* Channel basic information */
  65. i2s_controller_t *controller; /*!< Parent pointer to controller object */
  66. i2s_comm_mode_t mode; /*!< i2s channel communication mode */
  67. i2s_role_t role; /*!< i2s role */
  68. i2s_dir_t dir; /*!< i2s channel direction */
  69. i2s_dma_t dma; /*!< i2s dma object */
  70. i2s_state_t state; /*!< i2s driver state. Ensuring the driver working in a correct sequence */
  71. /* Stored configurations */
  72. void *mode_info; /*!< Slot, clock and gpio information of each mode */
  73. #if SOC_I2S_SUPPORTS_APLL
  74. bool apll_en; /*!< Flag of wether APLL enabled */
  75. #endif
  76. uint32_t active_slot; /*!< Active slot number */
  77. uint32_t total_slot; /*!< Total slot number */
  78. /* Locks and queues */
  79. SemaphoreHandle_t mutex; /*!< Mutex semaphore for the channel operations */
  80. SemaphoreHandle_t binary; /*!< Binary semaphore for writing / reading / enabling / disabling */
  81. #if CONFIG_PM_ENABLE
  82. esp_pm_lock_handle_t pm_lock; /*!< Power management lock, to avoid apb clock frequency changes while i2s is working */
  83. #endif
  84. #if CONFIG_I2S_ISR_IRAM_SAFE
  85. StaticSemaphore_t *mutex_struct; /*!< Static mutex struct */
  86. StaticSemaphore_t *binary_struct; /*!< Static binary struct */
  87. StaticQueue_t *msg_que_struct; /*!< Static message queue struct */
  88. void *msg_que_storage; /*!< Static message queue storage */
  89. #endif
  90. QueueHandle_t msg_queue; /*!< Message queue handler, used for transporting data between interrupt and read/write task */
  91. i2s_event_callbacks_t callbacks; /*!< Callback functions */
  92. void *user_data; /*!< User data for callback functions */
  93. void (*start)(i2s_chan_handle_t); /*!< start tx/rx channel */
  94. void (*stop)(i2s_chan_handle_t); /*!< stop tx/rx channel */
  95. };
  96. /**
  97. * @brief i2s platform level configurations
  98. * @note All i2s controllers' resources are involved
  99. */
  100. typedef struct {
  101. portMUX_TYPE spinlock; /*!< Platform level lock */
  102. i2s_controller_t *controller[SOC_I2S_NUM]; /*!< Controller object */
  103. const char *comp_name[SOC_I2S_NUM]; /*!< The component name that occupied i2s controller */
  104. } i2s_platform_t;
  105. extern i2s_platform_t g_i2s;
  106. /**
  107. * @brief Initialize I2S DMA interrupt
  108. *
  109. * @param handle I2S channel handle
  110. * @param intr_flag I2S interrupt flags, `ESP_INTR_FLAG_XXX` defined in `esp_intr_alloc.h`
  111. * @return
  112. * - ESP_OK Initialize interrupt success
  113. * - ESP_ERR_INVALID_ARG Wrong port id or NULL pointer
  114. */
  115. esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag);
  116. /**
  117. * @brief Free I2S DMA descriptor and DMA buffer
  118. *
  119. * @param handle I2S channel handle
  120. * @return
  121. * - ESP_OK Free success
  122. * - ESP_ERR_INVALID_ARG NULL pointer
  123. */
  124. esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle);
  125. /**
  126. * @brief Allocate memory for I2S DMA descriptor and DMA buffer
  127. *
  128. * @param handle I2S channel handle
  129. * @param num Number of DMA descriptors
  130. * @param bufsize The DMA buffer size
  131. *
  132. * @return
  133. * - ESP_OK Allocate memory success
  134. * - ESP_ERR_INVALID_ARG NULL pointer or bufsize is too big
  135. * - ESP_ERR_NO_MEM No memmory for DMA descriptor and DMA buffer
  136. */
  137. esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize);
  138. /**
  139. * @brief Get DMA buffer size
  140. *
  141. * @param handle I2S channel handle
  142. * @param data_bit_width Data bit width in one slot
  143. * @param dma_frame_num Frame number in one DMA buffer
  144. *
  145. * @return
  146. * - DMA buffer size
  147. */
  148. uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uint32_t dma_frame_num);
  149. #if SOC_I2S_SUPPORTS_APLL
  150. /**
  151. * @brief Set mclk frequency and get the actuall APLL frequency
  152. *
  153. * @param mclk_freq_hz Expected mclk frequenct in Hz
  154. * @return
  155. * - Actuall APLL frequency
  156. */
  157. uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz);
  158. #endif
  159. /**
  160. * @brief Check gpio validity and attach to corresponding signal
  161. *
  162. * @param gpio GPIO number
  163. * @param signal_idx Signal index
  164. * @param is_input Is input gpio
  165. * @param is_invert Is invert gpio
  166. */
  167. void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input, bool is_invert);
  168. /**
  169. * @brief Check gpio validity and output mclk signal
  170. *
  171. * @param id I2S port id
  172. * @param gpio_num GPIO number
  173. * @param is_apll Is using APLL as clock source
  174. * @param is_invert Is invert the GPIO
  175. * @return
  176. * - ESP_OK Set mclk output gpio success
  177. * - ESP_ERR_INVALID_ARG Invalid GPIO number
  178. */
  179. esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num, bool is_apll, bool is_invert);
  180. /**
  181. * @brief Attach data out signal and data in signal to a same gpio
  182. *
  183. * @param gpio GPIO number
  184. * @param out_sig_idx Data out signal index
  185. * @param in_sig_idx Data in signal index
  186. */
  187. void i2s_gpio_loopback_set(gpio_num_t gpio, uint32_t out_sig_idx, uint32_t in_sig_idx);
  188. #ifdef __cplusplus
  189. }
  190. #endif