当前位置:网站首页>Esp32 audio frame esp-adf add key peripheral process code tracking
Esp32 audio frame esp-adf add key peripheral process code tracking
2022-07-02 11:44:00 【hwd00001】
This is a study note , Track key driver code , For your own reference only .
Take... For example 《esp-adf\examples\player\pipeline_play_sdcard_music》 Source code to analyze .
1. 《play_sdcard_music_example.c》 The main function app_main analysis
The following directly posts the code related to the key in the main function .
void app_main(void)
{
......
ESP_LOGI(TAG, "[1.0] Initialize peripherals management");
esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);//------(1)
ESP_LOGI(TAG, "[1.1] Initialize and start peripherals");
audio_board_key_init(set); //------(2)
audio_board_sdcard_init(set, SD_MODE_1_LINE);
......
ESP_LOGI(TAG, "[ 3 ] Create and start input key service");
input_key_service_info_t input_key_info[] = INPUT_KEY_DEFAULT_INFO();//------(3)
input_key_service_cfg_t input_cfg = INPUT_KEY_SERVICE_DEFAULT_CONFIG();//------(4)
input_cfg.handle = set; //------(5)
periph_service_handle_t input_ser = input_key_service_create(&input_cfg);//------(6)
input_key_service_add_key(input_ser, input_key_info, INPUT_KEY_NUM);//------(7)
periph_service_set_callback(input_ser, input_key_service_cb,
(void *)board_handle);//------(8)
......
}
Here we analyze each line of code , track .
1.1 esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);//------(1)
This code doesn't understand . The function is implemented in 《esp-adf\components\esp_peripherals\esp_peripherals.c》:
esp_periph_set_handle_t esp_periph_set_init(esp_periph_config_t *config)
{
esp_periph_set_t *periph_sets = NULL;
int _err_step = 1;
bool _success =
(
(periph_sets = audio_calloc(1, sizeof(esp_periph_set_t))) && _err_step ++ &&
(periph_sets->state_event_bits = xEventGroupCreate()) && _err_step ++ &&
(periph_sets->lock = mutex_create()) && _err_step ++
);
AUDIO_MEM_CHECK(TAG, _success, {
goto _periph_init_failed;
});
STAILQ_INIT(&periph_sets->periph_list);
//TODO: Should we uninstall gpio isr service??
//TODO: Because gpio need for sdcard and gpio, then install isr here
gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1);
periph_sets->run = false;
xEventGroupClearBits(periph_sets->state_event_bits, STARTED_BIT);
xEventGroupSetBits(periph_sets->state_event_bits, STOPPED_BIT);
periph_sets->task_stack = config->task_stack;
periph_sets->task_prio = config->task_prio;
periph_sets->task_core = config->task_core;
periph_sets->ext_stack = config->extern_stack;
audio_event_iface_cfg_t event_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG();
event_cfg.queue_set_size = 0;
event_cfg.context = periph_sets;
event_cfg.on_cmd = process_peripheral_event;
periph_sets->event_handle.iface = audio_event_iface_init(&event_cfg);
AUDIO_MEM_CHECK(TAG, periph_sets->event_handle.iface, goto _periph_init_failed);
audio_event_iface_set_cmd_waiting_timeout(periph_sets->event_handle.iface, DEFAULT_ESP_PERIPH_WAIT_TICK);
return periph_sets;
_periph_init_failed:
if (periph_sets) {
mutex_destroy(periph_sets->lock);
vEventGroupDelete(periph_sets->state_event_bits);
if (periph_sets->event_handle.iface) {
audio_event_iface_destroy(periph_sets->event_handle.iface);
}
audio_free(periph_sets);
periph_sets = NULL;
}
return NULL;
}
1.2 audio_board_key_init(set); //------(2)
Select the corresponding key according to your own development board IO mouth , I use “ESP32_A1S_Audio_Kit_v2_2” Replace with “lyrat_v4_3” The file of . In this way menuconfig When the configuration , Direct selection Audio HAL == lyrat_v4_3.
Look at the implementation code of this function :《D:\study\esp-adf\components\audio_board\lyrat_v4_3\board.c》
esp_err_t audio_board_key_init(esp_periph_set_handle_t set)
{
periph_button_cfg_t btn_cfg = {
.gpio_mask = ESP32_A1S_AUDIO_KEY1 |
ESP32_A1S_AUDIO_KEY2 |
ESP32_A1S_AUDIO_KEY3 |
ESP32_A1S_AUDIO_KEY4 |
ESP32_A1S_AUDIO_KEY5 |
ESP32_A1S_AUDIO_KEY6 , //REC BTN & MODE BTN
};
esp_periph_handle_t button_handle = periph_button_init(&btn_cfg);
AUDIO_NULL_CHECK(TAG, button_handle, return ESP_ERR_ADF_MEMORY_LACK);
esp_err_t ret = ESP_OK;
ret = esp_periph_start(set, button_handle);
if (ret != ESP_OK) {
return ret;
}
return ret;
}
1.3 input_key_service_info_t input_key_info[] =INPUT_KEY_DEFAULT_INFO()//------(3)
Combined with safe and credible ESP32-AUDIO-kit Schematic diagram of the bottom plate keys , Can be more clearly understood .
Through the selection of resistance , To decide whether to use the level value key or the analog value key :
Level value button :R55-R64 Use a suitable resistor ,R66-R70 leave a blank , need 6 individual IO mouth .
Analog value key :R55-R64 leave a blank ,R66-R70 Use 0R resistance , It only needs 1 individual IO mouth .
This data type is a structure :
typedef struct {
esp_periph_id_t type; /*!< ID of peripherals,-- Bus type , The buses related to keys are 3 Kind of : Level bus and analog input bus , Touch the key bus */
int user_id; /*!< The key's user id -- User defined functions ID */
int act_id; /*!< The key's action id -- Corresponding IO mouth GPIO_NUM_x */
} input_key_service_info_t;
typedef enum {
PERIPH_ID_BUTTON = AUDIO_ELEMENT_TYPE_PERIPH + 1, //-- Level bus
PERIPH_ID_TOUCH = AUDIO_ELEMENT_TYPE_PERIPH + 2, //-- Touch bus
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, //-- Analog input bus
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,
PERIPH_ID_LCD = AUDIO_ELEMENT_TYPE_PERIPH + 17
} esp_periph_id_t;
Give the structure array input_key_info[] Give the initial value INPUT_KEY_DEFAULT_INFO()
This is a macro definition , As follows :
...... // Here all use the level value buttons
#define BUTTON_REC_ID GPIO_NUM_36 //KEY1
#define BUTTON_MODE_ID GPIO_NUM_19 //KEY3
#define BUTTON_SET_ID GPIO_NUM_5 //KEY2 -- old==GPIO_NUM_13
#define BUTTON_PLAY_ID GPIO_NUM_23 //KEY4
#define BUTTON_VOLUP_ID GPIO_NUM_18 //KEY5
#define BUTTON_VOLDOWN_ID GPIO_NUM_36 //KEY6 -- old==GPIO_NUM_5
......
#define INPUT_KEY_DEFAULT_INFO() {
\ {
\ .type = PERIPH_ID_BUTTON, \ .user_id = INPUT_KEY_USER_ID_REC, \ .act_id = BUTTON_REC_ID, \ }, \ {
\ .type = PERIPH_ID_BUTTON, \ .user_id = INPUT_KEY_USER_ID_MODE, \ .act_id = BUTTON_MODE_ID, \ }, \ {
\ .type = PERIPH_ID_BUTTON, \ .user_id = INPUT_KEY_USER_ID_SET, \ .act_id = BUTTON_SET_ID, \ }, \ {
\ .type = PERIPH_ID_BUTTON, \ .user_id = INPUT_KEY_USER_ID_PLAY, \ .act_id = BUTTON_PLAY_ID, \ }, \ {
\ .type = PERIPH_ID_BUTTON, \ .user_id = INPUT_KEY_USER_ID_VOLUP, \ .act_id = BUTTON_VOLUP_ID, \ }, \ {
\ .type = PERIPH_ID_BUTTON, \ .user_id = INPUT_KEY_USER_ID_VOLDOWN, \ .act_id = BUTTON_VOLDOWN_ID, \ } \ }
1.4 input_key_service_cfg_t input_cfg = INPUT_KEY_SERVICE_DEFAULT_CONFIG();//------(4)
input_cfg.handle = set; //------(5)
(4)(5) Line together input_cfg To initialize .
set I can't understand this handle .
This is the key service configuration structure , See what it contains :
// <esp-adf\components\esp_peripherals\esp_peripherals.c>
typedef struct esp_periph_sets {
EventGroupHandle_t state_event_bits;
xSemaphoreHandle lock;
int task_stack;
int task_prio;
int task_core;
audio_thread_t audio_thread;
bool ext_stack;
bool run;
esp_periph_event_t event_handle;
STAILQ_HEAD(esp_periph_list_item, esp_periph) periph_list;
} esp_periph_set_t;
// <esp-adf\components\esp_peripherals\include\esp_peripherals.h>
typedef struct esp_periph_sets *esp_periph_set_handle_t;
//<esp-adf\components\input_key_service\include\input_key_service.h>
typedef struct {
periph_service_config_t based_cfg; /*!< Peripheral service configuration */
esp_periph_set_handle_t handle; /*!< Peripheral set handle */
} input_key_service_cfg_t;
#define INPUT_KEY_SERVICE_DEFAULT_CONFIG() {
\ .based_cfg = {
\ .task_stack = INPUT_KEY_SERVICE_TASK_STACK_SIZE, \ .task_prio = INPUT_KEY_SERVICE_TASK_PRIORITY, \ .task_core = INPUT_KEY_SERVICE_TASK_ON_CORE, \ .extern_stack = false \ } \ }
1.5 periph_service_handle_t input_ser = input_key_service_create(&input_cfg);//------(6)
Create key service handle , Function implementation in 《esp-adf\components\input_key_service\input_key_service.c》.
periph_service_handle_t input_key_service_create(input_key_service_cfg_t *input_key_config)
{
AUDIO_NULL_CHECK(TAG, input_key_config, return NULL);
periph_service_config_t *input_cfg = &input_key_config->based_cfg;
periph_service_config_t service_cfg = {
.task_stack = input_cfg->task_stack,
.task_prio = input_cfg->task_prio,
.task_core = input_cfg->task_core,
.extern_stack = input_cfg->extern_stack,
.task_func = input_key_service_task,
.service_start = input_key_service_start,
.service_stop = input_key_service_stop,
.service_destroy = input_key_service_destroy,
.service_ioctl = NULL,
.service_name = "input_key_service",
};
input_key_service_t *input_key_ser = NULL;
periph_service_handle_t input_key_handle = NULL;
input_key_ser = (input_key_service_t *)audio_calloc(1, sizeof(input_key_service_t));
AUDIO_NULL_CHECK(TAG, input_key_ser, goto _create_service_failed);
if (input_key_config->handle) {
input_key_ser->periph_set_handle = input_key_config->handle;
} else {
ESP_LOGE(TAG, "peripherals set handle is NULL");
free(input_key_ser);
return NULL;
}
input_key_ser->ser_state = PERIPH_SERVICE_STATE_UNKNOWN;
STAILQ_INIT(&input_key_ser->input_info_list);
service_cfg.user_data = (void *)input_key_ser;
input_key_handle = periph_service_create(&service_cfg);
AUDIO_NULL_CHECK(TAG, input_key_handle, goto _create_service_failed);
return input_key_handle;
_create_service_failed:
if (input_key_handle) {
audio_free(input_key_handle);
input_key_handle = NULL;
}
if (input_key_ser) {
audio_free(input_key_ser);
input_key_ser = NULL;
}
return NULL;
}
1.6 input_key_service_add_key(input_ser, input_key_info, INPUT_KEY_NUM);//------(7)
Include 6 An array of key information input_key_info Add to the key service function .
《esp-adf\components\input_key_service\input_key_service.c》
esp_err_t input_key_service_add_key(periph_service_handle_t input_key_handle, input_key_service_info_t *input_key_info, int add_key_num)
{
AUDIO_NULL_CHECK(TAG, input_key_handle, return ESP_ERR_INVALID_ARG);
AUDIO_NULL_CHECK(TAG, input_key_info, return ESP_ERR_INVALID_ARG);
if (add_key_num <= 0) {
return ESP_FAIL;
}
input_key_service_t *input_key_ser = periph_service_get_data(input_key_handle);
AUDIO_NULL_CHECK(TAG, input_key_ser, return ESP_FAIL);
for (int i = 0; i < add_key_num; i++) {
input_key_node_t *input_key_node = (input_key_node_t *)audio_calloc(1, sizeof(input_key_node_t));
AUDIO_NULL_CHECK(TAG, input_key_node, return ESP_FAIL);
memcpy(&input_key_node->input_key_info, &input_key_info[i], sizeof(input_key_service_info_t));
STAILQ_INSERT_TAIL(&input_key_ser->input_info_list, input_key_node, entries);
}
return ESP_OK;
}
边栏推荐
- Is it safe to open a stock account through the QR code of the securities manager? Or is it safe to open an account in a securities company?
- Webauthn - official development document
- Xiao Sha's pain (double pointer
- 揭露数据不一致的利器 —— 实时核对系统
- What are the methods of adding elements to arrays in JS
- Map set assignment to database
- 基于 Openzeppelin 的可升级合约解决方案的注意事项
- 程序员成长第六篇:如何选择公司?
- 在网上开股票账户安全吗?我是新手,还请指导
- spritejs
猜你喜欢

webauthn——官方开发文档

Tdsql | difficult employment? Tencent cloud database micro authentication to help you

Mmrotate rotation target detection framework usage record

Attribute acquisition method and operation notes of C # multidimensional array

mmrotate旋转目标检测框架使用记录

Amazon cloud technology community builder application window opens

Wechat applet uses Baidu API to achieve plant recognition

八大排序汇总

微信小程序利用百度api达成植物识别

Tick Data and Resampling
随机推荐
基于 Openzeppelin 的可升级合约解决方案的注意事项
Xiao Sha's pain (double pointer
PHP query distance according to longitude and latitude
可昇級合約的原理-DelegateCall
通过券商经理的开户二维码开股票账户安全吗?还是去证券公司开户安全?
Digital transformation takes the lead to resume production and work, and online and offline full integration rebuilds business logic
How to Visualize Missing Data in R using a Heatmap
ctf 记录
Principe du contrat évolutif - delegatecall
ImportError: cannot import name ‘Digraph‘ from ‘graphviz‘
Installation of ROS gazebo related packages
从ros1到ros2配置的一些东西
HOW TO CREATE A BEAUTIFUL INTERACTIVE HEATMAP IN R
What week is a date obtained by QT
STM32 single chip microcomputer programming learning
ROS lacks xacro package
程序员成长第六篇:如何选择公司?
R HISTOGRAM EXAMPLE QUICK REFERENCE
spritejs
【云原生】2.5 Kubernetes 核心实战(下)