update dac volume

This commit is contained in:
Steven Dan
2026-03-26 10:16:17 +08:00
parent 21956716cb
commit a2fb9442f7
3 changed files with 84 additions and 21 deletions

View File

@@ -15,6 +15,7 @@
#include "user_uart.h"
#include "debug_print.h"
#include "roleswitchflag.h"
#include "xua_hid_report.h"
#if defined (CODEC_AIC3204)
#include "eq_flash_storage.h"
@@ -75,10 +76,14 @@ unsigned g_mute_enable = 0;
unsigned g_mute_state = 0;
unsigned g_mute_state_old = 1;
unsigned g_unmute_dac_state, g_unmute_time, g_format_time;
unsigned g_volume_level = 60, g_saved_volume_level = 60;
unsigned g_volume_level = 15, g_saved_volume_level = 15;
unsigned g_request_volume_set = 0;
unsigned g_init_saved_settings = 0;
unsigned g_host_volume = 0x0;
// HID主动上报缓冲区被eq.c通过extern引用
unsigned char g_hid_status_report_data[63] = {0};
unsigned int g_hid_status_report_index = 0;
unsigned g_last_volume_level = 0xFF; // 上次已上报的音量级别0xFF表示初始化未完成
unsigned g_dac_m_gain = 0;
unsigned g_unmute_delay_time = 0;
unsigned g_format_delay_time = 0;
@@ -488,6 +493,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
else
save_value(dac_vol_path, (unsigned char)dac_level);
}
// 同步全局音量变量与从Flash恢复的dac_level
g_volume_level = dac_level;
// 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
@@ -1050,6 +1057,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
// 增加音量
++dac_level;
g_volume_level = dac_level;
dac_volume(dac_level - DAC_LEVEL_MAX);
save_value(dac_vol_path, dac_level);
@@ -1068,6 +1076,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
// 减小音量
--dac_level;
g_volume_level = dac_level;
if(dac_level == DAC_LEVEL_MIN)
unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
else
@@ -1227,6 +1236,50 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol)
last_uac_vol = uac_vol;
}
// 处理HID SET_VOLUME (0x93) 请求应用新音量到DAC和LED
if (g_request_volume_set) {
g_request_volume_set = 0;
unsigned new_level = g_volume_level;
if (new_level <= DAC_LEVEL_MAX) {
uint8_t new_led_count;
dac_level = new_level;
if (dac_level == DAC_LEVEL_MIN)
unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
else
dac_volume(dac_level - DAC_LEVEL_MAX);
save_value(dac_vol_path, (unsigned char)dac_level);
// 更新DAC音量指示LED
new_led_count = dac_gain_to_led[dac_level];
for (int i = 0; i < 15; i++) {
if (i < new_led_count)
led_on(&led_ctx, led_d_physical_map[i]);
else
led_off(&led_ctx, led_d_physical_map[i]);
}
led_update_all(&led_ctx);
debug_printf("HID SET_VOLUME: dac_level=%d\n", dac_level);
}
}
#if HID_CONTROLS == 1
// HID音量变化主动上报编码器旋转或HID命令导致的音量变化
{
unsigned current_volume_level = g_volume_level;
if (g_last_volume_level != current_volume_level && g_last_volume_level != 0xFF) {
g_hid_status_report_data[0] = 0x77; // 同步头1
g_hid_status_report_data[1] = 0x94; // GET_VOLUME命令码
g_hid_status_report_data[2] = (unsigned char)current_volume_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("Volume changed: %d -> %d, HID report sent\n",
g_last_volume_level, current_volume_level);
}
g_last_volume_level = current_volume_level;
}
#endif
#if EQ_EN
{

View File

@@ -607,12 +607,13 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) {
}
// 处理设置音量命令 (0x93) - SET_VOLUME
// 范围: 0-15 (0=静音, 1-15=-28dB~0dB, 2dB/步)
if (data[1] == 0x93) {
// 获取音量级别
uint8_t volume_level = data[2];
// 参数验证
if (volume_level > 60) {
// 参数验证: 0-15 (0=mute, 1-15 = -28dB~0dB)
if (volume_level > 15) {
return false;
}

View File

@@ -17,8 +17,8 @@
| 0x90 | RESET_EQ_PARAMS | 复位EQ参数 | 主机→设备 | 删除Flash中的EQ参数并恢复头文件预设参数 |
| 0x91 | GET_EQ_MODE_COUNT | 获取EQ模式总数 | 主机→设备 | 返回预定义加用户模式的总数(不包含禁用模式) |
| 0x92 | SET_AND_SAVE_EQ_MODE | 设置并保存EQ模式 | 主机→设备 | 设置当前EQ模式(0-9)并保存到Flash开机时自动恢复 |
| 0x93 | SET_VOLUME | 设置音量级别 | 主机→设备 | 设置设备音量级别0-60 |
| 0x94 | GET_VOLUME | 获取音量级别 | 主机→设备 | 读取设备当前音量级别0-60 |
| 0x93 | SET_VOLUME | 设置监听音量级别 | 主机→设备 | 设置设备监听音量级别0-150=静音, 1-15=-28dB~0dB, 2dB/步 |
| 0x94 | GET_VOLUME | 获取监听音量级别 | 主机→设备 | 读取设备当前监听音量级别0-150=静音, 1-15=-28dB~0dB |
| 0x9D | SET_EQ_ENABLE | 设置EQ使能开关 | 主机→设备 | 设置EQ使能开关ON/OFF禁用时保存当前模式启用时恢复之前模式 |
| 0x9E | GET_EQ_ENABLE | 获取EQ使能开关 | 主机→设备 | 读取EQ使能开关状态ON/OFF |
| 0x9F | GET_SAMPLE_FORMAT | 获取采样率和格式 | 主机→设备 | 读取当前采样率、DSD模式和DAC采样分辨率 |
@@ -274,8 +274,8 @@
4-62 | 59 | 0x00 | 保留字节
```
### 2.10 0x93 - SET_VOLUME (设置音量级别)
**功能**: 设置设备音量级别
### 2.10 0x93 - SET_VOLUME (设置监听音量级别)
**功能**: 设置设备监听(耳机/DAC音量级别
**方向**: 主机→设备
**数据包格式**:
```
@@ -283,27 +283,32 @@
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x93 | 命令码
2 | 1 | uint8 | 音量级别 (0-60: 0=最小音量, 60=最大音量)
2 | 1 | uint8 | 音量级别 (0-15: 0=静音, 1=-28dB, ..., 15=0dB)
3-62 | 60 | 0x00 | 保留字节
```
**参数说明**:
- **音量级别范围:** 0-60共61级)
- **说明:** 控制设备的输出音量级别
- 0: 最小音量(约-127.5dB
- 60: 最大音量0dB
- 每级约2dB的衰减变化
- **音量级别范围:** 0-15共16级)
- **说明:** 控制设备监听输出DAC/耳机)音量级别
- 0: 静音muteDAC完全静音
- 1: -28dB最小有效音量
- 2: -26dB
- ...每级2dB步进
- 15: 0dB最大音量
- **对应硬件**NAU88C22 DAC音量寄存器reg 0x003416级精度
**设备端处理**:
- 参数会通过现有的定时保存机制自动保存到Flash
- 如果参数超出范围(>60固件将拒绝设置并返回false
- 设置后立即应用到DAC硬件
- 同步更新前面板LEDD系列15个LED反映当前音量级别
- 保存到Flashdac_vol路径断电重启后自动恢复
- 如果参数超出范围(>15固件将拒绝设置
**返回值**:
无直接返回值。如需确认音量是否设置成功请使用GET_VOLUME命令读取当前音量。
无直接返回值。如需确认音量是否设置成功请使用GET_VOLUME命令读取当前音量。设备端音量变化含编码器旋转引起的变化会主动通过0x94格式上报。
### 2.11 0x94 - GET_VOLUME (获取音量级别)
**功能**: 读取设备当前音量级别
**方向**: 主机→设备
### 2.11 0x94 - GET_VOLUME (获取监听音量级别)
**功能**: 读取设备当前监听音量级别;设备端音量变化时也会主动上报此格式
**方向**: 主机→设备(请求),设备→主机(响应/主动上报)
**请求数据包格式**:
```
字节位置 | 长度 | 内容 | 描述
@@ -313,17 +318,21 @@
2-62 | 61 | 0x00 | 保留字节
```
**响应数据包格式**:
**响应数据包格式**(含主动上报):
```
字节位置 | 长度 | 内容 | 描述
---------|------|------|------
0 | 1 | 0x01 | Report ID
1 | 1 | 0x77 | 同步头1
2 | 1 | 0x94 | 同步头2
3 | 1 | uint8 | 当前音量级别 (0-60)
3 | 1 | uint8 | 当前音量级别 (0-15: 0=静音, 1-15=-28dB~0dB)
4-62 | 59 | 0x00 | 保留字节
```
**主动上报说明**:
- 当编码器旋转导致音量变化时,设备会主动向主机上报当前音量(使用相同的响应格式)
- 当HID SET_VOLUME0x93命令被成功执行后设备也会主动上报新音量
### 2.20 0x9D - SET_EQ_ENABLE (设置EQ使能开关)
**功能**: 设置EQ使能开关启用/禁用)
**方向**: 主机→设备