i2s_std.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * This file is specified for I2S standard communication mode
  8. * Features:
  9. * - Philips/MSB/PCM are supported in standard mode
  10. * - Fixed to 2 slots
  11. */
  12. #pragma once
  13. #include "hal/i2s_types.h"
  14. #include "hal/gpio_types.h"
  15. #include "driver/i2s_common.h"
  16. #include "sdkconfig.h"
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. #if CONFIG_IDF_TARGET_ESP32
  21. /**
  22. * @brief Philips format in 2 slots
  23. * @param bits_per_sample i2s data bit width
  24. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  25. */
  26. #define I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  27. .data_bit_width = bits_per_sample, \
  28. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  29. .slot_mode = mono_or_stereo, \
  30. .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \
  31. I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH, \
  32. .ws_width = bits_per_sample, \
  33. .ws_pol = false, \
  34. .bit_shift = true, \
  35. .msb_right = (bits_per_sample <= I2S_DATA_BIT_WIDTH_16BIT) ? \
  36. true : false, \
  37. }
  38. /**
  39. * @brief PCM(short) format in 2 slots
  40. * @note PCM(long) is same as philips in 2 slots
  41. * @param bits_per_sample i2s data bit width
  42. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  43. */
  44. #define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  45. .data_bit_width = bits_per_sample, \
  46. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  47. .slot_mode = mono_or_stereo, \
  48. .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \
  49. I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH, \
  50. .ws_width = 1, \
  51. .ws_pol = true, \
  52. .bit_shift = true, \
  53. .msb_right = (bits_per_sample <= I2S_DATA_BIT_WIDTH_16BIT) ? \
  54. true : false, \
  55. }
  56. /**
  57. * @brief MSB format in 2 slots
  58. * @param bits_per_sample i2s data bit width
  59. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  60. */
  61. #define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  62. .data_bit_width = bits_per_sample, \
  63. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  64. .slot_mode = mono_or_stereo, \
  65. .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \
  66. I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH, \
  67. .ws_width = bits_per_sample, \
  68. .ws_pol = false, \
  69. .bit_shift = false, \
  70. .msb_right = (bits_per_sample <= I2S_DATA_BIT_WIDTH_16BIT) ? \
  71. true : false, \
  72. }
  73. #elif CONFIG_IDF_TARGET_ESP32S2
  74. /**
  75. * @brief Philips format in 2 slots
  76. * @param bits_per_sample i2s data bit width
  77. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  78. */
  79. #define I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  80. .data_bit_width = bits_per_sample, \
  81. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  82. .slot_mode = mono_or_stereo, \
  83. .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \
  84. I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH, \
  85. .ws_width = bits_per_sample, \
  86. .ws_pol = false, \
  87. .bit_shift = true, \
  88. .msb_right = true, \
  89. }
  90. /**
  91. * @brief PCM(short) format in 2 slots
  92. * @note PCM(long) is same as philips in 2 slots
  93. * @param bits_per_sample i2s data bit width
  94. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  95. */
  96. #define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  97. .data_bit_width = bits_per_sample, \
  98. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  99. .slot_mode = mono_or_stereo, \
  100. .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \
  101. I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH, \
  102. .ws_width = 1, \
  103. .ws_pol = true, \
  104. .bit_shift = true, \
  105. .msb_right = true, \
  106. }
  107. /**
  108. * @brief MSB format in 2 slots
  109. * @param bits_per_sample i2s data bit width
  110. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  111. */
  112. #define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  113. .data_bit_width = bits_per_sample, \
  114. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  115. .slot_mode = mono_or_stereo, \
  116. .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \
  117. I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH, \
  118. .ws_width = bits_per_sample, \
  119. .ws_pol = false, \
  120. .bit_shift = false, \
  121. .msb_right = true, \
  122. }
  123. #else
  124. /**
  125. * @brief Philips format in 2 slots
  126. * @param bits_per_sample i2s data bit width
  127. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  128. */
  129. #define I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  130. .data_bit_width = bits_per_sample, \
  131. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  132. .slot_mode = mono_or_stereo, \
  133. .slot_mask = I2S_STD_SLOT_BOTH, \
  134. .ws_width = bits_per_sample, \
  135. .ws_pol = false, \
  136. .bit_shift = true, \
  137. .left_align = false, \
  138. .big_endian = false, \
  139. .bit_order_lsb = false \
  140. }
  141. /**
  142. * @brief PCM(short) format in 2 slots
  143. * @note PCM(long) is same as philips in 2 slots
  144. * @param bits_per_sample i2s data bit width
  145. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  146. */
  147. #define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  148. .data_bit_width = bits_per_sample, \
  149. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  150. .slot_mode = mono_or_stereo, \
  151. .slot_mask = I2S_STD_SLOT_BOTH, \
  152. .ws_width = 1, \
  153. .ws_pol = true, \
  154. .bit_shift = true, \
  155. .left_align = false, \
  156. .big_endian = false, \
  157. .bit_order_lsb = false \
  158. }
  159. /**
  160. * @brief MSB format in 2 slots
  161. * @param bits_per_sample i2s data bit width
  162. * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  163. */
  164. #define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
  165. .data_bit_width = bits_per_sample, \
  166. .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \
  167. .slot_mode = mono_or_stereo, \
  168. .slot_mask = I2S_STD_SLOT_BOTH, \
  169. .ws_width = bits_per_sample, \
  170. .ws_pol = false, \
  171. .bit_shift = false, \
  172. .left_align = false, \
  173. .big_endian = false, \
  174. .bit_order_lsb = false \
  175. }
  176. #endif
  177. /** @cond */
  178. #define I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) \
  179. I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) // Alias
  180. /** @endcond */
  181. /**
  182. * @brief i2s default standard clock configuration
  183. * @note Please set the mclk_multiple to I2S_MCLK_MULTIPLE_384 while using 24 bits data width
  184. * Otherwise the sample rate might be imprecise since the bclk division is not a integer
  185. * @param rate sample rate
  186. */
  187. #define I2S_STD_CLK_DEFAULT_CONFIG(rate) { \
  188. .sample_rate_hz = rate, \
  189. .clk_src = I2S_CLK_SRC_DEFAULT, \
  190. .mclk_multiple = I2S_MCLK_MULTIPLE_256, \
  191. }
  192. /**
  193. * @brief I2S slot configuration for standard mode
  194. */
  195. typedef struct {
  196. /* General fields */
  197. i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample) */
  198. i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) */
  199. i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  200. * In TX direction, mono means the written buffer contains only one slot data
  201. * and stereo means the written buffer contains both left and right data
  202. */
  203. /* Particular fields */
  204. i2s_std_slot_mask_t slot_mask; /*!< Select the left, right or both slot */
  205. uint32_t ws_width; /*!< WS signal width (i.e. the number of bclk ticks that ws signal is high) */
  206. bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */
  207. bool bit_shift; /*!< Set to enable bit shift in Philips mode */
  208. #if SOC_I2S_HW_VERSION_1 // For esp32/esp32-s2
  209. bool msb_right; /*!< Set to place right channel data at the MSB in the FIFO */
  210. #else
  211. bool left_align; /*!< Set to enable left alignment */
  212. bool big_endian; /*!< Set to enable big endian */
  213. bool bit_order_lsb; /*!< Set to enable lsb first */
  214. #endif
  215. } i2s_std_slot_config_t;
  216. /**
  217. * @brief I2S clock configuration for standard mode
  218. */
  219. typedef struct {
  220. /* General fields */
  221. uint32_t sample_rate_hz; /*!< I2S sample rate */
  222. i2s_clock_src_t clk_src; /*!< Choose clock source */
  223. i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate
  224. * Default is 256 in the helper macro, it can satisfy most of cases,
  225. * but please set this field a multiple of '3' (like 384) when using 24-bit data width,
  226. * otherwise the sample rate might be inaccurate
  227. */
  228. } i2s_std_clk_config_t;
  229. /**
  230. * @brief I2S standard mode GPIO pins configuration
  231. */
  232. typedef struct {
  233. gpio_num_t mclk; /*!< MCK pin, output */
  234. gpio_num_t bclk; /*!< BCK pin, input in slave role, output in master role */
  235. gpio_num_t ws; /*!< WS pin, input in slave role, output in master role */
  236. gpio_num_t dout; /*!< DATA pin, output */
  237. gpio_num_t din; /*!< DATA pin, input */
  238. struct {
  239. uint32_t mclk_inv: 1; /*!< Set 1 to invert the mclk output */
  240. uint32_t bclk_inv: 1; /*!< Set 1 to invert the bclk input/output */
  241. uint32_t ws_inv: 1; /*!< Set 1 to invert the ws input/output */
  242. } invert_flags; /*!< GPIO pin invert flags */
  243. } i2s_std_gpio_config_t;
  244. /**
  245. * @brief I2S standard mode major configuration that including clock/slot/gpio configuration
  246. */
  247. typedef struct {
  248. i2s_std_clk_config_t clk_cfg; /*!< Standard mode clock configuration, can be generated by macro I2S_STD_CLK_DEFAULT_CONFIG */
  249. i2s_std_slot_config_t slot_cfg; /*!< Standard mode slot configuration, can be generated by macros I2S_STD_[mode]_SLOT_DEFAULT_CONFIG, [mode] can be replaced with PHILIPS/MSB/PCM */
  250. i2s_std_gpio_config_t gpio_cfg; /*!< Standard mode gpio configuration, specified by user */
  251. } i2s_std_config_t;
  252. /**
  253. * @brief Initialize i2s channel to standard mode
  254. * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized)
  255. * and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED.
  256. *
  257. * @param[in] handle I2S channel handler
  258. * @param[in] std_cfg Configurations for standard mode, including clock, slot and gpio
  259. * The clock configuration can be generated by the helper macro `I2S_STD_CLK_DEFAULT_CONFIG`
  260. * The slot configuration can be generated by the helper macro `I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG`,
  261. * `I2S_STD_PCM_SLOT_DEFAULT_CONFIG` or `I2S_STD_MSB_SLOT_DEFAULT_CONFIG`
  262. *
  263. * @return
  264. * - ESP_OK Initialize successfully
  265. * - ESP_ERR_NO_MEM No memory for storing the channel information
  266. * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration
  267. * - ESP_ERR_INVALID_STATE This channel is not registered
  268. */
  269. esp_err_t i2s_channel_init_std_mode(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg);
  270. /**
  271. * @brief Reconfigure the I2S clock for standard mode
  272. * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started
  273. * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started.
  274. * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfiguring
  275. *
  276. * @param[in] handle I2S channel handler
  277. * @param[in] clk_cfg Standard mode clock configuration, can be generated by `I2S_STD_CLK_DEFAULT_CONFIG`
  278. * @return
  279. * - ESP_OK Set clock successfully
  280. * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
  281. * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
  282. */
  283. esp_err_t i2s_channel_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg);
  284. /**
  285. * @brief Reconfigure the I2S slot for standard mode
  286. * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started
  287. * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started.
  288. * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfiguring
  289. *
  290. * @param[in] handle I2S channel handler
  291. * @param[in] slot_cfg Standard mode slot configuration, can be generated by `I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG`,
  292. * `I2S_STD_PCM_SLOT_DEFAULT_CONFIG` and `I2S_STD_MSB_SLOT_DEFAULT_CONFIG`.
  293. * @return
  294. * - ESP_OK Set clock successfully
  295. * - ESP_ERR_NO_MEM No memory for DMA buffer
  296. * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
  297. * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
  298. */
  299. esp_err_t i2s_channel_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg);
  300. /**
  301. * @brief Reconfigure the I2S gpio for standard mode
  302. * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started
  303. * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started.
  304. * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfiguring
  305. *
  306. * @param[in] handle I2S channel handler
  307. * @param[in] gpio_cfg Standard mode gpio configuration, specified by user
  308. * @return
  309. * - ESP_OK Set clock successfully
  310. * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
  311. * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
  312. */
  313. esp_err_t i2s_channel_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg);
  314. #ifdef __cplusplus
  315. }
  316. #endif