update mic volume

This commit is contained in:
Steven Dan
2026-03-26 10:42:50 +08:00
parent a2fb9442f7
commit fb30861ffd
4 changed files with 281 additions and 58 deletions

View File

@@ -84,6 +84,9 @@ unsigned g_host_volume = 0x0;
unsigned char g_hid_status_report_data[63] = {0}; unsigned char g_hid_status_report_data[63] = {0};
unsigned int g_hid_status_report_index = 0; unsigned int g_hid_status_report_index = 0;
unsigned g_last_volume_level = 0xFF; // 上次已上报的音量级别0xFF表示初始化未完成 unsigned g_last_volume_level = 0xFF; // 上次已上报的音量级别0xFF表示初始化未完成
unsigned g_mic_volume_level = 38; // 麦克风PGA增益级别1-38对应NAU88L21寄存器值
unsigned g_request_mic_volume_set = 0;
unsigned g_last_mic_volume_level = 0xFF; // 上次已上报的麦克风增益级别0xFF表示初始化未完成
unsigned g_dac_m_gain = 0; unsigned g_dac_m_gain = 0;
unsigned g_unmute_delay_time = 0; unsigned g_unmute_delay_time = 0;
unsigned g_format_delay_time = 0; unsigned g_format_delay_time = 0;
@@ -493,8 +496,9 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
else else
save_value(dac_vol_path, (unsigned char)dac_level); save_value(dac_vol_path, (unsigned char)dac_level);
} }
// 同步全局音量变量与从Flash恢复的dac_level // 同步全局音量变量与从Flash恢复的dac_level / codec_adc_pga_gain_reg_value
g_volume_level = dac_level; g_volume_level = dac_level;
g_mic_volume_level = codec_adc_pga_gain_reg_value;
// ADCL PGA default setting // ADCL PGA default setting
mic_volume(codec_adc_pga_gain_reg_value); // make sure to write adc reg after initialize the codec, otherwise it does not take effect because of the hardware reset in the initial code mic_volume(codec_adc_pga_gain_reg_value); // make sure to write adc reg after initialize the codec, otherwise it does not take effect because of the hardware reset in the initial code
@@ -960,6 +964,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
// 增加音量 // 增加音量
mic_volume(++codec_adc_pga_gain_reg_value); mic_volume(++codec_adc_pga_gain_reg_value);
g_mic_volume_level = codec_adc_pga_gain_reg_value;
debug_printf("volume up %d\n", codec_adc_pga_gain_reg_value); debug_printf("volume up %d\n", codec_adc_pga_gain_reg_value);
save_value(mic_vol_path, codec_adc_pga_gain_reg_value); save_value(mic_vol_path, codec_adc_pga_gain_reg_value);
uint8_t new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value]; uint8_t new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value];
@@ -977,6 +982,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
// 减小音量 // 减小音量
mic_volume(--codec_adc_pga_gain_reg_value); mic_volume(--codec_adc_pga_gain_reg_value);
g_mic_volume_level = codec_adc_pga_gain_reg_value;
debug_printf("volume down %d\n", codec_adc_pga_gain_reg_value); debug_printf("volume down %d\n", codec_adc_pga_gain_reg_value);
save_value(mic_vol_path, codec_adc_pga_gain_reg_value); save_value(mic_vol_path, codec_adc_pga_gain_reg_value);
@@ -1261,8 +1267,31 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
} }
} }
// 处理HID SET_MIC_VOLUME (0x82) 请求应用新麦克风增益到硬件和LED
if (g_request_mic_volume_set) {
g_request_mic_volume_set = 0;
unsigned new_mic_level = g_mic_volume_level;
if (new_mic_level >= NAU88L21_PGA_GAIN_REG_MIN_USED_VALUE &&
new_mic_level <= NAU88L21_PGA_GAIN_REG_MAX_VALUE) {
uint8_t new_led_count;
codec_adc_pga_gain_reg_value = new_mic_level;
mic_volume(codec_adc_pga_gain_reg_value);
save_value(mic_vol_path, (unsigned char)codec_adc_pga_gain_reg_value);
// 更新麦克风增益指示LED
new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value];
for (int i = 0; i < 15; i++) {
if (i < new_led_count)
led_on(&led_ctx, led_l_physical_map[i]);
else
led_off(&led_ctx, led_l_physical_map[i]);
}
led_update_all(&led_ctx);
debug_printf("HID SET_MIC_VOLUME: pga=%d\n", codec_adc_pga_gain_reg_value);
}
}
#if HID_CONTROLS == 1 #if HID_CONTROLS == 1
// HID音量变化主动上报编码器旋转或HID命令导致的音量变化 // HID监听音量变化主动上报编码器旋转或HID命令导致的音量变化
{ {
unsigned current_volume_level = g_volume_level; unsigned current_volume_level = g_volume_level;
if (g_last_volume_level != current_volume_level && g_last_volume_level != 0xFF) { if (g_last_volume_level != current_volume_level && g_last_volume_level != 0xFF) {
@@ -1278,6 +1307,23 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
} }
g_last_volume_level = current_volume_level; g_last_volume_level = current_volume_level;
} }
// HID麦克风增益变化主动上报
{
unsigned current_mic_level = g_mic_volume_level;
if (g_last_mic_volume_level != current_mic_level && g_last_mic_volume_level != 0xFF) {
g_hid_status_report_data[0] = 0x77; // 同步头1
g_hid_status_report_data[1] = 0x83; // GET_MIC_VOLUME命令码
g_hid_status_report_data[2] = (unsigned char)current_mic_level;
for (int i = 3; i < 63; i++)
g_hid_status_report_data[i] = 0x00;
g_hid_status_report_index = 63;
hidSetChangePending(0x1);
debug_printf("Mic volume changed: %d -> %d, HID report sent\n",
g_last_mic_volume_level, current_mic_level);
}
g_last_mic_volume_level = current_mic_level;
}
#endif #endif
#if EQ_EN #if EQ_EN

View File

@@ -606,6 +606,30 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) {
return true; return true;
} }
// 处理设置麦克风增益命令 (0x82) - SET_MIC_VOLUME
// 范围: 1-38 (NAU88L21 PGA寄存器值1=0dB, 38≈36+1.5dB)
if (data[1] == 0x82) {
uint8_t mic_level = data[2];
// 参数验证: 1-38
if (mic_level < 1 || mic_level > 38) {
return false;
}
extern unsigned g_mic_volume_level;
extern unsigned g_request_mic_volume_set;
g_mic_volume_level = mic_level;
g_request_mic_volume_set = 1;
return true;
}
// 处理读取麦克风增益命令 (0x83) - GET_MIC_VOLUME
if (data[1] == 0x83) {
read_request.pending_cmd = 0x83;
return true;
}
// 处理设置音量命令 (0x93) - SET_VOLUME // 处理设置音量命令 (0x93) - SET_VOLUME
// 范围: 0-15 (0=静音, 1-15=-28dB~0dB, 2dB/步) // 范围: 0-15 (0=静音, 1-15=-28dB~0dB, 2dB/步)
if (data[1] == 0x93) { if (data[1] == 0x93) {
@@ -940,6 +964,16 @@ unsigned char process_read_params(uint8_t response[]) {
read_request.pending_cmd = 0; // Clear read request flag read_request.pending_cmd = 0; // Clear read request flag
return true; return true;
} }
// 处理读取麦克风增益请求 (0x83) - GET_MIC_VOLUME
if (read_request.pending_cmd == 0x83) {
RSP_HDR(response, 0x83);
extern unsigned g_mic_volume_level;
response[2] = (uint8_t)g_mic_volume_level;
read_request.pending_cmd = 0;
return true;
}
// 处理读取音量请求 (0x94) - GET_VOLUME // 处理读取音量请求 (0x94) - GET_VOLUME
if (read_request.pending_cmd == 0x94) { if (read_request.pending_cmd == 0x94) {
RSP_HDR(response, 0x94); RSP_HDR(response, 0x94);

View File

@@ -597,26 +597,47 @@ class EQDesigner(QMainWindow):
self.ui_groups['volume'] = volume_group # 保存引用 self.ui_groups['volume'] = volume_group # 保存引用
volume_layout = QFormLayout(volume_group) volume_layout = QFormLayout(volume_group)
# 音量级别显示和设置 # 监听音量DAC/耳机)级别显示和设置
volume_control_layout = QHBoxLayout() volume_control_layout = QHBoxLayout()
self.volume_label = QLabel("音量级别:") self.volume_label = QLabel("监听音量 (0x93/0x94):")
self.volume_spin = QSpinBox() self.volume_spin = QSpinBox()
self.volume_spin.setRange(0, 60) self.volume_spin.setRange(0, 15)
self.volume_spin.setValue(60) self.volume_spin.setValue(15)
self.volume_spin.setSuffix(" (0=最小, 60=最大)") self.volume_spin.setSuffix(" (0=静音, 15=0dB)")
volume_control_layout.addWidget(self.volume_label) volume_control_layout.addWidget(self.volume_label)
volume_control_layout.addWidget(self.volume_spin) volume_control_layout.addWidget(self.volume_spin)
volume_layout.addRow(volume_control_layout) volume_layout.addRow(volume_control_layout)
# 设置音量按钮 # 设置监听音量按钮
self.set_volume_btn = QPushButton("设置音量") vol_btn_layout = QHBoxLayout()
self.set_volume_btn = QPushButton("设置监听音量")
self.set_volume_btn.clicked.connect(self.on_set_volume) self.set_volume_btn.clicked.connect(self.on_set_volume)
volume_layout.addRow(self.set_volume_btn) self.get_volume_btn = QPushButton("读取监听音量")
# 读取音量按钮
self.get_volume_btn = QPushButton("读取音量")
self.get_volume_btn.clicked.connect(self.on_get_volume) self.get_volume_btn.clicked.connect(self.on_get_volume)
volume_layout.addRow(self.get_volume_btn) vol_btn_layout.addWidget(self.set_volume_btn)
vol_btn_layout.addWidget(self.get_volume_btn)
volume_layout.addRow(vol_btn_layout)
# 麦克风增益级别显示和设置
mic_vol_control_layout = QHBoxLayout()
self.mic_volume_label = QLabel("麦克风增益 (0x82/0x83):")
self.mic_volume_spin = QSpinBox()
self.mic_volume_spin.setRange(1, 38)
self.mic_volume_spin.setValue(38)
self.mic_volume_spin.setSuffix(" (1=0dB, 38=最大)")
mic_vol_control_layout.addWidget(self.mic_volume_label)
mic_vol_control_layout.addWidget(self.mic_volume_spin)
volume_layout.addRow(mic_vol_control_layout)
# 设置/读取麦克风增益按钮
mic_btn_layout = QHBoxLayout()
self.set_mic_volume_btn = QPushButton("设置麦克风增益")
self.set_mic_volume_btn.clicked.connect(self.on_set_mic_volume)
self.get_mic_volume_btn = QPushButton("读取麦克风增益")
self.get_mic_volume_btn.clicked.connect(self.on_get_mic_volume)
mic_btn_layout.addWidget(self.set_mic_volume_btn)
mic_btn_layout.addWidget(self.get_mic_volume_btn)
volume_layout.addRow(mic_btn_layout)
# 读取采样率和格式按钮 # 读取采样率和格式按钮
self.get_sample_format_btn = QPushButton("读取采样率和格式") self.get_sample_format_btn = QPushButton("读取采样率和格式")
@@ -2295,20 +2316,18 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
log_message(LOG_LEVEL_ERROR, f"设置并保存EQ模式时出错: {str(e)}", self.log_level) log_message(LOG_LEVEL_ERROR, f"设置并保存EQ模式时出错: {str(e)}", self.log_level)
def on_set_volume(self): def on_set_volume(self):
"""设置音量级别发送0x93命令""" """设置监听音量级别发送0x93命令范围0-15"""
if self.device_combo.currentData() is None: if self.device_combo.currentData() is None:
log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level) log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level)
return return
# 获取音量值
volume_level = self.volume_spin.value() volume_level = self.volume_spin.value()
# 弹出确认对话框
reply = QMessageBox.question( reply = QMessageBox.question(
self, self,
"确认设置音量", "确认设置监听音量",
f"将要设置音量级别为: {volume_level}\n\n" f"将要设置监听音量级别为: {volume_level}\n\n"
f"音量范围: 0-60 (0=最小音量, 60=最大音量)\n\n" f"音量范围: 0-15 (0=静音, 1=-28dB, ..., 15=0dB)\n\n"
f"是否继续?", f"是否继续?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes | QMessageBox.No,
QMessageBox.No QMessageBox.No
@@ -2321,30 +2340,23 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
h.open(device_info['vendor_id'], device_info['product_id']) h.open(device_info['vendor_id'], device_info['product_id'])
h.set_nonblocking(1) h.set_nonblocking(1)
# 构建0x93数据包 data = bytearray(63)
data = bytearray(63) # 63字节数据包 data[0] = 0x77
data[0] = 0x77 # 同步头1 data[1] = 0x93 # SET_VOLUME
data[1] = 0x93 # 命令码 (SET_VOLUME) data[2] = volume_level # 0-15
data[2] = volume_level # 音量级别 (0-60)
# 其余字节保持为0
# 发送请求 log_message(LOG_LEVEL_INFO, f"正在设置监听音量级别为 {volume_level}...", self.log_level)
log_message(LOG_LEVEL_INFO, f"正在设置音量级别为 {volume_level}...", self.log_level)
h.write([0x01] + list(data)) h.write([0x01] + list(data))
h.close() h.close()
log_message(LOG_LEVEL_INFO, f"音量级别 {volume_level} 设置成功", self.log_level)
QMessageBox.information( log_message(LOG_LEVEL_INFO, f"监听音量级别 {volume_level} 设置成功", self.log_level)
self, QMessageBox.information(self, "成功", f"监听音量级别已设置为: {volume_level}")
"成功",
f"音量级别已设置为: {volume_level}"
)
except Exception as e: except Exception as e:
log_message(LOG_LEVEL_ERROR, f"设置音量时出错: {str(e)}", self.log_level) log_message(LOG_LEVEL_ERROR, f"设置监听音量时出错: {str(e)}", self.log_level)
def on_get_volume(self): def on_get_volume(self):
"""读取音量级别发送0x94命令""" """读取监听音量级别发送0x94命令"""
if self.device_combo.currentData() is None: if self.device_combo.currentData() is None:
log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level) log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level)
return return
@@ -2355,35 +2367,25 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
h.open(device_info['vendor_id'], device_info['product_id']) h.open(device_info['vendor_id'], device_info['product_id'])
h.set_nonblocking(1) h.set_nonblocking(1)
# 构建0x94数据包 data = bytearray(63)
data = bytearray(63) # 63字节数据包 data[0] = 0x77
data[0] = 0x77 # 同步头1 data[1] = 0x94 # GET_VOLUME
data[1] = 0x94 # 命令码 (GET_VOLUME)
# 其余字节保持为0
# 发送请求 log_message(LOG_LEVEL_INFO, "正在读取监听音量级别...", self.log_level)
log_message(LOG_LEVEL_INFO, "正在读取音量级别...", self.log_level)
h.write([0x01] + list(data)) h.write([0x01] + list(data))
# 读取响应
import time import time
time.sleep(0.05) # 等待设备响应 time.sleep(0.05)
reply = h.get_input_report(0x1, 64) # 64字节响应 reply = h.get_input_report(0x1, 64)
if reply and len(reply) == 64: if reply and len(reply) == 64:
# 检查Report ID和同步头
if reply[0] == 0x01 and reply[1] == 0x77 and reply[2] == 0x94: if reply[0] == 0x01 and reply[1] == 0x77 and reply[2] == 0x94:
# 解析音量级别
volume_level = reply[3] volume_level = reply[3]
# 更新UI显示
self.volume_spin.setValue(volume_level) self.volume_spin.setValue(volume_level)
log_message(LOG_LEVEL_INFO, f"当前监听音量级别: {volume_level}", self.log_level)
log_message(LOG_LEVEL_INFO, f"当前音量级别: {volume_level}", self.log_level)
QMessageBox.information( QMessageBox.information(
self, self, "监听音量级别",
"音量级别", f"当前监听音量级别: {volume_level}\n\n"
f"当前音量级别: {volume_level}\n\n" f"音量范围: 0-15 (0=静音, 1=-28dB, ..., 15=0dB)"
f"音量范围: 0-60 (0=最小音量, 60=最大音量)"
) )
else: else:
log_message(LOG_LEVEL_ERROR, f"无效的0x94响应同步头: 0x{reply[1]:02x} 0x{reply[2]:02x}", self.log_level) log_message(LOG_LEVEL_ERROR, f"无效的0x94响应同步头: 0x{reply[1]:02x} 0x{reply[2]:02x}", self.log_level)
@@ -2393,7 +2395,89 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
h.close() h.close()
except Exception as e: except Exception as e:
log_message(LOG_LEVEL_ERROR, f"读取音量时出错: {str(e)}", self.log_level) log_message(LOG_LEVEL_ERROR, f"读取监听音量时出错: {str(e)}", self.log_level)
def on_set_mic_volume(self):
"""设置麦克风增益级别发送0x82命令范围1-38"""
if self.device_combo.currentData() is None:
log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level)
return
mic_level = self.mic_volume_spin.value()
reply = QMessageBox.question(
self,
"确认设置麦克风增益",
f"将要设置麦克风增益级别为: {mic_level}\n\n"
f"增益范围: 1-38 (1=0dB, 38≈36+1.5dB)\n\n"
f"是否继续?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
)
if reply == QMessageBox.Yes:
try:
device_info = self.device_combo.currentData()
h = hid.device()
h.open(device_info['vendor_id'], device_info['product_id'])
h.set_nonblocking(1)
data = bytearray(63)
data[0] = 0x77
data[1] = 0x82 # SET_MIC_VOLUME
data[2] = mic_level # 1-38
log_message(LOG_LEVEL_INFO, f"正在设置麦克风增益级别为 {mic_level}...", self.log_level)
h.write([0x01] + list(data))
h.close()
log_message(LOG_LEVEL_INFO, f"麦克风增益级别 {mic_level} 设置成功", self.log_level)
QMessageBox.information(self, "成功", f"麦克风增益级别已设置为: {mic_level}")
except Exception as e:
log_message(LOG_LEVEL_ERROR, f"设置麦克风增益时出错: {str(e)}", self.log_level)
def on_get_mic_volume(self):
"""读取麦克风增益级别发送0x83命令"""
if self.device_combo.currentData() is None:
log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level)
return
try:
device_info = self.device_combo.currentData()
h = hid.device()
h.open(device_info['vendor_id'], device_info['product_id'])
h.set_nonblocking(1)
data = bytearray(63)
data[0] = 0x77
data[1] = 0x83 # GET_MIC_VOLUME
log_message(LOG_LEVEL_INFO, "正在读取麦克风增益级别...", self.log_level)
h.write([0x01] + list(data))
import time
time.sleep(0.05)
reply = h.get_input_report(0x1, 64)
if reply and len(reply) == 64:
if reply[0] == 0x01 and reply[1] == 0x77 and reply[2] == 0x83:
mic_level = reply[3]
self.mic_volume_spin.setValue(mic_level)
log_message(LOG_LEVEL_INFO, f"当前麦克风增益级别: {mic_level}", self.log_level)
QMessageBox.information(
self, "麦克风增益级别",
f"当前麦克风增益级别: {mic_level}\n\n"
f"增益范围: 1-38 (1=0dB, 38≈36+1.5dB)"
)
else:
log_message(LOG_LEVEL_ERROR, f"无效的0x83响应同步头: 0x{reply[1]:02x} 0x{reply[2]:02x}", self.log_level)
else:
log_message(LOG_LEVEL_ERROR, "未收到0x83响应数据", self.log_level)
h.close()
except Exception as e:
log_message(LOG_LEVEL_ERROR, f"读取麦克风增益时出错: {str(e)}", self.log_level)
def on_get_sample_format(self): def on_get_sample_format(self):
"""读取采样率和格式信息发送0x9F命令""" """读取采样率和格式信息发送0x9F命令"""

View File

@@ -8,6 +8,8 @@
### 1.2 支持的指令列表 ### 1.2 支持的指令列表
| 指令码 | 命令名称 | 功能 | 方向 | 描述 | | 指令码 | 命令名称 | 功能 | 方向 | 描述 |
|--------|----------|------|------|------| |--------|----------|------|------|------|
| 0x82 | SET_MIC_VOLUME | 设置麦克风增益级别 | 主机→设备 | 设置麦克风PGA增益1-381=0dB, 38=约36+1.5dB |
| 0x83 | GET_MIC_VOLUME | 获取麦克风增益级别 | 主机→设备 | 读取当前麦克风PGA增益级别1-38 |
| 0x8A | SET_EQ_MODE | 切换EQ模式 | 主机→设备 | 切换EQ模式 | | 0x8A | SET_EQ_MODE | 切换EQ模式 | 主机→设备 | 切换EQ模式 |
| 0x8B | GET_EQ_MODE | 获取当前EQ模式信息 | 主机→设备 | 读取设备当前EQ模式和名称 | | 0x8B | GET_EQ_MODE | 获取当前EQ模式信息 | 主机→设备 | 读取设备当前EQ模式和名称 |
| 0x8C | SET_MODE_GAIN_AND_NAME | 设置模式整体增益和名称 | 主机→设备 | 设置模式整体增益和名称 | | 0x8C | SET_MODE_GAIN_AND_NAME | 设置模式整体增益和名称 | 主机→设备 | 设置模式整体增益和名称 |
@@ -36,6 +38,63 @@
## 2. 详细指令说明 ## 2. 详细指令说明
### 2.0 0x82 - SET_MIC_VOLUME (设置麦克风增益级别)
**功能**: 设置麦克风PGA增益级别
**方向**: 主机→设备
**数据包格式**:
```
字节位置 | 长度 | 内容 | 描述
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x82 | 命令码
2 | 1 | uint8 | 增益级别 (1-38: 1=0dB, 38≈36+1.5dB每级约1dB步进)
3-62 | 60 | 0x00 | 保留字节
```
**参数说明**:
- **增益级别范围:** 1-38共38级
- **对应硬件**NAU88C22 ADC PGA增益寄存器reg 0x007E直接写入寄存器值
- 1最小增益0dB
- 38最大增益约36+1.5dB数字增益)
- 中间各级约1dB步进
- 0 和 >38 均为无效值,固件将拒绝设置
**设备端处理**:
- 设置后立即应用到ADC PGA硬件
- 同步更新前面板LEDL系列15个LED反映当前增益级别
- 保存到Flashmic_vol路径断电重启后自动恢复
- 设备端增益变化含编码器旋转会主动通过0x83格式上报
**返回值**:
无直接返回值。设备端增益变化会主动上报0x83格式数据包。
### 2.0b 0x83 - GET_MIC_VOLUME (获取麦克风增益级别)
**功能**: 读取设备当前麦克风PGA增益级别设备端增益变化时也会主动上报
**方向**: 主机→设备(请求),设备→主机(响应/主动上报)
**请求数据包格式**:
```
字节位置 | 长度 | 内容 | 描述
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x83 | 命令码
2-62 | 61 | 0x00 | 保留字节
```
**响应数据包格式**(含主动上报):
```
字节位置 | 长度 | 内容 | 描述
---------|------|------|------
0 | 1 | 0x01 | Report ID
1 | 1 | 0x77 | 同步头1
2 | 1 | 0x83 | 同步头2
3 | 1 | uint8 | 当前增益级别 (1-38)
4-62 | 59 | 0x00 | 保留字节
```
**主动上报说明**:
- 编码器旋转导致增益变化时,设备主动向主机上报当前增益
- HID SET_MIC_VOLUME0x82命令成功执行后设备也主动上报新增益
### 2.1 0x8A - SET_EQ_MODE (切换EQ模式) ### 2.1 0x8A - SET_EQ_MODE (切换EQ模式)
**功能**: 切换当前EQ模式 **功能**: 切换当前EQ模式
**方向**: 主机→设备 **方向**: 主机→设备