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;
+}