update app_usb_aud_fosi_c1_v71

This commit is contained in:
Steven Dan
2026-05-14 11:57:07 +08:00
parent b4de6d4f73
commit b9303bccb8
18 changed files with 1996 additions and 3089 deletions

View File

@@ -162,7 +162,11 @@
/* Board power source - Default is bus-powered */
#ifndef XUA_POWERMODE
#define XUA_POWERMODE XUA_POWERMODE_SELF
#define XUA_POWERMODE XUA_POWERMODE_BUS
#endif
#ifndef _XUA_BMAX_POWER
#define _XUA_BMAX_POWER (50)
#endif
/* Enable/Disable example HID code - Default is off */

View File

@@ -40,28 +40,20 @@ set(SW_FACT_AUDIO_FLAGS ${EXTRA_BUILD_FLAGS} ${SW_FACT_VERSION}
LINK_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR}/../../lib_dnr/lib_dnr)
set(APP_COMPILER_FLAGS_v71_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
-DI2S_CHANS_ADC=2
-DMIN_FREQ=48000
-DMAX_FREQ=48000
-DUAC1_MODE=0
-DUSE_EX3D=1
-DF3_F4_FPS_UAC2=1
-DMIXER=0
-DUAC2_MODE=1
-ldnr_50ms
-llib_ex3d_all
-DEQ_EN=1
-DDNR_ENABLE=1
-DEQ_EN=0
#-DDNR_ENABLE=1
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=16
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=16
-DINPUT_FORMAT_COUNT=1
@@ -83,15 +75,17 @@ set(APP_COMPILER_FLAGS_v71_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
-DI2S_CHANS_ADC=2
-DMIN_FREQ=48000
-DAUDIO_CLASS=1
-DUAC1_MODE=1
-DMAX_FREQ=48000
-DWIN_OS_DETECTION=1
-DUSE_EX3D=1
-DF3_F4_FPS_UAC2=1
-DMIXER=0
-DUAC2_MODE=1
-ldnr_50ms
-llib_ex3d_all
-DEQ_EN=1
-DDNR_ENABLE=1
-DEQ_EN=0
#-DDNR_ENABLE=1
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=32
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=32
-DINPUT_FORMAT_COUNT=1
@@ -110,7 +104,10 @@ set(APP_COMPILER_FLAGS_v71_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
-DHID_CONTROLS=1)
set(APP_INCLUDES src src/core src/extensions ../../lib_dnr/lib_dnr)
LINK_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR}/../../lib_dnr/lib_dnr ${CMAKE_CURRENT_LIST_DIR}/../../lib_ex3d/lib_ex3d/lib)
set(APP_INCLUDES src src/core src/extensions ../shared/)
set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
XMOS_REGISTER_APP()

View File

@@ -0,0 +1,53 @@
function(calculate_config_value VALUES_VAR CONFIG_VALUE_VAR)
set(BYTE0 0)
set(BYTE1 0)
set(BYTE2 0)
set(BYTE3 0)
foreach(FLAG ${${VALUES_VAR}})
string(REPLACE "=" ";" FLAG_LIST ${FLAG})
list(GET FLAG_LIST 0 KEY)
list(GET FLAG_LIST 1 VALUE)
if("${KEY}" STREQUAL "I2S_MODE")
math(EXPR BYTE0 "${BYTE0} | ${VALUE} << 7" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "SYNC_MODE")
math(EXPR BYTE0 "${BYTE0} | ${VALUE} << 6" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "MIDI_ENABLE")
math(EXPR BYTE0 "${BYTE0} | ${VALUE} << 5" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "SPDIF_IN_ENABLE")
math(EXPR BYTE0 "${BYTE0} | ${VALUE} << 4" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "SPDIF_OUT_ENABLE")
math(EXPR BYTE0 "${BYTE0} | ${VALUE} << 3" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "ADAT_IN_ENABLE")
math(EXPR BYTE0 "${BYTE0} | ${VALUE} << 2" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "ADAT_OUT_ENABLE")
math(EXPR BYTE0 "${BYTE0} | ${VALUE} << 1" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "DSD_OUT_ENABLE")
math(EXPR BYTE0 "${BYTE0} | ${VALUE}" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "AUDIO_SAMPLE_RATE")
math(EXPR BYTE1 "${BYTE1} | ${VALUE} & 0x0F" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "MQA_ENABLE")
math(EXPR BYTE1 "${BYTE1} | (${VALUE} << 4)" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "AUDIO_CLASS")
math(EXPR BYTE1 "${BYTE1} | (${VALUE} << 5)" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "AUDIO_WIDTH")
math(EXPR BYTE1 "${BYTE1} | (${VALUE} << 6)" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "INPUT_CHANNEL")
math(EXPR BYTE2 "${BYTE2} | ${VALUE} & 0x3F" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "OUTPUT_CHANNEL")
math(EXPR BYTE2 "${BYTE2} | (${VALUE} << 6) & 0xFC0" OUTPUT_FORMAT HEXADECIMAL)
elseif("${KEY}" STREQUAL "OTHER_CFG")
math(EXPR BYTE2 "${BYTE2} | (${VALUE} << 12) & 0xF000" OUTPUT_FORMAT HEXADECIMAL)
endif()
endforeach()
# 打印每个字节的值
#message(STATUS "BYTE0: 0x${BYTE0}")
#message(STATUS "BYTE1: 0x${BYTE1}")
#message(STATUS "BYTE2: 0x${BYTE2}")
#message(STATUS "BYTE3: 0x${BYTE3}")
math(EXPR CONFIG_VALUE "${BYTE3} << 24 | ${BYTE2} << 16 | ${BYTE1} << 8 | ${BYTE0}" OUTPUT_FORMAT HEXADECIMAL)
set(${CONFIG_VALUE_VAR} "${CONFIG_VALUE}" PARENT_SCOPE)
endfunction()

View File

@@ -131,7 +131,7 @@
#define XUD_TILE (0)
#define PLL_REF_TILE (0)
#define AUDIO_IO_TILE (1)
#define AUDIO_IO_TILE (0)
#define MIDI_TILE (1)
/*** Defines relating to USB descriptor strings and ID's ***/

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,27 @@
#if UART_DEBUG || DEBUG_MEMORY_LOG_ENABLED
#define DEBUG_PRINT_ENABLE 1
#endif
#include <platform.h>
#include "gpio_access.h"
#include "xc_ptr.h"
#include "debug_print.h"
//on tile[0]: out port p_leds = XS1_PORT_4F;
extern unsigned g_mute_enable, g_unmute_time;
extern unsigned g_unmute_dac_state;
unsigned long get_reference_time();
void UserAudioStreamStart(void)
{
/* Turn all LEDs on */
// p_leds <: 0xF;
unsigned long time = get_reference_time();
SET_SHARED_GLOBAL(g_unmute_dac_state, 1);
SET_SHARED_GLOBAL(g_unmute_time, time);
debug_printf("UserAudioStreamStart\n");
}
void UserAudioStreamStop(void)
{
/* Turn all LEDs off */
// p_leds <: 0x0;
unsigned enable_mute;
debug_printf("UserAudioStreamStop\n");
//SET_SHARED_GLOBAL(g_unmute_dac_state, 0);
//set_gpio(P_GPIO_MUTE, MUTE);
delay_milliseconds(10);
}

View File

@@ -1,77 +0,0 @@
// Copyright 2020-2023 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef AIC3204_H_
#define AIC3204_H_
// TLV320AIC3204 Device I2C Address
#define AIC3204_I2C_DEVICE_ADDR 0x18
#define CODEC_I2C_DEVICE_ADDR AIC3204_I2C_DEVICE_ADDR
// TLV320AIC3204 Register Addresses
// Page 0
#define AIC3204_PAGE_CTRL 0x00 // Register 0 - Page Control
#define AIC3204_SW_RST 0x01 // Register 1 - Software Reset
#define AIC3204_NDAC 0x0B // Register 11 - NDAC Divider Value
#define AIC3204_MDAC 0x0C // Register 12 - MDAC Divider Value
#define AIC3204_DOSR_MSB 0x0d // Register 14 - DOSR Divider Value (MS Byte)
#define AIC3204_DOSR_LSB 0x0e // Register 14 - DOSR Divider Value (LS Byte)
#define AIC3204_NADC 0x12 // Register 18 - NADC Divider Value
#define AIC3204_MADC 0x13 // Register 19 - MADC Divider Value
#define AIC3204_AOSR 0x14 // Register 20 - AOSR Divider Value
#define AIC3204_CLK_MUL 0x19 // Register 25
#define AIC3204_CLK_DIV 0x1A // Register 26
#define AIC3204_CODEC_IF 0x1B // Register 27 - CODEC Interface Control
#define AIC3204_D_OFFSET 0x1C // Register 28 -
#define AIC3204_LOOPBACK 0x1D // Register 29 -
#define AIC3204_BCLK_DIV 0x1E // Register 30 - --------
#define AIC3204_CLK_MUL 0x1F // Register 31 -
#define AIC3204_BCLK_SEL 0x20 // Register 32 - 0:Primary; 1:Second
#define AIC3204_DAC_SIG_PROC 0x3C // Register 60 - DAC Sig Processing Block Control
#define AIC3204_ADC_SIG_PROC 0x3D // Register 61 - ADC Sig Processing Block Control
#define AIC3204_DAC_CH_SET1 0x3F // Register 63 - DAC Channel Setup 1
#define AIC3204_DAC_CH_SET2 0x40 // Register 64 - DAC Channel Setup 2
#define AIC3204_DACL_VOL_D 0x41 // Register 65 - DAC Left Digital Vol Control
#define AIC3204_DACR_VOL_D 0x42 // Register 66 - DAC Right Digital Vol Control
#define AIC3204_HEADSET_DET 0x43 // Register 67 - Headset Detection configuration
#define AIC3204_DRC_CON1 0x44 // Register 68 - DRC control reg1
#define AIC3204_DRC_CON2 0x45 // Register 69 - DRC control reg2
#define AIC3204_DRC_CON3 0x46 // Register 70 - DRC control reg3
#define AIC3204_ADC_CH_SET 0x51 // Register 81 - ADC Channel Setup
#define AIC3204_ADC_FGA_MUTE 0x52 // Register 82 - ADC Fine Gain Adjust/Mute
#define AIC3204_ADC_CH1_SET 0x53 // Register 83 - ADC L_CH vol
#define AIC3204_ADC_CH2_SET 0x54 // Register 84 - ADC R_CH vol
#define AIC3204_ADC_PHA_SET 0x55 // Register 84 - ADC Phase Adjust Reg
//0x56~0x5c: L-CH agc control regs
//0x5e~0x65: R-CH agc control regs
///0x66~0x67: DC measurement regs
//0x68~0x6d: DC Measurement output regs
// Page 1
#define AIC3204_PAGE_SEL1 0x00 // Register 0 - Page Select Reg
#define AIC3204_PWR_CFG 0x01 // Register 1 - Power Config
#define AIC3204_LDO_CTRL 0x02 // Register 2 - LDO Control
#define AIC3204_PLAY_CFG1 0x03 // Register 3 - Playback Config 1
#define AIC3204_PLAY_CFG2 0x04 // Register 4 - Playback Config 2
#define AIC3204_OP_PWR_CTRL 0x09 // Register 9 - Output Driver Power Control
#define AIC3204_CM_CTRL 0x0A // Register 10 - Common Mode Control
#define AIC3204_HPL_ROUTE 0x0C // Register 12 - HPL Routing Select
#define AIC3204_HPR_ROUTE 0x0D // Register 13 - HPR Routing Select
#define AIC3204_HPL_GAIN 0x10 // Register 16 - HPL Driver Gain
#define AIC3204_HPR_GAIN 0x11 // Register 17 - HPR Driver Gain
#define AIC3204_HP_START 0x14 // Register 20 - Headphone Driver Startup
#define AIC3204_LPGA_P_ROUTE 0x34 // Register 52 - Left PGA Positive Input Route
#define AIC3204_LPGA_N_ROUTE 0x36 // Register 54 - Left PGA Negative Input Route
#define AIC3204_RPGA_P_ROUTE 0x37 // Register 55 - Right PGA Positive Input Route
#define AIC3204_RPGA_N_ROUTE 0x39 // Register 57 - Right PGA Negative Input Route
#define AIC3204_LPGA_VOL 0x3B // Register 59 - Left PGA Volume
#define AIC3204_RPGA_VOL 0x3C // Register 60 - Right PGA Volume
#define AIC3204_ADC_PTM 0x3D // Register 61 - ADC Power Tune Config
#define AIC3204_ADC_VOL 0x3E // Register 62 - ADC Analog Gain Control Flag
#define AIC3204_AN_IN_CHRG 0x47 // Register 71 - Analog Input Quick Charging Config
#define AIC3204_REF_STARTUP 0x7B // Register 123 - Reference Power Up Config
int aic3204_init(void);
#endif /* AIC3204_H_ */

View File

@@ -18,11 +18,11 @@ extern swlock_t flash_lock;
extern void hidSetChangePending(unsigned int id);
extern unsigned char check_sum(unsigned char *pbuf, unsigned len);
extern void device_reboot(void);
extern unsigned hidSendData[];
// 固件升级通知MCU的标志phaten无UART MCU保留为静态变量供内部使用
static unsigned g_firmware_upgrade_mcu_notify = 0;
unsigned g_in_fw_upgrade = 0; // 升级进行中标志供其他模块检查以阻止非升级HID上报
// 全局变量
extern unsigned char g_hid_pass_data[64]; // HID主动上报数据缓冲区
extern unsigned g_firmware_upgrade_mcu_notify; // 固件升级状态通知 MCU1=开始 2=结束成功 3=结束(中止/失败)
extern unsigned g_in_fw_upgrade; // 是否处于固件升级中START=1 END/ABORT=0
// 升级状态(静态全局变量)
static upgrade_status_t g_upgrade_status;
@@ -59,24 +59,42 @@ void firmware_upgrade_reset(void)
}
// 发送固件升级响应(主动上报)
// 填充hidSendData通过UserHIDGetData上报给host
// 改动原因通过HID主动上报机制发送响应参考audiohw.xc中的音量上报实现
// 使用g_hid_pass_data全局数组存储响应数据然后调用hidSetChangePending触发主动上报
void send_firmware_upgrade_response(uint8_t cmd, uint8_t *response_data, uint16_t data_len)
{
unsigned char *ptr = (unsigned char *)hidSendData;
ptr[0] = 1;
ptr[1] = 0x77; // 同步头
ptr[2] = cmd; // 命令码
// 构建响应数据包
g_hid_pass_data[0] = 0x77; // 同步头
g_hid_pass_data[1] = cmd; // 命令码
// 复制响应数据
if (response_data != NULL && data_len > 0) {
uint16_t copy_len = (data_len < 61) ? data_len : 61;
memcpy(&ptr[3], response_data, copy_len);
memcpy(&g_hid_pass_data[2], response_data, copy_len);
}
for (int i = 3 + (int)data_len; i < 64; i++) {
ptr[i] = 0x00;
// 其余字节填充为0
for (int i = 2 + data_len; i < 63; i++) {
g_hid_pass_data[i] = 0x00;
}
// 改动原因:先触发主动上报,再打印调试信息,确保响应及时发送
// 通知HID系统有数据变化触发主动上报优先执行减少延迟
hidSetChangePending(0x1);
// 改动原因添加调试打印显示上报的响应数据16进制格式
// 注意g_hid_pass_data是63字节不包括Report ID但HID实际发送的是64字节包括Report ID 0x01
// 为了完整显示我们需要构建完整的64字节数据包
// 注意打印操作移到hidSetChangePending之后避免打印延迟影响响应发送
uint8_t full_packet[64];
full_packet[0] = 0x01; // Report ID
memcpy(&full_packet[1], g_hid_pass_data, 63); // 复制63字节数据
char prefix[64];
//debug_printf(prefix, sizeof(prefix), "[Device Report] Response (0x%02X)", cmd);
//debug_print_hex(prefix, full_packet, 64, 64);
//debug_printf("Firmware upgrade response sent: cmd=0x%02x\n", cmd);
}
// 处理START命令

View File

@@ -48,12 +48,6 @@ void start_dsp_processing(unsigned samFreq);
#define KEY_PLAY_VOL_UP 0x80
#define KEY_BITS (KEY_MIC_VOL_DN | KEY_MUTE | KEY_MIC_VOL_UP | KEY_PLAY_VOL_DN | KEY_PLAY_VOL_UP)
#if defined (PHATEN_GSV2)
#define DEBOUNCE_TIMEOUT 10 // in units of 2.6ms; 128 samples/frame
#else
#error "Please define DEBOUNCE_TIMEOUT"
#endif
#define MUTED_MIC 0x5A
#define UNMUTED_MIC 0xA5
@@ -66,4 +60,3 @@ void start_dsp_processing(unsigned samFreq);
#define HID_CONTROL_MUTE 0x20
#endif //RINGBUFFER_H

View File

@@ -120,6 +120,9 @@ chanend_t uc_dsp_to_dnr_t1;
chanend_t uc_key_to_ubm_t0;
volatile EXTERN DS_BOOL m_hThread;
extern unsigned g_dnr_init_flag;
void SetEx3dToUbmChan (chanend_t c) {
uc_ex3d_to_ubm = c;
}
void SetEqDataChan (chanend_t c) {
uc_eq_data = c;
}
@@ -161,7 +164,7 @@ void key_sender(chanend_t c)
void UserBufferManagementInit(unsigned sampFreq)
{
ubm_sample_freq = sampFreq;
#if USE_EX3D == 1
#if 0// USE_EX3D == 1
memset(ubm_ingress, 0, sizeof(ubm_ingress));
memset(ubm_egress, 0, sizeof(ubm_egress));
frame_index = 0;
@@ -885,12 +888,10 @@ void update_button(unsigned char b)
#endif
#if defined (PHATEN_GSV2)
#define KEY_POLLING_INTERVAL 10000000L // 100ms polling interval
#define HOLD_THRESHOLD 20 // time = HOLD_THRESHOLD * KEY_POLLING_INTERVAL = 2000ms
// 改动原因添加LED闪烁相关宏定义用于长按时直接循环闪烁3次
#define BLINK_COUNT 3 // LED闪烁次数3次
#endif
@@ -1153,10 +1154,8 @@ void hid_button_task(chanend_t cc_mic_level, chanend_t c_hidRcvData, chanend_t c
chanend_t uc_dsp_to_ex3d[DSP_WORKER_COUNT];
extern int OnProcessing();
void ex3d_task(){
channel_t c = chan_alloc();
chanend_t c_ex3d_to_ubm = c.end_a;
uc_ex3d_to_ubm = c.end_b;
void ex3d_task(chanend_t c_ex3d_to_ubm){
// set_core_high_priority_on();
delay_milliseconds(500);
@@ -1164,7 +1163,10 @@ void ex3d_task(){
if(ret != 0) {
debug_printf("audio_ex3d_init() error:%d\n\r", ret);
}
memset(ubm_ingress, 0, sizeof(ubm_ingress));
memset(ubm_egress, 0, sizeof(ubm_egress));
audio_ex3d_onoff(1);
#if !UAC1_MODE
Ex3dOffGain = -5;
Ex3dOnGain = -5;

View File

@@ -35,7 +35,7 @@ extern void debug_print_eq_params(unsigned sample_freq);
extern uint32_t get_reference_time(void);
extern void update_eq_post_gain(void);
extern unsigned int g_eq_sample_rate;
extern unsigned g_windows_detect_done;
unsigned g_windows_detect_done = 1;
extern unsigned g_dnr_init_flag;
extern unsigned g_ex3d_key_verified;

View File

@@ -0,0 +1,50 @@
#include "gpio_access.h"
#include "swlock.h"
#include <xs1.h>
swlock_t gpo_swlock = SWLOCK_INITIAL_VALUE;
void p_gpio_lock()
{
swlock_acquire(&gpo_swlock);
}
void p_gpio_unlock()
{
swlock_release(&gpo_swlock);
}
unsigned p_gpio_peek()
{
unsigned portId, x;
// Wrapped in lock to ensure it's safe from multiple logical cores
swlock_acquire(&gpo_swlock);
asm("ldw %0, dp[p_gpio]":"=r"(portId));
asm volatile("peek %0, res[%1]":"=r"(x):"r"(portId));
return x;
}
void p_gpio_out(unsigned x)
{
unsigned portId;
asm("ldw %0, dp[p_gpio]":"=r"(portId));
asm volatile("out res[%0], %1"::"r"(portId),"r"(x));
// Wrapped in lock to ensure it's safe from multiple logical cores
swlock_release(&gpo_swlock);
}
void set_gpio(unsigned bit, unsigned value)
{
unsigned port_shadow;
port_shadow = p_gpio_peek(); // Read port pin value
if (value == 0) port_shadow &= ~bit; // If writing a 0, generate mask and AND with current val
else port_shadow |= bit; // Else use mask and OR to set bit
p_gpio_out(port_shadow); // Write back to port. Will make port an output if not already
}

View File

@@ -0,0 +1,17 @@
#ifndef _GPIO_ACCESS_H_
#define _GPIO_ACCESS_H_
/* General output port bit definitions */
#define P_GPIO_DAC_RST_N (1 << 1)
#define P_GPIO_MUTE (1 << 3)
#define P_GPIO_SET (1 << 2)
#define MUTE (0)
#define UNMUTE (1)
void set_gpio(unsigned bit, unsigned value);
void p_gpio_lock();
void p_gpio_unlock();
unsigned p_gpio_peek();
void p_gpio_out(unsigned x);
#endif

View File

@@ -1,252 +0,0 @@
/**
* @file htr3236.c
* @brief HTR3236 36-Channel LED PWM Driver Implementation for XMOS
* @version 1.1
*/
#include "htr3236.h"
#include <xccompat.h>
#include <platform.h>
out port p_htr3235_sdb = PORT_HTR3236_SDB; /* 连接到HTR3236的SDB引脚用于控制其电源状态 */
/*=========================================================================
Gamma 校正查找表
-----------------------------------------------------------------------*/
static const uint8_t gamma_table_32[32] = {
0, 1, 2, 4, 6, 10, 13, 18,
22, 28, 33, 39, 46, 53, 61, 69,
78, 86, 96, 106, 116, 126, 138, 149,
161, 173, 186, 199, 212, 226, 240, 255
};
static const uint8_t gamma_table_64[64] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 10, 12, 14, 16, 18, 20, 22,
24, 26, 29, 32, 35, 38, 41, 44,
47, 50, 53, 57, 61, 65, 69, 73,
77, 81, 85, 89, 94, 99, 104, 109,
114, 119, 124, 129, 134, 140, 146, 152,
158, 164, 170, 176, 182, 188, 195, 202,
209, 216, 223, 230, 237, 244, 251, 255
};
/*=========================================================================
内部函数
-----------------------------------------------------------------------*/
/**
* @brief 写单字节到寄存器
*/
static int write_reg(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t reg, uint8_t data)
{
uint8_t buf[2] = {reg, data};
size_t n;
i2c.write(dev->i2c_addr, buf, 2, n, 1);
if (n == 0)
{
return I2C_REGOP_DEVICE_NACK;
}
if (n < 2)
{
return I2C_REGOP_INCOMPLETE;
}
return I2C_REGOP_SUCCESS;
}
/**
* @brief 写多字节到寄存器 (支持自动地址递增)
*/
static int write_reg_bulk(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t start_reg,
const uint8_t *data, uint8_t len)
{
uint8_t buf[36 + 1];
size_t n;
buf[0] = start_reg;
for (int i = 0; i < len; i++) {
buf[i + 1] = data[i];
}
i2c.write(dev->i2c_addr, buf, len + 1, n, 1);
if (n == 0)
{
return I2C_REGOP_DEVICE_NACK;
}
if (n < 2)
{
return I2C_REGOP_INCOMPLETE;
}
return I2C_REGOP_SUCCESS;
}
/**
* @brief 读取寄存器值
*/
static int read_reg(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t reg, i2c_regop_res_t &result)
{
uint8_t a_reg[1] = {reg};
uint8_t data[1] = {0};
size_t n;
i2c_res_t res;
unsafe
{
res = i2c.write(dev->i2c_addr, a_reg, 1, n, 0);
if (n != 1)
{
result = I2C_REGOP_DEVICE_NACK;
i2c.send_stop_bit();
return 0;
}
res = i2c.read(dev->i2c_addr, data, 1, 1);
}
if (res == I2C_ACK)
{
result = I2C_REGOP_SUCCESS;
}
else
{
result = I2C_REGOP_DEVICE_NACK;
}
return data[0];
}
/*=========================================================================
API 函数实现
-----------------------------------------------------------------------*/
void htr3236_init(htr3236_t *dev, uint8_t addr)
{
dev->i2c_addr = addr;
// 默认 SDB 拉高,使能芯片
//htr3236_hw_enable(dev);
}
void htr3236_hw_enable(htr3236_t *dev)
{
p_htr3235_sdb <: 1;
}
void htr3236_hw_disable(htr3236_t *dev)
{
p_htr3235_sdb <: 0;
}
int htr3236_software_wake(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c))
{
return write_reg(dev, i2c, HTR3236_REG_SHUTDOWN, HTR3236_NORMAL_OP);
}
int htr3236_software_shutdown(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c))
{
return write_reg(dev, i2c, HTR3236_REG_SHUTDOWN, HTR3236_SHUTDOWN_SOFT);
}
int htr3236_software_reset(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c))
{
return write_reg(dev, i2c, HTR3236_REG_RESET, 0x00);
}
int htr3236_set_pwm(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t channel, uint8_t brightness)
{
if (channel < 1 || channel > 36) {
return -1;
}
uint8_t reg = HTR3236_REG_PWM_START + (channel - 1);
return write_reg(dev, i2c, reg, brightness);
}
int htr3236_set_pwm_bulk(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t start_ch,
const uint8_t *values, uint8_t len)
{
if (start_ch < 1 || start_ch > 36 || len == 0) {
return -1;
}
// 检查是否会超出寄存器范围
if (start_ch + len - 1 > 36) {
return -1;
}
uint8_t start_reg = HTR3236_REG_PWM_START + (start_ch - 1);
return write_reg_bulk(dev, i2c, start_reg, values, len);
}
int htr3236_set_led_config(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t channel,
htr3236_current_t current, uint8_t enable)
{
if (channel < 1 || channel > 36) {
return -1;
}
uint8_t reg = HTR3236_REG_LED_CTRL_START + (channel - 1);
uint8_t data = (enable ? 1 : 0) | (current << 1);
return write_reg(dev, i2c, reg, data);
}
int htr3236_set_led_config_bulk(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t start_ch,
const uint8_t *configs, uint8_t len)
{
if (start_ch < 1 || start_ch > 36 || len == 0) {
return -1;
}
// 检查是否会超出寄存器范围
if (start_ch + len - 1 > 36) {
return -1;
}
uint8_t start_reg = HTR3236_REG_LED_CTRL_START + (start_ch - 1);
return write_reg_bulk(dev, i2c, start_reg, configs, len);
}
int htr3236_update(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c))
{
// 写入任意值到更新寄存器使配置生效
return write_reg(dev, i2c, HTR3236_REG_PWM_UPDATE, 0x00);
}
int htr3236_global_enable(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t enable)
{
uint8_t data = enable ? 1 : 0;
return write_reg(dev, i2c, HTR3236_REG_GLOBAL_CTRL, data);
}
int htr3236_set_frequency(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), htr3236_freq_t freq)
{
uint8_t data = (freq == HTR3236_FREQ_22KHZ) ? 1 : 0;
return write_reg(dev, i2c, HTR3236_REG_FREQ_SET, data);
}
uint8_t htr3236_gamma_32(uint8_t index)
{
if (index >= 32) {
index = 31;
}
return gamma_table_32[index];
}
uint8_t htr3236_gamma_64(uint8_t index)
{
if (index >= 64) {
index = 63;
}
return gamma_table_64[index];
}

View File

@@ -1,331 +0,0 @@
/**
* @file led_control.c
* @brief LED控制API实现 (基于HTR3236)
* @version 1.0
*/
#include "led_control.h"
#include <string.h>
#include <math.h>
#include <timer.h>
/*=========================================================================
内部函数
-----------------------------------------------------------------------*/
/**
* @brief 检查LED ID是否有效
*/
static int is_valid_led(led_id_t led)
{
return (led >= 1 && led <= 36 && led != 36); // OUT36未使用
}
/**
* @brief 获取LED组起始和结束索引
*/
static void get_group_range(led_group_t group, uint8_t *start, uint8_t *end)
{
switch (group) {
case LED_GROUP_L_SERIES:
*start = LED_L1;
*end = LED_L15;
break;
case LED_GROUP_D_SERIES:
*start = LED_D1;
*end = LED_D15;
break;
// case LED_GROUP_FUNCTION:
// *start = LED_ANC;
// *end = LED_GAME_MODE;
// break;
case LED_GROUP_ALL:
default:
*start = 1;
*end = 35; // 排除OUT36
break;
}
}
/*=========================================================================
LED物理映射表
-----------------------------------------------------------------------*/
// 根据测试结果LED_L1-L15的实际OUT口
const uint8_t led_l_physical_map[15] = {
15, // LED_L1 -> OUT15
14, // LED_L2 -> OUT14
13, // LED_L3 -> OUT13
11, // LED_L4 -> OUT11
10, // LED_L5 -> OUT10
9, // LED_L6 -> OUT9
8, // LED_L7 -> OUT8
7, // LED_L8 -> OUT7
6, // LED_L9 -> OUT6
5, // LED_L10 -> OUT5
4, // LED_L11 -> OUT4
12, // LED_L12 -> OUT12 *
18, // LED_L13 -> OUT18 *
17, // LED_L14 -> OUT17
16, // LED_L15 -> OUT16
};
// 根据测试结果LED_D1-D15的实际OUT口
const uint8_t led_d_physical_map[15] = {
21, // LED_D1 -> OUT21
20, // LED_D2 -> OUT20
19, // LED_D3 -> OUT19
26, // LED_D4 -> OUT26 *
33, // LED_D5 -> OUT33 *
32, // LED_D6 -> OUT32
31, // LED_D7 -> OUT31
30, // LED_D8 -> OUT30
29, // LED_D9 -> OUT29
28, // LED_D10 -> OUT28
27, // LED_D11 -> OUT27
25, // LED_D12 -> OUT25
24, // LED_D13 -> OUT24
23, // LED_D14 -> OUT23
22, // LED_D15 -> OUT22
};
// 改动原因:按 SY102mic音量对应表.csv将麦克风音量等级改为 49 级(0~48),最大增益改为 24dB
// LED档位按表中“旋钮刻度49级 + LED灯15个”的分段阈值重建。
const uint8_t mic_gain_to_led[49] = {
0, // [0] mute
1, // [1]
1, // [2]
1, // [3]
2, // [4]
2, // [5]
2, // [6]
3, // [7]
3, // [8]
3, // [9]
4, // [10]
4, // [11]
4, // [12]
5, // [13]
5, // [14]
5, // [15]
6, // [16]
6, // [17]
6, // [18]
7, // [19]
7, // [20]
7, // [21]
8, // [22]
8, // [23]
8, // [24]
9, // [25]
9, // [26]
9, // [27]
10, // [28]
10, // [29]
10, // [30]
11, // [31]
11, // [32]
11, // [33]
12, // [34]
12, // [35]
12, // [36]
13, // [37]
13, // [38]
13, // [39]
13, // [40]
14, // [41]
14, // [42]
14, // [43]
14, // [44]
15, // [45]
15, // [46]
15, // [47]
15 // [48] max 24dB
};
// 改动原因:按 SY102dac对应表.csv将DAC音量等级改为 49 级(0~48)
// LED分段阈值按“旋钮48格 + 15灯”映射重建确保HID 0x93新范围显示一致。
const uint8_t dac_gain_to_led[49] = {
0, // [0] mute
1, // [1]
1, // [2]
1, // [3]
2, // [4]
2, // [5]
2, // [6]
3, // [7]
3, // [8]
3, // [9]
4, // [10]
4, // [11]
4, // [12]
5, // [13]
5, // [14]
5, // [15]
6, // [16]
6, // [17]
6, // [18]
7, // [19]
7, // [20]
7, // [21]
8, // [22]
8, // [23]
8, // [24]
9, // [25]
9, // [26]
9, // [27]
10, // [28]
10, // [29]
10, // [30]
11, // [31]
11, // [32]
11, // [33]
12, // [34]
12, // [35]
12, // [36]
13, // [37]
13, // [38]
13, // [39]
13, // [40]
14, // [41]
14, // [42]
14, // [43]
14, // [44]
15, // [45]
15, // [46]
15, // [47]
15, // [48]
};
/*=========================================================================
内部函数 - 获取实际OUT口
-----------------------------------------------------------------------*/
static uint8_t get_physical_out(led_id_t led)
{
// 如果是L系列LED
if (led >= LED_L1 && led <= LED_L15) {
uint8_t index = led - LED_L1;
return led_l_physical_map[index];
}
else if (led >= LED_D1 && led <= LED_D15) {
uint8_t index = led - LED_D1;
return led_d_physical_map[index];
}
// 其他LED直接返回原值
return (uint8_t)led;
}
/*=========================================================================
基础控制API实现
-----------------------------------------------------------------------*/
void led_control_init(led_control_t *ctx,
htr3236_t *dev,
CLIENT_INTERFACE(i2c_master_if,i2c))
{
ctx->htr3236_dev = dev;
ctx->i2c = i2c;
// 初始化亮度缓存
memset(ctx->brightness, 0, sizeof(ctx->brightness));
// 配置所有LED通道的电流 (使用IMAX/2)
for (int led = 1; led <= 35; led++) { // 跳过OUT36
htr3236_set_led_config(ctx->htr3236_dev, ctx->i2c,
led, HTR3236_CURRENT_HALF, 1);
}
// 初始关闭所有LED
for (int led = 1; led <= 35; led++) {
htr3236_set_pwm(ctx->htr3236_dev, ctx->i2c, led, 0);
}
htr3236_update(ctx->htr3236_dev, ctx->i2c);
}
int led_set_brightness(led_control_t *ctx,
led_id_t led,
uint8_t brightness)
{
if (!is_valid_led(led)) {
return -1;
}
ctx->brightness[led - 1] = brightness;
return htr3236_set_pwm(ctx->htr3236_dev, ctx->i2c, led, brightness);
}
int led_on(led_control_t *ctx, led_id_t led)
{
return led_set_brightness(ctx, led, 30/*255*/);
}
int led_off(led_control_t *ctx, led_id_t led)
{
return led_set_brightness(ctx, led, 0);
}
int led_toggle(led_control_t *ctx, led_id_t led)
{
if (!is_valid_led(led)) {
return -1;
}
uint8_t new_brightness = (ctx->brightness[led - 1] == 0) ? 255 : 0;
return led_set_brightness(ctx, led, new_brightness);
}
int led_update_all(led_control_t *ctx)
{
return htr3236_update(ctx->htr3236_dev, ctx->i2c);
}
/*=========================================================================
组控制API实现
-----------------------------------------------------------------------*/
int led_group_set_brightness(led_control_t *ctx,
led_group_t group,
uint8_t brightness)
{
uint8_t start, end;
get_group_range(group, &start, &end);
if (group == LED_GROUP_FUNCTION) {
// 功能LED需要单独处理每个LED
led_id_t function_leds[] = {
LED_MUSIC, LED_ANC, LED_FOOTSTEP_MODE, LED_AI7_1, LED_GAME_MODE
};
for (int i = 0; i < 5; i++) {
led_id_t led = function_leds[i];
uint8_t physical_out = get_physical_out(led); // 如果有映射
ctx->brightness[physical_out - 1] = brightness;
htr3236_set_pwm(ctx->htr3236_dev, ctx->i2c, led, brightness);
}
}
else
{
for (uint8_t led = start; led <= end; led++) {
if (led == 36) continue; // 跳过未使用的OUT36
if((group == LED_GROUP_L_SERIES) || (group == LED_GROUP_D_SERIES))
{
uint8_t physical_out = get_physical_out(led);
ctx->brightness[physical_out - 1] = brightness;
}
else ctx->brightness[led - 1] = brightness;
htr3236_set_pwm(ctx->htr3236_dev, ctx->i2c, led, brightness);
}
}
return htr3236_update(ctx->htr3236_dev, ctx->i2c);
}
int led_group_on(led_control_t *ctx, led_group_t group)
{
return led_group_set_brightness(ctx, group, 255);
}
int led_group_off(led_control_t *ctx, led_group_t group)
{
return led_group_set_brightness(ctx, group, 0);
}

View File

@@ -24,6 +24,8 @@
#endif
#include "uac_hwresources.h"
/* 改动原因:引入 C1 面板 LED 控制 interface 声明user_main.h供 main 中声明 interface 实例并连接 AudioHwRemote / app_control_slave。 */
#include "user_main.h"
#ifdef IAP
#include "i2c_shared.h"
@@ -429,26 +431,31 @@ extern void SetEx3dHidChan (chanend c);
extern int dsp_worker_tile(chanend c_dsp_to_ex3d, int worker_id);
//extern int dsp_worker_tile_1(chanend c_dsp_to_ex3d, int worker_id);
extern void ex3d_task();
extern void ex3d_task(chanend c_ex3d_to_ubm);
extern void hid_button_task(chanend cc_mic_level, chanend c_hid, chanend c_hidSendData, chanend c_uac_vol, chanend c_ex3d_hid_cmd);
/* 改动原因:与 audiohw.xc 中 AudioHwRemote 一致。HID/音量/MIC 检测等已迁到 tile1 hid_button_task 与 AudioHwRemote2 内物理口;
* codec 仅经 streaming c_audiohwDFU 命令经 c_dfu仅 HID_DFU_EN=1。 */
#if HID_DFU_EN
extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, streaming chanend c_dfu_rx, chanend c_mic_det);
extern void AudioHwRemote(streaming chanend c_audiohw_rx, client interface c1_led_ctrl_if i_c1_led_ctrl, streaming chanend c_dfu_rx);
#else
extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, chanend c_mic_det);
extern void AudioHwRemote(streaming chanend c_audiohw_rx, client interface c1_led_ctrl_if i_c1_led_ctrl);
#endif
extern void dnr_dsp_proc_task(void);
extern unsafe chanend uc_dsp_to_ex3d[DSP_WORKER_COUNT];
extern unsafe chanend uc_dsp_to_dnr_t1;
extern unsafe chanend uc_key_to_ubm_t0;
extern unsafe chanend uc_audiohw;
extern streaming unsafe chanend uc_audiohw;
#if HID_DFU_EN
extern unsafe streaming chanend uc_dfu;
#endif
extern void key_sender(chanend c_key);
extern void key_receiver(chanend c_key);
extern void mute_handler(chanend c_mic_det);
extern void SetEx3dToUbmChan (chanend c);
/* 改动原因main 绑定 uc_audiohw 后写 1供 AudioHwInit 自旋等待(定义在 audiohw.xc消除与 usb_audio_io 的启动竞态。 */
extern unsigned g_uc_audiohw_chan_bound;
/* Main for USB Audio Applications */
int main()
@@ -541,8 +548,8 @@ int main()
USER_MAIN_DECLARATIONS
chan c_dsp_to_ex3d[DSP_WORKER_COUNT];
chan cc_mic_level;
chan c_audiohw;
// chan cc_mic_level;
streaming chan c_audiohw;
#if HID_DFU_EN
streaming chan c_dfu;
#endif
@@ -551,7 +558,10 @@ int main()
chan c_eq_data;
chan c_uac_vol;
chan c_ex3d_hid_cmd;
chan c_mic_det;
chan c_ex3d_to_ubm;
/* 改动原因MIC 插拔检测已并入 audiohw.xcp_mic_phone_detect / AudioHwRemote2删除未使用 c_mic_det。
* C1 面板灯tile0 AudioHwRemote 为 c1_led_ctrl_if clienttile1 app_control_slave 为 server。 */
interface c1_led_ctrl_if i_c1_led_ctrl;
par
{
@@ -559,42 +569,54 @@ int main()
on tile[1] : {
par {
unsafe {
uc_audiohw = (chanend)c_audiohw;
#if EQ_EN == 1 && USE_EX3D == 0
SetEqDataChan(c_eq_data);
#endif
hid_button_task(cc_mic_level, c_hidRcvData, c_hidSendData, c_uac_vol, c_ex3d_hid_cmd);
// hid_button_task(cc_mic_level, c_hidRcvData, c_hidSendData, c_uac_vol, c_ex3d_hid_cmd);
}
#if USE_EX3D == 1
par(int i = 0; i < DSP_WORKER_COUNT; i++)
dsp_worker_tile(c_dsp_to_ex3d[i], i);
unsafe {
SetEqDataChan(c_eq_data);
delay_milliseconds(200);
key_sender(c_key);
for (int i = 0; i < DSP_WORKER_COUNT; i++)
uc_dsp_to_ex3d[i] = (chanend)c_dsp_to_ex3d[i];
ex3d_task();
ex3d_task(c_ex3d_to_ubm);
}
#endif
}
}
on tile[1]: mute_handler(c_mic_det);
/* 改动原因C1 硬件插拔检测与 DAC/MIC 哑音逻辑已并入 tile0 button_task见 audiohw.xc不再使用原 mute_handler + p_ctl_det 方案。 */
on tile[1]: app_control_slave(i_c1_led_ctrl);
/* 改动原因XUA_AudioHub 与 AudioHwRemote/dsp 并行启动AudioHwInit→codec_init 经 CODEC_REGWRITE 使用 uc_audiohw。
* 若仅在 dsp_main 内赋值AudioHub 先跑到 codec_init 时 uc_audiohw 未绑定会 ET_ILLEGAL_RESOURCE。
* 与 fosi_c1 user_main.h 一致:在 tile[0]、启动 AudioHwRemote 之前绑定 streaming chan 发送端句柄。 */
on tile[0] : {
unsafe {
uc_audiohw = (streaming chanend)c_audiohw;
g_uc_audiohw_chan_bound = 1;
}
par {
{
/* 改动原因:参数顺序与类型对齐 audiohw.xc 的 AudioHwRemote修复链接阶段符号类型不一致。 */
{
unsafe {
SetEqDataChan(c_eq_data);
SetEx3dToUbmChan(c_ex3d_to_ubm);
}
#if USE_EX3D == 1
unsafe { key_receiver(c_key); }
#endif
AudioHwRemote(c_hidSendData, cc_mic_level, c_uac_vol, c_audiohw
#if HID_DFU_EN
, c_dfu
AudioHwRemote(c_audiohw, i_c1_led_ctrl, c_dfu);
#else
AudioHwRemote(c_audiohw, i_c1_led_ctrl);
#endif
, c_mic_det
);
}
}
}
}
@@ -611,6 +633,7 @@ int main()
dsp_core0();
}
}
/* 改动原因uc_audiohw 已在上文 tile[0] AudioHwRemote 父块入口绑定,此处删除重复赋值,避免误读为唯一初始化点。 */
on tile[0] : { dsp_main(c_eq_data); }
#endif

View File

@@ -263,3 +263,35 @@ void save_userconfig_info(unsigned char *buffer)
{
memcpy((unsigned char *)&appUserConf, buffer, sizeof(appUserConf));
}
unsigned char g_hid_pass_data[64];
/* 改动原因:固件升级开始/结束时通知 MCU0=无1=升级开始2=升级结束成功3=升级结束(中止/失败)。
* 由 dfu_upgrade.c 在 handle_firmware_upgrade_start/end/abort 中设置uart_handler 在 se_tmr 中读取并发送 0x62 串口包后清零。 */
unsigned g_firmware_upgrade_mcu_notify = 0;
/* 改动原因:标记是否处于固件升级中,供 uart_handler 跳过 heatTick 等START 时置 1END/ABORT 时置 0。由 dfu_upgrade.c 设置。 */
unsigned g_in_fw_upgrade = 0;
extern void hidSetChangePending(unsigned int);
void user_read_hidpass(unsigned char * hidPassData)
{
int i = 0;
for (i = 0; i < 64; i++)
{
hidPassData[i] = g_hid_pass_data[i];
debug_printf("hidPassData[%d] = %02x\n", i, hidPassData[i]);
g_hid_pass_data[i] = 0;
}
}
void user_set_hidpass(unsigned char *data)
{
#if HID_CONTROLS
for (int i = 0; i < 63; i++)
{
g_hid_pass_data[i] = data[i];
debug_printf("g_hid_pass_data[%d] = %02x\n", i, g_hid_pass_data[i]);
}
hidSetChangePending(0x1);
#endif
}

View File

@@ -10,9 +10,17 @@
#include <platform.h>
#include "DSBuild.h"
/* 改动原因:与 fosi_c1 一致mode/mic 物理灯在 tile[1]tile[0] 的 button_task 通过 client interface 下发状态,由 app_control_slave 统一驱动 GPIO。 */
interface c1_led_ctrl_if {
void set_mode_led_color(unsigned color_idx);
void set_mic_mute_state(unsigned mute_switch);
void set_mic_voice_fx(unsigned voice_fx_enabled);
};
#define USER_MAIN_DECLARATIONS \
void app_control_slave(server interface c1_led_ctrl_if i_c1_led_ctrl);
/* 改动原因v71 main.xc 自行展开任务拓扑,此处不注入额外 chan/interface 声明,避免宏续行空定义导致预处理异常。 */
#define USER_MAIN_DECLARATIONS
#endif // __XC__