mirror of
https://github.com/m5stack/esp-adf.git
synced 2026-05-20 10:25:46 -07:00
cad40aed4f
Add new periph_is31fl3216 APIs
455 lines
16 KiB
C
455 lines
16 KiB
C
/* Console example.
|
|
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
|
Unless required by applicable law or agreed to in writing, this
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "esp_wifi.h"
|
|
#include "nvs_flash.h"
|
|
#include "esp_log.h"
|
|
#include "sdkconfig.h"
|
|
#include "audio_element.h"
|
|
#include "audio_mem.h"
|
|
#include "board.h"
|
|
#include "audio_common.h"
|
|
#include "fatfs_stream.h"
|
|
#include "raw_stream.h"
|
|
#include "i2s_stream.h"
|
|
#include "esp_audio.h"
|
|
#include "esp_peripherals.h"
|
|
#include "periph_sdcard.h"
|
|
#include "periph_wifi.h"
|
|
#include "periph_button.h"
|
|
#include "periph_console.h"
|
|
#include "esp_decoder.h"
|
|
#include "amr_decoder.h"
|
|
#include "flac_decoder.h"
|
|
#include "ogg_decoder.h"
|
|
#include "opus_decoder.h"
|
|
#include "mp3_decoder.h"
|
|
#include "wav_decoder.h"
|
|
#include "aac_decoder.h"
|
|
#include "http_stream.h"
|
|
#include "wav_encoder.h"
|
|
#include "display_service.h"
|
|
#include "led_bar_is31x.h"
|
|
|
|
#define ESP_AUDIO_AUTO_PLAY
|
|
|
|
static const char *TAG = "CONSOLE_EXAMPLE";
|
|
static esp_audio_handle_t player;
|
|
static esp_periph_set_handle_t set;
|
|
|
|
int _http_stream_event_handle(http_stream_event_msg_t *msg)
|
|
{
|
|
if (msg->event_id == HTTP_STREAM_RESOLVE_ALL_TRACKS) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
if (msg->event_id == HTTP_STREAM_FINISH_TRACK) {
|
|
return http_stream_next_track(msg->el);
|
|
}
|
|
if (msg->event_id == HTTP_STREAM_FINISH_PLAYLIST) {
|
|
return http_stream_restart(msg->el);
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t cli_play(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
ESP_LOGI(TAG, "app_audio play");
|
|
const char *uri[] = {
|
|
"file://sdcard/test.amr",
|
|
"file://sdcard/test.flac",
|
|
"file://sdcard/test.ogg",
|
|
"file://sdcard/test.opus",
|
|
"file://sdcard/test.mp3",
|
|
"file://sdcard/test.wav",
|
|
"file://sdcard/test.aac",
|
|
"file://sdcard/test.m4a",
|
|
"file://sdcard/test.ts",
|
|
"http://dl.espressif.com/dl/audio/adf_music.mp3",
|
|
};
|
|
|
|
char *str = NULL;
|
|
if (argv[0] && argc) {
|
|
if (isdigit((int)argv[0][0])) {
|
|
int index = atoi(argv[0]);
|
|
if (index >= sizeof(uri) / sizeof(char *)) {
|
|
ESP_LOGE(TAG, "Out of range, index:%d", index);
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
str = (char *)uri[index];
|
|
ESP_LOGI(TAG, "play index= %d, URI:%s", index, str);
|
|
} else {
|
|
ESP_LOGI(TAG, "play URI:%s", argv[0]);
|
|
str = argv[0];
|
|
}
|
|
}
|
|
esp_audio_play(player, AUDIO_CODEC_TYPE_DECODER, str, 0);
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t cli_pause(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
esp_audio_pause(player);
|
|
ESP_LOGI(TAG, "app_audio paused");
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t cli_resume(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
esp_audio_resume(player);
|
|
ESP_LOGI(TAG, "app_audio resume");
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t cli_stop(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
esp_audio_stop(player, 0);
|
|
ESP_LOGI(TAG, "app_audio stop");
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t cli_set_vol(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
int cur_vol = 0;
|
|
if (argc == 1) {
|
|
cur_vol = atoi(argv[0]);
|
|
} else {
|
|
ESP_LOGE(TAG, "Invalid volume parameter");
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
int prev_vol = 0;
|
|
esp_audio_vol_get(player, &prev_vol);
|
|
esp_audio_vol_set(player, cur_vol);
|
|
ESP_LOGI(TAG, "Volume setting changed from %d to %d", prev_vol, cur_vol);
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t cli_get_vol(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
int vol = 0;
|
|
esp_audio_vol_get(player, &vol);
|
|
ESP_LOGI(TAG, "Current volume is %d", vol);
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t get_pos(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
int pos = 0;
|
|
esp_audio_time_get(player, &pos);
|
|
ESP_LOGI(TAG, "Current time position is %d second", pos / 1000);
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t wifi_set(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
wifi_config_t w_config = {0};
|
|
switch (argc) {
|
|
case 2:
|
|
memcpy(w_config.sta.password, argv[1], strlen(argv[1]));
|
|
case 1:
|
|
memcpy(w_config.sta.ssid, argv[0], strlen(argv[0]));
|
|
esp_wifi_disconnect();
|
|
ESP_LOGI(TAG, "Connecting Wi-Fi, SSID:\"%s\" PASSWORD:\"%s\"", w_config.sta.ssid, w_config.sta.password);
|
|
esp_wifi_set_config(WIFI_IF_STA, &w_config);
|
|
esp_wifi_connect();
|
|
break;
|
|
default:
|
|
ESP_LOGE(TAG, "Invalid SSID or PASSWORD");
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t wifi_info(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
wifi_config_t w_config = {0};
|
|
wifi_ap_record_t ap_info = {0};
|
|
esp_err_t ret = esp_wifi_sta_get_ap_info(&ap_info);
|
|
if (ret == ESP_ERR_WIFI_NOT_CONNECT) {
|
|
ESP_LOGI(TAG, "Not connected Wi-Fi");
|
|
return ESP_OK;
|
|
}
|
|
if (ESP_OK == esp_wifi_get_config(WIFI_IF_STA, &w_config)) {
|
|
ESP_LOGI(TAG, "Connected Wi-Fi, SSID:\"%s\"", w_config.sta.ssid);
|
|
} else {
|
|
ESP_LOGE(TAG, "esp_wifi_get_config failed");
|
|
return ESP_FAIL;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t led(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
static display_service_handle_t disp_led_serv = NULL;
|
|
if (disp_led_serv == NULL) {
|
|
esp_periph_handle_t led_bar = led_bar_is31x_init();
|
|
if (led_bar == NULL) {
|
|
ESP_LOGE(TAG, "led_bar handle create failed, this command only support lyrat-msc board");
|
|
return ESP_FAIL;
|
|
}
|
|
display_service_config_t display = {
|
|
.based_cfg = {
|
|
.task_stack = 0,
|
|
.task_prio = 0,
|
|
.task_core = 0,
|
|
.task_func = NULL,
|
|
.service_start = NULL,
|
|
.service_stop = NULL,
|
|
.service_destroy = NULL,
|
|
.service_ioctl = led_bar_is31x_pattern,
|
|
.service_name = "DISPLAY_LED_BAR",
|
|
.user_data = NULL,
|
|
},
|
|
.instance = led_bar,
|
|
};
|
|
disp_led_serv = display_service_create(&display);
|
|
}
|
|
int cur_vol = 0;
|
|
if (argc == 1) {
|
|
cur_vol = atoi(argv[0]);
|
|
} else {
|
|
ESP_LOGE(TAG, "Invalid volume parameter, %d", argc);
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
ESP_LOGI(TAG, "Set display pattern %d", cur_vol);
|
|
display_service_set_pattern(disp_led_serv, cur_vol, 0);
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t sys_reset(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
esp_restart();
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t show_free_mem(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
AUDIO_MEM_SHOW(TAG);
|
|
return ESP_OK;
|
|
}
|
|
|
|
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
|
|
static esp_err_t run_time_stats(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
static char buf[1024];
|
|
vTaskGetRunTimeStats(buf);
|
|
printf("Run Time Stats:\nTask Name Time Percent\n%s\n", buf);
|
|
return ESP_OK;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
|
|
static esp_err_t task_list(esp_periph_handle_t periph, int argc, char *argv[])
|
|
{
|
|
static char buf[1024];
|
|
vTaskList(buf);
|
|
printf("Task List:\nTask Name Status Prio HWM Task Number\n%s\n", buf);
|
|
return ESP_OK;
|
|
}
|
|
#endif
|
|
|
|
|
|
const periph_console_cmd_t cli_cmd[] = {
|
|
/* ======================== Esp_audio ======================== */
|
|
{ .cmd = "play", .id = 1, .help = "Play music", .func = cli_play },
|
|
{ .cmd = "pause", .id = 2, .help = "Pause", .func = cli_pause },
|
|
{ .cmd = "resume", .id = 3, .help = "Resume", .func = cli_resume },
|
|
{ .cmd = "stop", .id = 3, .help = "Stop player", .func = cli_stop },
|
|
{ .cmd = "setvol", .id = 4, .help = "Set volume", .func = cli_set_vol },
|
|
{ .cmd = "getvol", .id = 5, .help = "Get volume", .func = cli_get_vol },
|
|
{ .cmd = "getpos", .id = 6, .help = "Get position by seconds", .func = get_pos },
|
|
|
|
/* ======================== Wi-Fi ======================== */
|
|
{ .cmd = "join", .id = 20, .help = "Join WiFi AP as a station", .func = wifi_set },
|
|
{ .cmd = "wifi", .id = 21, .help = "Get connected AP information", .func = wifi_info },
|
|
|
|
/* ======================== Led bar ======================== */
|
|
{ .cmd = "led", .id = 1, .help = "Lyrat-MSC led bar pattern", .func = led },
|
|
|
|
/* ======================== System ======================== */
|
|
{ .cmd = "reboot", .id = 30, .help = "Reboot system", .func = sys_reset },
|
|
{ .cmd = "free", .id = 31, .help = "Get system free memory", .func = show_free_mem },
|
|
#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
|
|
{ .cmd = "stat", .id = 32, .help = "Show processor time of all FreeRTOS tasks", .func = run_time_stats },
|
|
#endif
|
|
#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY
|
|
{ .cmd = "tasks", .id = 33, .help = "Get information about running tasks", .func = task_list },
|
|
#endif
|
|
};
|
|
|
|
static void esp_audio_state_task (void *para)
|
|
{
|
|
QueueHandle_t que = (QueueHandle_t) para;
|
|
esp_audio_state_t esp_state = {0};
|
|
while (1) {
|
|
xQueueReceive(que, &esp_state, portMAX_DELAY);
|
|
ESP_LOGI(TAG, "esp_auido status:%x,err:%x\n", esp_state.status, esp_state.err_msg);
|
|
}
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
static void cli_setup_wifi()
|
|
{
|
|
ESP_LOGI(TAG, "Start Wi-Fi");
|
|
periph_wifi_cfg_t wifi_cfg = {
|
|
.disable_auto_reconnect = true,
|
|
.ssid = "",
|
|
.password = "",
|
|
};
|
|
esp_periph_handle_t wifi_handle = periph_wifi_init(&wifi_cfg);
|
|
esp_periph_start(set, wifi_handle);
|
|
}
|
|
|
|
static void cli_setup_sdcard()
|
|
{
|
|
ESP_LOGI(TAG, "Start SdCard");
|
|
periph_sdcard_cfg_t sdcard_cfg = {
|
|
.root = "/sdcard",
|
|
.card_detect_pin = get_sdcard_intr_gpio(), // GPIO_NUM_34
|
|
};
|
|
esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sdcard_cfg);
|
|
esp_periph_start(set, sdcard_handle);
|
|
|
|
while (!periph_sdcard_is_mounted(sdcard_handle)) {
|
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
|
ESP_LOGI(TAG, "sdcard mounting...");
|
|
}
|
|
}
|
|
|
|
static void cli_setup_console()
|
|
{
|
|
periph_console_cfg_t console_cfg = {
|
|
.command_num = sizeof(cli_cmd) / sizeof(periph_console_cmd_t),
|
|
.commands = cli_cmd,
|
|
};
|
|
esp_periph_handle_t console_handle = periph_console_init(&console_cfg);
|
|
esp_periph_start(set, console_handle);
|
|
}
|
|
|
|
static void cli_setup_player(void)
|
|
{
|
|
if (player ) {
|
|
return ;
|
|
}
|
|
esp_audio_cfg_t cfg = {
|
|
.in_stream_buf_size = 10 * 1024,
|
|
.out_stream_buf_size = 6 * 1024,
|
|
.evt_que = NULL,
|
|
.resample_rate = 0,
|
|
.hal = NULL,
|
|
};
|
|
|
|
|
|
audio_board_handle_t board_handle = audio_board_init();
|
|
cfg.hal = board_handle->audio_hal;
|
|
cfg.evt_que = xQueueCreate(3, sizeof(esp_audio_state_t));
|
|
audio_hal_ctrl_codec(cfg.hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);
|
|
player = esp_audio_create(&cfg);
|
|
xTaskCreate(esp_audio_state_task, "player_task", 4096, cfg.evt_que, 1, NULL);
|
|
|
|
// Create readers and add to esp_audio
|
|
fatfs_stream_cfg_t fs_reader = FATFS_STREAM_CFG_DEFAULT();
|
|
fs_reader.type = AUDIO_STREAM_READER;
|
|
i2s_stream_cfg_t i2s_reader = I2S_STREAM_CFG_DEFAULT();
|
|
i2s_reader.type = AUDIO_STREAM_READER;
|
|
raw_stream_cfg_t raw_reader = RAW_STREAM_CFG_DEFAULT();
|
|
raw_reader.type = AUDIO_STREAM_READER;
|
|
|
|
esp_audio_input_stream_add(player, raw_stream_init(&raw_reader));
|
|
esp_audio_input_stream_add(player, fatfs_stream_init(&fs_reader));
|
|
esp_audio_input_stream_add(player, i2s_stream_init(&i2s_reader));
|
|
http_stream_cfg_t http_cfg = HTTP_STREAM_CFG_DEFAULT();
|
|
http_cfg.event_handle = _http_stream_event_handle;
|
|
http_cfg.type = AUDIO_STREAM_READER;
|
|
http_cfg.enable_playlist_parser = true;
|
|
audio_element_handle_t http_stream_reader = http_stream_init(&http_cfg);
|
|
esp_audio_input_stream_add(player, http_stream_reader);
|
|
|
|
// Create writers and add to esp_audio
|
|
fatfs_stream_cfg_t fs_writer = FATFS_STREAM_CFG_DEFAULT();
|
|
fs_writer.type = AUDIO_STREAM_WRITER;
|
|
|
|
i2s_stream_cfg_t i2s_writer = I2S_STREAM_CFG_DEFAULT();
|
|
i2s_writer.type = AUDIO_STREAM_WRITER;
|
|
|
|
raw_stream_cfg_t raw_writer = RAW_STREAM_CFG_DEFAULT();
|
|
raw_writer.type = AUDIO_STREAM_WRITER;
|
|
|
|
esp_audio_output_stream_add(player, i2s_stream_init(&i2s_writer));
|
|
esp_audio_output_stream_add(player, fatfs_stream_init(&fs_writer));
|
|
esp_audio_output_stream_add(player, raw_stream_init(&raw_writer));
|
|
|
|
// Add decoders and encoders to esp_audio
|
|
#ifdef ESP_AUDIO_AUTO_PLAY
|
|
audio_decoder_t auto_decode[] = {
|
|
DEFAULT_ESP_AMRNB_DECODER_CONFIG(),
|
|
DEFAULT_ESP_AMRWB_DECODER_CONFIG(),
|
|
DEFAULT_ESP_FLAC_DECODER_CONFIG(),
|
|
DEFAULT_ESP_OGG_DECODER_CONFIG(),
|
|
DEFAULT_ESP_OPUS_DECODER_CONFIG(),
|
|
DEFAULT_ESP_MP3_DECODER_CONFIG(),
|
|
DEFAULT_ESP_WAV_DECODER_CONFIG(),
|
|
DEFAULT_ESP_AAC_DECODER_CONFIG(),
|
|
DEFAULT_ESP_M4A_DECODER_CONFIG(),
|
|
DEFAULT_ESP_TS_DECODER_CONFIG(),
|
|
};
|
|
esp_decoder_cfg_t auto_dec_cfg = DEFAULT_ESP_DECODER_CONFIG();
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, esp_decoder_init(&auto_dec_cfg, auto_decode, 10));
|
|
#else
|
|
amr_decoder_cfg_t amr_dec_cfg = DEFAULT_AMR_DECODER_CONFIG();
|
|
flac_decoder_cfg_t flac_dec_cfg = DEFAULT_FLAC_DECODER_CONFIG();
|
|
ogg_decoder_cfg_t ogg_dec_cfg = DEFAULT_OGG_DECODER_CONFIG();
|
|
opus_decoder_cfg_t opus_dec_cfg = DEFAULT_OPUS_DECODER_CONFIG();
|
|
mp3_decoder_cfg_t mp3_dec_cfg = DEFAULT_MP3_DECODER_CONFIG();
|
|
wav_decoder_cfg_t wav_dec_cfg = DEFAULT_WAV_DECODER_CONFIG();
|
|
aac_decoder_cfg_t aac_dec_cfg = DEFAULT_AAC_DECODER_CONFIG();
|
|
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, amr_decoder_init(&amr_dec_cfg));
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, flac_decoder_init(&flac_dec_cfg));
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, ogg_decoder_init(&ogg_dec_cfg));
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, decoder_opus_init(&opus_dec_cfg));
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, mp3_decoder_init(&mp3_dec_cfg));
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, wav_decoder_init(&wav_dec_cfg));
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, aac_decoder_init(&aac_dec_cfg));
|
|
audio_element_handle_t m4a_dec_cfg = aac_decoder_init(&aac_dec_cfg);
|
|
audio_element_set_tag(m4a_dec_cfg, "m4a");
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, m4a_dec_cfg);
|
|
|
|
audio_element_handle_t ts_dec_cfg = aac_decoder_init(&aac_dec_cfg);
|
|
audio_element_set_tag(ts_dec_cfg, "ts");
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_DECODER, ts_dec_cfg);
|
|
|
|
wav_encoder_cfg_t wav_enc_cfg = DEFAULT_WAV_ENCODER_CONFIG();
|
|
esp_audio_codec_lib_add(player, AUDIO_CODEC_TYPE_ENCODER, wav_encoder_init(&wav_enc_cfg));
|
|
#endif
|
|
// Set default volume
|
|
esp_audio_vol_set(player, 45);
|
|
AUDIO_MEM_SHOW(TAG);
|
|
ESP_LOGI(TAG, "esp_audio instance is:%p\r\n", player);
|
|
}
|
|
|
|
void app_main(void)
|
|
{
|
|
esp_log_level_set("*", ESP_LOG_INFO);
|
|
ESP_ERROR_CHECK(nvs_flash_init());
|
|
tcpip_adapter_init();
|
|
esp_periph_config_t periph_cfg = DEFAULT_ESP_PHERIPH_SET_CONFIG();
|
|
set = esp_periph_set_init(&periph_cfg);
|
|
|
|
cli_setup_sdcard();
|
|
cli_setup_wifi();
|
|
cli_setup_player();
|
|
|
|
cli_setup_console();
|
|
}
|