main.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <string.h>
  10. #include <inttypes.h>
  11. #include "freertos/FreeRTOS.h"
  12. #include "freertos/task.h"
  13. #include "freertos/queue.h"
  14. #include "nvs.h"
  15. #include "nvs_flash.h"
  16. #include "esp_system.h"
  17. #include "esp_log.h"
  18. #include "esp_bt.h"
  19. #include "bt_app_core.h"
  20. #include "bt_app_av.h"
  21. #include "esp_bt_main.h"
  22. #include "esp_bt_device.h"
  23. #include "esp_gap_bt_api.h"
  24. #include "esp_a2dp_api.h"
  25. #include "esp_avrc_api.h"
  26. #include "driver/gpio.h"
  27. /* device name */
  28. #define LOCAL_DEVICE_NAME "ESP_SPEAKER"
  29. /* event for stack up */
  30. enum {
  31. BT_APP_EVT_STACK_UP = 0,
  32. };
  33. /* GPIO definitions */
  34. #define GPIO_BTN GPIO_NUM_2 // 按钮引脚
  35. #define GPIO_OUTPUT GPIO_NUM_19 // 输出控制引脚
  36. /* Audio mode states */
  37. typedef enum {
  38. AUDIO_MODE_NORMAL = 0,
  39. AUDIO_MODE_BASS_BOOST,
  40. AUDIO_MODE_MAX
  41. } audio_mode_t;
  42. static audio_mode_t current_audio_mode = AUDIO_MODE_NORMAL;
  43. static QueueHandle_t gpio_evt_queue = NULL;
  44. /********************************
  45. * STATIC FUNCTION DECLARATIONS
  46. *******************************/
  47. /* Device callback function */
  48. static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param);
  49. /* GAP callback function */
  50. static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param);
  51. /* handler for bluetooth stack enabled events */
  52. static void bt_av_hdl_stack_evt(uint16_t event, void *p_param);
  53. /* GPIO interrupt handler */
  54. static void IRAM_ATTR gpio_isr_handler(void* arg);
  55. /* GPIO task to handle events */
  56. static void gpio_task(void* arg);
  57. /* Switch audio mode */
  58. static void switch_audio_mode(void);
  59. /* Update GPIO output based on audio mode */
  60. static void update_gpio_output(void);
  61. /*******************************
  62. * STATIC FUNCTION DEFINITIONS
  63. ******************************/
  64. static char *bda2str(uint8_t * bda, char *str, size_t size)
  65. {
  66. if (bda == NULL || str == NULL || size < 18) {
  67. return NULL;
  68. }
  69. uint8_t *p = bda;
  70. sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
  71. p[0], p[1], p[2], p[3], p[4], p[5]);
  72. return str;
  73. }
  74. static void bt_app_dev_cb(esp_bt_dev_cb_event_t event, esp_bt_dev_cb_param_t *param)
  75. {
  76. switch (event) {
  77. case ESP_BT_DEV_NAME_RES_EVT: {
  78. if (param->name_res.status == ESP_BT_STATUS_SUCCESS) {
  79. ESP_LOGI(BT_AV_TAG, "Get local device name success: %s", param->name_res.name);
  80. } else {
  81. ESP_LOGE(BT_AV_TAG, "Get local device name failed, status: %d", param->name_res.status);
  82. }
  83. break;
  84. }
  85. default: {
  86. ESP_LOGI(BT_AV_TAG, "event: %d", event);
  87. break;
  88. }
  89. }
  90. }
  91. static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
  92. {
  93. uint8_t *bda = NULL;
  94. switch (event) {
  95. /* when authentication completed, this event comes */
  96. case ESP_BT_GAP_AUTH_CMPL_EVT: {
  97. if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
  98. ESP_LOGI(BT_AV_TAG, "authentication success: %s", param->auth_cmpl.device_name);
  99. esp_log_buffer_hex(BT_AV_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
  100. } else {
  101. ESP_LOGE(BT_AV_TAG, "authentication failed, status: %d", param->auth_cmpl.stat);
  102. }
  103. ESP_LOGI(BT_AV_TAG, "link key type of current link is: %d", param->auth_cmpl.lk_type);
  104. break;
  105. }
  106. case ESP_BT_GAP_ENC_CHG_EVT: {
  107. char *str_enc[3] = {"OFF", "E0", "AES"};
  108. bda = (uint8_t *)param->enc_chg.bda;
  109. ESP_LOGI(BT_AV_TAG, "Encryption mode to [%02x:%02x:%02x:%02x:%02x:%02x] changed to %s",
  110. bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], str_enc[param->enc_chg.enc_mode]);
  111. break;
  112. }
  113. #if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == true)
  114. /* when Security Simple Pairing user confirmation requested, this event comes */
  115. case ESP_BT_GAP_CFM_REQ_EVT:
  116. ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %"PRIu32, param->cfm_req.num_val);
  117. esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
  118. break;
  119. /* when Security Simple Pairing passkey notified, this event comes */
  120. case ESP_BT_GAP_KEY_NOTIF_EVT:
  121. ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey: %"PRIu32, param->key_notif.passkey);
  122. break;
  123. /* when Security Simple Pairing passkey requested, this event comes */
  124. case ESP_BT_GAP_KEY_REQ_EVT:
  125. ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
  126. break;
  127. #endif
  128. /* when GAP mode changed, this event comes */
  129. case ESP_BT_GAP_MODE_CHG_EVT:
  130. ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_MODE_CHG_EVT mode: %d", param->mode_chg.mode);
  131. break;
  132. /* when ACL connection completed, this event comes */
  133. case ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT:
  134. bda = (uint8_t *)param->acl_conn_cmpl_stat.bda;
  135. ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT Connected to [%02x:%02x:%02x:%02x:%02x:%02x], status: 0x%x",
  136. bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], param->acl_conn_cmpl_stat.stat);
  137. break;
  138. /* when ACL disconnection completed, this event comes */
  139. case ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT:
  140. bda = (uint8_t *)param->acl_disconn_cmpl_stat.bda;
  141. ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_ACL_DISC_CMPL_STAT_EVT Disconnected from [%02x:%02x:%02x:%02x:%02x:%02x], reason: 0x%x",
  142. bda[0], bda[1], bda[2], bda[3], bda[4], bda[5], param->acl_disconn_cmpl_stat.reason);
  143. break;
  144. /* others */
  145. default: {
  146. ESP_LOGI(BT_AV_TAG, "event: %d", event);
  147. break;
  148. }
  149. }
  150. }
  151. static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
  152. {
  153. ESP_LOGD(BT_AV_TAG, "%s event: %d", __func__, event);
  154. switch (event) {
  155. /* when do the stack up, this event comes */
  156. case BT_APP_EVT_STACK_UP: {
  157. esp_bt_gap_set_device_name(LOCAL_DEVICE_NAME);
  158. esp_bt_dev_register_callback(bt_app_dev_cb);
  159. esp_bt_gap_register_callback(bt_app_gap_cb);
  160. assert(esp_avrc_ct_init() == ESP_OK);
  161. esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
  162. assert(esp_avrc_tg_init() == ESP_OK);
  163. esp_avrc_tg_register_callback(bt_app_rc_tg_cb);
  164. esp_avrc_rn_evt_cap_mask_t evt_set = {0};
  165. esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE);
  166. assert(esp_avrc_tg_set_rn_evt_cap(&evt_set) == ESP_OK);
  167. assert(esp_a2d_sink_init() == ESP_OK);
  168. esp_a2d_register_callback(&bt_app_a2d_cb);
  169. esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb);
  170. /* Get the default value of the delay value */
  171. esp_a2d_sink_get_delay_value();
  172. /* Get local device name */
  173. esp_bt_gap_get_device_name();
  174. /* set discoverable and connectable mode, wait to be connected */
  175. esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
  176. break;
  177. }
  178. /* others */
  179. default:
  180. ESP_LOGE(BT_AV_TAG, "%s unhandled event: %d", __func__, event);
  181. break;
  182. }
  183. }
  184. static void IRAM_ATTR gpio_isr_handler(void* arg)
  185. {
  186. uint32_t gpio_num = (uint32_t) arg;
  187. xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
  188. }
  189. static void gpio_task(void* arg)
  190. {
  191. uint32_t io_num;
  192. for(;;) {
  193. if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
  194. // 消抖处理
  195. vTaskDelay(50 / portTICK_PERIOD_MS);
  196. if(gpio_get_level(io_num) == 0) { // 确认仍然是低电平
  197. ESP_LOGI(BT_AV_TAG, "GPIO%"PRIu32" interrupt, button pressed", io_num);
  198. switch_audio_mode();
  199. }
  200. }
  201. }
  202. }
  203. static void switch_audio_mode(void)
  204. {
  205. // 切换音频模式
  206. current_audio_mode = (current_audio_mode + 1) % AUDIO_MODE_MAX;
  207. const char* mode_names[] = {
  208. "NORMAL",
  209. "BASS_BOOST",
  210. };
  211. ESP_LOGI(BT_AV_TAG, "Audio mode switched to: %s", mode_names[current_audio_mode]);
  212. // 更新GPIO输出状态
  213. update_gpio_output();
  214. }
  215. static void update_gpio_output(void)
  216. {
  217. // 根据音频模式设置GPIO19输出状态
  218. switch(current_audio_mode) {
  219. case AUDIO_MODE_NORMAL:
  220. gpio_set_level(GPIO_OUTPUT, 0); // 低电平
  221. break;
  222. case AUDIO_MODE_BASS_BOOST:
  223. gpio_set_level(GPIO_OUTPUT, 1); // 高电平
  224. break;
  225. default:
  226. gpio_set_level(GPIO_OUTPUT, 0);
  227. break;
  228. }
  229. ESP_LOGI(BT_AV_TAG, "GPIO19 set to: %d", gpio_get_level(GPIO_OUTPUT));
  230. }
  231. /*******************************
  232. * MAIN ENTRY POINT
  233. ******************************/
  234. void app_main(void)
  235. {
  236. char bda_str[18] = {0};
  237. /* initialize NVS — it is used to store PHY calibration data */
  238. esp_err_t err = nvs_flash_init();
  239. if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  240. ESP_ERROR_CHECK(nvs_flash_erase());
  241. err = nvs_flash_init();
  242. }
  243. ESP_ERROR_CHECK(err);
  244. // todo 拉低引脚 io32
  245. // todo 拉低引脚 io32 - 已完善
  246. // 配置GPIO32为输出模式并拉低电平
  247. gpio_config_t io_conf = {
  248. .pin_bit_mask = (1ULL << GPIO_NUM_32), // GPIO32
  249. .mode = GPIO_MODE_OUTPUT, // 输出模式
  250. .pull_up_en = GPIO_PULLUP_DISABLE, // 禁用上拉
  251. .pull_down_en = GPIO_PULLDOWN_DISABLE, // 禁用下拉
  252. .intr_type = GPIO_INTR_DISABLE // 禁用中断
  253. };
  254. // 配置GPIO
  255. err = gpio_config(&io_conf);
  256. if (err != ESP_OK) {
  257. ESP_LOGE(BT_AV_TAG, "GPIO32 config failed: %s", esp_err_to_name(err));
  258. return;
  259. }
  260. // 拉低GPIO32
  261. err = gpio_set_level(GPIO_NUM_32, 0);
  262. if (err != ESP_OK) {
  263. ESP_LOGE(BT_AV_TAG, "Set GPIO32 low failed: %s", esp_err_to_name(err));
  264. return;
  265. }
  266. // system state led
  267. gpio_config_t led_io_conf = {
  268. .pin_bit_mask = (1ULL << GPIO_NUM_15), // GPIO15
  269. .mode = GPIO_MODE_OUTPUT, // 输出模式
  270. .pull_up_en = GPIO_PULLUP_DISABLE, // 禁用上拉
  271. .pull_down_en = GPIO_PULLDOWN_DISABLE, // 禁用下拉
  272. .intr_type = GPIO_INTR_DISABLE // 禁用中断
  273. };
  274. // 配置GPIO
  275. err = gpio_config(&led_io_conf);
  276. if (err != ESP_OK) {
  277. ESP_LOGE(BT_AV_TAG, "GPIO15 config failed: %s", esp_err_to_name(err));
  278. return;
  279. }
  280. // 拉低GPIO15
  281. err = gpio_set_level(GPIO_NUM_15, 0);
  282. if (err != ESP_OK) {
  283. ESP_LOGE(BT_AV_TAG, "Set GPIO15 low failed: %s", esp_err_to_name(err));
  284. return;
  285. }
  286. ESP_LOGI(BT_AV_TAG, "GPIO15 set to low level");
  287. // 配置GPIO2为输入模式,用于低电平中断
  288. gpio_config_t btn_conf = {
  289. .pin_bit_mask = (1ULL << GPIO_BTN),
  290. .mode = GPIO_MODE_INPUT,
  291. .pull_up_en = GPIO_PULLUP_ENABLE, // 启用上拉,按钮按下时拉低
  292. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  293. .intr_type = GPIO_INTR_NEGEDGE // 下降沿触发(按下按钮)
  294. };
  295. err = gpio_config(&btn_conf);
  296. if (err != ESP_OK) {
  297. ESP_LOGE(BT_AV_TAG, "GPIO2 config failed: %s", esp_err_to_name(err));
  298. return;
  299. }
  300. // 配置GPIO19为输出模式
  301. gpio_config_t output_conf = {
  302. .pin_bit_mask = (1ULL << GPIO_OUTPUT),
  303. .mode = GPIO_MODE_OUTPUT,
  304. .pull_up_en = GPIO_PULLUP_DISABLE,
  305. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  306. .intr_type = GPIO_INTR_DISABLE
  307. };
  308. err = gpio_config(&output_conf);
  309. if (err != ESP_OK) {
  310. ESP_LOGE(BT_AV_TAG, "GPIO19 config failed: %s", esp_err_to_name(err));
  311. return;
  312. }
  313. // 初始化GPIO19为低电平
  314. gpio_set_level(GPIO_OUTPUT, 0);
  315. // 创建GPIO事件队列
  316. gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
  317. // 启动GPIO任务
  318. xTaskCreate(gpio_task, "gpio_task", 2048, NULL, 10, NULL);
  319. // 安装GPIO ISR服务
  320. gpio_install_isr_service(0);
  321. // 注册GPIO2的中断处理函数
  322. gpio_isr_handler_add(GPIO_BTN, gpio_isr_handler, (void*) GPIO_BTN);
  323. ESP_LOGI(BT_AV_TAG, "GPIO2 interrupt and GPIO19 output initialized");
  324. /*
  325. * This example only uses the functions of Classical Bluetooth.
  326. * So release the controller memory for Bluetooth Low Energy.
  327. */
  328. ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));
  329. esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  330. if ((err = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
  331. ESP_LOGE(BT_AV_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(err));
  332. return;
  333. }
  334. if ((err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
  335. ESP_LOGE(BT_AV_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(err));
  336. return;
  337. }
  338. esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
  339. #if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == false)
  340. bluedroid_cfg.ssp_en = false;
  341. #endif
  342. if ((err = esp_bluedroid_init_with_cfg(&bluedroid_cfg)) != ESP_OK) {
  343. ESP_LOGE(BT_AV_TAG, "%s initialize bluedroid failed: %s", __func__, esp_err_to_name(err));
  344. return;
  345. }
  346. if ((err = esp_bluedroid_enable()) != ESP_OK) {
  347. ESP_LOGE(BT_AV_TAG, "%s enable bluedroid failed: %s", __func__, esp_err_to_name(err));
  348. return;
  349. }
  350. #if (CONFIG_EXAMPLE_A2DP_SINK_SSP_ENABLED == true)
  351. /* set default parameters for Secure Simple Pairing */
  352. esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
  353. esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
  354. esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
  355. #endif
  356. /* set default parameters for Legacy Pairing (use fixed pin code 1234) */
  357. esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_FIXED;
  358. esp_bt_pin_code_t pin_code;
  359. pin_code[0] = '1';
  360. pin_code[1] = '2';
  361. pin_code[2] = '3';
  362. pin_code[3] = '4';
  363. esp_bt_gap_set_pin(pin_type, 4, pin_code);
  364. ESP_LOGI(BT_AV_TAG, "Own address:[%s]", bda2str((uint8_t *)esp_bt_dev_get_address(), bda_str, sizeof(bda_str)));
  365. bt_app_task_start_up();
  366. /* bluetooth device name, connection mode and profile set up */
  367. bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
  368. }