2026-07-15 02:31:33 +00:00
|
|
|
|
#include "kt.h"
|
2026-07-19 16:22:24 +00:00
|
|
|
|
#include "key_event_deal.h"
|
|
|
|
|
|
#include "music_player.h"
|
2026-07-15 02:31:33 +00:00
|
|
|
|
|
2026-07-19 16:22:24 +00:00
|
|
|
|
enum {
|
|
|
|
|
|
KT_LED_IDLE = 0, /* 空闲慢闪 */
|
|
|
|
|
|
KT_LED_PLAY, /* 播放常亮 */
|
|
|
|
|
|
KT_LED_FAIL, /* 播放失败快闪 */
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* 定时器 50ms:慢闪 1s灭/1s亮,快闪 100ms灭/100ms亮 */
|
|
|
|
|
|
#define KT_LED_SLOW_HALF 20
|
|
|
|
|
|
#define KT_LED_FAST_HALF 2
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct _kt_var_ {
|
|
|
|
|
|
int kt_timer;
|
|
|
|
|
|
int t_cnt;
|
|
|
|
|
|
u8 led_mode;
|
|
|
|
|
|
u8 active_ch; /* 1~6, 0=无按键播放会话 */
|
|
|
|
|
|
} _kt_var;
|
|
|
|
|
|
|
|
|
|
|
|
static _kt_var kt_var;
|
|
|
|
|
|
#define __this (&kt_var)
|
|
|
|
|
|
|
|
|
|
|
|
static const char *const kt_file_tab[6] = {
|
|
|
|
|
|
"/01.mp3", "/02.mp3", "/03.mp3", "/04.mp3", "/05.mp3", "/06.mp3",
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void kt_led_set_mode(u8 mode)
|
|
|
|
|
|
{
|
|
|
|
|
|
__this->led_mode = mode;
|
|
|
|
|
|
__this->t_cnt = 0;
|
|
|
|
|
|
if (mode == KT_LED_PLAY) {
|
|
|
|
|
|
BT_LED_ON();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void kt_audio_all_off(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
AUDIO_OUT_CH1_OFF();
|
|
|
|
|
|
AUDIO_OUT_CH2_OFF();
|
|
|
|
|
|
AUDIO_OUT_CH3_OFF();
|
|
|
|
|
|
AUDIO_OUT_CH4_OFF();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void kt_channel_outputs_off(u8 ch)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (ch) {
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
AUDIO_OUT_CH1_OFF();
|
|
|
|
|
|
VOLTAGE_OUT_CH1_OFF();
|
|
|
|
|
|
VLED_OUT_CH1_OFF();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
AUDIO_OUT_CH2_OFF();
|
|
|
|
|
|
VOLTAGE_OUT_CH2_OFF();
|
|
|
|
|
|
VLED_OUT_CH2_OFF();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
AUDIO_OUT_CH3_OFF();
|
|
|
|
|
|
VOLTAGE_OUT_CH3_OFF();
|
|
|
|
|
|
VLED_OUT_CH3_OFF();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 4:
|
|
|
|
|
|
AUDIO_OUT_CH4_OFF();
|
|
|
|
|
|
VOLTAGE_OUT_CH4_OFF();
|
|
|
|
|
|
VLED_OUT_CH4_OFF();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 5:
|
|
|
|
|
|
VLED_OUT_CH5_OFF();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 6:
|
|
|
|
|
|
VLED_OUT_CH6_OFF();
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void kt_channel_outputs_on(u8 ch)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* 音频通道互斥:先全关再开对应通道(仅 1~4 有音频/电压脚) */
|
|
|
|
|
|
kt_audio_all_off();
|
|
|
|
|
|
VOLTAGE_OUT_CH1_OFF();
|
|
|
|
|
|
VOLTAGE_OUT_CH2_OFF();
|
|
|
|
|
|
VOLTAGE_OUT_CH3_OFF();
|
|
|
|
|
|
VOLTAGE_OUT_CH4_OFF();
|
|
|
|
|
|
VLED_OUT_CH1_OFF();
|
|
|
|
|
|
VLED_OUT_CH2_OFF();
|
|
|
|
|
|
VLED_OUT_CH3_OFF();
|
|
|
|
|
|
VLED_OUT_CH4_OFF();
|
|
|
|
|
|
VLED_OUT_CH5_OFF();
|
|
|
|
|
|
VLED_OUT_CH6_OFF();
|
|
|
|
|
|
|
|
|
|
|
|
switch (ch) {
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
AUDIO_OUT_CH1_ON();
|
|
|
|
|
|
VOLTAGE_OUT_CH1_ON();
|
|
|
|
|
|
VLED_OUT_CH1_ON();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
AUDIO_OUT_CH2_ON();
|
|
|
|
|
|
VOLTAGE_OUT_CH2_ON();
|
|
|
|
|
|
VLED_OUT_CH2_ON();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
AUDIO_OUT_CH3_ON();
|
|
|
|
|
|
VOLTAGE_OUT_CH3_ON();
|
|
|
|
|
|
VLED_OUT_CH3_ON();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 4:
|
|
|
|
|
|
AUDIO_OUT_CH4_ON();
|
|
|
|
|
|
VOLTAGE_OUT_CH4_ON();
|
|
|
|
|
|
VLED_OUT_CH4_ON();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 5:
|
|
|
|
|
|
/* 硬件无 AUDIO/VOLTAGE 通道5,仅 VLED */
|
|
|
|
|
|
VLED_OUT_CH5_ON();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 6:
|
|
|
|
|
|
/* 硬件无 AUDIO/VOLTAGE 通道6,仅 VLED */
|
|
|
|
|
|
VLED_OUT_CH6_ON();
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-07-15 02:31:33 +00:00
|
|
|
|
|
|
|
|
|
|
void kt_boot_init(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
//CS8406 RST
|
|
|
|
|
|
gpio_set_pull_down(IO_PORTA_06,0);
|
|
|
|
|
|
gpio_set_pull_up(IO_PORTA_06,0);
|
|
|
|
|
|
gpio_set_direction(IO_PORTA_06,0);
|
|
|
|
|
|
gpio_set_output_value(IO_PORTA_06,0);
|
|
|
|
|
|
|
|
|
|
|
|
//iis 双绑引脚高阻化
|
|
|
|
|
|
gpio_set_pull_down(IO_PORTA_01,0);
|
|
|
|
|
|
gpio_set_pull_up(IO_PORTA_01,0);
|
|
|
|
|
|
gpio_set_direction(IO_PORTA_01,1);
|
|
|
|
|
|
gpio_set_die(IO_PORTA_01,1);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(IO_PORTA_05,0);
|
|
|
|
|
|
gpio_set_pull_up(IO_PORTA_05,0);
|
|
|
|
|
|
gpio_set_direction(IO_PORTA_05,1);
|
|
|
|
|
|
gpio_set_die(IO_PORTA_05,1);
|
|
|
|
|
|
|
|
|
|
|
|
//CS8406 TX EN
|
2026-07-19 16:22:24 +00:00
|
|
|
|
gpio_set_pull_down(AUDIO_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_pull_up(AUDIO_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_direction(AUDIO_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_output_value(AUDIO_OUT_CHANNEL1,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(AUDIO_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_pull_up(AUDIO_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_direction(AUDIO_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_output_value(AUDIO_OUT_CHANNEL2,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(AUDIO_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_pull_up(AUDIO_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_direction(AUDIO_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_output_value(AUDIO_OUT_CHANNEL3,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(AUDIO_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_pull_up(AUDIO_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_direction(AUDIO_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_output_value(AUDIO_OUT_CHANNEL4,0);
|
|
|
|
|
|
|
|
|
|
|
|
//voltage output
|
|
|
|
|
|
gpio_set_pull_down(VOLTAGE_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_pull_up(VOLTAGE_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_direction(VOLTAGE_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_output_value(VOLTAGE_OUT_CHANNEL1,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(VOLTAGE_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_pull_up(VOLTAGE_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_direction(VOLTAGE_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_output_value(VOLTAGE_OUT_CHANNEL2,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(VOLTAGE_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_pull_up(VOLTAGE_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_direction(VOLTAGE_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_output_value(VOLTAGE_OUT_CHANNEL3,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(VOLTAGE_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_pull_up(VOLTAGE_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_direction(VOLTAGE_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_output_value(VOLTAGE_OUT_CHANNEL4,0);
|
|
|
|
|
|
|
|
|
|
|
|
//vled output
|
|
|
|
|
|
gpio_set_pull_down(VLED_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_pull_up(VLED_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_direction(VLED_OUT_CHANNEL1,0);
|
|
|
|
|
|
gpio_set_output_value(VLED_OUT_CHANNEL1,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(VLED_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_pull_up(VLED_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_direction(VLED_OUT_CHANNEL2,0);
|
|
|
|
|
|
gpio_set_output_value(VLED_OUT_CHANNEL2,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(VLED_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_pull_up(VLED_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_direction(VLED_OUT_CHANNEL3,0);
|
|
|
|
|
|
gpio_set_output_value(VLED_OUT_CHANNEL3,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(VLED_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_pull_up(VLED_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_direction(VLED_OUT_CHANNEL4,0);
|
|
|
|
|
|
gpio_set_output_value(VLED_OUT_CHANNEL4,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(VLED_OUT_CHANNEL5,0);
|
|
|
|
|
|
gpio_set_pull_up(VLED_OUT_CHANNEL5,0);
|
|
|
|
|
|
gpio_set_direction(VLED_OUT_CHANNEL5,0);
|
|
|
|
|
|
gpio_set_output_value(VLED_OUT_CHANNEL5,0);
|
|
|
|
|
|
|
|
|
|
|
|
gpio_set_pull_down(VLED_OUT_CHANNEL6,0);
|
|
|
|
|
|
gpio_set_pull_up(VLED_OUT_CHANNEL6,0);
|
|
|
|
|
|
gpio_set_direction(VLED_OUT_CHANNEL6,0);
|
|
|
|
|
|
gpio_set_output_value(VLED_OUT_CHANNEL6,0);
|
|
|
|
|
|
|
|
|
|
|
|
//bt led
|
|
|
|
|
|
gpio_set_pull_down(BT_LED_PIN,0);
|
|
|
|
|
|
gpio_set_pull_up(BT_LED_PIN,0);
|
|
|
|
|
|
gpio_set_direction(BT_LED_PIN,0);
|
|
|
|
|
|
gpio_set_output_value(BT_LED_PIN,0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void timer_cb(void *priv)
|
|
|
|
|
|
{
|
|
|
|
|
|
u8 half;
|
|
|
|
|
|
|
|
|
|
|
|
if (__this->led_mode == KT_LED_PLAY) {
|
|
|
|
|
|
BT_LED_ON();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
half = (__this->led_mode == KT_LED_FAIL) ? KT_LED_FAST_HALF : KT_LED_SLOW_HALF;
|
|
|
|
|
|
__this->t_cnt++;
|
|
|
|
|
|
if (__this->t_cnt <= half) {
|
|
|
|
|
|
BT_LED_OFF();
|
|
|
|
|
|
} else if (__this->t_cnt <= (half * 2)) {
|
|
|
|
|
|
BT_LED_ON();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
__this->t_cnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void start_time_base(u32 time_base_ms)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (__this->kt_timer) {
|
|
|
|
|
|
sys_timer_del(__this->kt_timer);
|
|
|
|
|
|
}
|
|
|
|
|
|
__this->t_cnt = 0;
|
|
|
|
|
|
__this->kt_timer = sys_timer_add(NULL, timer_cb, time_base_ms);
|
2026-07-15 02:31:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void kt_init(void)
|
|
|
|
|
|
{
|
2026-07-19 16:22:24 +00:00
|
|
|
|
__this->active_ch = 0;
|
|
|
|
|
|
kt_led_set_mode(KT_LED_IDLE);
|
2026-07-15 02:31:33 +00:00
|
|
|
|
//CS8406 RST
|
2026-07-19 16:22:24 +00:00
|
|
|
|
gpio_set_output_value(IO_PORTA_06, 1);
|
|
|
|
|
|
/* 默认关闭各音频通道,按键播放时再打开对应通道 */
|
|
|
|
|
|
kt_audio_all_off();
|
|
|
|
|
|
start_time_base(50);
|
|
|
|
|
|
}
|
2026-07-15 02:31:33 +00:00
|
|
|
|
|
2026-07-19 16:22:24 +00:00
|
|
|
|
/* 播放结束/出错/拔卡:关闭对应输出,返回1表示是按键播放会话 */
|
|
|
|
|
|
int kt_music_play_end_handler(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (__this->active_ch == 0) {
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
printf("kt_music_play_end_handler ch=%d\n", __this->active_ch);
|
|
|
|
|
|
kt_channel_outputs_off(__this->active_ch);
|
|
|
|
|
|
__this->active_ch = 0;
|
|
|
|
|
|
kt_led_set_mode(KT_LED_IDLE);
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* 优先 sd1/0x.mp3,其次 udisk0/0x.mp3;
|
|
|
|
|
|
* 成功则打开对应音频/电压/VLED,失败不做任何反应;
|
|
|
|
|
|
* 播完由 kt_music_play_end_handler 关闭输出。
|
|
|
|
|
|
*/
|
|
|
|
|
|
int kt_key_event_handler(u16 key)
|
|
|
|
|
|
{
|
|
|
|
|
|
u8 ch;
|
|
|
|
|
|
int err;
|
|
|
|
|
|
const char *path;
|
|
|
|
|
|
|
|
|
|
|
|
if (key < KEY_USER_KEY_1 || key > KEY_USER_KEY_6) {
|
|
|
|
|
|
return MUSIC_PLAYER_ERR_NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ch = (u8)(key - KEY_USER_KEY_1 + 1);
|
|
|
|
|
|
path = kt_file_tab[ch - 1];
|
|
|
|
|
|
printf("kt_key_event_handler key=%d ch=%d path=%s\n", key, ch, path);
|
|
|
|
|
|
|
|
|
|
|
|
/* 若上一首按键播放未结束,先关掉上一通道输出 */
|
|
|
|
|
|
if (__this->active_ch) {
|
|
|
|
|
|
kt_channel_outputs_off(__this->active_ch);
|
|
|
|
|
|
__this->active_ch = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
err = music_player_play_by_path((char *)"sd1", path);
|
|
|
|
|
|
if (err != MUSIC_PLAYER_SUCC) {
|
|
|
|
|
|
err = music_player_play_by_path((char *)"udisk0", path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (err == MUSIC_PLAYER_SUCC) {
|
|
|
|
|
|
kt_channel_outputs_on(ch);
|
|
|
|
|
|
__this->active_ch = ch;
|
|
|
|
|
|
kt_led_set_mode(KT_LED_PLAY);
|
|
|
|
|
|
return MUSIC_PLAYER_SUCC;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 播放失败:通道不动作,BT_LED 快闪 */
|
|
|
|
|
|
printf("kt play fail ch=%d err=%d\n", ch, err);
|
|
|
|
|
|
kt_led_set_mode(KT_LED_FAIL);
|
|
|
|
|
|
return MUSIC_PLAYER_ERR_NULL;
|
|
|
|
|
|
}
|