| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- //
- // Created by kindring on 2025/12/26.
- //
- #include "esp_log.h"
- #include "app_io.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #define TAG "app_io"
- static QueueHandle_t g_io_evt_queue = NULL;
- static void io_task(void* arg)
- {
- uint32_t io_num;
- while (true)
- {
- if(xQueueReceive(g_io_evt_queue, &io_num, portMAX_DELAY))
- {
- // 消抖处理
- vTaskDelay(50 / portTICK_PERIOD_MS);
- if(gpio_get_level(io_num) == 0)
- { // 确认仍然是低电平
- ESP_LOGI(TAG, "GPIO%"PRIu32" interrupt, button pressed", io_num);
- next_audio_mode();
- }
- }
- }
- }
- static void IRAM_ATTR gpio_isr_handler(void* arg)
- {
- const uint32_t gpio_num = (uint32_t) arg;
- xQueueSendFromISR(g_io_evt_queue, &gpio_num, NULL);
- }
- /**
- * 切换系统状态灯
- * @param on
- * @return
- */
- esp_err_t set_led_io(const bool on)
- {
- const esp_err_t err = gpio_set_level(IO_LED, on);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "Set system to %d failed: %s", on, esp_err_to_name(err));
- return err;
- }
- return ESP_OK;
- }
- esp_err_t init_led_io() {
- // system state led
- const gpio_config_t led_io_conf = {
- .pin_bit_mask = (1ULL << IO_LED), // GPIO15
- .mode = GPIO_MODE_OUTPUT, // 输出模式
- .pull_up_en = GPIO_PULLUP_DISABLE, // 禁用上拉
- .pull_down_en = GPIO_PULLDOWN_DISABLE, // 禁用下拉
- .intr_type = GPIO_INTR_DISABLE // 禁用中断
- };
- // 配置GPIO
- const esp_err_t err = gpio_config(&led_io_conf);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "system led config failed: %s", esp_err_to_name(err));
- return err;
- }
- return set_led_io(0);
- }
- esp_err_t init_btn_io() {
- // 配置GPIO2为输入模式,用于低电平中断
- const gpio_config_t btn_conf = {
- .pin_bit_mask = (1ULL << IO_BTN),
- .mode = GPIO_MODE_INPUT,
- .pull_up_en = GPIO_PULLUP_ENABLE, // 启用上拉,按钮按下时拉低
- .pull_down_en = GPIO_PULLDOWN_DISABLE,
- .intr_type = GPIO_INTR_NEGEDGE // 下降沿触发(按下按钮)
- };
- const esp_err_t err = gpio_config(&btn_conf);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "BTN config failed: %s", esp_err_to_name(err));
- return err;
- }
- // 注册中断服务
- gpio_isr_handler_add(IO_BTN, gpio_isr_handler, (void*) IO_BTN);
- return ESP_OK;
- }
- // 更新输出引脚状态
- esp_err_t update_output_mode(const audio_mode_t mode)
- {
- esp_err_t err = ESP_OK;
- // 根据音频模式设置GPIO19输出状态
- switch(mode) {
- case AUDIO_MODE_NORMAL:
- err = gpio_set_level(IO_OUTPUT_SW, 0); // 低电平
- break;
- case AUDIO_MODE_BASS_BOOST:
- err = gpio_set_level(IO_OUTPUT_SW, 1); // 高电平
- break;
- default:
- err = gpio_set_level(IO_OUTPUT_SW, 0);
- break;
- }
- ESP_LOGD(TAG, "GPIO19 set to: %d", gpio_get_level(IO_OUTPUT_SW));
- return err;
- }
- // 初始化输出引脚
- esp_err_t init_output_io() {
- // 配置GPIO2为输入模式,用于低电平中断
- const gpio_config_t output_conf = {
- .pin_bit_mask = (1ULL << IO_OUTPUT_SW),
- .mode = GPIO_MODE_OUTPUT,
- .pull_up_en = GPIO_PULLUP_DISABLE,
- .pull_down_en = GPIO_PULLDOWN_DISABLE,
- .intr_type = GPIO_INTR_DISABLE
- };
- const esp_err_t err = gpio_config(&output_conf);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "OUTPUT config failed: %s", esp_err_to_name(err));
- return err;
- }
- return ESP_OK;
- }
- // 启用或者关闭功放
- esp_err_t enable_amp(const bool on) {
- // 低有效, 高无效, 需要将电平反转
- const int io_level = !on;
- const esp_err_t err = gpio_set_level(IO_AMP_EN, io_level );
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "%s apm failed: %s", on? "ENABLE" : "DISABLE", esp_err_to_name(err));
- return err;
- }
- return ESP_OK;
- }
- esp_err_t init_amp_io() {
- // 配置GPIO32为输出模式并拉低电平
- const gpio_config_t io_conf = {
- .pin_bit_mask = (1ULL << IO_AMP_EN), // GPIO32
- .mode = GPIO_MODE_OUTPUT, // 输出模式
- .pull_up_en = GPIO_PULLUP_DISABLE, // 禁用上拉
- .pull_down_en = GPIO_PULLDOWN_DISABLE, // 禁用下拉
- .intr_type = GPIO_INTR_DISABLE // 禁用中断
- };
- // 配置GPIO
- const esp_err_t err = gpio_config(&io_conf);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "IO_AMP_EN config failed: %s", esp_err_to_name(err));
- return err;
- }
- return enable_amp(false);
- }
- // 初始化io引脚配置
- int init_io() {
- // 安装GPIO ISR服务
- esp_err_t err = gpio_install_isr_service(0);
- g_io_evt_queue = xQueueCreate(10, sizeof(uint32_t));
- xTaskCreate(io_task, "io_task", 2048, NULL, 10, NULL);
- init_amp_io();
- init_output_io();
- init_led_io();
- init_btn_io();
- return 0;
- }
|