ESP32 ADF 语音开发基础 认识外设periphy 通过按键初步认识外设接口

认识完ADF的pipeline,element和event之后,继续学习peripyh外设接口,也是非常重要的ADF的接口,本节以按键为例子。
本节参考源文件在adf/compoments/esp_peripherals目录

event接口广泛使用在各个接口,对event接口的认识非常重要。

一,esp32外设接口 periph

1,adf关于外设结构体的定义

esp_periph成员:

  • tag:外设的标签,每个外设都有一个唯一的标签
  • disable:布尔值,外设是否使能。
  • periph_id:外设的id号,是在esp_periph.h文件中定义的元素
  • init,run,destroy:是外设的相关函数
  • state:外设工作状态
  • data:外设对应的具体的外设结构体指针,如button结构体指针。
  • event:外设的event接口,回调函数
  • entries:指向下一个外设

esp_periph_set实际上一个管理所有外设对象的任务

  • evengroup:事件标志组。
  • lock:信号量。
  • freertos任务配置。
  • periph_event:外设事件。
  • list:以esp_periph为成员的单链表。

在这里插入图片描述
periph_id:

/**
 * @brief Peripheral Identify, this must be unique for each peripheral added to the peripherals list
 */
typedef enum {
    PERIPH_ID_BUTTON     = AUDIO_ELEMENT_TYPE_PERIPH + 1,
    PERIPH_ID_TOUCH      = AUDIO_ELEMENT_TYPE_PERIPH + 2,
    PERIPH_ID_SDCARD     = AUDIO_ELEMENT_TYPE_PERIPH + 3,
    PERIPH_ID_WIFI       = AUDIO_ELEMENT_TYPE_PERIPH + 4,
    PERIPH_ID_FLASH      = AUDIO_ELEMENT_TYPE_PERIPH + 5,
    PERIPH_ID_AUXIN      = AUDIO_ELEMENT_TYPE_PERIPH + 6,
    PERIPH_ID_ADC        = AUDIO_ELEMENT_TYPE_PERIPH + 7,
    PERIPH_ID_CONSOLE    = AUDIO_ELEMENT_TYPE_PERIPH + 8,
    PERIPH_ID_BLUETOOTH  = AUDIO_ELEMENT_TYPE_PERIPH + 9,
    PERIPH_ID_LED        = AUDIO_ELEMENT_TYPE_PERIPH + 10,
    PERIPH_ID_SPIFFS     = AUDIO_ELEMENT_TYPE_PERIPH + 11,
    PERIPH_ID_ADC_BTN    = AUDIO_ELEMENT_TYPE_PERIPH + 12,
    PERIPH_ID_IS31FL3216 = AUDIO_ELEMENT_TYPE_PERIPH + 13,
    PERIPH_ID_GPIO_ISR   = AUDIO_ELEMENT_TYPE_PERIPH + 14,
    PERIPH_ID_WS2812     = AUDIO_ELEMENT_TYPE_PERIPH + 15,
    PERIPH_ID_AW2013     = AUDIO_ELEMENT_TYPE_PERIPH + 16
} esp_periph_id_t;

二,button外设

button外设接口逻辑框图:(参考periph_button.h
periph_button_cfg_t是用户来配置periph_button的结构体,用户可以配置的是按键的gpio和长按的时间。
在这里插入图片描述
button外设初始化逻辑图:
先初始化一个esp_periph接口,然后再初始化esp_button_handle,最后将button_item添加到list,当然这些都是ADF帮我们做好的。
在这里插入图片描述

三,用户代码

用户代码的逻辑是:初始化esp_periph_set,根据esp_periph_set创建esp_periph,esp_button_handle,初始化一个单链表,然后创建一个event事件接口,设置外设event的监听者。在任务中监听事件的消息,并根据消息内容作出动作。

初始化代码:

    //初始化默认外设接口
    esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
    esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);
    
    //初始化按键外设
    ESP_LOGI(TAG, "[1.1] Initialize keys on board");
    audio_board_key_init(set);
     
    //创建event接口
    ESP_LOGI(TAG, "[ 1.2 ] Set up  event listener");
    audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
    audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg);

    //监听按键的事件
    ESP_LOGI(TAG, "[1.3] Listening event from button peripherals");
    audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt);

处理代码:
audio_event_iface_listen();会使任务进入阻塞态直到接收到event的消息。

        audio_event_iface_msg_t msg;
        esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY);
        if (ret != ESP_OK) {
            ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret);
            continue;
        }
        if ((msg.source_type == PERIPH_ID_TOUCH || msg.source_type == PERIPH_ID_BUTTON || msg.source_type == PERIPH_ID_ADC_BTN)
            && (msg.cmd == PERIPH_TOUCH_TAP || msg.cmd == PERIPH_BUTTON_PRESSED || msg.cmd == PERIPH_ADC_BUTTON_PRESSED)) {
            
                if ((int) msg.data == get_input_play_id()){
                    ESP_LOGI(TAG, "GPIO_NUM_23");
                }
                else if((int) msg.data == get_input_volup_id()){
                    ESP_LOGI(TAG, "GPIO_NUM_18");
                }
                else if((int) msg.data == get_input_voldown_id()){
                    ESP_LOGI(TAG, "GPIO_NUM_5");
                }

        }

msg结构体定义如下:

  • cmd:命令的id,也就是event的id,这里是button_event_id
  • data:这里存放的是按键按下对应的gpio号
  • source:指向periph_button_handle
  • source_type:event源的类型,外设event的类型定义在periph_id

根据这些信息用户就可以作出相应的以上动作

/**
 * Event message
 */
typedef struct {
    int cmd;                /*!< Command id */
    void *data;             /*!< Data pointer */
    int data_len;           /*!< Data length */
    void *source;           /*!< Source event */
    int source_type;        /*!< Source type (To know where it came from) */
    bool need_free_data;    /*!< Need to free data pointer after the event has been processed */
} audio_event_iface_msg_t;

猜你喜欢

转载自blog.csdn.net/weixin_44821644/article/details/108035161
今日推荐