From 62e8cef13f722945ef4e0ed78f0a69052742153c Mon Sep 17 00:00:00 2001 From: frankie Date: Sat, 2 Jun 2018 10:55:15 +0800 Subject: [PATCH 1/5] rm idf --- .gitmodules | 3 --- esp-idf | 1 - 2 files changed, 4 deletions(-) delete mode 160000 esp-idf diff --git a/.gitmodules b/.gitmodules index 9a69a3110..9f95e53e5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "esp-idf"] - path = esp-idf - url = https://github.com/espressif/esp-idf [submodule "components/esp-adf-libs"] path = components/esp-adf-libs url = https://github.com/espressif/esp-adf-libs diff --git a/esp-idf b/esp-idf deleted file mode 160000 index 489e98cfb..000000000 --- a/esp-idf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 489e98cfb77e6fb98a2ed04edc3c775241cdcf6f From a21984af2269998e507180ce34c5573766cefecb Mon Sep 17 00:00:00 2001 From: frankie Date: Sun, 3 Jun 2018 18:16:50 +0800 Subject: [PATCH 2/5] add wm8978 template --- components/audio_hal/Kconfig.projbuild | 2 + components/audio_hal/audio_hal.c | 1 + components/audio_hal/board/board.h | 4 ++ components/audio_hal/board/we_lin_board.h | 60 +++++++++++++++++++++ components/audio_hal/component.mk | 10 +++- components/audio_hal/driver/wm8978/wm8978.c | 0 components/audio_hal/driver/wm8978/wm8978.h | 0 7 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 components/audio_hal/board/we_lin_board.h create mode 100644 components/audio_hal/driver/wm8978/wm8978.c create mode 100644 components/audio_hal/driver/wm8978/wm8978.h diff --git a/components/audio_hal/Kconfig.projbuild b/components/audio_hal/Kconfig.projbuild index 49eb50a25..bf19d81ad 100644 --- a/components/audio_hal/Kconfig.projbuild +++ b/components/audio_hal/Kconfig.projbuild @@ -8,4 +8,6 @@ config ESP_LYRAT_V4_3_BOARD bool "ESP32-Lyrat V4.3" config ESP_LYRAT_V4_2_BOARD bool "ESP32-Lyrat V4.2" +config WHYENGINEER_LIN_BOARD + bool "WhyEngineer Lin Audio board" endchoice diff --git a/components/audio_hal/audio_hal.c b/components/audio_hal/audio_hal.c index 824d24365..1fba6377a 100755 --- a/components/audio_hal/audio_hal.c +++ b/components/audio_hal/audio_hal.c @@ -31,6 +31,7 @@ #include "audio_mutex.h" #include "es8374.h" #include "es8388.h" +#include "wm8978.h" static const char *TAG = "AUDIO_HAL"; diff --git a/components/audio_hal/board/board.h b/components/audio_hal/board/board.h index 72e29e746..03a9a9ec5 100644 --- a/components/audio_hal/board/board.h +++ b/components/audio_hal/board/board.h @@ -39,6 +39,10 @@ extern "C" { #include "lyrat_v4_2_board.h" #endif +#ifdef CONFIG_WHYENGINEER_LIN_BOARD +#include "we_lin_board.h" +#endif + #ifdef __cplusplus } diff --git a/components/audio_hal/board/we_lin_board.h b/components/audio_hal/board/we_lin_board.h new file mode 100644 index 000000000..ee1d2284a --- /dev/null +++ b/components/audio_hal/board/we_lin_board.h @@ -0,0 +1,60 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2018 + * + * 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 _WHYENGINEER_BOARD_H_ +#define _WHYENGINEER_BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_CARD_OPEN_FILE_NUM_MAX 5 + +#define IIC_DATA 19 +#define IIC_CLK 28 + + +/* I2S gpios */ +#define IIS_SCLK 33 +#define IIS_LCLK 25 +#define IIS_DSIN 27 +#define IIS_DOUT 26 + + +#define LED_R 5 +#define LED_G 21 +#define LED_B 22 + +#define KEY_1 34 +#define KEY_2 35 +#define KEY_3 32 + +#define SD_CD 23 + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/audio_hal/component.mk b/components/audio_hal/component.mk index a5aecfcd1..b2d545975 100755 --- a/components/audio_hal/component.mk +++ b/components/audio_hal/component.mk @@ -4,6 +4,12 @@ # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) -COMPONENT_ADD_INCLUDEDIRS := ./include ./driver/es8388 ./board ./driver/es8374 +COMPONENT_ADD_INCLUDEDIRS := ./include ./driver/es8388 ./board ./driver/es8374 ./driver/wm8978 + +ifdef CONFIG_WHYENGINEER_LIN_BOARD +COMPONENT_SRCDIRS := . ./driver/wm8978 +else +COMPONENT_SRCDIRS := . ./driver/es8388 ./board ./driver/es8374 +endif + -COMPONENT_SRCDIRS := . ./driver/es8388 ./board ./driver/es8374 diff --git a/components/audio_hal/driver/wm8978/wm8978.c b/components/audio_hal/driver/wm8978/wm8978.c new file mode 100644 index 000000000..e69de29bb diff --git a/components/audio_hal/driver/wm8978/wm8978.h b/components/audio_hal/driver/wm8978/wm8978.h new file mode 100644 index 000000000..e69de29bb From 41526bd506936cd301eeabed147875064cd72991 Mon Sep 17 00:00:00 2001 From: frankie Date: Thu, 14 Jun 2018 15:33:58 +0800 Subject: [PATCH 3/5] add wm8978 need to test --- components/audio_hal/audio_hal.c | 14 + components/audio_hal/board/we_lin_board.h | 4 +- components/audio_hal/component.mk | 4 +- components/audio_hal/driver/wm8978/wm8978.c | 827 ++++++++++++++++++++ components/audio_hal/driver/wm8978/wm8978.h | 109 +++ components/audio_hal/include/audio_hal.h | 13 + 6 files changed, 968 insertions(+), 3 deletions(-) diff --git a/components/audio_hal/audio_hal.c b/components/audio_hal/audio_hal.c index 1fba6377a..1505ac83e 100755 --- a/components/audio_hal/audio_hal.c +++ b/components/audio_hal/audio_hal.c @@ -53,6 +53,7 @@ struct audio_hal { }; static struct audio_hal audio_hal_codecs_default[] = { +#if (defined CONFIG_ESP_LYRAT_V4_3_BOARD) ||(defined CONFIG_ESP_LYRAT_V4_2_BOARD) { .audio_codec_initialize = es8388_init, .audio_codec_deinitialize = es8388_deinit, @@ -68,7 +69,18 @@ static struct audio_hal audio_hal_codecs_default[] = { .audio_codec_config_iface = es8374_config_i2s, .audio_codec_set_volume = es8374_set_voice_volume, .audio_codec_get_volume = es8374_get_voice_volume, + }, +#endif +#ifdef CONFIG_WHYENGINEER_LIN_BOARD + { + .audio_codec_initialize =wm8978_init, + .audio_codec_deinitialize=wm8978_deinit, + .audio_codec_ctrl=wm8978_ctrl_state, + .audio_codec_config_iface=wm8978_config_i2s, + .audio_codec_set_volume=wm8978_set_voice_volume, + .audio_codec_get_volume=wm8978_get_voice_volume, } +#endif }; audio_hal_handle_t audio_hal_init(audio_hal_codec_config_t* audio_hal_conf, int index) @@ -94,7 +106,9 @@ audio_hal_handle_t audio_hal_init(audio_hal_codec_config_t* audio_hal_conf, int audio_hal->handle = audio_hal; audio_hal_codecs_default[index].handle = audio_hal; mutex_unlock(audio_hal->audio_hal_lock); +#if (defined CONFIG_ESP_LYRAT_V4_3_BOARD) ||(defined CONFIG_ESP_LYRAT_V4_2_BOARD) es8388_pa_power(true); +#endif return audio_hal; } diff --git a/components/audio_hal/board/we_lin_board.h b/components/audio_hal/board/we_lin_board.h index ee1d2284a..8b48aa05a 100644 --- a/components/audio_hal/board/we_lin_board.h +++ b/components/audio_hal/board/we_lin_board.h @@ -31,6 +31,7 @@ extern "C" { #define SD_CARD_OPEN_FILE_NUM_MAX 5 +#define IIC_PORT 0 #define IIC_DATA 19 #define IIC_CLK 28 @@ -50,7 +51,8 @@ extern "C" { #define KEY_2 35 #define KEY_3 32 -#define SD_CD 23 +#define SD_CARD_INTR_GPIO 23 +#define SD_CARD_INTR_SEL 23 #ifdef __cplusplus diff --git a/components/audio_hal/component.mk b/components/audio_hal/component.mk index b2d545975..5407464f8 100755 --- a/components/audio_hal/component.mk +++ b/components/audio_hal/component.mk @@ -6,10 +6,10 @@ COMPONENT_ADD_INCLUDEDIRS := ./include ./driver/es8388 ./board ./driver/es8374 ./driver/wm8978 + +#COMPONENT_SRCDIRS :=. ./driver/es8388 ./board ./driver/es8374 ./driver/wm8978 ifdef CONFIG_WHYENGINEER_LIN_BOARD COMPONENT_SRCDIRS := . ./driver/wm8978 else COMPONENT_SRCDIRS := . ./driver/es8388 ./board ./driver/es8374 endif - - diff --git a/components/audio_hal/driver/wm8978/wm8978.c b/components/audio_hal/driver/wm8978/wm8978.c index e69de29bb..a4b430bac 100644 --- a/components/audio_hal/driver/wm8978/wm8978.c +++ b/components/audio_hal/driver/wm8978/wm8978.c @@ -0,0 +1,827 @@ + +#include +#include "esp_log.h" +#include "driver/i2c.h" +#include "driver/i2s.h" +#include "wm8978.h" +#include "board.h" + + +#define bit0 0x001 +#define bit1 0x002 +#define bit2 0x004 +#define bit3 0x008 +#define bit4 0x010 +#define bit5 0x020 +#define bit6 0x040 +#define bit7 0x080 +#define bit8 0x100 + + +#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ +#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ +#define ACK_VAL 0x0 /*!< I2C ack value */ +#define NACK_VAL 0x1 /*!< I2C nack value */ + +static const char *ES_TAG = "WM8978_DRIVER"; + +#define WM8978_ADDR 0X1A + +#define ES_ASSERT(a, format, b, ...) \ + if ((a) != 0) { \ + ESP_LOGE(ES_TAG, format, ##__VA_ARGS__); \ + return b;\ + } + + +static uint16_t WM8978_REGVAL_TBL[58]= +{ + 0X0000,0X0000,0X0000,0X0000,0X0050,0X0000,0X0140,0X0000, + 0X0000,0X0000,0X0000,0X00FF,0X00FF,0X0000,0X0100,0X00FF, + 0X00FF,0X0000,0X012C,0X002C,0X002C,0X002C,0X002C,0X0000, + 0X0032,0X0000,0X0000,0X0000,0X0000,0X0000,0X0000,0X0000, + 0X0038,0X000B,0X0032,0X0000,0X0008,0X000C,0X0093,0X00E9, + 0X0000,0X0000,0X0000,0X0000,0X0003,0X0010,0X0010,0X0100, + 0X0100,0X0002,0X0001,0X0001,0X0039,0X0039,0X0039,0X0039, + 0X0001,0X0001 +}; + + +static const i2c_config_t es_i2c_cfg = { + .mode = I2C_MODE_MASTER, + .sda_io_num = IIC_DATA, + .scl_io_num = IIC_CLK, + .sda_pullup_en = GPIO_PULLUP_DISABLE, + .scl_pullup_en = GPIO_PULLUP_DISABLE, + .master.clk_speed = 400000 +}; +static inline esp_err_t _i2c_master_mem_write(i2c_port_t i2c_num, uint8_t DevAddr,uint8_t MemAddr,uint8_t* data_wr, size_t size) +{ + if (size == 0) { + return ESP_OK; + } + i2c_cmd_handle_t cmd = i2c_cmd_link_create();//a cmd list + i2c_master_start(cmd); + i2c_master_write_byte(cmd, ( DevAddr << 1 ) | I2C_MASTER_WRITE, ACK_CHECK_EN); + i2c_master_write_byte(cmd, MemAddr, ACK_CHECK_EN); + i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + + return ret; +} +static int _wm8978_write_reg(uint8_t reg, uint16_t val) +{ + int res = 0; + uint8_t buf[2]; + buf[0]=((val&0x0100)>>8)|(reg<<1); + buf[1]=(uint8_t)(val&0xff); + res=(int)_i2c_master_mem_write(IIC_PORT,WM8978_ADDR,buf[0],buf+1,1); + ES_ASSERT(res, "es_write_reg error", -1); + return res; +} +static int wm8978_write_reg(uint8_t index){ + return _wm8978_write_reg(index,WM8978_REGVAL_TBL[index]); +} + +static int wm8978_read_reg(uint8_t reg_add, uint16_t *pData) +{ + *pData = WM8978_REGVAL_TBL[reg_add]; + return 0; +} + +static int i2c_init() +{ + int res; + res = i2c_param_config(IIC_PORT, &es_i2c_cfg); + res |= i2c_driver_install(IIC_PORT, es_i2c_cfg.mode, 0, 0, 0); + ES_ASSERT(res, "i2c_init error", -1); + return res; +} + +void wm8978_read_all() +{ + for (int i = 0; i < 58; i++) { + uint16_t reg = 0; + wm8978_read_reg(i, ®); + ets_printf("0x%x: 0x%x\n", i, reg); + } +} + + +/******** input signal path **********/ + + +static int wm8978_pga_enable(bool right,bool left){ + WM8978_REGVAL_TBL[2]&=~bit2; + WM8978_REGVAL_TBL[2]&=~bit3; + if(right) + WM8978_REGVAL_TBL[2]|=bit3; + if(left) + WM8978_REGVAL_TBL[2]|=bit2; + return wm8978_write_reg(2); +} +//const,not need to change +//do nothing +//the default value is ok +//mic is in different mode +//L2 and R2 not connect to PGA +static int wm8978_input_pga_ctrl(){ + return wm8978_write_reg(44); +} +int wm8978_pga_mute(bool right,bool left){ + int res=0; + if(right){ + WM8978_REGVAL_TBL[46]|=bit6; + }else{ + WM8978_REGVAL_TBL[46]&=~bit6; + } + res|=wm8978_write_reg(46); + if(left){ + WM8978_REGVAL_TBL[45]|=bit6; + }else{ + WM8978_REGVAL_TBL[45]&=!bit6; + } + res|=wm8978_write_reg(45); + return res; +} +/* +* step is :0.75db +* range -12db~+35.25db +* input is mDB: 1db=1000mdb +*/ +int wm8978_pga_vol(int right_mdb,int left_mdb){ + int rmdb,lmdb; + int res=0; + if(right_mdb>35250) + rmdb=35250; + if(left_mdb>35250) + lmdb=35250; + if(right_mdb<-12000) + rmdb=12000; + if(left_mdb<-12000) + lmdb=12000; + rmdb+=12000; + lmdb+=12000; + uint16_t r_value=rmdb/750; + uint16_t l_value=lmdb/750; + WM8978_REGVAL_TBL[45]&=0x0c0; + WM8978_REGVAL_TBL[46]&=0x0c0; + WM8978_REGVAL_TBL[45]|=r_value|bit6; //open zero cross + WM8978_REGVAL_TBL[46]|=l_value|bit6; //open zero cross + res|=wm8978_write_reg(45); + res|=wm8978_write_reg(46); + //write teh update bit + WM8978_REGVAL_TBL[45]|=bit8; + WM8978_REGVAL_TBL[46]|=bit8; + res|=wm8978_write_reg(46); + res|=wm8978_write_reg(45); + return res; +} +//open alc +static int wm8978_alc_enable(){ + WM8978_REGVAL_TBL[32]|=bit7|bit8; + return wm8978_write_reg(32); +} + +//auxl and auxr input +static int wm8978_input_boost_enable(bool re,bool le){ + int res =0; + if(re){ + WM8978_REGVAL_TBL[48]|=bit8; + }else{ + WM8978_REGVAL_TBL[48]&=~bit8; + } + res|=wm8978_write_reg(48); + if(le){ + WM8978_REGVAL_TBL[47]|=bit8; + }else{ + WM8978_REGVAL_TBL[47]&=~bit8; + } + res|=wm8978_write_reg(47); + return res; +} +/* +* aul left and l2 control +* auxl_db:-12db~6db step:3db +* l2_db:-12db~0 db step:3db +* if the input is -0xff, disconnect the line +*/ +int wm8978_auxl_l2(int auxl_db,int l2_db){ + if(auxl_db==-0xff) + auxl_db=0; + if(l2_db==-0xff) + l2_db=0; + if(auxl_db>6) + auxl_db=6; + if(auxl_db<-12) + auxl_db=-12; + if(l2_db>6) + l2_db=6; + if(l2_db<-12) + l2_db=12; + l2_db+=12; + auxl_db+=12; + l2_db/=3; + auxl_db/=3; + WM8978_REGVAL_TBL[47]&=0x188; + WM8978_REGVAL_TBL[47]|=(l2_db<<4); + WM8978_REGVAL_TBL[47]|=auxl_db; + return wm8978_write_reg(47); +} +/* +* aul right and r2 control +* auxl_db:-12db~6db step:3db +* l2_db:-12db~0 db step:3db +* if the input is -0xff, disconnect the line +*/ +int wm8978_auxr_r2(int auxr_db,int r2_db){ + if(auxr_db==-0xff) + auxr_db=0; + if(r2_db==-0xff) + r2_db=0; + if(auxr_db>6) + auxr_db=6; + if(auxr_db<-12) + auxr_db=-12; + if(r2_db>6) + r2_db=6; + if(r2_db<-12) + r2_db=12; + r2_db+=12; + auxr_db+=12; + r2_db/=3; + auxr_db/=3; + WM8978_REGVAL_TBL[48]&=0x188; + WM8978_REGVAL_TBL[48]|=(r2_db<<4); + WM8978_REGVAL_TBL[48]|=auxr_db; + return wm8978_write_reg(48); +} +/* +*rvmdb,lvmdb +*-127db~0db +* -127000~0 +* step 500mdb +*/ +int wm8978_adc_vol(int rvmdb,int lvmdb){ + int res=0; + + if(rvmdb<-127000) + rvmdb=-127500; + if(rvmdb>0) + rvmdb=0; + rvmdb+=127500; + rvmdb/=500; + WM8978_REGVAL_TBL[16]=rvmdb; + res|=wm8978_write_reg(16); + WM8978_REGVAL_TBL[16]|=bit8; + res|=wm8978_write_reg(16); + + if(lvmdb<-127000) + lvmdb=-127500; + if(lvmdb>0) + lvmdb=0; + lvmdb+=127500; + lvmdb/=500; + WM8978_REGVAL_TBL[15]=lvmdb; + res|=wm8978_write_reg(15); + WM8978_REGVAL_TBL[15]|=bit8; + res|=wm8978_write_reg(15); + + return res; +} +/******** output signal path **********/ +int wm8978_dac_both_mute(bool enable){ + if(enable){ + WM8978_REGVAL_TBL[10]|=bit6; + }else{ + WM8978_REGVAL_TBL[10]&=~bit6; + } + return wm8978_write_reg(10); +} +/* +*rvmdb,lvmdb +*-127db~0db +* -127000~0 +* step 500mdb +*/ +int wm8978_dac_vol(int rvmdb,int lvmdb){ + int res=0; + + if(rvmdb<-127000) + rvmdb=-127500; + if(rvmdb>0) + rvmdb=0; + rvmdb+=127500; + rvmdb/=500; + WM8978_REGVAL_TBL[12]=rvmdb; + res|=wm8978_write_reg(12); + WM8978_REGVAL_TBL[12]|=bit8; + res|=wm8978_write_reg(12); + + if(lvmdb<-127000) + lvmdb=-127500; + if(lvmdb>0) + lvmdb=0; + lvmdb+=127500; + lvmdb/=500; + WM8978_REGVAL_TBL[11]=lvmdb; + res|=wm8978_write_reg(11); + WM8978_REGVAL_TBL[11]|=bit8; + res|=wm8978_write_reg(11); + + return res; +} +//enable zero cross +static int wm8978_out1_cfg(){ + int res=0; + WM8978_REGVAL_TBL[52]|=bit7; + WM8978_REGVAL_TBL[53]|=bit7; + res|=wm8978_write_reg(52); + res|=wm8978_write_reg(53); + return res; +} +/* +* -57db~+6db +*/ +int wm8978_out1_vol(int rdb,int ldb){ + int res=0; + if(rdb<-57) + rdb=-57; + if(rdb>6) + rdb=6; + rdb+=57; + WM8978_REGVAL_TBL[53]&=0xc0; + WM8978_REGVAL_TBL[53]|=rdb; + res|=wm8978_write_reg(53); + WM8978_REGVAL_TBL[53]|=bit8; + res|=wm8978_write_reg(53); + + if(ldb<-57) + ldb=-57; + if(ldb>6) + ldb=6; + ldb+=57; + WM8978_REGVAL_TBL[52]&=0xc0; + WM8978_REGVAL_TBL[52]|=ldb; + res|=wm8978_write_reg(52); + WM8978_REGVAL_TBL[52]|=bit8; + res|=wm8978_write_reg(52); + + return res; +} +int wm8978_out1_mute(bool right,bool left){ + int res=0; + WM8978_REGVAL_TBL[53]&=~bit8; + if(right) + WM8978_REGVAL_TBL[53]|=bit6; + else + WM8978_REGVAL_TBL[53]&=~bit6; + res|=wm8978_write_reg(53); + + WM8978_REGVAL_TBL[52]&=~bit8; + if(left) + WM8978_REGVAL_TBL[52]|=bit6; + else + WM8978_REGVAL_TBL[52]&=~bit6; + res|=wm8978_write_reg(52); + + return res; +} +//enable zero cross +//DC=1.5*AVDD/2 +static int wm8978_out2_cfg(){ + int res=0; + WM8978_REGVAL_TBL[54]|=bit7; + WM8978_REGVAL_TBL[55]|=bit7; + res|=wm8978_write_reg(54); + res|=wm8978_write_reg(55); + + WM8978_REGVAL_TBL[1]|=bit8; + res|=wm8978_write_reg(1); + WM8978_REGVAL_TBL[49]|=bit2; + res|=wm8978_write_reg(49); + return res; +} +/* +* -57db~+6db +*/ +int wm8978_out2_vol(int rdb,int ldb){ + int res=0; + if(rdb<-57) + rdb=-57; + if(rdb>6) + rdb=6; + rdb+=57; + WM8978_REGVAL_TBL[55]&=0xc0; + WM8978_REGVAL_TBL[55]|=rdb; + res|=wm8978_write_reg(55); + WM8978_REGVAL_TBL[55]|=bit8; + res|=wm8978_write_reg(55); + + if(ldb<-57) + ldb=-57; + if(ldb>6) + ldb=6; + ldb+=57; + WM8978_REGVAL_TBL[54]&=0xc0; + WM8978_REGVAL_TBL[54]|=ldb; + res|=wm8978_write_reg(54); + WM8978_REGVAL_TBL[54]|=bit8; + res|=wm8978_write_reg(54); + + return res; +} +int wm8978_out2_mute(bool right,bool left){ + int res=0; + WM8978_REGVAL_TBL[55]&=~bit8; + if(right) + WM8978_REGVAL_TBL[55]|=bit6; + else + WM8978_REGVAL_TBL[55]&=~bit6; + res|=wm8978_write_reg(55); + + WM8978_REGVAL_TBL[54]&=~bit8; + if(left) + WM8978_REGVAL_TBL[54]|=bit6; + else + WM8978_REGVAL_TBL[54]&=~bit6; + res|=wm8978_write_reg(54); + + return res; +} +static int wm8978_out34_cfg(){ + int res=0; + WM8978_REGVAL_TBL[49]|=bit3|bit4; + res|=wm8978_write_reg(49); + WM8978_REGVAL_TBL[1]|=bit8; + res|=wm8978_write_reg(1); + + return res; +} + +/******** EQ control **********/ + +/* +mode:1 dac 0:adc +*/ + +int wm8978_eq_mode(uint8_t mode){ + if(mode){ + WM8978_REGVAL_TBL[18]|=bit8; + }else{ + WM8978_REGVAL_TBL[18]&=~bit8; + } + return wm8978_write_reg(18); +} + +/* +* eq_a length :5 +* gain:-12db~+12db + eq1:80,105,135,175 + eq2:230,300,385,500 + eq3:650,850,1100,1400 + eq4:1800,2400,3200,4100 + eq5:5300,6900,9000,11700 +*/ +int wm8978_eq_ctrl(eq_t* eq_a){ + int res=0; + for(int i=0;i<5;i++){ + eq_a[i].gain=12-eq_a[i].gain; + WM8978_REGVAL_TBL[18+i]=(eq_a[i].gain)|(eq_a[i].freq<<5); + res|=wm8978_write_reg(18+i); + } + return res; +} +int wm8978_loopback(bool enable){ + if(enable){ + WM8978_REGVAL_TBL[5]|=bit0; + }else{ + WM8978_REGVAL_TBL[5]&=~bit0; + } + return wm8978_write_reg(5); +} +/******** interface ********/ +int wm8978_i2s_ctrl(i2s_config_t* i2s_config){ + int res=0; + WM8978_REGVAL_TBL[4]&=~(bit6|bit5); + if(i2s_config->bits_per_sample==8){ + return -1; //codec not support + }else if(i2s_config->bits_per_sample==16){ + //default + }else if(i2s_config->bits_per_sample==24){ + WM8978_REGVAL_TBL[4]|=bit6; + }else if(i2s_config->bits_per_sample==32){ + WM8978_REGVAL_TBL[4]|=bit5|bit6; + }else{ + return -1; + } + res|=wm8978_write_reg(4); + WM8978_REGVAL_TBL[7]&=~(bit3|bit2|bit1); + if(i2s_config->sample_rate==48000){ + }else if(i2s_config->sample_rate==32000){ + WM8978_REGVAL_TBL[7]|=bit1; + }else if(i2s_config->sample_rate==24000){ + WM8978_REGVAL_TBL[7]|=bit2; + }else if(i2s_config->sample_rate==16000){ + WM8978_REGVAL_TBL[7]|=bit2|bit1; + }else if(i2s_config->sample_rate==8000){ + WM8978_REGVAL_TBL[7]|=bit3|bit1; + }else if(i2s_config->sample_rate==12000){ + WM8978_REGVAL_TBL[7]|=bit3; + }else{ + + } + res|=wm8978_write_reg(7); + return res; +} +static int wm8978_clk_cfg(){ + WM8978_REGVAL_TBL[6]&=~bit8;//use the mclk + WM8978_REGVAL_TBL[6]&=~(bit7|bit6|bit5); //mclk div1 + return wm8978_write_reg(6); +} + + +/******** power control **********/ + +/*power control*/ +int wm8978_power_ctrl(wm8978_pwr_t* pwr){ + int res=0; + WM8978_REGVAL_TBL[1]|=bit3|bit1|bit0; + if(pwr->boostl){ + WM8978_REGVAL_TBL[2]|=bit4; + }else{ + WM8978_REGVAL_TBL[2]&=~bit4; + } + if(pwr->boostl){ + WM8978_REGVAL_TBL[2]|=bit4; + }else{ + WM8978_REGVAL_TBL[2]&=~bit4; + } + if(pwr->micb){ + WM8978_REGVAL_TBL[1]|=bit4; + if(pwr->micb==2){ + WM8978_REGVAL_TBL[44]|=bit8; + }else{ + WM8978_REGVAL_TBL[44]&=~bit8; + } + res|=wm8978_write_reg(44); + }else{ + WM8978_REGVAL_TBL[1]&=~bit4; + } + if(pwr->dacl){ + WM8978_REGVAL_TBL[3]|=bit0; + }else{ + WM8978_REGVAL_TBL[3]&=~bit0; + } + if(pwr->dacr){ + WM8978_REGVAL_TBL[3]|=bit1; + }else{ + WM8978_REGVAL_TBL[3]&=~bit1; + } + + if(pwr->lmix){ + WM8978_REGVAL_TBL[3]|=bit2; + }else{ + WM8978_REGVAL_TBL[3]&=~bit2; + } + + if(pwr->rmix){ + WM8978_REGVAL_TBL[3]|=bit3; + }else{ + WM8978_REGVAL_TBL[3]&=~bit3; + } + + if(pwr->lout1){ + WM8978_REGVAL_TBL[2]|=bit7; + }else{ + WM8978_REGVAL_TBL[2]&=~bit7; + } + + if(pwr->rout1){ + WM8978_REGVAL_TBL[2]|=bit8; + }else{ + WM8978_REGVAL_TBL[2]&=~bit8; + } + + if(pwr->lout2){ + WM8978_REGVAL_TBL[3]|=bit6; + }else{ + WM8978_REGVAL_TBL[3]&=~bit6; + } + + if(pwr->rout2){ + WM8978_REGVAL_TBL[3]|=bit5; + }else{ + WM8978_REGVAL_TBL[3]&=~bit5; + } + + if(pwr->out3){ + WM8978_REGVAL_TBL[3]|=bit7; + }else{ + WM8978_REGVAL_TBL[3]&=~bit7; + } + + if(pwr->out4){ + WM8978_REGVAL_TBL[3]|=bit8; + }else{ + WM8978_REGVAL_TBL[3]&=~bit8; + } + + if(pwr->out3_mix){ + WM8978_REGVAL_TBL[1]|=bit6; + }else{ + WM8978_REGVAL_TBL[1]&=~bit6; + } + + if(pwr->out4_mix){ + WM8978_REGVAL_TBL[1]|=bit7; + }else{ + WM8978_REGVAL_TBL[1]&=~bit7; + } + + + res|=wm8978_write_reg(1); + res|=wm8978_write_reg(2); + res|=wm8978_write_reg(3); + + return res; +} +esp_err_t wm8978_init(audio_hal_codec_config_t *cfg){ + (void)cfg;//fix init + int res=0; + + res|=i2c_init(); + res|=wm8978_pga_enable(true,true);//must enable + res|=wm8978_input_pga_ctrl();//mic is in diff mode + res|=wm8978_input_boost_enable(true,true); + res|=wm8978_pga_mute(false,false); + res|=wm8978_pga_vol(0,0); + res|=wm8978_alc_enable(); + res|=wm8978_auxl_l2(-0xff,-0xff);//disconnect auxl and l2 to mixer + res|=wm8978_auxr_r2(-0xff,-0xff);//disconnect auxr and r2 to mixer + //set adc oversample 128x, + WM8978_REGVAL_TBL[14]|=bit3; + res|=wm8978_write_reg(14); + //set dac oversample 128x + //auto mute enable + WM8978_REGVAL_TBL[10]|=bit3|bit2; + WM8978_REGVAL_TBL[10]&=~bit6; + res|=wm8978_write_reg(10); + //the left mix and right mix use the default value + res|=wm8978_out1_cfg(); + res|=wm8978_out2_cfg(); + res|=wm8978_out34_cfg(); + res|=wm8978_clk_cfg(); + res|=wm8978_eq_mode(1); + eq_t eq; + eq.freq=1; + eq.gain=0; + eq_t eq_a[5]={eq,eq,eq,eq,eq}; + res|=wm8978_eq_ctrl(eq_a); + return res; +} +/** + * @brief Control WM8978 codec chip + * + * @param mode codec mode + * @param ctrl_state start or stop decode or encode progress + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ + +#define AUDIO_HAL_WM8978_START_DEFAULT(){ \ + .boostl = 1, \ + .boostr = 1, \ + .micb = 2, \ + .adcl = 1, \ + .adcr = 1, \ + .dacl =1,\ + .dacr =1,\ + .lmix =1,\ + .rmix =1,\ + .rout1 =1,\ + .lout1 =1,\ + .lout2 =1,\ + .rout2 =1,\ + .out3_mix =1,\ + .out4_mix =1,\ + .out3 =1,\ + .out4 =1,\ +}; + + + +esp_err_t wm8978_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state){ + int res = 0; + if(mode!=AUDIO_HAL_CODEC_MODE_BOTH) + return ESP_FAIL; + wm8978_pwr_t start_cfg=AUDIO_HAL_WM8978_START_DEFAULT(); + if (AUDIO_HAL_CTRL_STOP == ctrl_state) { + memset(&start_cfg,0,sizeof(start_cfg)); + res = wm8978_power_ctrl(&start_cfg); + } else { + res =wm8978_power_ctrl(&start_cfg); + } + return res; +} +/** + * @brief Deinitialize WM8978 codec chip + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t wm8978_deinit(void){ + return wm8978_write_reg(0); +} +/** + * @brief Configure WM8978 codec mode and I2S interface,not support slave mode + * + * @param mode codec mode + * @param iface I2S config + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t wm8978_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface){ + (void)mode;//useless + i2s_config_t i2s_cfg; + if(iface->bits==AUDIO_HAL_BIT_LENGTH_16BITS){ + i2s_cfg.bits_per_sample=16; + }else if(iface->bits==AUDIO_HAL_BIT_LENGTH_24BITS){ + i2s_cfg.bits_per_sample=24; + }else if(iface->bits==AUDIO_HAL_BIT_LENGTH_32BITS){ + i2s_cfg.bits_per_sample=32; + }else{ + return ESP_FAIL; + } + + if(iface->fmt!=AUDIO_HAL_I2S_NORMAL){ + return ESP_FAIL; + } + if(iface->mode!=AUDIO_HAL_MODE_MASTER){ + return ESP_FAIL; + } + + if(iface->samples==AUDIO_HAL_48K_SAMPLES||iface->samples==AUDIO_HAL_44K_SAMPLES){ + i2s_cfg.sample_rate=48000; + }else if(iface->samples==AUDIO_HAL_32K_SAMPLES){ + i2s_cfg.sample_rate=32000; + }else if(iface->samples==AUDIO_HAL_24K_SAMPLES){ + i2s_cfg.sample_rate=24000; + }else if(iface->samples==AUDIO_HAL_16K_SAMPLES){ + i2s_cfg.sample_rate=16000; + }else if(iface->samples==AUDIO_HAL_11K_SAMPLES){ + i2s_cfg.sample_rate=12000; + }else if(iface->samples==AUDIO_HAL_08K_SAMPLES){ + i2s_cfg.sample_rate=8000; + }else{ + return ESP_FAIL; + } + + if(wm8978_i2s_ctrl(&i2s_cfg)) + return ESP_FAIL; + return ESP_OK; + +} +static int _volume; +/** + * @brief Set voice volume + * + * @param volume: voice volume (0~100) + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t wm8978_set_voice_volume(int volume){ + int v; + + v=volume*1270-127000; + if(wm8978_dac_vol(v,v)){ + return ESP_FAIL; + } + else{ + _volume=volume; + } + return ESP_OK; +} + +/** + * @brief Get voice volume + * + * @param[out] *volume: voice volume (0~100) + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t wm8978_get_voice_volume(int *volume){ + *volume=_volume; + return ESP_OK; +} \ No newline at end of file diff --git a/components/audio_hal/driver/wm8978/wm8978.h b/components/audio_hal/driver/wm8978/wm8978.h index e69de29bb..9db810401 100644 --- a/components/audio_hal/driver/wm8978/wm8978.h +++ b/components/audio_hal/driver/wm8978/wm8978.h @@ -0,0 +1,109 @@ +#ifndef WM8978_H +#define WM8978_H + +#include "esp_types.h" +#include "audio_hal.h" +#include "driver/i2s.h" + +typedef struct{ + int gain; //-12db~+12db + int freq; +}eq_t; + +typedef struct{ + uint8_t boostl; + uint8_t boostr; + uint8_t micb; //0:disable 1:0.65vdd 2;0.9vdd + uint8_t adcl; + uint8_t adcr; + uint8_t dacl; + uint8_t dacr; + uint8_t lmix; + uint8_t rmix; + uint8_t rout1; + uint8_t lout1; + uint8_t rout2; + uint8_t lout2; + uint8_t out3_mix; + uint8_t out4_mix; + uint8_t out3; + uint8_t out4; +}wm8978_pwr_t; + + + +//print all reg +void wm8978_read_all(); +/* +* step is :0.75db +* range -12db~+35.25db +* input is mDB: 1db=1000mdb +*/ +int wm8978_pga_vol(int right_mdb,int left_mdb); +int wm8978_pga_mute(bool right,bool left); +/* +* aul left and l2 control +* auxl_db:-12db~6db step:3db +* l2_db:-12db~0 db step:3db +* if the input is -0xff, disconnect the line +*/ +int wm8978_auxl_l2(int auxl_db,int l2_db); +/* +* aul right and r2 control +* auxl_db:-12db~6db step:3db +* l2_db:-12db~0 db step:3db +* if the input is -0xff, disconnect the line +*/ +int wm8978_auxr_r2(int auxr_db,int r2_db); +/* +*rvmdb,lvmdb +*-127db~0db +* -127000~0 +* step 500mdb +*/ +int wm8978_adc_vol(int rvmdb,int lvmdb); + +int wm8978_dac_both_mute(bool enable); +/* +*rvmdb,lvmdb +*-127db~0db +* -127000~0 +* step 500mdb +*/ +int wm8978_dac_vol(int rvmdb,int lvmdb); +/* +* -57db~+6db +*/ +int wm8978_out1_vol(int rdb,int ldb); +int wm8978_out1_mute(bool right,bool left); +/* +* -57db~+6db +*/ +int wm8978_out2_vol(int rdb,int ldb); +int wm8978_out2_mute(bool right,bool left); +/* +mode:1 dac 0:adc +*/ +int wm8978_eq_mode(uint8_t mode); +/* +* eq_a length :5 +* gain:-12db~+db + eq1:80,105,135,175 + eq2:230,300,385,500 + eq3:650,850,1100,1400 + eq4:1800,2400,3200,4100 + eq5:5300,6900,9000,11700 +*/ +int wm8978_eq_ctrl(eq_t* eq_a); +int wm8978_loopback(bool enable); +int wm8978_i2s_ctrl(i2s_config_t* i2s_config); +int wm8978_power_ctrl(wm8978_pwr_t* pwr); + +esp_err_t wm8978_init(audio_hal_codec_config_t *cfg); +esp_err_t wm8978_deinit(void); + +esp_err_t wm8978_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state); +esp_err_t wm8978_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface); +esp_err_t wm8978_set_voice_volume(int volume); +esp_err_t wm8978_get_voice_volume(int *volume); +#endif \ No newline at end of file diff --git a/components/audio_hal/include/audio_hal.h b/components/audio_hal/include/audio_hal.h index 34e0ab26e..f26d197ac 100755 --- a/components/audio_hal/include/audio_hal.h +++ b/components/audio_hal/include/audio_hal.h @@ -61,6 +61,19 @@ typedef struct audio_hal* audio_hal_handle_t; }, \ }; +#define AUDIO_HAL_WM8978_DEFAULT(){ \ + .adc_input = AUDIO_HAL_ADC_INPUT_DIFFERENCE, \ + .dac_output = AUDIO_HAL_DAC_OUTPUT_ALL, \ + .codec_mode = AUDIO_HAL_CODEC_MODE_BOTH, \ + .i2s_iface = { \ + .mode = AUDIO_HAL_MODE_MASTER, \ + .fmt = AUDIO_HAL_I2S_NORMAL, \ + .samples = AUDIO_HAL_44K_SAMPLES, \ + .bits = AUDIO_HAL_BIT_LENGTH_16BITS, \ + }, \ +}; + + /** * @brief Select media hal codec mode */ From cd68b4378b1396bc76afca84c2aebd1e554bcfe2 Mon Sep 17 00:00:00 2001 From: frankie Date: Tue, 19 Jun 2018 22:57:27 +0800 Subject: [PATCH 4/5] wm8978 can use,not config salve mode --- components/audio_hal/board/we_lin_board.h | 16 +- components/audio_hal/driver/wm8978/wm8978.c | 919 ++++++-------------- components/audio_hal/driver/wm8978/wm8978.h | 111 +-- project.mk | 1 - 4 files changed, 286 insertions(+), 761 deletions(-) diff --git a/components/audio_hal/board/we_lin_board.h b/components/audio_hal/board/we_lin_board.h index 8b48aa05a..0716be55f 100644 --- a/components/audio_hal/board/we_lin_board.h +++ b/components/audio_hal/board/we_lin_board.h @@ -33,23 +33,27 @@ extern "C" { #define IIC_PORT 0 #define IIC_DATA 19 -#define IIC_CLK 28 +#define IIC_CLK 18 /* I2S gpios */ #define IIS_SCLK 33 #define IIS_LCLK 25 -#define IIS_DSIN 27 -#define IIS_DOUT 26 +#define IIS_DSIN 26 +#define IIS_DOUT 27 #define LED_R 5 #define LED_G 21 #define LED_B 22 -#define KEY_1 34 -#define KEY_2 35 -#define KEY_3 32 +#define KEY_1_SEL GPIO_SEL_34 +#define KEY_2_SEL GPIO_SEL_35 +#define KEY_3_SEL GPIO_SEL_32 + +#define KEY_1_NUM GPIO_NUM_34 +#define KEY_2_NUM GPIO_NUM_35 +#define KEY_3_NUM GPIO_NUM_32 #define SD_CARD_INTR_GPIO 23 #define SD_CARD_INTR_SEL 23 diff --git a/components/audio_hal/driver/wm8978/wm8978.c b/components/audio_hal/driver/wm8978/wm8978.c index a4b430bac..1ff50307d 100644 --- a/components/audio_hal/driver/wm8978/wm8978.c +++ b/components/audio_hal/driver/wm8978/wm8978.c @@ -6,18 +6,6 @@ #include "wm8978.h" #include "board.h" - -#define bit0 0x001 -#define bit1 0x002 -#define bit2 0x004 -#define bit3 0x008 -#define bit4 0x010 -#define bit5 0x020 -#define bit6 0x040 -#define bit7 0x080 -#define bit8 0x100 - - #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ #define ACK_VAL 0x0 /*!< I2C ack value */ @@ -53,7 +41,7 @@ static const i2c_config_t es_i2c_cfg = { .scl_io_num = IIC_CLK, .sda_pullup_en = GPIO_PULLUP_DISABLE, .scl_pullup_en = GPIO_PULLUP_DISABLE, - .master.clk_speed = 400000 + .master.clk_speed = 100000 }; static inline esp_err_t _i2c_master_mem_write(i2c_port_t i2c_num, uint8_t DevAddr,uint8_t MemAddr,uint8_t* data_wr, size_t size) { @@ -71,7 +59,7 @@ static inline esp_err_t _i2c_master_mem_write(i2c_port_t i2c_num, uint8_t DevAdd return ret; } -static int _wm8978_write_reg(uint8_t reg, uint16_t val) +static int wm8978_write_reg(uint8_t reg, uint16_t val) { int res = 0; uint8_t buf[2]; @@ -79,11 +67,9 @@ static int _wm8978_write_reg(uint8_t reg, uint16_t val) buf[1]=(uint8_t)(val&0xff); res=(int)_i2c_master_mem_write(IIC_PORT,WM8978_ADDR,buf[0],buf+1,1); ES_ASSERT(res, "es_write_reg error", -1); + WM8978_REGVAL_TBL[reg]=val; return res; } -static int wm8978_write_reg(uint8_t index){ - return _wm8978_write_reg(index,WM8978_REGVAL_TBL[index]); -} static int wm8978_read_reg(uint8_t reg_add, uint16_t *pData) { @@ -109,719 +95,332 @@ void wm8978_read_all() } } - -/******** input signal path **********/ - - -static int wm8978_pga_enable(bool right,bool left){ - WM8978_REGVAL_TBL[2]&=~bit2; - WM8978_REGVAL_TBL[2]&=~bit3; - if(right) - WM8978_REGVAL_TBL[2]|=bit3; - if(left) - WM8978_REGVAL_TBL[2]|=bit2; - return wm8978_write_reg(2); -} -//const,not need to change -//do nothing -//the default value is ok -//mic is in different mode -//L2 and R2 not connect to PGA -static int wm8978_input_pga_ctrl(){ - return wm8978_write_reg(44); -} -int wm8978_pga_mute(bool right,bool left){ +esp_err_t wm8978_init(audio_hal_codec_config_t *cfg){ int res=0; - if(right){ - WM8978_REGVAL_TBL[46]|=bit6; + res|=i2c_init(); + //power config + res|=wm8978_write_reg(1,0x1df); + res|=wm8978_write_reg(2,0x1bf); + res|=wm8978_write_reg(3,0x1ff); + //interface config + uint16_t val; + res|=wm8978_read_reg(4,&val); + + if(cfg->i2s_iface.bits==AUDIO_HAL_BIT_LENGTH_16BITS){ + val&=0x19f; + }else if(cfg->i2s_iface.bits==AUDIO_HAL_BIT_LENGTH_24BITS){ + val&=0x19f; + val|=BIT6; + }else if(cfg->i2s_iface.bits==AUDIO_HAL_BIT_LENGTH_32BITS){ + val|=(BIT6|BIT5); }else{ - WM8978_REGVAL_TBL[46]&=~bit6; + return ESP_FAIL; + } + + if(cfg->i2s_iface.fmt==AUDIO_HAL_I2S_NORMAL){ + val&=0x1e7; + val|=(BIT4); + }else if(cfg->i2s_iface.fmt==AUDIO_HAL_I2S_RIGHT){ + val&=0x1e7; + }else if(cfg->i2s_iface.fmt==AUDIO_HAL_I2S_LEFT){ + val&=0x1e7; + val|=BIT3; + }else if(cfg->i2s_iface.fmt==AUDIO_HAL_I2S_DSP){ + val|=(BIT4|BIT3); + }else{ + return ESP_FAIL; } - res|=wm8978_write_reg(46); - if(left){ - WM8978_REGVAL_TBL[45]|=bit6; + res|=wm8978_write_reg(4,val); + //clk config + res|=wm8978_read_reg(6,&val); + val&=0x01f;//use the mclk,not need pll,div=1 + if(cfg->i2s_iface.mode==AUDIO_HAL_MODE_MASTER){ + val&=~BIT0; }else{ - WM8978_REGVAL_TBL[45]&=!bit6; + //as slave mode ,must config bclk div + //the mclk=256fs + //todo ... + return ESP_FAIL; } - res|=wm8978_write_reg(45); + res|=wm8978_write_reg(6,val); + if(cfg->i2s_iface.samples==AUDIO_HAL_08K_SAMPLES){ + val=0x00A; + }else if(cfg->i2s_iface.samples==AUDIO_HAL_16K_SAMPLES){ + val=0x006; + }else if(cfg->i2s_iface.samples==AUDIO_HAL_24K_SAMPLES){ + val=0x004; + }else if((cfg->i2s_iface.samples==AUDIO_HAL_44K_SAMPLES)||(cfg->i2s_iface.samples==AUDIO_HAL_48K_SAMPLES)){ + val=0; + } + res|=wm8978_write_reg(7,val); + res|=wm8978_write_reg(10,0x008); + res|=wm8978_write_reg(14,0x108); + res|=wm8978_write_reg(32,0x1b8); + res|=wm8978_set_adc_volume(100);//max + res|=wm8978_write_reg(47,0x100); + res|=wm8978_write_reg(48,0x100); + res|=wm8978_read_reg(49,&val); + val|=BIT2|BIT3|BIT4; + res|=wm8978_write_reg(49,val); + res|=wm8978_read_reg(56,&val); + val|=BIT1; + val&=~BIT0; + res|=wm8978_write_reg(56,val); + res|=wm8978_read_reg(57,&val); + val|=BIT1; + val&=~BIT0; + res|=wm8978_write_reg(57,val); + wm8979_eq_dir(0); + wm8978_read_all(); return res; + } /* -* step is :0.75db -* range -12db~+35.25db -* input is mDB: 1db=1000mdb +* 0: adc +* 1: dac */ -int wm8978_pga_vol(int right_mdb,int left_mdb){ - int rmdb,lmdb; - int res=0; - if(right_mdb>35250) - rmdb=35250; - if(left_mdb>35250) - lmdb=35250; - if(right_mdb<-12000) - rmdb=12000; - if(left_mdb<-12000) - lmdb=12000; - rmdb+=12000; - lmdb+=12000; - uint16_t r_value=rmdb/750; - uint16_t l_value=lmdb/750; - WM8978_REGVAL_TBL[45]&=0x0c0; - WM8978_REGVAL_TBL[46]&=0x0c0; - WM8978_REGVAL_TBL[45]|=r_value|bit6; //open zero cross - WM8978_REGVAL_TBL[46]|=l_value|bit6; //open zero cross - res|=wm8978_write_reg(45); - res|=wm8978_write_reg(46); - //write teh update bit - WM8978_REGVAL_TBL[45]|=bit8; - WM8978_REGVAL_TBL[46]|=bit8; - res|=wm8978_write_reg(46); - res|=wm8978_write_reg(45); - return res; -} -//open alc -static int wm8978_alc_enable(){ - WM8978_REGVAL_TBL[32]|=bit7|bit8; - return wm8978_write_reg(32); -} - -//auxl and auxr input -static int wm8978_input_boost_enable(bool re,bool le){ - int res =0; - if(re){ - WM8978_REGVAL_TBL[48]|=bit8; - }else{ - WM8978_REGVAL_TBL[48]&=~bit8; - } - res|=wm8978_write_reg(48); - if(le){ - WM8978_REGVAL_TBL[47]|=bit8; +esp_err_t wm8979_eq_dir(uint8_t dir){ + uint16_t val; + int res; + res=wm8978_read_reg(18,&val); + if(dir){ + val|=BIT8; }else{ - WM8978_REGVAL_TBL[47]&=~bit8; + val&=~BIT8; } - res|=wm8978_write_reg(47); + res|=wm8978_write_reg(18,val); return res; } /* -* aul left and l2 control -* auxl_db:-12db~6db step:3db -* l2_db:-12db~0 db step:3db -* if the input is -0xff, disconnect the line + * gain: 0~100(-12db~12db) + * freq: 0:80 1:105 2:135 3:175 */ -int wm8978_auxl_l2(int auxl_db,int l2_db){ - if(auxl_db==-0xff) - auxl_db=0; - if(l2_db==-0xff) - l2_db=0; - if(auxl_db>6) - auxl_db=6; - if(auxl_db<-12) - auxl_db=-12; - if(l2_db>6) - l2_db=6; - if(l2_db<-12) - l2_db=12; - l2_db+=12; - auxl_db+=12; - l2_db/=3; - auxl_db/=3; - WM8978_REGVAL_TBL[47]&=0x188; - WM8978_REGVAL_TBL[47]|=(l2_db<<4); - WM8978_REGVAL_TBL[47]|=auxl_db; - return wm8978_write_reg(47); +esp_err_t wm8978_set_eq1(uint8_t freq,int gain){ + uint16_t val; + if(gain>100) + gain=100; + if(gain<0) + gain=0; + gain*=24; + gain/=100; + gain=24-gain; + int res=wm8978_read_reg(18,&val); + val&=0x100; + val|=(freq<<5)|((uint16_t)gain); + res|=wm8978_write_reg(18,val); + return res; } /* -* aul right and r2 control -* auxl_db:-12db~6db step:3db -* l2_db:-12db~0 db step:3db -* if the input is -0xff, disconnect the line + * gain: 0~100(-12db~12db) + * freq: 0:230 1:300 2:385 3:500 */ -int wm8978_auxr_r2(int auxr_db,int r2_db){ - if(auxr_db==-0xff) - auxr_db=0; - if(r2_db==-0xff) - r2_db=0; - if(auxr_db>6) - auxr_db=6; - if(auxr_db<-12) - auxr_db=-12; - if(r2_db>6) - r2_db=6; - if(r2_db<-12) - r2_db=12; - r2_db+=12; - auxr_db+=12; - r2_db/=3; - auxr_db/=3; - WM8978_REGVAL_TBL[48]&=0x188; - WM8978_REGVAL_TBL[48]|=(r2_db<<4); - WM8978_REGVAL_TBL[48]|=auxr_db; - return wm8978_write_reg(48); +esp_err_t wm8978_set_eq2(uint8_t freq,int gain){ + uint16_t val; + if(gain>100) + gain=100; + if(gain<0) + gain=0; + gain*=24; + gain/=100; + gain=24-gain; + val=(freq<<5)|((uint16_t)gain); + return wm8978_write_reg(19,val); } /* -*rvmdb,lvmdb -*-127db~0db -* -127000~0 -* step 500mdb + * gain: 0~100(-12db~12db) + * freq: 0:650 1:850 2:1.1k 3:1.4k */ -int wm8978_adc_vol(int rvmdb,int lvmdb){ - int res=0; - - if(rvmdb<-127000) - rvmdb=-127500; - if(rvmdb>0) - rvmdb=0; - rvmdb+=127500; - rvmdb/=500; - WM8978_REGVAL_TBL[16]=rvmdb; - res|=wm8978_write_reg(16); - WM8978_REGVAL_TBL[16]|=bit8; - res|=wm8978_write_reg(16); - - if(lvmdb<-127000) - lvmdb=-127500; - if(lvmdb>0) - lvmdb=0; - lvmdb+=127500; - lvmdb/=500; - WM8978_REGVAL_TBL[15]=lvmdb; - res|=wm8978_write_reg(15); - WM8978_REGVAL_TBL[15]|=bit8; - res|=wm8978_write_reg(15); - - return res; -} -/******** output signal path **********/ -int wm8978_dac_both_mute(bool enable){ - if(enable){ - WM8978_REGVAL_TBL[10]|=bit6; - }else{ - WM8978_REGVAL_TBL[10]&=~bit6; - } - return wm8978_write_reg(10); +esp_err_t wm8978_set_eq3(uint8_t freq,int gain){ + uint16_t val; + if(gain>100) + gain=100; + if(gain<0) + gain=0; + gain*=24; + gain/=100; + gain=24-gain; + val=(freq<<5)|((uint16_t)gain); + return wm8978_write_reg(20,val); } /* -*rvmdb,lvmdb -*-127db~0db -* -127000~0 -* step 500mdb + * gain: 0~100(-12db~12db) + * freq: 0:1.8k 1:2.4k 2:3.2k 3:4.1k */ -int wm8978_dac_vol(int rvmdb,int lvmdb){ - int res=0; - - if(rvmdb<-127000) - rvmdb=-127500; - if(rvmdb>0) - rvmdb=0; - rvmdb+=127500; - rvmdb/=500; - WM8978_REGVAL_TBL[12]=rvmdb; - res|=wm8978_write_reg(12); - WM8978_REGVAL_TBL[12]|=bit8; - res|=wm8978_write_reg(12); - - if(lvmdb<-127000) - lvmdb=-127500; - if(lvmdb>0) - lvmdb=0; - lvmdb+=127500; - lvmdb/=500; - WM8978_REGVAL_TBL[11]=lvmdb; - res|=wm8978_write_reg(11); - WM8978_REGVAL_TBL[11]|=bit8; - res|=wm8978_write_reg(11); - - return res; -} -//enable zero cross -static int wm8978_out1_cfg(){ - int res=0; - WM8978_REGVAL_TBL[52]|=bit7; - WM8978_REGVAL_TBL[53]|=bit7; - res|=wm8978_write_reg(52); - res|=wm8978_write_reg(53); - return res; +esp_err_t wm8978_set_eq4(uint8_t freq,int gain){ + uint16_t val; + if(gain>100) + gain=100; + if(gain<0) + gain=0; + gain*=24; + gain/=100; + gain=24-gain; + val=(freq<<5)|((uint16_t)gain); + return wm8978_write_reg(21,val); } /* -* -57db~+6db + * gain: 0~100(-12db~12db) + * freq: 0:5.3k 1:6.9k 2:9k 3:11.7k */ -int wm8978_out1_vol(int rdb,int ldb){ +esp_err_t wm8978_set_eq5(uint8_t freq,int gain){ + uint16_t val; + if(gain>100) + gain=100; + if(gain<0) + gain=0; + gain*=24; + gain/=100; + gain=24-gain; + val=(freq<<5)|((uint16_t)gain); + return wm8978_write_reg(22,val); +} + +esp_err_t wm8978_pga_volume(int volume){ int res=0; - if(rdb<-57) - rdb=-57; - if(rdb>6) - rdb=6; - rdb+=57; - WM8978_REGVAL_TBL[53]&=0xc0; - WM8978_REGVAL_TBL[53]|=rdb; - res|=wm8978_write_reg(53); - WM8978_REGVAL_TBL[53]|=bit8; - res|=wm8978_write_reg(53); - - if(ldb<-57) - ldb=-57; - if(ldb>6) - ldb=6; - ldb+=57; - WM8978_REGVAL_TBL[52]&=0xc0; - WM8978_REGVAL_TBL[52]|=ldb; - res|=wm8978_write_reg(52); - WM8978_REGVAL_TBL[52]|=bit8; - res|=wm8978_write_reg(52); - + volume*=63; + volume/=100; + res|=wm8978_write_reg(45,volume); + res|=wm8978_write_reg(46,volume|BIT8); return res; } -int wm8978_out1_mute(bool right,bool left){ +esp_err_t wm8978_set_hp_volume(int volume){ int res=0; - WM8978_REGVAL_TBL[53]&=~bit8; - if(right) - WM8978_REGVAL_TBL[53]|=bit6; - else - WM8978_REGVAL_TBL[53]&=~bit6; - res|=wm8978_write_reg(53); - - WM8978_REGVAL_TBL[52]&=~bit8; - if(left) - WM8978_REGVAL_TBL[52]|=bit6; - else - WM8978_REGVAL_TBL[52]&=~bit6; - res|=wm8978_write_reg(52); - + volume*=63; + volume/=100; + res|=wm8978_write_reg(53,volume); + res|=wm8978_write_reg(52,volume|BIT8); return res; } -//enable zero cross -//DC=1.5*AVDD/2 -static int wm8978_out2_cfg(){ +esp_err_t wm8978_set_spk_volume(int volume){ int res=0; - WM8978_REGVAL_TBL[54]|=bit7; - WM8978_REGVAL_TBL[55]|=bit7; - res|=wm8978_write_reg(54); - res|=wm8978_write_reg(55); - - WM8978_REGVAL_TBL[1]|=bit8; - res|=wm8978_write_reg(1); - WM8978_REGVAL_TBL[49]|=bit2; - res|=wm8978_write_reg(49); - return res; -} -/* -* -57db~+6db -*/ -int wm8978_out2_vol(int rdb,int ldb){ - int res=0; - if(rdb<-57) - rdb=-57; - if(rdb>6) - rdb=6; - rdb+=57; - WM8978_REGVAL_TBL[55]&=0xc0; - WM8978_REGVAL_TBL[55]|=rdb; - res|=wm8978_write_reg(55); - WM8978_REGVAL_TBL[55]|=bit8; - res|=wm8978_write_reg(55); - - if(ldb<-57) - ldb=-57; - if(ldb>6) - ldb=6; - ldb+=57; - WM8978_REGVAL_TBL[54]&=0xc0; - WM8978_REGVAL_TBL[54]|=ldb; - res|=wm8978_write_reg(54); - WM8978_REGVAL_TBL[54]|=bit8; - res|=wm8978_write_reg(54); - - return res; -} -int wm8978_out2_mute(bool right,bool left){ - int res=0; - WM8978_REGVAL_TBL[55]&=~bit8; - if(right) - WM8978_REGVAL_TBL[55]|=bit6; - else - WM8978_REGVAL_TBL[55]&=~bit6; - res|=wm8978_write_reg(55); - - WM8978_REGVAL_TBL[54]&=~bit8; - if(left) - WM8978_REGVAL_TBL[54]|=bit6; - else - WM8978_REGVAL_TBL[54]&=~bit6; - res|=wm8978_write_reg(54); - - return res; -} -static int wm8978_out34_cfg(){ - int res=0; - WM8978_REGVAL_TBL[49]|=bit3|bit4; - res|=wm8978_write_reg(49); - WM8978_REGVAL_TBL[1]|=bit8; - res|=wm8978_write_reg(1); - + volume*=63; + volume/=100; + res|=wm8978_write_reg(55,volume); + res|=wm8978_write_reg(54,volume|BIT8); return res; } - -/******** EQ control **********/ - -/* -mode:1 dac 0:adc -*/ - -int wm8978_eq_mode(uint8_t mode){ - if(mode){ - WM8978_REGVAL_TBL[18]|=bit8; +esp_err_t wm8978_mute(bool en){ + uint16_t val; + int res=wm8978_read_reg(10,&val); + if(en){ + val|=BIT6; }else{ - WM8978_REGVAL_TBL[18]&=~bit8; - } - return wm8978_write_reg(18); -} - -/* -* eq_a length :5 -* gain:-12db~+12db - eq1:80,105,135,175 - eq2:230,300,385,500 - eq3:650,850,1100,1400 - eq4:1800,2400,3200,4100 - eq5:5300,6900,9000,11700 -*/ -int wm8978_eq_ctrl(eq_t* eq_a){ - int res=0; - for(int i=0;i<5;i++){ - eq_a[i].gain=12-eq_a[i].gain; - WM8978_REGVAL_TBL[18+i]=(eq_a[i].gain)|(eq_a[i].freq<<5); - res|=wm8978_write_reg(18+i); + val&=~BIT6; } + res|=wm8978_write_reg(10,val); return res; } -int wm8978_loopback(bool enable){ - if(enable){ - WM8978_REGVAL_TBL[5]|=bit0; - }else{ - WM8978_REGVAL_TBL[5]&=~bit0; - } - return wm8978_write_reg(5); -} -/******** interface ********/ -int wm8978_i2s_ctrl(i2s_config_t* i2s_config){ +esp_err_t wm8978_set_adc_volume(int volume){ int res=0; - WM8978_REGVAL_TBL[4]&=~(bit6|bit5); - if(i2s_config->bits_per_sample==8){ - return -1; //codec not support - }else if(i2s_config->bits_per_sample==16){ - //default - }else if(i2s_config->bits_per_sample==24){ - WM8978_REGVAL_TBL[4]|=bit6; - }else if(i2s_config->bits_per_sample==32){ - WM8978_REGVAL_TBL[4]|=bit5|bit6; - }else{ - return -1; - } - res|=wm8978_write_reg(4); - WM8978_REGVAL_TBL[7]&=~(bit3|bit2|bit1); - if(i2s_config->sample_rate==48000){ - }else if(i2s_config->sample_rate==32000){ - WM8978_REGVAL_TBL[7]|=bit1; - }else if(i2s_config->sample_rate==24000){ - WM8978_REGVAL_TBL[7]|=bit2; - }else if(i2s_config->sample_rate==16000){ - WM8978_REGVAL_TBL[7]|=bit2|bit1; - }else if(i2s_config->sample_rate==8000){ - WM8978_REGVAL_TBL[7]|=bit3|bit1; - }else if(i2s_config->sample_rate==12000){ - WM8978_REGVAL_TBL[7]|=bit3; - }else{ - - } - res|=wm8978_write_reg(7); + volume*=255; + volume/=100; + volume|=BIT8; + res|=wm8978_write_reg(15,volume); + res|=wm8978_write_reg(16,volume); return res; } -static int wm8978_clk_cfg(){ - WM8978_REGVAL_TBL[6]&=~bit8;//use the mclk - WM8978_REGVAL_TBL[6]&=~(bit7|bit6|bit5); //mclk div1 - return wm8978_write_reg(6); -} - -/******** power control **********/ -/*power control*/ -int wm8978_power_ctrl(wm8978_pwr_t* pwr){ +esp_err_t wm8978_deinit(void){ + return wm8978_write_reg(0,0x1); +} +esp_err_t wm8978_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state){ + uint16_t val1,val2; int res=0; - WM8978_REGVAL_TBL[1]|=bit3|bit1|bit0; - if(pwr->boostl){ - WM8978_REGVAL_TBL[2]|=bit4; - }else{ - WM8978_REGVAL_TBL[2]&=~bit4; - } - if(pwr->boostl){ - WM8978_REGVAL_TBL[2]|=bit4; - }else{ - WM8978_REGVAL_TBL[2]&=~bit4; - } - if(pwr->micb){ - WM8978_REGVAL_TBL[1]|=bit4; - if(pwr->micb==2){ - WM8978_REGVAL_TBL[44]|=bit8; - }else{ - WM8978_REGVAL_TBL[44]&=~bit8; - } - res|=wm8978_write_reg(44); - }else{ - WM8978_REGVAL_TBL[1]&=~bit4; - } - if(pwr->dacl){ - WM8978_REGVAL_TBL[3]|=bit0; - }else{ - WM8978_REGVAL_TBL[3]&=~bit0; - } - if(pwr->dacr){ - WM8978_REGVAL_TBL[3]|=bit1; + res|=wm8978_read_reg(2,&val1); + res|=wm8978_read_reg(3,&val2); + if(mode==AUDIO_HAL_CODEC_MODE_ENCODE){ + //disable dac + val2&=~(BIT0|BIT1); + res|=wm8978_write_reg(3,val2); + val1|=(BIT0|BIT1); + res|=wm8978_write_reg(2,val1); + }else if(mode==AUDIO_HAL_CODEC_MODE_DECODE){ + val1&=~(BIT0|BIT1); + res|=wm8978_write_reg(2,val1); + val2|=(BIT0|BIT1); + res|=wm8978_write_reg(3,val2); + }else if(mode==AUDIO_HAL_CODEC_MODE_BOTH){ + val1|=(BIT0|BIT1); + val2|=(BIT0|BIT1); + res|=wm8978_write_reg(2,val1); + res|=wm8978_write_reg(3,val2); }else{ - WM8978_REGVAL_TBL[3]&=~bit1; - } - - if(pwr->lmix){ - WM8978_REGVAL_TBL[3]|=bit2; - }else{ - WM8978_REGVAL_TBL[3]&=~bit2; - } - - if(pwr->rmix){ - WM8978_REGVAL_TBL[3]|=bit3; - }else{ - WM8978_REGVAL_TBL[3]&=~bit3; - } - - if(pwr->lout1){ - WM8978_REGVAL_TBL[2]|=bit7; - }else{ - WM8978_REGVAL_TBL[2]&=~bit7; - } - - if(pwr->rout1){ - WM8978_REGVAL_TBL[2]|=bit8; - }else{ - WM8978_REGVAL_TBL[2]&=~bit8; - } - - if(pwr->lout2){ - WM8978_REGVAL_TBL[3]|=bit6; - }else{ - WM8978_REGVAL_TBL[3]&=~bit6; - } - - if(pwr->rout2){ - WM8978_REGVAL_TBL[3]|=bit5; - }else{ - WM8978_REGVAL_TBL[3]&=~bit5; - } - - if(pwr->out3){ - WM8978_REGVAL_TBL[3]|=bit7; - }else{ - WM8978_REGVAL_TBL[3]&=~bit7; - } - - if(pwr->out4){ - WM8978_REGVAL_TBL[3]|=bit8; - }else{ - WM8978_REGVAL_TBL[3]&=~bit8; - } - - if(pwr->out3_mix){ - WM8978_REGVAL_TBL[1]|=bit6; - }else{ - WM8978_REGVAL_TBL[1]&=~bit6; + return ESP_FAIL; } - - if(pwr->out4_mix){ - WM8978_REGVAL_TBL[1]|=bit7; + if(ctrl_state==AUDIO_HAL_CTRL_START){ + wm8978_mute(false); }else{ - WM8978_REGVAL_TBL[1]&=~bit7; + wm8978_mute(true); } - - - res|=wm8978_write_reg(1); - res|=wm8978_write_reg(2); - res|=wm8978_write_reg(3); - return res; -} -esp_err_t wm8978_init(audio_hal_codec_config_t *cfg){ - (void)cfg;//fix init - int res=0; - res|=i2c_init(); - res|=wm8978_pga_enable(true,true);//must enable - res|=wm8978_input_pga_ctrl();//mic is in diff mode - res|=wm8978_input_boost_enable(true,true); - res|=wm8978_pga_mute(false,false); - res|=wm8978_pga_vol(0,0); - res|=wm8978_alc_enable(); - res|=wm8978_auxl_l2(-0xff,-0xff);//disconnect auxl and l2 to mixer - res|=wm8978_auxr_r2(-0xff,-0xff);//disconnect auxr and r2 to mixer - //set adc oversample 128x, - WM8978_REGVAL_TBL[14]|=bit3; - res|=wm8978_write_reg(14); - //set dac oversample 128x - //auto mute enable - WM8978_REGVAL_TBL[10]|=bit3|bit2; - WM8978_REGVAL_TBL[10]&=~bit6; - res|=wm8978_write_reg(10); - //the left mix and right mix use the default value - res|=wm8978_out1_cfg(); - res|=wm8978_out2_cfg(); - res|=wm8978_out34_cfg(); - res|=wm8978_clk_cfg(); - res|=wm8978_eq_mode(1); - eq_t eq; - eq.freq=1; - eq.gain=0; - eq_t eq_a[5]={eq,eq,eq,eq,eq}; - res|=wm8978_eq_ctrl(eq_a); - return res; } -/** - * @brief Control WM8978 codec chip - * - * @param mode codec mode - * @param ctrl_state start or stop decode or encode progress - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success - */ - -#define AUDIO_HAL_WM8978_START_DEFAULT(){ \ - .boostl = 1, \ - .boostr = 1, \ - .micb = 2, \ - .adcl = 1, \ - .adcr = 1, \ - .dacl =1,\ - .dacr =1,\ - .lmix =1,\ - .rmix =1,\ - .rout1 =1,\ - .lout1 =1,\ - .lout2 =1,\ - .rout2 =1,\ - .out3_mix =1,\ - .out4_mix =1,\ - .out3 =1,\ - .out4 =1,\ -}; - - - -esp_err_t wm8978_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state){ - int res = 0; - if(mode!=AUDIO_HAL_CODEC_MODE_BOTH) +esp_err_t wm8978_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface){ + (void)mode; + uint16_t val; + int res=0; + if(iface->mode!=AUDIO_HAL_MODE_MASTER){ + //todo ... return ESP_FAIL; - wm8978_pwr_t start_cfg=AUDIO_HAL_WM8978_START_DEFAULT(); - if (AUDIO_HAL_CTRL_STOP == ctrl_state) { - memset(&start_cfg,0,sizeof(start_cfg)); - res = wm8978_power_ctrl(&start_cfg); - } else { - res =wm8978_power_ctrl(&start_cfg); } - return res; -} -/** - * @brief Deinitialize WM8978 codec chip - * - * @return - * - ESP_OK - * - ESP_FAIL - */ -esp_err_t wm8978_deinit(void){ - return wm8978_write_reg(0); -} -/** - * @brief Configure WM8978 codec mode and I2S interface,not support slave mode - * - * @param mode codec mode - * @param iface I2S config - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success - */ -esp_err_t wm8978_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface){ - (void)mode;//useless - i2s_config_t i2s_cfg; + res|=wm8978_read_reg(4,&val); if(iface->bits==AUDIO_HAL_BIT_LENGTH_16BITS){ - i2s_cfg.bits_per_sample=16; + val&=0x19f; }else if(iface->bits==AUDIO_HAL_BIT_LENGTH_24BITS){ - i2s_cfg.bits_per_sample=24; + val&=0x19f; + val|=BIT6; }else if(iface->bits==AUDIO_HAL_BIT_LENGTH_32BITS){ - i2s_cfg.bits_per_sample=32; + val|=(BIT6|BIT5); }else{ return ESP_FAIL; } - - if(iface->fmt!=AUDIO_HAL_I2S_NORMAL){ - return ESP_FAIL; - } - if(iface->mode!=AUDIO_HAL_MODE_MASTER){ + if(iface->fmt==AUDIO_HAL_I2S_NORMAL){ + val&=0x1e7; + val|=(BIT4); + }else if(iface->fmt==AUDIO_HAL_I2S_RIGHT){ + val&=0x1e7; + }else if(iface->fmt==AUDIO_HAL_I2S_LEFT){ + val&=0x1e7; + val|=BIT3; + }else if(iface->fmt==AUDIO_HAL_I2S_DSP){ + val|=(BIT4|BIT3); + }else{ return ESP_FAIL; } + res|=wm8978_write_reg(4,val); - if(iface->samples==AUDIO_HAL_48K_SAMPLES||iface->samples==AUDIO_HAL_44K_SAMPLES){ - i2s_cfg.sample_rate=48000; - }else if(iface->samples==AUDIO_HAL_32K_SAMPLES){ - i2s_cfg.sample_rate=32000; - }else if(iface->samples==AUDIO_HAL_24K_SAMPLES){ - i2s_cfg.sample_rate=24000; + if(iface->samples==AUDIO_HAL_08K_SAMPLES){ + val=0x00A; }else if(iface->samples==AUDIO_HAL_16K_SAMPLES){ - i2s_cfg.sample_rate=16000; - }else if(iface->samples==AUDIO_HAL_11K_SAMPLES){ - i2s_cfg.sample_rate=12000; - }else if(iface->samples==AUDIO_HAL_08K_SAMPLES){ - i2s_cfg.sample_rate=8000; - }else{ - return ESP_FAIL; + val=0x006; + }else if(iface->samples==AUDIO_HAL_24K_SAMPLES){ + val=0x004; + }else if((iface->samples==AUDIO_HAL_44K_SAMPLES)||(iface->samples==AUDIO_HAL_48K_SAMPLES)){ + val=0; } - - if(wm8978_i2s_ctrl(&i2s_cfg)) - return ESP_FAIL; - return ESP_OK; - + res|=wm8978_write_reg(7,val); + return res; } -static int _volume; -/** - * @brief Set voice volume - * - * @param volume: voice volume (0~100) - * - * @return - * - ESP_OK - * - ESP_FAIL - */ +static int _vol; + esp_err_t wm8978_set_voice_volume(int volume){ - int v; - - v=volume*1270-127000; - if(wm8978_dac_vol(v,v)){ - return ESP_FAIL; - } - else{ - _volume=volume; - } - return ESP_OK; + if(volume>100) + volume=100; + if(volume<0) + volume=0; + int res=0; + _vol=volume; + volume*=255; + volume/=100; + volume|=BIT8; + res|=wm8978_write_reg(11,volume); + res|=wm8978_write_reg(12,volume); + res=0; + return res; } -/** - * @brief Get voice volume - * - * @param[out] *volume: voice volume (0~100) - * - * @return - * - ESP_OK - * - ESP_FAIL - */ esp_err_t wm8978_get_voice_volume(int *volume){ - *volume=_volume; + *volume=_vol; return ESP_OK; } \ No newline at end of file diff --git a/components/audio_hal/driver/wm8978/wm8978.h b/components/audio_hal/driver/wm8978/wm8978.h index 9db810401..579431154 100644 --- a/components/audio_hal/driver/wm8978/wm8978.h +++ b/components/audio_hal/driver/wm8978/wm8978.h @@ -5,105 +5,28 @@ #include "audio_hal.h" #include "driver/i2s.h" -typedef struct{ - int gain; //-12db~+12db - int freq; -}eq_t; - -typedef struct{ - uint8_t boostl; - uint8_t boostr; - uint8_t micb; //0:disable 1:0.65vdd 2;0.9vdd - uint8_t adcl; - uint8_t adcr; - uint8_t dacl; - uint8_t dacr; - uint8_t lmix; - uint8_t rmix; - uint8_t rout1; - uint8_t lout1; - uint8_t rout2; - uint8_t lout2; - uint8_t out3_mix; - uint8_t out4_mix; - uint8_t out3; - uint8_t out4; -}wm8978_pwr_t; - - - -//print all reg -void wm8978_read_all(); -/* -* step is :0.75db -* range -12db~+35.25db -* input is mDB: 1db=1000mdb -*/ -int wm8978_pga_vol(int right_mdb,int left_mdb); -int wm8978_pga_mute(bool right,bool left); -/* -* aul left and l2 control -* auxl_db:-12db~6db step:3db -* l2_db:-12db~0 db step:3db -* if the input is -0xff, disconnect the line -*/ -int wm8978_auxl_l2(int auxl_db,int l2_db); -/* -* aul right and r2 control -* auxl_db:-12db~6db step:3db -* l2_db:-12db~0 db step:3db -* if the input is -0xff, disconnect the line -*/ -int wm8978_auxr_r2(int auxr_db,int r2_db); -/* -*rvmdb,lvmdb -*-127db~0db -* -127000~0 -* step 500mdb -*/ -int wm8978_adc_vol(int rvmdb,int lvmdb); - -int wm8978_dac_both_mute(bool enable); -/* -*rvmdb,lvmdb -*-127db~0db -* -127000~0 -* step 500mdb -*/ -int wm8978_dac_vol(int rvmdb,int lvmdb); -/* -* -57db~+6db -*/ -int wm8978_out1_vol(int rdb,int ldb); -int wm8978_out1_mute(bool right,bool left); -/* -* -57db~+6db -*/ -int wm8978_out2_vol(int rdb,int ldb); -int wm8978_out2_mute(bool right,bool left); -/* -mode:1 dac 0:adc -*/ -int wm8978_eq_mode(uint8_t mode); -/* -* eq_a length :5 -* gain:-12db~+db - eq1:80,105,135,175 - eq2:230,300,385,500 - eq3:650,850,1100,1400 - eq4:1800,2400,3200,4100 - eq5:5300,6900,9000,11700 -*/ -int wm8978_eq_ctrl(eq_t* eq_a); -int wm8978_loopback(bool enable); -int wm8978_i2s_ctrl(i2s_config_t* i2s_config); -int wm8978_power_ctrl(wm8978_pwr_t* pwr); - esp_err_t wm8978_init(audio_hal_codec_config_t *cfg); esp_err_t wm8978_deinit(void); esp_err_t wm8978_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state); esp_err_t wm8978_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface); +//0-100 esp_err_t wm8978_set_voice_volume(int volume); esp_err_t wm8978_get_voice_volume(int *volume); + +esp_err_t wm8978_set_adc_volume(int volume); +esp_err_t wm8978_mute(bool en); +esp_err_t wm8978_pga_volume(int volume); +esp_err_t wm8978_set_spk_volume(int volume); +esp_err_t wm8978_set_hp_volume(int volume); +/* +* 0: adc +* 1: dac +*/ +esp_err_t wm8979_eq_dir(uint8_t dir); +esp_err_t wm8978_set_eq5(uint8_t freq,int gain); +esp_err_t wm8978_set_eq4(uint8_t freq,int gain); +esp_err_t wm8978_set_eq3(uint8_t freq,int gain); +esp_err_t wm8978_set_eq2(uint8_t freq,int gain); +esp_err_t wm8978_set_eq1(uint8_t freq,int gain); #endif \ No newline at end of file diff --git a/project.mk b/project.mk index fec131e28..8a04e008d 100644 --- a/project.mk +++ b/project.mk @@ -1,5 +1,4 @@ ADF_VER := $(shell cd ${ADF_PATH} && git describe --always --tags --dirty) -IDF_PATH := $(ADF_PATH)/esp-idf EXTRA_COMPONENT_DIRS += $(ADF_PATH)/components/ CPPFLAGS := -D ADF_VER=\"$(ADF_VER)\" include $(IDF_PATH)/make/project.mk From 37090e7ec7fecc8484bb166b761ada5bbec5f53e Mon Sep 17 00:00:00 2001 From: frankie Date: Sat, 21 Jul 2018 16:38:41 +0800 Subject: [PATCH 5/5] remove read all reg --- components/audio_hal/driver/wm8978/wm8978.c | 1 - docs/_static/adf_block_diagram.xml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/components/audio_hal/driver/wm8978/wm8978.c b/components/audio_hal/driver/wm8978/wm8978.c index 1ff50307d..ff8b0c9a7 100644 --- a/components/audio_hal/driver/wm8978/wm8978.c +++ b/components/audio_hal/driver/wm8978/wm8978.c @@ -171,7 +171,6 @@ esp_err_t wm8978_init(audio_hal_codec_config_t *cfg){ val&=~BIT0; res|=wm8978_write_reg(57,val); wm8979_eq_dir(0); - wm8978_read_all(); return res; } diff --git a/docs/_static/adf_block_diagram.xml b/docs/_static/adf_block_diagram.xml index 9a2876412..afc3d6eca 100644 --- a/docs/_static/adf_block_diagram.xml +++ b/docs/_static/adf_block_diagram.xml @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file