led working
This commit is contained in:
@@ -45,8 +45,8 @@
|
|||||||
</Tile>
|
</Tile>
|
||||||
|
|
||||||
<Tile Number="1" Reference="tile[1]">
|
<Tile Number="1" Reference="tile[1]">
|
||||||
<Port Location="XS1_PORT_1A" Name="PORT_UART_RX"/>
|
<!-- 改动原因:删除原 fosi_c1 的 PORT_UART_RX/TX(1A/1K),与 jok LED/HTR3236 引脚冲突;
|
||||||
<Port Location="XS1_PORT_1K" Name="PORT_UART_TX"/>
|
UART 曾占用 1K 会导致 SDB 拉低,I2C 有应答但 RGB 不亮 -->
|
||||||
<!-- 改动原因:与 jok.xn 对齐,功放静音控制 (tx1_led_helper p_ctl_mute) -->
|
<!-- 改动原因:与 jok.xn 对齐,功放静音控制 (tx1_led_helper p_ctl_mute) -->
|
||||||
<Port Location="XS1_PORT_1F" Name="PORT_CTL_MUTE"/>
|
<Port Location="XS1_PORT_1F" Name="PORT_CTL_MUTE"/>
|
||||||
<!-- HRT3236 -->
|
<!-- HRT3236 -->
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "debug_print.h"
|
#include "debug_print.h"
|
||||||
#include "user_uart.h"
|
#include "user_uart.h"
|
||||||
#include "htr3236.h"
|
#include "htr3236.h"
|
||||||
|
#include "tx1_led_effects.h"
|
||||||
#include "eq_flash_storage.h"
|
#include "eq_flash_storage.h"
|
||||||
#include "lfs_io.h"
|
#include "lfs_io.h"
|
||||||
#include "roleswitchflag.h"
|
#include "roleswitchflag.h"
|
||||||
@@ -29,6 +30,8 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define TIMER_PERIOD 2000000
|
#define TIMER_PERIOD 2000000
|
||||||
|
/* 改动原因:与 jok TIMER_2_PERIOD 一致,50ms 驱动 RGB 灯效/工厂复位 LED */
|
||||||
|
#define TIMER_2_PERIOD 5000000
|
||||||
|
|
||||||
#define DISABLE_REBOOT 1
|
#define DISABLE_REBOOT 1
|
||||||
|
|
||||||
@@ -94,6 +97,8 @@ unsigned g_hid_expand_gain_request = (unsigned)-1;
|
|||||||
unsigned g_hid_lmt_threshold_request = (unsigned)-1;
|
unsigned g_hid_lmt_threshold_request = (unsigned)-1;
|
||||||
unsigned g_hid_angle_values[C1_EX3D_ANGLE_CHANNELS] = {0};
|
unsigned g_hid_angle_values[C1_EX3D_ANGLE_CHANNELS] = {0};
|
||||||
unsigned g_request_factory_reset = 0;
|
unsigned g_request_factory_reset = 0;
|
||||||
|
/* 改动原因:HTR3236 bringup 须在 codec_init 完成之后执行,避免与 NAU88 I2C 抢线/阻塞 */
|
||||||
|
unsigned g_audiohw_codec_init_done = 0;
|
||||||
|
|
||||||
// CODEC I2C lines
|
// CODEC I2C lines
|
||||||
on tile[0]: port p_scl = PORT_I2C_SCL;
|
on tile[0]: port p_scl = PORT_I2C_SCL;
|
||||||
@@ -110,13 +115,17 @@ on tile[0]: out port p_led_tile0 = PORT_LED_D10_8_11_9; // 8D bit7-4 = D10/D8/D
|
|||||||
|
|
||||||
// TX1 HTR3236 RGB LED driver control - declared in tx1_led_helper.xc
|
// TX1 HTR3236 RGB LED driver control - declared in tx1_led_helper.xc
|
||||||
|
|
||||||
// TX1 Button bit masks
|
// TX1 原理图位掩码(与 jok buttons.h BIT_* 一致,接在 4F/4E 端口上)
|
||||||
#define TX1_BIT_FPS_MODE (1<<3) // 4F bit3
|
#define TX1_BIT_FPS_MODE (1<<3) // 4F bit3
|
||||||
#define TX1_BIT_GAME_MODE (1<<2) // 4F bit2
|
#define TX1_BIT_GAME_MODE (1<<2) // 4F bit2
|
||||||
#define TX1_BIT_MIC_MUTE (1<<1) // 4F bit1
|
#define TX1_BIT_MIC_MUTE (1<<1) // 4F bit1
|
||||||
#define TX1_BIT_VOL_PLUS (1<<3) // 4E bit3
|
#define TX1_BIT_VOL_PLUS (1<<3) // 4E bit3
|
||||||
#define TX1_BIT_VOL_MINUS (1<<2) // 4E bit2
|
#define TX1_BIT_VOL_MINUS (1<<2) // 4E bit2
|
||||||
|
|
||||||
|
/* 改动原因:与 jok PCB 相同,面板从左到右为 FPS / VOL+ / VOL- / GAME / MIC,
|
||||||
|
* 原理图端口位序不同。采用 lib_board_support buttons.xc #else 映射(非 #if 0 原理图直读)。 */
|
||||||
|
#define TX1_BUTTON_MAP_PANEL_LAYOUT (0)
|
||||||
|
|
||||||
// TX1 Button timing thresholds (in 50ms ticks)
|
// TX1 Button timing thresholds (in 50ms ticks)
|
||||||
#define TX1_SHORT_PRESS_TICKS 1 // 50ms minimum press
|
#define TX1_SHORT_PRESS_TICKS 1 // 50ms minimum press
|
||||||
#define TX1_LONG_PRESS_TICKS 20 // 1s = 20 * 50ms
|
#define TX1_LONG_PRESS_TICKS 20 // 1s = 20 * 50ms
|
||||||
@@ -376,75 +385,101 @@ void mic_volume(unsigned level, client interface i2c_master_if i2c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 改动原因:按 phaten_golden_6ch/audiohw.xc 流程初始化——先 SDB 使能并延时,再 wake/freq/通道配置,
|
/* 改动原因:jok 默认 10 过暗肉眼难辨;自检/灯效用 80,音量条仍可用较低亮度 */
|
||||||
* 带 I2C 重试。xC 禁止 client interface 全局变量,SDB 在本函数内直接用 led_if 控制(不经 htr3236_hw_enable)。 */
|
#define TX1_RGB_GLOBAL_BRIGHTNESS 40
|
||||||
|
#define TX1_RGB_SELFTEST_BRIGHTNESS 200
|
||||||
|
#define TX1_RGB_SCALE8(c) ((uint8_t)(((unsigned)(c) * TX1_RGB_GLOBAL_BRIGHTNESS) / 255))
|
||||||
|
|
||||||
|
/* 改动原因:bringup 失败时灯效任务不刷屏 I2C */
|
||||||
|
static unsigned g_htr3236_ready = 0;
|
||||||
|
|
||||||
|
// RGB LED to HTR3236 OUT channel mapping (D1-D12),须在 bringup 自检前定义
|
||||||
|
static const uint8_t rgb_led_map[13][3] = {
|
||||||
|
{0, 0, 0},
|
||||||
|
{24, 23, 22}, {21, 20, 19}, {18, 17, 16}, {15, 14, 13},
|
||||||
|
{12, 11, 10}, {9, 8, 7}, {6, 5, 4}, {3, 2, 1},
|
||||||
|
{36, 35, 34}, {33, 32, 31}, {30, 29, 28}, {27, 26, 25}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 改动原因:与 jok tile1_io_control_task 相同,仅 tile1 1K 拉高 SDB,勿动 tile0 8C(非 SDB) */
|
||||||
|
static void tx1_htr3236_sdb_enable(client interface tx1_led_if led_if)
|
||||||
|
{
|
||||||
|
led_if.set_htr3236_sdb(1);
|
||||||
|
delay_milliseconds(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 改动原因:按 jok rgb_led 流程 D1-D12 白灯自检,最后统一 UPDATE */
|
||||||
|
static void tx1_htr3236_self_test_rgb(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
uint8_t led;
|
||||||
|
for (led = 1; led <= 12; led++) {
|
||||||
|
htr3236_set_pwm(dev, i2c, rgb_led_map[led][0], TX1_RGB_SELFTEST_BRIGHTNESS);
|
||||||
|
htr3236_set_pwm(dev, i2c, rgb_led_map[led][1], TX1_RGB_SELFTEST_BRIGHTNESS);
|
||||||
|
htr3236_set_pwm(dev, i2c, rgb_led_map[led][2], TX1_RGB_SELFTEST_BRIGHTNESS);
|
||||||
|
}
|
||||||
|
htr3236_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 改动原因:按 jok + golden 流程;避开 AudioHwInit 与 codec 抢 I2C;读回 0x00 验证唤醒 */
|
||||||
static void tx1_htr3236_bringup(htr3236_t *dev, client interface i2c_master_if i2c,
|
static void tx1_htr3236_bringup(htr3236_t *dev, client interface i2c_master_if i2c,
|
||||||
client interface tx1_led_if led_if)
|
client interface tx1_led_if led_if)
|
||||||
{
|
{
|
||||||
int ch;
|
int ch;
|
||||||
unsigned retry;
|
unsigned retry;
|
||||||
uint8_t zeros[36];
|
int wake_ok = 0;
|
||||||
|
int freq_ok = 0;
|
||||||
|
|
||||||
led_if.init();
|
g_htr3236_ready = 0;
|
||||||
led_if.set_htr3236_sdb(1);
|
|
||||||
delay_milliseconds(2);
|
/* 改动原因:上电已在 Remote2 入口拉过 SDB,此处仅再脉冲一次确保硬件退出关断 */
|
||||||
|
tx1_htr3236_sdb_enable(led_if);
|
||||||
|
|
||||||
htr3236_init(dev, HTR3236_ADDR_GND);
|
htr3236_init(dev, HTR3236_ADDR_GND);
|
||||||
|
debug_printf("HTR3236 addr 0x%02x (jok same HW)\n", dev->i2c_addr);
|
||||||
|
|
||||||
retry = 0;
|
for (retry = 0; retry < 10; retry++) {
|
||||||
while (htr3236_software_wake(dev, i2c) != I2C_REGOP_SUCCESS && retry < 10) {
|
if (htr3236_software_wake(dev, i2c) == I2C_REGOP_SUCCESS) {
|
||||||
retry++;
|
wake_ok = 1;
|
||||||
delay_milliseconds(1);
|
break;
|
||||||
debug_printf("HTR3236 wake retry %u\n", retry);
|
}
|
||||||
|
delay_milliseconds(2);
|
||||||
|
htr3236_software_reset(dev, i2c);
|
||||||
|
delay_milliseconds(2);
|
||||||
|
debug_printf("HTR3236 wake retry %u\n", retry + 1);
|
||||||
}
|
}
|
||||||
if (retry >= 10) {
|
if (!wake_ok) {
|
||||||
debug_printf("HTR3236 LED driver wake failed\n");
|
debug_printf("HTR3236 wake FAILED (no I2C ACK, check SDB+addr)\n");
|
||||||
} else {
|
return;
|
||||||
debug_printf("HTR3236 LED driver wake ok\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retry = 0;
|
debug_printf("HTR3236 wake ok\n");
|
||||||
while (htr3236_set_frequency(dev, i2c, HTR3236_FREQ_22KHZ) != I2C_REGOP_SUCCESS && retry < 10) {
|
|
||||||
retry++;
|
|
||||||
delay_milliseconds(1);
|
|
||||||
debug_printf("HTR3236 freq retry %u\n", retry);
|
|
||||||
}
|
|
||||||
if (retry >= 10) {
|
|
||||||
debug_printf("HTR3236 set frequency failed\n");
|
|
||||||
} else {
|
|
||||||
debug_printf("HTR3236 set frequency ok\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ch = 1; ch <= 35; ch++) {
|
for (retry = 0; retry < 10; retry++) {
|
||||||
|
if (htr3236_set_frequency(dev, i2c, HTR3236_FREQ_22KHZ) == I2C_REGOP_SUCCESS) {
|
||||||
|
freq_ok = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delay_milliseconds(2);
|
||||||
|
debug_printf("HTR3236 freq retry %u\n", retry + 1);
|
||||||
|
}
|
||||||
|
if (!freq_ok) {
|
||||||
|
debug_printf("HTR3236 set frequency FAILED\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
debug_printf("HTR3236 set frequency ok\n");
|
||||||
|
|
||||||
|
/* 改动原因:与 jok xk_audio_316_mc_ab_board 一致,逐通道配置 LED 电流/使能 */
|
||||||
|
for (ch = 1; ch <= 36; ch++) {
|
||||||
htr3236_set_led_config(dev, i2c, ch, HTR3236_CURRENT_HALF, 1);
|
htr3236_set_led_config(dev, i2c, ch, HTR3236_CURRENT_HALF, 1);
|
||||||
}
|
}
|
||||||
htr3236_global_enable(dev, i2c, 1);
|
|
||||||
|
|
||||||
for (ch = 0; ch < 36; ch++) {
|
tx1_htr3236_self_test_rgb(dev, i2c);
|
||||||
zeros[ch] = 0;
|
debug_printf("HTR3236 self-test: D1-D12 white PWM=%u, hold 5s\n", TX1_RGB_SELFTEST_BRIGHTNESS);
|
||||||
}
|
delay_milliseconds(5000);
|
||||||
htr3236_set_pwm_bulk(dev, i2c, 1, zeros, 36);
|
|
||||||
htr3236_update(dev, i2c);
|
g_htr3236_ready = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RGB LED to HTR3236 OUT channel mapping (D1-D12)
|
|
||||||
// Each LED: {out_b, out_g, out_r}
|
|
||||||
static const uint8_t rgb_led_map[13][3] = {
|
|
||||||
{0, 0, 0}, // [0] invalid
|
|
||||||
{24, 23, 22}, // D1
|
|
||||||
{21, 20, 19}, // D2
|
|
||||||
{18, 17, 16}, // D3
|
|
||||||
{15, 14, 13}, // D4
|
|
||||||
{12, 11, 10}, // D5
|
|
||||||
{9, 8, 7}, // D6
|
|
||||||
{6, 5, 4}, // D7
|
|
||||||
{3, 2, 1}, // D8
|
|
||||||
{36, 35, 34}, // D9
|
|
||||||
{33, 32, 31}, // D10
|
|
||||||
{30, 29, 28}, // D11
|
|
||||||
{27, 26, 25} // D12
|
|
||||||
};
|
|
||||||
|
|
||||||
static void tx1_rgb_led_set(htr3236_t *dev, client interface i2c_master_if i2c,
|
static void tx1_rgb_led_set(htr3236_t *dev, client interface i2c_master_if i2c,
|
||||||
uint8_t led, uint8_t r, uint8_t g, uint8_t b)
|
uint8_t led, uint8_t r, uint8_t g, uint8_t b)
|
||||||
{
|
{
|
||||||
@@ -465,6 +500,73 @@ static void tx1_rgb_led_all_off(htr3236_t *dev, client interface i2c_master_if i
|
|||||||
htr3236_update(dev, i2c);
|
htr3236_update(dev, i2c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 改动原因:单颗 RGB 只写 PWM 寄存器,最后统一 htr3236_update(对照 ui_app 303-336 的 bulk 刷新) */
|
||||||
|
static void tx1_rgb_pwm_write_led(htr3236_t *dev, client interface i2c_master_if i2c,
|
||||||
|
uint8_t led, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
if (led < 1 || led > 12) return;
|
||||||
|
htr3236_set_pwm(dev, i2c, rgb_led_map[led][0], b);
|
||||||
|
htr3236_set_pwm(dev, i2c, rgb_led_map[led][1], g);
|
||||||
|
htr3236_set_pwm(dev, i2c, rgb_led_map[led][2], r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 改动原因:按 feature_mode + 音量格数刷新 HTR3236 D1-D12 音量条(jok ui_app led_ui 303-336) */
|
||||||
|
static void tx1_rgb_volume_bar_refresh(htr3236_t *dev, client interface i2c_master_if i2c,
|
||||||
|
tx1_feature_mode_t mode, unsigned feature_vol_0_12)
|
||||||
|
{
|
||||||
|
uint8_t zeros[36];
|
||||||
|
int i;
|
||||||
|
uint8_t led;
|
||||||
|
unsigned bar_level = 0;
|
||||||
|
uint8_t r = 0, g = 0, b = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 36; i++) zeros[i] = 0;
|
||||||
|
htr3236_set_pwm_bulk(dev, i2c, 1, zeros, 36);
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case FEATURE_MODE_SYSTEM_VOLUME: {
|
||||||
|
unsigned vol_pct;
|
||||||
|
GET_SHARED_GLOBAL(vol_pct, g_volume_level);
|
||||||
|
bar_level = (vol_pct * 12u) / 100u;
|
||||||
|
if (bar_level > 12) bar_level = 12;
|
||||||
|
r = TX1_RGB_SCALE8(255);
|
||||||
|
g = TX1_RGB_SCALE8(255);
|
||||||
|
b = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FEATURE_MODE_GUNSHOT_LEVEL:
|
||||||
|
bar_level = feature_vol_0_12;
|
||||||
|
if (bar_level > 12) bar_level = 12;
|
||||||
|
r = TX1_RGB_SCALE8(128);
|
||||||
|
g = 0;
|
||||||
|
b = TX1_RGB_SCALE8(128);
|
||||||
|
break;
|
||||||
|
case FEATURE_MODE_FOOTSTEPS_LEVEL:
|
||||||
|
bar_level = feature_vol_0_12;
|
||||||
|
if (bar_level > 12) bar_level = 12;
|
||||||
|
r = TX1_RGB_SCALE8(255);
|
||||||
|
g = TX1_RGB_SCALE8(165);
|
||||||
|
b = 0;
|
||||||
|
break;
|
||||||
|
case FEATURE_MODE_MIC_LEVEL:
|
||||||
|
bar_level = feature_vol_0_12;
|
||||||
|
if (bar_level > 12) bar_level = 12;
|
||||||
|
r = 0;
|
||||||
|
g = 0;
|
||||||
|
b = TX1_RGB_SCALE8(255);
|
||||||
|
break;
|
||||||
|
case FEATURE_MODE_NONE:
|
||||||
|
default:
|
||||||
|
htr3236_update(dev, i2c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (led = 1; led <= bar_level; led++) {
|
||||||
|
tx1_rgb_pwm_write_led(dev, i2c, led, r, g, b);
|
||||||
|
}
|
||||||
|
htr3236_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
void save_value(unsigned char * unsafe path, unsigned char value);
|
void save_value(unsigned char * unsafe path, unsigned char value);
|
||||||
unsigned char load_value(unsigned char * unsafe path);
|
unsigned char load_value(unsigned char * unsafe path);
|
||||||
/* 改动原因:c_dfu 仅接收 FIRMWARE_UPGRADE_START,在此线程执行 handle_firmware_upgrade_start。
|
/* 改动原因:c_dfu 仅接收 FIRMWARE_UPGRADE_START,在此线程执行 handle_firmware_upgrade_start。
|
||||||
@@ -481,7 +583,8 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
|
|||||||
unsigned eq_mode_time = 0;
|
unsigned eq_mode_time = 0;
|
||||||
unsigned se_time = 0;
|
unsigned se_time = 0;
|
||||||
unsigned se_count = 0;
|
unsigned se_count = 0;
|
||||||
timer tmr, se_tmr, eq_mode_timer, eq_sync_timer;
|
timer tmr, se_tmr, eq_mode_timer, eq_sync_timer, led_fx_tmr;
|
||||||
|
unsigned led_fx_time = 0;
|
||||||
unsigned eq_sync_time = 0;
|
unsigned eq_sync_time = 0;
|
||||||
unsigned old_format = 14;
|
unsigned old_format = 14;
|
||||||
unsigned unmute_dac_state;
|
unsigned unmute_dac_state;
|
||||||
@@ -520,13 +623,19 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
|
|||||||
eq_mode_time += EQ_MODE_DELAY;
|
eq_mode_time += EQ_MODE_DELAY;
|
||||||
eq_sync_timer :> eq_sync_time;
|
eq_sync_timer :> eq_sync_time;
|
||||||
eq_sync_time += EQ_SYNC_DELAY;
|
eq_sync_time += EQ_SYNC_DELAY;
|
||||||
|
led_fx_tmr :> led_fx_time;
|
||||||
|
led_fx_time += TIMER_2_PERIOD;
|
||||||
|
|
||||||
// TX1: Initialize tile[0] GPIO LEDs (all off, active low)
|
// TX1: Initialize tile[0] GPIO LEDs (all off, active low)
|
||||||
led_tile0_shadow = 0xF0;
|
led_tile0_shadow = 0xF0;
|
||||||
p_led_tile0 <: led_tile0_shadow;
|
p_led_tile0 <: led_tile0_shadow;
|
||||||
|
|
||||||
// TX1: tile[1] GPIO + HTR3236 SDB,再经 I2C 按 golden 流程配置 HTR3236
|
/* 改动原因:仅预拉 SDB;完整 bringup 在 codec_init 完成后执行(见 tmr 分支) */
|
||||||
tx1_htr3236_bringup(&htr3236_dev, i2c, led_if);
|
led_if.init();
|
||||||
|
tx1_htr3236_sdb_enable(led_if);
|
||||||
|
htr3236_init(&htr3236_dev, HTR3236_ADDR_GND);
|
||||||
|
|
||||||
|
unsigned htr3236_bringup_done = 0;
|
||||||
|
|
||||||
// TX1 button previous state (active low: 0=pressed, 1=released)
|
// TX1 button previous state (active low: 0=pressed, 1=released)
|
||||||
unsigned prev_fps = 1, prev_game = 1, prev_mic = 1;
|
unsigned prev_fps = 1, prev_game = 1, prev_mic = 1;
|
||||||
@@ -552,6 +661,7 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
|
|||||||
|
|
||||||
// TX1 LED effect state for game mode indicators
|
// TX1 LED effect state for game mode indicators
|
||||||
unsigned gpio_leds_dirty = 1; // refresh LEDs on first tick
|
unsigned gpio_leds_dirty = 1; // refresh LEDs on first tick
|
||||||
|
unsigned led_pattern_step = TX1_EFFECT_RACE; // 改动原因:BYPASS 下 RGB 装饰灯效,VOL++/VOL- 循环
|
||||||
|
|
||||||
#if HID_DFU_EN
|
#if HID_DFU_EN
|
||||||
firmware_upgrade_init();
|
firmware_upgrade_init();
|
||||||
@@ -594,6 +704,17 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
|
|||||||
uint32_t now, old_time;
|
uint32_t now, old_time;
|
||||||
time += TIMER_PERIOD;
|
time += TIMER_PERIOD;
|
||||||
unsigned dac_vol, adc_vol, dac_mode, new_dac_mode;
|
unsigned dac_vol, adc_vol, dac_mode, new_dac_mode;
|
||||||
|
unsigned codec_init_done;
|
||||||
|
|
||||||
|
/* 改动原因:codec_init 经 chan 在本任务处理;完成后再做 HTR3236,避免假成功 */
|
||||||
|
if (!htr3236_bringup_done) {
|
||||||
|
GET_SHARED_GLOBAL(codec_init_done, g_audiohw_codec_init_done);
|
||||||
|
if (codec_init_done) {
|
||||||
|
debug_printf("HTR3236 bringup start (after codec)\n");
|
||||||
|
tx1_htr3236_bringup(&htr3236_dev, i2c, led_if);
|
||||||
|
htr3236_bringup_done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
now = get_reference_time();
|
now = get_reference_time();
|
||||||
|
|
||||||
@@ -1054,15 +1175,27 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
|
|||||||
// ========== TX1 BUTTON SCANNING ==========
|
// ========== TX1 BUTTON SCANNING ==========
|
||||||
{
|
{
|
||||||
unsigned btn1, btn2;
|
unsigned btn1, btn2;
|
||||||
p_button_fps_game_mic :> btn1; // bit3=FPS, bit2=GAME, bit1=MIC
|
unsigned fps, game, mic, vol_plus, vol_minus;
|
||||||
p_button_vol :> btn2; // bit3=VOL+, bit2=VOL-
|
|
||||||
|
|
||||||
// Extract button states (active low: 0=pressed, 1=released)
|
p_button_fps_game_mic :> btn1;
|
||||||
unsigned fps = (btn1 & TX1_BIT_FPS_MODE) ? 1 : 0;
|
p_button_vol :> btn2;
|
||||||
unsigned game = (btn1 & TX1_BIT_GAME_MODE) ? 1 : 0;
|
|
||||||
unsigned mic = (btn1 & TX1_BIT_MIC_MUTE) ? 1 : 0;
|
/* 改动原因:低有效,1=弹起 0=按下;逻辑值 1=released 与 jok buttons.xc 一致 */
|
||||||
unsigned vol_plus = (btn2 & TX1_BIT_VOL_PLUS) ? 1 : 0;
|
#if TX1_BUTTON_MAP_PANEL_LAYOUT
|
||||||
unsigned vol_minus = (btn2 & TX1_BIT_VOL_MINUS) ? 1 : 0;
|
/* 面板位映射(jok buttons.xc #else):左→右 FPS, VOL+, VOL-, GAME, MIC */
|
||||||
|
vol_minus = (btn1 & TX1_BIT_FPS_MODE) ? 1 : 0;
|
||||||
|
vol_plus = (btn1 & TX1_BIT_GAME_MODE) ? 1 : 0;
|
||||||
|
fps = (btn1 & TX1_BIT_MIC_MUTE) ? 1 : 0;
|
||||||
|
mic = (btn2 & TX1_BIT_VOL_PLUS) ? 1 : 0;
|
||||||
|
game = (btn2 & TX1_BIT_VOL_MINUS) ? 1 : 0;
|
||||||
|
#else
|
||||||
|
/* 原理图直读(jok buttons.xc #if 0):4F=FPS/GAME/MIC, 4E=VOL+/VOL- */
|
||||||
|
fps = (btn1 & TX1_BIT_FPS_MODE) ? 1 : 0;
|
||||||
|
game = (btn1 & TX1_BIT_GAME_MODE) ? 1 : 0;
|
||||||
|
mic = (btn1 & TX1_BIT_MIC_MUTE) ? 1 : 0;
|
||||||
|
vol_plus = (btn2 & TX1_BIT_VOL_PLUS) ? 1 : 0;
|
||||||
|
vol_minus = (btn2 & TX1_BIT_VOL_MINUS) ? 1 : 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Combo key detection (highest priority)
|
// Combo key detection (highest priority)
|
||||||
tx1_combo_t new_combo = COMBO_NONE;
|
tx1_combo_t new_combo = COMBO_NONE;
|
||||||
@@ -1091,10 +1224,14 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
|
|||||||
gpio_leds_dirty = 1;
|
gpio_leds_dirty = 1;
|
||||||
debug_printf("TX1: GAME+MIC combo - high_perf_mode=%d\n", high_perf_mode);
|
debug_printf("TX1: GAME+MIC combo - high_perf_mode=%d\n", high_perf_mode);
|
||||||
} else if (current_combo == COMBO_VOL_UP_DOWN) {
|
} else if (current_combo == COMBO_VOL_UP_DOWN) {
|
||||||
// Cycle LED effects in BYPASS mode only
|
/* 改动原因:对照 jok on_combo_vol_up_down,BYPASS 下循环 RGB 灯效 */
|
||||||
if (game_mode == GAME_MODE_BYPASS && feature_mode == FEATURE_MODE_NONE) {
|
if (game_mode == GAME_MODE_BYPASS && feature_mode == FEATURE_MODE_NONE) {
|
||||||
// For now, just toggle feature mode indicator
|
led_pattern_step = (led_pattern_step + 1) % TX1_EFFECT_MAX;
|
||||||
debug_printf("TX1: VOL++VOL- combo - LED effect cycle\n");
|
debug_printf("TX1: VOL++VOL- combo - led_pattern_step=%u\n", led_pattern_step);
|
||||||
|
} else if (feature_mode != FEATURE_MODE_NONE) {
|
||||||
|
feature_mode = FEATURE_MODE_NONE;
|
||||||
|
feature_timeout_ticks = 0;
|
||||||
|
gpio_leds_dirty = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1114,24 +1251,29 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
|
|||||||
factory_reset_6s_fired = 0;
|
factory_reset_6s_fired = 0;
|
||||||
factory_reset_10s_fired = 0;
|
factory_reset_10s_fired = 0;
|
||||||
factory_reset_done = 0;
|
factory_reset_done = 0;
|
||||||
|
tx1_factory_reset_countdown_start();
|
||||||
debug_printf("TX1: Factory reset countdown started\n");
|
debug_printf("TX1: Factory reset countdown started\n");
|
||||||
} else if (!factory_reset_done) {
|
} else if (!factory_reset_done) {
|
||||||
unsigned elapsed = now - factory_reset_start_time;
|
unsigned elapsed = now - factory_reset_start_time;
|
||||||
if (elapsed >= 10600000000ull && !factory_reset_done) { // 10.6s
|
if (elapsed >= 10600000000ull && !factory_reset_done) { // 10.6s
|
||||||
factory_reset_done = 1;
|
factory_reset_done = 1;
|
||||||
|
tx1_factory_reset_triggered();
|
||||||
debug_printf("TX1: FACTORY RESET TRIGGERED!\n");
|
debug_printf("TX1: FACTORY RESET TRIGGERED!\n");
|
||||||
SET_SHARED_GLOBAL(g_request_factory_reset, 1);
|
SET_SHARED_GLOBAL(g_request_factory_reset, 1);
|
||||||
} else if (elapsed >= 10000000000ull && !factory_reset_10s_fired) {
|
} else if (elapsed >= 10000000000ull && !factory_reset_10s_fired) {
|
||||||
factory_reset_10s_fired = 1;
|
factory_reset_10s_fired = 1;
|
||||||
|
tx1_factory_reset_countdown_10s();
|
||||||
debug_printf("TX1: Factory reset 10s warning\n");
|
debug_printf("TX1: Factory reset 10s warning\n");
|
||||||
} else if (elapsed >= 6000000000ull && !factory_reset_6s_fired) {
|
} else if (elapsed >= 6000000000ull && !factory_reset_6s_fired) {
|
||||||
factory_reset_6s_fired = 1;
|
factory_reset_6s_fired = 1;
|
||||||
|
tx1_factory_reset_countdown_6s();
|
||||||
debug_printf("TX1: Factory reset 6s warning\n");
|
debug_printf("TX1: Factory reset 6s warning\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (factory_reset_counting) {
|
if (factory_reset_counting) {
|
||||||
factory_reset_counting = 0;
|
factory_reset_counting = 0;
|
||||||
|
tx1_factory_reset_cancel();
|
||||||
debug_printf("TX1: Factory reset cancelled\n");
|
debug_printf("TX1: Factory reset cancelled\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1328,9 +1470,35 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
|
|||||||
if (mic_muted) {
|
if (mic_muted) {
|
||||||
led_if.led_on(TX1_GPIO_LED_D2);
|
led_if.led_on(TX1_GPIO_LED_D2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 改动原因:HTR3236 RGB D1-D12 音量条;工厂复位灯效占用 RGB 时不刷条 */
|
||||||
|
if (g_htr3236_ready && !tx1_factory_reset_rgb_active()) {
|
||||||
|
tx1_rgb_volume_bar_refresh(&htr3236_dev, i2c, feature_mode, feature_volume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* 改动原因:第二定时器 50ms,移植 jok led_effects_period_update_task */
|
||||||
|
case led_fx_tmr when timerafter(led_fx_time) :> void :
|
||||||
|
if (g_htr3236_ready) {
|
||||||
|
unsigned gm;
|
||||||
|
static unsigned led_fx_dbg_cnt;
|
||||||
|
GET_SHARED_GLOBAL(gm, g_3d_fps);
|
||||||
|
tx1_led_effects_periodic(&htr3236_dev, i2c,
|
||||||
|
gm,
|
||||||
|
(unsigned)feature_mode,
|
||||||
|
led_pattern_step);
|
||||||
|
/* 改动原因:确认 50ms 灯效任务在跑;每约 5s 打一次 gm/fm/pattern */
|
||||||
|
led_fx_dbg_cnt++;
|
||||||
|
if ((led_fx_dbg_cnt % 100) == 1) {
|
||||||
|
debug_printf("led_fx gm=%u fm=%u pat=%u ready=%u\n",
|
||||||
|
gm, (unsigned)feature_mode, led_pattern_step, g_htr3236_ready);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
led_fx_time += TIMER_2_PERIOD;
|
||||||
|
break;
|
||||||
|
|
||||||
case se_tmr when timerafter(se_time) :> void :
|
case se_tmr when timerafter(se_time) :> void :
|
||||||
se_time += SE_DELAY;
|
se_time += SE_DELAY;
|
||||||
se_count ++;
|
se_count ++;
|
||||||
@@ -1426,8 +1594,8 @@ void AudioHwRemote(streaming chanend c, streaming chanend c_dfu, client interfac
|
|||||||
|
|
||||||
par
|
par
|
||||||
{
|
{
|
||||||
/* 改动原因:与 golden_6ch 一致使用 300kHz I2C,原 100kHz 非 HTR3236 失效主因但统一时序 */
|
/* 改动原因:与 jok xk_audio_316_mc_ab 一致 100kHz;300kHz 可能导致 HTR3236 长包异常 */
|
||||||
i2c_master(i2c, 1, p_scl, p_sda, 300);
|
i2c_master(i2c, 1, p_scl, p_sda, 100);
|
||||||
AudioHwRemote2(c, i2c[0], c_dfu, led_if);
|
AudioHwRemote2(c, i2c[0], c_dfu, led_if);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1438,8 +1606,8 @@ void AudioHwRemote(streaming chanend c, client interface tx1_led_if led_if)
|
|||||||
|
|
||||||
par
|
par
|
||||||
{
|
{
|
||||||
/* 改动原因:与 golden_6ch 一致使用 300kHz I2C,原 100kHz 非 HTR3236 失效主因但统一时序 */
|
/* 改动原因:与 jok xk_audio_316_mc_ab 一致 100kHz */
|
||||||
i2c_master(i2c, 1, p_scl, p_sda, 300);
|
i2c_master(i2c, 1, p_scl, p_sda, 100);
|
||||||
AudioHwRemote2(c, i2c[0], led_if);
|
AudioHwRemote2(c, i2c[0], led_if);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1478,11 +1646,13 @@ void AudioHwInit()
|
|||||||
|
|
||||||
codec_init();
|
codec_init();
|
||||||
|
|
||||||
debug_printf("AudioHwInit completed\n");
|
|
||||||
|
|
||||||
CODEC_REGWRITE(NAU88_I2C_DEVICE_ADDR, 0x0003, 0x0053);
|
CODEC_REGWRITE(NAU88_I2C_DEVICE_ADDR, 0x0003, 0x0053);
|
||||||
CODEC_REGWRITE(NAU88_I2C_DEVICE_ADDR, 0x002B, 0x4002);
|
CODEC_REGWRITE(NAU88_I2C_DEVICE_ADDR, 0x002B, 0x4002);
|
||||||
CODEC_REGWRITE(NAU88_I2C_DEVICE_ADDR, 0x002C, 0x0082);
|
CODEC_REGWRITE(NAU88_I2C_DEVICE_ADDR, 0x002C, 0x0082);
|
||||||
|
|
||||||
|
debug_printf("AudioHwInit completed\n");
|
||||||
|
/* 改动原因:全部 codec 寄存器写完后再置位,触发 HTR3236 bringup */
|
||||||
|
SET_SHARED_GLOBAL(g_audiohw_codec_init_done, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmute_dac(void)
|
void unmute_dac(void)
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ int htr3236_update(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c));
|
|||||||
/**
|
/**
|
||||||
* @brief 全局 LED 使能控制
|
* @brief 全局 LED 使能控制
|
||||||
* @param dev 设备结构体指针
|
* @param dev 设备结构体指针
|
||||||
* @param enable 1:关闭所有LED, 0:正常模式
|
* @param enable 1:正常输出, 0:关闭全部 36 路 LED(4Ah G_EN=1)
|
||||||
* @return 0:成功, -1:失败
|
* @return 0:成功, -1:失败
|
||||||
*/
|
*/
|
||||||
int htr3236_global_enable(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t enable);
|
int htr3236_global_enable(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t enable);
|
||||||
@@ -200,4 +200,7 @@ uint8_t htr3236_gamma_32(uint8_t index);
|
|||||||
*/
|
*/
|
||||||
uint8_t htr3236_gamma_64(uint8_t index);
|
uint8_t htr3236_gamma_64(uint8_t index);
|
||||||
|
|
||||||
|
/* 改动原因:bringup 读回 0x00 关断寄存器,确认 I2C 真连通且非 NACK 假象 */
|
||||||
|
int htr3236_read_reg(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t reg, uint8_t *value);
|
||||||
|
|
||||||
#endif /* HTR3236_H */
|
#endif /* HTR3236_H */
|
||||||
214
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/htr3236.xc
Normal file
214
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/htr3236.xc
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
/**
|
||||||
|
* @file htr3236.xc
|
||||||
|
* @brief HTR3236 36 路 LED PWM 驱动(与 phaten_golden_6ch 同源)
|
||||||
|
* @version 1.1
|
||||||
|
*
|
||||||
|
* 改动原因:与 jok 相同,SDB 仅 tile1 PORT_HTR3236_SDB(1K),由 tx1_led_if 控制,不在此操作 GPIO。
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "htr3236.h"
|
||||||
|
#include <xccompat.h>
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 改动原因:与 jok/htr3236 及 lib_i2c write_reg 一致,按字节数判断(100kHz 下更稳) */
|
||||||
|
unsafe {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
i2c.write(dev->i2c_addr, buf, len + 1, n, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
return I2C_REGOP_DEVICE_NACK;
|
||||||
|
}
|
||||||
|
if (n < (len + 1)) {
|
||||||
|
return I2C_REGOP_INCOMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return I2C_REGOP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void htr3236_init(htr3236_t *dev, uint8_t addr)
|
||||||
|
{
|
||||||
|
dev->i2c_addr = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 改动原因:jok 在 tile1_io_control_task 拉 SDB,此处保持空实现 */
|
||||||
|
void htr3236_hw_enable(htr3236_t *dev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void htr3236_hw_disable(htr3236_t *dev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
/* 改动原因:数据手册 4Ah D0——0=正常工作,1=关闭全部 LED;原 enable?1:0 会误关断 */
|
||||||
|
uint8_t data = enable ? 0 : 1;
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 改动原因:自检读 shutdown 寄存器,区分「I2C 有应答」与「芯片已唤醒」 */
|
||||||
|
int htr3236_read_reg(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t reg, uint8_t *value)
|
||||||
|
{
|
||||||
|
i2c_regop_res_t result;
|
||||||
|
|
||||||
|
if (value == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 改动原因:使用 lib_i2c 标准 read_reg(重复起始),与 jok 一致 */
|
||||||
|
unsafe {
|
||||||
|
*value = i2c.read_reg(dev->i2c_addr, reg, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == I2C_REGOP_SUCCESS) {
|
||||||
|
return I2C_REGOP_SUCCESS;
|
||||||
|
}
|
||||||
|
return I2C_REGOP_DEVICE_NACK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* @file tx1_led_effects.h
|
||||||
|
* @brief TX1 HTR3236 RGB 灯效与工厂复位 LED(移植自 jok led_effects.xc / ui_app.c)
|
||||||
|
*/
|
||||||
|
#ifndef TX1_LED_EFFECTS_H
|
||||||
|
#define TX1_LED_EFFECTS_H
|
||||||
|
|
||||||
|
#include "htr3236.h"
|
||||||
|
#include <i2c.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* 与 jok ui_app.h factory_reset_effect_state_t 一致 */
|
||||||
|
typedef enum {
|
||||||
|
TX1_FACTORY_RESET_IDLE = 0,
|
||||||
|
TX1_FACTORY_RESET_WAITING,
|
||||||
|
TX1_FACTORY_RESET_COUNTDOWN,
|
||||||
|
TX1_FACTORY_RESET_COUNTDOWN_2,
|
||||||
|
TX1_FACTORY_RESET_TRIGGERED
|
||||||
|
} tx1_factory_reset_state_t;
|
||||||
|
|
||||||
|
/* 与 jok led_effect_t 一致 */
|
||||||
|
typedef enum {
|
||||||
|
TX1_EFFECT_RACE = 0,
|
||||||
|
TX1_EFFECT_BREATH_ALL,
|
||||||
|
TX1_EFFECT_RAINBOW_RACE,
|
||||||
|
TX1_EFFECT_RAINBOW_FILL,
|
||||||
|
TX1_EFFECT_COLOR_WAVE,
|
||||||
|
TX1_EFFECT_STROBE,
|
||||||
|
TX1_EFFECT_PULSE,
|
||||||
|
TX1_EFFECT_SPARKLE,
|
||||||
|
TX1_EFFECT_GRADIENT,
|
||||||
|
TX1_EFFECT_MAX
|
||||||
|
} tx1_led_effect_t;
|
||||||
|
|
||||||
|
extern tx1_factory_reset_state_t g_tx1_factory_reset_state;
|
||||||
|
|
||||||
|
void tx1_factory_reset_countdown_start(void);
|
||||||
|
void tx1_factory_reset_countdown_6s(void);
|
||||||
|
void tx1_factory_reset_countdown_10s(void);
|
||||||
|
void tx1_factory_reset_triggered(void);
|
||||||
|
void tx1_factory_reset_cancel(void);
|
||||||
|
|
||||||
|
/* 改动原因:工厂复位灯效占用 RGB 时,gpio_leds_dirty 不应再刷音量条 */
|
||||||
|
unsigned tx1_factory_reset_rgb_active(void);
|
||||||
|
|
||||||
|
void tx1_factory_reset_led_tick(htr3236_t *dev, client interface i2c_master_if i2c);
|
||||||
|
|
||||||
|
/* 改动原因:50ms 定时器入口,对照 jok led_effects_period_update_task */
|
||||||
|
void tx1_led_effects_periodic(htr3236_t *dev, client interface i2c_master_if i2c,
|
||||||
|
unsigned game_mode,
|
||||||
|
unsigned feature_mode,
|
||||||
|
unsigned led_pattern_step);
|
||||||
|
|
||||||
|
#endif /* TX1_LED_EFFECTS_H */
|
||||||
@@ -0,0 +1,414 @@
|
|||||||
|
/**
|
||||||
|
* @file tx1_led_effects.xc
|
||||||
|
* @brief HTR3236 RGB 灯效 + 工厂复位 LED(移植自 jok led_effects.xc,50ms 步进)
|
||||||
|
*/
|
||||||
|
#include "tx1_led_effects.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define TX1_RGB_LED_MAX 12
|
||||||
|
|
||||||
|
/* 改动原因:与 audiohw 提高后的亮度一致,否则灯效仍几乎不可见 */
|
||||||
|
/* 改动原因:与 bringup 自检亮度一致,便于肉眼确认灯效 */
|
||||||
|
#define TX1_FX_RGB_BRIGHTNESS 200
|
||||||
|
#define TX1_FX_SCALE8(c) ((uint8_t)(((unsigned)(c) * TX1_FX_RGB_BRIGHTNESS) / 255))
|
||||||
|
|
||||||
|
/* D1-D12 B,G,R 通道映射(与 audiohw rgb_led_map 相同) */
|
||||||
|
static const uint8_t tx1_rgb_led_map[13][3] = {
|
||||||
|
{0, 0, 0},
|
||||||
|
{24, 23, 22}, {21, 20, 19}, {18, 17, 16}, {15, 14, 13},
|
||||||
|
{12, 11, 10}, {9, 8, 7}, {6, 5, 4}, {3, 2, 1},
|
||||||
|
{36, 35, 34}, {33, 32, 31}, {30, 29, 28}, {27, 26, 25}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void tx1_fx_pwm_led(htr3236_t *dev, client interface i2c_master_if i2c,
|
||||||
|
uint8_t led, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
if (led < 1 || led > TX1_RGB_LED_MAX) return;
|
||||||
|
htr3236_set_pwm(dev, i2c, tx1_rgb_led_map[led][0], b);
|
||||||
|
htr3236_set_pwm(dev, i2c, tx1_rgb_led_map[led][1], g);
|
||||||
|
htr3236_set_pwm(dev, i2c, tx1_rgb_led_map[led][2], r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_fx_update(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
htr3236_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_fx_all_off(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
uint8_t zeros[36];
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 36; i++) zeros[i] = 0;
|
||||||
|
htr3236_set_pwm_bulk(dev, i2c, 1, zeros, 36);
|
||||||
|
htr3236_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_fx_all_color(htr3236_t *dev, client interface i2c_master_if i2c,
|
||||||
|
uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
uint8_t led;
|
||||||
|
for (led = 1; led <= TX1_RGB_LED_MAX; led++) {
|
||||||
|
tx1_fx_pwm_led(dev, i2c, led, r, g, b);
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
灯效状态(jok led_effects.xc)
|
||||||
|
-----------------------------------------------------------------------*/
|
||||||
|
static int head_pos = 0;
|
||||||
|
static int breath_idx = 0;
|
||||||
|
static int rainbow_hue = 0;
|
||||||
|
static int color_wave_pos = 0;
|
||||||
|
static uint32_t sparkle_seed = 1;
|
||||||
|
static int gradient_pos = 0;
|
||||||
|
|
||||||
|
static const uint8_t breath_curve[] = {
|
||||||
|
0, 8, 16, 28, 40, 55, 70, 88, 106, 125, 144, 163, 180, 196, 210, 222,
|
||||||
|
232, 240, 246, 250, 252, 253, 252, 250, 246, 240, 232, 222, 210, 196,
|
||||||
|
180, 163, 144, 125, 106, 88, 70, 55, 40, 28, 16, 8, 0
|
||||||
|
};
|
||||||
|
#define BREATH_STEPS (sizeof(breath_curve) / sizeof(breath_curve[0]))
|
||||||
|
|
||||||
|
static const uint8_t trail_table[] = {255, 200, 140, 80, 40, 20, 8};
|
||||||
|
#define TRAIL_LEN (sizeof(trail_table) / sizeof(trail_table[0]))
|
||||||
|
|
||||||
|
static const uint8_t rainbow_trail_table[] = {255, 200, 150, 100, 60, 30, 15};
|
||||||
|
#define RAINBOW_TRAIL_LEN (sizeof(rainbow_trail_table) / sizeof(rainbow_trail_table[0]))
|
||||||
|
|
||||||
|
static uint32_t tx1_simple_rand(void)
|
||||||
|
{
|
||||||
|
sparkle_seed = sparkle_seed * 1103515245u + 12345u;
|
||||||
|
return (sparkle_seed >> 16) & 0x7FFFu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 改动原因:移植 jok get_rainbow_color */
|
||||||
|
static void tx1_get_rainbow_color(int hue, uint8_t *r, uint8_t *g, uint8_t *b)
|
||||||
|
{
|
||||||
|
int phase = hue % 240;
|
||||||
|
|
||||||
|
if (phase < 40) {
|
||||||
|
*r = 255; *g = (uint8_t)((phase * 255) / 40); *b = 0;
|
||||||
|
} else if (phase < 80) {
|
||||||
|
*r = (uint8_t)(255 - ((phase - 40) * 255) / 40); *g = 255; *b = 0;
|
||||||
|
} else if (phase < 120) {
|
||||||
|
*r = 0; *g = 255; *b = (uint8_t)(((phase - 80) * 255) / 40);
|
||||||
|
} else if (phase < 160) {
|
||||||
|
*r = 0; *g = (uint8_t)(255 - ((phase - 120) * 255) / 40); *b = 255;
|
||||||
|
} else if (phase < 200) {
|
||||||
|
*r = (uint8_t)(((phase - 160) * 255) / 40); *g = 0; *b = 255;
|
||||||
|
} else {
|
||||||
|
*r = 255; *g = 0; *b = (uint8_t)(255 - ((phase - 200) * 255) / 40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
工厂复位 LED(jok factory_reset_led_effect_loop)
|
||||||
|
-----------------------------------------------------------------------*/
|
||||||
|
tx1_factory_reset_state_t g_tx1_factory_reset_state = TX1_FACTORY_RESET_IDLE;
|
||||||
|
static int g_tx1_factory_reset_timer_counter = 0;
|
||||||
|
static int g_tx1_factory_reset_blink_counter = 0;
|
||||||
|
|
||||||
|
void tx1_factory_reset_countdown_start(void)
|
||||||
|
{
|
||||||
|
g_tx1_factory_reset_state = TX1_FACTORY_RESET_WAITING;
|
||||||
|
g_tx1_factory_reset_timer_counter = 0;
|
||||||
|
g_tx1_factory_reset_blink_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tx1_factory_reset_countdown_6s(void)
|
||||||
|
{
|
||||||
|
g_tx1_factory_reset_state = TX1_FACTORY_RESET_COUNTDOWN;
|
||||||
|
g_tx1_factory_reset_timer_counter = 0;
|
||||||
|
g_tx1_factory_reset_blink_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tx1_factory_reset_countdown_10s(void)
|
||||||
|
{
|
||||||
|
g_tx1_factory_reset_state = TX1_FACTORY_RESET_COUNTDOWN_2;
|
||||||
|
g_tx1_factory_reset_timer_counter = 0;
|
||||||
|
g_tx1_factory_reset_blink_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tx1_factory_reset_triggered(void)
|
||||||
|
{
|
||||||
|
g_tx1_factory_reset_state = TX1_FACTORY_RESET_TRIGGERED;
|
||||||
|
g_tx1_factory_reset_timer_counter = 0;
|
||||||
|
g_tx1_factory_reset_blink_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tx1_factory_reset_cancel(void)
|
||||||
|
{
|
||||||
|
g_tx1_factory_reset_state = TX1_FACTORY_RESET_IDLE;
|
||||||
|
g_tx1_factory_reset_timer_counter = 0;
|
||||||
|
g_tx1_factory_reset_blink_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned tx1_factory_reset_rgb_active(void)
|
||||||
|
{
|
||||||
|
return (g_tx1_factory_reset_state != TX1_FACTORY_RESET_IDLE
|
||||||
|
&& g_tx1_factory_reset_state != TX1_FACTORY_RESET_WAITING) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tx1_factory_reset_led_tick(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
switch (g_tx1_factory_reset_state) {
|
||||||
|
case TX1_FACTORY_RESET_WAITING:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX1_FACTORY_RESET_COUNTDOWN:
|
||||||
|
g_tx1_factory_reset_timer_counter++;
|
||||||
|
if (g_tx1_factory_reset_timer_counter >= 10) {
|
||||||
|
g_tx1_factory_reset_timer_counter = 0;
|
||||||
|
g_tx1_factory_reset_blink_counter++;
|
||||||
|
if ((g_tx1_factory_reset_blink_counter % 2) == 0) {
|
||||||
|
tx1_fx_all_color(dev, i2c,
|
||||||
|
0, TX1_FX_SCALE8(255), 0);
|
||||||
|
} else {
|
||||||
|
tx1_fx_all_color(dev, i2c,
|
||||||
|
TX1_FX_SCALE8(139), TX1_FX_SCALE8(91), TX1_FX_SCALE8(246));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX1_FACTORY_RESET_COUNTDOWN_2:
|
||||||
|
g_tx1_factory_reset_timer_counter++;
|
||||||
|
if (g_tx1_factory_reset_timer_counter >= 2) {
|
||||||
|
g_tx1_factory_reset_timer_counter = 0;
|
||||||
|
if (g_tx1_factory_reset_blink_counter == 0) {
|
||||||
|
g_tx1_factory_reset_blink_counter = 1;
|
||||||
|
tx1_fx_all_color(dev, i2c, 0, 0, 0);
|
||||||
|
} else {
|
||||||
|
g_tx1_factory_reset_blink_counter = 0;
|
||||||
|
tx1_fx_all_color(dev, i2c, TX1_FX_SCALE8(255), 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TX1_FACTORY_RESET_TRIGGERED:
|
||||||
|
tx1_fx_all_color(dev, i2c, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
装饰灯效(每步由 50ms 定时器调用一次)
|
||||||
|
-----------------------------------------------------------------------*/
|
||||||
|
static void tx1_effect_race(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < TX1_RGB_LED_MAX; i++) {
|
||||||
|
int dist = (head_pos - i + TX1_RGB_LED_MAX) % TX1_RGB_LED_MAX;
|
||||||
|
uint8_t br = 0;
|
||||||
|
if (dist < (int)TRAIL_LEN) {
|
||||||
|
br = TX1_FX_SCALE8(trail_table[dist]);
|
||||||
|
}
|
||||||
|
tx1_fx_pwm_led(dev, i2c, (uint8_t)(i + 1), br, br, br);
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
head_pos = (head_pos + 1) % TX1_RGB_LED_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_effect_breath_all(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
uint8_t br = TX1_FX_SCALE8(breath_curve[breath_idx]);
|
||||||
|
uint8_t led;
|
||||||
|
breath_idx = (breath_idx + 1) % (int)BREATH_STEPS;
|
||||||
|
for (led = 1; led <= TX1_RGB_LED_MAX; led++) {
|
||||||
|
tx1_fx_pwm_led(dev, i2c, led, br, br, br);
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_effect_rainbow_race(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < TX1_RGB_LED_MAX; i++) {
|
||||||
|
int dist = (head_pos - i + TX1_RGB_LED_MAX) % TX1_RGB_LED_MAX;
|
||||||
|
if (dist < (int)RAINBOW_TRAIL_LEN) {
|
||||||
|
uint8_t brightness = rainbow_trail_table[dist];
|
||||||
|
uint8_t r, g, b;
|
||||||
|
int hue = (head_pos * 20) % 240;
|
||||||
|
tx1_get_rainbow_color(hue, &r, &g, &b);
|
||||||
|
r = (uint8_t)((r * brightness) / 255);
|
||||||
|
g = (uint8_t)((g * brightness) / 255);
|
||||||
|
b = (uint8_t)((b * brightness) / 255);
|
||||||
|
tx1_fx_pwm_led(dev, i2c, (uint8_t)(i + 1),
|
||||||
|
TX1_FX_SCALE8(r), TX1_FX_SCALE8(g), TX1_FX_SCALE8(b));
|
||||||
|
} else {
|
||||||
|
tx1_fx_pwm_led(dev, i2c, (uint8_t)(i + 1), 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
head_pos = (head_pos + 1) % TX1_RGB_LED_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_effect_rainbow_fill(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
uint8_t led;
|
||||||
|
for (led = 1; led <= TX1_RGB_LED_MAX; led++) {
|
||||||
|
int hue = (rainbow_hue + ((int)led * 20)) % 240;
|
||||||
|
uint8_t r, g, b;
|
||||||
|
tx1_get_rainbow_color(hue, &r, &g, &b);
|
||||||
|
tx1_fx_pwm_led(dev, i2c, led, TX1_FX_SCALE8(r), TX1_FX_SCALE8(g), TX1_FX_SCALE8(b));
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
rainbow_hue = (rainbow_hue + 4) % 240;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_effect_color_wave(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
uint8_t led;
|
||||||
|
for (led = 1; led <= TX1_RGB_LED_MAX; led++) {
|
||||||
|
int hue = (((int)led * 20) + color_wave_pos) % 240;
|
||||||
|
uint8_t r, g, b;
|
||||||
|
tx1_get_rainbow_color(hue, &r, &g, &b);
|
||||||
|
tx1_fx_pwm_led(dev, i2c, led, TX1_FX_SCALE8(r), TX1_FX_SCALE8(g), TX1_FX_SCALE8(b));
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
color_wave_pos = (color_wave_pos + 8) % 240;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_effect_strobe(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
uint8_t r = (uint8_t)(tx1_simple_rand() % 256);
|
||||||
|
uint8_t g = (uint8_t)(tx1_simple_rand() % 256);
|
||||||
|
uint8_t b = (uint8_t)(tx1_simple_rand() % 256);
|
||||||
|
uint8_t led;
|
||||||
|
|
||||||
|
if (tx1_simple_rand() % 2) {
|
||||||
|
for (led = 1; led <= TX1_RGB_LED_MAX; led++) {
|
||||||
|
tx1_fx_pwm_led(dev, i2c, led,
|
||||||
|
TX1_FX_SCALE8(r), TX1_FX_SCALE8(g), TX1_FX_SCALE8(b));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tx1_fx_all_off(dev, i2c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_effect_pulse(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
uint8_t brightness = breath_curve[breath_idx];
|
||||||
|
uint8_t r, g, b;
|
||||||
|
uint8_t led;
|
||||||
|
|
||||||
|
breath_idx = (breath_idx + 1) % (int)BREATH_STEPS;
|
||||||
|
if (brightness < 128) {
|
||||||
|
r = brightness;
|
||||||
|
g = (uint8_t)(brightness / 3);
|
||||||
|
b = 0;
|
||||||
|
} else {
|
||||||
|
r = 255; g = 255; b = 255;
|
||||||
|
}
|
||||||
|
for (led = 1; led <= TX1_RGB_LED_MAX; led++) {
|
||||||
|
tx1_fx_pwm_led(dev, i2c, led,
|
||||||
|
TX1_FX_SCALE8(r), TX1_FX_SCALE8(g), TX1_FX_SCALE8(b));
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_effect_sparkle(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
int sparkle_count = 3 + (int)(tx1_simple_rand() % 3);
|
||||||
|
int i;
|
||||||
|
uint8_t led;
|
||||||
|
|
||||||
|
tx1_fx_all_off(dev, i2c);
|
||||||
|
for (i = 0; i < sparkle_count; i++) {
|
||||||
|
int led_idx = (int)(tx1_simple_rand() % TX1_RGB_LED_MAX);
|
||||||
|
uint8_t brightness = (uint8_t)(100 + (tx1_simple_rand() % 156));
|
||||||
|
uint8_t color_choice = (uint8_t)(tx1_simple_rand() % 6);
|
||||||
|
uint8_t r = 0, g = 0, b = 0;
|
||||||
|
|
||||||
|
switch (color_choice) {
|
||||||
|
case 0: r = brightness; break;
|
||||||
|
case 1: g = brightness; break;
|
||||||
|
case 2: b = brightness; break;
|
||||||
|
case 3: r = brightness; g = brightness; break;
|
||||||
|
case 4: g = brightness; b = brightness; break;
|
||||||
|
default: r = brightness; g = brightness; b = brightness; break;
|
||||||
|
}
|
||||||
|
tx1_fx_pwm_led(dev, i2c, (uint8_t)(led_idx + 1),
|
||||||
|
TX1_FX_SCALE8(r), TX1_FX_SCALE8(g), TX1_FX_SCALE8(b));
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx1_effect_gradient(htr3236_t *dev, client interface i2c_master_if i2c)
|
||||||
|
{
|
||||||
|
int progress = gradient_pos;
|
||||||
|
uint8_t r, g, b;
|
||||||
|
uint8_t led;
|
||||||
|
|
||||||
|
if (progress < 128) {
|
||||||
|
r = 255; g = 0; b = (uint8_t)((progress * 2) * 255 / 256);
|
||||||
|
} else {
|
||||||
|
r = (uint8_t)(255 - ((progress - 128) * 2) * 255 / 256);
|
||||||
|
g = 0; b = 255;
|
||||||
|
}
|
||||||
|
for (led = 1; led <= TX1_RGB_LED_MAX; led++) {
|
||||||
|
tx1_fx_pwm_led(dev, i2c, led,
|
||||||
|
TX1_FX_SCALE8(r), TX1_FX_SCALE8(g), TX1_FX_SCALE8(b));
|
||||||
|
}
|
||||||
|
tx1_fx_update(dev, i2c);
|
||||||
|
gradient_pos = (gradient_pos + 2) % 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* game_mode / feature_mode 数值与 audiohw tx1_*_t 枚举一致:BYPASS=0, FEATURE_NONE=0 */
|
||||||
|
void tx1_led_effects_periodic(htr3236_t *dev, client interface i2c_master_if i2c,
|
||||||
|
unsigned game_mode,
|
||||||
|
unsigned feature_mode,
|
||||||
|
unsigned led_pattern_step)
|
||||||
|
{
|
||||||
|
if (g_tx1_factory_reset_state != TX1_FACTORY_RESET_IDLE) {
|
||||||
|
tx1_factory_reset_led_tick(dev, i2c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feature_mode != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 非 BYPASS 时暂不跑方位灯效(ex3d 后续可接);熄灭 RGB 装饰 */
|
||||||
|
if (game_mode != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (led_pattern_step) {
|
||||||
|
case TX1_EFFECT_RACE:
|
||||||
|
tx1_effect_race(dev, i2c);
|
||||||
|
break;
|
||||||
|
case TX1_EFFECT_BREATH_ALL:
|
||||||
|
tx1_effect_breath_all(dev, i2c);
|
||||||
|
break;
|
||||||
|
case TX1_EFFECT_RAINBOW_RACE:
|
||||||
|
tx1_effect_rainbow_race(dev, i2c);
|
||||||
|
break;
|
||||||
|
case TX1_EFFECT_RAINBOW_FILL:
|
||||||
|
tx1_effect_rainbow_fill(dev, i2c);
|
||||||
|
break;
|
||||||
|
case TX1_EFFECT_COLOR_WAVE:
|
||||||
|
tx1_effect_color_wave(dev, i2c);
|
||||||
|
break;
|
||||||
|
case TX1_EFFECT_STROBE:
|
||||||
|
tx1_effect_strobe(dev, i2c);
|
||||||
|
break;
|
||||||
|
case TX1_EFFECT_PULSE:
|
||||||
|
tx1_effect_pulse(dev, i2c);
|
||||||
|
break;
|
||||||
|
case TX1_EFFECT_SPARKLE:
|
||||||
|
tx1_effect_sparkle(dev, i2c);
|
||||||
|
break;
|
||||||
|
case TX1_EFFECT_GRADIENT:
|
||||||
|
tx1_effect_gradient(dev, i2c);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tx1_fx_all_off(dev, i2c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,7 +32,8 @@ void tx1_led_helper_task(server interface tx1_led_if led_if)
|
|||||||
p_led_d3 <: 0xF;
|
p_led_d3 <: 0xF;
|
||||||
p_led_d5 <: 1;
|
p_led_d5 <: 1;
|
||||||
p_led_d4_d7_d6 <: 0xF;
|
p_led_d4_d7_d6 <: 0xF;
|
||||||
p_htr3236_sdb <: 0; // HTR3236 disabled initially
|
/* 改动原因:上电即拉高 SDB,与 jok tile1_io_control_task 一致;勿长期拉低否则 I2C 配置无效 */
|
||||||
|
p_htr3236_sdb <: 1;
|
||||||
p_ctl_mute <: 1; // Muted initially
|
p_ctl_mute <: 1; // Muted initially
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
|||||||
Reference in New Issue
Block a user