From ffc13174cae03b7d64f260efdf2a03dc3afd89b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20Ali=C3=A9?= Date: Sat, 4 Nov 2023 08:17:53 +0100 Subject: [PATCH] Added support for MAX98357 (#46) * Added support for MAX98357 * Delete unused macro * Update readme * Update kconfig default settings --- README.md | 7 +- components/custom_board/CMakeLists.txt | 5 ++ components/custom_board/Kconfig.projbuild | 28 ++++++- components/custom_board/component.mk | 5 ++ components/custom_board/generic_board/board.c | 7 +- .../custom_board/max98357/include/max98357.h | 49 ++++++++++++ components/custom_board/max98357/max98357.c | 79 +++++++++++++++++++ 7 files changed, 172 insertions(+), 8 deletions(-) create mode 100644 components/custom_board/max98357/include/max98357.h create mode 100644 components/custom_board/max98357/max98357.c diff --git a/README.md b/README.md index 3d7967c..33eca9a 100644 --- a/README.md +++ b/README.md @@ -139,14 +139,15 @@ Configure to match your setup - ESP32-S2 Kaluga (1.2) - Or a custom board - Custom Audio Board : Configure your DAC and GPIO - - DAC Chip : + - DAC Chip : - TI PCM51XX/TAS57XX DAC (PCM51XX are stereo DAC in TSSOP package and TAS57XX are class-D amp in HTSSOP package. Both have i2s input and i2c control) - - TI PCM5102A DAC (Very basic stereo DAC WITHOUT i2c control. Use this option if you only want i2s out like for a MAX98357) + - TI PCM5102A DAC (Very basic stereo DAC WITHOUT i2c control) - Infineon MA120X0 (High power class-D amp in QFN package) - Analog Devices ADAU1961 (Stereo DAC with multiple analog inputs in LFCSP package) + - Analog Devices MAX98357 (Very popular basic mono AMP without i2c control) - DAC I2C control interface : Choose GPIO pin of your I2C line and address of the DAC. If your DAC doesn't support I2C (PCM5102A or equivalent), put unused GPIO values. - I2C master interface : GPIO pin of your DAC I2S bus. - - DAC interface configuration : Configure specific GPIO for your DAC functionnalities. If you use a MAX98357 with PCM5102A config, don't connect the SD pin to master mute. (PCM5102A logic is inverted) + - DAC interface configuration : Configure specific GPIO for your DAC functionnalities. Use `?` to have more info. - ESP32 DSP processor config : - DSP flow : Choose between Stereo, Bassboost, Bi-amp or Bass/Treble EQ. You can further configure it on the ESP web interface/ - Use asm version of Biquad_f32 : Optimized version of the DSP algorithm only for ESP32. Don't work on ESP32-S2 diff --git a/components/custom_board/CMakeLists.txt b/components/custom_board/CMakeLists.txt index 5420353..3ff4ee5 100644 --- a/components/custom_board/CMakeLists.txt +++ b/components/custom_board/CMakeLists.txt @@ -40,6 +40,11 @@ if(CONFIG_AUDIO_BOARD_CUSTOM) list(APPEND COMPONENT_SRCS ./ma120/ma120.c) endif() + if(CONFIG_DAC_MAX98357) + message(STATUS "Selected DAC is " CONFIG_DAC_MAX98357) + list(APPEND COMPONENT_ADD_INCLUDEDIRS ./max98357/include) + list(APPEND COMPONENT_SRCS ./max98357/max98357.c) + endif() endif() register_component() diff --git a/components/custom_board/Kconfig.projbuild b/components/custom_board/Kconfig.projbuild index 7080b9b..b8c3e4a 100644 --- a/components/custom_board/Kconfig.projbuild +++ b/components/custom_board/Kconfig.projbuild @@ -22,25 +22,28 @@ menu "Custom Audio Board" config DAC_ADAU1961 bool "Analog Devices ADAU1961 DAC" + config DAC_MAX98357 + bool "Analog Devices MAX98357 DAC" + endchoice menu "DAC I2C control interface" config DAC_I2C_SDA int "SDA pin" default 12 if DAC_ADAU1961 - default 21 if DAC_MA120 || DAC_PCM51XX || DAC_MA120 || DAC_MA120X0 + default 21 if DAC_MA120 || DAC_PCM51XX || DAC_MA120 || DAC_MA120X0 || DAC_MAX98357 || DAC_PCM5102A help I2C SDA pin of the DAC control interface config DAC_I2C_SCL int "SCL pin" default 14 if DAC_ADAU1961 - default 22 if DAC_MA120 || DAC_PCM51XX || DAC_MA120 || DAC_MA120X0 + default 22 if DAC_MA120 || DAC_PCM51XX || DAC_MA120 || DAC_MA120X0 || DAC_MAX98357 || DAC_PCM5102A help I2C SCL pin of the DAC control interface config DAC_I2C_ADDR hex "I2C address" default 0x70 if DAC_ADAU1961 - default 0x20 if DAC_MA120 || DAC_PCM51XX || DAC_MA120 || DAC_MA120X0 + default 0x20 if DAC_MA120 || DAC_PCM51XX || DAC_MA120 || DAC_MA120X0 || DAC_MAX98357 || DAC_PCM5102A help I2C Address of the DAC control interface endmenu @@ -54,18 +57,21 @@ menu "Custom Audio Board" config MASTER_I2S_BCK_PIN int "Master i2s bck" + default 23 if DAC_MAX98357 default 23 help Master audio interface bit clock. config MASTER_I2S_LRCK_PIN int "Master i2s lrck" + default 24 if DAC_MAX98357 default 13 help Master audio interface left/right sync clock. config MASTER_I2S_DATAOUT_PIN int "Master i2s data out" + default 25 if DAC_MAX98357 default 14 help Master audio interface data out. @@ -158,4 +164,20 @@ menu "Custom Audio Board" This is labeled "X(S)MT" on chip/boards endmenu + menu "MAX98357 interface Configuration" + depends on DAC_MAX98357 + + config MAX98357_MUTE_PIN + int "Master mute/mode for MAX98357" + default 18 + help + GPIO number to control mute/mode. This require a special resistor to select the correct mode. + You need to put a serie resistor to select the mode (GPIO --> Resistor --> SD): + LEFT only : 0ohm (direct connection) + RIGHT only : 220Kohm + (L+R)/2 : 1Mohm + Refer to Analog Devices' doc for more infos. + This is labeled "SD" on chip/boards. + endmenu + endmenu diff --git a/components/custom_board/component.mk b/components/custom_board/component.mk index e5fbe4d..3bebfc2 100644 --- a/components/custom_board/component.mk +++ b/components/custom_board/component.mk @@ -22,4 +22,9 @@ COMPONENT_ADD_INCLUDEDIRS += ./ma120x0/include COMPONENT_SRCDIRS += ./ma120x0 endif +ifdef CONFIG_DAC_MAX98357 +COMPONENT_ADD_INCLUDEDIRS += ./max98357/include +COMPONENT_SRCDIRS += ./max98357 +endif + endif diff --git a/components/custom_board/generic_board/board.c b/components/custom_board/generic_board/board.c index 11b0066..3b50a43 100644 --- a/components/custom_board/generic_board/board.c +++ b/components/custom_board/generic_board/board.c @@ -28,8 +28,8 @@ #include "audio_mem.h" #include "esp_log.h" -//#include "periph_adc_button.h" -//#include "periph_sdcard.h" +// #include "periph_adc_button.h" +// #include "periph_sdcard.h" #if CONFIG_DAC_PCM51XX extern audio_hal_func_t AUDIO_CODEC_PCM51XX_DEFAULT_HANDLE; @@ -46,6 +46,9 @@ extern audio_hal_func_t AUDIO_CODEC_MA120_DEFAULT_HANDLE; #elif CONFIG_DAC_ADAU1961 extern audio_hal_func_t AUDIO_CODEC_ADAU1961_DEFAULT_HANDLE; #define AUDIO_CODEC_DEFAULT_HANDLE AUDIO_CODEC_ADAU1961_DEFAULT_HANDLE +#elif CONFIG_DAC_MAX98357 +extern audio_hal_func_t AUDIO_CODEC_MAX98357_DEFAULT_HANDLE; +#define AUDIO_CODEC_DEFAULT_HANDLE AUDIO_CODEC_MAX98357_DEFAULT_HANDLE #endif static const char *TAG = "AUDIO_BOARD"; diff --git a/components/custom_board/max98357/include/max98357.h b/components/custom_board/max98357/include/max98357.h new file mode 100644 index 0000000..48ca804 --- /dev/null +++ b/components/custom_board/max98357/include/max98357.h @@ -0,0 +1,49 @@ +/* + * Analog Devices MAX98357 audio hal + */ + +#ifndef _MAX98357_H_ +#define _MAX98357_H_ + +#include "audio_hal.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialize MAX98357 codec chip + */ +esp_err_t max98357_init(audio_hal_codec_config_t *codec_cfg); + +/** + * Deinitialize MAX98357 codec chip + */ +esp_err_t max98357_deinit(void); + +/** + * Set volume - NOT AVAILABLE + */ +esp_err_t max98357_set_volume(int vol); + +/** + * Get volume - NOT AVAILABLE + */ +esp_err_t max98357_get_volume(int *value); + +/** + * Set MAX98357 mute or not + */ +esp_err_t max98357_set_mute(bool enable); + +/** + * Get MAX98357 mute status - NOT IMPLEMENTED + */ +esp_err_t max98357_get_mute(bool *enabled); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/custom_board/max98357/max98357.c b/components/custom_board/max98357/max98357.c new file mode 100644 index 0000000..8cd16b2 --- /dev/null +++ b/components/custom_board/max98357/max98357.c @@ -0,0 +1,79 @@ +/* + * Analog Devices MAX98357 audio hal + * + * Mostly stubs (no I2C or volume control) + * Configuration of mute/unmute gpio in init (connected to XSMT) + */ + +#include "max98357.h" + +#include + +#include "board.h" +#include "esp_log.h" + +static const char *TAG = "MAX98357"; + +esp_err_t max98357_ctrl(audio_hal_codec_mode_t mode, + audio_hal_ctrl_t ctrl_state); +esp_err_t max98357_config_iface(audio_hal_codec_mode_t mode, + audio_hal_codec_i2s_iface_t *iface); + +audio_hal_func_t AUDIO_CODEC_MAX98357_DEFAULT_HANDLE = { + .audio_codec_initialize = max98357_init, + .audio_codec_deinitialize = max98357_deinit, + .audio_codec_ctrl = max98357_ctrl, + .audio_codec_config_iface = max98357_config_iface, + .audio_codec_set_mute = max98357_set_mute, + .audio_codec_set_volume = max98357_set_volume, + .audio_codec_get_volume = max98357_get_volume, + .audio_hal_lock = NULL, + .handle = NULL, +}; + +esp_err_t max98357_init(audio_hal_codec_config_t *codec_cfg) { + esp_err_t ret; + + gpio_config_t io_conf; + + io_conf.intr_type = GPIO_PIN_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = (1ULL << CONFIG_MAX98357_MUTE_PIN); + io_conf.pull_down_en = 0; + io_conf.pull_up_en = 0; + + ret = gpio_config(&io_conf); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Mute gpio config failed for pin %d", + CONFIG_MAX98357_MUTE_PIN); + } else { + gpio_set_level(CONFIG_MAX98357_MUTE_PIN, 0); + ESP_LOGD(TAG, "Setup mute (SD) output %d\n", CONFIG_MAX98357_MUTE_PIN); + } + + return ret; +} + +esp_err_t max98357_set_volume(int vol) { return ESP_OK; } + +esp_err_t max98357_get_volume(int *value) { return ESP_OK; } + +esp_err_t max98357_set_mute(bool enable) { + return gpio_set_level(CONFIG_MAX98357_MUTE_PIN, enable ? 0 : 1); +} + +esp_err_t max98357_get_mute(bool *enabled) { return ESP_OK; } + +esp_err_t max98357_deinit(void) { + return gpio_reset_pin(CONFIG_MAX98357_MUTE_PIN); +} + +esp_err_t max98357_ctrl(audio_hal_codec_mode_t mode, + audio_hal_ctrl_t ctrl_state) { + return ESP_OK; +} + +esp_err_t max98357_config_iface(audio_hal_codec_mode_t mode, + audio_hal_codec_i2s_iface_t *iface) { + return ESP_OK; +}