当前位置:网站首页>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;
}
边栏推荐
猜你喜欢
Wechat applet uses Baidu API to achieve plant recognition
Is the Ren domain name valuable? Is it worth investing? What is the application scope of Ren domain name?
Verilog and VHDL signed and unsigned number correlation operations
Verilog 和VHDL有符号数和无符号数相关运算
八大排序汇总
Develop scalable contracts based on hardhat and openzeppelin (II)
Skills of PLC recorder in quickly monitoring multiple PLC bits
Map set assignment to database
ctf 记录
Cluster Analysis in R Simplified and Enhanced
随机推荐
原生方法合并word
Attribute acquisition method and operation notes of C # multidimensional array
Gaode draws lines according to the track
php 根据经纬度查询距离
Tick Data and Resampling
[cloud native] 2.5 kubernetes core practice (Part 2)
CTF record
MySQL比较运算符IN问题求解
接口调试工具概论
Seriation in R: How to Optimally Order Objects in a Data Matrice
Functional interfaces and method references
JS——每次调用从数组里面随机取一个数,且不能与上一次为同一个
Map set assignment to database
Liftover for genome coordinate conversion
HOW TO CREATE AN INTERACTIVE CORRELATION MATRIX HEATMAP IN R
八大排序汇总
Jenkins installation
Redis超出最大内存错误OOM command not allowed when used memory &gt; 'maxmemory'
程序员成长第六篇:如何选择公司?
Principle of scalable contract delegatecall