feat(es3c28p,es3c35p): restore ES8311 42dB mic gain, font size, flash script
- Re-apply input-gain-percent (100 = no digital boost) + 42dB HW max mapping lost in the upstream merge (was 340953b1/7788415e) - es3c35p: lvgl.fontSize=16 (text 12/16/22, launcher icons 42) - Add flash-es3c.sh build+flash helper for 28p/35p
This commit is contained in:
@@ -90,6 +90,7 @@
|
|||||||
compatible = "everest,es8311";
|
compatible = "everest,es8311";
|
||||||
reg = <0x18>;
|
reg = <0x18>;
|
||||||
i2s = <&i2s0>;
|
i2s = <&i2s0>;
|
||||||
|
input-gain-percent = <100>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ display.shape=rectangle
|
|||||||
display.dpi=165
|
display.dpi=165
|
||||||
|
|
||||||
lvgl.colorDepth=16
|
lvgl.colorDepth=16
|
||||||
|
lvgl.fontSize=16
|
||||||
|
|
||||||
storage.userDataLocation=SD
|
storage.userDataLocation=SD
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
compatible = "everest,es8311";
|
compatible = "everest,es8311";
|
||||||
reg = <0x18>;
|
reg = <0x18>;
|
||||||
i2s = <&i2s0>;
|
i2s = <&i2s0>;
|
||||||
|
input-gain-percent = <100>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,3 +9,7 @@ properties:
|
|||||||
type: phandle
|
type: phandle
|
||||||
required: true
|
required: true
|
||||||
description: "I2S controller device that carries audio data"
|
description: "I2S controller device that carries audio data"
|
||||||
|
input-gain-percent:
|
||||||
|
type: int
|
||||||
|
default: 100
|
||||||
|
description: "Extra digital gain multiplier applied by audio_stream on top of the ES8311's own 42dB hardware ADC gain, as an integer percentage (100 = 1.0x / no extra boost). For quiet MEMS mic capsules that are still quiet even at max hardware gain."
|
||||||
|
|||||||
@@ -25,6 +25,14 @@ struct Es8311Config {
|
|||||||
uint8_t address;
|
uint8_t address;
|
||||||
/** I2S controller device that carries audio data */
|
/** I2S controller device that carries audio data */
|
||||||
struct Device* i2s_device;
|
struct Device* i2s_device;
|
||||||
|
/**
|
||||||
|
* Extra fixed digital gain multiplier applied by audio_stream on top of the ES8311's
|
||||||
|
* own hardware ADC gain (0..42dB), as an integer percentage (100 = 1.0x / no extra boost).
|
||||||
|
* Small MEMS mic capsules can still sound quiet even near max hardware gain; this is for
|
||||||
|
* boards where 42dB hardware gain alone isn't enough. devicetree has no float property type,
|
||||||
|
* hence the x100 integer encoding.
|
||||||
|
*/
|
||||||
|
uint16_t input_gain_percent;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ struct Es8311Data {
|
|||||||
bool is_open = false;
|
bool is_open = false;
|
||||||
AudioCodecDirection open_direction = AUDIO_CODEC_DIR_BOTH;
|
AudioCodecDirection open_direction = AUDIO_CODEC_DIR_BOTH;
|
||||||
esp_codec_dev_sample_info_t open_sample_info = {};
|
esp_codec_dev_sample_info_t open_sample_info = {};
|
||||||
|
float input_gain = 1.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GET_CONFIG(device) (static_cast<const Es8311Config*>((device)->config))
|
#define GET_CONFIG(device) (static_cast<const Es8311Config*>((device)->config))
|
||||||
@@ -144,8 +145,8 @@ error_t set_volume(Device* device, AudioCodecDirection direction, float volume_p
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (direction == AUDIO_CODEC_DIR_INPUT) {
|
if (direction == AUDIO_CODEC_DIR_INPUT) {
|
||||||
// ES8311 ADC gain range is roughly 0..24 dB; map 0..100% linearly onto it.
|
// ES8311 ADC gain supports 0..42dB (0,6,12,18,24,30,36,42) in 6dB steps
|
||||||
float db = (volume_percent / 100.0f) * 24.0f;
|
float db = (volume_percent / 100.0f) * 42.0f;
|
||||||
return (esp_codec_dev_set_in_gain(data->codec_device, db) == ESP_CODEC_DEV_OK) ? ERROR_NONE : ERROR_RESOURCE;
|
return (esp_codec_dev_set_in_gain(data->codec_device, db) == ESP_CODEC_DEV_OK) ? ERROR_NONE : ERROR_RESOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +173,8 @@ error_t get_volume(Device* device, AudioCodecDirection direction, float* volume_
|
|||||||
if (esp_codec_dev_get_in_gain(data->codec_device, &db) != ESP_CODEC_DEV_OK) {
|
if (esp_codec_dev_get_in_gain(data->codec_device, &db) != ESP_CODEC_DEV_OK) {
|
||||||
return ERROR_RESOURCE;
|
return ERROR_RESOURCE;
|
||||||
}
|
}
|
||||||
*volume_percent = (db / 24.0f) * 100.0f;
|
*volume_percent = (db / 42.0f) * 100.0f;
|
||||||
|
if (*volume_percent > 100.0f) *volume_percent = 100.0f;
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,6 +237,12 @@ error_t get_capabilities(Device* device, AudioCodecDirection* supported_directio
|
|||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_t get_input_gain_multiplier(Device* device, float* gain) {
|
||||||
|
auto* data = GET_DATA(device);
|
||||||
|
*gain = data->input_gain;
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct AudioCodecApi API = {
|
static const struct AudioCodecApi API = {
|
||||||
.open = open,
|
.open = open,
|
||||||
.close = close,
|
.close = close,
|
||||||
@@ -247,7 +255,7 @@ static const struct AudioCodecApi API = {
|
|||||||
.get_native_sample_rate = get_native_sample_rate,
|
.get_native_sample_rate = get_native_sample_rate,
|
||||||
.get_native_channels = get_native_channels,
|
.get_native_channels = get_native_channels,
|
||||||
.get_capabilities = get_capabilities,
|
.get_capabilities = get_capabilities,
|
||||||
.get_input_gain_multiplier = nullptr,
|
.get_input_gain_multiplier = get_input_gain_multiplier,
|
||||||
};
|
};
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
@@ -257,6 +265,11 @@ static const struct AudioCodecApi API = {
|
|||||||
error_t start_device(Device* device) {
|
error_t start_device(Device* device) {
|
||||||
const auto* config = GET_CONFIG(device);
|
const auto* config = GET_CONFIG(device);
|
||||||
|
|
||||||
|
if (config->input_gain_percent > 2000) {
|
||||||
|
LOG_E(TAG, "Invalid input_gain_percent %u (must be 0..2000)", config->input_gain_percent);
|
||||||
|
return ERROR_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
auto* i2c_controller = device_get_parent(device);
|
auto* i2c_controller = device_get_parent(device);
|
||||||
if (i2c_controller == nullptr || device_get_type(i2c_controller) != &I2C_CONTROLLER_TYPE) {
|
if (i2c_controller == nullptr || device_get_type(i2c_controller) != &I2C_CONTROLLER_TYPE) {
|
||||||
LOG_E(TAG, "Parent is not an I2C controller");
|
LOG_E(TAG, "Parent is not an I2C controller");
|
||||||
@@ -270,6 +283,8 @@ error_t start_device(Device* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto* data = new Es8311Data();
|
auto* data = new Es8311Data();
|
||||||
|
data->input_gain = (float) config->input_gain_percent / 100.0f;
|
||||||
|
if (config->input_gain_percent == 0) data->input_gain = 1.0f; // 0 means unset
|
||||||
|
|
||||||
data->ctrl_if = audio_codec_adapter_new_i2c_ctrl(i2c_controller, config->address);
|
data->ctrl_if = audio_codec_adapter_new_i2c_ctrl(i2c_controller, config->address);
|
||||||
data->data_if = audio_codec_adapter_new_i2s_data(i2s_controller);
|
data->data_if = audio_codec_adapter_new_i2s_data(i2s_controller);
|
||||||
|
|||||||
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
# Build and flash LCDWIKI ES3C28P / ES3C35P firmware.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./flash-es3c.sh 35p [port] [--build-only]
|
||||||
|
# ./flash-es3c.sh 28p [port] [--build-only]
|
||||||
|
#
|
||||||
|
# If port is omitted, the single /dev/cu.usbmodem* device is used.
|
||||||
|
# Each board keeps its own build dir (build-es3c28p / build-es3c35p),
|
||||||
|
# so switching boards only rewrites sdkconfig via device.py.
|
||||||
|
set -eu -o pipefail
|
||||||
|
|
||||||
|
FIRMWARE_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
cd "$FIRMWARE_DIR"
|
||||||
|
SCRIPT_NAME="$(basename "$0")"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: ${SCRIPT_NAME} <28p|35p> [port] [--build-only]"
|
||||||
|
echo " port defaults to the single /dev/cu.usbmodem* device"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (( $# == 0 )); then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
28p|es3c28p) DEVICE_ID="es3c28p" ;;
|
||||||
|
35p|es3c35p) DEVICE_ID="es3c35p" ;;
|
||||||
|
-h|--help|help) usage; exit 0 ;;
|
||||||
|
*) echo "Unknown device '$1' (expected 28p or 35p)"; usage; exit 1 ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
|
||||||
|
PORT=""
|
||||||
|
BUILD_ONLY=0
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--build-only) BUILD_ONLY=1 ;;
|
||||||
|
*) PORT="$arg" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ! BUILD_ONLY )) && [[ -z "$PORT" ]]; then
|
||||||
|
candidates=(/dev/cu.usbmodem*(N))
|
||||||
|
if (( ${#candidates} == 0 )); then
|
||||||
|
echo "No /dev/cu.usbmodem* device found. Connect the board or pass the port explicitly."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if (( ${#candidates} > 1 )); then
|
||||||
|
echo "Multiple USB modem devices found:"
|
||||||
|
printf ' %s\n' "${candidates[@]}"
|
||||||
|
echo "Unplug one board or pass the port explicitly."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
PORT="${candidates[1]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# IDF 5.5 environment (host venvs corrupt IDF tooling, so pin the IDF python env)
|
||||||
|
unset VIRTUAL_ENV PYTHONPATH PYTHONHOME
|
||||||
|
export IDF_PYTHON_ENV_PATH=/Users/adolforeyna/.espressif/python_env/idf5.5_py3.9_env
|
||||||
|
source /Users/adolforeyna/esp/esp-idf/export.sh
|
||||||
|
|
||||||
|
BUILD_DIR="build-${DEVICE_ID}"
|
||||||
|
"$IDF_PYTHON_ENV_PATH/bin/python" device.py "$DEVICE_ID"
|
||||||
|
idf.py -B "$BUILD_DIR" reconfigure build
|
||||||
|
|
||||||
|
if (( BUILD_ONLY )); then
|
||||||
|
echo "Build done (${BUILD_DIR}/Tactility.bin). Skipping flash (--build-only)."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Confirming board on ${PORT} ==="
|
||||||
|
"$IDF_PYTHON_ENV_PATH/bin/python" -m esptool --chip esp32s3 -p "$PORT" chip_id | grep -E "Chip is|MAC:"
|
||||||
|
|
||||||
|
idf.py -B "$BUILD_DIR" -p "$PORT" -b 460800 flash
|
||||||
|
echo "Flashed ${DEVICE_ID} on ${PORT}."
|
||||||
Reference in New Issue
Block a user