### Install and Configure ESP-ADF Component for AI Thinker ESP32 A1S Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Instructions for cloning the repository, creating a symlink to integrate the component into an ESP-IDF project, and configuring the board variant using `idf.py menuconfig`. This setup is crucial for enabling the custom audio board features. ```bash # Clone the repository git clone https://github.com/trombik/esp-adf-component-ai-thinker-esp32-a1s.git # In your ESP-IDF project root, create components directory if needed mkdir -p components # Create symlink to the board component ln -s /path/to/esp-adf-component-ai-thinker-esp32-a1s/components/ai-thinker-esp32-a1s components/ # Configure the board idf.py menuconfig # Navigate to: Audio HAL > Audio board > Select "Custom audio board" # Navigate to: Custom Audio Board > Select your ES8388 variant (5 or 7) # Press 's' to save configuration ``` -------------------------------- ### Initialize On-Board SD Card (C) Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Initializes the on-board SD card peripheral with automatic mount retry functionality. This requires enabling the SD card in menuconfig and ensuring the DATA3 and CMD switches on the board are set to the ON position. The function attempts to mount the SD card and logs its status. Requires 'board.h' and 'periph_sdcard.h'. ```c #include "board.h" #include "periph_sdcard.h" // Enable in menuconfig: Custom Audio Board > Use on-board SD card void setup_sdcard(void) { // Create peripheral set esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD card in 1-line mode esp_err_t ret = audio_board_sdcard_init(set, SD_MODE_1_LINE); if (ret != ESP_OK) { ESP_LOGE("SD", "SD card initialization failed - check switches are ON"); return; } ESP_LOGI("SD", "SD card mounted at /sdcard"); // Now you can access files on SD card FILE *f = fopen("/sdcard/test.mp3", "r"); if (f) { ESP_LOGI("SD", "File opened successfully"); fclose(f); } } ``` -------------------------------- ### Manage Audio Board Handle (C) Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Provides functions to initialize the audio board, retrieve its singleton handle, and deinitialize it to release resources. `audio_board_init()` creates the handle, `audio_board_get_handle()` retrieves the existing handle, and `audio_board_deinit()` cleans up resources. Requires 'board.h'. ```c #include "board.h" void audio_operations(void) { // Initialize board once audio_board_handle_t board = audio_board_init(); // ... elsewhere in the code, get the existing handle audio_board_handle_t existing_board = audio_board_get_handle(); if (existing_board != NULL) { // Use the board handle audio_hal_set_volume(existing_board->audio_hal, 80); } } void cleanup(void) { // Get the board handle audio_board_handle_t board = audio_board_get_handle(); if (board != NULL) { // Deinitialize and free resources esp_err_t ret = audio_board_deinit(board); if (ret == ESP_OK) { ESP_LOGI("BOARD", "Audio board deinitialized successfully"); } } } ``` -------------------------------- ### MP3 Player with Button Control using ESP-ADF (C) Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Demonstrates initializing an audio board, setting up peripherals like buttons and LEDs, creating an audio pipeline for MP3 playback from an HTTP stream, and handling playback control (play/pause, volume) via button presses. Requires ESP-ADF and ESP-IDF. ```c #include "board.h" #include "audio_pipeline.h" #include "audio_element.h" #include "audio_event_iface.h" #include "esp_peripherals.h" #include "http_stream.h" #include "mp3_decoder.h" #include "i2s_stream.h" static audio_board_handle_t board_handle; static audio_pipeline_handle_t pipeline; static int current_volume = 50; void app_main(void) { // Initialize audio board board_handle = audio_board_init(); // Initialize peripherals esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize buttons audio_board_key_init(set); // Initialize LED display_service_handle_t disp = audio_board_led_init(); // Create audio pipeline audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); pipeline = audio_pipeline_init(&pipeline_cfg); // Create HTTP stream reader http_stream_cfg_t http_cfg = HTTP_STREAM_CFG_DEFAULT(); audio_element_handle_t http_stream = http_stream_init(&http_cfg); // Create MP3 decoder mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG(); audio_element_handle_t mp3_decoder = mp3_decoder_init(&mp3_cfg); // Create I2S stream writer i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); i2s_cfg.type = AUDIO_STREAM_WRITER; audio_element_handle_t i2s_stream = i2s_stream_init(&i2s_cfg); // Register and link pipeline elements audio_pipeline_register(pipeline, http_stream, "http"); audio_pipeline_register(pipeline, mp3_decoder, "mp3"); audio_pipeline_register(pipeline, i2s_stream, "i2s"); audio_pipeline_link(pipeline, (const char *[]){"http", "mp3", "i2s"}, 3); // Set stream URL audio_element_set_uri(http_stream, "http://example.com/music.mp3"); // Start playback audio_pipeline_run(pipeline); display_service_set_pattern(disp, DISPLAY_PATTERN_WIFI_CONNECTED, 0); // Event loop for button handling audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg); audio_pipeline_set_listener(pipeline, evt); esp_periph_set_register_callback(set, NULL, NULL); while (1) { audio_event_iface_msg_t msg; if (audio_event_iface_listen(evt, &msg, portMAX_DELAY) == ESP_OK) { if (msg.source_type == PERIPH_ID_BUTTON) { if ((int)msg.data == get_input_play_id()) { // Toggle play/pause audio_pipeline_pause(pipeline); } else if ((int)msg.data == get_input_volup_id()) { current_volume = (current_volume < 100) ? current_volume + 10 : 100; audio_hal_set_volume(board_handle->audio_hal, current_volume); } else if ((int)msg.data == get_input_voldown_id()) { current_volume = (current_volume > 0) ? current_volume - 10 : 0; audio_hal_set_volume(board_handle->audio_hal, current_volume); } } } } } ``` -------------------------------- ### Configure Component Requirements and Sources (CMake) Source: https://github.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/blob/main/components/ai-thinker-esp32-a1s/CMakeLists.txt Sets the required components and source files for the ESP32-A1S AI Thinker component. It conditionally adds include directories and source files based on the CONFIG_AUDIO_BOARD_CUSTOM setting. ```cmake set(COMPONENT_REQUIRES) set(COMPONENT_PRIV_REQUIRES audio_sal audio_hal esp_dispatcher esp_peripherals display_service) if(CONFIG_AUDIO_BOARD_CUSTOM) message(STATUS "Current board name is " CONFIG_AUDIO_BOARD_CUSTOM) list(APPEND COMPONENT_ADD_INCLUDEDIRS ./ai_thinker_esp32_a1s) set(COMPONENT_SRCS ./ai_thinker_esp32_a1s/board.c ./ai_thinker_esp32_a1s/board_pins_config.c ) endif() register_component() ``` -------------------------------- ### Initialize AI Thinker ESP32 A1S Audio Board (C) Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Initializes the AI Thinker ESP32 A1S audio board, returning a handle for audio operations. This function allocates memory, initializes the ES8388 audio codec, and optionally configures ADC for button input. It's the primary entry point for using the audio board. ```c #include "board.h" void app_main(void) { // Initialize the audio board audio_board_handle_t board_handle = audio_board_init(); if (board_handle == NULL) { ESP_LOGE("APP", "Failed to initialize audio board"); return; } // Board is ready for audio operations ESP_LOGI("APP", "Audio board initialized successfully"); // Access the audio HAL through the board handle audio_hal_handle_t hal = board_handle->audio_hal; // Set volume (0-100) audio_hal_set_volume(hal, 70); } ``` -------------------------------- ### Set Component Library Properties based on IDF Version (CMake) Source: https://github.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/blob/main/components/ai-thinker-esp32-a1s/CMakeLists.txt Configures the component's library properties, specifically interface include directories, based on the major version of the ESP-IDF. This ensures compatibility with different IDF releases. ```cmake IF (IDF_VERSION_MAJOR GREATER 3) idf_component_get_property(audio_board_lib audio_board COMPONENT_LIB) set_property(TARGET ${audio_board_lib} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${COMPONENT_LIB}) ELSEIF (IDF_VERSION_MAJOR EQUAL 3) set_property(TARGET idf_component_audio_board APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $) ENDIF (IDF_VERSION_MAJOR GREATER 3) ``` -------------------------------- ### Initialize Buttons for AI Thinker ESP32 A1S Audio Board (C) Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Initializes the six programmable buttons (Mode, Rec, Play, Set, Volume Up, Volume Down) on the AI Thinker ESP32 A1S audio board. It supports both GPIO and ADC-based input depending on hardware configuration and sets up an event listener for button presses. ```c #include "board.h" #include "esp_peripherals.h" #include "periph_button.h" void setup_buttons(void) { // Create peripheral set esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize buttons esp_err_t ret = audio_board_key_init(set); if (ret != ESP_OK) { ESP_LOGE("KEYS", "Button initialization failed"); return; } // Set up event listener for button presses 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_periph_set_register_callback(set, periph_event_callback, NULL); ESP_LOGI("KEYS", "Buttons initialized - KEY1:Mode, KEY2:Rec, KEY3:Play, KEY4:Set, KEY5:VolDown, KEY6:VolUp"); } // Button event callback esp_err_t periph_event_callback(audio_event_iface_msg_t *event, void *context) { switch ((int)event->data) { case get_input_play_id(): ESP_LOGI("KEY", "Play button pressed"); break; case get_input_volup_id(): ESP_LOGI("KEY", "Volume up pressed"); break; case get_input_voldown_id(): ESP_LOGI("KEY", "Volume down pressed"); break; case get_input_mode_id(): ESP_LOGI("KEY", "Mode button pressed"); break; } return ESP_OK; } ``` -------------------------------- ### Initialize On-Board LED Indicator (C) Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Initializes the on-board green LED indicator using the ESP-ADF display service. It returns a display service handle that can be used to control the LED's patterns, such as turning it on, off, or blinking it to indicate connection status. Requires the 'display_service.h' header. ```c #include "board.h" #include "display_service.h" void setup_led(void) { // Initialize LED display service display_service_handle_t disp = audio_board_led_init(); if (disp == NULL) { ESP_LOGE("LED", "LED initialization failed"); return; } // Control LED using display service patterns // Turn on LED (pattern depends on led_indicator implementation) display_service_set_pattern(disp, DISPLAY_PATTERN_WIFI_CONNECTED, 0); // Blink LED for connecting state display_service_set_pattern(disp, DISPLAY_PATTERN_WIFI_CONNECTING, 0); // Turn off LED display_service_set_pattern(disp, DISPLAY_PATTERN_TURN_OFF, 0); } ``` -------------------------------- ### Initialize ES8388 Audio Codec for AI Thinker ESP32 A1S (C) Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Initializes the ES8388 audio codec directly with default settings for playback. It configures ADC input, DAC output, sample rate, and bit depth. This function returns an audio HAL handle for direct codec control, typically called by `audio_board_init`. ```c #include "board.h" #include "audio_hal.h" void setup_audio_codec(void) { // Initialize codec directly (usually called by audio_board_init) audio_hal_handle_t codec_hal = audio_board_codec_init(); if (codec_hal == NULL) { ESP_LOGE("CODEC", "Codec initialization failed"); return; } // Configure codec for playback audio_hal_ctrl_codec(codec_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START); // Set initial volume audio_hal_set_volume(codec_hal, 50); // For recording, use: // audio_hal_ctrl_codec(codec_hal, AUDIO_HAL_CODEC_MODE_ENCODE, AUDIO_HAL_CTRL_START); } ``` -------------------------------- ### Retrieve I2C and I2S Pin Configurations (C) Source: https://context7.com/trombik/esp-adf-component-ai-thinker-esp32-a1s/llms.txt Retrieves the I2C and I2S pin configurations specific to the selected board variant. These functions populate the respective pin configuration structures, enabling communication with codecs like ES8388. Requires 'board.h', 'driver/i2c.h', and 'driver/i2s.h'. ```c #include "board.h" #include "driver/i2c.h" #include "driver/i2s.h" void get_board_pins(void) { // Get I2C pins for codec communication i2c_config_t i2c_cfg = { .mode = I2C_MODE_MASTER, .master.clk_speed = 100000, }; esp_err_t ret = get_i2c_pins(I2C_NUM_0, &i2c_cfg); if (ret == ESP_OK) { // Variant 5: SDA=GPIO33, SCL=GPIO32 // Variant 7: SDA=GPIO18, SCL=GPIO23 ESP_LOGI("PINS", "I2C SDA: %d, SCL: %d", i2c_cfg.sda_io_num, i2c_cfg.scl_io_num); } // Get I2S pins for audio data board_i2s_pin_t i2s_pins; ret = get_i2s_pins(0, &i2s_pins); if (ret == ESP_OK) { ESP_LOGI("PINS", "I2S MCK: %d, BCK: %d, WS: %d, DOUT: %d, DIN: %d", i2s_pins.mck_io_num, // GPIO 0 i2s_pins.bck_io_num, // Variant 5: GPIO27, Variant 7: GPIO5 i2s_pins.ws_io_num, // GPIO 25 i2s_pins.data_out_num, // GPIO 26 i2s_pins.data_in_num); // GPIO 35 } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.