当前位置:网站首页>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;
}
边栏推荐
- MySQL比较运算符IN问题求解
- Order by注入
- 亚马逊云科技 Community Builder 申请窗口开启
- 念念不忘,必有回响 | 悬镜诚邀您参与OpenSCA用户有奖调研
- Order by injection
- C#基于当前时间,获取唯一识别号(ID)的方法
- R HISTOGRAM EXAMPLE QUICK REFERENCE
- Precautions for scalable contract solution based on openzeppelin
- The computer screen is black for no reason, and the brightness cannot be adjusted.
- Is it safe to open a stock account online? I'm a novice, please guide me
猜你喜欢

MySQL comparison operator in problem solving

The computer screen is black for no reason, and the brightness cannot be adjusted.

在连接mysql数据库的时候一直报错

MySQL比较运算符IN问题求解

TDSQL|就业难?腾讯云数据库微认证来帮你

HOW TO EASILY CREATE BARPLOTS WITH ERROR BARS IN R

基于Hardhat和Openzeppelin开发可升级合约(一)

Map set assignment to database

What is the relationship between digital transformation of manufacturing industry and lean production

Amazon cloud technology community builder application window opens
随机推荐
ren域名有价值吗?值不值得投资?ren域名的应用范围有哪些?
php 根据经纬度查询距离
Compilation errors and printout garbled problems caused by Chinese content in vs2019 code
What week is a date obtained by QT
How to Create a Beautiful Plots in R with Summary Statistics Labels
对毕业季即将踏入职场的年轻人的一点建议
Functional interfaces and method references
STM32 single chip microcomputer programming learning
Attribute acquisition method and operation notes of C # multidimensional array
On April 17, 2022, the five heart matchmaker team received double good news
Tick Data and Resampling
PYQT5+openCV项目实战:微循环仪图片、视频记录和人工对比软件(附源码)
Is the stock account given by qiniu business school safe? Can I open an account?
Liftover for genome coordinate conversion
Summary of data export methods in powerbi
Cluster Analysis in R Simplified and Enhanced
基于Hardhat和Openzeppelin开发可升级合约(一)
[idea] use the plug-in to reverse generate code with one click
抖音海外版TikTok:正与拜登政府敲定最终数据安全协议
PX4 Position_ Control RC_ Remoter import