upgrade to IDF v5.1.1
custom board driver ma120x0 is broken esp dsp is now IDF managed component mdns is now IDF managed component Signed-off-by: Karl Osterseher <karli_o@gmx.at>
This commit is contained in:
@@ -2,41 +2,54 @@ set(COMPONENT_ADD_INCLUDEDIRS ./include
|
||||
./driver/es8388
|
||||
./driver/es8374
|
||||
./driver/es8311
|
||||
./driver/es8156
|
||||
./driver/es7243
|
||||
./driver/es7148
|
||||
./driver/es7210
|
||||
./driver/es7243e
|
||||
./driver/tas5805m
|
||||
#./driver/zl38063
|
||||
#./driver/zl38063/api_lib
|
||||
#./driver/zl38063/example_apps
|
||||
#./driver/zl38063/firmware
|
||||
./driver/include
|
||||
)
|
||||
./driver/include)
|
||||
IF (NOT ((CONFIG_IDF_TARGET STREQUAL "esp32c3") OR (CONFIG_IDF_TARGET STREQUAL "esp32c6")))
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS
|
||||
./driver/zl38063
|
||||
./driver/zl38063/api_lib
|
||||
./driver/zl38063/example_apps
|
||||
./driver/zl38063/firmware)
|
||||
endif()
|
||||
|
||||
# Edit following two lines to set component requirements (see docs)
|
||||
set(COMPONENT_REQUIRES )
|
||||
set(COMPONENT_PRIV_REQUIRES audio_sal audio_board mbedtls esp_peripherals)
|
||||
set(COMPONENT_PRIV_REQUIRES audio_sal audio_board mbedtls esp_peripherals custom_board)
|
||||
|
||||
set(COMPONENT_SRCS ./audio_hal.c
|
||||
./audio_volume.c
|
||||
./driver/es8388/es8388.c
|
||||
./driver/es8388/headphone_detect.c
|
||||
./driver/es8374/es8374.c
|
||||
./driver/es8311/es8311.c
|
||||
./driver/es8156/es8156.c
|
||||
./driver/es7243/es7243.c
|
||||
./driver/es7148/es7148.c
|
||||
./driver/es7210/es7210.c
|
||||
./driver/es7243e/es7243e.c
|
||||
./driver/tas5805m/tas5805m.c
|
||||
#./driver/zl38063/zl38063.c
|
||||
#./driver/zl38063/api_lib/vprocTwolf_access.c
|
||||
#./driver/zl38063/api_lib/vproc_common.c
|
||||
#./driver/zl38063/example_apps/tw_hal_verify.c
|
||||
#./driver/zl38063/example_apps/tw_ldcfg.c
|
||||
#./driver/zl38063/example_apps/tw_ldfw.c
|
||||
#./driver/zl38063/example_apps/tw_ldfwcfg.c
|
||||
#./driver/zl38063/example_apps/tw_spi_access.c
|
||||
)
|
||||
|
||||
IF (NOT ((CONFIG_IDF_TARGET STREQUAL "esp32c3") OR (CONFIG_IDF_TARGET STREQUAL "esp32c6")))
|
||||
list(APPEND COMPONENT_SRCS
|
||||
./driver/zl38063/zl38063.c
|
||||
./driver/zl38063/api_lib/vprocTwolf_access.c
|
||||
./driver/zl38063/api_lib/vproc_common.c
|
||||
./driver/zl38063/example_apps/tw_hal_verify.c
|
||||
./driver/zl38063/example_apps/tw_ldcfg.c
|
||||
./driver/zl38063/example_apps/tw_ldfw.c
|
||||
./driver/zl38063/example_apps/tw_ldfwcfg.c
|
||||
./driver/zl38063/example_apps/tw_spi_access.c)
|
||||
endif()
|
||||
|
||||
register_component()
|
||||
|
||||
#target_link_libraries(${COMPONENT_TARGET} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/driver/zl38063/firmware")
|
||||
#target_link_libraries(${COMPONENT_TARGET} INTERFACE firmware)
|
||||
IF (NOT ((CONFIG_IDF_TARGET STREQUAL "esp32c3") OR (CONFIG_IDF_TARGET STREQUAL "esp32c6")))
|
||||
target_link_libraries(${COMPONENT_TARGET} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/driver/zl38063/firmware")
|
||||
target_link_libraries(${COMPONENT_TARGET} INTERFACE firmware)
|
||||
ENDIF()
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,140 +18,132 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "audio_hal.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "audio_mem.h"
|
||||
#include "audio_mutex.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "AUDIO_HAL";
|
||||
|
||||
#define AUDIO_HAL_CHECK_NULL(a, format, b, ...) \
|
||||
if ((a) == 0) \
|
||||
{ \
|
||||
ESP_LOGE (TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
#define AUDIO_HAL_CHECK_NULL(a, format, b, ...) \
|
||||
if ((a) == 0) { \
|
||||
ESP_LOGE(TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
|
||||
audio_hal_handle_t
|
||||
audio_hal_init (audio_hal_codec_config_t *audio_hal_conf,
|
||||
audio_hal_func_t *audio_hal_func)
|
||||
{
|
||||
audio_hal_handle_t audio_hal_init(audio_hal_codec_config_t *audio_hal_conf,
|
||||
audio_hal_func_t *audio_hal_func) {
|
||||
esp_err_t ret = 0;
|
||||
audio_hal_handle_t audio_hal
|
||||
= (audio_hal_handle_t)audio_calloc (1, sizeof (audio_hal_func_t));
|
||||
AUDIO_MEM_CHECK (TAG, audio_hal, return NULL);
|
||||
memcpy (audio_hal, audio_hal_func, sizeof (audio_hal_func_t));
|
||||
audio_hal->audio_hal_lock = mutex_create ();
|
||||
audio_hal_handle_t audio_hal =
|
||||
(audio_hal_handle_t)audio_calloc(1, sizeof(audio_hal_func_t));
|
||||
AUDIO_MEM_CHECK(TAG, audio_hal, return NULL);
|
||||
memcpy(audio_hal, audio_hal_func, sizeof(audio_hal_func_t));
|
||||
audio_hal->audio_hal_lock = mutex_create();
|
||||
|
||||
AUDIO_MEM_CHECK (TAG, audio_hal->audio_hal_lock, {
|
||||
audio_free (audio_hal);
|
||||
AUDIO_MEM_CHECK(TAG, audio_hal->audio_hal_lock, {
|
||||
audio_free(audio_hal);
|
||||
return NULL;
|
||||
});
|
||||
mutex_lock (audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_initialize (audio_hal_conf);
|
||||
if (ret == ESP_FAIL)
|
||||
{
|
||||
audio_free (audio_hal);
|
||||
if (audio_hal_func->handle)
|
||||
{
|
||||
return audio_hal_func->handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE (TAG, "codec init failed!");
|
||||
return NULL;
|
||||
}
|
||||
mutex_lock(audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_initialize(audio_hal_conf);
|
||||
if (ret == ESP_FAIL) {
|
||||
audio_free(audio_hal);
|
||||
if (audio_hal_func->handle) {
|
||||
return audio_hal_func->handle;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "codec init failed!");
|
||||
return NULL;
|
||||
}
|
||||
ret |= audio_hal->audio_codec_config_iface (audio_hal_conf->codec_mode,
|
||||
&audio_hal_conf->i2s_iface);
|
||||
ret |= audio_hal->audio_codec_set_volume (AUDIO_HAL_VOL_DEFAULT);
|
||||
}
|
||||
ret |= audio_hal->audio_codec_config_iface(audio_hal_conf->codec_mode,
|
||||
&audio_hal_conf->i2s_iface);
|
||||
ret |= audio_hal->audio_codec_set_volume(AUDIO_HAL_VOL_DEFAULT);
|
||||
AUDIO_RET_ON_FALSE(TAG, ret, return NULL, "audio_hal_init failed");
|
||||
audio_hal->handle = audio_hal;
|
||||
audio_hal_func->handle = audio_hal;
|
||||
mutex_unlock (audio_hal->audio_hal_lock);
|
||||
mutex_unlock(audio_hal->audio_hal_lock);
|
||||
return audio_hal;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
audio_hal_deinit (audio_hal_handle_t audio_hal)
|
||||
{
|
||||
esp_err_t audio_hal_deinit(audio_hal_handle_t audio_hal) {
|
||||
esp_err_t ret;
|
||||
AUDIO_HAL_CHECK_NULL (audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_destroy (audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_deinitialize ();
|
||||
AUDIO_HAL_CHECK_NULL(audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_destroy(audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_deinitialize();
|
||||
audio_hal->audio_hal_lock = NULL;
|
||||
audio_hal->handle = NULL;
|
||||
audio_free (audio_hal);
|
||||
audio_free(audio_hal);
|
||||
audio_hal = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
audio_hal_ctrl_codec (audio_hal_handle_t audio_hal,
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t audio_hal_state)
|
||||
{
|
||||
esp_err_t audio_hal_ctrl_codec(audio_hal_handle_t audio_hal,
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t audio_hal_state) {
|
||||
esp_err_t ret;
|
||||
AUDIO_HAL_CHECK_NULL (audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_lock (audio_hal->audio_hal_lock);
|
||||
ESP_LOGI (TAG, "Codec mode is %d, Ctrl:%d", mode, audio_hal_state);
|
||||
ret = audio_hal->audio_codec_ctrl (mode, audio_hal_state);
|
||||
mutex_unlock (audio_hal->audio_hal_lock);
|
||||
AUDIO_HAL_CHECK_NULL(audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_lock(audio_hal->audio_hal_lock);
|
||||
ESP_LOGI(TAG, "Codec mode is %d, Ctrl:%d", mode, audio_hal_state);
|
||||
ret = audio_hal->audio_codec_ctrl(mode, audio_hal_state);
|
||||
mutex_unlock(audio_hal->audio_hal_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
audio_hal_codec_iface_config (audio_hal_handle_t audio_hal,
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface)
|
||||
{
|
||||
esp_err_t audio_hal_codec_iface_config(audio_hal_handle_t audio_hal,
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface) {
|
||||
esp_err_t ret = 0;
|
||||
AUDIO_HAL_CHECK_NULL (audio_hal, "audio_hal handle is null", -1);
|
||||
AUDIO_HAL_CHECK_NULL (iface, "Get volume para is null", -1);
|
||||
mutex_lock (audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_config_iface (mode, iface);
|
||||
mutex_unlock (audio_hal->audio_hal_lock);
|
||||
AUDIO_HAL_CHECK_NULL(audio_hal, "audio_hal handle is null", -1);
|
||||
AUDIO_HAL_CHECK_NULL(iface, "Get volume para is null", -1);
|
||||
mutex_lock(audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_config_iface(mode, iface);
|
||||
mutex_unlock(audio_hal->audio_hal_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
audio_hal_set_mute (audio_hal_handle_t audio_hal, bool mute)
|
||||
{
|
||||
esp_err_t audio_hal_set_mute(audio_hal_handle_t audio_hal, bool mute) {
|
||||
esp_err_t ret;
|
||||
AUDIO_HAL_CHECK_NULL (audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_lock (audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_set_mute (mute);
|
||||
mutex_unlock (audio_hal->audio_hal_lock);
|
||||
AUDIO_HAL_CHECK_NULL(audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_lock(audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_set_mute(mute);
|
||||
mutex_unlock(audio_hal->audio_hal_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
audio_hal_set_volume (audio_hal_handle_t audio_hal, int volume)
|
||||
{
|
||||
esp_err_t audio_hal_enable_pa(audio_hal_handle_t audio_hal, bool enable) {
|
||||
esp_err_t ret;
|
||||
AUDIO_HAL_CHECK_NULL (audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_lock (audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_set_volume (volume);
|
||||
mutex_unlock (audio_hal->audio_hal_lock);
|
||||
AUDIO_HAL_CHECK_NULL(audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_lock(audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_enable_pa(enable);
|
||||
mutex_unlock(audio_hal->audio_hal_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
audio_hal_get_volume (audio_hal_handle_t audio_hal, int *volume)
|
||||
{
|
||||
esp_err_t audio_hal_set_volume(audio_hal_handle_t audio_hal, int volume) {
|
||||
esp_err_t ret;
|
||||
AUDIO_HAL_CHECK_NULL (audio_hal, "audio_hal handle is null", -1);
|
||||
AUDIO_HAL_CHECK_NULL (volume, "Get volume para is null", -1);
|
||||
mutex_lock (audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_get_volume (volume);
|
||||
mutex_unlock (audio_hal->audio_hal_lock);
|
||||
AUDIO_HAL_CHECK_NULL(audio_hal, "audio_hal handle is null", -1);
|
||||
mutex_lock(audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_set_volume(volume);
|
||||
mutex_unlock(audio_hal->audio_hal_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t audio_hal_get_volume(audio_hal_handle_t audio_hal, int *volume) {
|
||||
esp_err_t ret;
|
||||
AUDIO_HAL_CHECK_NULL(audio_hal, "audio_hal handle is null", -1);
|
||||
AUDIO_HAL_CHECK_NULL(volume, "Get volume para is null", -1);
|
||||
mutex_lock(audio_hal->audio_hal_lock);
|
||||
ret = audio_hal->audio_codec_get_volume(volume);
|
||||
mutex_unlock(audio_hal->audio_hal_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
195
components/audio_hal/audio_volume.c
Normal file
195
components/audio_hal/audio_volume.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2022 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* |----------------Digital Gain---------------------|--Analog
|
||||
* Gain-|
|
||||
*
|
||||
* |--------------| |--------------------| |------------------|
|
||||
* |---------| |----------------| | Audio Stream |--->| Audio Process Gain
|
||||
* |--->| Codec DAC Volume |--->| PA Gain |--->| Speaker Output |
|
||||
* |--------------| |--------------------| |------------------|
|
||||
* |---------| |----------------|
|
||||
*
|
||||
* The speaker playback route is shown as the block diagram above. The speaker
|
||||
* loudness is affected by both audio Digital Gain and Analog Gain.
|
||||
*
|
||||
* Digital Gain:
|
||||
* Audio Process Gain: Audio Process, such as ALC, AGC, DRC target MAX Gain.
|
||||
* Codec DAC Volume: The audio codec DAC volume control, such as ES8311
|
||||
* DAC_Volume control register.
|
||||
*
|
||||
* Analog Gain:
|
||||
* PA Gain: The speaker power amplifier Gain, which is determined by the
|
||||
* hardware circuit board.
|
||||
*
|
||||
* User can control the speaker playback volume by adjusting Codec DAC Volume.
|
||||
*
|
||||
* We use volume level (1-100) to represent the volume levels, level 100 is the
|
||||
* MAX volume. We create a volume mapping index table for the user to set the
|
||||
* volume level through Codec DAC volume. The default mapping table maps volume
|
||||
* level(1-100) to Codec DAC Volume (-49.5dB, 0dB). The volume setting has 25
|
||||
* volume levels. Level step is 4, and the corresponding to Codec DAC Volume
|
||||
* Gain is 2 dB step. Normally, Codec DAC volume -50 dB reproduces a minimal
|
||||
* speaker loudness, and the 2 dB step allows the user to detect the volume
|
||||
* change.
|
||||
*
|
||||
* Gain and Decibel Reference:
|
||||
* https://www.espressif.com/zh-hans/media_overview/blog
|
||||
*
|
||||
*/
|
||||
|
||||
#include "audio_volume.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "audio_mem.h"
|
||||
|
||||
/**
|
||||
* The speaker playback route gain (Audio Process Gain + Codec DAC Volume + PA
|
||||
* Gain) needs to ensure that the speaker PA output is not saturated and exceeds
|
||||
* the speaker rated power. We define the maximum route gain as MAX_GAIN. To
|
||||
* ensure the speaker PA output is not saturated, MAX_GAIN can be calculated
|
||||
* simply by the formula. MAX_GAIN = 20 * log(Vpa/Vdac) Vpa: PA power supply
|
||||
* Vdac: Codec DAC power supply
|
||||
* e.g., Vpa = 5V, Vdac = 3.3V, then MAX_GAIN = 20 * log(5/3.3) = 3.6 dB.
|
||||
* If the speaker rated power is lower than the speaker PA MAX power, MAX_GAIN
|
||||
* should be defined according to the speaker rated power.
|
||||
*
|
||||
*/
|
||||
#define VPA (5.0)
|
||||
#define VDAC (3.3)
|
||||
#define MAX_GAIN (20.0 * log10(VPA / VDAC))
|
||||
|
||||
/*
|
||||
* User can customize the volume setting by modifying the mapping table and
|
||||
* adjust the volume step according to the speaker playback system, and the
|
||||
* other volume levels shift the value accordingly. Integers are used instead of
|
||||
* floating-point variables to reduce storage space. -80 means -40 dB, 0 means 0
|
||||
* dB.
|
||||
*/
|
||||
static const int8_t dac_volume_offset[] = {
|
||||
-99, -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85,
|
||||
-84, -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70,
|
||||
-69, -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55,
|
||||
-54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40,
|
||||
-39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25,
|
||||
-24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10,
|
||||
-9, -8, -7, -6, -5, -4, -3, -2, -1, 0};
|
||||
|
||||
/**
|
||||
* @brief Get DAC volume offset from user set volume, you can use an array or
|
||||
* function to finish this map
|
||||
*
|
||||
* @note The max DAC volume is 0 dB when the user volume is 100. 0 dB means
|
||||
* there is no attenuation of the sound source, and it is the original sound
|
||||
* source. It can not exceed 0 dB. Otherwise, there is a risk of clipping noise.
|
||||
* @note For better audio dynamic range, we'd better use 0dB full scale digital
|
||||
* gain and lower analog gain.
|
||||
* @note DAC volume offset is positively correlated with the user volume.
|
||||
*
|
||||
* @param volume User set volume (1-100)
|
||||
*
|
||||
* @return
|
||||
* - Codec DAC volume offset. The max value must be 0 dB.
|
||||
*/
|
||||
static inline float codec_get_dac_volume_offset(int volume) {
|
||||
float offset = dac_volume_offset[volume - 1] / 2.0;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The register value is linear to the dac_volume
|
||||
*/
|
||||
static inline uint8_t audio_codec_calculate_reg(volume_handle_t vol_handle,
|
||||
float dac_volume) {
|
||||
codec_dac_volume_config_t *handle = (codec_dac_volume_config_t *)vol_handle;
|
||||
uint8_t reg = (uint8_t)(dac_volume / (handle->dac_vol_symbol *
|
||||
handle->volume_accuracy) +
|
||||
handle->zero_volume_reg);
|
||||
return reg;
|
||||
}
|
||||
|
||||
volume_handle_t audio_codec_volume_init(codec_dac_volume_config_t *config) {
|
||||
codec_dac_volume_config_t *handle = (codec_dac_volume_config_t *)audio_calloc(
|
||||
1, sizeof(codec_dac_volume_config_t));
|
||||
memcpy(handle, config, sizeof(codec_dac_volume_config_t));
|
||||
if (!handle->offset_conv_volume) {
|
||||
handle->offset_conv_volume = codec_get_dac_volume_offset;
|
||||
}
|
||||
return (volume_handle_t)handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Take zero dac_volume as the origin and calculate the volume offset
|
||||
* according to the register value
|
||||
*/
|
||||
float audio_codec_cal_dac_volume(volume_handle_t vol_handle) {
|
||||
codec_dac_volume_config_t *handle = (codec_dac_volume_config_t *)vol_handle;
|
||||
float dac_volume = handle->dac_vol_symbol * handle->volume_accuracy *
|
||||
(handle->reg_value - handle->zero_volume_reg);
|
||||
return dac_volume;
|
||||
}
|
||||
|
||||
uint8_t audio_codec_get_dac_reg_value(volume_handle_t vol_handle, int volume) {
|
||||
float dac_volume = 0;
|
||||
int user_volume = volume;
|
||||
codec_dac_volume_config_t *handle = (codec_dac_volume_config_t *)vol_handle;
|
||||
|
||||
if (user_volume < 0) {
|
||||
user_volume = 0;
|
||||
} else if (user_volume > 100) {
|
||||
user_volume = 100;
|
||||
}
|
||||
|
||||
if (user_volume == 0) {
|
||||
dac_volume =
|
||||
handle->min_dac_volume; // Make sure the speaker voice is near silent
|
||||
} else {
|
||||
/*
|
||||
* For better audio performance, at the max volume, we need to ensure:
|
||||
* Audio Process Gain + Codec DAC Volume + PA Gain <= MAX_GAIN.
|
||||
* The PA Gain and Audio Process Gain are known when the board design is
|
||||
* fixed, so max Codec DAC Volume = MAX_GAIN - PA Gain - Audio Process
|
||||
* Gain,then the volume mapping table shift accordingly.
|
||||
*/
|
||||
dac_volume = handle->offset_conv_volume(user_volume) + MAX_GAIN -
|
||||
handle->board_pa_gain;
|
||||
dac_volume = dac_volume < handle->max_dac_volume ? dac_volume
|
||||
: handle->max_dac_volume;
|
||||
}
|
||||
handle->reg_value = audio_codec_calculate_reg(handle, dac_volume);
|
||||
handle->user_volume = user_volume;
|
||||
return handle->reg_value;
|
||||
}
|
||||
|
||||
void audio_codec_volume_deinit(volume_handle_t vol_handle) {
|
||||
if (vol_handle) {
|
||||
audio_free(vol_handle);
|
||||
vol_handle = NULL;
|
||||
}
|
||||
}
|
||||
@@ -20,5 +20,5 @@ COMPONENT_ADD_LDFLAGS += -L$(COMPONENT_PATH)/driver/zl38063/firmware -lfirmware
|
||||
COMPONENT_ADD_INCLUDEDIRS += ./driver/tas5805m ./driver/es7148
|
||||
COMPONENT_SRCDIRS += ./driver/tas5805m ./driver/es7148
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS += ./driver/es7210
|
||||
COMPONENT_SRCDIRS += ./driver/es7210
|
||||
COMPONENT_ADD_INCLUDEDIRS += ./driver/es7210 ./driver/es8156 ./driver/es7243e
|
||||
COMPONENT_SRCDIRS += ./driver/es7210 ./driver/es8156 ./driver/es7243e
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,13 +18,14 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "es7148.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
@@ -34,72 +35,52 @@ static const char *TAG = "es7148";
|
||||
static bool codec_init_flag = 0;
|
||||
|
||||
audio_hal_func_t AUDIO_CODEC_ES7148_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = es7148_codec_init,
|
||||
.audio_codec_deinitialize = es7148_codec_deinit,
|
||||
.audio_codec_ctrl = es7148_codec_ctrl_state,
|
||||
.audio_codec_config_iface = es7148_codec_config_i2s,
|
||||
.audio_codec_set_mute = es7148_codec_set_voice_mute,
|
||||
.audio_codec_set_volume = es7148_codec_set_voice_volume,
|
||||
.audio_codec_get_volume = es7148_codec_get_voice_volume,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
.audio_codec_initialize = es7148_codec_init,
|
||||
.audio_codec_deinitialize = es7148_codec_deinit,
|
||||
.audio_codec_ctrl = es7148_codec_ctrl_state,
|
||||
.audio_codec_config_iface = es7148_codec_config_i2s,
|
||||
.audio_codec_set_mute = es7148_codec_set_voice_mute,
|
||||
.audio_codec_set_volume = es7148_codec_set_voice_volume,
|
||||
.audio_codec_get_volume = es7148_codec_get_voice_volume,
|
||||
.audio_codec_enable_pa = NULL,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
static bool
|
||||
es7148_codec_initialized ()
|
||||
{
|
||||
return codec_init_flag;
|
||||
}
|
||||
static bool es7148_codec_initialized() { return codec_init_flag; }
|
||||
|
||||
esp_err_t
|
||||
es7148_codec_init (audio_hal_codec_config_t *cfg)
|
||||
{
|
||||
if (es7148_codec_initialized ())
|
||||
{
|
||||
ESP_LOGW (TAG, "The es7148 codec has been already initialized");
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t es7148_codec_init(audio_hal_codec_config_t *cfg) {
|
||||
if (es7148_codec_initialized()) {
|
||||
ESP_LOGW(TAG, "The es7148 codec has been already initialized");
|
||||
return ESP_OK;
|
||||
}
|
||||
codec_init_flag = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7148_codec_deinit (void)
|
||||
{
|
||||
esp_err_t es7148_codec_deinit(void) {
|
||||
codec_init_flag = false;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7148_codec_ctrl_state (audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state)
|
||||
{
|
||||
esp_err_t es7148_codec_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7148_codec_config_i2s (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface)
|
||||
{
|
||||
esp_err_t es7148_codec_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7148_codec_set_voice_mute (bool mute)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t es7148_codec_set_voice_mute(bool mute) { return ESP_OK; }
|
||||
|
||||
esp_err_t
|
||||
es7148_codec_set_voice_volume (int volume)
|
||||
{
|
||||
esp_err_t es7148_codec_set_voice_volume(int volume) {
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7148_codec_get_voice_volume (int *volume)
|
||||
{
|
||||
esp_err_t es7148_codec_get_voice_volume(int *volume) {
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -30,92 +30,91 @@
|
||||
#include "audio_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize es7148 chip
|
||||
*
|
||||
* @param cfg configuration of es7148
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_codec_init (audio_hal_codec_config_t *cfg);
|
||||
/**
|
||||
* @brief Deinitialize es7148 chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_codec_deinit (void);
|
||||
/**
|
||||
* The functions es7148_ctrl_state and es7148_config_i2s are not used by this
|
||||
* driver. They are kept here to maintain the uniformity and convenience of
|
||||
* the interface of the ADF project. These settings for es7148 are burned in
|
||||
* firmware and configuration files. Default i2s configuration: 48000Hz,
|
||||
* 16bit, Left-Right channels. Use resampling to be compatible with different
|
||||
* file types.
|
||||
*
|
||||
* @brief Control es7148 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 es7148_codec_ctrl_state (audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
/**
|
||||
* @brief Configure es7148 codec mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es7148_codec_config_i2s (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
/**
|
||||
* @brief Initialize es7148 chip
|
||||
*
|
||||
* @param cfg configuration of es7148
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_codec_init(audio_hal_codec_config_t *cfg);
|
||||
/**
|
||||
* @brief Deinitialize es7148 chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_codec_deinit(void);
|
||||
/**
|
||||
* The functions es7148_ctrl_state and es7148_config_i2s are not used by this
|
||||
* driver. They are kept here to maintain the uniformity and convenience of the
|
||||
* interface of the ADF project. These settings for es7148 are burned in
|
||||
* firmware and configuration files. Default i2s configuration: 48000Hz, 16bit,
|
||||
* Left-Right channels. Use resampling to be compatible with different file
|
||||
* types.
|
||||
*
|
||||
* @brief Control es7148 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 es7148_codec_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
/**
|
||||
* @brief Configure es7148 codec mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es7148_codec_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
/**
|
||||
* @brief mute or unmute the codec
|
||||
*
|
||||
* @param mute: true, false
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_codec_set_voice_mute (bool mute);
|
||||
/**
|
||||
* @brief mute or unmute the codec
|
||||
*
|
||||
* @param mute: true, false
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_codec_set_voice_mute(bool mute);
|
||||
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_codec_set_voice_volume (int volume);
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_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 es7148_codec_get_voice_volume (int *volume);
|
||||
/**
|
||||
* @brief Get voice volume
|
||||
*
|
||||
* @param[out] *volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7148_codec_get_voice_volume(int *volume);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,22 +18,24 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "es7210.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "esp_log.h"
|
||||
#include "i2c_bus.h"
|
||||
#include <string.h>
|
||||
|
||||
#define I2S_DSP_MODE 0
|
||||
#define MCLK_DIV_FRE 256
|
||||
|
||||
/* ES7210 address*/
|
||||
/* ES7210 address */
|
||||
#define ES7210_ADDR ES7210_AD1_AD0_00
|
||||
#define ES7210_MCLK_SOURCE \
|
||||
FROM_CLOCK_DOUBLE_PIN /* In master mode, 0 : MCLK from pad 1 : MCLK from \
|
||||
@@ -41,25 +43,42 @@
|
||||
#define FROM_PAD_PIN 0
|
||||
#define FROM_CLOCK_DOUBLE_PIN 1
|
||||
|
||||
/* ES7210 mic select */
|
||||
#if CONFIG_ESP32_S3_KORVO2_V3_BOARD
|
||||
#define ES7210_MIC_SELECT \
|
||||
ES7210_INPUT_MIC1 | ES7210_INPUT_MIC2 | ES7210_INPUT_MIC3
|
||||
#else
|
||||
#define ES7210_MIC_SELECT ES7210_INPUT_MIC1 | ES7210_INPUT_MIC2
|
||||
#endif
|
||||
#define ENABLE_TDM_MAX_NUM 3
|
||||
|
||||
static char *TAG = "ES7210";
|
||||
|
||||
static struct {
|
||||
i2c_bus_handle_t i2c_handle;
|
||||
es7210_input_mics_t mic_select;
|
||||
es7210_gain_value_t gain;
|
||||
} es7210_handle;
|
||||
|
||||
/*
|
||||
* Operate function of ADC
|
||||
*/
|
||||
audio_hal_func_t AUDIO_CODEC_ES7210_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = es7210_adc_init,
|
||||
.audio_codec_deinitialize = es7210_adc_deinit,
|
||||
.audio_codec_ctrl = es7210_adc_ctrl_state,
|
||||
.audio_codec_config_iface = es7210_adc_config_i2s,
|
||||
.audio_codec_set_mute = es7210_set_mute,
|
||||
.audio_codec_set_volume = es7210_adc_set_volume,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
.audio_codec_initialize = es7210_adc_init,
|
||||
.audio_codec_deinitialize = es7210_adc_deinit,
|
||||
.audio_codec_ctrl = es7210_adc_ctrl_state,
|
||||
.audio_codec_config_iface = es7210_adc_config_i2s,
|
||||
.audio_codec_set_mute = es7210_set_mute,
|
||||
.audio_codec_set_volume = es7210_adc_set_volume,
|
||||
.audio_codec_enable_pa = NULL,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock coefficient structer
|
||||
*/
|
||||
struct _coeff_div
|
||||
{
|
||||
struct _coeff_div {
|
||||
uint32_t mclk; /* mclk frequency */
|
||||
uint32_t lrck; /* lrck */
|
||||
uint8_t ss_ds;
|
||||
@@ -72,11 +91,6 @@ struct _coeff_div
|
||||
uint32_t lrck_l; /* The low 8 bits of lrck */
|
||||
};
|
||||
|
||||
static char *TAG = "ES7210";
|
||||
static i2c_bus_handle_t i2c_handle;
|
||||
static es7210_input_mics_t mic_select
|
||||
= ES7210_INPUT_MIC1 | ES7210_INPUT_MIC2; /* Number of microphones */
|
||||
|
||||
/* Codec hifi mclk clock divider coefficients
|
||||
* MEMBER REG
|
||||
* mclk: 0x03
|
||||
@@ -91,125 +105,106 @@ static es7210_input_mics_t mic_select
|
||||
* 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 },
|
||||
// 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* 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)
|
||||
{
|
||||
return i2c_bus_write_bytes (i2c_handle, ES7210_ADDR, ®_addr,
|
||||
sizeof (reg_addr), &data, sizeof (data));
|
||||
static esp_err_t es7210_write_reg(uint8_t reg_addr, uint8_t data) {
|
||||
return i2c_bus_write_bytes(es7210_handle.i2c_handle, ES7210_ADDR, ®_addr,
|
||||
sizeof(reg_addr), &data, sizeof(data));
|
||||
}
|
||||
|
||||
static esp_err_t
|
||||
es7210_update_reg_bit (uint8_t reg_addr, uint8_t update_bits, uint8_t data)
|
||||
{
|
||||
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 = es7210_read_reg(reg_addr);
|
||||
regv = (regv & (~update_bits)) | (update_bits & data);
|
||||
return es7210_write_reg (reg_addr, regv);
|
||||
return es7210_write_reg(reg_addr, regv);
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_init ()
|
||||
{
|
||||
static int i2c_init() {
|
||||
int ret = 0;
|
||||
i2c_config_t es_i2c_cfg = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000,
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000,
|
||||
};
|
||||
ret = get_i2c_pins (I2C_NUM_0, &es_i2c_cfg);
|
||||
AUDIO_CHECK (TAG, !ret, return ESP_FAIL;, "getting i2c pins error");
|
||||
i2c_handle = i2c_bus_create (I2C_NUM_0, &es_i2c_cfg);
|
||||
ret = get_i2c_pins(I2C_NUM_0, &es_i2c_cfg);
|
||||
AUDIO_RET_ON_FALSE(TAG, ret, return ESP_FAIL, "getting i2c pins error");
|
||||
es7210_handle.i2c_handle = i2c_bus_create(I2C_NUM_0, &es_i2c_cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
int8_t get_es7210_mclk_src(void) { return ES7210_MCLK_SOURCE; }
|
||||
|
||||
int
|
||||
es7210_read_reg (uint8_t reg_addr)
|
||||
{
|
||||
int es7210_read_reg(uint8_t reg_addr) {
|
||||
uint8_t data;
|
||||
i2c_bus_read_bytes (i2c_handle, ES7210_ADDR, ®_addr, sizeof (reg_addr),
|
||||
&data, sizeof (data));
|
||||
i2c_bus_read_bytes(es7210_handle.i2c_handle, ES7210_ADDR, ®_addr,
|
||||
sizeof(reg_addr), &data, sizeof(data));
|
||||
return (int)data;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_config_sample (audio_hal_iface_samples_t sample)
|
||||
{
|
||||
uint8_t regv;
|
||||
esp_err_t es7210_config_sample(audio_hal_iface_samples_t sample) {
|
||||
int coeff;
|
||||
int sample_fre = 0;
|
||||
int mclk_fre = 0;
|
||||
esp_err_t ret = ESP_OK;
|
||||
switch (sample)
|
||||
{
|
||||
switch (sample) {
|
||||
case AUDIO_HAL_08K_SAMPLES:
|
||||
sample_fre = 8000;
|
||||
break;
|
||||
@@ -235,205 +230,202 @@ es7210_config_sample (audio_hal_iface_samples_t sample)
|
||||
sample_fre = 48000;
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE (TAG, "Unable to configure sample rate %dHz", sample_fre);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (coeff >= 0) {
|
||||
/* Set adc_div & doubler & dll */
|
||||
uint8_t regv;
|
||||
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 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);
|
||||
}
|
||||
uint16_t mic_num = 0;
|
||||
es7210_handle.mic_select = mic;
|
||||
if (es7210_handle.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);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE (TAG, "Microphone selection error");
|
||||
return ESP_FAIL;
|
||||
ret |= es7210_write_reg(ES7210_MIC12_POWER_REG4B, 0xff);
|
||||
ret |= es7210_write_reg(ES7210_MIC34_POWER_REG4C, 0xff);
|
||||
if (es7210_handle.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);
|
||||
ret |= es7210_update_reg_bit(ES7210_MIC1_GAIN_REG43, 0x0f,
|
||||
es7210_handle.gain);
|
||||
}
|
||||
if (es7210_handle.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);
|
||||
ret |= es7210_update_reg_bit(ES7210_MIC2_GAIN_REG44, 0x0f,
|
||||
es7210_handle.gain);
|
||||
}
|
||||
if (es7210_handle.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);
|
||||
ret |= es7210_update_reg_bit(ES7210_MIC3_GAIN_REG45, 0x0f,
|
||||
es7210_handle.gain);
|
||||
}
|
||||
if (es7210_handle.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);
|
||||
ret |= es7210_update_reg_bit(ES7210_MIC4_GAIN_REG46, 0x0f,
|
||||
es7210_handle.gain);
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Microphone selection error");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
for (int i = ES7210_INPUT_MIC1; i <= ES7210_INPUT_MIC4; i = i << 1) {
|
||||
if (es7210_handle.mic_select & i) {
|
||||
mic_num++;
|
||||
}
|
||||
}
|
||||
if (mic_num >= ENABLE_TDM_MAX_NUM) {
|
||||
ret |= es7210_write_reg(ES7210_SDP_INTERFACE2_REG12, 0x02);
|
||||
ESP_LOGW(TAG, "Enable TDM mode. ES7210_SDP_INTERFACE2_REG12: %X",
|
||||
es7210_read_reg(ES7210_SDP_INTERFACE2_REG12));
|
||||
} else {
|
||||
ret |= es7210_write_reg(ES7210_SDP_INTERFACE2_REG12, 0x00);
|
||||
ESP_LOGW(TAG, "Disable TDM mode. ES7210_SDP_INTERFACE2_REG12: %X",
|
||||
es7210_read_reg(ES7210_SDP_INTERFACE2_REG12));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_adc_init (audio_hal_codec_config_t *codec_cfg)
|
||||
{
|
||||
esp_err_t es7210_adc_init(audio_hal_codec_config_t *codec_cfg) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
i2c_init ();
|
||||
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);
|
||||
i2c_init();
|
||||
ret |= es7210_write_reg(ES7210_RESET_REG00, 0xff);
|
||||
ret |= es7210_write_reg(ES7210_RESET_REG00, 0x41);
|
||||
ret |= es7210_write_reg(ES7210_CLOCK_OFF_REG01, 0x3f);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
ESP_LOGI(TAG, "ES7210 in Master mode");
|
||||
ret |= es7210_update_reg_bit(ES7210_MODE_CONFIG_REG08, 0x01, 0x01);
|
||||
/* Select clock source for internal mclk */
|
||||
switch (get_es7210_mclk_src ())
|
||||
{
|
||||
switch (get_es7210_mclk_src()) {
|
||||
case FROM_PAD_PIN:
|
||||
ret |= es7210_update_reg_bit (ES7210_MASTER_CLK_REG03, 0x80, 0x00);
|
||||
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);
|
||||
ret |= es7210_update_reg_bit(ES7210_MASTER_CLK_REG03, 0x80, 0x80);
|
||||
break;
|
||||
default:
|
||||
ret |= es7210_update_reg_bit (ES7210_MASTER_CLK_REG03, 0x80, 0x00);
|
||||
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");
|
||||
ret |= es7210_update_reg_bit (ES7210_MODE_CONFIG_REG08, 0x01, 0x00);
|
||||
ESP_LOGI(TAG, "ES7210 in Slave mode");
|
||||
ret |= es7210_update_reg_bit(ES7210_MODE_CONFIG_REG08, 0x01, 0x00);
|
||||
break;
|
||||
default:
|
||||
ret |= es7210_update_reg_bit (ES7210_MODE_CONFIG_REG08, 0x01, 0x00);
|
||||
}
|
||||
ret |= es7210_write_reg (ES7210_ANALOG_REG40,
|
||||
0x43); /* 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 (
|
||||
ret |= es7210_update_reg_bit(ES7210_MODE_CONFIG_REG08, 0x01, 0x00);
|
||||
}
|
||||
ret |= es7210_write_reg(ES7210_ANALOG_REG40,
|
||||
0x43); /* 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 (GAIN_30DB);
|
||||
ret |= es7210_config_sample(i2s_cfg->samples);
|
||||
ret |= es7210_mic_select(ES7210_MIC_SELECT);
|
||||
ret |= es7210_adc_set_gain(GAIN_24DB);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_adc_deinit ()
|
||||
{
|
||||
i2c_bus_delete (i2c_handle);
|
||||
esp_err_t es7210_adc_deinit() {
|
||||
i2c_bus_delete(es7210_handle.i2c_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_config_fmt (audio_hal_iface_format_t fmt)
|
||||
{
|
||||
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 = es7210_read_reg(ES7210_SDP_INTERFACE1_REG11);
|
||||
adc_iface &= 0xfc;
|
||||
switch (fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case AUDIO_HAL_I2S_NORMAL:
|
||||
ESP_LOGD (TAG, "ES7210 in I2S Format");
|
||||
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");
|
||||
ESP_LOGD(TAG, "ES7210 in LJ Format");
|
||||
adc_iface |= 0x01;
|
||||
break;
|
||||
case AUDIO_HAL_I2S_DSP:
|
||||
if (I2S_DSP_MODE)
|
||||
{
|
||||
ESP_LOGD (TAG, "ES7210 in DSP-A Format");
|
||||
adc_iface |= 0x13;
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGD (TAG, "ES7210 in DSP-B Format");
|
||||
adc_iface |= 0x03;
|
||||
}
|
||||
if (I2S_DSP_MODE) {
|
||||
ESP_LOGD(TAG, "ES7210 in DSP-A Format");
|
||||
adc_iface |= 0x13;
|
||||
} else {
|
||||
ESP_LOGD(TAG, "ES7210 in DSP-B Format");
|
||||
adc_iface |= 0x03;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
adc_iface &= 0xfc;
|
||||
break;
|
||||
}
|
||||
ret |= es7210_write_reg (ES7210_SDP_INTERFACE1_REG11, adc_iface);
|
||||
}
|
||||
ret |= es7210_write_reg(ES7210_SDP_INTERFACE1_REG11, adc_iface);
|
||||
ESP_LOGI(TAG, "config fmt %X", adc_iface);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_set_bits (audio_hal_iface_bits_t bits)
|
||||
{
|
||||
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 = es7210_read_reg(ES7210_SDP_INTERFACE1_REG11);
|
||||
adc_iface &= 0x1f;
|
||||
switch (bits)
|
||||
{
|
||||
switch (bits) {
|
||||
case AUDIO_HAL_BIT_LENGTH_16BITS:
|
||||
adc_iface |= 0x60;
|
||||
break;
|
||||
@@ -446,169 +438,132 @@ es7210_set_bits (audio_hal_iface_bits_t bits)
|
||||
default:
|
||||
adc_iface |= 0x60;
|
||||
break;
|
||||
}
|
||||
ret |= es7210_write_reg (ES7210_SDP_INTERFACE1_REG11, adc_iface);
|
||||
}
|
||||
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 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);
|
||||
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 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, 0x43);
|
||||
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);
|
||||
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, 0x43);
|
||||
ret |= es7210_write_reg(ES7210_MIC1_POWER_REG47, 0x08);
|
||||
ret |= es7210_write_reg(ES7210_MIC2_POWER_REG48, 0x08);
|
||||
ret |= es7210_write_reg(ES7210_MIC3_POWER_REG49, 0x08);
|
||||
ret |= es7210_write_reg(ES7210_MIC4_POWER_REG4A, 0x08);
|
||||
ret |= es7210_mic_select(es7210_handle.mic_select);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_stop (void)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
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 ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_adc_set_gain (es7210_gain_value_t gain)
|
||||
{
|
||||
esp_err_t es7210_adc_set_gain(es7210_gain_value_t gain) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint32_t max_gain_vaule = 14;
|
||||
if (gain < 0)
|
||||
{
|
||||
gain = 0;
|
||||
}
|
||||
else if (gain > max_gain_vaule)
|
||||
{
|
||||
gain = 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);
|
||||
}
|
||||
if (gain < 0) {
|
||||
gain = 0;
|
||||
} else if (gain > max_gain_vaule) {
|
||||
gain = max_gain_vaule;
|
||||
}
|
||||
ESP_LOGD(TAG, "SET: gain:%d", gain);
|
||||
if (es7210_handle.mic_select & ES7210_INPUT_MIC1) {
|
||||
ret |= es7210_update_reg_bit(ES7210_MIC1_GAIN_REG43, 0x0f, gain);
|
||||
}
|
||||
if (es7210_handle.mic_select & ES7210_INPUT_MIC2) {
|
||||
ret |= es7210_update_reg_bit(ES7210_MIC2_GAIN_REG44, 0x0f, gain);
|
||||
}
|
||||
if (es7210_handle.mic_select & ES7210_INPUT_MIC3) {
|
||||
ret |= es7210_update_reg_bit(ES7210_MIC3_GAIN_REG45, 0x0f, gain);
|
||||
}
|
||||
if (es7210_handle.mic_select & ES7210_INPUT_MIC4) {
|
||||
ret |= es7210_update_reg_bit(ES7210_MIC4_GAIN_REG46, 0x0f, gain);
|
||||
}
|
||||
es7210_handle.gain = gain;
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_adc_get_gain (void)
|
||||
{
|
||||
esp_err_t es7210_adc_get_gain(void) {
|
||||
int regv = 0;
|
||||
uint8_t gain_value;
|
||||
if (mic_select & ES7210_INPUT_MIC1)
|
||||
{
|
||||
regv = es7210_read_reg (ES7210_MIC1_GAIN_REG43);
|
||||
}
|
||||
else if (mic_select & ES7210_INPUT_MIC2)
|
||||
{
|
||||
regv = es7210_read_reg (ES7210_MIC2_GAIN_REG44);
|
||||
}
|
||||
else if (mic_select & ES7210_INPUT_MIC3)
|
||||
{
|
||||
regv = es7210_read_reg (ES7210_MIC3_GAIN_REG45);
|
||||
}
|
||||
else if (mic_select & 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;
|
||||
}
|
||||
if (es7210_handle.mic_select & ES7210_INPUT_MIC1) {
|
||||
regv = es7210_read_reg(ES7210_MIC1_GAIN_REG43);
|
||||
} else if (es7210_handle.mic_select & ES7210_INPUT_MIC2) {
|
||||
regv = es7210_read_reg(ES7210_MIC2_GAIN_REG44);
|
||||
} else if (es7210_handle.mic_select & ES7210_INPUT_MIC3) {
|
||||
regv = es7210_read_reg(ES7210_MIC3_GAIN_REG45);
|
||||
} else if (es7210_handle.mic_select & 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 */
|
||||
ESP_LOGI (TAG, "GET: gain_value:%d", gain_value);
|
||||
ESP_LOGI(TAG, "GET: gain_value:%d", gain_value);
|
||||
return gain_value;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_adc_set_volume (int volume)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_LOGD (TAG, "ADC can adjust gain");
|
||||
esp_err_t es7210_adc_set_volume(int volume) {
|
||||
ESP_LOGD(TAG, "ADC can adjust gain");
|
||||
if (volume > GAIN_37_5DB) {
|
||||
volume = GAIN_37_5DB;
|
||||
}
|
||||
esp_err_t ret = es7210_adc_set_gain(volume);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7210_set_mute (bool enable)
|
||||
{
|
||||
ESP_LOGD (TAG, "ES7210 SetMute :%d", enable);
|
||||
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);
|
||||
}
|
||||
void es7210_read_all(void) {
|
||||
for (int i = 0; i <= 0x4E; i++) {
|
||||
uint8_t reg = es7210_read_reg(i);
|
||||
ESP_LOGI(TAG, "REG:%02x, %02x", reg, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
#include "audio_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ES7210_RESET_REG00 0x00 /* Reset control */
|
||||
@@ -67,165 +66,162 @@ extern "C"
|
||||
#define ES7210_MIC12_POWER_REG4B 0x4B /* MICBias & ADC & PGA Power */
|
||||
#define ES7210_MIC34_POWER_REG4C 0x4C
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ES7210_AD1_AD0_00 = 0x80,
|
||||
ES7210_AD1_AD0_01 = 0x82,
|
||||
ES7210_AD1_AD0_10 = 0x84,
|
||||
ES7210_AD1_AD0_11 = 0x86
|
||||
} es7210_address_t;
|
||||
typedef enum {
|
||||
ES7210_AD1_AD0_00 = 0x80,
|
||||
ES7210_AD1_AD0_01 = 0x82,
|
||||
ES7210_AD1_AD0_10 = 0x84,
|
||||
ES7210_AD1_AD0_11 = 0x86
|
||||
} es7210_address_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ES7210_INPUT_MIC1 = 0x01,
|
||||
ES7210_INPUT_MIC2 = 0x02,
|
||||
ES7210_INPUT_MIC3 = 0x04,
|
||||
ES7210_INPUT_MIC4 = 0x08
|
||||
} es7210_input_mics_t;
|
||||
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;
|
||||
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 (audio_hal_codec_config_t *codec_cfg);
|
||||
/*
|
||||
* @brief Initialize ES7210 ADC chip
|
||||
*
|
||||
* @param[in] codec_cfg: configuration of ES7210
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7210_adc_init(audio_hal_codec_config_t *codec_cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ES7210 ADC chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7210_adc_deinit ();
|
||||
/**
|
||||
* @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 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 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 (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 (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(es7210_gain_value_t gain);
|
||||
|
||||
/**
|
||||
* @brief Get gain
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7210_adc_get_gain (void);
|
||||
/**
|
||||
* @brief Get gain
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7210_adc_get_gain(void);
|
||||
|
||||
/**
|
||||
* @brief Set volume
|
||||
*
|
||||
* @param[in] volume: volume
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es7210_adc_set_volume (int volume);
|
||||
/**
|
||||
* @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 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 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 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);
|
||||
/**
|
||||
* @brief Read all regs of ES7210
|
||||
*/
|
||||
void es7210_read_all(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,193 +18,165 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "es7243.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "esp_log.h"
|
||||
#include "i2c_bus.h"
|
||||
#include <string.h>
|
||||
|
||||
#define MCLK_PULSES_NUMBER (20)
|
||||
#define ES_ASSERT(a, format, b, ...) \
|
||||
if ((a) != 0) \
|
||||
{ \
|
||||
ESP_LOGE (TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
#define ES_ASSERT(a, format, b, ...) \
|
||||
if ((a) != 0) { \
|
||||
ESP_LOGE(TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
|
||||
static char *TAG = "DRV7243";
|
||||
static i2c_bus_handle_t i2c_handle;
|
||||
static int es7243_addr = 0x26;
|
||||
|
||||
audio_hal_func_t AUDIO_CODEC_ES7243_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = es7243_adc_init,
|
||||
.audio_codec_deinitialize = es7243_adc_deinit,
|
||||
.audio_codec_ctrl = es7243_adc_ctrl_state,
|
||||
.audio_codec_config_iface = es7243_adc_config_i2s,
|
||||
.audio_codec_set_mute = es7243_adc_set_voice_mute,
|
||||
.audio_codec_set_volume = es7243_adc_set_voice_volume,
|
||||
.audio_codec_get_volume = es7243_adc_get_voice_volume,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
.audio_codec_initialize = es7243_adc_init,
|
||||
.audio_codec_deinitialize = es7243_adc_deinit,
|
||||
.audio_codec_ctrl = es7243_adc_ctrl_state,
|
||||
.audio_codec_config_iface = es7243_adc_config_i2s,
|
||||
.audio_codec_set_mute = es7243_adc_set_voice_mute,
|
||||
.audio_codec_set_volume = es7243_adc_set_voice_volume,
|
||||
.audio_codec_get_volume = es7243_adc_get_voice_volume,
|
||||
.audio_codec_enable_pa = NULL,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
static esp_err_t
|
||||
es7243_write_reg (uint8_t reg_add, uint8_t data)
|
||||
{
|
||||
return i2c_bus_write_bytes (i2c_handle, es7243_addr, ®_add,
|
||||
sizeof (reg_add), &data, sizeof (data));
|
||||
static esp_err_t es7243_write_reg(uint8_t reg_add, uint8_t data) {
|
||||
return i2c_bus_write_bytes(i2c_handle, es7243_addr, ®_add, sizeof(reg_add),
|
||||
&data, sizeof(data));
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_init ()
|
||||
{
|
||||
static int i2c_init() {
|
||||
int res = 0;
|
||||
i2c_config_t es_i2c_cfg = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000,
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000,
|
||||
};
|
||||
res = get_i2c_pins (I2C_NUM_0, &es_i2c_cfg);
|
||||
ES_ASSERT (res, "getting i2c pins error", -1);
|
||||
i2c_handle = i2c_bus_create (I2C_NUM_0, &es_i2c_cfg);
|
||||
res = get_i2c_pins(I2C_NUM_0, &es_i2c_cfg);
|
||||
ES_ASSERT(res, "getting i2c pins error", -1);
|
||||
i2c_handle = i2c_bus_create(I2C_NUM_0, &es_i2c_cfg);
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7243_adc_set_addr (int addr)
|
||||
{
|
||||
esp_err_t es7243_adc_set_addr(int addr) {
|
||||
es7243_addr = addr;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t
|
||||
es7243_mclk_active (uint8_t mclk_gpio)
|
||||
{
|
||||
gpio_pad_select_gpio (mclk_gpio);
|
||||
gpio_set_direction (mclk_gpio, GPIO_MODE_OUTPUT);
|
||||
static esp_err_t es7243_mclk_active(uint8_t mclk_gpio) {
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
esp_rom_gpio_pad_select_gpio(mclk_gpio);
|
||||
#else
|
||||
gpio_pad_select_gpio(mclk_gpio);
|
||||
#endif
|
||||
gpio_set_direction(mclk_gpio, GPIO_MODE_OUTPUT);
|
||||
/*
|
||||
Before initializing es7243, it is necessary to output
|
||||
mclk to es7243 to activate the I2C configuration.
|
||||
So give some clocks to active es7243.
|
||||
*/
|
||||
for (int i = 0; i < MCLK_PULSES_NUMBER; ++i)
|
||||
{
|
||||
gpio_set_level (mclk_gpio, 0);
|
||||
vTaskDelay (1 / portTICK_PERIOD_MS);
|
||||
gpio_set_level (mclk_gpio, 1);
|
||||
vTaskDelay (1 / portTICK_PERIOD_MS);
|
||||
}
|
||||
for (int i = 0; i < MCLK_PULSES_NUMBER; ++i) {
|
||||
gpio_set_level(mclk_gpio, 0);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
gpio_set_level(mclk_gpio, 1);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7243_adc_init (audio_hal_codec_config_t *codec_cfg)
|
||||
{
|
||||
esp_err_t es7243_adc_init(audio_hal_codec_config_t *codec_cfg) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
es7243_mclk_active (get_es7243_mclk_gpio ());
|
||||
i2c_init ();
|
||||
ret |= es7243_write_reg (0x00, 0x01);
|
||||
ret |= es7243_write_reg (0x06, 0x00);
|
||||
ret |= es7243_write_reg (0x05, 0x1B);
|
||||
ret |= es7243_write_reg (0x01, 0x0C);
|
||||
ret |= es7243_write_reg (0x08, 0x43);
|
||||
ret |= es7243_write_reg (0x05, 0x13);
|
||||
if (ret)
|
||||
{
|
||||
ESP_LOGE (TAG, "Es7243 initialize failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
es7243_mclk_active(get_es7243_mclk_gpio());
|
||||
i2c_init();
|
||||
ret |= es7243_write_reg(0x00, 0x01);
|
||||
ret |= es7243_write_reg(0x06, 0x00);
|
||||
ret |= es7243_write_reg(0x05, 0x1B);
|
||||
ret |= es7243_write_reg(0x01, 0x0C);
|
||||
ret |= es7243_write_reg(0x08, 0x43);
|
||||
ret |= es7243_write_reg(0x05, 0x13);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "Es7243 initialize failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7243_adc_deinit (void)
|
||||
{
|
||||
esp_err_t es7243_adc_deinit(void) { return ESP_OK; }
|
||||
|
||||
esp_err_t es7243_adc_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7243_adc_ctrl_state (audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state)
|
||||
{
|
||||
esp_err_t es7243_adc_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7243_adc_config_i2s (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface)
|
||||
{
|
||||
esp_err_t es7243_adc_set_voice_mute(bool mute) {
|
||||
ESP_LOGI(TAG, "Enter into es7243_mute(), mute = %d\n", mute);
|
||||
if (mute) {
|
||||
es7243_write_reg(0x05, 0x1B);
|
||||
} else {
|
||||
es7243_write_reg(0x05, 0x13);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7243_adc_set_voice_mute (bool mute)
|
||||
{
|
||||
ESP_LOGI (TAG, "Enter into es7243_mute(), mute = %d\n", mute);
|
||||
if (mute)
|
||||
{
|
||||
es7243_write_reg (0x05, 0x1B);
|
||||
}
|
||||
else
|
||||
{
|
||||
es7243_write_reg (0x05, 0x13);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7243_adc_set_voice_volume (int volume)
|
||||
{
|
||||
esp_err_t es7243_adc_set_voice_volume(int volume) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
if (volume > 100)
|
||||
{
|
||||
volume = 100;
|
||||
}
|
||||
if (volume < 0)
|
||||
{
|
||||
volume = 0;
|
||||
}
|
||||
switch (volume)
|
||||
{
|
||||
if (volume > 100) {
|
||||
volume = 100;
|
||||
}
|
||||
if (volume < 0) {
|
||||
volume = 0;
|
||||
}
|
||||
switch (volume) {
|
||||
case 0 ... 12:
|
||||
ret |= es7243_write_reg (0x08, 0x11); // 1db
|
||||
ret |= es7243_write_reg(0x08, 0x11); // 1db
|
||||
break;
|
||||
case 13 ... 25:
|
||||
ret |= es7243_write_reg (0x08, 0x13); // 3.5db
|
||||
ret |= es7243_write_reg(0x08, 0x13); // 3.5db
|
||||
break;
|
||||
case 26 ... 38:
|
||||
ret |= es7243_write_reg (0x08, 0x21); // 18db
|
||||
ret |= es7243_write_reg(0x08, 0x21); // 18db
|
||||
break;
|
||||
case 39 ... 51:
|
||||
ret |= es7243_write_reg (0x08, 0x23); // 20.5db
|
||||
ret |= es7243_write_reg(0x08, 0x23); // 20.5db
|
||||
break;
|
||||
case 52 ... 65:
|
||||
ret |= es7243_write_reg (0x08, 0x06); // 22.5db
|
||||
ret |= es7243_write_reg(0x08, 0x06); // 22.5db
|
||||
break;
|
||||
case 66 ... 80:
|
||||
ret |= es7243_write_reg (0x08, 0x41); // 24.5db
|
||||
ret |= es7243_write_reg(0x08, 0x41); // 24.5db
|
||||
break;
|
||||
case 81 ... 90:
|
||||
ret |= es7243_write_reg (0x08, 0x07); // 25db
|
||||
ret |= es7243_write_reg(0x08, 0x07); // 25db
|
||||
break;
|
||||
case 91 ... 100:
|
||||
ret |= es7243_write_reg (0x08, 0x43); // 27db
|
||||
ret |= es7243_write_reg(0x08, 0x43); // 27db
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es7243_adc_get_voice_volume (int *volume)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t es7243_adc_get_voice_volume(int *volume) { return ESP_OK; }
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -31,99 +31,98 @@
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize ES7243 adc chip
|
||||
*
|
||||
* @param codec_cfg configuration of ES7243
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_init (audio_hal_codec_config_t *codec_cfg);
|
||||
/**
|
||||
* @brief Initialize ES7243 adc chip
|
||||
*
|
||||
* @param codec_cfg configuration of ES7243
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_init(audio_hal_codec_config_t *codec_cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ES7243 adc chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_deinit (void);
|
||||
/**
|
||||
* @brief Deinitialize ES7243 adc chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Control ES7243 adc chip
|
||||
*
|
||||
* @param mode adc mode
|
||||
* @param ctrl_state start or stop decode or encode progress
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es7243_adc_ctrl_state (audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
/**
|
||||
* @brief Control ES7243 adc chip
|
||||
*
|
||||
* @param mode adc mode
|
||||
* @param ctrl_state start or stop decode or encode progress
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es7243_adc_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
|
||||
/**
|
||||
* @brief Configure ES7243 adc mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es7243_adc_config_i2s (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
/**
|
||||
* @brief Configure ES7243 adc mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es7243_adc_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
/**
|
||||
* @brief Set mute
|
||||
*
|
||||
* @param mute true, false
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_set_voice_mute (bool mute);
|
||||
/**
|
||||
* @brief Set mute
|
||||
*
|
||||
* @param mute true, false
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_set_voice_mute(bool mute);
|
||||
|
||||
/**
|
||||
* @brief Set adc gain
|
||||
*
|
||||
* @param volume value of gain (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_set_voice_volume (int volume);
|
||||
/**
|
||||
* @brief Set adc gain
|
||||
*
|
||||
* @param volume value of gain (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_set_voice_volume(int volume);
|
||||
|
||||
/**
|
||||
* @brief Get adc gain
|
||||
*
|
||||
* @param[out] *volume: value of gain (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_get_voice_volume (int *volume);
|
||||
/**
|
||||
* @brief Get adc gain
|
||||
*
|
||||
* @param[out] *volume: value of gain (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_get_voice_volume(int *volume);
|
||||
|
||||
/**
|
||||
* @brief Set adc I2C address
|
||||
*
|
||||
* @param[in] addr: value of I2C address
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_set_addr (int addr);
|
||||
/**
|
||||
* @brief Set adc I2C address
|
||||
*
|
||||
* @param[in] addr: value of I2C address
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243_adc_set_addr(int addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
167
components/audio_hal/driver/es7243e/es7243e.c
Normal file
167
components/audio_hal/driver/es7243e/es7243e.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2021 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "es7243e.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "esp_log.h"
|
||||
#include "i2c_bus.h"
|
||||
|
||||
static char *TAG = "DRV7243E";
|
||||
static i2c_bus_handle_t i2c_handle;
|
||||
static int es7243e_addr = 0x20;
|
||||
|
||||
audio_hal_func_t AUDIO_CODEC_ES7243E_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = es7243e_adc_init,
|
||||
.audio_codec_deinitialize = es7243e_adc_deinit,
|
||||
.audio_codec_ctrl = es7243e_adc_ctrl_state,
|
||||
.audio_codec_config_iface = es7243e_adc_config_i2s,
|
||||
.audio_codec_set_mute = NULL,
|
||||
.audio_codec_set_volume = es7243e_adc_set_voice_volume,
|
||||
.audio_codec_get_volume = es7243e_adc_get_voice_volume,
|
||||
.audio_codec_enable_pa = NULL,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
static esp_err_t es7243e_write_reg(uint8_t reg_add, uint8_t data) {
|
||||
return i2c_bus_write_bytes(i2c_handle, es7243e_addr, ®_add,
|
||||
sizeof(reg_add), &data, sizeof(data));
|
||||
}
|
||||
|
||||
static int i2c_init() {
|
||||
int res = 0;
|
||||
i2c_config_t es_i2c_cfg = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000,
|
||||
};
|
||||
res = get_i2c_pins(I2C_NUM_0, &es_i2c_cfg);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "getting i2c pins error");
|
||||
}
|
||||
i2c_handle = i2c_bus_create(I2C_NUM_0, &es_i2c_cfg);
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t es7243e_adc_set_addr(int addr) {
|
||||
es7243e_addr = addr;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t es7243e_adc_init(audio_hal_codec_config_t *codec_cfg) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
i2c_init();
|
||||
ret |= es7243e_write_reg(0x01, 0x3A);
|
||||
ret |= es7243e_write_reg(0x00, 0x80);
|
||||
ret |= es7243e_write_reg(0xF9, 0x00);
|
||||
ret |= es7243e_write_reg(0x04, 0x02);
|
||||
ret |= es7243e_write_reg(0x04, 0x01);
|
||||
ret |= es7243e_write_reg(0xF9, 0x01);
|
||||
ret |= es7243e_write_reg(0x00, 0x1E);
|
||||
ret |= es7243e_write_reg(0x01, 0x00);
|
||||
|
||||
ret |= es7243e_write_reg(0x02, 0x00);
|
||||
ret |= es7243e_write_reg(0x03, 0x20);
|
||||
ret |= es7243e_write_reg(0x04, 0x01);
|
||||
ret |= es7243e_write_reg(0x0D, 0x00);
|
||||
ret |= es7243e_write_reg(0x05, 0x00);
|
||||
ret |= es7243e_write_reg(0x06, 0x03); // SCLK=MCLK/4
|
||||
ret |= es7243e_write_reg(0x07, 0x00); // LRCK=MCLK/256
|
||||
ret |= es7243e_write_reg(0x08, 0xFF); // LRCK=MCLK/256
|
||||
|
||||
ret |= es7243e_write_reg(0x09, 0xCA);
|
||||
ret |= es7243e_write_reg(0x0A, 0x85);
|
||||
ret |= es7243e_write_reg(0x0B, 0x00);
|
||||
ret |= es7243e_write_reg(0x0E, 0xBF);
|
||||
ret |= es7243e_write_reg(0x0F, 0x80);
|
||||
ret |= es7243e_write_reg(0x14, 0x0C);
|
||||
ret |= es7243e_write_reg(0x15, 0x0C);
|
||||
ret |= es7243e_write_reg(0x17, 0x02);
|
||||
ret |= es7243e_write_reg(0x18, 0x26);
|
||||
ret |= es7243e_write_reg(0x19, 0x77);
|
||||
ret |= es7243e_write_reg(0x1A, 0xF4);
|
||||
ret |= es7243e_write_reg(0x1B, 0x66);
|
||||
ret |= es7243e_write_reg(0x1C, 0x44);
|
||||
ret |= es7243e_write_reg(0x1E, 0x00);
|
||||
ret |= es7243e_write_reg(0x1F, 0x0C);
|
||||
ret |= es7243e_write_reg(0x20, 0x1A); // PGA gain +30dB
|
||||
ret |= es7243e_write_reg(0x21, 0x1A); // PGA gain +30dB
|
||||
|
||||
ret |= es7243e_write_reg(0x00, 0x80); // Slave Mode
|
||||
ret |= es7243e_write_reg(0x01, 0x3A);
|
||||
ret |= es7243e_write_reg(0x16, 0x3F);
|
||||
ret |= es7243e_write_reg(0x16, 0x00);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "Es7243e initialize failed!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t es7243e_adc_deinit(void) { return ESP_OK; }
|
||||
|
||||
esp_err_t es7243e_adc_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
if (ctrl_state == AUDIO_HAL_CTRL_START) {
|
||||
ret |= es7243e_write_reg(0xF9, 0x00);
|
||||
ret |= es7243e_write_reg(0x04, 0x01);
|
||||
ret |= es7243e_write_reg(0x17, 0x01);
|
||||
ret |= es7243e_write_reg(0x20, 0x10);
|
||||
ret |= es7243e_write_reg(0x21, 0x10);
|
||||
ret |= es7243e_write_reg(0x00, 0x80);
|
||||
ret |= es7243e_write_reg(0x01, 0x3A);
|
||||
ret |= es7243e_write_reg(0x16, 0x3F);
|
||||
ret |= es7243e_write_reg(0x16, 0x00);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "The codec going to stop");
|
||||
ret |= es7243e_write_reg(0x04, 0x02);
|
||||
ret |= es7243e_write_reg(0x04, 0x01);
|
||||
ret |= es7243e_write_reg(0xF7, 0x30);
|
||||
ret |= es7243e_write_reg(0xF9, 0x01);
|
||||
ret |= es7243e_write_reg(0x16, 0xFF);
|
||||
ret |= es7243e_write_reg(0x17, 0x00);
|
||||
ret |= es7243e_write_reg(0x01, 0x38);
|
||||
ret |= es7243e_write_reg(0x20, 0x00);
|
||||
ret |= es7243e_write_reg(0x21, 0x00);
|
||||
ret |= es7243e_write_reg(0x00, 0x00);
|
||||
ret |= es7243e_write_reg(0x00, 0x1E);
|
||||
ret |= es7243e_write_reg(0x01, 0x30);
|
||||
ret |= es7243e_write_reg(0x01, 0x00);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t es7243e_adc_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t es7243e_adc_set_voice_volume(int volume) { return ESP_OK; }
|
||||
|
||||
esp_err_t es7243e_adc_get_voice_volume(int *volume) { return ESP_OK; }
|
||||
120
components/audio_hal/driver/es7243e/es7243e.h
Normal file
120
components/audio_hal/driver/es7243e/es7243e.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2021 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
|
||||
*
|
||||
* 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 _ES7243E_H_
|
||||
#define _ES7243E_H_
|
||||
|
||||
#include "audio_hal.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize ES7243E adc chip
|
||||
*
|
||||
* @param codec_cfg configuration of ES7243E
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243e_adc_init(audio_hal_codec_config_t *codec_cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ES7243E adc chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243e_adc_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Control ES7243E adc chip
|
||||
*
|
||||
* @param mode adc mode
|
||||
* @param ctrl_state start or stop decode or encode progress
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es7243e_adc_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
|
||||
/**
|
||||
* @brief Configure ES7243E adc mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es7243e_adc_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
/**
|
||||
* @brief Set adc gain
|
||||
*
|
||||
* @param volume value of gain (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243e_adc_set_voice_volume(int volume);
|
||||
|
||||
/**
|
||||
* @brief Get adc gain
|
||||
*
|
||||
* @param[out] *volume: value of gain (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243e_adc_get_voice_volume(int *volume);
|
||||
|
||||
/**
|
||||
* @brief Set adc I2C address
|
||||
*
|
||||
* @param[in] addr: value of I2C address
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es7243e_adc_set_addr(int addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
248
components/audio_hal/driver/es8156/es8156.c
Normal file
248
components/audio_hal/driver/es8156/es8156.c
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2021 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "es8156.h"
|
||||
|
||||
#include "audio_volume.h"
|
||||
#include "board.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "i2c_bus.h"
|
||||
#include "string.h"
|
||||
|
||||
#define ES8156_ADDR 0x10
|
||||
|
||||
static const char *TAG = "DRV8156";
|
||||
static bool codec_init_flag = 0;
|
||||
static i2c_bus_handle_t i2c_handle;
|
||||
static codec_dac_volume_config_t *dac_vol_handle;
|
||||
|
||||
#define ES8156_DAC_VOL_CFG_DEFAULT() \
|
||||
{ \
|
||||
.max_dac_volume = 32, .min_dac_volume = -95.5, \
|
||||
.board_pa_gain = BOARD_PA_GAIN, .volume_accuracy = 0.5, \
|
||||
.dac_vol_symbol = 1, .zero_volume_reg = 0xBF, .reg_value = 0, \
|
||||
.user_volume = 0, .offset_conv_volume = NULL, \
|
||||
}
|
||||
|
||||
audio_hal_func_t AUDIO_CODEC_ES8156_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = es8156_codec_init,
|
||||
.audio_codec_deinitialize = es8156_codec_deinit,
|
||||
.audio_codec_ctrl = es8156_codec_ctrl_state,
|
||||
.audio_codec_config_iface = es8156_codec_config_i2s,
|
||||
.audio_codec_set_mute = es8156_codec_set_voice_mute,
|
||||
.audio_codec_set_volume = es8156_codec_set_voice_volume,
|
||||
.audio_codec_get_volume = es8156_codec_get_voice_volume,
|
||||
.audio_codec_enable_pa = es8156_pa_power,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
static bool es8156_codec_initialized() { return codec_init_flag; }
|
||||
|
||||
static esp_err_t es8156_write_reg(uint8_t reg_addr, uint8_t data) {
|
||||
return i2c_bus_write_bytes(i2c_handle, ES8156_ADDR, ®_addr,
|
||||
sizeof(reg_addr), &data, sizeof(data));
|
||||
}
|
||||
|
||||
static int es8156_read_reg(uint8_t reg_addr) {
|
||||
uint8_t data;
|
||||
i2c_bus_read_bytes(i2c_handle, ES8156_ADDR, ®_addr, sizeof(reg_addr),
|
||||
&data, sizeof(data));
|
||||
return (int)data;
|
||||
}
|
||||
|
||||
static int i2c_init() {
|
||||
int res = 0;
|
||||
i2c_config_t es_i2c_cfg = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000,
|
||||
};
|
||||
res = get_i2c_pins(I2C_NUM_0, &es_i2c_cfg);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "getting i2c pins error");
|
||||
}
|
||||
i2c_handle = i2c_bus_create(I2C_NUM_0, &es_i2c_cfg);
|
||||
return res;
|
||||
}
|
||||
|
||||
static esp_err_t es8156_standby(void) {
|
||||
esp_err_t ret = 0;
|
||||
ret = es8156_write_reg(0x14, 0x00);
|
||||
ret |= es8156_write_reg(0x19, 0x02);
|
||||
ret |= es8156_write_reg(0x21, 0x1F);
|
||||
ret |= es8156_write_reg(0x22, 0x02);
|
||||
ret |= es8156_write_reg(0x25, 0x21);
|
||||
ret |= es8156_write_reg(0x25, 0xA1);
|
||||
ret |= es8156_write_reg(0x18, 0x01);
|
||||
ret |= es8156_write_reg(0x09, 0x02);
|
||||
ret |= es8156_write_reg(0x09, 0x01);
|
||||
ret |= es8156_write_reg(0x08, 0x00);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t es8156_resume(void) {
|
||||
esp_err_t ret = 0;
|
||||
ret |= es8156_write_reg(0x08, 0x3F);
|
||||
ret |= es8156_write_reg(0x09, 0x00);
|
||||
ret |= es8156_write_reg(0x18, 0x00);
|
||||
|
||||
ret |= es8156_write_reg(0x25, 0x20);
|
||||
ret |= es8156_write_reg(0x22, 0x00);
|
||||
ret |= es8156_write_reg(0x21, 0x3C);
|
||||
ret |= es8156_write_reg(0x19, 0x20);
|
||||
ret |= es8156_write_reg(0x14, 179);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t es8156_pa_power(bool enable) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
if (enable) {
|
||||
ret = gpio_set_level(get_pa_enable_gpio(), 1);
|
||||
} else {
|
||||
ret = gpio_set_level(get_pa_enable_gpio(), 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t es8156_codec_init(audio_hal_codec_config_t *cfg) {
|
||||
if (es8156_codec_initialized()) {
|
||||
ESP_LOGW(TAG, "The es8156 DAC has been already initialized");
|
||||
return ESP_OK;
|
||||
}
|
||||
codec_init_flag = true;
|
||||
|
||||
i2c_init();
|
||||
es8156_write_reg(0x02, 0x04);
|
||||
es8156_write_reg(0x20, 0x2A);
|
||||
es8156_write_reg(0x21, 0x3C);
|
||||
es8156_write_reg(0x22, 0x00);
|
||||
es8156_write_reg(0x24, 0x07);
|
||||
es8156_write_reg(0x23, 0x00);
|
||||
|
||||
es8156_write_reg(0x0A, 0x01);
|
||||
es8156_write_reg(0x0B, 0x01);
|
||||
es8156_write_reg(0x11, 0x00);
|
||||
es8156_write_reg(0x14, 179); // volume 70%
|
||||
|
||||
es8156_write_reg(0x0D, 0x14);
|
||||
es8156_write_reg(0x18, 0x00);
|
||||
es8156_write_reg(0x08, 0x3F);
|
||||
es8156_write_reg(0x00, 0x02);
|
||||
es8156_write_reg(0x00, 0x03);
|
||||
es8156_write_reg(0x25, 0x20);
|
||||
|
||||
gpio_config_t io_conf;
|
||||
memset(&io_conf, 0, sizeof(io_conf));
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.pin_bit_mask = BIT64(get_pa_enable_gpio());
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 0;
|
||||
gpio_config(&io_conf);
|
||||
es8156_pa_power(true);
|
||||
|
||||
codec_dac_volume_config_t vol_cfg = ES8156_DAC_VOL_CFG_DEFAULT();
|
||||
dac_vol_handle = audio_codec_volume_init(&vol_cfg);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t es8156_codec_deinit(void) {
|
||||
codec_init_flag = false;
|
||||
audio_codec_volume_deinit(dac_vol_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t es8156_codec_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
if (ctrl_state == AUDIO_HAL_CTRL_START) {
|
||||
ret = es8156_resume();
|
||||
} else {
|
||||
ESP_LOGW(TAG, "The codec going to stop");
|
||||
ret = es8156_standby();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t es8156_codec_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t es8156_codec_set_voice_mute(bool enable) {
|
||||
int regv = es8156_read_reg(ES8156_DAC_MUTE_REG13);
|
||||
if (enable) {
|
||||
regv = regv | BIT(1) | BIT(2);
|
||||
} else {
|
||||
regv = regv & (~(BIT(1) | BIT(2)));
|
||||
}
|
||||
es8156_write_reg(ES8156_DAC_MUTE_REG13, regv);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @note Register values. 0x00: -95.5 dB, 0x5B: -50 dB, 0xBF: 0 dB, 0xFF: 32 dB
|
||||
* @note Accuracy of gain is 0.5 dB
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8156_codec_set_voice_volume(int volume) {
|
||||
int ret = 0;
|
||||
uint8_t reg = 0;
|
||||
reg = audio_codec_get_dac_reg_value(dac_vol_handle, volume);
|
||||
ret = es8156_write_reg(ES8156_VOLUME_CONTROL_REG14, reg);
|
||||
ESP_LOGD(TAG, "Set volume:%.2d reg_value:0x%.2x dB:%.1f",
|
||||
dac_vol_handle->user_volume, reg,
|
||||
audio_codec_cal_dac_volume(dac_vol_handle));
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t es8156_codec_get_voice_volume(int *volume) {
|
||||
int ret = 0;
|
||||
int regv = 0;
|
||||
*volume = 0;
|
||||
regv = es8156_read_reg(ES8156_VOLUME_CONTROL_REG14);
|
||||
if (regv == ESP_FAIL) {
|
||||
ret = ESP_FAIL;
|
||||
} else {
|
||||
if (regv == dac_vol_handle->reg_value) {
|
||||
*volume = dac_vol_handle->user_volume;
|
||||
} else {
|
||||
*volume = 0;
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
}
|
||||
ESP_LOGD(TAG, "Get volume:%.2d reg_value:0x%.2x", *volume, regv);
|
||||
return ret;
|
||||
}
|
||||
190
components/audio_hal/driver/es8156/es8156.h
Normal file
190
components/audio_hal/driver/es8156/es8156.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2021 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
|
||||
*
|
||||
* 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 _ES8156_H
|
||||
#define _ES8156_H
|
||||
|
||||
#include "audio_hal.h"
|
||||
#include "esp_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ES8156 register space */
|
||||
/*
|
||||
* RESET Control
|
||||
*/
|
||||
#define ES8156_RESET_REG00 0x00
|
||||
/*
|
||||
* Clock Managerment
|
||||
*/
|
||||
#define ES8156_MAINCLOCK_CTL_REG01 0x01
|
||||
#define ES8156_SCLK_MODE_REG02 0x02
|
||||
#define ES8156_LRCLK_DIV_H_REG03 0x03
|
||||
#define ES8156_LRCLK_DIV_L_REG04 0x04
|
||||
#define ES8156_SCLK_DIV_REG05 0x05
|
||||
#define ES8156_NFS_CONFIG_REG06 0x06
|
||||
#define ES8156_MISC_CONTROL1_REG07 0x07
|
||||
#define ES8156_CLOCK_ON_OFF_REG08 0x08
|
||||
#define ES8156_MISC_CONTROL2_REG09 0x09
|
||||
#define ES8156_TIME_CONTROL1_REG0A 0x0a
|
||||
#define ES8156_TIME_CONTROL2_REG0B 0x0b
|
||||
/*
|
||||
* System Control
|
||||
*/
|
||||
#define ES8156_CHIP_STATUS_REG0C 0x0c
|
||||
#define ES8156_P2S_CONTROL_REG0D 0x0d
|
||||
#define ES8156_DAC_OSR_COUNTER_REG10 0x10
|
||||
/*
|
||||
* SDP Control
|
||||
*/
|
||||
#define ES8156_DAC_SDP_REG11 0x11
|
||||
#define ES8156_AUTOMUTE_SET_REG12 0x12
|
||||
#define ES8156_DAC_MUTE_REG13 0x13
|
||||
#define ES8156_VOLUME_CONTROL_REG14 0x14
|
||||
|
||||
/*
|
||||
* ALC Control
|
||||
*/
|
||||
#define ES8156_ALC_CONFIG1_REG15 0x15
|
||||
#define ES8156_ALC_CONFIG2_REG16 0x16
|
||||
#define ES8156_ALC_CONFIG3_REG17 0x17
|
||||
#define ES8156_MISC_CONTROL3_REG18 0x18
|
||||
#define ES8156_EQ_CONTROL1_REG19 0x19
|
||||
#define ES8156_EQ_CONTROL2_REG1A 0x1a
|
||||
/*
|
||||
* Analog System Control
|
||||
*/
|
||||
#define ES8156_ANALOG_SYS1_REG20 0x20
|
||||
#define ES8156_ANALOG_SYS2_REG21 0x21
|
||||
#define ES8156_ANALOG_SYS3_REG22 0x22
|
||||
#define ES8156_ANALOG_SYS4_REG23 0x23
|
||||
#define ES8156_ANALOG_LP_REG24 0x24
|
||||
#define ES8156_ANALOG_SYS5_REG25 0x25
|
||||
/*
|
||||
* Chip Information
|
||||
*/
|
||||
#define ES8156_I2C_PAGESEL_REGFC 0xFC
|
||||
#define ES8156_CHIPID1_REGFD 0xFD
|
||||
#define ES8156_CHIPID0_REGFE 0xFE
|
||||
#define ES8156_CHIP_VERSION_REGFF 0xFF
|
||||
|
||||
/*
|
||||
* @brief Enables or disables PA
|
||||
*
|
||||
* @param enable true/false
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es8156_pa_power(bool enable);
|
||||
|
||||
/*
|
||||
* @brief Initialize ES8156 codec chip
|
||||
*
|
||||
* @param codec_cfg configuration of ES8156
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8156_codec_init(audio_hal_codec_config_t *codec_cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ES8156 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8156_codec_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Control ES8156 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 es8156_codec_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
|
||||
/**
|
||||
* @brief Configure ES8156 codec mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8156_codec_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
/**
|
||||
* @brief Configure ES8156 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 es8156_codec_set_voice_mute(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8156_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 es8156_codec_get_voice_volume(int *volume);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -32,8 +32,7 @@
|
||||
#include "esxxx_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -44,7 +43,7 @@ extern "C"
|
||||
/*
|
||||
* Clock Scheme Register definition
|
||||
*/
|
||||
#define ES8311_CLK_MANAGER_REG01 \
|
||||
#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 */
|
||||
@@ -70,7 +69,7 @@ extern "C"
|
||||
#define ES8311_SYSTEM_REG11 0x11 /* system */
|
||||
#define ES8311_SYSTEM_REG12 0x12 /* system, Enable DAC */
|
||||
#define ES8311_SYSTEM_REG13 0x13 /* system */
|
||||
#define ES8311_SYSTEM_REG14 \
|
||||
#define ES8311_SYSTEM_REG14 \
|
||||
0x14 /* system, select DMIC, select analog pga gain */
|
||||
/*
|
||||
* ADC
|
||||
@@ -107,173 +106,183 @@ extern "C"
|
||||
|
||||
#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;
|
||||
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 (audio_hal_codec_config_t *codec_cfg);
|
||||
/*
|
||||
* @brief Enables or disables PA
|
||||
*
|
||||
* @param enable true/false
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es8311_pa_power(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ES8311 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8311_codec_deinit (void);
|
||||
/*
|
||||
* @brief Initialize ES8311 codec chip
|
||||
*
|
||||
* @param codec_cfg configuration of ES8311
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8311_codec_init(audio_hal_codec_config_t *codec_cfg);
|
||||
|
||||
/**
|
||||
* @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 Deinitialize ES8311 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8311_codec_deinit(void);
|
||||
|
||||
/**
|
||||
* @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 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 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 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 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 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 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 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 Configure ES8311 I2S format
|
||||
*
|
||||
* @param mod: set ADC or DAC or both
|
||||
* @param cfg: ES8388 I2S format
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8311_config_fmt (es_i2s_fmt_t fmt);
|
||||
/**
|
||||
* @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 data sample bits
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
* @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 Configure ES8311 I2S format
|
||||
*
|
||||
* @param mod: set ADC or DAC or both
|
||||
* @param cfg: ES8388 I2S format
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8311_config_fmt(es_i2s_fmt_t fmt);
|
||||
|
||||
/**
|
||||
* @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 Configure ES8311 data sample bits
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
* @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 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 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 Get ES8311 DAC mute status
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es8311_get_voice_mute (int *mute);
|
||||
/**
|
||||
* @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 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 Get ES8311 DAC mute status
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es8311_get_voice_mute(int *mute);
|
||||
|
||||
/**
|
||||
* @brief Print all ES8311 registers
|
||||
*
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
void es8311_read_all ();
|
||||
/**
|
||||
* @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();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -32,225 +32,225 @@
|
||||
#include "esxxx_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ES8374 address */
|
||||
#define ES8374_ADDR 0x20 // 0x22:CE=1;0x20:CE=0
|
||||
#define ES8374_ADDR 0x20 // 0x22:CE=1;0x20:CE=0
|
||||
|
||||
/**
|
||||
* @brief Initialize ES8374 codec chip
|
||||
*
|
||||
* @param cfg configuration of ES8374
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_codec_init (audio_hal_codec_config_t *cfg);
|
||||
/**
|
||||
* @brief Initialize ES8374 codec chip
|
||||
*
|
||||
* @param cfg configuration of ES8374
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_codec_init(audio_hal_codec_config_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ES8374 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_codec_deinit (void);
|
||||
/**
|
||||
* @brief Deinitialize ES8374 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_codec_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Configure ES8374 I2S format
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
* @param fmt: ES8374 I2S format
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_config_fmt (es_module_t mode, es_i2s_fmt_t fmt);
|
||||
/**
|
||||
* @brief Configure ES8374 I2S format
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
* @param fmt: ES8374 I2S format
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_config_fmt(es_module_t mode, es_i2s_fmt_t fmt);
|
||||
|
||||
/**
|
||||
* @brief Configure I2S clock in MSATER mode
|
||||
*
|
||||
* @param cfg: set bits clock and WS clock
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_i2s_config_clock (es_i2s_clock_t cfg);
|
||||
/**
|
||||
* @brief Configure I2S clock in MSATER mode
|
||||
*
|
||||
* @param cfg: set bits clock and WS clock
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_i2s_config_clock(es_i2s_clock_t cfg);
|
||||
|
||||
/**
|
||||
* @brief Configure ES8374 data sample bits
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
* @param bit_per_sample: bit number of per sample
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_set_bits_per_sample (es_module_t mode,
|
||||
es_bits_length_t bit_per_sample);
|
||||
/**
|
||||
* @brief Configure ES8374 data sample bits
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
* @param bit_per_sample: bit number of per sample
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_set_bits_per_sample(es_module_t mode,
|
||||
es_bits_length_t bit_per_sample);
|
||||
|
||||
/**
|
||||
* @brief Start ES8374 codec chip
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_start (es_module_t mode);
|
||||
/**
|
||||
* @brief Start ES8374 codec chip
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_start(es_module_t mode);
|
||||
|
||||
/**
|
||||
* @brief Stop ES8374 codec chip
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_stop (es_module_t mode);
|
||||
/**
|
||||
* @brief Stop ES8374 codec chip
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_stop(es_module_t mode);
|
||||
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_codec_set_voice_volume (int volume);
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_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 es8374_codec_get_voice_volume (int *volume);
|
||||
/**
|
||||
* @brief Get voice volume
|
||||
*
|
||||
* @param[out] *volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8374_codec_get_voice_volume(int *volume);
|
||||
|
||||
/**
|
||||
* @brief Mute or unmute ES8374 DAC. Basically you can use this function to
|
||||
* mute or unmute the output
|
||||
*
|
||||
* @param enable mute(1) or unmute(0)
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_set_voice_mute (bool enable);
|
||||
/**
|
||||
* @brief Mute or unmute ES8374 DAC. Basically you can use this function to mute
|
||||
* or unmute the output
|
||||
*
|
||||
* @param enable mute(1) or unmute(0)
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_set_voice_mute(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Get ES8374 DAC mute status
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es8374_get_voice_mute (void);
|
||||
/**
|
||||
* @brief Get ES8374 DAC mute status
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es8374_get_voice_mute(void);
|
||||
|
||||
/**
|
||||
* @brief Set ES8374 mic gain
|
||||
*
|
||||
* @param gain db of mic gain
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_set_mic_gain (es_mic_gain_t gain);
|
||||
/**
|
||||
* @brief Set ES8374 mic gain
|
||||
*
|
||||
* @param gain db of mic gain
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_set_mic_gain(es_mic_gain_t gain);
|
||||
|
||||
/**
|
||||
* @brief Set ES8374 ADC input mode
|
||||
*
|
||||
* @param input adc input mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_config_adc_input (es_adc_input_t input);
|
||||
/**
|
||||
* @brief Set ES8374 ADC input mode
|
||||
*
|
||||
* @param input adc input mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_config_adc_input(es_adc_input_t input);
|
||||
|
||||
/**
|
||||
* @brief Set ES8374 DAC output mode
|
||||
*
|
||||
* @param output dac output mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_config_dac_output (es_dac_output_t output);
|
||||
/**
|
||||
* @brief Set ES8374 DAC output mode
|
||||
*
|
||||
* @param output dac output mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_config_dac_output(es_dac_output_t output);
|
||||
|
||||
/**
|
||||
* @brief Write ES8374 register
|
||||
*
|
||||
* @param reg_add address of register
|
||||
* @param data data of register
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_write_reg (uint8_t reg_add, uint8_t data);
|
||||
/**
|
||||
* @brief Write ES8374 register
|
||||
*
|
||||
* @param reg_add address of register
|
||||
* @param data data of register
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_write_reg(uint8_t reg_add, uint8_t data);
|
||||
|
||||
/**
|
||||
* @brief Print all ES8374 registers
|
||||
*
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
void es8374_read_all ();
|
||||
/**
|
||||
* @brief Print all ES8374 registers
|
||||
*
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
void es8374_read_all();
|
||||
|
||||
/**
|
||||
* @brief Configure ES8374 codec mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_codec_config_i2s (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
/**
|
||||
* @brief Configure ES8374 codec mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8374_codec_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
/**
|
||||
* @brief Control ES8374 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 es8374_codec_ctrl_state (audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
/**
|
||||
* @brief Control ES8374 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 es8374_codec_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
|
||||
/**
|
||||
* @brief Set ES8374 PA power
|
||||
*
|
||||
* @param enable true for enable PA power, false for disable PA power
|
||||
*
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
void es8374_pa_power (bool enable);
|
||||
/**
|
||||
* @brief Set ES8374 PA power
|
||||
*
|
||||
* @param enable true for enable PA power, false for disable PA power
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es8374_pa_power(bool enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__ES8374_H__
|
||||
#endif //__ES8374_H__
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,17 +18,20 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "es8388.h"
|
||||
#include "board_pins_config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "audio_volume.h"
|
||||
#include "board.h"
|
||||
#include "esp_log.h"
|
||||
#include "i2c_bus.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
|
||||
#include "headphone_detect.h"
|
||||
@@ -36,69 +39,68 @@
|
||||
|
||||
static const char *ES_TAG = "ES8388_DRIVER";
|
||||
static i2c_bus_handle_t i2c_handle;
|
||||
static codec_dac_volume_config_t *dac_vol_handle;
|
||||
|
||||
#define ES_ASSERT(a, format, b, ...) \
|
||||
if ((a) != 0) \
|
||||
{ \
|
||||
ESP_LOGE (ES_TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
#define ES8388_DAC_VOL_CFG_DEFAULT() \
|
||||
{ \
|
||||
.max_dac_volume = 0, .min_dac_volume = -96, \
|
||||
.board_pa_gain = BOARD_PA_GAIN, .volume_accuracy = 0.5, \
|
||||
.dac_vol_symbol = -1, .zero_volume_reg = 0, .reg_value = 0, \
|
||||
.user_volume = 0, .offset_conv_volume = NULL, \
|
||||
}
|
||||
|
||||
#define ES_ASSERT(a, format, b, ...) \
|
||||
if ((a) != 0) { \
|
||||
ESP_LOGE(ES_TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
|
||||
audio_hal_func_t AUDIO_CODEC_ES8388_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = es8388_init,
|
||||
.audio_codec_deinitialize = es8388_deinit,
|
||||
.audio_codec_ctrl = es8388_ctrl_state,
|
||||
.audio_codec_config_iface = es8388_config_i2s,
|
||||
.audio_codec_set_mute = es8388_set_voice_mute,
|
||||
.audio_codec_set_volume = es8388_set_voice_volume,
|
||||
.audio_codec_get_volume = es8388_get_voice_volume,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
.audio_codec_initialize = es8388_init,
|
||||
.audio_codec_deinitialize = es8388_deinit,
|
||||
.audio_codec_ctrl = es8388_ctrl_state,
|
||||
.audio_codec_config_iface = es8388_config_i2s,
|
||||
.audio_codec_set_mute = es8388_set_voice_mute,
|
||||
.audio_codec_set_volume = es8388_set_voice_volume,
|
||||
.audio_codec_get_volume = es8388_get_voice_volume,
|
||||
.audio_codec_enable_pa = es8388_pa_power,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
static esp_err_t
|
||||
es_write_reg (uint8_t slave_addr, uint8_t reg_add, uint8_t data)
|
||||
{
|
||||
return i2c_bus_write_bytes (i2c_handle, slave_addr, ®_add,
|
||||
sizeof (reg_add), &data, sizeof (data));
|
||||
static esp_err_t es_write_reg(uint8_t slave_addr, uint8_t reg_add,
|
||||
uint8_t data) {
|
||||
return i2c_bus_write_bytes(i2c_handle, slave_addr, ®_add, sizeof(reg_add),
|
||||
&data, sizeof(data));
|
||||
}
|
||||
|
||||
static esp_err_t
|
||||
es_read_reg (uint8_t reg_add, uint8_t *p_data)
|
||||
{
|
||||
return i2c_bus_read_bytes (i2c_handle, ES8388_ADDR, ®_add,
|
||||
sizeof (reg_add), p_data, 1);
|
||||
static esp_err_t es_read_reg(uint8_t reg_add, uint8_t *p_data) {
|
||||
return i2c_bus_read_bytes(i2c_handle, ES8388_ADDR, ®_add, sizeof(reg_add),
|
||||
p_data, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_init ()
|
||||
{
|
||||
static int i2c_init() {
|
||||
int res;
|
||||
i2c_config_t es_i2c_cfg = { .mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000 };
|
||||
res = get_i2c_pins (I2C_NUM_0, &es_i2c_cfg);
|
||||
ES_ASSERT (res, "getting i2c pins error", -1);
|
||||
i2c_handle = i2c_bus_create (I2C_NUM_0, &es_i2c_cfg);
|
||||
i2c_config_t es_i2c_cfg = {.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000};
|
||||
res = get_i2c_pins(I2C_NUM_0, &es_i2c_cfg);
|
||||
ES_ASSERT(res, "getting i2c pins error", -1);
|
||||
i2c_handle = i2c_bus_create(I2C_NUM_0, &es_i2c_cfg);
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
es8388_read_all ()
|
||||
{
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
uint8_t reg = 0;
|
||||
es_read_reg (i, ®);
|
||||
ets_printf ("%x: %x\n", i, reg);
|
||||
}
|
||||
void es8388_read_all() {
|
||||
for (int i = 0; i < 50; i++) {
|
||||
uint8_t reg = 0;
|
||||
es_read_reg(i, ®);
|
||||
ESP_LOGI(ES_TAG, "%x: %x", i, reg);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es8388_write_reg (uint8_t reg_add, uint8_t data)
|
||||
{
|
||||
return es_write_reg (ES8388_ADDR, reg_add, data);
|
||||
esp_err_t es8388_write_reg(uint8_t reg_add, uint8_t data) {
|
||||
return es_write_reg(ES8388_ADDR, reg_add, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,31 +117,26 @@ es8388_write_reg (uint8_t reg_add, uint8_t data)
|
||||
* - (-1) Parameter error
|
||||
* - (0) Success
|
||||
*/
|
||||
static int
|
||||
es8388_set_adc_dac_volume (int mode, int volume, int dot)
|
||||
{
|
||||
static int es8388_set_adc_dac_volume(int mode, int volume, int dot) {
|
||||
int res = 0;
|
||||
if (volume < -96 || volume > 0)
|
||||
{
|
||||
ESP_LOGW (ES_TAG, "Warning: volume < -96! or > 0!\n");
|
||||
if (volume < -96)
|
||||
volume = -96;
|
||||
else
|
||||
volume = 0;
|
||||
}
|
||||
if (volume < -96 || volume > 0) {
|
||||
ESP_LOGW(ES_TAG, "Warning: volume < -96! or > 0!\n");
|
||||
if (volume < -96)
|
||||
volume = -96;
|
||||
else
|
||||
volume = 0;
|
||||
}
|
||||
dot = (dot >= 5 ? 1 : 0);
|
||||
volume = (-volume << 1) + dot;
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL8, volume);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL9,
|
||||
volume); // ADC Right Volume=0db
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL5, volume);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL4, volume);
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL8, volume);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL9,
|
||||
volume); // ADC Right Volume=0db
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL5, volume);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL4, volume);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -154,57 +151,47 @@ es8388_set_adc_dac_volume (int mode, int volume, int dot)
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_start (es_module_t mode)
|
||||
{
|
||||
esp_err_t es8388_start(es_module_t mode) {
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t prev_data = 0, data = 0;
|
||||
es_read_reg (ES8388_DACCONTROL21, &prev_data);
|
||||
if (mode == ES_MODULE_LINE)
|
||||
{
|
||||
res |= es_write_reg (
|
||||
ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x09); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable
|
||||
res |= es_write_reg (
|
||||
ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x50); // left DAC to left mixer enable and LIN signal to left
|
||||
// mixer enable 0db : bupass enable
|
||||
res |= es_write_reg (
|
||||
ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x50); // right DAC to right mixer enable and LIN signal to right
|
||||
// mixer enable 0db : bupass enable
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0xC0); // enable adc
|
||||
}
|
||||
else
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x80); // enable dac
|
||||
}
|
||||
es_read_reg (ES8388_DACCONTROL21, &data);
|
||||
if (prev_data != data)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0xF0); // start state machine
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x16);
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x50);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0x00); // start state machine
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC
|
||||
|| mode == ES_MODULE_LINE)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0x00); // power up adc and line in
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC
|
||||
|| mode == ES_MODULE_LINE)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER,
|
||||
0x3c); // power up dac and line out
|
||||
res |= es8388_set_voice_mute (false);
|
||||
ESP_LOGD (ES_TAG, "es8388_start default is mode:%d", mode);
|
||||
}
|
||||
es_read_reg(ES8388_DACCONTROL21, &prev_data);
|
||||
if (mode == ES_MODULE_LINE) {
|
||||
res |= es_write_reg(
|
||||
ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x09); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable
|
||||
res |=
|
||||
es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x50); // left DAC to left mixer enable and LIN signal
|
||||
// to left mixer enable 0db : bupass enable
|
||||
res |=
|
||||
es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x50); // right DAC to right mixer enable and LIN signal
|
||||
// to right mixer enable 0db : bupass enable
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0xC0); // enable adc
|
||||
} else {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x80); // enable dac
|
||||
}
|
||||
es_read_reg(ES8388_DACCONTROL21, &data);
|
||||
if (prev_data != data) {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0xF0); // start state machine
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x16);
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x50);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0x00); // start state machine
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC ||
|
||||
mode == ES_MODULE_LINE) {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0x00); // power up adc and line in
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC ||
|
||||
mode == ES_MODULE_LINE) {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER,
|
||||
0x3c); // power up dac and line out
|
||||
res |= es8388_set_voice_mute(false);
|
||||
ESP_LOGD(ES_TAG, "es8388_start default is mode:%d", mode);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -220,45 +207,39 @@ es8388_start (es_module_t mode)
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_stop (es_module_t mode)
|
||||
{
|
||||
esp_err_t es8388_stop(es_module_t mode) {
|
||||
esp_err_t res = ESP_OK;
|
||||
if (mode == ES_MODULE_LINE)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x80); // enable dac
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x90); // only left DAC to left mixer enable 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x90); // only right DAC to right mixer enable 0db
|
||||
return res;
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER, 0x00);
|
||||
res |= es8388_set_voice_mute (
|
||||
true); // res |= Es8388SetAdcDacVolume(ES_MODULE_DAC, -96, 5); // 0db
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //power down
|
||||
// dac and line out
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
// res |= Es8388SetAdcDacVolume(ES_MODULE_ADC, -96, 5); // 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0xFF); // power down adc and line in
|
||||
}
|
||||
if (mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x9C); // disable mclk
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x00);
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x58);
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER, 0xF3);
|
||||
// //stop state machine
|
||||
}
|
||||
if (mode == ES_MODULE_LINE) {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x80); // enable dac
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x90); // only left DAC to left mixer enable 0db
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x90); // only right DAC to right mixer enable 0db
|
||||
return res;
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0x00);
|
||||
res |= es8388_set_voice_mute(
|
||||
true); // res |= Es8388SetAdcDacVolume(ES_MODULE_DAC, -96, 5); //
|
||||
// 0db
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //power down
|
||||
// dac and line out
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
||||
// res |= Es8388SetAdcDacVolume(ES_MODULE_ADC, -96, 5); // 0db
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0xFF); // power down adc and line in
|
||||
}
|
||||
if (mode == ES_MODULE_ADC_DAC) {
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x9C); // disable
|
||||
// mclk
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x00);
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x58);
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER, 0xF3); //stop
|
||||
// state machine
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -273,29 +254,26 @@ es8388_stop (es_module_t mode)
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_i2s_config_clock (es_i2s_clock_t cfg)
|
||||
{
|
||||
esp_err_t es8388_i2s_config_clock(es_i2s_clock_t cfg) {
|
||||
esp_err_t res = ESP_OK;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_MASTERMODE, cfg.sclk_div);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL5,
|
||||
cfg.lclk_div); // ADCFsMode,singel SPEED,RATIO=256
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL2,
|
||||
cfg.lclk_div); // ADCFsMode,singel SPEED,RATIO=256
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_MASTERMODE, cfg.sclk_div);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL5,
|
||||
cfg.lclk_div); // ADCFsMode,singel SPEED,RATIO=256
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL2,
|
||||
cfg.lclk_div); // ADCFsMode,singel SPEED,RATIO=256
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es8388_deinit (void)
|
||||
{
|
||||
esp_err_t es8388_deinit(void) {
|
||||
int res = 0;
|
||||
res = es_write_reg (ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0xFF); // reset and stop es8388
|
||||
i2c_bus_delete (i2c_handle);
|
||||
res = es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0xFF); // reset and stop es8388
|
||||
i2c_bus_delete(i2c_handle);
|
||||
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
|
||||
headphone_detect_deinit ();
|
||||
headphone_detect_deinit();
|
||||
#endif
|
||||
|
||||
audio_codec_volume_deinit(dac_vol_handle);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -304,99 +282,110 @@ es8388_deinit (void)
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_init (audio_hal_codec_config_t *cfg)
|
||||
{
|
||||
esp_err_t es8388_init(audio_hal_codec_config_t *cfg) {
|
||||
int res = 0;
|
||||
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARD
|
||||
headphone_detect_init (get_headphone_detect_gpio ());
|
||||
headphone_detect_init(get_headphone_detect_gpio());
|
||||
#endif
|
||||
|
||||
res = i2c_init (); // ESP32 in master mode
|
||||
res = i2c_init(); // ESP32 in master mode
|
||||
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL3,
|
||||
0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL3,
|
||||
0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and
|
||||
// disabled digital volume control soft ramp
|
||||
/* Chip Control and Power Management */
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_CONTROL2, 0x50);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0x00); // normal all and power up all
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_MASTERMODE,
|
||||
cfg->i2s_iface.mode); // CODEC IN I2S SLAVE MODE
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x50);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER,
|
||||
0x00); // normal all and power up all
|
||||
|
||||
// Disable the internal DLL to improve 8K sample rate
|
||||
res |= es_write_reg(ES8388_ADDR, 0x35, 0xA0);
|
||||
res |= es_write_reg(ES8388_ADDR, 0x37, 0xD0);
|
||||
res |= es_write_reg(ES8388_ADDR, 0x39, 0xD0);
|
||||
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_MASTERMODE,
|
||||
cfg->i2s_iface.mode); // CODEC IN I2S SLAVE MODE
|
||||
|
||||
/* dac */
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER,
|
||||
0xC0); // disable DAC and disable Lout/Rout/1/2
|
||||
res |= es_write_reg (
|
||||
ES8388_ADDR, ES8388_CONTROL1,
|
||||
0x12); // Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER,
|
||||
0xC0); // disable DAC and disable Lout/Rout/1/2
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1,
|
||||
0x12); // Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
|
||||
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0);
|
||||
// //LPVrefBuf=0,Pdn_ana=0
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL1,
|
||||
0x18); // 1a 0x18:16bit iis , 0x00:24
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL2,
|
||||
0x02); // DACFsMode,SINGLE SPEED; DACFsRatio,256
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x90); // only left DAC to left mixer enable 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x90); // only right DAC to right mixer enable 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x80); // set internal ADC and DAC use the same LRCK
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1,
|
||||
0x18); // 1a 0x18:16bit iis , 0x00:24
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL2,
|
||||
0x02); // DACFsMode,SINGLE SPEED; DACFsRatio,256
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL16,
|
||||
0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17,
|
||||
0x90); // only left DAC to left mixer enable 0db
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20,
|
||||
0x90); // only right DAC to right mixer enable 0db
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21,
|
||||
0x80); // set internal ADC and DAC use the same LRCK
|
||||
// clock, ADC LRCK as internal LRCK
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL23, 0x00); // vroi=0
|
||||
res |= es8388_set_adc_dac_volume (ES_MODULE_DAC, 0, 0); // 0db
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL23, 0x00); // vroi=0
|
||||
|
||||
res |= es_write_reg(
|
||||
ES8388_ADDR, ES8388_DACCONTROL24,
|
||||
0x1E); // Set L1 R1 L2 R2 volume. 0x00: -30dB, 0x1E: 0dB, 0x21: 3dB
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL25, 0x1E);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL26, 0);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL27, 0);
|
||||
// res |= es8388_set_adc_dac_volume(ES_MODULE_DAC, 0, 0); // 0db
|
||||
int tmp = 0;
|
||||
if (AUDIO_HAL_DAC_OUTPUT_LINE2 == cfg->dac_output)
|
||||
{
|
||||
tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_ROUT1;
|
||||
}
|
||||
else if (AUDIO_HAL_DAC_OUTPUT_LINE1 == cfg->dac_output)
|
||||
{
|
||||
tmp = DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT1
|
||||
| DAC_OUTPUT_ROUT2;
|
||||
}
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER,
|
||||
tmp); // 0x3c Enable DAC and Enable Lout/Rout/1/2
|
||||
if (AUDIO_HAL_DAC_OUTPUT_LINE2 == cfg->dac_output) {
|
||||
tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_ROUT1;
|
||||
} else if (AUDIO_HAL_DAC_OUTPUT_LINE1 == cfg->dac_output) {
|
||||
tmp = DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT2;
|
||||
} else {
|
||||
tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT1 |
|
||||
DAC_OUTPUT_ROUT2;
|
||||
}
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER,
|
||||
tmp); // 0x3c Enable DAC and Enable Lout/Rout/1/2
|
||||
/* adc */
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCPOWER, 0xFF);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL1,
|
||||
0xbb); // MIC Left and Right channel PGA gain
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER, 0xFF);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL1,
|
||||
0xbb); // MIC Left and Right channel PGA gain
|
||||
tmp = 0;
|
||||
if (AUDIO_HAL_ADC_INPUT_LINE1 == cfg->adc_input)
|
||||
{
|
||||
tmp = ADC_INPUT_LINPUT1_RINPUT1;
|
||||
}
|
||||
else if (AUDIO_HAL_ADC_INPUT_LINE2 == cfg->adc_input)
|
||||
{
|
||||
tmp = ADC_INPUT_LINPUT2_RINPUT2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = ADC_INPUT_DIFFERENCE;
|
||||
}
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL2,
|
||||
tmp); // 0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input;
|
||||
if (AUDIO_HAL_ADC_INPUT_LINE1 == cfg->adc_input) {
|
||||
tmp = ADC_INPUT_LINPUT1_RINPUT1;
|
||||
} else if (AUDIO_HAL_ADC_INPUT_LINE2 == cfg->adc_input) {
|
||||
tmp = ADC_INPUT_LINPUT2_RINPUT2;
|
||||
} else {
|
||||
tmp = ADC_INPUT_DIFFERENCE;
|
||||
}
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL2,
|
||||
tmp); // 0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input;
|
||||
// DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL3, 0x02);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL4,
|
||||
0x0d); // Left/Right data, Left/Right justified mode,
|
||||
// Bits length, I2S format
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL5,
|
||||
0x02); // ADCFsMode,singel SPEED,RATIO=256
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL3, 0x02);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL4,
|
||||
0x0c); // 16 Bits length and I2S serial audio data format
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL5,
|
||||
0x02); // ADCFsMode,singel SPEED,RATIO=256
|
||||
// ALC for Microphone
|
||||
res |= es8388_set_adc_dac_volume (ES_MODULE_ADC, 0, 0); // 0db
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0x09); // Power on ADC, Enable LIN&RIN, Power off
|
||||
// MICBIAS, set int1lp to low power mode
|
||||
res |= es8388_set_adc_dac_volume(ES_MODULE_ADC, 0, 0); // 0db
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER,
|
||||
0x09); // Power on ADC, enable LIN&RIN, power off
|
||||
// MICBIAS, and set int1lp to low power mode
|
||||
|
||||
/* es8388 PA gpio_config */
|
||||
gpio_config_t io_conf;
|
||||
memset(&io_conf, 0, sizeof(io_conf));
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.pin_bit_mask = BIT64(get_pa_enable_gpio());
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 0;
|
||||
gpio_config(&io_conf);
|
||||
/* enable es8388 PA */
|
||||
es8388_pa_power (true);
|
||||
ESP_LOGI (ES_TAG, "init,out:%02x, in:%02x", cfg->dac_output, cfg->adc_input);
|
||||
es8388_pa_power(true);
|
||||
|
||||
codec_dac_volume_config_t vol_cfg = ES8388_DAC_VOL_CFG_DEFAULT();
|
||||
dac_vol_handle = audio_codec_volume_init(&vol_cfg);
|
||||
ESP_LOGI(ES_TAG, "init,out:%02x, in:%02x", cfg->dac_output, cfg->adc_input);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -410,71 +399,61 @@ es8388_init (audio_hal_codec_config_t *cfg)
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_config_fmt (es_module_t mode, es_i2s_fmt_t fmt)
|
||||
{
|
||||
esp_err_t es8388_config_fmt(es_module_t mode, es_i2s_fmt_t fmt) {
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res = es_read_reg (ES8388_ADCCONTROL4, ®);
|
||||
reg = reg & 0xfc;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL4, reg | fmt);
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res = es_read_reg (ES8388_DACCONTROL1, ®);
|
||||
reg = reg & 0xf9;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL1, reg | (fmt << 1));
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
||||
res = es_read_reg(ES8388_ADCCONTROL4, ®);
|
||||
reg = reg & 0xfc;
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL4, reg | fmt);
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
||||
res = es_read_reg(ES8388_DACCONTROL1, ®);
|
||||
reg = reg & 0xf9;
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1, reg | (fmt << 1));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param volume: 0 ~ 100
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @note Register values. 0xC0: -96 dB, 0x64: -50 dB, 0x00: 0 dB
|
||||
* @note Accuracy of gain is 0.5 dB
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_set_voice_volume (int volume)
|
||||
{
|
||||
esp_err_t es8388_set_voice_volume(int volume) {
|
||||
esp_err_t res = ESP_OK;
|
||||
if (volume < 0)
|
||||
volume = 0;
|
||||
else if (volume > 100)
|
||||
volume = 100;
|
||||
volume /= 3;
|
||||
res = es_write_reg (ES8388_ADDR, ES8388_DACCONTROL24, volume);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL25, volume);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL26, 0);
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL27, 0);
|
||||
uint8_t reg = 0;
|
||||
reg = audio_codec_get_dac_reg_value(dac_vol_handle, volume);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL5, reg);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL4, reg);
|
||||
ESP_LOGD(ES_TAG, "Set volume:%.2d reg_value:0x%.2x dB:%.1f",
|
||||
(int)dac_vol_handle->user_volume, reg,
|
||||
audio_codec_cal_dac_volume(dac_vol_handle));
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* volume
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_get_voice_volume (int *volume)
|
||||
{
|
||||
esp_err_t es8388_get_voice_volume(int *volume) {
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_DACCONTROL24, ®);
|
||||
if (res == ESP_FAIL)
|
||||
{
|
||||
res = es_read_reg(ES8388_DACCONTROL4, ®);
|
||||
if (res == ESP_FAIL) {
|
||||
*volume = 0;
|
||||
} else {
|
||||
if (reg == dac_vol_handle->reg_value) {
|
||||
*volume = dac_vol_handle->user_volume;
|
||||
} else {
|
||||
*volume = 0;
|
||||
res = ESP_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*volume = reg;
|
||||
*volume *= 3;
|
||||
if (*volume == 99)
|
||||
*volume = 100;
|
||||
}
|
||||
}
|
||||
ESP_LOGD(ES_TAG, "Get volume:%.2d reg_value:0x%.2x", *volume, reg);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -488,25 +467,22 @@ es8388_get_voice_volume (int *volume)
|
||||
* - (-1) Parameter error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_set_bits_per_sample (es_module_t mode, es_bits_length_t bits_length)
|
||||
{
|
||||
esp_err_t es8388_set_bits_per_sample(es_module_t mode,
|
||||
es_bits_length_t bits_length) {
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
int bits = (int)bits_length;
|
||||
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res = es_read_reg (ES8388_ADCCONTROL4, ®);
|
||||
reg = reg & 0xe3;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL4, reg | (bits << 2));
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC)
|
||||
{
|
||||
res = es_read_reg (ES8388_DACCONTROL1, ®);
|
||||
reg = reg & 0xc7;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL1, reg | (bits << 3));
|
||||
}
|
||||
if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
|
||||
res = es_read_reg(ES8388_ADCCONTROL4, ®);
|
||||
reg = reg & 0xe3;
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL4, reg | (bits << 2));
|
||||
}
|
||||
if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
|
||||
res = es_read_reg(ES8388_DACCONTROL1, ®);
|
||||
reg = reg & 0xc7;
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1, reg | (bits << 3));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -520,28 +496,23 @@ es8388_set_bits_per_sample (es_module_t mode, es_bits_length_t bits_length)
|
||||
* - (-1) Parameter error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_set_voice_mute (bool enable)
|
||||
{
|
||||
esp_err_t es8388_set_voice_mute(bool enable) {
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_DACCONTROL3, ®);
|
||||
res = es_read_reg(ES8388_DACCONTROL3, ®);
|
||||
reg = reg & 0xFB;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACCONTROL3,
|
||||
reg | (((int)enable) << 2));
|
||||
res |=
|
||||
es_write_reg(ES8388_ADDR, ES8388_DACCONTROL3, reg | (((int)enable) << 2));
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es8388_get_voice_mute (void)
|
||||
{
|
||||
esp_err_t es8388_get_voice_mute(void) {
|
||||
esp_err_t res = ESP_OK;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_DACCONTROL3, ®);
|
||||
if (res == ESP_OK)
|
||||
{
|
||||
reg = (reg & 0x04) >> 2;
|
||||
}
|
||||
res = es_read_reg(ES8388_DACCONTROL3, ®);
|
||||
if (res == ESP_OK) {
|
||||
reg = (reg & 0x04) >> 2;
|
||||
}
|
||||
return res == ESP_OK ? reg : res;
|
||||
}
|
||||
|
||||
@@ -552,14 +523,12 @@ es8388_get_voice_mute (void)
|
||||
* - (-1) Parameter error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_config_dac_output (int output)
|
||||
{
|
||||
esp_err_t es8388_config_dac_output(int output) {
|
||||
esp_err_t res;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_DACPOWER, ®);
|
||||
res = es_read_reg(ES8388_DACPOWER, ®);
|
||||
reg = reg & 0xc3;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_DACPOWER, reg | output);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, reg | output);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -570,14 +539,12 @@ es8388_config_dac_output (int output)
|
||||
* - (-1) Parameter error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_config_adc_input (es_adc_input_t input)
|
||||
{
|
||||
esp_err_t es8388_config_adc_input(es_adc_input_t input) {
|
||||
esp_err_t res;
|
||||
uint8_t reg = 0;
|
||||
res = es_read_reg (ES8388_ADCCONTROL2, ®);
|
||||
res = es_read_reg(ES8388_ADCCONTROL2, ®);
|
||||
reg = reg & 0x0f;
|
||||
res |= es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL2, reg | input);
|
||||
res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL2, reg | input);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -588,23 +555,19 @@ es8388_config_adc_input (es_adc_input_t input)
|
||||
* - (-1) Parameter error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t
|
||||
es8388_set_mic_gain (es_mic_gain_t gain)
|
||||
{
|
||||
esp_err_t es8388_set_mic_gain(es_mic_gain_t gain) {
|
||||
esp_err_t res, gain_n;
|
||||
gain_n = (int)gain / 3;
|
||||
gain_n = (gain_n << 4) + gain_n;
|
||||
res = es_write_reg (ES8388_ADDR, ES8388_ADCCONTROL1, gain_n); // MIC PGA
|
||||
res = es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL1, gain_n); // MIC PGA
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
es8388_ctrl_state (audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state)
|
||||
{
|
||||
int es8388_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state) {
|
||||
int res = 0;
|
||||
int es_mode_t = 0;
|
||||
switch (mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case AUDIO_HAL_CODEC_MODE_ENCODE:
|
||||
es_mode_t = ES_MODULE_ADC;
|
||||
break;
|
||||
@@ -619,61 +582,40 @@ es8388_ctrl_state (audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state)
|
||||
break;
|
||||
default:
|
||||
es_mode_t = ES_MODULE_DAC;
|
||||
ESP_LOGW (ES_TAG, "Codec mode not support, default is decode mode");
|
||||
ESP_LOGW(ES_TAG, "Codec mode not support, default is decode mode");
|
||||
break;
|
||||
}
|
||||
if (AUDIO_HAL_CTRL_STOP == ctrl_state)
|
||||
{
|
||||
res = es8388_stop (es_mode_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = es8388_start (es_mode_t);
|
||||
ESP_LOGD (ES_TAG, "start default is decode mode:%d", es_mode_t);
|
||||
}
|
||||
}
|
||||
if (AUDIO_HAL_CTRL_STOP == ctrl_state) {
|
||||
res = es8388_stop(es_mode_t);
|
||||
} else {
|
||||
res = es8388_start(es_mode_t);
|
||||
ESP_LOGD(ES_TAG, "start default is decode mode:%d", es_mode_t);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
es8388_config_i2s (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface)
|
||||
{
|
||||
esp_err_t es8388_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface) {
|
||||
esp_err_t res = ESP_OK;
|
||||
int tmp = 0;
|
||||
res |= es8388_config_fmt (ES_MODULE_ADC_DAC, iface->fmt);
|
||||
if (iface->bits == AUDIO_HAL_BIT_LENGTH_16BITS)
|
||||
{
|
||||
tmp = BIT_LENGTH_16BITS;
|
||||
}
|
||||
else if (iface->bits == AUDIO_HAL_BIT_LENGTH_24BITS)
|
||||
{
|
||||
tmp = BIT_LENGTH_24BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = BIT_LENGTH_32BITS;
|
||||
}
|
||||
res |= es8388_set_bits_per_sample (ES_MODULE_ADC_DAC, tmp);
|
||||
res |= es8388_config_fmt(ES_MODULE_ADC_DAC, iface->fmt);
|
||||
if (iface->bits == AUDIO_HAL_BIT_LENGTH_16BITS) {
|
||||
tmp = BIT_LENGTH_16BITS;
|
||||
} else if (iface->bits == AUDIO_HAL_BIT_LENGTH_24BITS) {
|
||||
tmp = BIT_LENGTH_24BITS;
|
||||
} else {
|
||||
tmp = BIT_LENGTH_32BITS;
|
||||
}
|
||||
res |= es8388_set_bits_per_sample(ES_MODULE_ADC_DAC, tmp);
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
es8388_pa_power (bool enable)
|
||||
{
|
||||
gpio_config_t io_conf;
|
||||
memset (&io_conf, 0, sizeof (io_conf));
|
||||
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.pin_bit_mask = BIT64 (get_pa_enable_gpio ());
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 0;
|
||||
gpio_config (&io_conf);
|
||||
if (enable)
|
||||
{
|
||||
gpio_set_level (get_pa_enable_gpio (), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_set_level (get_pa_enable_gpio (), 0);
|
||||
}
|
||||
esp_err_t es8388_pa_power(bool enable) {
|
||||
esp_err_t res = ESP_OK;
|
||||
if (enable) {
|
||||
res = gpio_set_level(get_pa_enable_gpio(), 1);
|
||||
} else {
|
||||
res = gpio_set_level(get_pa_enable_gpio(), 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
#include "esxxx_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ES8388 address */
|
||||
@@ -102,218 +101,219 @@ extern "C"
|
||||
#define ES8388_DACCONTROL29 0x33
|
||||
#define ES8388_DACCONTROL30 0x34
|
||||
|
||||
/**
|
||||
* @brief Initialize ES8388 codec chip
|
||||
*
|
||||
* @param cfg configuration of ES8388
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_init (audio_hal_codec_config_t *cfg);
|
||||
/**
|
||||
* @brief Initialize ES8388 codec chip
|
||||
*
|
||||
* @param cfg configuration of ES8388
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_init(audio_hal_codec_config_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize ES8388 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_deinit (void);
|
||||
/**
|
||||
* @brief Deinitialize ES8388 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Configure ES8388 I2S format
|
||||
*
|
||||
* @param mod: set ADC or DAC or both
|
||||
* @param cfg: ES8388 I2S format
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_config_fmt (es_module_t mod, es_i2s_fmt_t cfg);
|
||||
/**
|
||||
* @brief Configure ES8388 I2S format
|
||||
*
|
||||
* @param mod: set ADC or DAC or both
|
||||
* @param cfg: ES8388 I2S format
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_config_fmt(es_module_t mod, es_i2s_fmt_t cfg);
|
||||
|
||||
/**
|
||||
* @brief Configure I2s clock in MSATER mode
|
||||
*
|
||||
* @param cfg: set bits clock and WS clock
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_i2s_config_clock (es_i2s_clock_t cfg);
|
||||
/**
|
||||
* @brief Configure I2s clock in MSATER mode
|
||||
*
|
||||
* @param cfg: set bits clock and WS clock
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_i2s_config_clock(es_i2s_clock_t cfg);
|
||||
|
||||
/**
|
||||
* @brief Configure ES8388 data sample bits
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
* @param bit_per_sample: bit number of per sample
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_set_bits_per_sample (es_module_t mode,
|
||||
es_bits_length_t bit_per_sample);
|
||||
/**
|
||||
* @brief Configure ES8388 data sample bits
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
* @param bit_per_sample: bit number of per sample
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_set_bits_per_sample(es_module_t mode,
|
||||
es_bits_length_t bit_per_sample);
|
||||
|
||||
/**
|
||||
* @brief Start ES8388 codec chip
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_start (es_module_t mode);
|
||||
/**
|
||||
* @brief Start ES8388 codec chip
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_start(es_module_t mode);
|
||||
|
||||
/**
|
||||
* @brief Stop ES8388 codec chip
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_stop (es_module_t mode);
|
||||
/**
|
||||
* @brief Stop ES8388 codec chip
|
||||
*
|
||||
* @param mode: set ADC or DAC or both
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_stop(es_module_t mode);
|
||||
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_set_voice_volume (int volume);
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_set_voice_volume(int volume);
|
||||
|
||||
/**
|
||||
* @brief Get voice volume
|
||||
*
|
||||
* @param[out] *volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_get_voice_volume (int *volume);
|
||||
/**
|
||||
* @brief Get voice volume
|
||||
*
|
||||
* @param[out] *volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t es8388_get_voice_volume(int *volume);
|
||||
|
||||
/**
|
||||
* @brief Configure ES8388 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 es8388_set_voice_mute (bool enable);
|
||||
/**
|
||||
* @brief Configure ES8388 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 es8388_set_voice_mute(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Get ES8388 DAC mute status
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_get_voice_mute (void);
|
||||
/**
|
||||
* @brief Get ES8388 DAC mute status
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_get_voice_mute(void);
|
||||
|
||||
/**
|
||||
* @brief Set ES8388 mic gain
|
||||
*
|
||||
* @param gain db of mic gain
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_set_mic_gain (es_mic_gain_t gain);
|
||||
/**
|
||||
* @brief Set ES8388 mic gain
|
||||
*
|
||||
* @param gain db of mic gain
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_set_mic_gain(es_mic_gain_t gain);
|
||||
|
||||
/**
|
||||
* @brief Set ES8388 adc input mode
|
||||
*
|
||||
* @param input adc input mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_config_adc_input (es_adc_input_t input);
|
||||
/**
|
||||
* @brief Set ES8388 adc input mode
|
||||
*
|
||||
* @param input adc input mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_config_adc_input(es_adc_input_t input);
|
||||
|
||||
/**
|
||||
* @brief Set ES8388 dac output mode
|
||||
*
|
||||
* @param output dac output mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_config_dac_output (es_dac_output_t output);
|
||||
/**
|
||||
* @brief Set ES8388 dac output mode
|
||||
*
|
||||
* @param output dac output mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_config_dac_output(es_dac_output_t output);
|
||||
|
||||
/**
|
||||
* @brief Write ES8388 register
|
||||
*
|
||||
* @param reg_add address of register
|
||||
* @param data data of register
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_write_reg (uint8_t reg_add, uint8_t data);
|
||||
/**
|
||||
* @brief Write ES8388 register
|
||||
*
|
||||
* @param reg_add address of register
|
||||
* @param data data of register
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_write_reg(uint8_t reg_add, uint8_t data);
|
||||
|
||||
/**
|
||||
* @brief Print all ES8388 registers
|
||||
*
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
void es8388_read_all ();
|
||||
/**
|
||||
* @brief Print all ES8388 registers
|
||||
*
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
void es8388_read_all();
|
||||
|
||||
/**
|
||||
* @brief Configure ES8388 codec mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_config_i2s (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
/**
|
||||
* @brief Configure ES8388 codec mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t es8388_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
/**
|
||||
* @brief Control ES8388 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 es8388_ctrl_state (audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
/**
|
||||
* @brief Control ES8388 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 es8388_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
|
||||
/**
|
||||
* @brief Set ES8388 PA power
|
||||
*
|
||||
* @param enable true for enable PA power, false for disable PA power
|
||||
*
|
||||
* @return
|
||||
* - void
|
||||
*/
|
||||
void es8388_pa_power (bool enable);
|
||||
/**
|
||||
* @brief Set ES8388 PA power
|
||||
*
|
||||
* @param enable true for enable PA power, false for disable PA power
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
* - ESP_OK
|
||||
*/
|
||||
esp_err_t es8388_pa_power(bool enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__ES8388_H__
|
||||
#endif //__ES8388_H__
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -40,71 +40,56 @@
|
||||
|
||||
#define HP_DELAY_TIME_MS 1000
|
||||
|
||||
static char *TAG = "HEADPHONE";
|
||||
static const char *TAG = "HEADPHONE";
|
||||
static xTimerHandle timer_headphone;
|
||||
|
||||
static void
|
||||
hp_timer_cb (TimerHandle_t xTimer)
|
||||
{
|
||||
int num = (int)pvTimerGetTimerID (xTimer);
|
||||
int res = gpio_get_level (num);
|
||||
es8388_pa_power (res);
|
||||
ESP_LOGW (TAG, "Headphone jack %s", res ? "removed" : "inserted");
|
||||
static void hp_timer_cb(TimerHandle_t xTimer) {
|
||||
int num = (int)pvTimerGetTimerID(xTimer);
|
||||
int res = gpio_get_level(num);
|
||||
es8388_pa_power(res);
|
||||
}
|
||||
|
||||
static int
|
||||
hp_timer_init (int num)
|
||||
{
|
||||
timer_headphone
|
||||
= xTimerCreate ("hp_timer0", HP_DELAY_TIME_MS / portTICK_RATE_MS,
|
||||
pdFALSE, (void *)num, hp_timer_cb);
|
||||
if (timer_headphone == NULL)
|
||||
{
|
||||
ESP_LOGE (TAG, "hp_timer create err");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
static int hp_timer_init(int num) {
|
||||
timer_headphone =
|
||||
xTimerCreate("hp_timer0", HP_DELAY_TIME_MS / portTICK_RATE_MS, pdFALSE,
|
||||
(void *)num, hp_timer_cb);
|
||||
if (timer_headphone == NULL) {
|
||||
ESP_LOGE(TAG, "hp_timer create err");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void IRAM_ATTR
|
||||
headphone_gpio_intr_handler (void *arg)
|
||||
{
|
||||
static void IRAM_ATTR headphone_gpio_intr_handler(void *arg) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTimerResetFromISR (timer_headphone, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken != pdFALSE)
|
||||
{
|
||||
portYIELD_FROM_ISR ();
|
||||
}
|
||||
xTimerResetFromISR(timer_headphone, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken != pdFALSE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
headphone_detect_deinit ()
|
||||
{
|
||||
xTimerDelete (timer_headphone, HP_DELAY_TIME_MS / portTICK_RATE_MS);
|
||||
gpio_uninstall_isr_service ();
|
||||
void headphone_detect_deinit() {
|
||||
xTimerDelete(timer_headphone, HP_DELAY_TIME_MS / portTICK_RATE_MS);
|
||||
gpio_uninstall_isr_service();
|
||||
timer_headphone = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
headphone_status_get ()
|
||||
{
|
||||
return gpio_get_level (0);
|
||||
int headphone_status_get() {
|
||||
return gpio_get_level(get_headphone_detect_gpio());
|
||||
}
|
||||
|
||||
void
|
||||
headphone_detect_init (int num)
|
||||
{
|
||||
hp_timer_init (num);
|
||||
void headphone_detect_init(int num) {
|
||||
hp_timer_init(num);
|
||||
gpio_config_t io_conf;
|
||||
memset (&io_conf, 0, sizeof (io_conf));
|
||||
memset(&io_conf, 0, sizeof(io_conf));
|
||||
io_conf.intr_type = GPIO_INTR_ANYEDGE;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pin_bit_mask = BIT64 (num);
|
||||
io_conf.pin_bit_mask = BIT64(num);
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 1;
|
||||
gpio_config (&io_conf);
|
||||
gpio_config(&io_conf);
|
||||
|
||||
gpio_install_isr_service (0);
|
||||
gpio_isr_handler_add (num, headphone_gpio_intr_handler, (void *)num);
|
||||
gpio_install_isr_service(0);
|
||||
gpio_isr_handler_add(num, headphone_gpio_intr_handler, (void *)num);
|
||||
}
|
||||
#endif /* CONFIG_ESP_LYRAT_V4_3_BOARD */
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,46 +18,45 @@
|
||||
* 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.
|
||||
* 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 _AUDIO_HEADPHONE_DETEC_H_
|
||||
#define _AUDIO_HEADPHONE_DETEC_H_
|
||||
#ifndef _AUDIO_HEADPHONE_DETECT_H_
|
||||
#define _AUDIO_HEADPHONE_DETECT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get headphone insertion status
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return int, 0:headphone inserted, 1:headphone not inserted.
|
||||
*/
|
||||
int headphone_status_get ();
|
||||
/**
|
||||
* @brief Get headphone insertion status
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return int, 0:headphone inserted, 1:headphone not inserted.
|
||||
*/
|
||||
int headphone_status_get();
|
||||
|
||||
/**
|
||||
* @brief Initialize headphone detect gpio.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void headphone_detect_init (int num);
|
||||
/**
|
||||
* @brief Initialize headphone detect gpio.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void headphone_detect_init(int num);
|
||||
|
||||
/**
|
||||
* @brief Delete headphone detect timer.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void headphone_detect_deinit ();
|
||||
/**
|
||||
* @brief Delete headphone detect timer.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void headphone_detect_deinit();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -28,172 +28,160 @@
|
||||
#define _ESXXX_COMMON_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BIT_LENGTH_MIN = -1,
|
||||
BIT_LENGTH_16BITS = 0x03,
|
||||
BIT_LENGTH_18BITS = 0x02,
|
||||
BIT_LENGTH_20BITS = 0x01,
|
||||
BIT_LENGTH_24BITS = 0x00,
|
||||
BIT_LENGTH_32BITS = 0x04,
|
||||
BIT_LENGTH_MAX,
|
||||
} es_bits_length_t;
|
||||
typedef enum {
|
||||
BIT_LENGTH_MIN = -1,
|
||||
BIT_LENGTH_16BITS = 0x03,
|
||||
BIT_LENGTH_18BITS = 0x02,
|
||||
BIT_LENGTH_20BITS = 0x01,
|
||||
BIT_LENGTH_24BITS = 0x00,
|
||||
BIT_LENGTH_32BITS = 0x04,
|
||||
BIT_LENGTH_MAX,
|
||||
} es_bits_length_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MCLK_DIV_MIN = -1,
|
||||
MCLK_DIV_1 = 1,
|
||||
MCLK_DIV_2 = 2,
|
||||
MCLK_DIV_3 = 3,
|
||||
MCLK_DIV_4 = 4,
|
||||
MCLK_DIV_6 = 5,
|
||||
MCLK_DIV_8 = 6,
|
||||
MCLK_DIV_9 = 7,
|
||||
MCLK_DIV_11 = 8,
|
||||
MCLK_DIV_12 = 9,
|
||||
MCLK_DIV_16 = 10,
|
||||
MCLK_DIV_18 = 11,
|
||||
MCLK_DIV_22 = 12,
|
||||
MCLK_DIV_24 = 13,
|
||||
MCLK_DIV_33 = 14,
|
||||
MCLK_DIV_36 = 15,
|
||||
MCLK_DIV_44 = 16,
|
||||
MCLK_DIV_48 = 17,
|
||||
MCLK_DIV_66 = 18,
|
||||
MCLK_DIV_72 = 19,
|
||||
MCLK_DIV_5 = 20,
|
||||
MCLK_DIV_10 = 21,
|
||||
MCLK_DIV_15 = 22,
|
||||
MCLK_DIV_17 = 23,
|
||||
MCLK_DIV_20 = 24,
|
||||
MCLK_DIV_25 = 25,
|
||||
MCLK_DIV_30 = 26,
|
||||
MCLK_DIV_32 = 27,
|
||||
MCLK_DIV_34 = 28,
|
||||
MCLK_DIV_7 = 29,
|
||||
MCLK_DIV_13 = 30,
|
||||
MCLK_DIV_14 = 31,
|
||||
MCLK_DIV_MAX,
|
||||
} es_sclk_div_t;
|
||||
typedef enum {
|
||||
MCLK_DIV_MIN = -1,
|
||||
MCLK_DIV_1 = 1,
|
||||
MCLK_DIV_2 = 2,
|
||||
MCLK_DIV_3 = 3,
|
||||
MCLK_DIV_4 = 4,
|
||||
MCLK_DIV_6 = 5,
|
||||
MCLK_DIV_8 = 6,
|
||||
MCLK_DIV_9 = 7,
|
||||
MCLK_DIV_11 = 8,
|
||||
MCLK_DIV_12 = 9,
|
||||
MCLK_DIV_16 = 10,
|
||||
MCLK_DIV_18 = 11,
|
||||
MCLK_DIV_22 = 12,
|
||||
MCLK_DIV_24 = 13,
|
||||
MCLK_DIV_33 = 14,
|
||||
MCLK_DIV_36 = 15,
|
||||
MCLK_DIV_44 = 16,
|
||||
MCLK_DIV_48 = 17,
|
||||
MCLK_DIV_66 = 18,
|
||||
MCLK_DIV_72 = 19,
|
||||
MCLK_DIV_5 = 20,
|
||||
MCLK_DIV_10 = 21,
|
||||
MCLK_DIV_15 = 22,
|
||||
MCLK_DIV_17 = 23,
|
||||
MCLK_DIV_20 = 24,
|
||||
MCLK_DIV_25 = 25,
|
||||
MCLK_DIV_30 = 26,
|
||||
MCLK_DIV_32 = 27,
|
||||
MCLK_DIV_34 = 28,
|
||||
MCLK_DIV_7 = 29,
|
||||
MCLK_DIV_13 = 30,
|
||||
MCLK_DIV_14 = 31,
|
||||
MCLK_DIV_MAX,
|
||||
} es_sclk_div_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LCLK_DIV_MIN = -1,
|
||||
LCLK_DIV_128 = 0,
|
||||
LCLK_DIV_192 = 1,
|
||||
LCLK_DIV_256 = 2,
|
||||
LCLK_DIV_384 = 3,
|
||||
LCLK_DIV_512 = 4,
|
||||
LCLK_DIV_576 = 5,
|
||||
LCLK_DIV_768 = 6,
|
||||
LCLK_DIV_1024 = 7,
|
||||
LCLK_DIV_1152 = 8,
|
||||
LCLK_DIV_1408 = 9,
|
||||
LCLK_DIV_1536 = 10,
|
||||
LCLK_DIV_2112 = 11,
|
||||
LCLK_DIV_2304 = 12,
|
||||
typedef enum {
|
||||
LCLK_DIV_MIN = -1,
|
||||
LCLK_DIV_128 = 0,
|
||||
LCLK_DIV_192 = 1,
|
||||
LCLK_DIV_256 = 2,
|
||||
LCLK_DIV_384 = 3,
|
||||
LCLK_DIV_512 = 4,
|
||||
LCLK_DIV_576 = 5,
|
||||
LCLK_DIV_768 = 6,
|
||||
LCLK_DIV_1024 = 7,
|
||||
LCLK_DIV_1152 = 8,
|
||||
LCLK_DIV_1408 = 9,
|
||||
LCLK_DIV_1536 = 10,
|
||||
LCLK_DIV_2112 = 11,
|
||||
LCLK_DIV_2304 = 12,
|
||||
|
||||
LCLK_DIV_125 = 16,
|
||||
LCLK_DIV_136 = 17,
|
||||
LCLK_DIV_250 = 18,
|
||||
LCLK_DIV_272 = 19,
|
||||
LCLK_DIV_375 = 20,
|
||||
LCLK_DIV_500 = 21,
|
||||
LCLK_DIV_544 = 22,
|
||||
LCLK_DIV_750 = 23,
|
||||
LCLK_DIV_1000 = 24,
|
||||
LCLK_DIV_1088 = 25,
|
||||
LCLK_DIV_1496 = 26,
|
||||
LCLK_DIV_1500 = 27,
|
||||
LCLK_DIV_MAX,
|
||||
} es_lclk_div_t;
|
||||
LCLK_DIV_125 = 16,
|
||||
LCLK_DIV_136 = 17,
|
||||
LCLK_DIV_250 = 18,
|
||||
LCLK_DIV_272 = 19,
|
||||
LCLK_DIV_375 = 20,
|
||||
LCLK_DIV_500 = 21,
|
||||
LCLK_DIV_544 = 22,
|
||||
LCLK_DIV_750 = 23,
|
||||
LCLK_DIV_1000 = 24,
|
||||
LCLK_DIV_1088 = 25,
|
||||
LCLK_DIV_1496 = 26,
|
||||
LCLK_DIV_1500 = 27,
|
||||
LCLK_DIV_MAX,
|
||||
} es_lclk_div_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
D2SE_PGA_GAIN_MIN = -1,
|
||||
D2SE_PGA_GAIN_DIS = 0,
|
||||
D2SE_PGA_GAIN_EN = 1,
|
||||
D2SE_PGA_GAIN_MAX = 2,
|
||||
} es_d2se_pga_t;
|
||||
typedef enum {
|
||||
D2SE_PGA_GAIN_MIN = -1,
|
||||
D2SE_PGA_GAIN_DIS = 0,
|
||||
D2SE_PGA_GAIN_EN = 1,
|
||||
D2SE_PGA_GAIN_MAX = 2,
|
||||
} es_d2se_pga_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ADC_INPUT_MIN = -1,
|
||||
ADC_INPUT_LINPUT1_RINPUT1 = 0x00,
|
||||
ADC_INPUT_MIC1 = 0x05,
|
||||
ADC_INPUT_MIC2 = 0x06,
|
||||
ADC_INPUT_LINPUT2_RINPUT2 = 0x50,
|
||||
ADC_INPUT_DIFFERENCE = 0xf0,
|
||||
ADC_INPUT_MAX,
|
||||
} es_adc_input_t;
|
||||
typedef enum {
|
||||
ADC_INPUT_MIN = -1,
|
||||
ADC_INPUT_LINPUT1_RINPUT1 = 0x00,
|
||||
ADC_INPUT_MIC1 = 0x05,
|
||||
ADC_INPUT_MIC2 = 0x06,
|
||||
ADC_INPUT_LINPUT2_RINPUT2 = 0x50,
|
||||
ADC_INPUT_DIFFERENCE = 0xf0,
|
||||
ADC_INPUT_MAX,
|
||||
} es_adc_input_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DAC_OUTPUT_MIN = -1,
|
||||
DAC_OUTPUT_LOUT1 = 0x04,
|
||||
DAC_OUTPUT_LOUT2 = 0x08,
|
||||
DAC_OUTPUT_SPK = 0x09,
|
||||
DAC_OUTPUT_ROUT1 = 0x10,
|
||||
DAC_OUTPUT_ROUT2 = 0x20,
|
||||
DAC_OUTPUT_ALL = 0x3c,
|
||||
DAC_OUTPUT_MAX,
|
||||
} es_dac_output_t;
|
||||
typedef enum {
|
||||
DAC_OUTPUT_MIN = -1,
|
||||
DAC_OUTPUT_LOUT1 = 0x04,
|
||||
DAC_OUTPUT_LOUT2 = 0x08,
|
||||
DAC_OUTPUT_SPK = 0x09,
|
||||
DAC_OUTPUT_ROUT1 = 0x10,
|
||||
DAC_OUTPUT_ROUT2 = 0x20,
|
||||
DAC_OUTPUT_ALL = 0x3c,
|
||||
DAC_OUTPUT_MAX,
|
||||
} es_dac_output_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MIC_GAIN_MIN = -1,
|
||||
MIC_GAIN_0DB = 0,
|
||||
MIC_GAIN_3DB = 3,
|
||||
MIC_GAIN_6DB = 6,
|
||||
MIC_GAIN_9DB = 9,
|
||||
MIC_GAIN_12DB = 12,
|
||||
MIC_GAIN_15DB = 15,
|
||||
MIC_GAIN_18DB = 18,
|
||||
MIC_GAIN_21DB = 21,
|
||||
MIC_GAIN_24DB = 24,
|
||||
MIC_GAIN_MAX,
|
||||
} es_mic_gain_t;
|
||||
typedef enum {
|
||||
MIC_GAIN_MIN = -1,
|
||||
MIC_GAIN_0DB = 0,
|
||||
MIC_GAIN_3DB = 3,
|
||||
MIC_GAIN_6DB = 6,
|
||||
MIC_GAIN_9DB = 9,
|
||||
MIC_GAIN_12DB = 12,
|
||||
MIC_GAIN_15DB = 15,
|
||||
MIC_GAIN_18DB = 18,
|
||||
MIC_GAIN_21DB = 21,
|
||||
MIC_GAIN_24DB = 24,
|
||||
MIC_GAIN_MAX,
|
||||
} es_mic_gain_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ES_MODULE_MIN = -1,
|
||||
ES_MODULE_ADC = 0x01,
|
||||
ES_MODULE_DAC = 0x02,
|
||||
ES_MODULE_ADC_DAC = 0x03,
|
||||
ES_MODULE_LINE = 0x04,
|
||||
ES_MODULE_MAX
|
||||
} es_module_t;
|
||||
typedef enum {
|
||||
ES_MODULE_MIN = -1,
|
||||
ES_MODULE_ADC = 0x01,
|
||||
ES_MODULE_DAC = 0x02,
|
||||
ES_MODULE_ADC_DAC = 0x03,
|
||||
ES_MODULE_LINE = 0x04,
|
||||
ES_MODULE_MAX
|
||||
} es_module_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ES_MODE_MIN = -1,
|
||||
ES_MODE_SLAVE = 0x00,
|
||||
ES_MODE_MASTER = 0x01,
|
||||
ES_MODE_MAX,
|
||||
} es_mode_t;
|
||||
typedef enum {
|
||||
ES_MODE_MIN = -1,
|
||||
ES_MODE_SLAVE = 0x00,
|
||||
ES_MODE_MASTER = 0x01,
|
||||
ES_MODE_MAX,
|
||||
} es_mode_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ES_I2S_MIN = -1,
|
||||
ES_I2S_NORMAL = 0,
|
||||
ES_I2S_LEFT = 1,
|
||||
ES_I2S_RIGHT = 2,
|
||||
ES_I2S_DSP = 3,
|
||||
ES_I2S_MAX
|
||||
} es_i2s_fmt_t;
|
||||
typedef enum {
|
||||
ES_I2S_MIN = -1,
|
||||
ES_I2S_NORMAL = 0,
|
||||
ES_I2S_LEFT = 1,
|
||||
ES_I2S_RIGHT = 2,
|
||||
ES_I2S_DSP = 3,
|
||||
ES_I2S_MAX
|
||||
} es_i2s_fmt_t;
|
||||
|
||||
/**
|
||||
* @brief Configure ES8388 clock
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
es_sclk_div_t sclk_div; /*!< bits clock divide */
|
||||
es_lclk_div_t lclk_div; /*!< WS clock divide */
|
||||
} es_i2s_clock_t;
|
||||
/**
|
||||
* @brief Configure ES8388 clock
|
||||
*/
|
||||
typedef struct {
|
||||
es_sclk_div_t sclk_div; /*!< bits clock divide */
|
||||
es_lclk_div_t lclk_div; /*!< WS clock divide */
|
||||
} es_i2s_clock_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,13 +18,15 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tas5805m.h"
|
||||
|
||||
#include "audio_volume.h"
|
||||
#include "board.h"
|
||||
#include "esp_log.h"
|
||||
#include "i2c_bus.h"
|
||||
@@ -33,212 +35,205 @@
|
||||
static const char *TAG = "TAS5805M";
|
||||
|
||||
#define TAS5805M_ADDR 0x5c
|
||||
#define TAS5805M_RST_GPIO get_pa_enable_gpio ()
|
||||
#define TAS5805M_VOLUME_MAX 100
|
||||
#define TAS5805M_VOLUME_MIN 0
|
||||
#define TAS5805M_RST_GPIO get_pa_enable_gpio()
|
||||
|
||||
#define TAS5805M_ASSERT(a, format, b, ...) \
|
||||
if ((a) != 0) \
|
||||
{ \
|
||||
ESP_LOGE (TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
#define TAS5805M_ASSERT(a, format, b, ...) \
|
||||
if ((a) != 0) { \
|
||||
ESP_LOGE(TAG, format, ##__VA_ARGS__); \
|
||||
return b; \
|
||||
}
|
||||
|
||||
esp_err_t tas5805m_ctrl (audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
esp_err_t tas5805m_conig_iface (audio_hal_codec_mode_t mode,
|
||||
esp_err_t tas5805m_ctrl(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
esp_err_t tas5805m_config_iface(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
static i2c_bus_handle_t i2c_handler;
|
||||
static codec_dac_volume_config_t *dac_vol_handle;
|
||||
|
||||
#define TAS5805M_DAC_VOL_CFG_DEFAULT() \
|
||||
{ \
|
||||
.max_dac_volume = 24, .min_dac_volume = -103, \
|
||||
.board_pa_gain = BOARD_PA_GAIN, .volume_accuracy = 0.5, \
|
||||
.dac_vol_symbol = -1, .zero_volume_reg = 0x30, .reg_value = 0, \
|
||||
.user_volume = 0, .offset_conv_volume = NULL, \
|
||||
}
|
||||
|
||||
/*
|
||||
* i2c default configuration
|
||||
*/
|
||||
static i2c_config_t i2c_cfg = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000,
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = 100000,
|
||||
};
|
||||
|
||||
/*
|
||||
* Operate fuction of PA
|
||||
*/
|
||||
audio_hal_func_t AUDIO_CODEC_TAS5805M_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = tas5805m_init,
|
||||
.audio_codec_deinitialize = tas5805m_deinit,
|
||||
.audio_codec_ctrl = tas5805m_ctrl,
|
||||
.audio_codec_config_iface = tas5805m_conig_iface,
|
||||
.audio_codec_set_mute = tas5805m_set_mute,
|
||||
.audio_codec_set_volume = tas5805m_set_volume,
|
||||
.audio_codec_get_volume = tas5805m_get_volume,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
.audio_codec_initialize = tas5805m_init,
|
||||
.audio_codec_deinitialize = tas5805m_deinit,
|
||||
.audio_codec_ctrl = tas5805m_ctrl,
|
||||
.audio_codec_config_iface = tas5805m_config_iface,
|
||||
.audio_codec_set_mute = tas5805m_set_mute,
|
||||
.audio_codec_set_volume = tas5805m_set_volume,
|
||||
.audio_codec_get_volume = tas5805m_get_volume,
|
||||
.audio_codec_enable_pa = NULL,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
static esp_err_t
|
||||
tas5805m_transmit_registers (const tas5805m_cfg_reg_t *conf_buf, int size)
|
||||
{
|
||||
static esp_err_t tas5805m_transmit_registers(const tas5805m_cfg_reg_t *conf_buf,
|
||||
int size) {
|
||||
int i = 0;
|
||||
esp_err_t ret = ESP_OK;
|
||||
while (i < size)
|
||||
{
|
||||
switch (conf_buf[i].offset)
|
||||
{
|
||||
case CFG_META_SWITCH:
|
||||
// Used in legacy applications. Ignored here.
|
||||
break;
|
||||
case CFG_META_DELAY:
|
||||
vTaskDelay (conf_buf[i].value / portTICK_RATE_MS);
|
||||
break;
|
||||
case CFG_META_BURST:
|
||||
ret = i2c_bus_write_bytes (
|
||||
i2c_handler, TAS5805M_ADDR,
|
||||
(unsigned char *)(&conf_buf[i + 1].offset), 1,
|
||||
(unsigned char *)(&conf_buf[i + 1].value), conf_buf[i].value);
|
||||
i += (conf_buf[i].value / 2) + 1;
|
||||
break;
|
||||
case CFG_END_1:
|
||||
if (CFG_END_2 == conf_buf[i + 1].offset
|
||||
&& CFG_END_3 == conf_buf[i + 2].offset)
|
||||
{
|
||||
ESP_LOGI (TAG, "End of tms5805m reg: %d\n", i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = i2c_bus_write_bytes (i2c_handler, TAS5805M_ADDR,
|
||||
(unsigned char *)(&conf_buf[i].offset), 1,
|
||||
(unsigned char *)(&conf_buf[i].value), 1);
|
||||
break;
|
||||
while (i < size) {
|
||||
switch (conf_buf[i].offset) {
|
||||
case CFG_META_SWITCH:
|
||||
// Used in legacy applications. Ignored here.
|
||||
break;
|
||||
case CFG_META_DELAY:
|
||||
vTaskDelay(conf_buf[i].value / portTICK_RATE_MS);
|
||||
break;
|
||||
case CFG_META_BURST:
|
||||
ret = i2c_bus_write_bytes(i2c_handler, TAS5805M_ADDR,
|
||||
(unsigned char *)(&conf_buf[i + 1].offset), 1,
|
||||
(unsigned char *)(&conf_buf[i + 1].value),
|
||||
conf_buf[i].value);
|
||||
i += (conf_buf[i].value / 2) + 1;
|
||||
break;
|
||||
case CFG_END_1:
|
||||
if (CFG_END_2 == conf_buf[i + 1].offset &&
|
||||
CFG_END_3 == conf_buf[i + 2].offset) {
|
||||
ESP_LOGI(TAG, "End of tms5805m reg: %d\n", i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGE (TAG, "Fail to load configuration to tas5805m");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI (TAG, "%s: write %d reg done", __FUNCTION__, i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_init (audio_hal_codec_config_t *codec_cfg)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_LOGI (TAG, "Power ON CODEC with GPIO %d", TAS5805M_RST_GPIO);
|
||||
gpio_config_t io_conf;
|
||||
io_conf.pin_bit_mask = BIT64 (TAS5805M_RST_GPIO);
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
gpio_config (&io_conf);
|
||||
gpio_set_level (TAS5805M_RST_GPIO, 0);
|
||||
vTaskDelay (20 / portTICK_RATE_MS);
|
||||
gpio_set_level (TAS5805M_RST_GPIO, 1);
|
||||
vTaskDelay (200 / portTICK_RATE_MS);
|
||||
|
||||
ret = get_i2c_pins (I2C_NUM_0, &i2c_cfg);
|
||||
i2c_handler = i2c_bus_create (I2C_NUM_0, &i2c_cfg);
|
||||
if (i2c_handler == NULL)
|
||||
{
|
||||
ESP_LOGW (TAG, "failed to create i2c bus handler\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ret |= tas5805m_transmit_registers (tas5805m_registers,
|
||||
sizeof (tas5805m_registers)
|
||||
/ sizeof (tas5805m_registers[0]));
|
||||
|
||||
TAS5805M_ASSERT (ret, "Fail to iniitialize tas5805m PA", ESP_FAIL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_set_volume (int vol)
|
||||
{
|
||||
int vol_idx = 0;
|
||||
|
||||
if (vol < TAS5805M_VOLUME_MIN)
|
||||
{
|
||||
vol = TAS5805M_VOLUME_MIN;
|
||||
}
|
||||
if (vol > TAS5805M_VOLUME_MAX)
|
||||
{
|
||||
vol = TAS5805M_VOLUME_MAX;
|
||||
}
|
||||
vol_idx = vol / 5;
|
||||
|
||||
uint8_t cmd[2] = { 0, 0 };
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
cmd[0] = MASTER_VOL_REG_ADDR;
|
||||
cmd[1] = tas5805m_volume[vol_idx];
|
||||
ret = i2c_bus_write_bytes (i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1],
|
||||
1);
|
||||
ESP_LOGW (TAG, "volume = 0x%x", cmd[1]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_get_volume (int *value)
|
||||
{
|
||||
/// FIXME: Got the digit volume is not right.
|
||||
uint8_t cmd[2] = { MASTER_VOL_REG_ADDR, 0x00 };
|
||||
esp_err_t ret = i2c_bus_read_bytes (i2c_handler, TAS5805M_ADDR, &cmd[0], 1,
|
||||
&cmd[1], 1);
|
||||
TAS5805M_ASSERT (ret, "Fail to get volume", ESP_FAIL);
|
||||
int i;
|
||||
for (i = 0; i < sizeof (tas5805m_volume); i++)
|
||||
{
|
||||
if (cmd[1] >= tas5805m_volume[i])
|
||||
break;
|
||||
default:
|
||||
ret = i2c_bus_write_bytes(i2c_handler, TAS5805M_ADDR,
|
||||
(unsigned char *)(&conf_buf[i].offset), 1,
|
||||
(unsigned char *)(&conf_buf[i].value), 1);
|
||||
break;
|
||||
}
|
||||
ESP_LOGI (TAG, "Volume is %d", i * 5);
|
||||
*value = 5 * i;
|
||||
i++;
|
||||
}
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Fail to load configuration to tas5805m");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "%s: write %d reg done", __FUNCTION__, i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_set_mute (bool enable)
|
||||
{
|
||||
esp_err_t tas5805m_init(audio_hal_codec_config_t *codec_cfg) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t cmd[2] = { TAS5805M_REG_03, 0x00 };
|
||||
ret |= i2c_bus_read_bytes (i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1],
|
||||
1);
|
||||
ESP_LOGI(TAG, "Power ON CODEC with GPIO %d", TAS5805M_RST_GPIO);
|
||||
gpio_config_t io_conf;
|
||||
io_conf.pin_bit_mask = BIT64(TAS5805M_RST_GPIO);
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
gpio_config(&io_conf);
|
||||
gpio_set_level(TAS5805M_RST_GPIO, 0);
|
||||
vTaskDelay(20 / portTICK_RATE_MS);
|
||||
gpio_set_level(TAS5805M_RST_GPIO, 1);
|
||||
vTaskDelay(200 / portTICK_RATE_MS);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
cmd[1] |= 0x8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd[1] &= (~0x08);
|
||||
}
|
||||
ret |= i2c_bus_write_bytes (i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1],
|
||||
1);
|
||||
ret = get_i2c_pins(I2C_NUM_0, &i2c_cfg);
|
||||
i2c_handler = i2c_bus_create(I2C_NUM_0, &i2c_cfg);
|
||||
if (i2c_handler == NULL) {
|
||||
ESP_LOGW(TAG, "failed to create i2c bus handler\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
TAS5805M_ASSERT (ret, "Fail to set mute", ESP_FAIL);
|
||||
ret |= tas5805m_transmit_registers(
|
||||
tas5805m_registers,
|
||||
sizeof(tas5805m_registers) / sizeof(tas5805m_registers[0]));
|
||||
|
||||
TAS5805M_ASSERT(ret, "Fail to iniitialize tas5805m PA", ESP_FAIL);
|
||||
|
||||
codec_dac_volume_config_t vol_cfg = TAS5805M_DAC_VOL_CFG_DEFAULT();
|
||||
dac_vol_handle = audio_codec_volume_init(&vol_cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_get_mute (int *value)
|
||||
{
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @note Register values. 0xFE: -103 dB, 0x94: -50 dB, 0x30: 0 dB, 0x00: 24 dB
|
||||
* @note Accuracy of gain is 0.5 dB
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_set_volume(int volume) {
|
||||
uint8_t reg = 0;
|
||||
uint8_t cmd[2] = {0, 0};
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t cmd[2] = { TAS5805M_REG_03, 0x00 };
|
||||
ret |= i2c_bus_read_bytes (i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1],
|
||||
1);
|
||||
|
||||
TAS5805M_ASSERT (ret, "Fail to get mute", ESP_FAIL);
|
||||
reg = audio_codec_get_dac_reg_value(dac_vol_handle, volume);
|
||||
|
||||
cmd[0] = MASTER_VOL_REG_ADDR;
|
||||
cmd[1] = reg;
|
||||
|
||||
ret = i2c_bus_write_bytes(i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1], 1);
|
||||
|
||||
ESP_LOGD(TAG, "Set volume:%.2d reg_value:0x%.2x dB:%.1f",
|
||||
(int)dac_vol_handle->user_volume, reg,
|
||||
audio_codec_cal_dac_volume(dac_vol_handle));
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t tas5805m_get_volume(int *volume) {
|
||||
/// FIXME: Got the digit volume is not right.
|
||||
uint8_t cmd[2] = {MASTER_VOL_REG_ADDR, 0x00};
|
||||
esp_err_t ret =
|
||||
i2c_bus_read_bytes(i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1], 1);
|
||||
TAS5805M_ASSERT(ret, "Fail to get volume", ESP_FAIL);
|
||||
if (cmd[1] == dac_vol_handle->reg_value) {
|
||||
*volume = dac_vol_handle->user_volume;
|
||||
} else {
|
||||
*volume = 0;
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
ESP_LOGD(TAG, "Get volume:%.2d reg_value:0x%.2x", *volume, cmd[1]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t tas5805m_set_mute(bool enable) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t cmd[2] = {TAS5805M_REG_03, 0x00};
|
||||
ret |= i2c_bus_read_bytes(i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1], 1);
|
||||
|
||||
if (enable) {
|
||||
cmd[1] |= 0x8;
|
||||
} else {
|
||||
cmd[1] &= (~0x08);
|
||||
}
|
||||
ret |=
|
||||
i2c_bus_write_bytes(i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1], 1);
|
||||
|
||||
TAS5805M_ASSERT(ret, "Fail to set mute", ESP_FAIL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t tas5805m_get_mute(int *value) {
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t cmd[2] = {TAS5805M_REG_03, 0x00};
|
||||
ret |= i2c_bus_read_bytes(i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1], 1);
|
||||
|
||||
TAS5805M_ASSERT(ret, "Fail to get mute", ESP_FAIL);
|
||||
*value = (cmd[1] & 0x08) >> 4;
|
||||
ESP_LOGI (TAG, "Get mute value: 0x%x", *value);
|
||||
ESP_LOGI(TAG, "Get mute value: 0x%x", *value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_set_mute_fade (int value)
|
||||
{
|
||||
esp_err_t tas5805m_set_mute_fade(int value) {
|
||||
esp_err_t ret = 0;
|
||||
unsigned char cmd[2] = { MUTE_TIME_REG_ADDR, 0x00 };
|
||||
unsigned char cmd[2] = {MUTE_TIME_REG_ADDR, 0x00};
|
||||
/* Time for register value
|
||||
* 000: 11.5 ms
|
||||
* 001: 53 ms
|
||||
@@ -249,75 +244,55 @@ tas5805m_set_mute_fade (int value)
|
||||
* 110: 2.665 sec
|
||||
* 111: 5.33 sec
|
||||
*/
|
||||
if (value <= 12)
|
||||
{
|
||||
cmd[1] = 0;
|
||||
}
|
||||
else if (value <= 53)
|
||||
{
|
||||
cmd[1] = 1;
|
||||
}
|
||||
else if (value <= 107)
|
||||
{
|
||||
cmd[1] = 2;
|
||||
}
|
||||
else if (value <= 267)
|
||||
{
|
||||
cmd[1] = 3;
|
||||
}
|
||||
else if (value <= 535)
|
||||
{
|
||||
cmd[1] = 4;
|
||||
}
|
||||
else if (value <= 1065)
|
||||
{
|
||||
cmd[1] = 5;
|
||||
}
|
||||
else if (value <= 2665)
|
||||
{
|
||||
cmd[1] = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd[1] = 7;
|
||||
}
|
||||
if (value <= 12) {
|
||||
cmd[1] = 0;
|
||||
} else if (value <= 53) {
|
||||
cmd[1] = 1;
|
||||
} else if (value <= 107) {
|
||||
cmd[1] = 2;
|
||||
} else if (value <= 267) {
|
||||
cmd[1] = 3;
|
||||
} else if (value <= 535) {
|
||||
cmd[1] = 4;
|
||||
} else if (value <= 1065) {
|
||||
cmd[1] = 5;
|
||||
} else if (value <= 2665) {
|
||||
cmd[1] = 6;
|
||||
} else {
|
||||
cmd[1] = 7;
|
||||
}
|
||||
cmd[1] |= (cmd[1] << 4);
|
||||
|
||||
ret |= i2c_bus_write_bytes (i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1],
|
||||
1);
|
||||
TAS5805M_ASSERT (ret, "Fail to set mute fade", ESP_FAIL);
|
||||
ESP_LOGI (TAG, "Set mute fade, value:%d, 0x%x", value, cmd[1]);
|
||||
ret |=
|
||||
i2c_bus_write_bytes(i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1], 1);
|
||||
TAS5805M_ASSERT(ret, "Fail to set mute fade", ESP_FAIL);
|
||||
ESP_LOGI(TAG, "Set mute fade, value:%d, 0x%x", value, cmd[1]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_set_damp_mode (int value)
|
||||
{
|
||||
unsigned char cmd[2] = { 0 };
|
||||
esp_err_t tas5805m_set_damp_mode(int value) {
|
||||
unsigned char cmd[2] = {0};
|
||||
cmd[0] = TAS5805M_REG_02;
|
||||
cmd[1] = 0x10 | value;
|
||||
return i2c_bus_write_bytes (i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1],
|
||||
1);
|
||||
return i2c_bus_write_bytes(i2c_handler, TAS5805M_ADDR, &cmd[0], 1, &cmd[1],
|
||||
1);
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_deinit (void)
|
||||
{
|
||||
esp_err_t tas5805m_deinit(void) {
|
||||
// TODO
|
||||
i2c_bus_delete(i2c_handler);
|
||||
audio_codec_volume_deinit(dac_vol_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t tas5805m_ctrl(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state) {
|
||||
// TODO
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_ctrl (audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state)
|
||||
{
|
||||
// TODO
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t
|
||||
tas5805m_conig_iface (audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface)
|
||||
{
|
||||
esp_err_t tas5805m_config_iface(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface) {
|
||||
// TODO
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TAS5805M_REG_00 0x00
|
||||
@@ -62,91 +61,91 @@ extern "C"
|
||||
#define TAS5805M_DAMP_MODE_BTL 0x0
|
||||
#define TAS5805M_DAMP_MODE_PBTL 0x04
|
||||
|
||||
/**
|
||||
* @brief Initialize TAS5805 codec chip
|
||||
*
|
||||
* @param cfg configuration of TAS5805
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_init (audio_hal_codec_config_t *codec_cfg);
|
||||
/**
|
||||
* @brief Initialize TAS5805 codec chip
|
||||
*
|
||||
* @param cfg configuration of TAS5805
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_init(audio_hal_codec_config_t *codec_cfg);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize TAS5805 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_deinit (void);
|
||||
/**
|
||||
* @brief Deinitialize TAS5805 codec chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_set_volume (int vol);
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_set_volume(int vol);
|
||||
|
||||
/**
|
||||
* @brief Get voice volume
|
||||
*
|
||||
* @param[out] *volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_get_volume (int *value);
|
||||
/**
|
||||
* @brief Get voice volume
|
||||
*
|
||||
* @param[out] *volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t tas5805m_get_volume(int *value);
|
||||
|
||||
/**
|
||||
* @brief Set TAS5805 mute or not
|
||||
* Continuously call should have an interval time determined by
|
||||
* tas5805m_set_mute_fade()
|
||||
*
|
||||
* @param enable enable(1) or disable(0)
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t tas5805m_set_mute (bool enable);
|
||||
/**
|
||||
* @brief Set TAS5805 mute or not
|
||||
* Continuously call should have an interval time determined by
|
||||
* tas5805m_set_mute_fade()
|
||||
*
|
||||
* @param enable enable(1) or disable(0)
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t tas5805m_set_mute(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Mute gradually by (value)ms
|
||||
*
|
||||
* @param value Time for mute with millisecond.
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t tas5805m_set_mute_fade (int value);
|
||||
/**
|
||||
* @brief Mute gradually by (value)ms
|
||||
*
|
||||
* @param value Time for mute with millisecond.
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t tas5805m_set_mute_fade(int value);
|
||||
|
||||
/**
|
||||
* @brief Get TAS5805 mute status
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t tas5805m_get_mute (int *value);
|
||||
/**
|
||||
* @brief Get TAS5805 mute status
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t tas5805m_get_mute(int *value);
|
||||
|
||||
/**
|
||||
* @brief Set DAMP mode
|
||||
*
|
||||
* @param value TAS5805M_DAMP_MODE_BTL or TAS5805M_DAMP_MODE_PBTL
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t tas5805m_set_damp_mode (int value);
|
||||
/**
|
||||
* @brief Set DAMP mode
|
||||
*
|
||||
* @param value TAS5805M_DAMP_MODE_BTL or TAS5805M_DAMP_MODE_PBTL
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t tas5805m_set_damp_mode(int value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
9
components/audio_hal/driver/zl38063/LICENSE.txt
Normal file
9
components/audio_hal/driver/zl38063/LICENSE.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright 2018 Microsemi Inc.
|
||||
|
||||
Permission is hereby granted, 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.
|
||||
36
components/audio_hal/driver/zl38063/Readme_twolf.txt
Normal file
36
components/audio_hal/driver/zl38063/Readme_twolf.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
The Source code for the Timberwolf device driver is partitioned into 4 folders.
|
||||
|
||||
\api_lib\
|
||||
There are 5 files in this folder
|
||||
The VprocTwolf_access.c/h -
|
||||
is the user's space OS independent API to read/write specific register of the device to
|
||||
reset the device into one of the 5 supported reset modes and to boot load a firmware/configuration record into the device.
|
||||
The API must be used in conjunction with a low level device driver such as microsemi_spis_tw.c/h, VprocGal_HAL.c/h
|
||||
|
||||
vproc_common.c/h -
|
||||
includes functions and variable declarations that are common to all Microsemi Voice processing devices.
|
||||
These functions include the Vproc_msDelay(), VprocWait(). The Variables declarations include
|
||||
the device status codes, and device reset modes enums. As well as multiple macros to enable debug mode.
|
||||
|
||||
the specific user_space hardware abstraction layer code for the ZL38040/05x/06x/08x Timberwolf devices.
|
||||
|
||||
\firmware\
|
||||
This folder contains the firmware image , configuration record files and header file.
|
||||
|
||||
NOTE: The firmware of the development board and its corresponding configuration have been encapsulated into a static library.
|
||||
|
||||
\example_apps\
|
||||
This folder contains example host applications for the zl38040/050/060/080 Microsemi devices.
|
||||
|
||||
zl38063.c/h -
|
||||
a series of operations for zl38063, such as initialize, adjust the volume, and so on.
|
||||
|
||||
|
||||
NOTE: You can get the latest firmware and related technical support by registering SDS account.
|
||||
http://sds.microsemi.com/software.php.
|
||||
|
||||
ZLS38063 GUI software(MiTuner Lite GUI Software), ZLS38063 and ZLS38508LITE
|
||||
http://sds.microsemi.com/software.php?view_type=listrev&id=103386.
|
||||
|
||||
firmware of ZL38063
|
||||
http://sds.microsemi.com/software.php?view_type=listrev&id=104598.
|
||||
1061
components/audio_hal/driver/zl38063/api_lib/vprocTwolf_access.c
Normal file
1061
components/audio_hal/driver/zl38063/api_lib/vprocTwolf_access.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* vprocTwolf_access.h - Voice Processor devices high level access module
|
||||
*function prototypes, variables
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef VPROC_TWOLFACCESS_H
|
||||
#define VPROC_TWOLFACCESS_H
|
||||
|
||||
#include "vproc_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TWOLF_MAILBOX_SPINWAIT 1000 /*at least a 1000 to avoid mailbox busy */
|
||||
|
||||
/*device HBI command structure*/
|
||||
typedef struct hbiCmdInfo {
|
||||
unsigned char page;
|
||||
unsigned char offset;
|
||||
unsigned char numwords;
|
||||
} hbiCmdInfo;
|
||||
|
||||
/* external function prototypes */
|
||||
|
||||
VprocStatusType VprocTwolfHbiInit(
|
||||
void); /*Use this function to initialize the HBI bus*/
|
||||
|
||||
VprocStatusType VprocTwolfHbiRead(
|
||||
unsigned short cmd, /*the 16-bit register to read from*/
|
||||
unsigned char numwords, /* The number of 16-bit words to read*/
|
||||
unsigned short *pData); /* Pointer to the read data buffer*/
|
||||
|
||||
VprocStatusType VprocTwolfHbiWrite(
|
||||
unsigned short cmd, /*the 16-bit register to write to*/
|
||||
unsigned char numwords, /* The number of 16-bit words to write*/
|
||||
unsigned short *pData); /*the words (0-255) to write*/
|
||||
|
||||
VprocStatusType
|
||||
TwolfHbiNoOp( /*send no-op command to the device*/
|
||||
unsigned char numWords); /* The number of no-op (0-255) to write*/
|
||||
|
||||
/*An alternative method to loading the firmware into the device
|
||||
* USe this method if you have used the provided tool to convert the *.s3 into
|
||||
* c code that can be compiled with the application
|
||||
*/
|
||||
VprocStatusType
|
||||
VprocTwolfHbiBoot_alt(/*use this function to boot load the firmware (*.c) from
|
||||
the host to the device RAM*/
|
||||
twFirmware *st_firmware); /*Pointer to the firmware image
|
||||
in host RAM*/
|
||||
|
||||
VprocStatusType VprocTwolfLoadConfig(dataArr *pCr2Buf,
|
||||
unsigned short numElements);
|
||||
|
||||
VprocStatusType VprocTwolfHbiCleanup(void);
|
||||
VprocStatusType VprocTwolfHbiBootPrepare(void);
|
||||
VprocStatusType VprocTwolfHbiBootMoreData(char *dataBlock);
|
||||
VprocStatusType VprocTwolfHbiBootConclude(void);
|
||||
VprocStatusType VprocTwolfFirmwareStop(
|
||||
void); /*Use this function to halt the currently running firmware*/
|
||||
VprocStatusType VprocTwolfFirmwareStart(
|
||||
void); /*Use this function to start/restart the firmware currently in RAM*/
|
||||
VprocStatusType VprocTwolfSaveImgToFlash(
|
||||
void); /*Save current loaded firmware from device RAM to FLASH*/
|
||||
VprocStatusType VprocTwolfSaveCfgToFlash(
|
||||
void); /*Save current device config from device RAM to FLASH*/
|
||||
VprocStatusType VprocTwolfReset(VprocResetMode mode);
|
||||
VprocStatusType VprocTwolfEraseFlash(void);
|
||||
VprocStatusType VprocTwolfLoadFwrCfgFromFlash(uint16 image_number);
|
||||
VprocStatusType VprocTwolfSetVolume(uint8 vol);
|
||||
VprocStatusType VprocTwolfGetVolume(int8_t *vol);
|
||||
VprocStatusType VprocTwolfGetAppStatus(uint16 *status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* VPROCTWOLFACCESS_H */
|
||||
165
components/audio_hal/driver/zl38063/api_lib/vproc_common.c
Normal file
165
components/audio_hal/driver/zl38063/api_lib/vproc_common.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/****************************************************************************
|
||||
* vproc_common.c - Hal functions for the VPROC API
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "vproc_common.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "audio_idf_version.h"
|
||||
#include "board.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "lwip/def.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 4))
|
||||
#define SPI_HOST_NUM SPI2_HOST
|
||||
#elif (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0))
|
||||
#define SPI_HOST_NUM SPI3_HOST
|
||||
#else
|
||||
#define SPI_HOST_NUM HSPI_HOST
|
||||
#endif
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
#include "esp_rom_sys.h"
|
||||
#endif
|
||||
|
||||
static spi_device_handle_t g_spi = NULL;
|
||||
|
||||
int VprocHALInit(void) {
|
||||
/*if the customer platform requires any init
|
||||
* then implement such init here.
|
||||
* Otherwise the implementation of this function is complete
|
||||
*/
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
spi_bus_config_t buscfg = {0};
|
||||
spi_device_interface_config_t devcfg = {
|
||||
.clock_speed_hz = 1000000, // Clock out at 10 MHz
|
||||
.mode = 0, // SPI mode 0
|
||||
.queue_size = 6, // queue 7 transactions at a time
|
||||
};
|
||||
|
||||
get_spi_pins(&buscfg, &devcfg);
|
||||
// Initialize the SPI bus
|
||||
if (g_spi) {
|
||||
return ret;
|
||||
}
|
||||
ret = spi_bus_initialize(SPI_HOST_NUM, &buscfg, 0);
|
||||
assert(ret == ESP_OK);
|
||||
ret = spi_bus_add_device(SPI_HOST_NUM, &devcfg, &g_spi);
|
||||
assert(ret == ESP_OK);
|
||||
gpio_set_pull_mode(0, GPIO_FLOATING);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*HAL clean up function - To close any open file connection
|
||||
* microsemi_spis_tw kernel char driver
|
||||
*
|
||||
* return: a positive integer value for success, a negative integer value for
|
||||
* failure
|
||||
*/
|
||||
|
||||
void VprocHALcleanup(void) {
|
||||
/*if the customer platform requires any cleanup function
|
||||
* then implement such function here.
|
||||
* Otherwise the implementation of this function is complete
|
||||
*/
|
||||
int ret = 0;
|
||||
ret = spi_bus_remove_device(g_spi);
|
||||
assert(ret == ESP_OK);
|
||||
ret = spi_bus_free(SPI_HOST_NUM);
|
||||
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
/*Note - These functions are PLATFORM SPECIFIC- They must be modified
|
||||
* accordingly
|
||||
**********************************************************************/
|
||||
|
||||
/* Vproc_msDelay(): use this function to
|
||||
* force a delay of specified time in resolution of milli-second
|
||||
*
|
||||
* Input Argument: time in unsigned 16-bit
|
||||
* Return: none
|
||||
*/
|
||||
|
||||
void Vproc_msDelay(unsigned short time) {
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
esp_rom_delay_us(time * 1000);
|
||||
#else
|
||||
ets_delay_us(time * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* VprocWait(): use this function to
|
||||
* force a delay of specified time in resolution of 125 micro-Seconds
|
||||
*
|
||||
* Input Argument: time in unsigned 32-bit
|
||||
* Return: none
|
||||
*/
|
||||
void VprocWait(unsigned long int time) {
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
esp_rom_delay_us(time * 1000);
|
||||
#else
|
||||
ets_delay_us(time * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define BIGENDIAN 1
|
||||
|
||||
/* This is the platform dependent low level spi
|
||||
* function to write 16-bit data to the ZL380xx device
|
||||
*/
|
||||
int VprocHALWrite(unsigned short val) {
|
||||
/*Note: Implement this as per your platform*/
|
||||
esp_err_t ret;
|
||||
spi_transaction_t t;
|
||||
unsigned short data = 0;
|
||||
memset(&t, 0, sizeof(t)); // Zero out the transaction
|
||||
t.length = sizeof(unsigned short) *
|
||||
8; // Len is in bytes, transaction length is in bits.
|
||||
#if BIGENDIAN
|
||||
data = htons(val);
|
||||
t.tx_buffer = &data; // Data
|
||||
#else
|
||||
t.tx_buffer = &val;
|
||||
#endif
|
||||
ret = spi_device_transmit(g_spi, &t); // Transmit
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is the platform dependent low level spi
|
||||
* function to read 16-bit data from the ZL380xx device
|
||||
*/
|
||||
int VprocHALRead(unsigned short *pVal) {
|
||||
/*Note: Implement this as per your platform*/
|
||||
esp_err_t ret;
|
||||
spi_transaction_t t;
|
||||
unsigned short data = 0;
|
||||
|
||||
memset(&t, 0, sizeof(t)); // Zero out the transaction
|
||||
t.length = sizeof(unsigned short) * 8;
|
||||
t.rxlength = sizeof(unsigned short) *
|
||||
8; // The unit of len is byte, and the unit of length is bit.
|
||||
t.rx_buffer = &data;
|
||||
ret = spi_device_transmit(g_spi, &t); // Transmit!
|
||||
#if BIGENDIAN
|
||||
*pVal = ntohs(data);
|
||||
#else
|
||||
*pVal = data;
|
||||
#endif
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
129
components/audio_hal/driver/zl38063/api_lib/vproc_common.h
Normal file
129
components/audio_hal/driver/zl38063/api_lib/vproc_common.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
* vproc_common.h - Hal functions prototypes, macros and variables for the VPROC
|
||||
*API
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef VPROC_COMMON_H
|
||||
#define VPROC_COMMON_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DEBUG_LOGD ESP_LOGD
|
||||
#define DEBUG_LOGE ESP_LOGE
|
||||
#define DEBUG_LOGI ESP_LOGI
|
||||
/*This header includes some platform dependent data types*/
|
||||
#include "vproc_data_types.h"
|
||||
|
||||
// #define RETRY_COUNT 100
|
||||
#define VPROC_TIMEOUT 500
|
||||
|
||||
#define TAG_SPI "SPI"
|
||||
|
||||
/* external defines */
|
||||
#undef VPROC_DEBUG
|
||||
|
||||
/*create a 16-bit word out of two bytes*/
|
||||
#define MAKE16(a, b) \
|
||||
(unsigned short)(((unsigned short)(b) << 8) | (unsigned short)(a))
|
||||
/*create a 32-bit word out of 4 bytes*/
|
||||
|
||||
#define MAKE32(a, b, c, d) \
|
||||
(unsigned long)(((unsigned long)d << 24) | ((unsigned long)c << 16) | \
|
||||
((unsigned long)b << 8) | ((unsigned long)a))
|
||||
/*
|
||||
* debug - print the function name and line number for the source of the error
|
||||
* the line number count start at 1 and not 0
|
||||
*/
|
||||
|
||||
/*
|
||||
*Define this macro to report mode debug info
|
||||
*/
|
||||
#undef VPROC_API_DBG_INFO
|
||||
#ifdef VPROC_API_DBG_INFO
|
||||
#define VPROG_DBG_INFO(s, args...) printf(""s, ##args);
|
||||
#else
|
||||
#define VPROG_DBG_INFO(s, args...)
|
||||
#endif
|
||||
|
||||
#define VPROC_API_DBG_ERROR
|
||||
#ifdef VPROC_API_DBG_ERROR
|
||||
#define VPROG_DBG_ERROR(s, args...) \
|
||||
printf("---%s %d: "s, __func__, __LINE__, ##args);
|
||||
#else
|
||||
#define VPROG_DBG_ERROR(s, args...)
|
||||
#endif
|
||||
|
||||
/*unsigned char deviceType;*/
|
||||
/*device/access Status codes*/
|
||||
typedef enum VprocStatusType {
|
||||
VPROC_STATUS_SUCCESS = 0,
|
||||
VPROC_STATUS_FAILURE,
|
||||
VPROC_STATUS_INIT_FAILED,
|
||||
VPROC_STATUS_WR_FAILED,
|
||||
VPROC_STATUS_RD_FAILED,
|
||||
VPROC_STATUS_FW_LOAD_FAILED,
|
||||
VPROC_STATUS_CFG_LOAD_FAILED,
|
||||
VPROC_STATUS_CLOSE_FAILED,
|
||||
VPROC_STATUS_FW_SAVE_FAILED,
|
||||
VPROC_STATUS_GFG_SAVE_FAILED,
|
||||
VPROC_STATUS_MAU_NOT_READY,
|
||||
VPROC_STATUS_CHK_FAILED,
|
||||
VPROC_STATUS_FUNC_NOT_SUPPORTED,
|
||||
VPROC_STATUS_INVALID_ARG,
|
||||
VPROC_STATUS_ERR_VTD_CODE,
|
||||
VPROC_STATUS_ERR_VERIFY,
|
||||
VPROC_STATUS_DEVICE_BUSY,
|
||||
VPROC_STATUS_ERR_HBI,
|
||||
VPROC_STATUS_ERR_IMAGE,
|
||||
VPROC_STATUS_MAILBOX_BUSY,
|
||||
VPROC_STATUS_CMDREG_BUSY,
|
||||
VPROC_STATUS_IN_CRTCL_SECTN,
|
||||
VPROC_STATUS_BOOT_LOADING_MORE_DATA,
|
||||
VPROC_STATUS_BOOT_LOADING_CMP,
|
||||
VPROC_STATUS_DEV_NOT_INITIALIZED,
|
||||
|
||||
} VprocStatusType;
|
||||
|
||||
/* Device Reset modes*/
|
||||
typedef enum VprocResetMode {
|
||||
VPROC_RST_HARDWARE_ROM =
|
||||
0, /*hardware reset -reset the device and reload the firmware from flash*/
|
||||
VPROC_RST_HARDWARE_RAM =
|
||||
1, /*hardware reset -reset the device and reload the firmware from RAM*/
|
||||
VPROC_RST_SOFTWARE = 2,
|
||||
VPROC_RST_AEC = 3, /*software reset -reset and runs the firmware from RAM*/
|
||||
VPROC_RST_BOOT = 4
|
||||
} VprocResetMode;
|
||||
|
||||
typedef enum vProcDeviceType {
|
||||
VPROC_DEV_GALILEO = 1, /*Galileo devices: ZL38004, ZL38012, ZL38005*/
|
||||
VPROC_DEV_TIMBERWOLF = 2 /*Timberwolf: ZL38040*/
|
||||
} VprocDeviceType;
|
||||
|
||||
extern void VprocHALcleanup(void);
|
||||
extern int VprocHALInit(void);
|
||||
extern void Vproc_msDelay(unsigned short time);
|
||||
extern void VprocWait(unsigned long int time);
|
||||
extern int VprocHALWrite(unsigned short val);
|
||||
extern int VprocHALRead(unsigned short* pVal);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VPROC_COMMON_H */
|
||||
124
components/audio_hal/driver/zl38063/api_lib/vproc_data_types.h
Normal file
124
components/audio_hal/driver/zl38063/api_lib/vproc_data_types.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/** \file vproc_data_types.h
|
||||
* vproc_data_types.h
|
||||
*
|
||||
* This file is the header for all standard types used in the API code.
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef VP_API_TYPES_H
|
||||
#define VP_API_TYPES_H
|
||||
/* For maximum that can be stored in an int - if file exists in library */
|
||||
#include "esp_types.h"
|
||||
#include "limits.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL (0)
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
#undef EXTERN
|
||||
#error EXTERN was redefined!
|
||||
#endif /* undef EXTERN */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/********************* DECLARATIONS ***************************/
|
||||
/* Constants */
|
||||
#define FALSE (0) /* Boolean constant */
|
||||
#define TRUE (1) /* Boolean constant */
|
||||
#ifndef __cplusplus
|
||||
/* C++ language provides a boolean data type; So no need to define
|
||||
* one more data type; Make use of it
|
||||
* NOTE: The 'C' potions of the VP-API assume C++ "bool" to be of the
|
||||
* same size as that of "char". Please make sure this assumption is correct.
|
||||
*/
|
||||
|
||||
// typedef unsigned char bool;
|
||||
#endif /* __cplusplus */
|
||||
/****************** typedefs ***********************************/
|
||||
/* These are the basic number types used */
|
||||
/* for uint8, uint16, uint32, int8, int16, int32, bool */
|
||||
// PLATFORM SPECIFIC DEFINITIONS
|
||||
typedef unsigned char uchar;
|
||||
typedef signed char int8;
|
||||
typedef unsigned char UCharT; // 8 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef unsigned char UInt8T; // 8 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef unsigned short UInt16T; // 16 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef unsigned long UInt32T; // 32 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef signed long Int32T; // 32 bits signed - PLATFORM SPECIFIC
|
||||
typedef unsigned char uint8; // 8 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef unsigned short uint16; // 16 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef uint8* uint8p; // pointer to 8 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef uint16* uint16p; // pointer to 16 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef uint32_t uint32; // 32 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef signed short int16; // 32 bits unsigned - PLATFORM SPECIFIC
|
||||
typedef uint32* uint32p;
|
||||
typedef int8* int8p;
|
||||
typedef int16* int16p;
|
||||
typedef Int32T* int32p;
|
||||
|
||||
/* external types */
|
||||
/* Some compilers optimize the size of enumeration data types based on
|
||||
* the maximum data value assigned to the members of that data type.
|
||||
* 'Standard C' requires enumeration data types to be of the same size
|
||||
* as that of native 'int' implementation.
|
||||
* The VP-API from a portability persepective adds a 'dummy' member to
|
||||
* all enumeration data types that force the compilers to allocate the size
|
||||
* of enumeration data types to be equal to that of native 'int'
|
||||
* implementation */
|
||||
#define FORCE_STANDARD_C_ENUM_SIZE (INT_MAX)
|
||||
|
||||
/* Eliminate error messages that occur when comparing an enumeration constant
|
||||
< 0 */
|
||||
#define FORCE_SIGNED_ENUM (INT_MIN)
|
||||
|
||||
/* Define any API specific basic data type ranges (that are necessary) */
|
||||
#define VP_INT16_MAX (SHRT_MAX)
|
||||
#define VP_INT16_MIN (SHRT_MIN)
|
||||
#define VP_INT32_MAX (LONG_MAX)
|
||||
#define VP_INT32_MIN (LONG_MIN)
|
||||
|
||||
/*firmware data structures*/
|
||||
typedef struct {
|
||||
uint16 buf[16]; /*the firmware data block to send to the device*/
|
||||
uint16
|
||||
numWords; /*the number of words within the block of data stored in buf[]*/
|
||||
uint32 targetAddr; /*the target base address to write to register 0x00c of the
|
||||
device*/
|
||||
uint8 useTargetAddr; /*this value is either 0 or 1. When 1 the tarGetAddr must
|
||||
be written to the device*/
|
||||
} twFwr;
|
||||
|
||||
typedef struct {
|
||||
twFwr* st_Fwr;
|
||||
uint32 byteCount; /*The total number of bytes within the firmware - NOT USED*/
|
||||
uint8 havePrgmBase;
|
||||
uint32 prgmBase;
|
||||
uint32 execAddr; /*The execution start address of the firmware in RAM*/
|
||||
uint16 twFirmwareStreamLen; /*The number of blocks within the firmware*/
|
||||
} twFirmware;
|
||||
|
||||
/*config record structures*/
|
||||
typedef struct {
|
||||
uint16 reg; /*the register */
|
||||
uint16 value; /*the value to write into reg */
|
||||
} dataArr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VP_API_TYPES_H */
|
||||
307
components/audio_hal/driver/zl38063/example_apps/tw_hal_verify.c
Normal file
307
components/audio_hal/driver/zl38063/example_apps/tw_hal_verify.c
Normal file
@@ -0,0 +1,307 @@
|
||||
/****************************************************************************
|
||||
* tw_hal_verify.c - Read/write registers of the device and verify whether the
|
||||
* device is accessed properly
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* malloc, free, rand */
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "vprocTwolf_access.h"
|
||||
#include "vproc_common.h"
|
||||
#include "zl38063_config.h"
|
||||
#include "zl38063_firmware.h"
|
||||
|
||||
/*NOTE: notice that the *.c code are included in the apps-
|
||||
* This is because the compiler I'm using requires that
|
||||
* But if your makefile is such that compiler knows where to find these files
|
||||
* then remove the #include *.c below
|
||||
*/
|
||||
|
||||
#undef SAVE_IMAGE_TO_FLASH /*define this macro to save the firmware from RAM \
|
||||
to flash*/
|
||||
#undef SAVE_CFG_TO_FLASH /*define this macro to save the cfg from RAM to \
|
||||
flash*/
|
||||
/*quick test*/
|
||||
|
||||
#define TW_HAL_VERIFY_DEBUG
|
||||
|
||||
#define MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST 125
|
||||
|
||||
static const char* TAG = "TW_HAL_VERIFY";
|
||||
|
||||
/*LoadFwrConfig_Alt - to load a converted *s3, *cr2 to c code into the device.
|
||||
* Basically instead of loading the *.s3, *cr2 directly,
|
||||
* use the tw_convert tool to convert the ascii hex fwr mage into code and
|
||||
* compile with the application
|
||||
*
|
||||
* input arg: mode: 0 - load both firmware and confing
|
||||
* 1 - load firmware only
|
||||
* 2 - load config only
|
||||
*/
|
||||
VprocStatusType LoadFwrConfig_Alt(uint8 mode) {
|
||||
VprocStatusType status = VPROC_STATUS_SUCCESS;
|
||||
if ((mode == 0) || (mode == 1)) {
|
||||
twFirmware st_Firmware;
|
||||
st_Firmware.st_Fwr = (twFwr*)st_twFirmware;
|
||||
st_Firmware.twFirmwareStreamLen = (uint16)firmwareStreamLen;
|
||||
st_Firmware.execAddr = (uint32)executionAddress;
|
||||
st_Firmware.havePrgmBase = (uint8)haveProgramBaseAddress;
|
||||
st_Firmware.prgmBase = (uint32)programBaseAddress;
|
||||
ESP_LOGD(TAG, "Firmware boot loading started ....");
|
||||
status = VprocTwolfHbiBoot_alt(&st_Firmware);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiBoot()", status);
|
||||
return -1;
|
||||
}
|
||||
ESP_LOGD(TAG, "Loading the image to RAM....done");
|
||||
#ifdef SAVE_IMAGE_TO_FLASH
|
||||
ESP_LOGD(TAG, "Saving firmware to flash....");
|
||||
status = VprocTwolfSaveImgToFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfSaveImgToFlash()", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
ESP_LOGD(TAG, "Saving firmware to flash....done");
|
||||
|
||||
#endif
|
||||
|
||||
status = VprocTwolfFirmwareStart();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfFirmwareStart()", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
if ((mode == 0) || (mode == 2)) {
|
||||
ESP_LOGD(TAG, "Loading the config file into the device RAM....");
|
||||
|
||||
status =
|
||||
VprocTwolfLoadConfig((dataArr*)st_twConfig, (uint16)configStreamLen);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfLoadConfig()", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
#ifdef SAVE_CFG_TO_FLASH
|
||||
ESP_LOGD(TAG, "Saving config to flash....");
|
||||
status = VprocTwolfSaveCfgToFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfSaveCfgToFlash()", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
ESP_LOGD(TAG, "Saving config to flash....done");
|
||||
|
||||
#endif
|
||||
}
|
||||
{ /*Verify that the boot loading PASS or Fail*/
|
||||
uint16 val = 0;
|
||||
|
||||
status = VprocTwolfHbiRead(0x0022, 1, &val);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiRead()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
if ((val == 38040) || (val == 38050) || (val == 38060) || (val == 38080) ||
|
||||
(val == 38051) || (val == 38041)) {
|
||||
ESP_LOGD(TAG, "Device boot loading completed successfully...");
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Device boot loading failed!!!...");
|
||||
return VPROC_STATUS_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*Firmware reset - in order for the configuration to take effect
|
||||
* NOTE: The ZL38040 needs a soft reset for the uploaded configuration
|
||||
* to take effect. This soft-reset is sent below
|
||||
* if the ZL38040 is an I2S slave, if the I2S master is not stable
|
||||
* at the time of this reset, then that reset will not take effect.
|
||||
* In that case the host has to to simply resend the reset
|
||||
* command once the I2S master
|
||||
* is up and running and is at a stable state.
|
||||
*/
|
||||
status = VprocTwolfReset(VPROC_RST_SOFTWARE);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfReset()", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Device boot loading completed successfully...");
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_zl38063(void* arg) {
|
||||
int status = 0;
|
||||
uint16 cmdword = 0;
|
||||
uint16 val[MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST];
|
||||
uint8 numwords = 0;
|
||||
uint16 tempbuf[MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST];
|
||||
uint16 i = 0;
|
||||
#ifdef TW_HAL_VERIFY_DEBUG
|
||||
uint16 j = 0;
|
||||
#endif
|
||||
status = VprocTwolfHbiInit();
|
||||
if (status < 0) {
|
||||
perror("tw_spi_access open");
|
||||
return -1;
|
||||
}
|
||||
if ((MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST > 125) ||
|
||||
(MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST < 2)) {
|
||||
ESP_LOGD(TAG, "MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST must between 2 and 126");
|
||||
}
|
||||
memset(val, 0, sizeof(val));
|
||||
memset(tempbuf, 0, sizeof(tempbuf));
|
||||
|
||||
ESP_LOGD(TAG,
|
||||
"Test 1 - Verifying that the device is present and working ....");
|
||||
cmdword = 0x00C;
|
||||
numwords = 2;
|
||||
val[0] = 0x1234;
|
||||
val[1] = 0x5678;
|
||||
status = VprocTwolfHbiWrite(cmdword, numwords, val);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiWrite()\n", status);
|
||||
VprocHALcleanup();
|
||||
return -1;
|
||||
}
|
||||
#ifdef TW_HAL_VERIFY_DEBUG
|
||||
j = 0;
|
||||
for (i = 0; i < numwords; i++) {
|
||||
ESP_LOGD(TAG, "wr: addr 0x%04x = 0x%04x", (cmdword + j), val[i]);
|
||||
j = j + 2;
|
||||
}
|
||||
#endif
|
||||
status = VprocTwolfHbiRead(cmdword, numwords, tempbuf);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiRead()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
#ifdef TW_HAL_VERIFY_DEBUG
|
||||
j = 0;
|
||||
for (i = 0; i < numwords; i++) {
|
||||
ESP_LOGD(TAG, "RD: addr 0x%04x = 0x%04x", (cmdword + j), tempbuf[i]);
|
||||
j = j + 2;
|
||||
}
|
||||
#endif
|
||||
if ((tempbuf[0] != 0x1234) && (tempbuf[1] != 0x5600)) {
|
||||
ESP_LOGD(TAG, "Test 1 - completed - FAIL!!!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Test 1 - completed - PASS\n\n");
|
||||
|
||||
status = VprocTwolfReset(0);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiRead()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
ESP_LOGD(TAG, "Device reset completed successfully...");
|
||||
|
||||
ESP_LOGD(TAG, "Test 2 - Verifying single word write/read access ....");
|
||||
cmdword = 0x0300;
|
||||
val[0] = 0x4008;
|
||||
numwords = 1;
|
||||
status = VprocTwolfHbiWrite(cmdword, numwords, val);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiWrite()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
#ifdef TW_HAL_VERIFY_DEBUG
|
||||
j = 0;
|
||||
for (i = 0; i < numwords; i++) {
|
||||
ESP_LOGD(TAG, "wr: addr 0x%04x = 0x%04x", (cmdword + j), val[i]);
|
||||
j = j + 2;
|
||||
}
|
||||
#endif
|
||||
status = VprocTwolfHbiRead(cmdword, numwords, val);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiRead()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
#ifdef TW_HAL_VERIFY_DEBUG
|
||||
j = 0;
|
||||
for (i = 0; i < numwords; i++) {
|
||||
ESP_LOGD(TAG, "RD: addr 0x%04x = 0x%04x\n", (cmdword + j), val[i]);
|
||||
j = j + 2;
|
||||
}
|
||||
#endif
|
||||
if ((val[0] != 0x4008)) {
|
||||
ESP_LOGD(TAG, "Test 2 - completed - FAIL!!!");
|
||||
return -1;
|
||||
}
|
||||
ESP_LOGD(TAG, "Test 2 - completed - PASS");
|
||||
|
||||
ESP_LOGD(TAG, "Test 3 - Verifying multiple words write/read access ....");
|
||||
|
||||
/* Fill the data buffer with unique data values. */
|
||||
for (i = 0; i < MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST; i++) {
|
||||
val[i] = i | ((0xFF - i) << 8);
|
||||
}
|
||||
|
||||
cmdword = 0x0300;
|
||||
numwords = MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST;
|
||||
status = VprocTwolfHbiWrite(cmdword, numwords, val);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiWrite()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
#ifdef TW_HAL_VERIFY_DEBUG
|
||||
j = 0;
|
||||
for (i = 0; i < numwords; i++) {
|
||||
ESP_LOGD(TAG, "twr: addr 0x%04x = 0x%04x", (cmdword + j), val[i]);
|
||||
j = j + 2;
|
||||
}
|
||||
#endif
|
||||
status = VprocTwolfHbiRead(cmdword, numwords, tempbuf);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiRead()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
#ifdef TW_HAL_VERIFY_DEBUG
|
||||
j = 0;
|
||||
for (i = 0; i < numwords; i++) {
|
||||
ESP_LOGD(TAG, "RD: addr 0x%04x = 0x%04x =? 0x%04x", (cmdword + j),
|
||||
tempbuf[i], val[i]);
|
||||
j = j + 2;
|
||||
}
|
||||
#endif
|
||||
j = 0;
|
||||
for (i = 0; i < MAX_WORDS_FOR_MULTIWORD_ACCESS_TEST; i++) {
|
||||
if (tempbuf[i] != val[i]) {
|
||||
ESP_LOGD(TAG, "RD: addr 0x%04x = 0x%04x =? 0x%04x", (cmdword + j),
|
||||
tempbuf[i], val[i]);
|
||||
ESP_LOGD(TAG, "Test 3 - completed - FAIL!!!");
|
||||
return -1;
|
||||
}
|
||||
j = j + 2;
|
||||
}
|
||||
ESP_LOGD(TAG, "Test 3 - completed - PASS");
|
||||
|
||||
ESP_LOGD(TAG, "Test 4 - Verifying the firmware/config boot loading ....");
|
||||
if (LoadFwrConfig_Alt(0) != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Device boot loading failed.....");
|
||||
ESP_LOGD(TAG, "Test 4 - completed - FAIL!!!");
|
||||
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Test 4 - completed - PASS");
|
||||
}
|
||||
VprocTwolfHbiCleanup();
|
||||
return 0;
|
||||
}
|
||||
161
components/audio_hal/driver/zl38063/example_apps/tw_ldcfg.c
Normal file
161
components/audio_hal/driver/zl38063/example_apps/tw_ldcfg.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/****************************************************************************
|
||||
* tw_ldfwcfg.c - To load a *.s3 firmware and/or a *.cr2 into the device
|
||||
* and optionally save the loaded image to flash
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* malloc, free, rand */
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "vprocTwolf_access.h"
|
||||
#include "vproc_common.h"
|
||||
|
||||
/*NOTE: notice that the *.c code are included in the apps-
|
||||
* This is because the compiler I'm using requires that
|
||||
* But if your makefile is such that compiler knows where to find these files
|
||||
* then remove the #include *.c below
|
||||
*/
|
||||
|
||||
#undef SAVE_CFG_TO_FLASH /*define this macro to save the cfg from RAM to \
|
||||
flash*/
|
||||
static const char* TAG = "TW_LDCFG";
|
||||
uint16 numElements;
|
||||
dataArr* pCr2Buf;
|
||||
|
||||
/* fseekNunlines() -- The firmware file is an ascii text file.
|
||||
* the information from fseek will not be useful.
|
||||
* this is our own fseek equivalent
|
||||
*/
|
||||
static unsigned long fseekNunlines(FILE* BOOT_FD) {
|
||||
uint32 line_count = 0;
|
||||
int c;
|
||||
|
||||
while ((c = fgetc(BOOT_FD)) != EOF) {
|
||||
if (c == '\n') line_count++;
|
||||
}
|
||||
return line_count;
|
||||
}
|
||||
|
||||
/* readCfgFile() use this function to
|
||||
* Read the Voice processing cr2 config file into RAM
|
||||
* filepath -- pointer to the location where to find the file
|
||||
* pCr2Buf -- the actual firmware data array will be pointed to this buffer
|
||||
*/
|
||||
static int readCfgFile(char* filepath) {
|
||||
unsigned int reg[2], val[2], len;
|
||||
uint8 done = 0;
|
||||
uint16 index = 0;
|
||||
FILE* BOOT_FD;
|
||||
char* s;
|
||||
char line[512] = "";
|
||||
|
||||
BOOT_FD = fopen(filepath, "rb");
|
||||
if (BOOT_FD != NULL) {
|
||||
len = fseekNunlines(BOOT_FD);
|
||||
if (len <= 0) {
|
||||
ESP_LOGD(TAG, "Error: file is not of the correct format...");
|
||||
return -1;
|
||||
}
|
||||
ESP_LOGD(TAG, "fileLength = %u", len);
|
||||
/*start at the beginning of the file*/
|
||||
// fseek(BOOT_FD, 0, SEEK_SET);
|
||||
|
||||
/* allocate memory to contain the reg and val:*/
|
||||
pCr2Buf = (dataArr*)malloc(len * sizeof(dataArr));
|
||||
if (pCr2Buf == NULL) {
|
||||
ESP_LOGD(TAG, "not enough memory to allocate %u bytes.. ",
|
||||
len * sizeof(dataArr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rewind(BOOT_FD);
|
||||
/*read and format the data accordingly*/
|
||||
numElements = 0;
|
||||
do {
|
||||
s = fgets(line, 512, BOOT_FD);
|
||||
if (line[0] == ';') {
|
||||
continue;
|
||||
} else if (s != NULL) {
|
||||
numElements++;
|
||||
sscanf(line, "%x %c %x", reg, s, val);
|
||||
pCr2Buf[index].reg = reg[0];
|
||||
pCr2Buf[index].value = val[0];
|
||||
// ESP_LOGD(TAG,"pCr2Buf[%d].reg pCr2Buf[%d].value = 0x%04x\t0x%04x\n",
|
||||
// index, index, pCr2Buf[index].reg, pCr2Buf[index].value);
|
||||
index++;
|
||||
} else {
|
||||
done = 1;
|
||||
}
|
||||
|
||||
} while (done == 0);
|
||||
|
||||
fclose(BOOT_FD);
|
||||
ESP_LOGD(TAG, "size of pCr2Buf = %u bytes.. ", sizeof(pCr2Buf));
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Error: can't open file");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*This example host app load the *.s3 firmware to the device RAM. Optionally
|
||||
* save it to flash Then start the firmware from the execution address in RAM It
|
||||
* then stops the firmware - Load the cr2 file into RAM. Optionally save it to
|
||||
* flash Then restarts the firmware
|
||||
*/
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
VprocStatusType status = VPROC_STATUS_SUCCESS;
|
||||
|
||||
if (argc != 2) {
|
||||
ESP_LOGD(TAG, "Error: argc = %d - missing %d arg(s)... ", argc,
|
||||
3 - (argc - 1));
|
||||
ESP_LOGD(TAG, "command Usage:%s ConfigPath", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
ESP_LOGD(TAG, ":%s %s %s", argv[0], argv[1], argv[2]);
|
||||
|
||||
/*global file handle*/
|
||||
status = VprocTwolfHbiInit();
|
||||
|
||||
if (status < 0) {
|
||||
perror("tw_spi_access open");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (readCfgFile(argv[1]) < 0) {
|
||||
ESP_LOGD(TAG, "Error:read %s file", argv[1]);
|
||||
}
|
||||
ESP_LOGD(TAG, "a- Reading config file to host RAM - done....");
|
||||
|
||||
ESP_LOGD(TAG, "c- Loading the config file into the device RAM");
|
||||
status = VprocTwolfLoadConfig(pCr2Buf, numElements);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfLoadConfig()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SAVE_CONFIG_TO_FLASH
|
||||
status = VprocTwolfSaveCfgToFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfSaveCfgToFlash()", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
ESP_LOGD(TAG, "d- Saving config to flash- done....");
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "e- Loading config record - done....");
|
||||
free(pCr2Buf);
|
||||
pCr2Buf = NULL;
|
||||
VprocTwolfHbiCleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
118
components/audio_hal/driver/zl38063/example_apps/tw_ldfw.c
Normal file
118
components/audio_hal/driver/zl38063/example_apps/tw_ldfw.c
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
/****************************************************************************
|
||||
* tw_ldfw.c - To load a *.s3 firmware into the device
|
||||
* and optionally save the loaded image to flash
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "vprocTwolf_access.h"
|
||||
#include "vproc_common.h"
|
||||
|
||||
/*NOTE: notice that the *.c code are included in the apps-
|
||||
* This is because the compiler I'm using requires that
|
||||
* But if your makefile is such that compiler knows where to find these files
|
||||
* then remove the #include *.c below
|
||||
*/
|
||||
|
||||
// #undef SAVE_IMAGE_TO_FLASH /*define this macro to save the firmware from RAM
|
||||
// to flash*/
|
||||
static const char* TAG = "TW_LDFW";
|
||||
/*quick test*/
|
||||
|
||||
/*This example host app load the *.s3 firmware to the device RAM. Optionally
|
||||
* save it to flash Then start the firmware from the execution address in RAM
|
||||
*/
|
||||
int main(int argc, char** argv) {
|
||||
VprocStatusType status = VPROC_STATUS_SUCCESS;
|
||||
FILE* BOOT_FD;
|
||||
char line[256] = "";
|
||||
|
||||
if (argc != 2) {
|
||||
ESP_LOGD(TAG, "Error: argc = %d - missing %d arg(s)... ", argc,
|
||||
3 - (argc - 1));
|
||||
ESP_LOGD(TAG, "command Usage:%s firmwarePath", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
ESP_LOGD(TAG, ":%s %s %s", argv[0], argv[1], argv[2]);
|
||||
|
||||
BOOT_FD = fopen(argv[1], "rb");
|
||||
if (BOOT_FD == NULL) {
|
||||
ESP_LOGD(TAG, "Error: can't open file %s", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*global file handle*/
|
||||
status = VprocTwolfHbiInit();
|
||||
if (status < 0) {
|
||||
perror("tw_spi_access open");
|
||||
fclose(BOOT_FD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "1- Opening firmware file - done....");
|
||||
|
||||
status = VprocTwolfHbiBootPrepare();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiBootPrepare()", status);
|
||||
fclose(BOOT_FD);
|
||||
VprocHALcleanup();
|
||||
return -1;
|
||||
}
|
||||
ESP_LOGD(TAG, "-- Boot prepare - done....");
|
||||
|
||||
while (fgets(line, 256, BOOT_FD) != NULL) {
|
||||
status = VprocTwolfHbiBootMoreData(line);
|
||||
if (status == VPROC_STATUS_BOOT_LOADING_MORE_DATA) {
|
||||
continue;
|
||||
} else if (status == VPROC_STATUS_BOOT_LOADING_CMP) {
|
||||
break;
|
||||
} else if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiBootMoreData()", status);
|
||||
fclose(BOOT_FD);
|
||||
VprocHALcleanup();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ESP_LOGD(TAG, "-- Firmware data transfer - done....");
|
||||
fclose(BOOT_FD);
|
||||
/*clean up and verify that the boodloading completed correctly*/
|
||||
status = VprocTwolfHbiBootConclude();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfHbiBootConclude()", status);
|
||||
VprocHALcleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "2- Loading firmware - done....");
|
||||
#ifdef SAVE_IMAGE_TO_FLASH
|
||||
ESP_LOGD(TAG, "-- Saving firmware to flash....");
|
||||
status = VprocTwolfSaveImgToFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfSaveImgToFlash()", status);
|
||||
VprocHALcleanup();
|
||||
return -1;
|
||||
}
|
||||
ESP_LOGD(TAG, "-- Saving firmware to flash....done");
|
||||
|
||||
#endif
|
||||
|
||||
status = VprocTwolfFirmwareStart();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
ESP_LOGD(TAG, "Error %d:VprocTwolfFirmwareStart()", status);
|
||||
VprocHALcleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Device boot loading completed successfully...");
|
||||
|
||||
VprocHALcleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
222
components/audio_hal/driver/zl38063/example_apps/tw_ldfwcfg.c
Normal file
222
components/audio_hal/driver/zl38063/example_apps/tw_ldfwcfg.c
Normal file
@@ -0,0 +1,222 @@
|
||||
/****************************************************************************
|
||||
* tw_ldfwcfg.c - To load a *.s3 firmware and/or a *.cr2 into the device
|
||||
* and optionally save the loaded image to flash
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* malloc, free, rand */
|
||||
|
||||
#include "vprocTwolf_access.h"
|
||||
#include "vproc_common.h"
|
||||
|
||||
/*NOTE: notice that the *.c code are included in the apps-
|
||||
* This is because the compiler I'm using requires that
|
||||
* But if your makefile is such that compiler knows where to find these files
|
||||
* then remove the #include *.c below
|
||||
*/
|
||||
|
||||
#undef SAVE_IMAGE_TO_FLASH /*define this macro to save the firmware from RAM \
|
||||
to flash*/
|
||||
#undef SAVE_CFG_TO_FLASH /*define this macro to save the cfg from RAM to \
|
||||
flash*/
|
||||
/*quick test*/
|
||||
|
||||
uint16 numElements;
|
||||
|
||||
dataArr* pCr2Buf;
|
||||
/* fseekNunlines() -- The firmware file is an ascii text file.
|
||||
* the information from fseek will not be useful.
|
||||
* this is our own fseek equivalent.
|
||||
*/
|
||||
static unsigned long fseekNunlines(FILE* BOOT_FD) {
|
||||
uint32 line_count = 0;
|
||||
int c;
|
||||
|
||||
while ((c = fgetc(BOOT_FD)) != EOF) {
|
||||
if (c == '\n') line_count++;
|
||||
}
|
||||
return line_count;
|
||||
}
|
||||
|
||||
/* readCfgFile() use this function to
|
||||
* Read the Voice processing cr2 config file into RAM
|
||||
* filepath -- pointer to the location where to find the file
|
||||
* pCr2Buf -- the actual firmware data array will be pointed to this buffer
|
||||
*/
|
||||
static int readCfgFile(char* filepath) {
|
||||
unsigned int reg[2], val[2], len;
|
||||
uint8 done = 0;
|
||||
uint16 index = 0;
|
||||
FILE* BOOT_FD;
|
||||
char* s;
|
||||
char line[512] = "";
|
||||
|
||||
BOOT_FD = fopen(filepath, "rb");
|
||||
if (BOOT_FD != NULL) {
|
||||
len = fseekNunlines(BOOT_FD);
|
||||
if (len <= 0) {
|
||||
printf("Error: file is not of the correct format...\n");
|
||||
return -1;
|
||||
}
|
||||
// printf("fileLength = %u\n", len);
|
||||
/*start at the beginning of the file*/
|
||||
// fseek(BOOT_FD, 0, SEEK_SET);
|
||||
|
||||
/* allocate memory to contain the reg and val:*/
|
||||
pCr2Buf = (dataArr*)malloc(len * sizeof(dataArr));
|
||||
if (pCr2Buf == NULL) {
|
||||
printf("not enough memory to allocate %u bytes.. ",
|
||||
len * sizeof(dataArr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rewind(BOOT_FD);
|
||||
/*read and format the data accordingly*/
|
||||
numElements = 0;
|
||||
do {
|
||||
s = fgets(line, 512, BOOT_FD);
|
||||
if (line[0] == ';') {
|
||||
continue;
|
||||
} else if (s != NULL) {
|
||||
numElements++;
|
||||
sscanf(line, "%x %c %x", reg, s, val);
|
||||
pCr2Buf[index].reg = reg[0];
|
||||
pCr2Buf[index].value = val[0];
|
||||
// printf("pCr2Buf[%d].reg pCr2Buf[%d].value = 0x%04x\t0x%04x\n",
|
||||
// index, index, pCr2Buf[index].reg, pCr2Buf[index].value);
|
||||
index++;
|
||||
} else {
|
||||
done = 1;
|
||||
}
|
||||
|
||||
} while (done == 0);
|
||||
|
||||
fclose(BOOT_FD);
|
||||
// printf ("size of pCr2Buf = %u bytes.. \n", len*sizeof(pCr2Buf));
|
||||
} else {
|
||||
printf("Error: can't open file\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*This example host app load the *.s3 firmware to the device RAM. Optionally
|
||||
* save it to flash Then start the firmware from the execution address in RAM It
|
||||
* then stops the firmware - Load the cr2 file into RAM. Optionally save it to
|
||||
* flash Then resstarts the firmware
|
||||
*/
|
||||
int main(int argc, char** argv) {
|
||||
VprocStatusType status = VPROC_STATUS_SUCCESS;
|
||||
FILE* BOOT_FD;
|
||||
char line[256] = "";
|
||||
|
||||
if (argc < 3) {
|
||||
printf("Error: argc = %d - missing %d arg(s)... \n", argc, 3 - (argc - 1));
|
||||
printf("command Usage:%s firmwarePath ConfigPath\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
printf(":%s %s %s\n", argv[0], argv[1], argv[2]);
|
||||
|
||||
BOOT_FD = fopen(argv[1], "rb");
|
||||
if (BOOT_FD == NULL) {
|
||||
printf("Error: can't open file %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
/*global file handle*/
|
||||
status = VprocTwolfHbiInit();
|
||||
// gTwolf_fd = open(file_name, O_RDWR);
|
||||
if (status < 0) {
|
||||
perror("tw_spi_access open");
|
||||
fclose(BOOT_FD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("1- Opening firmware file - done....\n");
|
||||
|
||||
status = VprocTwolfHbiBootPrepare();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfHbiBootPrepare()\n", status);
|
||||
fclose(BOOT_FD);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
printf("-- Boot prepare - done....\n");
|
||||
|
||||
while (fgets(line, 256, BOOT_FD) != NULL) {
|
||||
status = VprocTwolfHbiBootMoreData(line);
|
||||
if (status == VPROC_STATUS_BOOT_LOADING_MORE_DATA) {
|
||||
continue;
|
||||
} else if (status == VPROC_STATUS_BOOT_LOADING_CMP) {
|
||||
break;
|
||||
} else if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfHbiBootMoreData()\n", status);
|
||||
fclose(BOOT_FD);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
printf("-- Firmware data transfer - done....\n");
|
||||
fclose(BOOT_FD);
|
||||
|
||||
status = VprocTwolfHbiBootConclude();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfHbiBootConclude()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SAVE_IMAGE_TO_FLASH
|
||||
printf("-- Saving firmware to flash....\n");
|
||||
status = VprocTwolfSaveImgToFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfSaveImgToFlash()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
printf("-- Saving firmware to flash....done\n");
|
||||
|
||||
#endif
|
||||
|
||||
status = VprocTwolfFirmwareStart();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfFirmwareStart()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("3- Loading the config file into the device RAM\n");
|
||||
if (readCfgFile(argv[2]) < 0) {
|
||||
printf("Error:read %s file\n", argv[2]);
|
||||
}
|
||||
printf("a- Reading config file to host RAM - done....\n");
|
||||
|
||||
status = VprocTwolfLoadConfig(pCr2Buf, numElements);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfLoadConfig()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SAVE_CFG_TO_FLASH
|
||||
printf("-- Saving config to flash....\n");
|
||||
status = VprocTwolfSaveCfgToFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfSaveCfgToFlash()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
printf("-- Saving config to flash....done\n");
|
||||
|
||||
#endif
|
||||
printf("Device boot loading completed successfully...\n");
|
||||
|
||||
VprocTwolfHbiCleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
458
components/audio_hal/driver/zl38063/example_apps/tw_spi_access.c
Normal file
458
components/audio_hal/driver/zl38063/example_apps/tw_spi_access.c
Normal file
@@ -0,0 +1,458 @@
|
||||
/****************************************************************************
|
||||
* tw_spi_access.c - Demo apps demonstrating how to access registers of the
|
||||
* device over spi or I2C. Loading a firmware and or config into the device
|
||||
*
|
||||
*
|
||||
****************************************************************************
|
||||
* Copyright Microsemi Inc, 2018. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project
|
||||
* root for license information.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "vprocTwolf_access.h"
|
||||
#include "vproc_common.h"
|
||||
|
||||
/*NOTE: notice that the *.c code are included in the apps-
|
||||
* This is because the compiler I'm using requires that
|
||||
* But if your makefile is such that compiler knows where to find these files
|
||||
* then remove the #include *.c below
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "zl38063_config.h"
|
||||
#include "zl38063_firmware.h"
|
||||
|
||||
#undef SAVE_IMAGE_TO_FLASH /*define this macro to save the firmware from RAM \
|
||||
to flash*/
|
||||
#undef SAVE_CFG_TO_FLASH /*define this macro to save the cfg from RAM to \
|
||||
flash*/
|
||||
|
||||
#define SAVE_IMAGE_TO_FLASH
|
||||
#define SAVE_CFG_TO_FLASH
|
||||
/*quick test*/
|
||||
|
||||
/*LoadFwrConfig_Alt - to load a converted *s3, *cr2 to c code into the device.
|
||||
* Basically instead of loading the *.s3, *cr2 directly,
|
||||
* use the tw_convert tool to convert the ascii hex fwr mage into code and
|
||||
* compile with the application
|
||||
*
|
||||
* input arg: mode: 0 - load both firmware and confing
|
||||
* 1 - load firmware only
|
||||
* 2 - load config only
|
||||
* -1 - Force loading
|
||||
*/
|
||||
int tw_upload_dsp_firmware(int mode) {
|
||||
union {
|
||||
short a;
|
||||
char b;
|
||||
} test_bigendian;
|
||||
if (mode >= 0) {
|
||||
uint16 vol = 0;
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
int ret = VprocTwolfGetAppStatus(&vol);
|
||||
if (vol) {
|
||||
ESP_LOGW(TAG_SPI, "MCS ret:%d,Status:%d", ret, vol);
|
||||
return 0;
|
||||
}
|
||||
ESP_LOGI(TAG_SPI, "** Loading DSP firmware ret:%d,Status:%d **", ret, vol);
|
||||
} else {
|
||||
mode = 0;
|
||||
}
|
||||
test_bigendian.a = 1;
|
||||
ESP_LOGI(TAG_SPI, "b=%d", test_bigendian.b);
|
||||
|
||||
int status = VprocTwolfHbiInit();
|
||||
if (status < 0) {
|
||||
DEBUG_LOGE(TAG_SPI, "tw_spi_access open");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((mode == 0) || (mode == 1)) {
|
||||
twFirmware st_Firmware;
|
||||
st_Firmware.st_Fwr = (twFwr *)st_twFirmware;
|
||||
st_Firmware.twFirmwareStreamLen = (uint16)firmwareStreamLen;
|
||||
st_Firmware.execAddr = (uint32)executionAddress;
|
||||
st_Firmware.havePrgmBase = (uint8)haveProgramBaseAddress;
|
||||
st_Firmware.prgmBase = (uint32)programBaseAddress;
|
||||
|
||||
ESP_LOGI(TAG_SPI, "1- Firmware boot loading started ....");
|
||||
|
||||
status = VprocTwolfHbiBoot_alt(&st_Firmware);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
DEBUG_LOGE(TAG_SPI, "Error %d:VprocTwolfHbiBoot()", status);
|
||||
// VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG_SPI, "2- Loading the image to RAM....done");
|
||||
#ifdef SAVE_IMAGE_TO_FLASH
|
||||
ESP_LOGI(TAG_SPI, "-- Saving firmware to flash....");
|
||||
status = VprocTwolfSaveImgToFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
DEBUG_LOGE(TAG_SPI, "Error %d:VprocTwolfSaveImgToFlash()", status);
|
||||
// VprocTwolfHbiCleanup();
|
||||
return status;
|
||||
}
|
||||
ESP_LOGI(TAG_SPI, "-- Saving firmware to flash....done");
|
||||
|
||||
#endif
|
||||
status = VprocTwolfFirmwareStart();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
DEBUG_LOGE(TAG_SPI, "Error %d:VprocTwolfFirmwareStart()", status);
|
||||
// VprocTwolfHbiCleanup();
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
if ((mode == 0) || (mode == 2)) {
|
||||
ESP_LOGI(TAG_SPI, "3- Loading the config file into the device RAM....");
|
||||
|
||||
status =
|
||||
VprocTwolfLoadConfig((dataArr *)st_twConfig, (uint16)configStreamLen);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
DEBUG_LOGE(TAG_SPI, "Error %d:VprocTwolfLoadConfig()", status);
|
||||
// VprocTwolfHbiCleanup();
|
||||
return status;
|
||||
}
|
||||
#ifdef SAVE_CFG_TO_FLASH
|
||||
ESP_LOGI(TAG_SPI, "-- Saving config to flash....");
|
||||
status = VprocTwolfSaveCfgToFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
DEBUG_LOGE(TAG_SPI, "Error %d:VprocTwolfSaveCfgToFlash()", status);
|
||||
// VprocTwolfHbiCleanup();
|
||||
return status;
|
||||
}
|
||||
ESP_LOGI(TAG_SPI, "-- Saving config to flash....done");
|
||||
|
||||
#endif
|
||||
}
|
||||
/*Firmware reset - in order for the configuration to take effect*/
|
||||
status = VprocTwolfReset(VPROC_RST_SOFTWARE);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
DEBUG_LOGE(TAG_SPI, "Error %d:VprocTwolfReset()", status);
|
||||
ESP_LOGI(TAG_SPI, "Error");
|
||||
// VprocTwolfHbiCleanup();
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG_SPI, "Device boot loading completed successfully...");
|
||||
return status;
|
||||
}
|
||||
|
||||
int zl38063_comm(int argc, char **argv) {
|
||||
VprocStatusType status = VPROC_STATUS_SUCCESS;
|
||||
|
||||
if (argc == 1) {
|
||||
printf("Usage: for help type:%s -h", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "-h") == 0) {
|
||||
printf(
|
||||
"\nUsage:\n\t%s [-cmd mode] [options...] see supported"
|
||||
" command modes below\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\t-wr : to write one or more 16-bit words to the device\n"
|
||||
"\t-rd : to read one or more 16-bit words from the device\n"
|
||||
"\t-rst : to reset the device in one of these"
|
||||
" supported reset modes:\n"
|
||||
"\t\t - [0: RAM | 1: ROM | 2: SOFT | 3: AEC | 4: BOOT]\n");
|
||||
printf(
|
||||
"\t-lfcff : to load a specific firmware and related"
|
||||
" config from flash - arg: 1 to 14\n");
|
||||
printf(
|
||||
"\t-lfcfh-a : to load a pre-compiled firmware and related config"
|
||||
" from host via SPI\n");
|
||||
printf("\t-lffh-a: to load a pre-compiled firmware from host via SPI\n");
|
||||
printf("\t-lcfh-a: to load a pre-compiled config from host via SPI\n");
|
||||
printf("\t-fclr : to erase the content of the ZL380xx slave flash\n");
|
||||
printf("\t-sto : to reset the device into boot mode\n");
|
||||
printf(
|
||||
"\t-sta : to start execution of firmware found at "
|
||||
"exec address in RAM\n");
|
||||
printf(
|
||||
"\t-apla : to configure the ZL380xx x-point for "
|
||||
"audio playback mode\n");
|
||||
printf(
|
||||
"\t-arec : to configure the ZL380xx x-point for audio "
|
||||
"recording mode\n");
|
||||
printf("Example:\n");
|
||||
printf(
|
||||
"\tEx to write 0x8004 into register 0x0300:"
|
||||
"\n\t%s -wr 0x0300 0x8004\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to read 12 words starting from register 0x020:"
|
||||
"\n\t%s -rd 0x0020 12\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to reset the device in boot mode:"
|
||||
"\n\t%s -rst n 'where n:[1-4]\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to load to RAM a firmware and config previously"
|
||||
" saved to flash at index 1:\n\t%s -lfcff 1\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to load to RAM a firmware previously"
|
||||
" saved to flash at index 1:\n\t%s -lfff 1\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to load to RAM the pre-compiled (in)firmware "
|
||||
"from teh host "
|
||||
"HBI (SPI):\n\t%s -lffh-a\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to load to RAM the pre-compiled (in)config "
|
||||
"from teh host "
|
||||
"HBI (SPI):\n\t%s -lcfh-a\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to load to RAM the pre-compiled (in)firmware and config "
|
||||
"from teh host "
|
||||
"HBI (SPI):\n\t%s -lfcfh-a\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to stop the firmware currently running and clear "
|
||||
"the RAM:\n\t%s -sto\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to start a firmware previously loaded into "
|
||||
"RAM:\n\t%s -sta\n\n",
|
||||
argv[0]);
|
||||
printf("\tEx to mute SOUT :\n\t%s -mute_s [1 | 0]\n\n", argv[0]);
|
||||
printf("\tEx to mute ROUT :\n\t%s -mute_r [1 | 0]\n\n", argv[0]);
|
||||
printf(
|
||||
"\tEx to erase the slave flash device controlled by "
|
||||
"the ZL380xx :\n\t%s -fclr\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to configure the device for recording mode at a "
|
||||
"desired clock and sample rates"
|
||||
" with AEC off[0] or on [1]:\n\t%s -arec clkrate "
|
||||
"fsrate n 'where n:[0 | 1]'\n\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"\tEx to configure the device for playback mode at a "
|
||||
"desired clock and sample rates"
|
||||
" with AEC off[0] or on [1]:\n\t%s -apla clkrate "
|
||||
"fsrate n 'where n:[0 | 1]'\n\n",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((argc < 3) && (strcmp(argv[1], "-wr") == 0)) {
|
||||
printf("Usage:%s -wr register value0 value1....value124 \n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if ((argc < 3) && (strcmp(argv[1], "-rd") == 0)) {
|
||||
printf("Usage:%s -rd register n 'where n:[1-127]'\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if ((argc < 3) && (strcmp(argv[1], "-rst") == 0)) {
|
||||
printf("Usage:%s -rst n 'where n:[0-4]'\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if ((argc < 3) && (strcmp(argv[1], "-apla") == 0)) {
|
||||
printf(
|
||||
"Usage:%s -apla <clkrate in KHz> <fsrate in Hz> n"
|
||||
" 'where n:[0 | 1]'\n",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if ((argc < 3) && (strcmp(argv[1], "-arec") == 0)) {
|
||||
printf(
|
||||
"Usage:%s -arec <clkrate in KHz> <fsrate in Hz> n"
|
||||
" 'where n:[0 | 1]'\n",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if ((argc < 3) && (strcmp(argv[1], "-lfcff") == 0)) {
|
||||
printf("Usage:%s -lfcfh 1\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
/*global file handle*/
|
||||
status = VprocTwolfHbiInit();
|
||||
if (status < 0) {
|
||||
perror("tw_spi_access open");
|
||||
return -1;
|
||||
}
|
||||
if ((strcmp(argv[1], "-wr") == 0) || (strcmp(argv[1], "-rd") == 0)) {
|
||||
int i = 0, j = 0;
|
||||
unsigned short val[128];
|
||||
unsigned short cmdword = (unsigned short)strtoul(argv[2], NULL, 0);
|
||||
unsigned char numwords = 0;
|
||||
|
||||
memset(val, 0, sizeof(val));
|
||||
|
||||
if (strcmp(argv[1], "-wr") ==
|
||||
0) { /*for WRITING 1 or more ZL380xx registers*/
|
||||
|
||||
unsigned short val[128];
|
||||
numwords = argc - 3; /*calculate the number of words to write*/
|
||||
;
|
||||
for (i = 0; i < numwords; i++) {
|
||||
val[i] = (unsigned short)strtoul(argv[3 + i], NULL, 0);
|
||||
}
|
||||
status = VprocTwolfHbiWrite(cmdword, numwords, val);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfHbiWrite()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < numwords; i++) {
|
||||
printf("wr: addr 0x%04x = 0x%04x\n", (cmdword + j), val[i]);
|
||||
j = j + 2;
|
||||
}
|
||||
|
||||
} else { /*for READING 1 or more ZL380xx registers**/
|
||||
numwords = (unsigned char)strtoul(argv[3], NULL, 0);
|
||||
if ((numwords == 0) || (numwords > 128)) {
|
||||
printf("number of words is out of range. Maximum is 128\n");
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
status = VprocTwolfHbiRead(cmdword, numwords, val);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfHbiRead()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < numwords; i++) {
|
||||
printf("RD: addr 0x%04x = 0x%04x\n", (cmdword + j), val[i]);
|
||||
j = j + 2;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(argv[1], "-rst") == 0) { /*for RESETTING ZL380xx*/
|
||||
unsigned char rstMode = (unsigned char)strtoul(argv[2], NULL, 0);
|
||||
status = VprocTwolfReset((uint16)rstMode);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfHbiRead()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
printf("Device reset completed successfully...\n");
|
||||
|
||||
} else if (strcmp(argv[1], "-lfcff") == 0) {
|
||||
/*Load ZL380x0 firmware + related config record from flash*/
|
||||
unsigned short image_num = (unsigned short)strtoul(argv[2], NULL, 0);
|
||||
status = VprocTwolfFirmwareStop();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfFirmwareStop()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
status = VprocTwolfLoadFwrCfgFromFlash(image_num);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfLoadFwrCfgFromFlash()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
status = VprocTwolfReset(VPROC_RST_HARDWARE_RAM);
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfReset()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
printf("Device boot loading from flash completed successfully...\n");
|
||||
} else if (strcmp(argv[1], "-lfff") == 0) {
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfLoadFwrFromFlash()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Device boot loading from flash completed successfully...\n");
|
||||
|
||||
} else if (strcmp(argv[1], "-lfcfh-a") == 0) { /*for LOADING FWR/CFG via SPI*/
|
||||
if (tw_upload_dsp_firmware(0) != VPROC_STATUS_SUCCESS)
|
||||
printf("Device boot loading failed.....\n");
|
||||
|
||||
} else if (strcmp(argv[1], "-lcfh-a") == 0) { /*for LOADING CFG via SPI*/
|
||||
if (tw_upload_dsp_firmware(2) != VPROC_STATUS_SUCCESS)
|
||||
printf("Device boot loading failed.....\n");
|
||||
|
||||
} else if (strcmp(argv[1], "-lffh-a") == 0) { /*for LOADING FWR via SPI*/
|
||||
if (tw_upload_dsp_firmware(1) != VPROC_STATUS_SUCCESS)
|
||||
printf("Device boot loading failed.....\n");
|
||||
|
||||
} else if (strcmp(argv[1], "-sto") == 0) { /*for resetting into boot mode*/
|
||||
if (VprocTwolfFirmwareStop() != 0)
|
||||
VprocTwolfHbiCleanup();
|
||||
else
|
||||
printf(
|
||||
"Firmware stopped to boot mode completed"
|
||||
" successfully...\n");
|
||||
} else if (strcmp(argv[1], "-sta") == 0) { /*start executing FWR/CFG */
|
||||
if (VprocTwolfFirmwareStart() != 0)
|
||||
VprocTwolfHbiCleanup();
|
||||
else
|
||||
printf("Firmware is now running successfully...\n");
|
||||
} else if (strcmp(argv[1], "-mute_r") == 0) { /*start executing FWR/CFG */
|
||||
uint8 mute = (uint8)strtoul(argv[2], NULL, 0);
|
||||
// to do need fix
|
||||
// if(VprocTwolfMute(VPROC_ROUT, mute) != 0)
|
||||
if (1) {
|
||||
VprocTwolfHbiCleanup();
|
||||
} else {
|
||||
if (mute)
|
||||
printf("ROUT Port muted sucessfully...\n");
|
||||
else
|
||||
printf("ROUT Port unmuted sucessfully...\n");
|
||||
}
|
||||
} else if (strcmp(argv[1], "-mute_s") == 0) { /*start executing FWR/CFG */
|
||||
uint8 mute = (uint8)strtoul(argv[2], NULL, 0);
|
||||
// to do need fix
|
||||
// if(VprocTwolfMute(VPROC_SOUT, mute) != 0)
|
||||
if (1)
|
||||
VprocTwolfHbiCleanup();
|
||||
else {
|
||||
if (mute)
|
||||
printf("SOUT Port muted sucessfully...\n");
|
||||
else
|
||||
printf("SOUT Port unmuted sucessfully...\n");
|
||||
}
|
||||
} else if ((strcmp(argv[1], "-arec") == 0) || (strcmp(argv[1], "-apla") == 0))
|
||||
/* configure the ZL380x0 for either audio recording or playback
|
||||
* Over an I2S link
|
||||
*/
|
||||
{
|
||||
unsigned short pclkrate = (unsigned short)strtoul(argv[2], NULL, 0);
|
||||
unsigned short fsrate = (unsigned short)strtoul(argv[3], NULL, 0);
|
||||
unsigned short aecState = (unsigned char)strtoul(argv[4], NULL, 0);
|
||||
printf("pclkrate = %u KHz, fsrate = %u Hz, AEC state = %d\n", pclkrate,
|
||||
fsrate, aecState);
|
||||
// to do need fix
|
||||
#if 0
|
||||
if (strcmp(argv[1], "-arec") == 0) {
|
||||
if (VprocTwolfUpstreamConfigure(pclkrate, fsrate, aecState) != 0)
|
||||
VprocTwolfHbiCleanup();
|
||||
else
|
||||
printf("Device configured for audio recording...\n");
|
||||
} else if (strcmp(argv[1], "-apla") == 0) {
|
||||
if (VprocTwolfDownstreamConfigure(pclkrate, fsrate, aecState) != 0)
|
||||
VprocTwolfHbiCleanup();
|
||||
else
|
||||
printf("Device configured for audio playback...\n");
|
||||
}
|
||||
#endif
|
||||
} else if (strcmp(argv[1], "-fclr") == 0) {
|
||||
/*Erase the full content of the ZL380x0 controlled slave flash*/
|
||||
status = VprocTwolfEraseFlash();
|
||||
if (status != VPROC_STATUS_SUCCESS) {
|
||||
printf("Error %d:VprocTwolfEraseFlash()\n", status);
|
||||
VprocTwolfHbiCleanup();
|
||||
return -1;
|
||||
}
|
||||
printf("flash erasing completed successfully...\n");
|
||||
} else {
|
||||
printf("Usage: for help type:\n%s -h\n", argv[0]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef TW_SPI_ACCESS_H
|
||||
#define TW_SPI_ACCESS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int tw_upload_dsp_firmware(int mode);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2018 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*Configuration file version: Microsemi_ZLS38063_1_P1_4_0_Config.cr2, modified:
|
||||
* Tue Sep 18 20:48:31 2018*/
|
||||
|
||||
#ifndef _ZL38063_CONFIG_H_
|
||||
#define _ZL38063_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const unsigned short configStreamLen;
|
||||
extern const dataArr st_twConfig[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2018 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*Firmware Version : Microsemi_ZLS38063_1_P1_4_0_Firmware.s3, modified: Tue Sep
|
||||
* 18 20:50:24 2018 */
|
||||
|
||||
#ifndef _ZL38063_FIRMWARE_H_
|
||||
#define _ZL38063_FIRMWARE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const twFwr st_twFirmware[];
|
||||
|
||||
extern const unsigned short firmwareStreamLen;
|
||||
extern const unsigned long programBaseAddress;
|
||||
extern const unsigned long executionAddress;
|
||||
extern const unsigned char haveProgramBaseAddress;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
153
components/audio_hal/driver/zl38063/zl38063.c
Normal file
153
components/audio_hal/driver/zl38063/zl38063.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2018 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "zl38063.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "audio_volume.h"
|
||||
#include "board.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_log.h"
|
||||
#include "tw_spi_access.h"
|
||||
#include "vprocTwolf_access.h"
|
||||
|
||||
static const char *TAG = "zl38063";
|
||||
|
||||
static int codec_init_flag = 0;
|
||||
static codec_dac_volume_config_t *dac_vol_handle;
|
||||
|
||||
#define ZL38063_DAC_VOL_CFG_DEFAULT() \
|
||||
{ \
|
||||
.max_dac_volume = 6, .min_dac_volume = -90, \
|
||||
.board_pa_gain = BOARD_PA_GAIN, .volume_accuracy = 1, .dac_vol_symbol = 1, \
|
||||
.zero_volume_reg = 0, .reg_value = 0, .user_volume = 0, \
|
||||
.offset_conv_volume = NULL, \
|
||||
}
|
||||
|
||||
audio_hal_func_t AUDIO_CODEC_ZL38063_DEFAULT_HANDLE = {
|
||||
.audio_codec_initialize = zl38063_codec_init,
|
||||
.audio_codec_deinitialize = zl38063_codec_deinit,
|
||||
.audio_codec_ctrl = zl38063_codec_ctrl_state,
|
||||
.audio_codec_config_iface = zl38063_codec_config_i2s,
|
||||
.audio_codec_set_mute = zl38063_codec_set_voice_mute,
|
||||
.audio_codec_set_volume = zl38063_codec_set_voice_volume,
|
||||
.audio_codec_get_volume = zl38063_codec_get_voice_volume,
|
||||
.audio_codec_enable_pa = NULL,
|
||||
.audio_hal_lock = NULL,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
static bool zl38063_codec_initialized() { return codec_init_flag; }
|
||||
|
||||
esp_err_t zl38063_codec_init(audio_hal_codec_config_t *cfg) {
|
||||
if (zl38063_codec_initialized()) {
|
||||
ESP_LOGW(TAG, "The zl38063 codec has been already initialized");
|
||||
return ESP_OK;
|
||||
}
|
||||
tw_upload_dsp_firmware(0);
|
||||
gpio_config_t borad_conf;
|
||||
memset(&borad_conf, 0, sizeof(borad_conf));
|
||||
borad_conf.mode = GPIO_MODE_OUTPUT;
|
||||
borad_conf.pin_bit_mask = 1UL << (get_reset_board_gpio());
|
||||
borad_conf.pull_down_en = 0;
|
||||
borad_conf.pull_up_en = 0;
|
||||
|
||||
gpio_config_t pa_conf;
|
||||
memset(&pa_conf, 0, sizeof(pa_conf));
|
||||
pa_conf.mode = GPIO_MODE_OUTPUT;
|
||||
pa_conf.pin_bit_mask = 1UL << (get_pa_enable_gpio());
|
||||
pa_conf.pull_down_en = 0;
|
||||
pa_conf.pull_up_en = 0;
|
||||
|
||||
gpio_config(&pa_conf);
|
||||
gpio_config(&borad_conf);
|
||||
gpio_set_level(get_pa_enable_gpio(), 1); // enable PA
|
||||
gpio_set_level(get_reset_board_gpio(), 0); // enable DSP
|
||||
codec_init_flag = 1;
|
||||
|
||||
codec_dac_volume_config_t vol_cfg = ZL38063_DAC_VOL_CFG_DEFAULT();
|
||||
dac_vol_handle = audio_codec_volume_init(&vol_cfg);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t zl38063_codec_deinit(void) {
|
||||
gpio_set_level(get_pa_enable_gpio(), 0);
|
||||
gpio_set_level(get_reset_board_gpio(), 1);
|
||||
codec_init_flag = 0;
|
||||
audio_codec_volume_deinit(dac_vol_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t zl38063_codec_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t zl38063_codec_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t zl38063_codec_set_voice_mute(bool mute) {
|
||||
/* For now we do not have implementation for this */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param volume: 0 ~ 100, 0 means mute
|
||||
*
|
||||
* @note Register values. 0xA6: -90 dB, 0xCE: -50 dB, 0x00: 0 dB, 0x06: 6 dB
|
||||
* @note Accuracy of gain is 1 dB
|
||||
*
|
||||
* @return
|
||||
* - (-1) Error
|
||||
* - (0) Success
|
||||
*/
|
||||
esp_err_t zl38063_codec_set_voice_volume(int volume) {
|
||||
int ret = 0;
|
||||
uint8_t reg = 0;
|
||||
reg = audio_codec_get_dac_reg_value(dac_vol_handle, volume);
|
||||
ret = VprocTwolfSetVolume(reg);
|
||||
ESP_LOGD(TAG, "Set volume:%.2d reg_value:0x%.2x dB:%.1f",
|
||||
dac_vol_handle->user_volume, reg, (int8_t)reg * 1.0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t zl38063_codec_get_voice_volume(int *volume) {
|
||||
int ret = 0;
|
||||
int8_t reg = 0;
|
||||
ret = VprocTwolfGetVolume(®);
|
||||
if (reg == (int8_t)dac_vol_handle->reg_value) {
|
||||
*volume = dac_vol_handle->user_volume;
|
||||
} else {
|
||||
*volume = 0;
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
ESP_LOGD(TAG, "Get volume:%.2d reg_value:0x%x", *volume, (uint8_t)reg);
|
||||
return ret;
|
||||
}
|
||||
123
components/audio_hal/driver/zl38063/zl38063.h
Normal file
123
components/audio_hal/driver/zl38063/zl38063.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2018 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* 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 __ZL38063_H__
|
||||
#define __ZL38063_H__
|
||||
|
||||
#include "audio_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize ZL38063 chip
|
||||
*
|
||||
* @param cfg configuration of ZL38063
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t zl38063_codec_init(audio_hal_codec_config_t *cfg);
|
||||
/**
|
||||
* @brief Deinitialize ZL38063 chip
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t zl38063_codec_deinit(void);
|
||||
/**
|
||||
* The functions zl38063_ctrl_state and zl38063_config_i2s are not used by this
|
||||
* driver. They are kept here to maintain the uniformity and convenience of the
|
||||
* interface of the ADF project. These settings for zl38063 are burned in
|
||||
* firmware and configuration files. Default i2s configuration: 48000Hz, 16bit,
|
||||
* Left-Right channels. Use resampling to be compatible with different file
|
||||
* types.
|
||||
*
|
||||
* @brief Control ZL38063 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 zl38063_codec_ctrl_state(audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state);
|
||||
/**
|
||||
* @brief Configure ZL38063 codec mode and I2S interface
|
||||
*
|
||||
* @param mode codec mode
|
||||
* @param iface I2S config
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t zl38063_codec_config_i2s(audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
/**
|
||||
* @brief mute or unmute the codec
|
||||
*
|
||||
* @param mute: true, false
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t zl38063_codec_set_voice_mute(bool mute);
|
||||
|
||||
/**
|
||||
* @brief Set voice volume
|
||||
*
|
||||
* @param volume: voice volume (0~100)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t zl38063_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 zl38063_codec_get_voice_volume(int *volume);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -32,241 +32,237 @@
|
||||
#include "freertos/task.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AUDIO_HAL_VOL_DEFAULT 70
|
||||
|
||||
typedef struct audio_hal *audio_hal_handle_t;
|
||||
typedef struct audio_hal *audio_hal_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Select media hal codec mode
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_HAL_CODEC_MODE_ENCODE = 1, /*!< select adc */
|
||||
AUDIO_HAL_CODEC_MODE_DECODE, /*!< select dac */
|
||||
AUDIO_HAL_CODEC_MODE_BOTH, /*!< select both adc and dac */
|
||||
AUDIO_HAL_CODEC_MODE_LINE_IN, /*!< set adc channel */
|
||||
} audio_hal_codec_mode_t;
|
||||
/**
|
||||
* @brief Select media hal codec mode
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_HAL_CODEC_MODE_ENCODE = 1, /*!< select adc */
|
||||
AUDIO_HAL_CODEC_MODE_DECODE, /*!< select dac */
|
||||
AUDIO_HAL_CODEC_MODE_BOTH, /*!< select both adc and dac */
|
||||
AUDIO_HAL_CODEC_MODE_LINE_IN, /*!< set adc channel */
|
||||
} audio_hal_codec_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Select adc channel for input mic signal
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_HAL_ADC_INPUT_LINE1 = 0x00, /*!< mic input to adc channel 1 */
|
||||
AUDIO_HAL_ADC_INPUT_LINE2, /*!< mic input to adc channel 2 */
|
||||
AUDIO_HAL_ADC_INPUT_ALL, /*!< mic input to both channels of adc */
|
||||
AUDIO_HAL_ADC_INPUT_DIFFERENCE, /*!< mic input to adc difference channel */
|
||||
} audio_hal_adc_input_t;
|
||||
/**
|
||||
* @brief Select adc channel for input mic signal
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_HAL_ADC_INPUT_LINE1 = 0x00, /*!< mic input to adc channel 1 */
|
||||
AUDIO_HAL_ADC_INPUT_LINE2, /*!< mic input to adc channel 2 */
|
||||
AUDIO_HAL_ADC_INPUT_ALL, /*!< mic input to both channels of adc */
|
||||
AUDIO_HAL_ADC_INPUT_DIFFERENCE, /*!< mic input to adc difference channel */
|
||||
} audio_hal_adc_input_t;
|
||||
|
||||
/**
|
||||
* @brief Select channel for dac output
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_HAL_DAC_OUTPUT_LINE1 = 0x00, /*!< dac output signal to channel 1 */
|
||||
AUDIO_HAL_DAC_OUTPUT_LINE2, /*!< dac output signal to channel 2 */
|
||||
AUDIO_HAL_DAC_OUTPUT_ALL, /*!< dac output signal to both channels */
|
||||
} audio_hal_dac_output_t;
|
||||
/**
|
||||
* @brief Select channel for dac output
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_HAL_DAC_OUTPUT_LINE1 = 0x00, /*!< dac output signal to channel 1 */
|
||||
AUDIO_HAL_DAC_OUTPUT_LINE2, /*!< dac output signal to channel 2 */
|
||||
AUDIO_HAL_DAC_OUTPUT_ALL, /*!< dac output signal to both channels */
|
||||
} audio_hal_dac_output_t;
|
||||
|
||||
/**
|
||||
* @brief Select operating mode i.e. start or stop for audio codec chip
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_HAL_CTRL_STOP = 0x00, /*!< set stop mode */
|
||||
AUDIO_HAL_CTRL_START = 0x01, /*!< set start mode */
|
||||
} audio_hal_ctrl_t;
|
||||
/**
|
||||
* @brief Select operating mode i.e. start or stop for audio codec chip
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_HAL_CTRL_STOP = 0x00, /*!< set stop mode */
|
||||
AUDIO_HAL_CTRL_START = 0x01, /*!< set start mode */
|
||||
} audio_hal_ctrl_t;
|
||||
|
||||
/**
|
||||
* @brief Select I2S interface operating mode i.e. master or slave for audio
|
||||
* codec chip
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_HAL_MODE_SLAVE = 0x00, /*!< set slave mode */
|
||||
AUDIO_HAL_MODE_MASTER = 0x01, /*!< set master mode */
|
||||
} audio_hal_iface_mode_t;
|
||||
/**
|
||||
* @brief Select I2S interface operating mode i.e. master or slave for audio
|
||||
* codec chip
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_HAL_MODE_SLAVE = 0x00, /*!< set slave mode */
|
||||
AUDIO_HAL_MODE_MASTER = 0x01, /*!< set master mode */
|
||||
} audio_hal_iface_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Select I2S interface samples per second
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_HAL_08K_SAMPLES, /*!< set to 8k samples per second */
|
||||
AUDIO_HAL_11K_SAMPLES, /*!< set to 11.025k samples per second */
|
||||
AUDIO_HAL_16K_SAMPLES, /*!< set to 16k samples in per second */
|
||||
AUDIO_HAL_22K_SAMPLES, /*!< set to 22.050k samples per second */
|
||||
AUDIO_HAL_24K_SAMPLES, /*!< set to 24k samples in per second */
|
||||
AUDIO_HAL_32K_SAMPLES, /*!< set to 32k samples in per second */
|
||||
AUDIO_HAL_44K_SAMPLES, /*!< set to 44.1k samples per second */
|
||||
AUDIO_HAL_48K_SAMPLES, /*!< set to 48k samples per second */
|
||||
} audio_hal_iface_samples_t;
|
||||
/**
|
||||
* @brief Select I2S interface samples per second
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_HAL_08K_SAMPLES, /*!< set to 8k samples per second */
|
||||
AUDIO_HAL_11K_SAMPLES, /*!< set to 11.025k samples per second */
|
||||
AUDIO_HAL_16K_SAMPLES, /*!< set to 16k samples in per second */
|
||||
AUDIO_HAL_22K_SAMPLES, /*!< set to 22.050k samples per second */
|
||||
AUDIO_HAL_24K_SAMPLES, /*!< set to 24k samples in per second */
|
||||
AUDIO_HAL_32K_SAMPLES, /*!< set to 32k samples in per second */
|
||||
AUDIO_HAL_44K_SAMPLES, /*!< set to 44.1k samples per second */
|
||||
AUDIO_HAL_48K_SAMPLES, /*!< set to 48k samples per second */
|
||||
} audio_hal_iface_samples_t;
|
||||
|
||||
/**
|
||||
* @brief Select I2S interface number of bits per sample
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_HAL_BIT_LENGTH_16BITS = 1, /*!< set 16 bits per sample */
|
||||
AUDIO_HAL_BIT_LENGTH_24BITS, /*!< set 24 bits per sample */
|
||||
AUDIO_HAL_BIT_LENGTH_32BITS, /*!< set 32 bits per sample */
|
||||
} audio_hal_iface_bits_t;
|
||||
/**
|
||||
* @brief Select I2S interface number of bits per sample
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_HAL_BIT_LENGTH_16BITS = 1, /*!< set 16 bits per sample */
|
||||
AUDIO_HAL_BIT_LENGTH_24BITS, /*!< set 24 bits per sample */
|
||||
AUDIO_HAL_BIT_LENGTH_32BITS, /*!< set 32 bits per sample */
|
||||
} audio_hal_iface_bits_t;
|
||||
|
||||
/**
|
||||
* @brief Select I2S interface format for audio codec chip
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_HAL_I2S_NORMAL = 0, /*!< set normal I2S format */
|
||||
AUDIO_HAL_I2S_LEFT, /*!< set all left format */
|
||||
AUDIO_HAL_I2S_RIGHT, /*!< set all right format */
|
||||
AUDIO_HAL_I2S_DSP, /*!< set dsp/pcm format */
|
||||
} audio_hal_iface_format_t;
|
||||
/**
|
||||
* @brief Select I2S interface format for audio codec chip
|
||||
*/
|
||||
typedef enum {
|
||||
AUDIO_HAL_I2S_NORMAL = 0, /*!< set normal I2S format */
|
||||
AUDIO_HAL_I2S_LEFT, /*!< set all left format */
|
||||
AUDIO_HAL_I2S_RIGHT, /*!< set all right format */
|
||||
AUDIO_HAL_I2S_DSP, /*!< set dsp/pcm format */
|
||||
} audio_hal_iface_format_t;
|
||||
|
||||
/**
|
||||
* @brief I2s interface configuration for audio codec chip
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
audio_hal_iface_mode_t mode; /*!< audio codec chip mode */
|
||||
audio_hal_iface_format_t fmt; /*!< I2S interface format */
|
||||
audio_hal_iface_samples_t samples; /*!< I2S interface samples per second */
|
||||
audio_hal_iface_bits_t
|
||||
bits; /*!< i2s interface number of bits per sample */
|
||||
} audio_hal_codec_i2s_iface_t;
|
||||
/**
|
||||
* @brief I2s interface configuration for audio codec chip
|
||||
*/
|
||||
typedef struct {
|
||||
audio_hal_iface_mode_t mode; /*!< audio codec chip mode */
|
||||
audio_hal_iface_format_t fmt; /*!< I2S interface format */
|
||||
audio_hal_iface_samples_t samples; /*!< I2S interface samples per second */
|
||||
audio_hal_iface_bits_t bits; /*!< i2s interface number of bits per sample */
|
||||
} audio_hal_codec_i2s_iface_t;
|
||||
|
||||
/**
|
||||
* @brief Configure media hal for initialization of audio codec chip
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
audio_hal_adc_input_t adc_input; /*!< set adc channel */
|
||||
audio_hal_dac_output_t dac_output; /*!< set dac channel */
|
||||
audio_hal_codec_mode_t
|
||||
codec_mode; /*!< select codec mode: adc, dac or both */
|
||||
audio_hal_codec_i2s_iface_t
|
||||
i2s_iface; /*!< set I2S interface configuration */
|
||||
} audio_hal_codec_config_t;
|
||||
/**
|
||||
* @brief Configure media hal for initialization of audio codec chip
|
||||
*/
|
||||
typedef struct {
|
||||
audio_hal_adc_input_t adc_input; /*!< set adc channel */
|
||||
audio_hal_dac_output_t dac_output; /*!< set dac channel */
|
||||
audio_hal_codec_mode_t codec_mode; /*!< select codec mode: adc, dac or both */
|
||||
audio_hal_codec_i2s_iface_t i2s_iface; /*!< set I2S interface configuration */
|
||||
} audio_hal_codec_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration of functions and variables used to operate audio
|
||||
* codec chip
|
||||
*/
|
||||
typedef struct audio_hal
|
||||
{
|
||||
esp_err_t (*audio_codec_initialize) (
|
||||
audio_hal_codec_config_t *codec_cfg); /*!< initialize codec */
|
||||
esp_err_t (*audio_codec_deinitialize) (void); /*!< deinitialize codec */
|
||||
esp_err_t (*audio_codec_ctrl) (
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state); /*!< control codec mode and state */
|
||||
esp_err_t (*audio_codec_config_iface) (
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface); /*!< configure i2s interface */
|
||||
esp_err_t (*audio_codec_set_mute) (bool mute); /*!< set codec mute */
|
||||
esp_err_t (*audio_codec_set_volume) (int volume); /*!< set codec volume */
|
||||
esp_err_t (*audio_codec_get_volume) (int *volume); /*!< get codec volume */
|
||||
xSemaphoreHandle audio_hal_lock; /*!< semaphore of codec */
|
||||
void *handle; /*!< handle of audio codec */
|
||||
} audio_hal_func_t;
|
||||
/**
|
||||
* @brief Configuration of functions and variables used to operate audio codec
|
||||
* chip
|
||||
*/
|
||||
typedef struct audio_hal {
|
||||
esp_err_t (*audio_codec_initialize)(
|
||||
audio_hal_codec_config_t *codec_cfg); /*!< initialize codec */
|
||||
esp_err_t (*audio_codec_deinitialize)(void); /*!< deinitialize codec */
|
||||
esp_err_t (*audio_codec_ctrl)(
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t ctrl_state); /*!< control codec mode and state */
|
||||
esp_err_t (*audio_codec_config_iface)(
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface); /*!< configure i2s interface */
|
||||
esp_err_t (*audio_codec_set_mute)(bool mute); /*!< set codec mute */
|
||||
esp_err_t (*audio_codec_set_volume)(int volume); /*!< set codec volume */
|
||||
esp_err_t (*audio_codec_get_volume)(int *volume); /*!< get codec volume */
|
||||
esp_err_t (*audio_codec_enable_pa)(bool enable); /*!< enable pa */
|
||||
xSemaphoreHandle audio_hal_lock; /*!< semaphore of codec */
|
||||
void *handle; /*!< handle of audio codec */
|
||||
} audio_hal_func_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize media codec driver
|
||||
*
|
||||
* @note If selected codec has already been installed, it'll return the
|
||||
* audio_hal handle.
|
||||
*
|
||||
* @param audio_hal_conf Configure structure audio_hal_config_t
|
||||
* @param audio_hal_func Structure containing functions used to operate audio
|
||||
* the codec chip
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
audio_hal_handle_t audio_hal_init (audio_hal_codec_config_t *audio_hal_conf,
|
||||
audio_hal_func_t *audio_hal_func);
|
||||
/**
|
||||
* @brief Initialize media codec driver
|
||||
*
|
||||
* @note If selected codec has already been installed, it'll return the
|
||||
* audio_hal handle.
|
||||
*
|
||||
* @param audio_hal_conf Configure structure audio_hal_config_t
|
||||
* @param audio_hal_func Structure containing functions used to operate audio
|
||||
* the codec chip
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
audio_hal_handle_t audio_hal_init(audio_hal_codec_config_t *audio_hal_conf,
|
||||
audio_hal_func_t *audio_hal_func);
|
||||
|
||||
/**
|
||||
* @brief Uninitialize media codec driver
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_deinit (audio_hal_handle_t audio_hal);
|
||||
/**
|
||||
* @brief Uninitialize media codec driver
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_deinit(audio_hal_handle_t audio_hal);
|
||||
|
||||
/**
|
||||
* @brief Start/stop codec driver
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param mode select media hal codec mode either encode/decode/or both to
|
||||
* start from audio_hal_codec_mode_t
|
||||
* @param audio_hal_ctrl select start stop state for specific mode
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_ctrl_codec (audio_hal_handle_t audio_hal,
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t audio_hal_ctrl);
|
||||
/**
|
||||
* @brief Start/stop codec driver
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param mode select media hal codec mode either encode/decode/or both to start
|
||||
* from audio_hal_codec_mode_t
|
||||
* @param audio_hal_ctrl select start stop state for specific mode
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_ctrl_codec(audio_hal_handle_t audio_hal,
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_ctrl_t audio_hal_ctrl);
|
||||
|
||||
/**
|
||||
* @brief Set codec I2S interface samples rate & bit width and format either
|
||||
* I2S or PCM/DSP.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param mode select media hal codec mode either encode/decode/or both to
|
||||
* start from audio_hal_codec_mode_t
|
||||
* @param iface I2S sample rate (ex: 16000, 44100), I2S bit width (16, 24,
|
||||
* 32),I2s format (I2S, PCM, DSP).
|
||||
*
|
||||
* @return
|
||||
* - 0 Success
|
||||
* - -1 Error
|
||||
*/
|
||||
esp_err_t audio_hal_codec_iface_config (audio_hal_handle_t audio_hal,
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
/**
|
||||
* @brief Set codec I2S interface samples rate & bit width and format either I2S
|
||||
* or PCM/DSP.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param mode select media hal codec mode either encode/decode/or both to start
|
||||
* from audio_hal_codec_mode_t
|
||||
* @param iface I2S sample rate (ex: 16000, 44100), I2S bit width (16, 24,
|
||||
* 32),I2s format (I2S, PCM, DSP).
|
||||
*
|
||||
* @return
|
||||
* - 0 Success
|
||||
* - -1 Error
|
||||
*/
|
||||
esp_err_t audio_hal_codec_iface_config(audio_hal_handle_t audio_hal,
|
||||
audio_hal_codec_mode_t mode,
|
||||
audio_hal_codec_i2s_iface_t *iface);
|
||||
|
||||
/**
|
||||
* @brief Set voice mute. Enables or disables DAC mute of a codec.
|
||||
* @note `audio_hal_get_volume` will still give a non-zero number in
|
||||
* mute state. It will be set to that number when speaker is unmuted.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param mute true/false. If true speaker will be muted and if false
|
||||
* speaker will be unmuted.
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_set_mute (audio_hal_handle_t audio_hal, bool mute);
|
||||
/**
|
||||
* @brief Set voice mute. Enables or disables DAC mute of a codec.
|
||||
* @note `audio_hal_get_volume` will still give a non-zero number in mute
|
||||
* state. It will be set to that number when speaker is unmuted.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param mute true/false. If true speaker will be muted and if false
|
||||
* speaker will be unmuted.
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_set_mute(audio_hal_handle_t audio_hal, bool mute);
|
||||
|
||||
/**
|
||||
* @brief Set voice volume.
|
||||
* @note if volume is 0, mute is enabled,range is 0-100.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param volume value of volume in percent(%)
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_set_volume (audio_hal_handle_t audio_hal, int volume);
|
||||
/**
|
||||
* @brief Set voice volume.
|
||||
* @note if volume is 0, mute is enabled,range is 0-100.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param volume value of volume in percent(%)
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_set_volume(audio_hal_handle_t audio_hal, int volume);
|
||||
|
||||
/**
|
||||
* @brief get voice volume.
|
||||
* @note if volume is 0, mute is enabled, range is 0-100.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param volume value of volume in percent returned(%)
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_get_volume (audio_hal_handle_t audio_hal, int *volume);
|
||||
/**
|
||||
* @brief get voice volume.
|
||||
* @note if volume is 0, mute is enabled, range is 0-100.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param volume value of volume in percent returned(%)
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_get_volume(audio_hal_handle_t audio_hal, int *volume);
|
||||
|
||||
/**
|
||||
* @brief Enables or disables PA.
|
||||
*
|
||||
* @param audio_hal reference function pointer for selected audio codec
|
||||
* @param enable true/false.
|
||||
*
|
||||
* @return int, 0--success, others--fail
|
||||
*/
|
||||
esp_err_t audio_hal_enable_pa(audio_hal_handle_t audio_hal, bool enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__AUDIO_HAL_H__
|
||||
#endif //__AUDIO_HAL_H__
|
||||
|
||||
99
components/audio_hal/include/audio_volume.h
Normal file
99
components/audio_hal/include/audio_volume.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2022 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
|
||||
*
|
||||
* 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 _AUDIO_VOLUME_H_
|
||||
#define _AUDIO_VOLUME_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Map of user volume to codec dac volume offset
|
||||
*/
|
||||
typedef float (*audio_codec_dac_vol_offset)(int volume);
|
||||
|
||||
typedef void *volume_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Codec dac volume configurations
|
||||
*/
|
||||
typedef struct {
|
||||
float max_dac_volume; /*!< Codec support max volume */
|
||||
float min_dac_volume; /*!< Codec support min volume */
|
||||
float board_pa_gain; /*!< Board power amplifier gain */
|
||||
float volume_accuracy; /*!< Codec dac volume accuracy(0.5 or 1) */
|
||||
int8_t dac_vol_symbol; /*!< Whether the dac volume is positively correlated
|
||||
with the register value */
|
||||
uint8_t zero_volume_reg; /*!< Codec register value for zero dac volume */
|
||||
uint8_t reg_value; /*!< Record current dac volume register value */
|
||||
int user_volume; /*!< Record the user set volume */
|
||||
audio_codec_dac_vol_offset
|
||||
offset_conv_volume; /*!< Convert user volume to dac volume offset */
|
||||
} codec_dac_volume_config_t;
|
||||
|
||||
/**
|
||||
* @brief Init the audio dac volume by config
|
||||
*
|
||||
* @param config Codec dac volume config
|
||||
*
|
||||
* @return volume_handle_t
|
||||
*/
|
||||
volume_handle_t audio_codec_volume_init(codec_dac_volume_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Calculate codec register value by a linear formula
|
||||
*
|
||||
* @param vol_handle The dac volume handle
|
||||
* @param volume User set volume (0-100)
|
||||
*
|
||||
* @return Codec dac register value
|
||||
*/
|
||||
uint8_t audio_codec_get_dac_reg_value(volume_handle_t vol_handle, int volume);
|
||||
|
||||
/**
|
||||
* @brief Calculate codec dac volume by a linear formula
|
||||
*
|
||||
* @param vol_handle The dac volume handle
|
||||
*
|
||||
* @return Codec dac volume
|
||||
*/
|
||||
float audio_codec_cal_dac_volume(volume_handle_t vol_handle);
|
||||
|
||||
/**
|
||||
* @brief Deinit the dac volume handle
|
||||
*
|
||||
* @param vol_handle The dac volume handle
|
||||
*/
|
||||
void audio_codec_volume_deinit(volume_handle_t vol_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_AUDIO_VOLUME_H_
|
||||
@@ -6,10 +6,10 @@
|
||||
* 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:
|
||||
* 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.
|
||||
@@ -18,9 +18,9 @@
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -42,148 +42,139 @@ static const char *TAG = "TEST_AUDIO_HAL";
|
||||
extern const uint8_t test_pcm_start[] asm("_binary_test_pcm_start");
|
||||
extern const uint8_t test_pcm_end[] asm("_binary_test_pcm_end");
|
||||
|
||||
static void
|
||||
i2s_init ()
|
||||
{
|
||||
static void i2s_init() {
|
||||
i2s_config_t i2s_cfg = {
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX,
|
||||
.sample_rate = 16000,
|
||||
.bits_per_sample = 16,
|
||||
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
|
||||
.communication_format = I2S_COMM_FORMAT_I2S,
|
||||
.dma_buf_count = 3,
|
||||
.dma_buf_len = 300,
|
||||
.use_apll = 1,
|
||||
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2,
|
||||
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX,
|
||||
.sample_rate = 16000,
|
||||
.bits_per_sample = 16,
|
||||
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
|
||||
.communication_format = I2S_COMM_FORMAT_I2S,
|
||||
.dma_buf_count = 3,
|
||||
.dma_buf_len = 300,
|
||||
.use_apll = 1,
|
||||
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2,
|
||||
};
|
||||
|
||||
i2s_driver_install (TEST_I2S_NUM, &i2s_cfg, 0, NULL);
|
||||
i2s_pin_config_t i2s_pin_cfg = { 0 };
|
||||
get_i2s_pins (TEST_I2S_NUM, &i2s_pin_cfg);
|
||||
i2s_set_pin (TEST_I2S_NUM, &i2s_pin_cfg);
|
||||
i2s_mclk_gpio_select (TEST_I2S_NUM, GPIO_NUM_0);
|
||||
i2s_driver_install(TEST_I2S_NUM, &i2s_cfg, 0, NULL);
|
||||
i2s_pin_config_t i2s_pin_cfg = {0};
|
||||
if (sizeof(board_i2s_pin_t) == sizeof(i2s_pin_config_t)) {
|
||||
get_i2s_pins(TEST_I2S_NUM, (board_i2s_pin_t *)&i2s_pin_cfg);
|
||||
i2s_set_pin(TEST_I2S_NUM, &i2s_pin_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
i2s_deinit ()
|
||||
{
|
||||
i2s_driver_uninstall (TEST_I2S_NUM);
|
||||
}
|
||||
static void i2s_deinit() { i2s_driver_uninstall(TEST_I2S_NUM); }
|
||||
|
||||
TEST_CASE ("Usage test", "[audio_hal]")
|
||||
{
|
||||
ESP_LOGI (TAG, "Initialize i2s");
|
||||
i2s_init ();
|
||||
TEST_CASE("Usage test", "[audio_hal]") {
|
||||
ESP_LOGI(TAG, "Initialize i2s");
|
||||
i2s_init();
|
||||
|
||||
ESP_LOGI (TAG, "Start codec chip");
|
||||
audio_board_handle_t board_handle = audio_board_init ();
|
||||
TEST_ASSERT_NOT_NULL (board_handle);
|
||||
TEST_ASSERT_FALSE (audio_hal_ctrl_codec (board_handle->audio_hal,
|
||||
AUDIO_HAL_CODEC_MODE_DECODE,
|
||||
AUDIO_HAL_CTRL_START));
|
||||
ESP_LOGI(TAG, "Start codec chip");
|
||||
audio_board_handle_t board_handle = audio_board_init();
|
||||
TEST_ASSERT_NOT_NULL(board_handle);
|
||||
TEST_ASSERT_FALSE(audio_hal_ctrl_codec(board_handle->audio_hal,
|
||||
AUDIO_HAL_CODEC_MODE_DECODE,
|
||||
AUDIO_HAL_CTRL_START));
|
||||
|
||||
ESP_LOGI (TAG, "Set codec volume");
|
||||
TEST_ASSERT_FALSE (audio_hal_set_volume (board_handle->audio_hal, 65));
|
||||
ESP_LOGI(TAG, "Set codec volume");
|
||||
TEST_ASSERT_FALSE(audio_hal_set_volume(board_handle->audio_hal, 65));
|
||||
|
||||
int volume = 0;
|
||||
TEST_ASSERT_FALSE (audio_hal_get_volume (board_handle->audio_hal, &volume));
|
||||
ESP_LOGI (TAG, "Get codec volume: %d", volume);
|
||||
TEST_ASSERT_FALSE(audio_hal_get_volume(board_handle->audio_hal, &volume));
|
||||
ESP_LOGI(TAG, "Get codec volume: %d", volume);
|
||||
|
||||
size_t bytes_written = 0;
|
||||
ESP_LOGI (TAG, "Start to play music");
|
||||
TEST_ASSERT_FALSE (i2s_write (TEST_I2S_NUM, test_pcm_start,
|
||||
test_pcm_end - test_pcm_start, &bytes_written,
|
||||
portMAX_DELAY));
|
||||
ESP_LOGI(TAG, "Start to play music");
|
||||
TEST_ASSERT_FALSE(i2s_write(TEST_I2S_NUM, test_pcm_start,
|
||||
test_pcm_end - test_pcm_start, &bytes_written,
|
||||
portMAX_DELAY));
|
||||
|
||||
ESP_LOGW (TAG, "Reach the end of music, release all resource");
|
||||
TEST_ASSERT_FALSE (audio_board_deinit (board_handle));
|
||||
i2c_driver_delete (I2C_NUM_0);
|
||||
i2s_deinit ();
|
||||
ESP_LOGW(TAG, "Reach the end of music, release all resource");
|
||||
TEST_ASSERT_FALSE(audio_board_deinit(board_handle));
|
||||
i2c_driver_delete(I2C_NUM_0);
|
||||
i2s_deinit();
|
||||
}
|
||||
|
||||
/*
|
||||
* To run this case, please choose Lyrat_v4.3 in menuconfig and run on
|
||||
* lyrat_v4.3 board
|
||||
*/
|
||||
TEST_CASE ("Test for es8388 driver", "[audio_hal]")
|
||||
{
|
||||
ESP_LOGI (TAG, "Initialize i2s");
|
||||
i2s_init ();
|
||||
TEST_CASE("Test for es8388 driver", "[audio_hal]") {
|
||||
ESP_LOGI(TAG, "Initialize i2s");
|
||||
i2s_init();
|
||||
|
||||
ESP_LOGI (TAG, "Start es8388 codec chip");
|
||||
audio_hal_codec_config_t es8388_cfg = AUDIO_CODEC_DEFAULT_CONFIG ();
|
||||
TEST_ASSERT_FALSE (es8388_init (&es8388_cfg));
|
||||
TEST_ASSERT_FALSE (
|
||||
es8388_config_i2s (es8388_cfg.codec_mode, &es8388_cfg.i2s_iface));
|
||||
TEST_ASSERT_FALSE (
|
||||
es8388_ctrl_state (AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START));
|
||||
TEST_ASSERT_FALSE (es8388_set_voice_volume (50));
|
||||
ESP_LOGI(TAG, "Start es8388 codec chip");
|
||||
audio_hal_codec_config_t es8388_cfg = AUDIO_CODEC_DEFAULT_CONFIG();
|
||||
TEST_ASSERT_FALSE(es8388_init(&es8388_cfg));
|
||||
TEST_ASSERT_FALSE(
|
||||
es8388_config_i2s(es8388_cfg.codec_mode, &es8388_cfg.i2s_iface));
|
||||
TEST_ASSERT_FALSE(
|
||||
es8388_ctrl_state(AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START));
|
||||
TEST_ASSERT_FALSE(es8388_set_voice_volume(50));
|
||||
|
||||
size_t bytes_written = 0;
|
||||
ESP_LOGI (TAG, "Start to play music");
|
||||
TEST_ASSERT_FALSE (i2s_write (TEST_I2S_NUM, test_pcm_start,
|
||||
test_pcm_end - test_pcm_start, &bytes_written,
|
||||
portMAX_DELAY));
|
||||
ESP_LOGI(TAG, "Start to play music");
|
||||
TEST_ASSERT_FALSE(i2s_write(TEST_I2S_NUM, test_pcm_start,
|
||||
test_pcm_end - test_pcm_start, &bytes_written,
|
||||
portMAX_DELAY));
|
||||
|
||||
ESP_LOGW (TAG, "Reach the end of music, release all resource");
|
||||
i2c_driver_delete (I2C_NUM_0);
|
||||
i2s_deinit ();
|
||||
ESP_LOGW(TAG, "Reach the end of music, release all resource");
|
||||
i2c_driver_delete(I2C_NUM_0);
|
||||
i2s_deinit();
|
||||
}
|
||||
|
||||
/*
|
||||
* To run this case, please choose Lyrat_mini in menuconfig and run on
|
||||
* lyrat_mini board
|
||||
*/
|
||||
TEST_CASE ("Test for es8311 driver", "[audio_hal]")
|
||||
{
|
||||
ESP_LOGI (TAG, "Initialize i2s");
|
||||
i2s_init ();
|
||||
TEST_CASE("Test for es8311 driver", "[audio_hal]") {
|
||||
ESP_LOGI(TAG, "Initialize i2s");
|
||||
i2s_init();
|
||||
|
||||
ESP_LOGI (TAG, "Start es8311 codec chip");
|
||||
audio_hal_codec_config_t es8311_cfg = AUDIO_CODEC_DEFAULT_CONFIG ();
|
||||
TEST_ASSERT_FALSE (es8311_codec_init (&es8311_cfg));
|
||||
TEST_ASSERT_FALSE (
|
||||
es8311_codec_config_i2s (es8311_cfg.codec_mode, &es8311_cfg.i2s_iface));
|
||||
TEST_ASSERT_FALSE (es8311_codec_ctrl_state (AUDIO_HAL_CODEC_MODE_BOTH,
|
||||
AUDIO_HAL_CTRL_START));
|
||||
TEST_ASSERT_FALSE (es8311_codec_set_voice_volume (50));
|
||||
ESP_LOGI(TAG, "Start es8311 codec chip");
|
||||
audio_hal_codec_config_t es8311_cfg = AUDIO_CODEC_DEFAULT_CONFIG();
|
||||
TEST_ASSERT_FALSE(es8311_codec_init(&es8311_cfg));
|
||||
TEST_ASSERT_FALSE(
|
||||
es8311_codec_config_i2s(es8311_cfg.codec_mode, &es8311_cfg.i2s_iface));
|
||||
TEST_ASSERT_FALSE(
|
||||
es8311_codec_ctrl_state(AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START));
|
||||
TEST_ASSERT_FALSE(es8311_codec_set_voice_volume(50));
|
||||
|
||||
size_t bytes_written = 0;
|
||||
ESP_LOGI (TAG, "Start to play music");
|
||||
TEST_ASSERT_FALSE (i2s_write (TEST_I2S_NUM, test_pcm_start,
|
||||
test_pcm_end - test_pcm_start, &bytes_written,
|
||||
portMAX_DELAY));
|
||||
ESP_LOGI(TAG, "Start to play music");
|
||||
TEST_ASSERT_FALSE(i2s_write(TEST_I2S_NUM, test_pcm_start,
|
||||
test_pcm_end - test_pcm_start, &bytes_written,
|
||||
portMAX_DELAY));
|
||||
|
||||
ESP_LOGW (TAG, "Reach the end of music, release all resource");
|
||||
i2c_driver_delete (I2C_NUM_0);
|
||||
i2s_deinit ();
|
||||
ESP_LOGW(TAG, "Reach the end of music, release all resource");
|
||||
i2c_driver_delete(I2C_NUM_0);
|
||||
i2s_deinit();
|
||||
}
|
||||
|
||||
/*
|
||||
* To run this case, please choose LyratD_MSC in menuconfig and run on
|
||||
* lyratD_MSC board
|
||||
*/
|
||||
TEST_CASE ("Test for zl38063 driver", "[audio_hal]")
|
||||
{
|
||||
ESP_LOGI (TAG, "Initialize i2s");
|
||||
i2s_init ();
|
||||
TEST_CASE("Test for zl38063 driver", "[audio_hal]") {
|
||||
ESP_LOGI(TAG, "Initialize i2s");
|
||||
i2s_init();
|
||||
|
||||
ESP_LOGI (TAG, "Start zl38063 DSP");
|
||||
audio_hal_codec_config_t zl38063_cfg = AUDIO_CODEC_DEFAULT_CONFIG ();
|
||||
TEST_ASSERT_FALSE (zl38063_codec_init (&zl38063_cfg));
|
||||
TEST_ASSERT_FALSE (zl38063_codec_config_i2s (zl38063_cfg.codec_mode,
|
||||
&zl38063_cfg.i2s_iface));
|
||||
TEST_ASSERT_FALSE (zl38063_codec_ctrl_state (AUDIO_HAL_CODEC_MODE_BOTH,
|
||||
AUDIO_HAL_CTRL_START));
|
||||
TEST_ASSERT_FALSE (zl38063_codec_set_voice_volume (50));
|
||||
ESP_LOGI(TAG, "Start zl38063 DSP");
|
||||
audio_hal_codec_config_t zl38063_cfg = AUDIO_CODEC_DEFAULT_CONFIG();
|
||||
TEST_ASSERT_FALSE(zl38063_codec_init(&zl38063_cfg));
|
||||
TEST_ASSERT_FALSE(
|
||||
zl38063_codec_config_i2s(zl38063_cfg.codec_mode, &zl38063_cfg.i2s_iface));
|
||||
TEST_ASSERT_FALSE(zl38063_codec_ctrl_state(AUDIO_HAL_CODEC_MODE_BOTH,
|
||||
AUDIO_HAL_CTRL_START));
|
||||
TEST_ASSERT_FALSE(zl38063_codec_set_voice_volume(50));
|
||||
|
||||
size_t bytes_written = 0;
|
||||
ESP_LOGI (TAG, "Start to play music");
|
||||
TEST_ASSERT_FALSE (i2s_write (TEST_I2S_NUM, test_pcm_start,
|
||||
test_pcm_end - test_pcm_start, &bytes_written,
|
||||
portMAX_DELAY));
|
||||
ESP_LOGI(TAG, "Start to play music");
|
||||
TEST_ASSERT_FALSE(i2s_write(TEST_I2S_NUM, test_pcm_start,
|
||||
test_pcm_end - test_pcm_start, &bytes_written,
|
||||
portMAX_DELAY));
|
||||
|
||||
ESP_LOGW (TAG, "Reach the end of music, release all resource");
|
||||
i2c_driver_delete (I2C_NUM_0);
|
||||
i2s_deinit ();
|
||||
ESP_LOGW(TAG, "Reach the end of music, release all resource");
|
||||
i2c_driver_delete(I2C_NUM_0);
|
||||
i2s_deinit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user