From d80ba93b68ed3f12b108147851137bd88a350173 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 11 Jul 2022 09:08:06 +0200 Subject: [PATCH 1/4] audio i2s refactor --- .../xdrv_42_1_i2s_audio.ino | 69 ++- .../tasmota_xdrv_driver/xdrv_42_i2s_audio.ino | 518 ++++++++++-------- 2 files changed, 347 insertions(+), 240 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_1_i2s_audio.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_1_i2s_audio.ino index c48c342c6..b772fbc4d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_42_1_i2s_audio.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_42_1_i2s_audio.ino @@ -3,13 +3,16 @@ #ifdef ESP32S3_BOX #include #include +#include #include +#include void S3boxAudioPower(uint8_t pwr) { pinMode(46 , OUTPUT); digitalWrite(46, pwr); } +// box lite dac init uint32_t ES8156_init() { uint32_t ret_val = ESP_OK; @@ -27,29 +30,87 @@ uint32_t ES8156_init() { return ret_val; } +// box lite adc init uint32_t es7243e_init() { uint32_t ret_val = ESP_OK; if (I2cSetDevice(ES7243_ADDR, 1)) { I2cSetActiveFound(ES7243_ADDR, "ES7243e-I2C", 1); - } - audio_hal_codec_config_t cfg = { + audio_hal_codec_config_t cfg = { .i2s_iface = { .mode = AUDIO_HAL_MODE_SLAVE, .bits = AUDIO_HAL_BIT_LENGTH_16BITS, } - }; + }; - ret_val |= es8156_codec_init(&Wire1, &cfg); + ret_val |= es7243e_adc_init(&Wire1, &cfg); + } return ret_val; } +// box adc init +uint32_t es7210_init() { + uint32_t ret_val = ESP_OK; + + if (I2cSetDevice(ES7210_ADDR, 1)) { + I2cSetActiveFound(ES7210_ADDR, "ES7210-I2C", 1); + audio_hal_codec_config_t cfg = { + .adc_input = AUDIO_HAL_ADC_INPUT_ALL, + .codec_mode = AUDIO_HAL_CODEC_MODE_ENCODE, + .i2s_iface = { + .mode = AUDIO_HAL_MODE_SLAVE, + .fmt = AUDIO_HAL_I2S_NORMAL, + .samples = AUDIO_HAL_16K_SAMPLES, + .bits = AUDIO_HAL_BIT_LENGTH_16BITS, + }, + }; + + ret_val |= es7210_adc_init(&Wire1, &cfg); + ret_val |= es7210_adc_config_i2s(cfg.codec_mode, &cfg.i2s_iface); + ret_val |= es7210_adc_set_gain((es7210_input_mics_t)(ES7210_INPUT_MIC1 | ES7210_INPUT_MIC2), (es7210_gain_value_t) GAIN_37_5DB); + ret_val |= es7210_adc_set_gain((es7210_input_mics_t)(ES7210_INPUT_MIC3 | ES7210_INPUT_MIC4), (es7210_gain_value_t) GAIN_0DB); + ret_val |= es7210_adc_ctrl_state(cfg.codec_mode, AUDIO_HAL_CTRL_START); + } + return ret_val; +} + +// box dac init +uint32_t ES8311_init() { + uint32_t ret_val = ESP_OK; + + if (I2cSetDevice(ES8311_ADDR, 1)) { + I2cSetActiveFound(ES8311_ADDR, "ES8311-I2C", 1); + audio_hal_codec_config_t cfg = { + .dac_output = AUDIO_HAL_DAC_OUTPUT_LINE1, + .codec_mode = AUDIO_HAL_CODEC_MODE_DECODE, + .i2s_iface = { + .mode = AUDIO_HAL_MODE_SLAVE, + .fmt = AUDIO_HAL_I2S_NORMAL, + .samples = AUDIO_HAL_16K_SAMPLES, + .bits = AUDIO_HAL_BIT_LENGTH_16BITS, + }, + }; + + ret_val |= es8311_codec_init(&Wire1, &cfg); + ret_val |= es8311_set_bits_per_sample(cfg.i2s_iface.bits); + ret_val |= es8311_config_fmt((es_i2s_fmt_t)cfg.i2s_iface.fmt); + ret_val |= es8311_codec_set_voice_volume(75); + ret_val |= es8311_codec_ctrl_state(cfg.codec_mode, AUDIO_HAL_CTRL_START); + + } + return ret_val; +} + void S3boxInit() { if (TasmotaGlobal.i2c_enabled_2) { + // box lite ES8156_init(); es7243e_init(); + // box full + ES8311_init(); + es7210_init(); } } #endif diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_i2s_audio.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_i2s_audio.ino index bd155f9b1..370b68187 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_42_i2s_audio.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_42_i2s_audio.ino @@ -63,6 +63,50 @@ #define AUDIO_PWR_ON #define AUDIO_PWR_OFF +#ifdef ESP8266 +#define i2s_port_t uint8_t +#endif + +struct AUDIO_I2S { + uint8_t is2_volume; // should be in settings + i2s_port_t i2s_port; + int8_t mclk = -1; + int8_t bclk = -1; + int8_t ws = -1; + int8_t dout = -1; + int8_t din = -1; + AudioGeneratorMP3 *mp3 = nullptr; + AudioFileSourceFS *file; +#ifdef USE_I2S_NO_DAC + AudioOutputI2SNoDAC *out; +#else + AudioOutputI2S *out; +#endif // USE_I2S_NO_DAC + AudioFileSourceID3 *id3; + AudioGeneratorMP3 *decoder = NULL; + void *mp3ram = NULL; +#ifdef USE_I2S_WEBRADIO + AudioFileSourceICYStream *ifile = NULL; + AudioFileSourceBuffer *buff = NULL; + char wr_title[64]; + void *preallocateBuffer = NULL; + void *preallocateCodec = NULL; + uint32_t retryms = 0; +#endif // USE_I2S_WEBRADIO + +#ifdef ESP32 + TaskHandle_t mp3_task_h; + TaskHandle_t mic_task_h; + uint32_t mic_size; + uint8_t *mic_buff; + char mic_path[32]; +#endif + +} audio_i2s; + + +#define MIC_CHANNELS 1 + #ifdef USE_TTGO_WATCH #undef AUDIO_PWR_ON #undef AUDIO_PWR_OFF @@ -71,6 +115,7 @@ #endif // USE_TTGO_WATCH #ifdef USE_M5STACK_CORE2 +// leave this predefined currently #undef AUDIO_PWR_ON #undef AUDIO_PWR_OFF #define AUDIO_PWR_ON Core2AudioPower(true); @@ -89,29 +134,10 @@ #undef AUDIO_PWR_OFF #define AUDIO_PWR_ON S3boxAudioPower(true); #define AUDIO_PWR_OFF S3boxAudioPower(false); - -#undef DAC_IIS_BCK -#undef DAC_IIS_WS -#undef DAC_IIS_DOUT -#define DAC_IIS_BCK 17 -#define DAC_IIS_WS 47 -#define DAC_IIS_DOUT 15 -#define DAC_IIS_DIN 16 -#define DAC_IIS_MCLK 2 - +#undef MIC_CHANNELS +#define MIC_CHANNELS 2 #endif // ESP32S3_BOX -AudioGeneratorMP3 *mp3 = nullptr; -AudioFileSourceFS *file; -#ifdef USE_I2S_NO_DAC - AudioOutputI2SNoDAC *out; -#else - AudioOutputI2S *out; -#endif // USE_I2S_NO_DAC -AudioFileSourceID3 *id3; -AudioGeneratorMP3 *decoder = NULL; -void *mp3ram = NULL; - extern FS *ufsp; #ifdef ESP8266 @@ -124,54 +150,6 @@ const int preallocateCodecSize = 29192; // MP3 codec max mem needed //const int preallocateCodecSize = 85332; // AAC+SBR codec max mem needed #endif // ESP32 -#ifdef USE_I2S_WEBRADIO -AudioFileSourceICYStream *ifile = NULL; -AudioFileSourceBuffer *buff = NULL; -char wr_title[64]; -//char status[64]; - -void *preallocateBuffer = NULL; -void *preallocateCodec = NULL; -uint32_t retryms = 0; -#endif // USE_I2S_WEBRADIO - -#ifdef USE_I2S_SAY_TIME -AudioGeneratorTalkie *talkie = nullptr; -#endif // USE_I2S_SAY_TIME - -//! MAX98357A + INMP441 DOUBLE I2S BOARD -#ifdef ESP8266 -#undef DAC_IIS_BCK -#undef DAC_IIS_WS -#undef DAC_IIS_DOUT -#define DAC_IIS_BCK 15 -#define DAC_IIS_WS 2 -#define DAC_IIS_DOUT 3 -#endif // ESP8266 - -// defaults to TTGO WATCH -#ifdef ESP32 -#ifndef DAC_IIS_BCK -#undef DAC_IIS_BCK -#define DAC_IIS_BCK 26 -#endif // DAC_IIS_BCK - -#ifndef DAC_IIS_WS -#undef DAC_IIS_WS -#define DAC_IIS_WS 25 -#endif // DAC_IIS_WS - -#ifndef DAC_IIS_DOUT -#undef DAC_IIS_DOUT -#define DAC_IIS_DOUT 33 -#endif // DAC_IIS_DOUT - -#ifndef DAC_IIS_DIN -#undef DAC_IIS_DIN -#define DAC_IIS_DIN 34 -#endif // DAC_IIS_DIN - -#endif // ESP32 #ifdef USE_I2S_SAY_TIME long timezone = 2; @@ -213,15 +191,16 @@ uint8_t spAFTERNOON[] PROGMEM = {0xC7,0xCE,0xCE,0x3A,0xCB,0x58,0x1F,0x3B,0x07,0x uint8_t spEVENING[] PROGMEM = {0xCD,0x6D,0x98,0x73,0x47,0x65,0x0D,0x6D,0x10,0xB2,0x5D,0x93,0x35,0x94,0xC1,0xD0,0x76,0x4D,0x66,0x93,0xA7,0x04,0xBD,0x71,0xD9,0x45,0xAE,0x92,0xD5,0xAC,0x53,0x07,0x6D,0xA5,0x76,0x63,0x51,0x92,0xD4,0xA1,0x83,0xD4,0xCB,0xB2,0x51,0x88,0xCD,0xF5,0x50,0x45,0xCE,0xA2,0x2E,0x27,0x28,0x54,0x15,0x37,0x0A,0xCF,0x75,0x61,0x5D,0xA2,0xC4,0xB5,0xC7,0x44,0x55,0x8A,0x0B,0xA3,0x6E,0x17,0x95,0x21,0xA9,0x0C,0x37,0xCD,0x15,0xBA,0xD4,0x2B,0x6F,0xB3,0x54,0xE4,0xD2,0xC8,0x64,0xBC,0x4C,0x91,0x49,0x12,0xE7,0xB2,0xB1,0xD0,0x22,0x0D,0x9C,0xDD,0xAB,0x62,0xA9,0x38,0x53,0x11,0xA9,0x74,0x2C,0xD2,0xCA,0x59,0x34,0xA3,0xE5,0xFF,0x03}; uint8_t spPAUSE1[] PROGMEM = {0x00,0x00,0x00,0x00,0xFF,0x0F}; -void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) ; +void sayTime(int hour, int minutes) ; -void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) { +void sayTime(int hour, int minutes) { +AudioGeneratorTalkie *talkie = nullptr; - if (!out) return; + if (!audio_i2s.out) return; AUDIO_PWR_ON talkie = new AudioGeneratorTalkie(); - talkie->begin(nullptr, out); + talkie->begin(nullptr, audio_i2s.out); bool pm = (hour >= 12); uint8_t *spHour[] = { spTWELVE, spONE, spTWO, spTHREE, spFOUR, spFIVE, spSIX, @@ -269,58 +248,113 @@ void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) { talkie->say(spA_M_, sizeof(spA_M_)); } delete talkie; - out->stop(); + audio_i2s.out->stop(); AUDIO_PWR_OFF } #endif // USE_I2S_SAY_TIME -// should be in settings -uint8_t is2_volume; + +int32_t I2S_Init_0(void) { + + audio_i2s.i2s_port = (i2s_port_t)0; + +#if USE_I2S_EXTERNAL_DAC + // use i2s +#if (defined(USE_I2S_NO_DAC) && defined(DAC_IIS_DOUT)) || (defined(DAC_IIS_BCK) && defined(DAC_IIS_WS) && defined(DAC_IIS_DOUT)) + audio_i2s.i2s_port = (i2s_port_t)0; +#ifdef USE_I2S_NO_DAC + audio_i2s.out = new AudioOutputI2SNoDAC(); +#else + audio_i2s.out = new AudioOutputI2S(); +#endif + audio_i2s.bclk = DAC_IIS_BCK; + audio_i2s.ws = DAC_IIS_WS; + audio_i2s.dout = DAC_IIS_DOUT; +#else +#ifdef USE_I2S_NO_DAC + if (PinUsed(GPIO_I2S_DOUT)) { +#else + if (PinUsed(GPIO_I2S_BCLK) && PinUsed(GPIO_I2S_WS) && PinUsed(GPIO_I2S_DOUT)) { +#endif // USE_I2S_NO_DAC + audio_i2s.i2s_port = (i2s_port_t)0; + #ifdef USE_I2S_NO_DAC + audio_i2s.out = new AudioOutputI2SNoDAC(); + #else + audio_i2s.out = new AudioOutputI2S(audio_i2s.i2s_port); + #endif // USE_I2S_NO_DAC + audio_i2s.mclk = Pin(GPIO_I2S_MCLK); + audio_i2s.bclk = Pin(GPIO_I2S_BCLK); + audio_i2s.ws = Pin(GPIO_I2S_WS); + audio_i2s.dout = Pin(GPIO_I2S_DOUT); + audio_i2s.din = Pin(GPIO_I2S_DIN); + } else if (PinUsed(GPIO_I2S_BCLK, 1) && PinUsed(GPIO_I2S_WS, 1) && PinUsed(GPIO_I2S_DOUT), 1) { + audio_i2s.i2s_port = (i2s_port_t)1; + #ifdef USE_I2S_NO_DAC + audio_i2s.out = new AudioOutputI2SNoDAC(); + #else + audio_i2s.out = new AudioOutputI2S(audio_i2s.i2s_port); + #endif // USE_I2S_NO_DAC + audio_i2s.mclk = Pin(GPIO_I2S_MCLK, 1); + audio_i2s.bclk = Pin(GPIO_I2S_BCLK, 1); + audio_i2s.ws = Pin(GPIO_I2S_WS, 1); + audio_i2s.dout = Pin(GPIO_I2S_DOUT, 1); + audio_i2s.din = Pin(GPIO_I2S_DIN, 1); + } else { + return -1; + } +#ifdef ESP8266 + // esp8266 have fixed pins + if ((audio_i2s.bclk != 15) || (audio_i2s.ws != 2) || (audio_i2s.dout!= 3)) { + return -2; + } +#endif // ESP8266 +#endif // defined(DAC_IIS_BCK) + + audio_i2s.out->SetPinout(audio_i2s.bclk, audio_i2s.ws, audio_i2s.dout, audio_i2s.mclk, audio_i2s.din); + + AddLog(LOG_LEVEL_INFO, PSTR("Init audio I2S: bclk=%d, ws=%d, dout=%d, mclk=%d, din=%d"), audio_i2s.bclk, audio_i2s.ws, audio_i2s.dout, audio_i2s.mclk, audio_i2s.din); + +#if defined(ESP32) && defined(ESP32S3_BOX) + S3boxInit(); +#endif + +#else + +#ifdef USE_I2S_NO_DAC + audio_i2s.out = new AudioOutputI2SNoDAC(); +#else + audio_i2s.out = new AudioOutputI2S(0, 1); // Internal DAC port 0 +#endif // USE_I2S_NO_DAC +#endif // USE_I2S_EXTERNAL_DAC + + return 0; +} void I2S_Init(void) { -#if USE_I2S_EXTERNAL_DAC - #ifdef USE_I2S_NO_DAC - out = new AudioOutputI2SNoDAC(); - #else - out = new AudioOutputI2S(); - #endif // USE_I2S_NO_DAC -#ifdef ESP32 -#ifdef ESP32S3_BOX - S3boxInit(); - out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT, DAC_IIS_MCLK, DAC_IIS_DIN); -#else - out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT); -#endif -#endif // ESP32 + if (I2S_Init_0()) { + return; + } -#else - #ifdef USE_I2S_NO_DAC - out = new AudioOutputI2SNoDAC(); - #else - out = new AudioOutputI2S(0, 1); // Internal DAC port 0 - #endif // USE_I2S_NO_DAC -#endif // USE_I2S_EXTERNAL_DAC - - is2_volume=10; - out->SetGain(((float)is2_volume/100.0)*4.0); - out->stop(); - mp3ram = nullptr; + audio_i2s.is2_volume=10; + audio_i2s.out->SetGain(((float)audio_i2s.is2_volume/100.0)*4.0); + audio_i2s.out->stop(); + audio_i2s.mp3ram = nullptr; #ifdef ESP32 if (UsePSRAM()) { - mp3ram = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + audio_i2s.mp3ram = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); } #ifdef USE_I2S_WEBRADIO if (UsePSRAM()) { - preallocateBuffer = heap_caps_malloc(preallocateBufferSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); - preallocateCodec = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + audio_i2s.preallocateBuffer = heap_caps_malloc(preallocateBufferSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + audio_i2s.preallocateCodec = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); } else { - preallocateBuffer = malloc(preallocateBufferSize); - preallocateCodec = malloc(preallocateCodecSize); + audio_i2s.preallocateBuffer = malloc(preallocateBufferSize); + audio_i2s.preallocateCodec = malloc(preallocateCodecSize); } - if (!preallocateBuffer || !preallocateCodec) { + if (!audio_i2s.preallocateBuffer || !audio_i2s.preallocateCodec) { //Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize); } #endif // USE_I2S_WEBRADIO @@ -331,29 +365,24 @@ void I2S_Init(void) { #ifdef ESP32 #define MODE_MIC 0 #define MODE_SPK 1 -#define Speak_I2S_NUMBER I2S_NUM_0 //#define MICSRATE 44100 #define MICSRATE 16000 uint32_t SpeakerMic(uint8_t spkr) { esp_err_t err = ESP_OK; - if (out) { - out->stop(); - delete out; - out = nullptr; + if (audio_i2s.out) { + audio_i2s.out->stop(); + delete audio_i2s.out; + audio_i2s.out = nullptr; } - i2s_driver_uninstall(Speak_I2S_NUMBER); - if (spkr==MODE_SPK) { - #ifdef USE_I2S_NO_DAC - out = new AudioOutputI2SNoDAC(); - #else - out = new AudioOutputI2S(0, 1); - #endif - out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT); - out->SetGain(((float)is2_volume/100.0)*4.0); - out->stop(); + i2s_driver_uninstall(audio_i2s.i2s_port); + + if (spkr == MODE_SPK) { + I2S_Init_0(); + audio_i2s.out->SetGain(((float)(audio_i2s.is2_volume-2)/100.0)*4.0); + audio_i2s.out->stop(); } else { // config mic i2s_config_t i2s_config = { @@ -366,48 +395,65 @@ uint32_t SpeakerMic(uint8_t spkr) { .dma_buf_count = 2, //.dma_buf_len = 128, .dma_buf_len = 1024, + .use_apll = 0, // Use audio PLL + .tx_desc_auto_clear = true, + .fixed_mclk = 0, + .mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT, + .bits_per_chan = I2S_BITS_PER_CHAN_16BIT }; + +#ifdef ESP32S3_BOX + i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; + i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX); + i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S; +#else i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM); - err += i2s_driver_install(Speak_I2S_NUMBER, &i2s_config, 0, NULL); +#endif + + err += i2s_driver_install(audio_i2s.i2s_port, &i2s_config, 0, NULL); i2s_pin_config_t tx_pin_config; - tx_pin_config.bck_io_num = DAC_IIS_BCK; - tx_pin_config.ws_io_num = DAC_IIS_WS; - tx_pin_config.data_out_num = DAC_IIS_DOUT; - tx_pin_config.data_in_num = DAC_IIS_DIN; - err += i2s_set_pin(Speak_I2S_NUMBER, &tx_pin_config); +#ifdef ESP32S3_BOX + tx_pin_config.mck_io_num = audio_i2s.mclk; +#else + tx_pin_config.mck_io_num = I2S_PIN_NO_CHANGE; +#endif + tx_pin_config.bck_io_num = audio_i2s.bclk; + tx_pin_config.ws_io_num = audio_i2s.ws; + tx_pin_config.data_out_num = audio_i2s.dout; + tx_pin_config.data_in_num = audio_i2s.din; - err += i2s_set_clk(Speak_I2S_NUMBER, MICSRATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO); + err += i2s_set_pin(audio_i2s.i2s_port, &tx_pin_config); +#ifdef ESP32S3_BOX + err += i2s_set_clk(audio_i2s.i2s_port, MICSRATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_STEREO); +#else + err += i2s_set_clk(audio_i2s.i2s_port, MICSRATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO); +#endif } return err; } #define DATA_SIZE 1024 -TaskHandle_t mic_task_h; -uint32_t mic_size; -uint8_t *mic_buff; -char mic_path[32]; - void mic_task(void *arg){ uint32_t data_offset = 0; while (1) { uint32_t bytes_read; - i2s_read(Speak_I2S_NUMBER, (char *)(mic_buff + data_offset), DATA_SIZE, &bytes_read, (100 / portTICK_RATE_MS)); + i2s_read(audio_i2s.i2s_port, (char *)(audio_i2s.mic_buff + data_offset), DATA_SIZE, &bytes_read, (100 / portTICK_RATE_MS)); if (bytes_read != DATA_SIZE) break; data_offset += DATA_SIZE; - if (data_offset >= mic_size-DATA_SIZE) break; + if (data_offset >= audio_i2s.mic_size-DATA_SIZE) break; } SpeakerMic(MODE_SPK); - SaveWav(mic_path, mic_buff, mic_size); - free(mic_buff); - vTaskDelete(mic_task_h); + SaveWav(audio_i2s.mic_path, audio_i2s.mic_buff, audio_i2s.mic_size); + free(audio_i2s.mic_buff); + vTaskDelete(audio_i2s.mic_task_h); } uint32_t i2s_record(char *path, uint32_t secs) { esp_err_t err = ESP_OK; - if (decoder || mp3) return 0; + if (audio_i2s.decoder || audio_i2s.mp3) return 0; err = SpeakerMic(MODE_MIC); if (err) { @@ -415,15 +461,15 @@ uint32_t i2s_record(char *path, uint32_t secs) { return err; } - mic_size = secs * MICSRATE * 2; + audio_i2s.mic_size = secs * MICSRATE * 2 * MIC_CHANNELS; - mic_buff = (uint8_t*)heap_caps_malloc(mic_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); - if (!mic_buff) return 2; + audio_i2s.mic_buff = (uint8_t*)heap_caps_malloc(audio_i2s.mic_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (!audio_i2s.mic_buff) return 2; if (*path=='+') { path++; - strlcpy(mic_path, path , sizeof(mic_path)); - xTaskCreatePinnedToCore(mic_task, "MIC", 4096, NULL, 3, &mic_task_h, 1); + strlcpy(audio_i2s.mic_path, path , sizeof(audio_i2s.mic_path)); + xTaskCreatePinnedToCore(mic_task, "MIC", 4096, NULL, 3, &audio_i2s.mic_task_h, 1); return 0; } @@ -431,17 +477,17 @@ uint32_t i2s_record(char *path, uint32_t secs) { uint32_t stime=millis(); while (1) { uint32_t bytes_read; - i2s_read(Speak_I2S_NUMBER, (char *)(mic_buff + data_offset), DATA_SIZE, &bytes_read, (100 / portTICK_RATE_MS)); + i2s_read(audio_i2s.i2s_port, (char *)(audio_i2s.mic_buff + data_offset), DATA_SIZE, &bytes_read, (100 / portTICK_RATE_MS)); if (bytes_read != DATA_SIZE) break; data_offset += DATA_SIZE; - if (data_offset >= mic_size-DATA_SIZE) break; + if (data_offset >= audio_i2s.mic_size-DATA_SIZE) break; delay(0); } //AddLog(LOG_LEVEL_INFO, PSTR("rectime: %d ms"), millis()-stime); SpeakerMic(MODE_SPK); // save to path - SaveWav(path, mic_buff, mic_size); - free(mic_buff); + SaveWav(path, audio_i2s.mic_buff, audio_i2s.mic_size); + free(audio_i2s.mic_buff); return 0; } @@ -456,7 +502,7 @@ bool SaveWav(char *path, uint8_t *buff, uint32_t size) { uint8_t wavHeader[sizeof(wavHTemplate)]; memcpy_P(wavHeader, wavHTemplate, sizeof(wavHTemplate)); - uint8_t channels = 1; + uint8_t channels = MIC_CHANNELS; uint32_t hertz = MICSRATE; uint8_t bps = 16; @@ -487,18 +533,17 @@ bool SaveWav(char *path, uint8_t *buff, uint32_t size) { #endif // ESP32 #ifdef ESP32 -TaskHandle_t mp3_task_h; void mp3_task(void *arg) { while (1) { - while (mp3->isRunning()) { - if (!mp3->loop()) { - mp3->stop(); + while (audio_i2s.mp3->isRunning()) { + if (!audio_i2s.mp3->loop()) { + audio_i2s.mp3->stop(); mp3_delete(); - out->stop(); - if (mp3_task_h) { - vTaskDelete(mp3_task_h); - mp3_task_h = 0; + audio_i2s.out->stop(); + if (audio_i2s.mp3_task_h) { + vTaskDelete(audio_i2s.mp3_task_h); + audio_i2s.mp3_task_h = 0; } //mp3_task_h=nullptr; } @@ -514,8 +559,8 @@ void MDCallback(void *cbData, const char *type, bool isUnicode, const char *str) (void) isUnicode; // Punt this ball for now (void) ptr; if (strstr_P(type, PSTR("Title"))) { - strncpy(wr_title, str, sizeof(wr_title)); - wr_title[sizeof(wr_title)-1] = 0; + strncpy(audio_i2s.wr_title, str, sizeof(audio_i2s.wr_title)); + audio_i2s.wr_title[sizeof(audio_i2s.wr_title)-1] = 0; //AddLog(LOG_LEVEL_INFO,PSTR("WR-Title: %s"),wr_title); } else { // Who knows what to do? Not me! @@ -531,30 +576,30 @@ void StatusCallback(void *cbData, int code, const char *string) { } void Webradio(const char *url) { - if (decoder || mp3) return; - if (!out) return; + if (audio_i2s.decoder || audio_i2s.mp3) return; + if (!audio_i2s.out) return; AUDIO_PWR_ON - ifile = new AudioFileSourceICYStream(url); - ifile->RegisterMetadataCB(MDCallback, NULL); - buff = new AudioFileSourceBuffer(ifile, preallocateBuffer, preallocateBufferSize); - buff->RegisterStatusCB(StatusCallback, NULL); - decoder = new AudioGeneratorMP3(preallocateCodec, preallocateCodecSize); - decoder->RegisterStatusCB(StatusCallback, NULL); - decoder->begin(buff, out); - if (!decoder->isRunning()) { + audio_i2s.ifile = new AudioFileSourceICYStream(url); + audio_i2s.ifile->RegisterMetadataCB(MDCallback, NULL); + audio_i2s.buff = new AudioFileSourceBuffer(audio_i2s.ifile, audio_i2s.preallocateBuffer, preallocateBufferSize); + audio_i2s.buff->RegisterStatusCB(StatusCallback, NULL); + audio_i2s.decoder = new AudioGeneratorMP3(audio_i2s.preallocateCodec, preallocateCodecSize); + audio_i2s.decoder->RegisterStatusCB(StatusCallback, NULL); + audio_i2s.decoder->begin(audio_i2s.buff, audio_i2s.out); + if (!audio_i2s.decoder->isRunning()) { // Serial.printf_P(PSTR("Can't connect to URL")); StopPlaying(); // strcpy_P(status, PSTR("Unable to connect to URL")); - retryms = millis() + 2000; + audio_i2s.retryms = millis() + 2000; } - xTaskCreatePinnedToCore(mp3_task2, "MP3-2", 8192, NULL, 3, &mp3_task_h, 1); + xTaskCreatePinnedToCore(mp3_task2, "MP3-2", 8192, NULL, 3, &audio_i2s.mp3_task_h, 1); } void mp3_task2(void *arg){ while (1) { - if (decoder && decoder->isRunning()) { - if (!decoder->loop()) { + if (audio_i2s.decoder && audio_i2s.decoder->isRunning()) { + if (!audio_i2s.decoder->loop()) { StopPlaying(); //retryms = millis() + 2000; } @@ -565,31 +610,33 @@ void mp3_task2(void *arg){ void StopPlaying() { - if (mp3_task_h) { - vTaskDelete(mp3_task_h); - mp3_task_h = nullptr; + if (audio_i2s.mp3_task_h) { + vTaskDelete(audio_i2s.mp3_task_h); + audio_i2s.mp3_task_h = nullptr; } - if (decoder) { - decoder->stop(); - delete decoder; - decoder = NULL; + if (audio_i2s.decoder) { + audio_i2s.decoder->stop(); + delete audio_i2s.decoder; + audio_i2s.decoder = NULL; } - if (buff) { - buff->close(); - delete buff; - buff = NULL; + + if (audio_i2s.buff) { + audio_i2s.buff->close(); + delete audio_i2s.buff; + audio_i2s.buff = NULL; } - if (ifile) { - ifile->close(); - delete ifile; - ifile = NULL; + + if (audio_i2s.ifile) { + audio_i2s.ifile->close(); + delete audio_i2s.ifile; + audio_i2s.ifile = NULL; } AUDIO_PWR_OFF } void Cmd_WebRadio(void) { - if (decoder) { + if (audio_i2s.decoder) { StopPlaying(); } if (XdrvMailbox.data_len > 0) { @@ -598,10 +645,22 @@ void Cmd_WebRadio(void) { } else { ResponseCmndChar_P(PSTR("Stopped")); } - } -#ifdef USE_M5STACK_CORE2 +#ifdef USE_WEBSERVER +const char HTTP_WEBRADIO[] PROGMEM = + "{s}" "I2S_WR-Title" "{m}%s{e}"; + +void I2S_WR_Show(void) { + if (audio_i2s.decoder) { + WSContentSend_PD(HTTP_WEBRADIO,audio_i2s.wr_title); + } +} +#endif // USE_WEBSERVER + +#endif // USE_I2S_WEBRADIO + +#if defined(USE_M5STACK_CORE2) || defined(ESP32S3_BOX) void Cmd_MicRec(void) { if (XdrvMailbox.data_len > 0) { uint16 time = 10; @@ -618,24 +677,11 @@ void Cmd_MicRec(void) { } #endif // USE_M5STACK_CORE2 -#ifdef USE_WEBSERVER -const char HTTP_WEBRADIO[] PROGMEM = - "{s}" "I2S_WR-Title" "{m}%s{e}"; - -void I2S_WR_Show(void) { - if (decoder) { - WSContentSend_PD(HTTP_WEBRADIO,wr_title); - } -} -#endif // USE_WEBSERVER - -#endif // USE_I2S_WEBRADIO - #ifdef ESP32 void Play_mp3(const char *path) { -#if (defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)) || defined(USE_UFILESYS) - if (decoder || mp3) return; - if (!out) return; +#ifdef USE_UFILESYS + if (audio_i2s.decoder || audio_i2s.mp3) return; + if (!audio_i2s.out) return; if (!ufsp->exists(path)) { return; @@ -651,54 +697,54 @@ void Play_mp3(const char *path) { I2S_Task = false; } - file = new AudioFileSourceFS(*ufsp, path); + audio_i2s.file = new AudioFileSourceFS(*ufsp, path); - id3 = new AudioFileSourceID3(file); + audio_i2s.id3 = new AudioFileSourceID3(audio_i2s.file); - if (mp3ram) { - mp3 = new AudioGeneratorMP3(mp3ram, preallocateCodecSize); + if (audio_i2s.mp3ram) { + audio_i2s.mp3 = new AudioGeneratorMP3(audio_i2s.mp3ram, preallocateCodecSize); } else { - mp3 = new AudioGeneratorMP3(); + audio_i2s.mp3 = new AudioGeneratorMP3(); } - mp3->begin(id3, out); + audio_i2s.mp3->begin(audio_i2s.id3, audio_i2s.out); if (I2S_Task) { - xTaskCreatePinnedToCore(mp3_task, "MP3", 8192, NULL, 3, &mp3_task_h, 1); + xTaskCreatePinnedToCore(mp3_task, "MP3", 8192, NULL, 3, &audio_i2s.mp3_task_h, 1); } else { - while (mp3->isRunning()) { - if (!mp3->loop()) { - mp3->stop(); + while (audio_i2s.mp3->isRunning()) { + if (!audio_i2s.mp3->loop()) { + audio_i2s.mp3->stop(); break; } OsWatchLoop(); } - out->stop(); + audio_i2s.out->stop(); mp3_delete(); } -#endif // USE_SCRIPT +#endif // USE_UFILESYS } void mp3_delete(void) { - delete file; - delete id3; - delete mp3; - mp3=nullptr; + delete audio_i2s.file; + delete audio_i2s.id3; + delete audio_i2s.mp3; + audio_i2s.mp3=nullptr; AUDIO_PWR_OFF } #endif // ESP32 void Say(char *text) { - if (!out) return; + if (!audio_i2s.out) return; AUDIO_PWR_ON - out->begin(); + audio_i2s.out->begin(); ESP8266SAM *sam = new ESP8266SAM; - sam->Say(out, text); + sam->Say(audio_i2s.out, text); delete sam; - out->stop(); + audio_i2s.out->stop(); AUDIO_PWR_OFF } @@ -711,7 +757,7 @@ const char kI2SAudio_Commands[] PROGMEM = "I2S|" #ifdef USE_I2S_WEBRADIO "|WR" #endif // USE_I2S_WEBRADIO -#ifdef USE_M5STACK_CORE2 +#if defined(USE_M5STACK_CORE2) || defined(ESP32S3_BOX) "|REC" #endif // USE_M5STACK_CORE2 #endif // ESP32 @@ -724,7 +770,7 @@ void (* const I2SAudio_Command[])(void) PROGMEM = { #ifdef USE_I2S_WEBRADIO ,&Cmd_WebRadio #endif // USE_I2S_WEBRADIO -#ifdef USE_M5STACK_CORE2 +#if defined(USE_M5STACK_CORE2) || defined(ESP32S3_BOX) ,&Cmd_MicRec #endif // USE_M5STACK_CORE2 #endif // ESP32 @@ -741,12 +787,12 @@ void Cmd_Play(void) { void Cmd_Gain(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { - if (out) { - is2_volume=XdrvMailbox.payload; - out->SetGain(((float)(is2_volume-2)/100.0)*4.0); + if (audio_i2s.out) { + audio_i2s.is2_volume=XdrvMailbox.payload; + audio_i2s.out->SetGain(((float)(audio_i2s.is2_volume-2)/100.0)*4.0); } } - ResponseCmndNumber(is2_volume); + ResponseCmndNumber(audio_i2s.is2_volume); } void Cmd_Say(void) { @@ -758,7 +804,7 @@ void Cmd_Say(void) { void Cmd_Time(void) { #ifdef USE_I2S_SAY_TIME - sayTime(RtcTime.hour, RtcTime.minute, talkie); + sayTime(RtcTime.hour, RtcTime.minute); #endif // USE_I2S_SAY_TIME ResponseCmndDone(); } From 82d668144edd1a2f1ca9a31d7d0c0929396b6008 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 11 Jul 2022 09:10:10 +0200 Subject: [PATCH 2/4] update sbox codecs --- lib/lib_audio/es7210/library.json | 7 + lib/lib_audio/es7210/library.properties | 9 + lib/lib_audio/es7210/src/es7210.cpp | 549 +++++++++++++++++++ lib/lib_audio/es7210/src/es7210.h | 260 +++++++++ lib/lib_audio/es8156/library.properties | 4 +- lib/lib_audio/es8311/library.json | 7 + lib/lib_audio/es8311/library.properties | 9 + lib/lib_audio/es8311/src/es8311.cpp | 695 ++++++++++++++++++++++++ lib/lib_audio/es8311/src/es8311.h | 285 ++++++++++ 9 files changed, 1823 insertions(+), 2 deletions(-) create mode 100644 lib/lib_audio/es7210/library.json create mode 100644 lib/lib_audio/es7210/library.properties create mode 100644 lib/lib_audio/es7210/src/es7210.cpp create mode 100644 lib/lib_audio/es7210/src/es7210.h create mode 100644 lib/lib_audio/es8311/library.json create mode 100644 lib/lib_audio/es8311/library.properties create mode 100644 lib/lib_audio/es8311/src/es8311.cpp create mode 100644 lib/lib_audio/es8311/src/es8311.h diff --git a/lib/lib_audio/es7210/library.json b/lib/lib_audio/es7210/library.json new file mode 100644 index 000000000..27e99c11a --- /dev/null +++ b/lib/lib_audio/es7210/library.json @@ -0,0 +1,7 @@ +{ + "name": "ES7210", + "description": "Audio codec", + "keywords": "ESP8266, ESP32, MP3, AAC, WAV, MOD, FLAC, RTTTL, MIDI, I2S, DAC, Delta-Sigma, TTS", + "version": "1.0.0", + "frameworks": "Arduino" +} diff --git a/lib/lib_audio/es7210/library.properties b/lib/lib_audio/es7210/library.properties new file mode 100644 index 000000000..ffa00ca45 --- /dev/null +++ b/lib/lib_audio/es7210/library.properties @@ -0,0 +1,9 @@ +name=ES7210 +version=1.0 +author= +maintainer= +sentence=Audio fcodec for ESP32 +paragraph= +category=Signal Output +url= +architectures=esp32 diff --git a/lib/lib_audio/es7210/src/es7210.cpp b/lib/lib_audio/es7210/src/es7210.cpp new file mode 100644 index 000000000..3bf680308 --- /dev/null +++ b/lib/lib_audio/es7210/src/es7210.cpp @@ -0,0 +1,549 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2021 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifdef ESP32 + +#include +#include +#include "esp_log.h" +#include "es7210.h" + + +#define I2S_DSP_MODE_A 0 +#define MCLK_DIV_FRE 256 + + +#define ES7210_MCLK_SOURCE FROM_CLOCK_DOUBLE_PIN /* In master mode, 0 : MCLK from pad 1 : MCLK from clock doubler */ +#define FROM_PAD_PIN 0 +#define FROM_CLOCK_DOUBLE_PIN 1 + + +static TwoWire *es7210wire; +static es7210_gain_value_t gain; + +/* + * Clock coefficient structer + */ +struct _coeff_div { + uint32_t mclk; /* mclk frequency */ + uint32_t lrck; /* lrck */ + uint8_t ss_ds; + uint8_t adc_div; /* adcclk divider */ + uint8_t dll; /* dll_bypass */ + uint8_t doubler; /* doubler enable */ + uint8_t osr; /* adc osr */ + uint8_t mclk_src; /* select mclk source */ + uint32_t lrck_h; /* The high 4 bits of lrck */ + uint32_t lrck_l; /* The low 8 bits of lrck */ +}; + +static const char *TAG = "ES7210"; + +static es7210_input_mics_t mic_select = (es7210_input_mics_t)(ES7210_INPUT_MIC1 | ES7210_INPUT_MIC2 | ES7210_INPUT_MIC3 | ES7210_INPUT_MIC4); + +/* Codec hifi mclk clock divider coefficients + * MEMBER REG + * mclk: 0x03 + * lrck: standard + * ss_ds: -- + * adc_div: 0x02 + * dll: 0x06 + * doubler: 0x02 + * osr: 0x07 + * mclk_src: 0x03 + * lrckh: 0x04 + * lrckl: 0x05 +*/ +static const struct _coeff_div coeff_div[] = { + //mclk lrck ss_ds adc_div dll doubler osr mclk_src lrckh lrckl + /* 8k */ + {12288000, 8000 , 0x00, 0x03, 0x01, 0x00, 0x20, 0x00, 0x06, 0x00}, + {16384000, 8000 , 0x00, 0x04, 0x01, 0x00, 0x20, 0x00, 0x08, 0x00}, + {19200000, 8000 , 0x00, 0x1e, 0x00, 0x01, 0x28, 0x00, 0x09, 0x60}, + {4096000, 8000 , 0x00, 0x01, 0x01, 0x00, 0x20, 0x00, 0x02, 0x00}, + + /* 11.025k */ + {11289600, 11025, 0x00, 0x02, 0x01, 0x00, 0x20, 0x00, 0x01, 0x00}, + + /* 12k */ + {12288000, 12000, 0x00, 0x02, 0x01, 0x00, 0x20, 0x00, 0x04, 0x00}, + {19200000, 12000, 0x00, 0x14, 0x00, 0x01, 0x28, 0x00, 0x06, 0x40}, + + /* 16k */ + {4096000, 16000, 0x00, 0x01, 0x01, 0x01, 0x20, 0x00, 0x01, 0x00}, + {19200000, 16000, 0x00, 0x0a, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x80}, + {16384000, 16000, 0x00, 0x02, 0x01, 0x00, 0x20, 0x00, 0x04, 0x00}, + {12288000, 16000, 0x00, 0x03, 0x01, 0x01, 0x20, 0x00, 0x03, 0x00}, + + /* 22.05k */ + {11289600, 22050, 0x00, 0x01, 0x01, 0x00, 0x20, 0x00, 0x02, 0x00}, + + /* 24k */ + {12288000, 24000, 0x00, 0x01, 0x01, 0x00, 0x20, 0x00, 0x02, 0x00}, + {19200000, 24000, 0x00, 0x0a, 0x00, 0x01, 0x28, 0x00, 0x03, 0x20}, + + /* 32k */ + {12288000, 32000, 0x00, 0x03, 0x00, 0x00, 0x20, 0x00, 0x01, 0x80}, + {16384000, 32000, 0x00, 0x01, 0x01, 0x00, 0x20, 0x00, 0x02, 0x00}, + {19200000, 32000, 0x00, 0x05, 0x00, 0x00, 0x1e, 0x00, 0x02, 0x58}, + + /* 44.1k */ + {11289600, 44100, 0x00, 0x01, 0x01, 0x01, 0x20, 0x00, 0x01, 0x00}, + + /* 48k */ + {12288000, 48000, 0x00, 0x01, 0x01, 0x01, 0x20, 0x00, 0x01, 0x00}, + {19200000, 48000, 0x00, 0x05, 0x00, 0x01, 0x28, 0x00, 0x01, 0x90}, + + /* 64k */ + {16384000, 64000, 0x01, 0x01, 0x01, 0x00, 0x20, 0x00, 0x01, 0x00}, + {19200000, 64000, 0x00, 0x05, 0x00, 0x01, 0x1e, 0x00, 0x01, 0x2c}, + + /* 88.2k */ + {11289600, 88200, 0x01, 0x01, 0x01, 0x01, 0x20, 0x00, 0x00, 0x80}, + + /* 96k */ + {12288000, 96000, 0x01, 0x01, 0x01, 0x01, 0x20, 0x00, 0x00, 0x80}, + {19200000, 96000, 0x01, 0x05, 0x00, 0x01, 0x28, 0x00, 0x00, 0xc8}, +}; + +static esp_err_t es7210_write_reg(uint8_t reg_addr, uint8_t data) +{ + + es7210wire->beginTransmission(ES7210_ADDR); + es7210wire->write(reg_addr); + es7210wire->write(data); + return es7210wire->endTransmission(); + +} + +static esp_err_t es7210_update_reg_bit(uint8_t reg_addr, uint8_t update_bits, uint8_t data) +{ + uint8_t regv; + regv = es7210_read_reg(reg_addr); + regv = (regv & (~update_bits)) | (update_bits & data); + return es7210_write_reg(reg_addr, regv); +} + +static int get_coeff(uint32_t mclk, uint32_t lrck) +{ + for (int i = 0; i < (sizeof(coeff_div) / sizeof(coeff_div[0])); i++) { + if (coeff_div[i].lrck == lrck && coeff_div[i].mclk == mclk) + return i; + } + return -1; +} + +int8_t get_es7210_mclk_src(void) +{ + return ES7210_MCLK_SOURCE; +} + +int es7210_read_reg(uint8_t reg_addr) +{ + uint8_t data; + es7210wire->beginTransmission(ES7210_ADDR); + es7210wire->write(reg_addr); + es7210wire->endTransmission(false); + es7210wire->requestFrom(ES7210_ADDR, (size_t)1); + data = es7210wire->read(); + return (int)data; +} + +esp_err_t es7210_config_sample(audio_hal_iface_samples_t sample) +{ + uint8_t regv; + int coeff; + int sample_fre = 0; + int mclk_fre = 0; + esp_err_t ret = ESP_OK; + switch (sample) { + case AUDIO_HAL_08K_SAMPLES: + sample_fre = 8000; + break; + case AUDIO_HAL_11K_SAMPLES: + sample_fre = 11025; + break; + case AUDIO_HAL_16K_SAMPLES: + sample_fre = 16000; + break; + case AUDIO_HAL_22K_SAMPLES: + sample_fre = 22050; + break; + case AUDIO_HAL_24K_SAMPLES: + sample_fre = 24000; + break; + case AUDIO_HAL_32K_SAMPLES: + sample_fre = 32000; + break; + case AUDIO_HAL_44K_SAMPLES: + sample_fre = 44100; + break; + case AUDIO_HAL_48K_SAMPLES: + sample_fre = 48000; + break; + default: + ESP_LOGE(TAG, "Unable to configure sample rate %dHz", sample_fre); + break; + } + mclk_fre = sample_fre * MCLK_DIV_FRE; + coeff = get_coeff(mclk_fre, sample_fre); + if (coeff < 0) { + ESP_LOGE(TAG, "Unable to configure sample rate %dHz with %dHz MCLK", sample_fre, mclk_fre); + return ESP_FAIL; + } + /* Set clock parammeters */ + if (coeff >= 0) { + /* Set adc_div & doubler & dll */ + regv = es7210_read_reg(ES7210_MAINCLK_REG02) & 0x00; + regv |= coeff_div[coeff].adc_div; + regv |= coeff_div[coeff].doubler << 6; + regv |= coeff_div[coeff].dll << 7; + ret |= es7210_write_reg(ES7210_MAINCLK_REG02, regv); + /* Set osr */ + regv = coeff_div[coeff].osr; + ret |= es7210_write_reg(ES7210_OSR_REG07, regv); + /* Set lrck */ + regv = coeff_div[coeff].lrck_h; + ret |= es7210_write_reg(ES7210_LRCK_DIVH_REG04, regv); + regv = coeff_div[coeff].lrck_l; + ret |= es7210_write_reg(ES7210_LRCK_DIVL_REG05, regv); + } + return ret; +} + +esp_err_t es7210_mic_select(es7210_input_mics_t mic) +{ + esp_err_t ret = ESP_OK; + mic_select = mic; + if (mic_select & (ES7210_INPUT_MIC1 | ES7210_INPUT_MIC2 | ES7210_INPUT_MIC3 | ES7210_INPUT_MIC4)) { + for (int i = 0; i < 4; i++) { + ret |= es7210_update_reg_bit(ES7210_MIC1_GAIN_REG43 + i, 0x10, 0x00); + } + ret |= es7210_write_reg(ES7210_MIC12_POWER_REG4B, 0xff); + ret |= es7210_write_reg(ES7210_MIC34_POWER_REG4C, 0xff); + if (mic_select & ES7210_INPUT_MIC1) { + ESP_LOGI(TAG, "Enable ES7210_INPUT_MIC1"); + ret |= es7210_update_reg_bit(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00); + ret |= es7210_write_reg(ES7210_MIC12_POWER_REG4B, 0x00); + ret |= es7210_update_reg_bit(ES7210_MIC1_GAIN_REG43, 0x10, 0x10); + } + if (mic_select & ES7210_INPUT_MIC2) { + ESP_LOGI(TAG, "Enable ES7210_INPUT_MIC2"); + ret |= es7210_update_reg_bit(ES7210_CLOCK_OFF_REG01, 0x0b, 0x00); + ret |= es7210_write_reg(ES7210_MIC12_POWER_REG4B, 0x00); + ret |= es7210_update_reg_bit(ES7210_MIC2_GAIN_REG44, 0x10, 0x10); + } + if (mic_select & ES7210_INPUT_MIC3) { + ESP_LOGI(TAG, "Enable ES7210_INPUT_MIC3"); + ret |= es7210_update_reg_bit(ES7210_CLOCK_OFF_REG01, 0x15, 0x00); + ret |= es7210_write_reg(ES7210_MIC34_POWER_REG4C, 0x00); + ret |= es7210_update_reg_bit(ES7210_MIC3_GAIN_REG45, 0x10, 0x10); + } + if (mic_select & ES7210_INPUT_MIC4) { + ESP_LOGI(TAG, "Enable ES7210_INPUT_MIC4"); + ret |= es7210_update_reg_bit(ES7210_CLOCK_OFF_REG01, 0x15, 0x00); + ret |= es7210_write_reg(ES7210_MIC34_POWER_REG4C, 0x00); + ret |= es7210_update_reg_bit(ES7210_MIC4_GAIN_REG46, 0x10, 0x10); + } + } else { + ESP_LOGE(TAG, "Microphone selection error"); + return ESP_FAIL; + } + return ret; +} + +esp_err_t es7210_adc_init(TwoWire *tw, audio_hal_codec_config_t *codec_cfg) +{ + esp_err_t ret = ESP_OK; + + es7210wire = tw; + + ret |= es7210_write_reg(ES7210_RESET_REG00, 0xff); + ret |= es7210_write_reg(ES7210_RESET_REG00, 0x41); + ret |= es7210_write_reg(ES7210_CLOCK_OFF_REG01, 0x1f); + ret |= es7210_write_reg(ES7210_TIME_CONTROL0_REG09, 0x30); /* Set chip state cycle */ + ret |= es7210_write_reg(ES7210_TIME_CONTROL1_REG0A, 0x30); /* Set power on state cycle */ + // ret |= es7210_write_reg(ES7210_ADC12_HPF2_REG23, 0x2a); /* Quick setup */ + // ret |= es7210_write_reg(ES7210_ADC12_HPF1_REG22, 0x0a); + // ret |= es7210_write_reg(ES7210_ADC34_HPF2_REG20, 0x0a); + // ret |= es7210_write_reg(ES7210_ADC34_HPF1_REG21, 0x2a); + /* Set master/slave audio interface */ + audio_hal_codec_i2s_iface_t *i2s_cfg = & (codec_cfg->i2s_iface); + switch (i2s_cfg->mode) { + case AUDIO_HAL_MODE_MASTER: /* MASTER MODE */ + ESP_LOGI(TAG, "ES7210 in Master mode"); + // ret |= es7210_update_reg_bit(ES7210_MODE_CONFIG_REG08, 0x01, 0x01); + ret |= es7210_write_reg(ES7210_MODE_CONFIG_REG08, 0x20); + /* Select clock source for internal mclk */ + switch (get_es7210_mclk_src()) { + case FROM_PAD_PIN: + ret |= es7210_update_reg_bit(ES7210_MASTER_CLK_REG03, 0x80, 0x00); + break; + case FROM_CLOCK_DOUBLE_PIN: + ret |= es7210_update_reg_bit(ES7210_MASTER_CLK_REG03, 0x80, 0x80); + break; + default: + ret |= es7210_update_reg_bit(ES7210_MASTER_CLK_REG03, 0x80, 0x00); + break; + } + break; + case AUDIO_HAL_MODE_SLAVE: /* SLAVE MODE */ + ESP_LOGI(TAG, "ES7210 in Slave mode"); + break; + default: + break; + } + ret |= es7210_write_reg(ES7210_ANALOG_REG40, 0xC3); /* Select power off analog, vdda = 3.3V, close vx20ff, VMID select 5KΩ start */ + ret |= es7210_write_reg(ES7210_MIC12_BIAS_REG41, 0x70); /* Select 2.87v */ + ret |= es7210_write_reg(ES7210_MIC34_BIAS_REG42, 0x70); /* Select 2.87v */ + ret |= es7210_write_reg(ES7210_OSR_REG07, 0x20); + ret |= es7210_write_reg(ES7210_MAINCLK_REG02, 0xc1); /* Set the frequency division coefficient and use dll except clock doubler, and need to set 0xc1 to clear the state */ + ret |= es7210_config_sample(i2s_cfg->samples); + ret |= es7210_mic_select(mic_select); + ret |= es7210_adc_set_gain_all(GAIN_0DB); + return ESP_OK; +} + +esp_err_t es7210_adc_deinit() +{ + return ESP_OK; +} + +esp_err_t es7210_config_fmt(audio_hal_iface_format_t fmt) +{ + esp_err_t ret = ESP_OK; + uint8_t adc_iface = 0; + adc_iface = es7210_read_reg(ES7210_SDP_INTERFACE1_REG11); + adc_iface &= 0xfc; + switch (fmt) { + case AUDIO_HAL_I2S_NORMAL: + ESP_LOGD(TAG, "ES7210 in I2S Format"); + adc_iface |= 0x00; + break; + case AUDIO_HAL_I2S_LEFT: + case AUDIO_HAL_I2S_RIGHT: + ESP_LOGD(TAG, "ES7210 in LJ Format"); + adc_iface |= 0x01; + break; + case AUDIO_HAL_I2S_DSP: + if (I2S_DSP_MODE_A) { + ESP_LOGD(TAG, "ES7210 in DSP-A Format"); + adc_iface |= 0x03; + } else { + ESP_LOGD(TAG, "ES7210 in DSP-B Format"); + adc_iface |= 0x13; + } + break; + default: + adc_iface &= 0xfc; + break; + } + ret |= es7210_write_reg(ES7210_SDP_INTERFACE1_REG11, adc_iface); + /* Force ADC1/2 output to SDOUT1 and ADC3/4 output to SDOUT2 */ + ret |= es7210_write_reg(ES7210_SDP_INTERFACE2_REG12, 0x00); + return ret; +} + +esp_err_t es7210_set_bits(audio_hal_iface_bits_t bits) +{ + esp_err_t ret = ESP_OK; + uint8_t adc_iface = 0; + adc_iface = es7210_read_reg(ES7210_SDP_INTERFACE1_REG11); + adc_iface &= 0x1f; + switch (bits) { + case AUDIO_HAL_BIT_LENGTH_16BITS: + adc_iface |= 0x60; + break; + case AUDIO_HAL_BIT_LENGTH_24BITS: + adc_iface |= 0x00; + break; + case AUDIO_HAL_BIT_LENGTH_32BITS: + adc_iface |= 0x80; + break; + default: + adc_iface |= 0x60; + break; + } + ret |= es7210_write_reg(ES7210_SDP_INTERFACE1_REG11, adc_iface); + return ret; +} + +esp_err_t es7210_adc_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface) +{ + esp_err_t ret = ESP_OK; + ret |= es7210_set_bits(iface->bits); + ret |= es7210_config_fmt(iface->fmt); + ret |= es7210_config_sample(iface->samples); + return ret; +} + +esp_err_t es7210_start(uint8_t clock_reg_value) +{ + esp_err_t ret = ESP_OK; + ret |= es7210_write_reg(ES7210_CLOCK_OFF_REG01, clock_reg_value); + ret |= es7210_write_reg(ES7210_POWER_DOWN_REG06, 0x00); + // ret |= es7210_write_reg(ES7210_ANALOG_REG40, 0x40); + ret |= es7210_write_reg(ES7210_MIC1_POWER_REG47, 0x00); + ret |= es7210_write_reg(ES7210_MIC2_POWER_REG48, 0x00); + ret |= es7210_write_reg(ES7210_MIC3_POWER_REG49, 0x00); + ret |= es7210_write_reg(ES7210_MIC4_POWER_REG4A, 0x00); + ret |= es7210_mic_select(mic_select); + return ret; +} + +esp_err_t es7210_stop(void) +{ + esp_err_t ret = ESP_OK; + ret |= es7210_write_reg(ES7210_MIC1_POWER_REG47, 0xff); + ret |= es7210_write_reg(ES7210_MIC2_POWER_REG48, 0xff); + ret |= es7210_write_reg(ES7210_MIC3_POWER_REG49, 0xff); + ret |= es7210_write_reg(ES7210_MIC4_POWER_REG4A, 0xff); + ret |= es7210_write_reg(ES7210_MIC12_POWER_REG4B,0xff); + ret |= es7210_write_reg(ES7210_MIC34_POWER_REG4C, 0xff); + // ret |= es7210_write_reg(ES7210_ANALOG_REG40, 0xc0); + ret |= es7210_write_reg(ES7210_CLOCK_OFF_REG01, 0x7f); + ret |= es7210_write_reg(ES7210_POWER_DOWN_REG06, 0x07); + return ret; +} + +esp_err_t es7210_adc_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state) +{ + static uint8_t regv; + esp_err_t ret = ESP_OK; + // ESP_LOGW(TAG, "ES7210 only supports ADC mode"); + ret = es7210_read_reg(ES7210_CLOCK_OFF_REG01); + if ((ret != 0x7f) && (ret != 0xff)) { + regv = es7210_read_reg(ES7210_CLOCK_OFF_REG01); + } + if (ctrl_state == AUDIO_HAL_CTRL_START) { + ESP_LOGI(TAG, "The ES7210_CLOCK_OFF_REG01 value before stop is %x",regv); + ret |= es7210_start(regv); + } else { + ESP_LOGW(TAG, "The codec is about to stop"); + regv = es7210_read_reg(ES7210_CLOCK_OFF_REG01); + ret |= es7210_stop(); + } + return ESP_OK; +} + +esp_err_t es7210_adc_set_gain(es7210_input_mics_t mic_mask, es7210_gain_value_t gain) +{ + esp_err_t ret_val = ESP_OK; + + if (gain < GAIN_0DB) { + gain = GAIN_0DB; + } + + if (gain > GAIN_37_5DB) { + gain = GAIN_37_5DB; + } + + if (mic_mask & ES7210_INPUT_MIC1) { + ret_val |= es7210_update_reg_bit(ES7210_MIC1_GAIN_REG43, 0x0f, gain); + } + if (mic_mask & ES7210_INPUT_MIC2) { + ret_val |= es7210_update_reg_bit(ES7210_MIC2_GAIN_REG44, 0x0f, gain); + } + if (mic_mask & ES7210_INPUT_MIC3) { + ret_val |= es7210_update_reg_bit(ES7210_MIC3_GAIN_REG45, 0x0f, gain); + } + if (mic_mask & ES7210_INPUT_MIC4) { + ret_val |= es7210_update_reg_bit(ES7210_MIC4_GAIN_REG46, 0x0f, gain); + } + + return ret_val; +} + +esp_err_t es7210_adc_set_gain_all(es7210_gain_value_t gain) +{ + esp_err_t ret = ESP_OK; + uint32_t max_gain_vaule = 14; + if (gain < 0) { + gain = (es7210_gain_value_t) 0; + } else if (gain > max_gain_vaule) { + gain = (es7210_gain_value_t) max_gain_vaule; + } + ESP_LOGD(TAG, "SET: gain:%d", gain); + if (mic_select & ES7210_INPUT_MIC1) { + ret |= es7210_update_reg_bit(ES7210_MIC1_GAIN_REG43, 0x0f, gain); + } + if (mic_select & ES7210_INPUT_MIC2) { + ret |= es7210_update_reg_bit(ES7210_MIC2_GAIN_REG44, 0x0f, gain); + } + if (mic_select & ES7210_INPUT_MIC3) { + ret |= es7210_update_reg_bit(ES7210_MIC3_GAIN_REG45, 0x0f, gain); + } + if (mic_select & ES7210_INPUT_MIC4) { + ret |= es7210_update_reg_bit(ES7210_MIC4_GAIN_REG46, 0x0f, gain); + } + return ret; +} + +esp_err_t es7210_adc_get_gain(es7210_input_mics_t mic_mask, es7210_gain_value_t *gain) +{ + int regv = 0; + uint8_t gain_value; + if (mic_mask & ES7210_INPUT_MIC1) { + regv = es7210_read_reg(ES7210_MIC1_GAIN_REG43); + } else if (mic_mask & ES7210_INPUT_MIC2) { + regv = es7210_read_reg(ES7210_MIC2_GAIN_REG44); + } else if (mic_mask & ES7210_INPUT_MIC3) { + regv = es7210_read_reg(ES7210_MIC3_GAIN_REG45); + } else if (mic_mask & ES7210_INPUT_MIC4) { + regv = es7210_read_reg(ES7210_MIC4_GAIN_REG46); + } else { + ESP_LOGE(TAG, "No MIC selected"); + return ESP_FAIL; + } + if (regv == ESP_FAIL) { + return regv; + } + gain_value = (regv & 0x0f); /* Retain the last four bits for gain */ + *gain = (es7210_gain_value_t) gain_value; + ESP_LOGI(TAG, "GET: gain_value:%d", gain_value); + return ESP_OK; +} + +esp_err_t es7210_adc_set_volume(int volume) +{ + esp_err_t ret = ESP_OK; + ESP_LOGD(TAG, "ADC can adjust gain"); + return ret; +} + +esp_err_t es7210_set_mute(bool enable) +{ + ESP_LOGD(TAG, "ES7210 SetMute :%d", enable); + return ESP_OK; +} + +void es7210_read_all(void) +{ + for (int i = 0; i <= 0x4E; i++) { + uint8_t reg = es7210_read_reg(i); + ets_printf("REG:%02x, %02x\n", reg, i); + } +} + +#endif diff --git a/lib/lib_audio/es7210/src/es7210.h b/lib/lib_audio/es7210/src/es7210.h new file mode 100644 index 000000000..07f7e6311 --- /dev/null +++ b/lib/lib_audio/es7210/src/es7210.h @@ -0,0 +1,260 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2021 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _ES7210_H +#define _ES7210_H + +#include "audio_hal.h" + + +typedef enum { + ES7210_AD1_AD0_00 = 0x40, + ES7210_AD1_AD0_01 = 0x41, + ES7210_AD1_AD0_10 = 0x42, + ES7210_AD1_AD0_11 = 0x43, +} es7210_address_t; + +/* ES7210 address*/ +#define ES7210_ADDR ES7210_AD1_AD0_00 + +#ifdef __cplusplus +extern "C" { +#endif + +#define ES7210_RESET_REG00 0x00 /* Reset control */ +#define ES7210_CLOCK_OFF_REG01 0x01 /* Used to turn off the ADC clock */ +#define ES7210_MAINCLK_REG02 0x02 /* Set ADC clock frequency division */ +#define ES7210_MASTER_CLK_REG03 0x03 /* MCLK source $ SCLK division */ +#define ES7210_LRCK_DIVH_REG04 0x04 /* lrck_divh */ +#define ES7210_LRCK_DIVL_REG05 0x05 /* lrck_divl */ +#define ES7210_POWER_DOWN_REG06 0x06 /* power down */ +#define ES7210_OSR_REG07 0x07 +#define ES7210_MODE_CONFIG_REG08 0x08 /* Set master/slave & channels */ +#define ES7210_TIME_CONTROL0_REG09 0x09 /* Set Chip intial state period*/ +#define ES7210_TIME_CONTROL1_REG0A 0x0A /* Set Power up state period */ +#define ES7210_SDP_INTERFACE1_REG11 0x11 /* Set sample & fmt */ +#define ES7210_SDP_INTERFACE2_REG12 0x12 /* Pins state */ +#define ES7210_ADC_AUTOMUTE_REG13 0x13 /* Set mute */ +#define ES7210_ADC34_MUTERANGE_REG14 0x14 /* Set mute range */ +#define ES7210_ADC34_HPF2_REG20 0x20 /* HPF */ +#define ES7210_ADC34_HPF1_REG21 0x21 +#define ES7210_ADC12_HPF1_REG22 0x22 +#define ES7210_ADC12_HPF2_REG23 0x23 +#define ES7210_ANALOG_REG40 0x40 /* ANALOG Power */ +#define ES7210_MIC12_BIAS_REG41 0x41 +#define ES7210_MIC34_BIAS_REG42 0x42 +#define ES7210_MIC1_GAIN_REG43 0x43 +#define ES7210_MIC2_GAIN_REG44 0x44 +#define ES7210_MIC3_GAIN_REG45 0x45 +#define ES7210_MIC4_GAIN_REG46 0x46 +#define ES7210_MIC1_POWER_REG47 0x47 +#define ES7210_MIC2_POWER_REG48 0x48 +#define ES7210_MIC3_POWER_REG49 0x49 +#define ES7210_MIC4_POWER_REG4A 0x4A +#define ES7210_MIC12_POWER_REG4B 0x4B /* MICBias & ADC & PGA Power */ +#define ES7210_MIC34_POWER_REG4C 0x4C + + + +typedef enum { + ES7210_INPUT_MIC1 = 0x01, + ES7210_INPUT_MIC2 = 0x02, + ES7210_INPUT_MIC3 = 0x04, + ES7210_INPUT_MIC4 = 0x08 +} es7210_input_mics_t; + +typedef enum gain_value{ + GAIN_0DB = 0, + GAIN_3DB, + GAIN_6DB, + GAIN_9DB, + GAIN_12DB, + GAIN_15DB, + GAIN_18DB, + GAIN_21DB, + GAIN_24DB, + GAIN_27DB, + GAIN_30DB, + GAIN_33DB, + GAIN_34_5DB, + GAIN_36DB, + GAIN_37_5DB, +} es7210_gain_value_t; + +/* + * @brief Initialize ES7210 ADC chip + * + * @param[in] codec_cfg: configuration of ES7210 + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es7210_adc_init(TwoWire *tw, audio_hal_codec_config_t *codec_cfg); + +/** + * @brief Deinitialize ES7210 ADC chip + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es7210_adc_deinit(); + +/** + * @brief Configure ES7210 ADC mode and I2S interface + * + * @param[in] mode: codec mode + * @param[in] iface: I2S config + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t es7210_adc_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface); + +/** + * @brief Control ES7210 ADC chip + * + * @param[in] mode: codec mode + * @param[in] ctrl_state: start or stop progress + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t es7210_adc_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state); + +/** + * @brief Set gain of given mask + * + * @param[in] mic_mask Mask of MIC channel + * + * @param[in] gain: gain + * + * gain : value + * GAIN_0DB : 1 + * GAIN_3DB : 2 + * GAIN_6DB : 3 + * · + * · + * · + * GAIN_30DB : 10 + * GAIN_33DB : 11 + * GAIN_34_5DB : 12 + * GAIN_36DB : 13 + * GAIN_37_5DB : 14 + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es7210_adc_set_gain(es7210_input_mics_t mic_mask, es7210_gain_value_t gain); + +/** + * @brief Set gain (Note: the enabled microphone sets the same gain) + * + * @param[in] gain: gain + * + * gain : value + * GAIN_0DB : 1 + * GAIN_3DB : 2 + * GAIN_6DB : 3 + * · + * · + * · + * GAIN_30DB : 10 + * GAIN_33DB : 11 + * GAIN_34_5DB : 12 + * GAIN_36DB : 13 + * GAIN_37_5DB : 14 + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es7210_adc_set_gain_all(es7210_gain_value_t gain); + +/** + * @brief Get MIC gain + * + * @param mic_mask Selected MIC + * @param gain Pointer to `es7210_gain_value_t` + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es7210_adc_get_gain(es7210_input_mics_t mic_mask, es7210_gain_value_t *gain); + +/** + * @brief Set volume + * + * @param[in] volume: volume + * + * @return + * - ESP_OK + */ +esp_err_t es7210_adc_set_volume(int volume); + +/** + * @brief Set ES7210 ADC mute status + * + * @return + * - ESP_FAIL + * - ESP_OK + */ +esp_err_t es7210_set_mute(bool enable); + +/** + * @brief Select ES7210 mic + * + * @param[in] mic: mics + * + * @return + * - ESP_FAIL + * - ESP_OK + */ +esp_err_t es7210_mic_select(es7210_input_mics_t mic); + +/** + * @brief Read regs of ES7210 + * + * @param[in] reg_addr: reg_addr + * + * @return + * - ESP_FAIL + * - ESP_OK + */ +int es7210_read_reg(uint8_t reg_addr); + +/** + * @brief Read all regs of ES7210 + */ +void es7210_read_all(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _ES7210_H_ */ diff --git a/lib/lib_audio/es8156/library.properties b/lib/lib_audio/es8156/library.properties index bd6db1442..7ff0a31b6 100644 --- a/lib/lib_audio/es8156/library.properties +++ b/lib/lib_audio/es8156/library.properties @@ -2,8 +2,8 @@ name=ES8156 version=1.0 author= maintainer= -sentence=Audio fcodec for ESP8266, ESP32 +sentence=Audio fcodec for ESP32 paragraph= category=Signal Output url= -architectures=* +architectures=esp32 diff --git a/lib/lib_audio/es8311/library.json b/lib/lib_audio/es8311/library.json new file mode 100644 index 000000000..bf1b4701b --- /dev/null +++ b/lib/lib_audio/es8311/library.json @@ -0,0 +1,7 @@ +{ + "name": "ES8311", + "description": "Audio codec", + "keywords": "ESP8266, ESP32, MP3, AAC, WAV, MOD, FLAC, RTTTL, MIDI, I2S, DAC, Delta-Sigma, TTS", + "version": "1.0.0", + "frameworks": "Arduino" +} diff --git a/lib/lib_audio/es8311/library.properties b/lib/lib_audio/es8311/library.properties new file mode 100644 index 000000000..fdbc224d2 --- /dev/null +++ b/lib/lib_audio/es8311/library.properties @@ -0,0 +1,9 @@ +name=ES8311 +version=1.0 +author= +maintainer= +sentence=Audio fcodec for ESP32 +paragraph= +category=Signal Output +url= +architectures=esp32 diff --git a/lib/lib_audio/es8311/src/es8311.cpp b/lib/lib_audio/es8311/src/es8311.cpp new file mode 100644 index 000000000..6cdc41f75 --- /dev/null +++ b/lib/lib_audio/es8311/src/es8311.cpp @@ -0,0 +1,695 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2019 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifdef ESP32 + +#include +#include +#include "esp_log.h" +#include "es8311.h" + + + +/* + * to define the clock soure of MCLK + */ +#define FROM_MCLK_PIN 0 +#define FROM_SCLK_PIN 1 +#define ES8311_MCLK_SOURCE FROM_MCLK_PIN + +/* + * to define whether to reverse the clock + */ +#define INVERT_MCLK 0 // do not invert +#define INVERT_SCLK 0 + +#define IS_DMIC 0 // Is it a digital microphone + +#define MCLK_DIV_FRE 256 + +static TwoWire *es8311_wire; + + +/* + * Clock coefficient structer + */ +struct _coeff_div { + uint32_t mclk; /* mclk frequency */ + uint32_t rate; /* sample rate */ + uint8_t pre_div; /* the pre divider with range from 1 to 8 */ + uint8_t pre_multi; /* the pre multiplier with x1, x2, x4 and x8 selection */ + uint8_t adc_div; /* adcclk divider */ + uint8_t dac_div; /* dacclk divider */ + uint8_t fs_mode; /* double speed or single speed, =0, ss, =1, ds */ + uint8_t lrck_h; /* adclrck divider and daclrck divider */ + uint8_t lrck_l; + uint8_t bclk_div; /* sclk divider */ + uint8_t adc_osr; /* adc osr */ + uint8_t dac_osr; /* dac osr */ +}; + +/* codec hifi mclk clock divider coefficients */ +static const struct _coeff_div coeff_div[] = { + //mclk rate pre_div mult adc_div dac_div fs_mode lrch lrcl bckdiv osr + /* 8k */ + {12288000, 8000 , 0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {18432000, 8000 , 0x03, 0x02, 0x03, 0x03, 0x00, 0x05, 0xff, 0x18, 0x10, 0x10}, + {16384000, 8000 , 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {8192000 , 8000 , 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000 , 8000 , 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {4096000 , 8000 , 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000 , 8000 , 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2048000 , 8000 , 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000 , 8000 , 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1024000 , 8000 , 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 11.025k */ + {11289600, 11025, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {5644800 , 11025, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2822400 , 11025, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1411200 , 11025, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 12k */ + {12288000, 12000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000 , 12000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000 , 12000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000 , 12000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 16k */ + {12288000, 16000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {18432000, 16000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10}, + {16384000, 16000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {8192000 , 16000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000 , 16000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {4096000 , 16000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000 , 16000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2048000 , 16000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000 , 16000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1024000 , 16000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 22.05k */ + {11289600, 22050, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {5644800 , 22050, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2822400 , 22050, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1411200 , 22050, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 24k */ + {12288000, 24000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {18432000, 24000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000 , 24000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000 , 24000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000 , 24000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 32k */ + {12288000, 32000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {18432000, 32000, 0x03, 0x04, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10}, + {16384000, 32000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {8192000 , 32000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000 , 32000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {4096000 , 32000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000 , 32000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2048000 , 32000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000 , 32000, 0x03, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, + {1024000 , 32000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 44.1k */ + {11289600, 44100, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {5644800 , 44100, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2822400 , 44100, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1411200 , 44100, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 48k */ + {12288000, 48000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {18432000, 48000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000 , 48000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000 , 48000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000 , 48000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + + /* 64k */ + {12288000, 64000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {18432000, 64000, 0x03, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10}, + {16384000, 64000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {8192000 , 64000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000 , 64000, 0x01, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10}, + {4096000 , 64000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000 , 64000, 0x01, 0x08, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10}, + {2048000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0xbf, 0x03, 0x18, 0x18}, + {1024000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, + + /* 88.2k */ + {11289600, 88200, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {5644800 , 88200, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {2822400 , 88200, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1411200 , 88200, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, + + /* 96k */ + {12288000, 96000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {18432000, 96000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {6144000 , 96000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {3072000 , 96000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10}, + {1536000 , 96000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10}, +}; + +static const char *TAG = "DRV8311"; + +#define ES_ASSERT(a, format, b, ...) \ + if ((a) != 0) { \ + ESP_LOGE(TAG, format, ##__VA_ARGS__); \ + return b;\ + } + +static esp_err_t es8311_write_reg(uint8_t reg_addr, uint8_t data) +{ + //return i2c_bus_write_byte(i2c_handle, reg_addr, data); + es8311_wire->beginTransmission(ES8311_ADDR); + es8311_wire->write(reg_addr); + es8311_wire->write(data); + return es8311_wire->endTransmission(); + +} + +static int es8311_read_reg(uint8_t reg_addr) +{ + uint8_t data; + //i2c_bus_read_byte(i2c_handle, reg_addr, &data); + es8311_wire->beginTransmission(ES8311_ADDR); + es8311_wire->write(reg_addr); + es8311_wire->endTransmission(false); + es8311_wire->requestFrom(ES8311_ADDR, (size_t)1); + data = es8311_wire->read(); + return (int)data; +} + +/* +* look for the coefficient in coeff_div[] table +*/ +static int get_coeff(uint32_t mclk, uint32_t rate) +{ + for (int i = 0; i < (sizeof(coeff_div) / sizeof(coeff_div[0])); i++) { + if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) + return i; + } + return -1; +} + +/* +* set es8311 dac mute or not +* if mute = 0, dac un-mute +* if mute = 1, dac mute +*/ +static void es8311_mute(int mute) +{ + uint8_t regv; + regv = es8311_read_reg(ES8311_DAC_REG31) & 0x9f; + if (mute) { + es8311_write_reg(ES8311_SYSTEM_REG12, 0x02); + es8311_write_reg(ES8311_DAC_REG31, regv | 0x60); + es8311_write_reg(ES8311_DAC_REG32, 0x00); + es8311_write_reg(ES8311_DAC_REG37, 0x08); + } else { + es8311_write_reg(ES8311_DAC_REG31, regv); + es8311_write_reg(ES8311_SYSTEM_REG12, 0x00); + } +} + +/* +* set es8311 into suspend mode +*/ +static void es8311_suspend(void) +{ + ESP_LOGI(TAG, "Enter into es8311_suspend()"); + es8311_write_reg(ES8311_DAC_REG32, 0x00); + es8311_write_reg(ES8311_ADC_REG17, 0x00); + es8311_write_reg(ES8311_SYSTEM_REG0E, 0xFF); + es8311_write_reg(ES8311_SYSTEM_REG12, 0x02); + es8311_write_reg(ES8311_SYSTEM_REG14, 0x00); + es8311_write_reg(ES8311_SYSTEM_REG0D, 0xFA); + es8311_write_reg(ES8311_ADC_REG15, 0x00); + es8311_write_reg(ES8311_DAC_REG37, 0x08); + es8311_write_reg(ES8311_GP_REG45, 0x01); +} + +esp_err_t es8311_codec_init(TwoWire *tw, audio_hal_codec_config_t *codec_cfg) +{ + + es8311_wire = tw; + + uint8_t datmp, regv; + int coeff; + esp_err_t ret = ESP_OK; + + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x30); + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, 0x00); + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, 0x10); + ret |= es8311_write_reg(ES8311_ADC_REG16, 0x24); + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, 0x10); + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, 0x00); + ret |= es8311_write_reg(ES8311_SYSTEM_REG0B, 0x00); + ret |= es8311_write_reg(ES8311_SYSTEM_REG0C, 0x00); + ret |= es8311_write_reg(ES8311_SYSTEM_REG10, 0x1F); + ret |= es8311_write_reg(ES8311_SYSTEM_REG11, 0x7F); + ret |= es8311_write_reg(ES8311_RESET_REG00, 0x80); + /* + * Set Codec into Master or Slave mode + */ + regv = es8311_read_reg(ES8311_RESET_REG00); + /* + * Set master/slave audio interface + */ + audio_hal_codec_i2s_iface_t *i2s_cfg = &(codec_cfg->i2s_iface); + switch (i2s_cfg->mode) { + case AUDIO_HAL_MODE_MASTER: /* MASTER MODE */ + ESP_LOGI(TAG, "ES8311 in Master mode"); + regv |= 0x40; + break; + case AUDIO_HAL_MODE_SLAVE: /* SLAVE MODE */ + ESP_LOGI(TAG, "ES8311 in Slave mode"); + regv &= 0xBF; + break; + default: + regv &= 0xBF; + } + ret |= es8311_write_reg(ES8311_RESET_REG00, regv); + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x3F); + /* + * Select clock source for internal mclk + */ + + int es8311_mclk_src = ES8311_MCLK_SOURCE; + switch (es8311_mclk_src) { + case FROM_MCLK_PIN: + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01); + regv &= 0x7F; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv); + break; + case FROM_SCLK_PIN: + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01); + regv |= 0x80; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv); + break; + default: + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01); + regv &= 0x7F; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv); + break; + } + int sample_fre = 0; + int mclk_fre = 0; + switch (i2s_cfg->samples) { + case AUDIO_HAL_08K_SAMPLES: + sample_fre = 8000; + break; + case AUDIO_HAL_11K_SAMPLES: + sample_fre = 11025; + break; + case AUDIO_HAL_16K_SAMPLES: + sample_fre = 16000; + break; + case AUDIO_HAL_22K_SAMPLES: + sample_fre = 22050; + break; + case AUDIO_HAL_24K_SAMPLES: + sample_fre = 24000; + break; + case AUDIO_HAL_32K_SAMPLES: + sample_fre = 32000; + break; + case AUDIO_HAL_44K_SAMPLES: + sample_fre = 44100; + break; + case AUDIO_HAL_48K_SAMPLES: + sample_fre = 48000; + break; + default: + ESP_LOGE(TAG, "Unable to configure sample rate %dHz", sample_fre); + break; + } + mclk_fre = sample_fre * MCLK_DIV_FRE; + coeff = get_coeff(mclk_fre, sample_fre); + if (coeff < 0) { + ESP_LOGE(TAG, "Unable to configure sample rate %dHz with %dHz MCLK", sample_fre, mclk_fre); + return ESP_FAIL; + } + /* + * Set clock parammeters + */ + if (coeff >= 0) { + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG02) & 0x07; + regv |= (coeff_div[coeff].pre_div - 1) << 5; + datmp = 0; + switch (coeff_div[coeff].pre_multi) { + case 1: + datmp = 0; + break; + case 2: + datmp = 1; + break; + case 4: + datmp = 2; + break; + case 8: + datmp = 3; + break; + default: + break; + } + + if (ES8311_MCLK_SOURCE == FROM_SCLK_PIN) { + datmp = 3; /* DIG_MCLK = LRCK * 256 = BCLK * 8 */ + } + regv |= (datmp) << 3; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, regv); + + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG05) & 0x00; + regv |= (coeff_div[coeff].adc_div - 1) << 4; + regv |= (coeff_div[coeff].dac_div - 1) << 0; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, regv); + + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG03) & 0x80; + regv |= coeff_div[coeff].fs_mode << 6; + regv |= coeff_div[coeff].adc_osr << 0; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, regv); + + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG04) & 0x80; + regv |= coeff_div[coeff].dac_osr << 0; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, regv); + + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG07) & 0xC0; + regv |= coeff_div[coeff].lrck_h << 0; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG07, regv); + + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG08) & 0x00; + regv |= coeff_div[coeff].lrck_l << 0; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG08, regv); + + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06) & 0xE0; + if (coeff_div[coeff].bclk_div < 19) { + regv |= (coeff_div[coeff].bclk_div - 1) << 0; + } else { + regv |= (coeff_div[coeff].bclk_div) << 0; + } + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv); + } + + /* + * mclk inverted or not + */ + if (INVERT_MCLK) { + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01); + regv |= 0x40; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv); + } else { + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01); + regv &= ~(0x40); + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv); + } + /* + * sclk inverted or not + */ + if (INVERT_SCLK) { + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06); + regv |= 0x20; + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv); + } else { + regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06); + regv &= ~(0x20); + ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv); + } + + ret |= es8311_write_reg(ES8311_SYSTEM_REG13, 0x10); + ret |= es8311_write_reg(ES8311_ADC_REG1B, 0x0A); + ret |= es8311_write_reg(ES8311_ADC_REG1C, 0x6A); + + return ESP_OK; +} + +esp_err_t es8311_codec_deinit() +{ + // i2c_bus_delete(i2c_handle); + return ESP_OK; +} + +esp_err_t es8311_config_fmt(es_i2s_fmt_t fmt) +{ + esp_err_t ret = ESP_OK; + uint8_t adc_iface = 0, dac_iface = 0; + dac_iface = es8311_read_reg(ES8311_SDPIN_REG09); + adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A); + switch (fmt) { + case AUDIO_HAL_I2S_NORMAL: + ESP_LOGD(TAG, "ES8311 in I2S Format"); + dac_iface &= 0xFC; + adc_iface &= 0xFC; + break; + case AUDIO_HAL_I2S_LEFT: + case AUDIO_HAL_I2S_RIGHT: + ESP_LOGD(TAG, "ES8311 in LJ Format"); + adc_iface &= 0xFC; + dac_iface &= 0xFC; + adc_iface |= 0x01; + dac_iface |= 0x01; + break; + case AUDIO_HAL_I2S_DSP: + ESP_LOGD(TAG, "ES8311 in DSP-B Format"); + adc_iface &= 0xDC; + dac_iface &= 0xDC; + adc_iface |= 0x23; + dac_iface |= 0x23; + break; + default: + dac_iface &= 0xFC; + adc_iface &= 0xFC; + break; + } + ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface); + ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface); + + return ret; +} + +esp_err_t es8311_set_bits_per_sample(audio_hal_iface_bits_t bits) +{ + esp_err_t ret = ESP_OK; + uint8_t adc_iface = 0, dac_iface = 0; + dac_iface = es8311_read_reg(ES8311_SDPIN_REG09); + adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A); + switch (bits) { + case AUDIO_HAL_BIT_LENGTH_16BITS: + dac_iface |= 0x0c; + adc_iface |= 0x0c; + break; + case AUDIO_HAL_BIT_LENGTH_24BITS: + break; + case AUDIO_HAL_BIT_LENGTH_32BITS: + dac_iface |= 0x10; + adc_iface |= 0x10; + break; + default: + dac_iface |= 0x0c; + adc_iface |= 0x0c; + break; + + } + ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface); + ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface); + + return ret; +} + +esp_err_t es8311_codec_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface) +{ + int ret = ESP_OK; + ret |= es8311_set_bits_per_sample(iface->bits); + ret |= es8311_config_fmt((es_i2s_fmt_t)iface->fmt); + return ret; +} + +esp_err_t es8311_codec_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state) +{ + esp_err_t ret = ESP_OK; + es_module_t es_mode = ES_MODULE_MIN; + + switch (mode) { + case AUDIO_HAL_CODEC_MODE_ENCODE: + es_mode = ES_MODULE_ADC; + break; + case AUDIO_HAL_CODEC_MODE_LINE_IN: + es_mode = ES_MODULE_LINE; + break; + case AUDIO_HAL_CODEC_MODE_DECODE: + es_mode = ES_MODULE_DAC; + break; + case AUDIO_HAL_CODEC_MODE_BOTH: + es_mode = ES_MODULE_ADC_DAC; + break; + default: + es_mode = ES_MODULE_DAC; + ESP_LOGW(TAG, "Codec mode not support, default is decode mode"); + break; + } + + if (ctrl_state == AUDIO_HAL_CTRL_START) { + ret |= es8311_start(es_mode); + } else { + ESP_LOGW(TAG, "The codec is about to stop"); + ret |= es8311_stop(es_mode); + } + + return ret; +} + +esp_err_t es8311_start(es_module_t mode) +{ + esp_err_t ret = ESP_OK; + uint8_t adc_iface = 0, dac_iface = 0; + + dac_iface = es8311_read_reg(ES8311_SDPIN_REG09) & 0xBF; + adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A) & 0xBF; + adc_iface |= BIT(6); + dac_iface |= BIT(6); + + if (mode == ES_MODULE_LINE) { + ESP_LOGE(TAG, "The codec es8311 doesn't support ES_MODULE_LINE mode"); + return ESP_FAIL; + } + if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) { + adc_iface &= ~(BIT(6)); + } + if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) { + dac_iface &= ~(BIT(6)); + } + + ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface); + ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface); + + ret |= es8311_write_reg(ES8311_ADC_REG17, 0xBF); + ret |= es8311_write_reg(ES8311_SYSTEM_REG0E, 0x02); + ret |= es8311_write_reg(ES8311_SYSTEM_REG12, 0x00); + ret |= es8311_write_reg(ES8311_SYSTEM_REG14, 0x1A); + + /* + * pdm dmic enable or disable + */ + int regv = 0; + if (IS_DMIC) { + regv = es8311_read_reg(ES8311_SYSTEM_REG14); + regv |= 0x40; + ret |= es8311_write_reg(ES8311_SYSTEM_REG14, regv); + } else { + regv = es8311_read_reg(ES8311_SYSTEM_REG14); + regv &= ~(0x40); + ret |= es8311_write_reg(ES8311_SYSTEM_REG14, regv); + } + + ret |= es8311_write_reg(ES8311_SYSTEM_REG0D, 0x01); + ret |= es8311_write_reg(ES8311_ADC_REG15, 0x40); + ret |= es8311_write_reg(ES8311_DAC_REG37, 0x48); + ret |= es8311_write_reg(ES8311_GP_REG45, 0x00); + + return ret; +} + +esp_err_t es8311_stop(es_module_t mode) +{ + esp_err_t ret = ESP_OK; + es8311_suspend(); + return ret; +} + +esp_err_t es8311_codec_set_voice_volume(int volume) +{ + esp_err_t res = ESP_OK; + if (volume < 0) { + volume = 0; + } else if (volume > 100) { + volume = 100; + } + int vol = (volume) * 2550 / 1000; + ESP_LOGD(TAG, "SET: volume:%d", vol); + es8311_write_reg(ES8311_DAC_REG32, vol); + return res; +} + +esp_err_t es8311_codec_get_voice_volume(int *volume) +{ + esp_err_t res = ESP_OK; + int regv = 0; + regv = es8311_read_reg(ES8311_DAC_REG32); + if (regv == ESP_FAIL) { + *volume = 0; + res = ESP_FAIL; + } else { + *volume = regv * 100 / 256; + } + ESP_LOGD(TAG, "GET: res:%d, volume:%d", regv, *volume); + return res; +} + +esp_err_t es8311_set_voice_mute(bool enable) +{ + ESP_LOGD(TAG, "Es8311SetVoiceMute volume:%d", enable); + es8311_mute(enable); + return ESP_OK; +} + +esp_err_t es8311_get_voice_mute(int *mute) +{ + esp_err_t res = ESP_OK; + uint8_t reg = 0; + res = es8311_read_reg(ES8311_DAC_REG31); + if (res != ESP_FAIL) { + reg = (res & 0x20) >> 5; + } + *mute = reg; + return res; +} + +esp_err_t es8311_set_mic_gain(es8311_mic_gain_t gain_db) +{ + esp_err_t res = ESP_OK; + res = es8311_write_reg(ES8311_ADC_REG16, gain_db); // MIC gain scale + return res; +} + +void es8311_read_all() +{ + for (int i = 0; i < 0x4A; i++) { + uint8_t reg = es8311_read_reg(i); + ets_printf("REG:%02x, %02x\n", reg, i); + } +} + +esp_err_t es8311_set_channel(int is_right) +{ + uint8_t reg_val = es8311_read_reg(ES8311_SDPIN_REG09); + if (is_right) { + reg_val |= 0b10000000; + } else { + reg_val &= 0b01111111; + } + return es8311_write_reg(ES8311_SDPIN_REG09, reg_val); +} + +#endif diff --git a/lib/lib_audio/es8311/src/es8311.h b/lib/lib_audio/es8311/src/es8311.h new file mode 100644 index 000000000..609357987 --- /dev/null +++ b/lib/lib_audio/es8311/src/es8311.h @@ -0,0 +1,285 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2019 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _ES8311_H +#define _ES8311_H + +#include "audio_hal.h" +#include "esp_types.h" +#include "esxxx_common.h" + + +/* ES8311 address + * 0x32:CE=1;0x30:CE=0 + */ +#define ES8311_ADDR 0x18 + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ES8311_REGISTER NAME_REG_REGISTER ADDRESS + */ +#define ES8311_RESET_REG00 0x00 /*reset digital,csm,clock manager etc.*/ + +/* + * Clock Scheme Register definition + */ +#define ES8311_CLK_MANAGER_REG01 0x01 /* select clk src for mclk, enable clock for codec */ +#define ES8311_CLK_MANAGER_REG02 0x02 /* clk divider and clk multiplier */ +#define ES8311_CLK_MANAGER_REG03 0x03 /* adc fsmode and osr */ +#define ES8311_CLK_MANAGER_REG04 0x04 /* dac osr */ +#define ES8311_CLK_MANAGER_REG05 0x05 /* clk divier for adc and dac */ +#define ES8311_CLK_MANAGER_REG06 0x06 /* bclk inverter and divider */ +#define ES8311_CLK_MANAGER_REG07 0x07 /* tri-state, lrck divider */ +#define ES8311_CLK_MANAGER_REG08 0x08 /* lrck divider */ +/* + * SDP + */ +#define ES8311_SDPIN_REG09 0x09 /* dac serial digital port */ +#define ES8311_SDPOUT_REG0A 0x0A /* adc serial digital port */ +/* + * SYSTEM + */ +#define ES8311_SYSTEM_REG0B 0x0B /* system */ +#define ES8311_SYSTEM_REG0C 0x0C /* system */ +#define ES8311_SYSTEM_REG0D 0x0D /* system, power up/down */ +#define ES8311_SYSTEM_REG0E 0x0E /* system, power up/down */ +#define ES8311_SYSTEM_REG0F 0x0F /* system, low power */ +#define ES8311_SYSTEM_REG10 0x10 /* system */ +#define ES8311_SYSTEM_REG11 0x11 /* system */ +#define ES8311_SYSTEM_REG12 0x12 /* system, Enable DAC */ +#define ES8311_SYSTEM_REG13 0x13 /* system */ +#define ES8311_SYSTEM_REG14 0x14 /* system, select DMIC, select analog pga gain */ +/* + * ADC + */ +#define ES8311_ADC_REG15 0x15 /* ADC, adc ramp rate, dmic sense */ +#define ES8311_ADC_REG16 0x16 /* ADC */ +#define ES8311_ADC_REG17 0x17 /* ADC, volume */ +#define ES8311_ADC_REG18 0x18 /* ADC, alc enable and winsize */ +#define ES8311_ADC_REG19 0x19 /* ADC, alc maxlevel */ +#define ES8311_ADC_REG1A 0x1A /* ADC, alc automute */ +#define ES8311_ADC_REG1B 0x1B /* ADC, alc automute, adc hpf s1 */ +#define ES8311_ADC_REG1C 0x1C /* ADC, equalizer, hpf s2 */ +/* + * DAC + */ +#define ES8311_DAC_REG31 0x31 /* DAC, mute */ +#define ES8311_DAC_REG32 0x32 /* DAC, volume */ +#define ES8311_DAC_REG33 0x33 /* DAC, offset */ +#define ES8311_DAC_REG34 0x34 /* DAC, drc enable, drc winsize */ +#define ES8311_DAC_REG35 0x35 /* DAC, drc maxlevel, minilevel */ +#define ES8311_DAC_REG37 0x37 /* DAC, ramprate */ +/* + *GPIO + */ +#define ES8311_GPIO_REG44 0x44 /* GPIO, dac2adc for test */ +#define ES8311_GP_REG45 0x45 /* GP CONTROL */ +/* + * CHIP + */ +#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */ +#define ES8311_CHD2_REGFE 0xFE /* CHIP ID2 */ +#define ES8311_CHVER_REGFF 0xFF /* VERSION */ +#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */ + +#define ES8311_MAX_REGISTER 0xFF + +typedef enum { + ES8311_MIC_GAIN_MIN = -1, + ES8311_MIC_GAIN_0DB, + ES8311_MIC_GAIN_6DB, + ES8311_MIC_GAIN_12DB, + ES8311_MIC_GAIN_18DB, + ES8311_MIC_GAIN_24DB, + ES8311_MIC_GAIN_30DB, + ES8311_MIC_GAIN_36DB, + ES8311_MIC_GAIN_42DB, + ES8311_MIC_GAIN_MAX +} es8311_mic_gain_t; + +/* + * @brief Initialize ES8311 codec chip + * + * @param codec_cfg configuration of ES8311 + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es8311_codec_init(TwoWire *tw, audio_hal_codec_config_t *codec_cfg); + +/** + * @brief Deinitialize ES8311 codec chip + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es8311_codec_deinit(void); + +/** + * @brief Control ES8311 codec chip + * + * @param mode codec mode + * @param ctrl_state start or stop decode or encode progress + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t es8311_codec_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state); + +/** + * @brief Configure ES8311 codec mode and I2S interface + * + * @param mode codec mode + * @param iface I2S config + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t es8311_codec_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface); + +/** + * @brief Configure ES8311 DAC mute or not. Basically you can use this function to mute the output or unmute + * + * @param enable enable(1) or disable(0) + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t es8311_set_voice_mute(bool enable); + +/** + * @brief Set voice volume + * + * @param volume: voice volume (0~100) + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es8311_codec_set_voice_volume(int volume); + +/** + * @brief Get voice volume + * + * @param[out] *volume: voice volume (0~100) + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es8311_codec_get_voice_volume(int *volume); + +/** + * @brief Configure ES8311 I2S format + * + * @param cfg: ES8388 I2S format + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es8311_config_fmt(es_i2s_fmt_t fmt); + +/** + * @brief Configure ES8311 data sample bits + * + * @param bit_per_sample: bit number of per sample + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es8311_set_bits_per_sample(audio_hal_iface_bits_t bits); + +/** + * @brief Start ES8311 codec chip + * + * @param mode: set ADC or DAC or both + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es8311_start(es_module_t mode); + +/** + * @brief Stop ES8311 codec chip + * + * @param mode: set ADC or DAC or both + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t es8311_stop(es_module_t mode); + +/** + * @brief Get ES8311 DAC mute status + * + * @return + * - ESP_FAIL + * - ESP_OK + */ +esp_err_t es8311_get_voice_mute(int *mute); + +/** + * @brief Set ES8311 mic gain + * + * @param gain db of mic gain + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t es8311_set_mic_gain(es8311_mic_gain_t gain_db); + +/** + * @brief Print all ES8311 registers + * + * @return + * - void + */ +void es8311_read_all(); + +/** + * @brief + * + * @param is_right + * @return esp_err_t + */ +esp_err_t es8311_set_channel(int is_right); + +#ifdef __cplusplus +} +#endif + +#endif From 7d9c51fb796e9951a197902f9162e761b1920c85 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 11 Jul 2022 09:13:49 +0200 Subject: [PATCH 3/4] audio i2s pins --- tasmota/language/af_AF.h | 9 ++++++++- tasmota/language/bg_BG.h | 8 +++++++- tasmota/language/cs_CZ.h | 8 +++++++- tasmota/language/de_DE.h | 9 ++++++++- tasmota/language/el_GR.h | 9 ++++++++- tasmota/language/en_GB.h | 6 ++++++ tasmota/language/es_ES.h | 8 +++++++- tasmota/language/fr_FR.h | 8 +++++++- tasmota/language/fy_NL.h | 8 +++++++- tasmota/language/he_HE.h | 8 +++++++- tasmota/language/hu_HU.h | 6 ++++++ tasmota/language/it_IT.h | 6 ++++++ tasmota/language/ko_KO.h | 8 +++++++- tasmota/language/nl_NL.h | 8 +++++++- tasmota/language/pl_PL.h | 8 +++++++- tasmota/language/pt_BR.h | 8 +++++++- tasmota/language/pt_PT.h | 8 +++++++- tasmota/language/ro_RO.h | 8 +++++++- tasmota/language/ru_RU.h | 8 +++++++- tasmota/language/sk_SK.h | 8 +++++++- tasmota/language/sv_SE.h | 8 +++++++- tasmota/language/tr_TR.h | 8 +++++++- tasmota/language/uk_UA.h | 8 +++++++- tasmota/language/vi_VN.h | 8 +++++++- tasmota/language/zh_CN.h | 8 +++++++- tasmota/language/zh_TW.h | 8 +++++++- 26 files changed, 182 insertions(+), 23 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 61e9e5c99..6ca9d320f 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -878,10 +878,17 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" + +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 091ef3fe5..a8efc271b 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 5eb89c9a4..c8ef289b2 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 7e574e0c8..70b3334df 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -878,10 +878,17 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" + +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 9bb00cc63..e72267baf 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -878,10 +878,17 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" + +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 958819a01..7994e2137 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -882,6 +882,12 @@ #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 3ff22557d..db311000e 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 7abc864ba..83c8cca0c 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index c155bffa9..3d0ff7549 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 96cf98eb5..6e9b40ffe 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 0d5ddbca8..73d0fed27 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -882,6 +882,12 @@ #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 6a4ecb8c8..6eb0c85df 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -882,6 +882,12 @@ #define D_SENSOR_CM11_RX "CM110x - RX" #define D_SENSOR_FLOWRATEMETER "Portata" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 091c530e5..e4301665f 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index bd5dcceb8..058cf32a4 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 59c3059c8..080b3d14f 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 11ebd3d13..ef3b038bb 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 1da1f2e27..70fd6b7d3 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index b1921be4b..8adb8cfa0 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index d042e83f5..b141139de 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "А" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 10e5aaacf..632b6d939 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 1b7a985ee..6e98dee29 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 1127a96c4..3c081de22 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 7d9fc0bc5..6a28205fe 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "А" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 1116e810b..55d5362ab 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 751959218..7ad9dd77d 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "A" #define D_UNIT_CELSIUS "C" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 5945993e8..d6bd3ba8f 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -878,10 +878,16 @@ #define D_GPIO_SHIFT595_RCLK "74x595 RCLK" #define D_GPIO_SHIFT595_OE "74x595 OE" #define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_TX "CM110x TX" #define D_SENSOR_CM11_RX "CM110x RX" #define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_I2S_MCLK "I2S_MCLK" +#define D_SENSOR_I2S_BCLK "I2S_BCLK" +#define D_SENSOR_I2S_WS "I2S_WS" +#define D_SENSOR_I2S_DIN "I2S_DIN" +#define D_SENSOR_I2S_DOUT "I2S_DOUT" + // Units #define D_UNIT_AMPERE "安培" #define D_UNIT_CELSIUS "C" From 11c72a985f2b91a0545e6916bcc0c706d01fe370 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 11 Jul 2022 09:18:27 +0200 Subject: [PATCH 4/4] i2s audio pins --- tasmota/include/tasmota_template.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 58954bd07..6919a1a72 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -193,6 +193,7 @@ enum UserSelectablePins { GPIO_MP3_DFR562_BUSY, // RB-DFR-562, DFPlayer Mini MP3 Player busy flag GPIO_TM1621_CS, GPIO_TM1621_WR, GPIO_TM1621_RD, GPIO_TM1621_DAT, // Sonoff POWR3xxD and THR3xxD LCD display GPIO_REL1_BI, GPIO_REL1_BI_INV, // 8 x Relays bistable + GPIO_I2S_MCLK, GPIO_I2S_BCLK, GPIO_I2S_WS, GPIO_I2S_DIN, GPIO_I2S_DOUT, GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage @@ -433,6 +434,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DFR562_BUSY "|" D_GPIO_TM1621_CS "|" D_GPIO_TM1621_WR "|" D_GPIO_TM1621_RD "|" D_GPIO_TM1621_DAT "|" D_SENSOR_RELAY "_b|" D_SENSOR_RELAY "_bi|" + D_SENSOR_I2S_MCLK "|" D_SENSOR_I2S_BCLK "|" D_SENSOR_I2S_WS "|" D_SENSOR_I2S_DIN "|" D_SENSOR_I2S_DOUT "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -527,6 +529,14 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_I2S_IN_SLCT) + MAX_I2S, // I2C In Word Select #endif +#ifdef USE_I2S_AUDIO + AGPIO(GPIO_I2S_MCLK) + MAX_I2S, // I2S master clock + AGPIO(GPIO_I2S_BCLK) + MAX_I2S, // I2S bit clock + AGPIO(GPIO_I2S_WS) + MAX_I2S, // I2S word select + AGPIO(GPIO_I2S_DIN) + MAX_I2S, // I2S IN Data + AGPIO(GPIO_I2S_DOUT) + MAX_I2S, // I2S Out Data +#endif + #ifdef USE_SPI AGPIO(GPIO_SPI_MISO) + MAX_SPI, // SPI MISO AGPIO(GPIO_SPI_MOSI) + MAX_SPI, // SPI MOSI