bsp_board.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. #include "bsp_board.h"
  2. #include <stdbool.h>
  3. #include "esp_err.h"
  4. #include "freertos/FreeRTOS.h"
  5. #include "freertos/semphr.h"
  6. #include "freertos/task.h"
  7. #include "string.h"
  8. #include "driver/gpio.h"
  9. #include "esp_err.h"
  10. #include "esp_log.h"
  11. #include "esp_rom_sys.h"
  12. #include "esp_check.h"
  13. #include "esp_vfs_fat.h"
  14. #include "sdmmc_cmd.h"
  15. #include "driver/i2s_std.h"
  16. #include "driver/i2s_types.h"
  17. #include "driver/i2s_pdm.h"
  18. #include "driver/i2s_tdm.h"
  19. #include <sys/unistd.h>
  20. #include <sys/stat.h>
  21. #include "dirent.h"
  22. #include "driver/sdmmc_host.h"
  23. #include <errno.h>
  24. #include "esp_aec.h"
  25. #include "tca9555_driver.h"
  26. #if ((SOC_SDMMC_HOST_SUPPORTED) && (FUNC_SDMMC_EN))
  27. #include "driver/sdmmc_host.h"
  28. #endif /* ((SOC_SDMMC_HOST_SUPPORTED) && (FUNC_SDMMC_EN)) */
  29. #define ADC_I2S_CHANNEL 2
  30. #define ADC_BITS_PER_SAMPLE 32
  31. static sdmmc_card_t *card;
  32. static const char *TAG = "board";
  33. static int s_play_sample_rate = 16000;
  34. static int s_play_channel_format = 1;
  35. static int s_bits_per_chan = 16;
  36. #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
  37. static i2s_chan_handle_t tx_handle = NULL; // I2S tx channel handler
  38. static i2s_chan_handle_t rx_handle = NULL; // I2S rx channel handler
  39. #endif
  40. static audio_codec_data_if_t *record_data_if = NULL;
  41. static audio_codec_ctrl_if_t *record_ctrl_if = NULL;
  42. static audio_codec_if_t *record_codec_if = NULL;
  43. static esp_codec_dev_handle_t record_dev = NULL;
  44. static audio_codec_data_if_t *play_data_if = NULL;
  45. static audio_codec_ctrl_if_t *play_ctrl_if = NULL;
  46. static audio_codec_gpio_if_t *play_gpio_if = NULL;
  47. static audio_codec_if_t *play_codec_if = NULL;
  48. static esp_codec_dev_handle_t play_dev = NULL;
  49. static i2c_master_bus_handle_t i2c_bus_handle = NULL;
  50. static uint32_t SDCard_Size = 0;
  51. static bool s_volume_buttons_task_started = false;
  52. static aec_handle_t *aec = NULL;
  53. static int frame_size = 0;
  54. static int16_t *mic = NULL;
  55. static int16_t *ref = NULL;
  56. static int16_t *out = NULL;
  57. static esp_err_t bsp_aec_init(void)
  58. {
  59. /* Espressif's direct AEC flow: create, query the algorithm frame size,
  60. * then allocate aligned signed-16-bit audio buffers for each frame.
  61. * aec_create_from_config() is used instead of aec_create() so the NLP
  62. * (residual echo suppression) level can be pushed to its strongest
  63. * setting; a longer filter_length also helps cancel longer echo tails. */
  64. aec_config_t aec_cfg = {
  65. .mic_num = 1,
  66. .ref_num = 1,
  67. .out_num = 1,
  68. .filter_length = 6,
  69. .sample_rate = 16000,
  70. .caps = MALLOC_CAP_8BIT,
  71. .mode = AEC_MODE_VOIP_HIGH_PERF,
  72. .nlp_level = AEC_NLP_LEVEL_AGGR,
  73. };
  74. aec = aec_create_from_config(&aec_cfg);
  75. if (aec == NULL) {
  76. ESP_LOGE(TAG, "AEC create failed");
  77. return ESP_ERR_NO_MEM;
  78. }
  79. frame_size = aec_get_chunksize(aec);
  80. mic = heap_caps_aligned_alloc(16, frame_size * sizeof(int16_t), MALLOC_CAP_8BIT);
  81. ref = heap_caps_aligned_alloc(16, frame_size * sizeof(int16_t), MALLOC_CAP_8BIT);
  82. out = heap_caps_aligned_alloc(16, frame_size * sizeof(int16_t), MALLOC_CAP_8BIT);
  83. if (mic == NULL || ref == NULL || out == NULL) {
  84. ESP_LOGE(TAG, "AEC buffer allocation failed for %d samples", frame_size);
  85. free(mic);
  86. free(ref);
  87. free(out);
  88. mic = NULL;
  89. ref = NULL;
  90. out = NULL;
  91. aec_destroy(aec);
  92. aec = NULL;
  93. frame_size = 0;
  94. return ESP_ERR_NO_MEM;
  95. }
  96. ESP_LOGI(TAG, "AEC ready: %d samples/frame at 16 kHz", frame_size);
  97. return ESP_OK;
  98. }
  99. static esp_err_t bsp_codec_deinit(void);
  100. static void bsp_aec_deinit(void)
  101. {
  102. if (aec != NULL) {
  103. aec_destroy(aec);
  104. aec = NULL;
  105. }
  106. free(mic);
  107. free(ref);
  108. free(out);
  109. mic = NULL;
  110. ref = NULL;
  111. out = NULL;
  112. frame_size = 0;
  113. }
  114. int bsp_aec_get_frame_size(void)
  115. {
  116. return frame_size;
  117. }
  118. esp_err_t bsp_aec_process_frame(const int16_t *near_end,
  119. const int16_t *far_end,
  120. int16_t *processed)
  121. {
  122. if (aec == NULL || mic == NULL || ref == NULL || out == NULL ||
  123. near_end == NULL || far_end == NULL || processed == NULL) {
  124. return ESP_ERR_INVALID_STATE;
  125. }
  126. memcpy(mic, near_end, frame_size * sizeof(int16_t));
  127. memcpy(ref, far_end, frame_size * sizeof(int16_t));
  128. aec_process(aec, mic, ref, out);
  129. memcpy(processed, out, frame_size * sizeof(int16_t));
  130. return ESP_OK;
  131. }
  132. int mic_level = 0;
  133. esp_codec_dev_handle_t esp_ret_play_dev(void)
  134. {
  135. return play_dev;
  136. }
  137. i2c_master_bus_handle_t esp_ret_i2c_handle(void)
  138. {
  139. return i2c_bus_handle;
  140. }
  141. static esp_err_t i2c_master_init(void)
  142. {
  143. const i2c_master_bus_config_t bus_config = {
  144. .i2c_port = I2C_NUM,
  145. .sda_io_num = GPIO_I2C_SDA,
  146. .scl_io_num = GPIO_I2C_SCL,
  147. .clk_source = I2C_CLK_SRC_DEFAULT,
  148. };
  149. esp_err_t ret = i2c_new_master_bus(&bus_config, &i2c_bus_handle);
  150. if (ret != ESP_OK) {
  151. ESP_LOGE(TAG, "Failed to initialize I2C bus: %s", esp_err_to_name(ret));
  152. return ret;
  153. }
  154. ESP_LOGI(TAG, "I2C bus initialized successfully");
  155. return ESP_OK; // 返回 ESP_OK 表示成功
  156. }
  157. esp_err_t bsp_codec_adc_init(int sample_rate)
  158. { ESP_LOGI(TAG,"ADC INIT START");
  159. esp_err_t ret_val = ESP_OK;
  160. audio_codec_i2s_cfg_t i2s_cfg = {
  161. .port = I2S_NUM_1,
  162. #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
  163. .rx_handle = rx_handle,
  164. .tx_handle = NULL,
  165. #endif
  166. };
  167. record_data_if = audio_codec_new_i2s_data(&i2s_cfg);
  168. if(record_data_if == NULL)
  169. {
  170. ESP_LOGE(TAG,"record_data_if creation failed");
  171. return ESP_FAIL;
  172. }
  173. audio_codec_i2c_cfg_t i2c_cfg = {
  174. .addr = ES7210_CODEC_DEFAULT_ADDR,
  175. .bus_handle = i2c_bus_handle
  176. };
  177. record_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
  178. es7210_codec_cfg_t es7210_cfg = {
  179. .ctrl_if = record_ctrl_if,
  180. .mic_selected =
  181. ES7210_SEL_MIC1 |
  182. ES7210_SEL_MIC2 |
  183. ES7210_SEL_MIC3 |
  184. ES7210_SEL_MIC4,
  185. };
  186. record_codec_if = es7210_codec_new(&es7210_cfg);
  187. ESP_LOGI(TAG,"ES7210 IF=%p", record_codec_if);
  188. esp_codec_dev_cfg_t dev_cfg = {
  189. .codec_if = record_codec_if,
  190. .data_if = record_data_if,
  191. .dev_type = ESP_CODEC_DEV_TYPE_IN,
  192. };
  193. record_dev = esp_codec_dev_new(&dev_cfg);
  194. if(record_dev == NULL)
  195. {
  196. ESP_LOGE(TAG,"Failed creating ADC codec");
  197. return ESP_FAIL;
  198. }
  199. esp_codec_dev_sample_info_t fs = {
  200. .sample_rate = sample_rate,
  201. .channel = 2,
  202. .bits_per_sample = 16,
  203. };
  204. ret_val = esp_codec_dev_open(record_dev, &fs);
  205. if(ret_val != ESP_OK)
  206. {
  207. ESP_LOGE(TAG,
  208. "Codec open failed %s",
  209. esp_err_to_name(ret_val));
  210. return ret_val;
  211. }
  212. esp_codec_dev_set_in_channel_gain(
  213. record_dev,
  214. ESP_CODEC_DEV_MAKE_CHANNEL_MASK(0),
  215. RECORD_VOLUME);
  216. esp_codec_dev_set_in_channel_gain(
  217. record_dev,
  218. ESP_CODEC_DEV_MAKE_CHANNEL_MASK(1),
  219. RECORD_VOLUME);
  220. return ret_val;
  221. }
  222. esp_err_t bsp_codec_dac_init(int sample_rate, int channel_format, int bits_per_chan)
  223. {
  224. esp_err_t ret_val = ESP_OK;
  225. // Do initialize of related interface: data_if, ctrl_if and gpio_if
  226. audio_codec_i2s_cfg_t i2s_cfg = {
  227. .port = I2S_NUM_1,
  228. #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
  229. .rx_handle = NULL,
  230. .tx_handle = tx_handle,
  231. #endif
  232. };
  233. play_data_if = audio_codec_new_i2s_data(&i2s_cfg);
  234. audio_codec_i2c_cfg_t i2c_cfg = {.addr = ES8311_CODEC_DEFAULT_ADDR,.bus_handle = i2c_bus_handle};
  235. play_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
  236. play_gpio_if = audio_codec_new_gpio();
  237. // New output codec interface
  238. es8311_codec_cfg_t es8311_cfg = {
  239. .codec_mode = ESP_CODEC_DEV_WORK_MODE_DAC,
  240. .ctrl_if = play_ctrl_if,
  241. .gpio_if = play_gpio_if,
  242. .pa_pin = GPIO_PWR_CTRL,
  243. .use_mclk = false,
  244. };
  245. play_codec_if = es8311_codec_new(&es8311_cfg);
  246. // New output codec device
  247. esp_codec_dev_cfg_t dev_cfg = {
  248. .codec_if = play_codec_if,
  249. .data_if = play_data_if,
  250. .dev_type = ESP_CODEC_DEV_TYPE_OUT,
  251. };
  252. play_dev = esp_codec_dev_new(&dev_cfg);
  253. esp_codec_dev_sample_info_t fs = {
  254. .bits_per_sample = bits_per_chan,
  255. .sample_rate = sample_rate,
  256. .channel = channel_format,
  257. };
  258. esp_codec_dev_set_out_vol(play_dev, PLAYER_VOLUME);
  259. esp_codec_dev_open(play_dev, &fs);
  260. return ret_val;
  261. }
  262. static esp_err_t bsp_codec_adc_deinit()
  263. {
  264. esp_err_t ret_val = ESP_OK;
  265. if (record_dev) {
  266. esp_codec_dev_close(record_dev);
  267. esp_codec_dev_delete(record_dev);
  268. record_dev = NULL;
  269. }
  270. // Delete codec interface
  271. if (record_codec_if) {
  272. audio_codec_delete_codec_if(record_codec_if);
  273. record_codec_if = NULL;
  274. }
  275. // Delete codec control interface
  276. if (record_ctrl_if) {
  277. audio_codec_delete_ctrl_if(record_ctrl_if);
  278. record_ctrl_if = NULL;
  279. }
  280. // Delete codec data interface
  281. if (record_data_if) {
  282. audio_codec_delete_data_if(record_data_if);
  283. record_data_if = NULL;
  284. }
  285. return ret_val;
  286. }
  287. static esp_err_t bsp_codec_dac_deinit()
  288. {
  289. esp_err_t ret_val = ESP_OK;
  290. if (play_dev) {
  291. esp_codec_dev_close(play_dev);
  292. esp_codec_dev_delete(play_dev);
  293. play_dev = NULL;
  294. }
  295. // Delete codec interface
  296. if (play_codec_if) {
  297. audio_codec_delete_codec_if(play_codec_if);
  298. play_codec_if = NULL;
  299. }
  300. // Delete codec control interface
  301. if (play_ctrl_if) {
  302. audio_codec_delete_ctrl_if(play_ctrl_if);
  303. play_ctrl_if = NULL;
  304. }
  305. if (play_gpio_if) {
  306. audio_codec_delete_gpio_if(play_gpio_if);
  307. play_gpio_if = NULL;
  308. }
  309. // Delete codec data interface
  310. if (play_data_if) {
  311. audio_codec_delete_data_if(play_data_if);
  312. play_data_if = NULL;
  313. }
  314. return ret_val;
  315. }
  316. esp_err_t esp_audio_set_play_vol(int volume)
  317. {
  318. if (!play_dev) {
  319. ESP_LOGE(TAG, "DAC codec init fail");
  320. return ESP_FAIL;
  321. }
  322. esp_codec_dev_set_out_vol(play_dev, volume);
  323. return ESP_OK;
  324. }
  325. esp_err_t esp_audio_get_play_vol(int *volume)
  326. {
  327. if (!play_dev) {
  328. ESP_LOGE(TAG, "DAC codec init fail");
  329. return ESP_FAIL;
  330. }
  331. esp_codec_dev_get_out_vol(play_dev, volume);
  332. return ESP_OK;
  333. }
  334. // static esp_err_t bsp_i2s_init(i2s_port_t i2s_num, uint32_t sample_rate, i2s_channel_fmt_t channel_format, i2s_bits_per_chan_t bits_per_chan)
  335. static esp_err_t bsp_i2s_init(int i2s_num, uint32_t sample_rate, int channel_format, int bits_per_chan)
  336. {
  337. esp_err_t ret_val = ESP_OK;
  338. #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
  339. i2s_slot_mode_t channel_fmt = I2S_SLOT_MODE_STEREO;
  340. if (channel_format == 1) {
  341. channel_fmt = I2S_SLOT_MODE_MONO;
  342. } else if (channel_format == 2) {
  343. channel_fmt = I2S_SLOT_MODE_STEREO;
  344. } else {
  345. ESP_LOGE(TAG, "Unable to configure channel_format %d", channel_format);
  346. channel_format = 1;
  347. channel_fmt = I2S_SLOT_MODE_MONO;
  348. }
  349. if (bits_per_chan != 16 && bits_per_chan != 32) {
  350. ESP_LOGE(TAG, "Unable to configure bits_per_chan %d", bits_per_chan);
  351. bits_per_chan = 32;
  352. }
  353. i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(i2s_num, I2S_ROLE_MASTER);
  354. ret_val |= i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle);
  355. i2s_std_config_t std_cfg = I2S_CONFIG_DEFAULT(sample_rate, channel_fmt, bits_per_chan);
  356. ret_val |= i2s_channel_init_std_mode(tx_handle, &std_cfg);
  357. ret_val |= i2s_channel_init_std_mode(rx_handle, &std_cfg);
  358. ret_val |= i2s_channel_enable(tx_handle);
  359. ret_val |= i2s_channel_enable(rx_handle);
  360. #else
  361. i2s_channel_fmt_t channel_fmt = I2S_CHANNEL_FMT_RIGHT_LEFT;
  362. if (channel_format == 1) {
  363. channel_fmt = I2S_CHANNEL_FMT_ONLY_LEFT;
  364. } else if (channel_format == 2) {
  365. channel_fmt = I2S_CHANNEL_FMT_RIGHT_LEFT;
  366. } else {
  367. ESP_LOGE(TAG, "Unable to configure channel_format %d", channel_format);
  368. channel_format = 1;
  369. channel_fmt = I2S_CHANNEL_FMT_ONLY_LEFT;
  370. }
  371. if (bits_per_chan != 16 && bits_per_chan != 32) {
  372. ESP_LOGE(TAG, "Unable to configure bits_per_chan %d", bits_per_chan);
  373. bits_per_chan = 16;
  374. }
  375. i2s_config_t i2s_config = I2S_CONFIG_DEFAULT(sample_rate, channel_fmt, bits_per_chan);
  376. i2s_pin_config_t pin_config = {
  377. .bck_io_num = GPIO_I2S_SCLK,
  378. .ws_io_num = GPIO_I2S_LRCK,
  379. .data_out_num = GPIO_I2S_DOUT,
  380. .data_in_num = GPIO_I2S_SDIN,
  381. .mck_io_num = GPIO_I2S_MCLK,
  382. };
  383. ret_val |= i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
  384. ret_val |= i2s_set_pin(i2s_num, &pin_config);
  385. #endif
  386. return ret_val;
  387. }
  388. static esp_err_t bsp_i2s_deinit(int i2s_num)
  389. {
  390. esp_err_t ret_val = ESP_OK;
  391. #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
  392. if (i2s_num == I2S_NUM_1 && rx_handle) {
  393. ret_val |= i2s_channel_disable(rx_handle);
  394. ret_val |= i2s_del_channel(rx_handle);
  395. rx_handle = NULL;
  396. } else if (i2s_num == I2S_NUM_0 && tx_handle) {
  397. ret_val |= i2s_channel_disable(tx_handle);
  398. ret_val |= i2s_del_channel(tx_handle);
  399. tx_handle = NULL;
  400. }
  401. #else
  402. ret_val |= i2s_stop(i2s_num);
  403. ret_val |= i2s_driver_uninstall(i2s_num);
  404. #endif
  405. return ret_val;
  406. }
  407. static esp_err_t bsp_codec_init(
  408. int adc_sample_rate,
  409. int dac_sample_rate,
  410. int dac_channel_format,
  411. int dac_bits_per_chan)
  412. {
  413. //ESP_LOGE(TAG, "bsp_codec_adc_init START");
  414. esp_err_t ret;
  415. ret = bsp_codec_adc_init(adc_sample_rate);
  416. if(ret != ESP_OK)
  417. {
  418. ESP_LOGE(TAG,"ADC init failed: %s",
  419. esp_err_to_name(ret));
  420. return ret;
  421. }
  422. ret = bsp_codec_dac_init(
  423. dac_sample_rate,
  424. dac_channel_format,
  425. dac_bits_per_chan);
  426. if(ret != ESP_OK)
  427. {
  428. ESP_LOGE(TAG,"DAC init failed: %s",
  429. esp_err_to_name(ret));
  430. }
  431. ret = bsp_aec_init();
  432. if (ret != ESP_OK) {
  433. bsp_codec_deinit();
  434. return ret;
  435. }
  436. return ret;
  437. }
  438. static esp_err_t bsp_codec_deinit()
  439. {
  440. esp_err_t ret_val = ESP_OK;
  441. ret_val |= bsp_codec_adc_deinit();
  442. ret_val |= bsp_codec_dac_deinit();
  443. bsp_aec_deinit();
  444. return ret_val;
  445. }
  446. esp_err_t esp_audio_play(const int16_t* data, int length, uint32_t ticks_to_wait)
  447. {
  448. size_t bytes_write = 0;
  449. esp_err_t ret = ESP_OK;
  450. if (!play_dev) {
  451. return ESP_FAIL;
  452. }
  453. int out_length= length;
  454. int audio_time = 1;
  455. audio_time *= (16000 / s_play_sample_rate);
  456. audio_time *= (2 / s_play_channel_format);
  457. int *data_out = NULL;
  458. if (s_bits_per_chan != 32) {
  459. out_length = length * 2;
  460. data_out = malloc(out_length);
  461. for (int i = 0; i < length / sizeof(int16_t); i++) {
  462. int ret = data[i];
  463. data_out[i] = ret << 16;
  464. }
  465. }
  466. int *data_out_1 = NULL;
  467. if (s_play_channel_format != 2 || s_play_sample_rate != 16000) {
  468. out_length *= audio_time;
  469. data_out_1 = malloc(out_length);
  470. int *tmp_data = NULL;
  471. if (data_out != NULL) {
  472. tmp_data = data_out;
  473. } else {
  474. tmp_data = (int *)data;
  475. }
  476. for (int i = 0; i < out_length / (audio_time * sizeof(int)); i++) {
  477. for (int j = 0; j < audio_time; j++) {
  478. data_out_1[audio_time * i + j] = tmp_data[i];
  479. }
  480. }
  481. if (data_out != NULL) {
  482. free(data_out);
  483. data_out = NULL;
  484. }
  485. }
  486. if (data_out != NULL) {
  487. ret = esp_codec_dev_write(play_dev, (void *)data_out, out_length);
  488. free(data_out);
  489. } else if (data_out_1 != NULL) {
  490. ret = esp_codec_dev_write(play_dev, (void *)data_out_1, out_length);
  491. free(data_out_1);
  492. } else {
  493. ret = esp_codec_dev_write(play_dev, (void *)data, length);
  494. }
  495. return ret;
  496. }
  497. int get_mic_level (void) {
  498. return mic_level;
  499. }
  500. esp_err_t esp_get_feed_data(
  501. bool is_get_raw_channel,
  502. int16_t *buffer,
  503. int buffer_len)
  504. {
  505. // ESP_LOGE(TAG, "NEW esp_get_feed_data CALLED");
  506. if(record_dev == NULL)
  507. {
  508. ESP_LOGE(TAG,"record_dev NULL");
  509. return ESP_ERR_INVALID_STATE;
  510. }
  511. // ESP_LOGI(TAG,
  512. // "read buffer=%p size=%d",
  513. // buffer,
  514. // buffer_len);
  515. esp_err_t ret;
  516. ret = esp_codec_dev_read(
  517. record_dev,
  518. buffer,
  519. buffer_len);
  520. // ESP_LOGI(TAG,
  521. // "codec read ret=%s",
  522. // esp_err_to_name(ret));
  523. if(ret != ESP_OK)
  524. {
  525. return ret;
  526. }
  527. // Check microphone data
  528. int64_t sum = 0;
  529. for(int i=0;i<buffer_len/sizeof(int16_t);i++)
  530. {
  531. sum += abs(buffer[i]);
  532. }
  533. ESP_LOGI(TAG,
  534. "MIC level=%lld",
  535. sum/(buffer_len/sizeof(int16_t)));
  536. return ESP_OK;
  537. }
  538. int esp_get_feed_channel(void)
  539. {
  540. return ADC_I2S_CHANNEL;
  541. }
  542. char* esp_get_input_format(void)
  543. {
  544. return "RM";
  545. }
  546. static void bsp_volume_buttons_task(void *arg)
  547. {
  548. /* K1/K3 are wired through the TCA9555 IO expander, not raw ESP32 GPIOs
  549. * (GPIO0 is the BOOT/RESET strapping pin, so it must not be used here). */
  550. int last_key1 = 1;
  551. int last_key3 = 1;
  552. while (io_expander == NULL) {
  553. vTaskDelay(pdMS_TO_TICKS(VOLUME_BUTTON_POLL_MS));
  554. }
  555. while (1) {
  556. uint32_t mask = 0;
  557. if (esp_io_expander_get_level(io_expander, KEY_VOLUME_UP_PIN | KEY_VOLUME_DOWN_PIN, &mask) != ESP_OK) {
  558. vTaskDelay(pdMS_TO_TICKS(VOLUME_BUTTON_POLL_MS));
  559. continue;
  560. }
  561. int key1 = (mask & KEY_VOLUME_UP_PIN) ? 1 : 0;
  562. int key3 = (mask & KEY_VOLUME_DOWN_PIN) ? 1 : 0;
  563. if (key1 == 0 && last_key1 != 0) {
  564. int current_vol = 0;
  565. if (esp_audio_get_play_vol(&current_vol) == ESP_OK) {
  566. current_vol += VOLUME_STEP;
  567. if (current_vol > VOLUME_MAX_LEVEL) {
  568. current_vol = VOLUME_MAX_LEVEL;
  569. }
  570. if (esp_audio_set_play_vol(current_vol) == ESP_OK) {
  571. ESP_LOGI(TAG, "Volume up -> %d", current_vol);
  572. }
  573. }
  574. }
  575. if (key3 == 0 && last_key3 != 0) {
  576. int current_vol = 0;
  577. if (esp_audio_get_play_vol(&current_vol) == ESP_OK) {
  578. current_vol -= VOLUME_STEP;
  579. if (current_vol < VOLUME_MIN_LEVEL) {
  580. current_vol = VOLUME_MIN_LEVEL;
  581. }
  582. if (esp_audio_set_play_vol(current_vol) == ESP_OK) {
  583. ESP_LOGI(TAG, "Volume down -> %d", current_vol);
  584. }
  585. }
  586. }
  587. last_key1 = key1;
  588. last_key3 = key3;
  589. vTaskDelay(pdMS_TO_TICKS(VOLUME_BUTTON_POLL_MS));
  590. }
  591. }
  592. static esp_err_t bsp_volume_buttons_init(void)
  593. {
  594. if (s_volume_buttons_task_started) {
  595. return ESP_OK;
  596. }
  597. /* K1/K3 input direction is already configured on the TCA9555 expander by
  598. * tca9555_driver_init(); no direct GPIO configuration is needed here. */
  599. BaseType_t task_created = xTaskCreate(bsp_volume_buttons_task, "vol_btns", 4096, NULL, 5, NULL);
  600. if (task_created != pdPASS) {
  601. return ESP_FAIL;
  602. }
  603. s_volume_buttons_task_started = true;
  604. return ESP_OK;
  605. }
  606. esp_err_t esp_board_init(uint32_t sample_rate, int channel_format, int bits_per_chan)
  607. {
  608. /*!< Initialize I2C bus, used for audio codec*/
  609. i2c_master_init();
  610. s_play_sample_rate = sample_rate;
  611. if (channel_format != 2 && channel_format != 1) {
  612. ESP_LOGE(TAG, "Unable to configure channel_format");
  613. channel_format = 2;
  614. }
  615. s_play_channel_format = channel_format;
  616. if (bits_per_chan != 32 && bits_per_chan != 16) {
  617. ESP_LOGE(TAG, "Unable to configure bits_per_chan");
  618. bits_per_chan = 32;
  619. }
  620. s_bits_per_chan = bits_per_chan;
  621. bsp_i2s_init(I2S_NUM_1, 16000, 2, 16);
  622. // Because record and play use the same i2s.
  623. esp_err_t codec_ret;
  624. codec_ret = bsp_codec_init(16000,16000,2,16);
  625. if(codec_ret != ESP_OK)
  626. {
  627. ESP_LOGE(TAG,
  628. "bsp_codec_init failed: %s",
  629. esp_err_to_name(codec_ret));
  630. }
  631. else
  632. {
  633. ESP_LOGI(TAG,"bsp_codec_init OK");
  634. }
  635. /* Initialize PA */
  636. /*gpio_config_t io_conf;
  637. memset(&io_conf, 0, sizeof(io_conf));
  638. io_conf.intr_type = GPIO_INTR_DISABLE;
  639. io_conf.mode = GPIO_MODE_OUTPUT;
  640. io_conf.pin_bit_mask = ((1ULL << GPIO_PWR_CTRL));
  641. io_conf.pull_down_en = 0;
  642. io_conf.pull_up_en = 0;
  643. gpio_config(&io_conf);
  644. */
  645. gpio_set_level(GPIO_PWR_CTRL, 1);
  646. esp_err_t button_ret = bsp_volume_buttons_init();
  647. if (button_ret != ESP_OK) {
  648. ESP_LOGW(TAG, "Failed to initialize volume buttons: %s", esp_err_to_name(button_ret));
  649. }
  650. return ESP_OK;
  651. }
  652. esp_err_t esp_sdcard_init(char *mount_point, size_t max_files)
  653. {
  654. if (NULL != card) {
  655. return ESP_ERR_INVALID_STATE;
  656. }
  657. /* Check if SD crad is supported */
  658. if (!FUNC_SDMMC_EN && !FUNC_SDSPI_EN) {
  659. ESP_LOGE(TAG, "SDMMC and SDSPI not supported on this board!");
  660. return ESP_ERR_NOT_SUPPORTED;
  661. }
  662. esp_err_t ret_val = ESP_OK;
  663. /**
  664. * @brief Options for mounting the filesystem.
  665. * If format_if_mount_failed is set to true, SD card will be partitioned and
  666. * formatted in case when mounting fails.
  667. *
  668. */
  669. esp_vfs_fat_sdmmc_mount_config_t mount_config = {
  670. .format_if_mount_failed = false,
  671. .max_files = max_files,
  672. .allocation_unit_size = 16 * 1024
  673. };
  674. /**
  675. * @brief Use settings defined above to initialize SD card and mount FAT filesystem.
  676. * Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
  677. * Please check its source code and implement error recovery when developing
  678. * production applications.
  679. *
  680. */
  681. sdmmc_host_t host =
  682. #if FUNC_SDMMC_EN
  683. SDMMC_HOST_DEFAULT();
  684. #else
  685. SDSPI_HOST_DEFAULT();
  686. spi_bus_config_t bus_cfg = {
  687. .mosi_io_num = GPIO_SDSPI_MOSI,
  688. .miso_io_num = GPIO_SDSPI_MISO,
  689. .sclk_io_num = GPIO_SDSPI_SCLK,
  690. .quadwp_io_num = GPIO_NUM_NC,
  691. .quadhd_io_num = GPIO_NUM_NC,
  692. .max_transfer_sz = 4000,
  693. };
  694. ret_val = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CH_AUTO);
  695. if (ret_val != ESP_OK) {
  696. ESP_LOGE(TAG, "Failed to initialize bus.");
  697. return ret_val;
  698. }
  699. #endif
  700. /**
  701. * @brief This initializes the slot without card detect (CD) and write protect (WP) signals.
  702. * Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
  703. *
  704. */
  705. #if FUNC_SDMMC_EN
  706. sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
  707. #else
  708. sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
  709. #endif
  710. #if FUNC_SDMMC_EN
  711. /* Config SD data width. 0, 4 or 8. Currently for SD card, 8 bit is not supported. */
  712. slot_config.width = SDMMC_BUS_WIDTH;
  713. /**
  714. * @brief On chips where the GPIOs used for SD card can be configured, set them in
  715. * the slot_config structure.
  716. *
  717. */
  718. #if SOC_SDMMC_USE_GPIO_MATRIX
  719. slot_config.clk = GPIO_SDMMC_CLK;
  720. slot_config.cmd = GPIO_SDMMC_CMD;
  721. slot_config.d0 = GPIO_SDMMC_D0;
  722. slot_config.d1 = GPIO_SDMMC_D1;
  723. slot_config.d2 = GPIO_SDMMC_D2;
  724. slot_config.d3 = GPIO_SDMMC_D3;
  725. #endif
  726. slot_config.cd = GPIO_SDMMC_DET;
  727. slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
  728. #else
  729. slot_config.gpio_cs = GPIO_SDSPI_CS;
  730. slot_config.host_id = host.slot;
  731. #endif
  732. /**
  733. * @brief Enable internal pullups on enabled pins. The internal pullups
  734. * are insufficient however, please make sure 10k external pullups are
  735. * connected on the bus. This is for debug / example purpose only.
  736. */
  737. /* get FAT filesystem on SD card registered in VFS. */
  738. ret_val =
  739. #if FUNC_SDMMC_EN
  740. esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
  741. #else
  742. esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
  743. #endif
  744. /* Check for SDMMC mount result. */
  745. if (ret_val != ESP_OK) {
  746. if (ret_val == ESP_FAIL) {
  747. ESP_LOGE(TAG, "Failed to mount filesystem. "
  748. "If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
  749. } else {
  750. ESP_LOGE(TAG, "Failed to initialize the card (%s). "
  751. "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret_val));
  752. }
  753. return ret_val;
  754. }
  755. /* Card has been initialized, print its properties. */
  756. sdmmc_card_print_info(stdout, card);
  757. SDCard_Size = ((uint64_t) card->csd.capacity) * card->csd.sector_size / (1024 * 1024);
  758. return ret_val;
  759. }
  760. esp_err_t esp_sdcard_deinit(char *mount_point)
  761. {
  762. if (NULL == mount_point) {
  763. return ESP_ERR_INVALID_STATE;
  764. }
  765. /* Unmount an SD card from the FAT filesystem and release resources acquired */
  766. esp_err_t ret_val = esp_vfs_fat_sdcard_unmount(mount_point, card);
  767. /* Make SD/MMC card information structure pointer NULL */
  768. card = NULL;
  769. return ret_val;
  770. }
  771. #define MOUNT_POINT "/sdcard"
  772. static const char *SD_TAG = "SD";
  773. uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][MAX_FILE_NAME_SIZE], uint16_t maxFiles)
  774. {
  775. DIR *dir = opendir(directory);
  776. if (dir == NULL) {
  777. ESP_LOGE(SD_TAG, "Path: <%s> does not exist", directory);
  778. return 0;
  779. }
  780. uint16_t fileCount = 0;
  781. struct dirent *entry;
  782. while ((entry = readdir(dir)) != NULL && fileCount < maxFiles) {
  783. if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
  784. continue;
  785. }
  786. const char *dot = strrchr(entry->d_name, '.');
  787. if (dot != NULL && dot != entry->d_name) {
  788. if (strcasecmp(dot, fileExtension) == 0) {
  789. strncpy(File_Name[fileCount], entry->d_name, MAX_FILE_NAME_SIZE - 1);
  790. File_Name[fileCount][MAX_FILE_NAME_SIZE - 1] = '\0';
  791. char filePath[MAX_PATH_SIZE];
  792. snprintf(filePath, MAX_PATH_SIZE, "%s/%s", directory, entry->d_name);
  793. printf("File found: %s\r\n", filePath);
  794. fileCount++;
  795. }
  796. }
  797. else{
  798. // printf("No extension found for file: %s\r\n", entry->d_name);
  799. }
  800. }
  801. closedir(dir);
  802. if (fileCount > 0) {
  803. ESP_LOGI(SD_TAG, "Retrieved %d files with extension '%s'", fileCount, fileExtension);
  804. } else {
  805. ESP_LOGW(SD_TAG, "No files with extension '%s' found in directory: %s", fileExtension, directory);
  806. }
  807. return fileCount;
  808. }