i2s_std.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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. * - Philip/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 Philip 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_PHILIP_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 sample as philip 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 Philip 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_PHILIP_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 sample as philip 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 Philip 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_PHILIP_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 sample as philip 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. /**
  178. * @brief i2s default standard clock configuration
  179. * @note Please set the mclk_multiple to I2S_MCLK_MULTIPLE_384 while using 24 bits data width
  180. * Otherwise the sample rate might be imprecise since the bclk division is not a integer
  181. * @param rate sample rate
  182. */
  183. #define I2S_STD_CLK_DEFAULT_CONFIG(rate) { \
  184. .sample_rate_hz = rate, \
  185. .clk_src = I2S_CLK_SRC_DEFAULT, \
  186. .mclk_multiple = I2S_MCLK_MULTIPLE_256, \
  187. }
  188. /**
  189. * @brief I2S slot configuration for standard mode
  190. */
  191. typedef struct {
  192. /* General fields */
  193. i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample) */
  194. i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) */
  195. i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
  196. * In TX direction, mono means the written buffer contains only one slot data
  197. * and stereo means the written buffer contains both left and right data
  198. */
  199. /* Particular fields */
  200. i2s_std_slot_mask_t slot_mask; /*!< Select the left, right or both slot */
  201. uint32_t ws_width; /*!< WS signal width (i.e. the number of bclk ticks that ws signal is high) */
  202. bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */
  203. bool bit_shift; /*!< Set to enbale bit shift in Philip mode */
  204. #if SOC_I2S_HW_VERSION_1 // For esp32/esp32-s2
  205. bool msb_right; /*!< Set to place right channel data at the MSB in the FIFO */
  206. #else
  207. bool left_align; /*!< Set to enable left alignment */
  208. bool big_endian; /*!< Set to enable big endian */
  209. bool bit_order_lsb; /*!< Set to enable lsb first */
  210. #endif
  211. } i2s_std_slot_config_t;
  212. /**
  213. * @brief I2S clock configuration for standard mode
  214. */
  215. typedef struct {
  216. /* General fields */
  217. uint32_t sample_rate_hz; /*!< I2S sample rate */
  218. i2s_clock_src_t clk_src; /*!< Choose clock source */
  219. i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate
  220. * Default is 256 in the helper macro, it can satisfy most of cases,
  221. * but please set this field a multiple of '3' (like 384) when using 24-bit data width,
  222. * otherwise the sample rate might be inaccurate
  223. */
  224. } i2s_std_clk_config_t;
  225. /**
  226. * @brief I2S standard mode GPIO pins configuration
  227. */
  228. typedef struct {
  229. gpio_num_t mclk; /*!< MCK pin, output */
  230. gpio_num_t bclk; /*!< BCK pin, input in slave role, output in master role */
  231. gpio_num_t ws; /*!< WS pin, input in slave role, output in master role */
  232. gpio_num_t dout; /*!< DATA pin, output */
  233. gpio_num_t din; /*!< DATA pin, input */
  234. struct {
  235. uint32_t mclk_inv: 1; /*!< Set 1 to invert the mclk output */
  236. uint32_t bclk_inv: 1; /*!< Set 1 to invert the bclk input/output */
  237. uint32_t ws_inv: 1; /*!< Set 1 to invert the ws input/output */
  238. } invert_flags; /*!< GPIO pin invert flags */
  239. } i2s_std_gpio_config_t;
  240. /**
  241. * @brief I2S standard mode major configuration that including clock/slot/gpio configuration
  242. */
  243. typedef struct {
  244. i2s_std_clk_config_t clk_cfg; /*!< Standard mode clock configuration, can be generated by macro I2S_STD_CLK_DEFAULT_CONFIG */
  245. 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 PHILIP/MSB/PCM */
  246. i2s_std_gpio_config_t gpio_cfg; /*!< Standard mode gpio configuration, specified by user */
  247. } i2s_std_config_t;
  248. /**
  249. * @brief Initialize i2s channel to standard mode
  250. * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized)
  251. * and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED.
  252. *
  253. * @param[in] handle I2S channel handler
  254. * @param[in] std_cfg Configurations for standard mode, including clock, slot and gpio
  255. * The clock configuration can be generated by the helper macro `I2S_STD_CLK_DEFAULT_CONFIG`
  256. * The slot configuration can be generated by the helper macro `I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG`,
  257. * `I2S_STD_PCM_SLOT_DEFAULT_CONFIG` or `I2S_STD_MSB_SLOT_DEFAULT_CONFIG`
  258. *
  259. * @return
  260. * - ESP_OK Initialize successfully
  261. * - ESP_ERR_NO_MEM No memory for storing the channel information
  262. * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration
  263. * - ESP_ERR_INVALID_STATE This channel is not registered
  264. */
  265. esp_err_t i2s_channel_init_std_mode(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg);
  266. /**
  267. * @brief Reconfigure the I2S clock for standard mode
  268. * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started
  269. * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started.
  270. * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfigring
  271. *
  272. * @param[in] handle I2S channel handler
  273. * @param[in] clk_cfg Standard mode clock configuration, can be generated by `I2S_STD_CLK_DEFAULT_CONFIG`
  274. * @return
  275. * - ESP_OK Set clock successfully
  276. * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
  277. * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
  278. */
  279. esp_err_t i2s_channel_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg);
  280. /**
  281. * @brief Reconfigure the I2S slot for standard mode
  282. * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started
  283. * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started.
  284. * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfigring
  285. *
  286. * @param[in] handle I2S channel handler
  287. * @param[in] slot_cfg Standard mode slot configuration, can be generated by `I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG`,
  288. * `I2S_STD_PCM_SLOT_DEFAULT_CONFIG` and `I2S_STD_MSB_SLOT_DEFAULT_CONFIG`.
  289. * @return
  290. * - ESP_OK Set clock successfully
  291. * - ESP_ERR_NO_MEM No memory for DMA buffer
  292. * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
  293. * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
  294. */
  295. esp_err_t i2s_channel_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg);
  296. /**
  297. * @brief Reconfigure the I2S gpio for standard mode
  298. * @note Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started
  299. * this function won't change the state. 'i2s_channel_disable' should be called before calling this function if i2s has started.
  300. * @note The input channel handle has to be initialized to standard mode, i.e., 'i2s_channel_init_std_mode' has been called before reconfigring
  301. *
  302. * @param[in] handle I2S channel handler
  303. * @param[in] gpio_cfg Standard mode gpio configuration, specified by user
  304. * @return
  305. * - ESP_OK Set clock successfully
  306. * - ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
  307. * - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
  308. */
  309. esp_err_t i2s_channel_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg);
  310. #ifdef __cplusplus
  311. }
  312. #endif