484 lines
16 KiB
C
484 lines
16 KiB
C
#include "includes.h"
|
||
|
||
static struct rt_thread TaskScanThread;
|
||
static struct rt_thread TaskUIThread;
|
||
static struct rt_thread TaskTouchThread;
|
||
static struct rt_thread TaskMainThread;
|
||
static struct rt_thread TaskBTHandleThread;
|
||
static struct rt_thread TaskBTRecvThread;
|
||
static struct rt_thread TaskAutobandThread;
|
||
|
||
ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskScanThread_Stack[512];
|
||
ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskUIThread_Stack[2048];
|
||
ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskTouchThread_Stack[1536];
|
||
ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskMainThread_Stack[512];
|
||
ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskBTTHandlehread_Stack[512];
|
||
ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskBTRecvThread_Stack[768];
|
||
ALIGN(RT_ALIGN_SIZE) static rt_uint8_t TaskAutobandThread_Stack[512];
|
||
|
||
|
||
void TaskScanThread_entry(void* parameter)
|
||
{
|
||
while(1)
|
||
{
|
||
app_tm1629_Scan_Key();
|
||
app_tm1617_scan_key();
|
||
app_adc_scan_all();
|
||
app_tm1617_auto_loop();
|
||
rt_thread_mdelay(2);
|
||
}
|
||
}
|
||
|
||
void TaskUIThread_entry(void* parameter)
|
||
{
|
||
DisplayTaskMessage_Type xEvent = {0,};
|
||
while(1)
|
||
{
|
||
if(rt_mq_recv(UITask_msg, &xEvent, sizeof(DisplayTaskMessage_Type), RT_WAITING_FOREVER) == RT_EOK)
|
||
{
|
||
/* BLE 写节奏风格:停伴奏+换库在任何页面都要执行,且必须在 UI 任务上下文
|
||
(TaskBTRecv 栈仅 768B,ReloadTone 深调用链会溢出;本地触控路径同在此任务) */
|
||
if (xEvent.MessageType == MSG_ID_BLE_STYLE_SET)
|
||
{
|
||
StartFlag = 0;
|
||
UI_ReloadTonePreset(); /* 内含 Stop_AutoBand */
|
||
}
|
||
/* 低电量提示:任意页面全屏覆盖;倒计时期间吞掉其它 UI 刷新,避免盖住提示 */
|
||
if (xEvent.MessageType == MSG_ID_LOW_BAT_TIP)
|
||
{
|
||
uint8_t peek[4];
|
||
LCD_WR_REG(0x29);
|
||
LCD_BLK_Set();
|
||
LCD_FillByColor(0, 0, 240, 320, BLACK);
|
||
W25Q128_Read(peek, UI0902_LOWBAT_TIP_ADDR, 4);
|
||
if (peek[0] != 0xFF || peek[1] != 0xFF)
|
||
{
|
||
LCD_WR_PIC_FROM_FLASH(0, 0, UI0902_LOWBAT_TIP_W, UI0902_LOWBAT_TIP_H,
|
||
UI0902_LOWBAT_TIP_ADDR);
|
||
}
|
||
else
|
||
{
|
||
LOG_W("UI", "lowbat flash empty @0x%08lX — flash ui0902",
|
||
(unsigned long)UI0902_LOWBAT_TIP_ADDR);
|
||
}
|
||
continue;
|
||
}
|
||
if (System_LowBat_IsActive())
|
||
continue;
|
||
/* 任意页面的用户交互统一复位自动关机;避免各 Process 漏调/early-return 漏调 */
|
||
switch (xEvent.MessageType)
|
||
{
|
||
case MSG_ID_TOUCH:
|
||
case MSG_ID_TOUCH_LONG_REPEAT:
|
||
case MSG_ID_EC_VOL:
|
||
case MSG_ID_TAP_SPEED:
|
||
case MSG_ID_BP_TRANSPOSE:
|
||
ResetAutoPowerCount();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
CurrUIProcress(xEvent);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void TaskTouchThread_entry(void* parameter)
|
||
{
|
||
static uint8_t s_last_pressed = 0;
|
||
LOG_TPI("touch task running");
|
||
while(1)
|
||
{
|
||
TP_Point tp = TP_Read(); /* 已含轴交换/镜像,直接进手势 */
|
||
if (tp.pressed) {
|
||
if (!s_last_pressed) {
|
||
LOG_TPI("scan down x=%u y=%u", (unsigned)tp.x, (unsigned)tp.y);
|
||
}
|
||
} else if (s_last_pressed) {
|
||
LOG_TPI("scan up");
|
||
}
|
||
s_last_pressed = tp.pressed;
|
||
app_touch_process(tp.x, tp.y, tp.pressed);
|
||
TP_LivePoll();
|
||
app_log_poll();
|
||
Read_Cur_Measure();
|
||
rt_thread_mdelay(8);
|
||
}
|
||
}
|
||
|
||
void TaskMainThread_entry(void* parameter)
|
||
{
|
||
DisplayTaskMessage_Type xEvent = {0,};
|
||
while(1)
|
||
{
|
||
if(rt_mq_recv(MainTask_msg, &xEvent, sizeof(DisplayTaskMessage_Type), RT_WAITING_FOREVER) == RT_EOK)
|
||
{
|
||
switch(xEvent.MessageType)
|
||
{
|
||
case MSG_ID_POWER_ON : UITask_Sendmsg(MSG_ID_POWER_ON, xEvent.ID, xEvent.HiByte, xEvent.LoByte); break;
|
||
case MSG_ID_POWER_OFF : break;
|
||
//case MSG_ID_ADCIN1KEY : ADC_IN1_KEY_Handle(xEvent.ID);break;
|
||
case MSG_ID_BP_KEY:
|
||
if (!System_LowBat_IsActive() && InModeFlag)
|
||
Pick_Handle();
|
||
break;
|
||
case MSG_ID_STOP_BAND:
|
||
/* 停止键/偶拍收束:MainTask 串行硬停(已撤销软停) */
|
||
if (!System_LowBat_IsActive())
|
||
Stop_AutoBand();
|
||
break;
|
||
case MSG_ID_START_FOLLOWUP:
|
||
/* 软停补发路径已撤销;保留 case 以免旧固件消息号撞车 */
|
||
break;
|
||
case MSG_ID_LOOP_LIGHT:
|
||
if (!System_LowBat_IsActive())
|
||
Loop_Light_Handle(xEvent.ID);
|
||
break;
|
||
case MSG_ID_TM1629_KEY : break;
|
||
case MSG_ID_TM1617_KEY : break;
|
||
case MSG_ID_EC_VOL:
|
||
/* 任意页面都先下发主音量,避免 UI 未处理导致屏显与实际脱节 */
|
||
if (!System_LowBat_IsActive())
|
||
Send_volume((uint8_t)xEvent.ID);
|
||
UITask_Sendmsg(xEvent.MessageType, xEvent.ID, xEvent.HiByte, xEvent.LoByte);
|
||
break;
|
||
case MSG_ID_LOW_BAT_TIP:
|
||
/* 立即停声并切掉音源/12V/蓝牙,避免提示的 10s 里继续把电池拉过保护电压 */
|
||
Stop_AutoBand();
|
||
Send_volume(0);
|
||
BSP_DreamCorePowerEnable(0);
|
||
BSP_HT7178PowerEnable(0);
|
||
BSP_BlueToothPowerEnable(0);
|
||
System_LowBat_Arm();
|
||
UITask_Sendmsg(MSG_ID_LOW_BAT_TIP, xEvent.ID, xEvent.HiByte, xEvent.LoByte);
|
||
break;
|
||
case MSG_ID_TOUCH:
|
||
case MSG_ID_CHARG:
|
||
case MSG_ID_TAP_SPEED:
|
||
case MSG_ID_BP_TRANSPOSE:
|
||
case MSG_ID_POWOFF_CHARG:
|
||
case MSG_ID_BATTERY_VALUE:
|
||
case MSG_ID_TOUCH_LONG_REPEAT:
|
||
case MSG_ID_BLE_UI_REFRESH:
|
||
case MSG_ID_BLE_STYLE_SET:
|
||
/* 业务消息:先做业务处理,再转发 UI 刷新 */
|
||
UITask_Sendmsg(xEvent.MessageType, xEvent.ID, xEvent.HiByte, xEvent.LoByte);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TaskBTHandleThread_entry(void* parameter)
|
||
{
|
||
DisplayTaskMessage_Type xEvent = {0,};
|
||
while(1)
|
||
{
|
||
if (rt_mq_recv(BLTask_msg, &xEvent, sizeof(DisplayTaskMessage_Type), RT_WAITING_FOREVER) == RT_EOK)
|
||
{
|
||
switch(xEvent.MessageType)
|
||
{
|
||
case MSG_ID_LIGHT_LED : BL_Set_led(xEvent.ID,xEvent.HiByte); break;
|
||
case MSG_ID_PITCH_OFFSET : BT_Pitch_offset_map(xEvent.ID,xEvent.HiByte); break;
|
||
case MSG_ID_CHORD_OFFSET : BT_Chord_offset_map(xEvent.ID,xEvent.HiByte); break;
|
||
/* BLE section / intro-outro-end commands (06 xx, 04 07) */
|
||
case MSG_ID_ADCIN1KEY:
|
||
if (InModeFlag)
|
||
ADC_IN1_KEY_Handle((uint8_t)xEvent.ID, true);
|
||
break;
|
||
case MSG_ID_KEY_1617:
|
||
if (InModeFlag)
|
||
TM1617_Handle((uint8_t)xEvent.ID);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TaskBTRecvThread_entry(void* parameter)
|
||
{
|
||
uint8_t c;
|
||
while(1)
|
||
{
|
||
if(rt_sem_take(UART4_sem, RT_WAITING_FOREVER) == RT_EOK)
|
||
{
|
||
while(UART4_RxPop(&c))
|
||
{
|
||
UART4_Data_Process(&c);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TaskAutobandThread_entry(void* parameter)
|
||
{
|
||
for(;;)
|
||
{
|
||
while(!mymidififo_IsQueueEmpty(&m_MidiSendFifo))
|
||
{
|
||
MidiFifoItem_t* pitem = mymidififo_DeQueue(&m_MidiSendFifo);
|
||
SendMidiDataToDreamDSP(pitem->msg, pitem->msglen);
|
||
//ResetAutoPowerCount();
|
||
}
|
||
rt_thread_mdelay(1);
|
||
}
|
||
}
|
||
|
||
rt_err_t TaskInit(void)
|
||
{
|
||
rt_err_t ret = RT_EINVAL;
|
||
TM1629_Mutex = rt_mutex_create("TM1629_Mutex",RT_IPC_FLAG_FIFO);
|
||
TM1617_Mutex = rt_mutex_create("TM1617_Mutex",RT_IPC_FLAG_FIFO);
|
||
UART4_sem = rt_sem_create("UART4_sem",0,RT_IPC_FLAG_FIFO);
|
||
MainTask_msg = rt_mq_create("MainTask msgQ",sizeof(DisplayTaskMessage_Type),128,RT_IPC_FLAG_FIFO);
|
||
UITask_msg = rt_mq_create("UITask msgQ",sizeof(DisplayTaskMessage_Type),128,RT_IPC_FLAG_FIFO);
|
||
BLTask_msg = rt_mq_create("BLTask msgQ",sizeof(DisplayTaskMessage_Type),128,RT_IPC_FLAG_FIFO);
|
||
if(MainTask_msg == RT_NULL || UITask_msg == RT_NULL)
|
||
{
|
||
LOG_E("BOOT", "mq create fail main=%p ui=%p", MainTask_msg, UITask_msg);
|
||
}
|
||
|
||
ret = rt_thread_init(&TaskScanThread,
|
||
"TaskScanThread",
|
||
TaskScanThread_entry,
|
||
RT_NULL,
|
||
&TaskScanThread_Stack,
|
||
sizeof(TaskScanThread_Stack),
|
||
5,
|
||
20);
|
||
|
||
ret = rt_thread_init(&TaskUIThread,
|
||
"TaskUIThread",
|
||
TaskUIThread_entry,
|
||
RT_NULL,
|
||
&TaskUIThread_Stack,
|
||
sizeof(TaskUIThread_Stack),
|
||
5,
|
||
20);
|
||
|
||
ret = rt_thread_init(&TaskTouchThread,
|
||
"TaskTouchThread",
|
||
TaskTouchThread_entry,
|
||
RT_NULL,
|
||
&TaskTouchThread_Stack,
|
||
sizeof(TaskTouchThread_Stack),
|
||
5,
|
||
20);
|
||
|
||
ret = rt_thread_init(&TaskMainThread,
|
||
"TaskMainThread",
|
||
TaskMainThread_entry,
|
||
RT_NULL,
|
||
&TaskMainThread_Stack,
|
||
sizeof(TaskMainThread_Stack),
|
||
5,
|
||
20);
|
||
|
||
ret = rt_thread_init(&TaskBTHandleThread,
|
||
"TaskBTHandleThread",
|
||
TaskBTHandleThread_entry,
|
||
RT_NULL,
|
||
&TaskBTTHandlehread_Stack,
|
||
sizeof(TaskBTTHandlehread_Stack),
|
||
5,
|
||
20);
|
||
|
||
ret = rt_thread_init(&TaskBTRecvThread,
|
||
"TaskBTRecvThread",
|
||
TaskBTRecvThread_entry,
|
||
RT_NULL,
|
||
&TaskBTRecvThread_Stack,
|
||
sizeof(TaskBTRecvThread_Stack),
|
||
5,
|
||
20);
|
||
|
||
ret = rt_thread_init(&TaskAutobandThread,
|
||
"TaskAutobandThread",
|
||
TaskAutobandThread_entry,
|
||
RT_NULL,
|
||
&TaskAutobandThread_Stack,
|
||
sizeof(TaskAutobandThread_Stack),
|
||
4,
|
||
20);
|
||
rt_thread_startup(&TaskMainThread);
|
||
rt_thread_startup(&TaskUIThread);
|
||
/* RTT LCD dump poller must run even before power-on / StartTouchTask. */
|
||
LCD_Dump_StartPoller();
|
||
return ret;
|
||
}
|
||
|
||
void StartTask(void)
|
||
{
|
||
/* 扫描任务可能已由 StartScanTask 拉起;重复 startup 会被 RT-Thread 忽略 */
|
||
StartScanTask();
|
||
|
||
/* Soft-off(StopFullTask) 会 detach 下列线程;开机须能重建,否则 UI/消息永久失效 */
|
||
if ((TaskMainThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
|
||
{
|
||
rt_thread_init(&TaskMainThread,
|
||
"TaskMainThread",
|
||
TaskMainThread_entry,
|
||
RT_NULL,
|
||
&TaskMainThread_Stack,
|
||
sizeof(TaskMainThread_Stack),
|
||
5,
|
||
20);
|
||
}
|
||
if ((TaskMainThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT)
|
||
rt_thread_startup(&TaskMainThread);
|
||
|
||
if ((TaskUIThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
|
||
{
|
||
rt_thread_init(&TaskUIThread,
|
||
"TaskUIThread",
|
||
TaskUIThread_entry,
|
||
RT_NULL,
|
||
&TaskUIThread_Stack,
|
||
sizeof(TaskUIThread_Stack),
|
||
5,
|
||
20);
|
||
}
|
||
if ((TaskUIThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT)
|
||
rt_thread_startup(&TaskUIThread);
|
||
|
||
if ((TaskBTHandleThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
|
||
{
|
||
rt_thread_init(&TaskBTHandleThread,
|
||
"TaskBTHandleThread",
|
||
TaskBTHandleThread_entry,
|
||
RT_NULL,
|
||
&TaskBTTHandlehread_Stack,
|
||
sizeof(TaskBTTHandlehread_Stack),
|
||
5,
|
||
20);
|
||
}
|
||
if ((TaskBTHandleThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT)
|
||
rt_thread_startup(&TaskBTHandleThread);
|
||
|
||
if ((TaskBTRecvThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
|
||
{
|
||
rt_thread_init(&TaskBTRecvThread,
|
||
"TaskBTRecvThread",
|
||
TaskBTRecvThread_entry,
|
||
RT_NULL,
|
||
&TaskBTRecvThread_Stack,
|
||
sizeof(TaskBTRecvThread_Stack),
|
||
5,
|
||
20);
|
||
}
|
||
if ((TaskBTRecvThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT)
|
||
rt_thread_startup(&TaskBTRecvThread);
|
||
|
||
if ((TaskAutobandThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
|
||
{
|
||
rt_thread_init(&TaskAutobandThread,
|
||
"TaskAutobandThread",
|
||
TaskAutobandThread_entry,
|
||
RT_NULL,
|
||
&TaskAutobandThread_Stack,
|
||
sizeof(TaskAutobandThread_Stack),
|
||
4,
|
||
20);
|
||
}
|
||
if ((TaskAutobandThread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT)
|
||
rt_thread_startup(&TaskAutobandThread);
|
||
}
|
||
|
||
void StartTouchTask(void)
|
||
{
|
||
rt_uint8_t st = (rt_uint8_t)(TaskTouchThread.stat & RT_THREAD_STAT_MASK);
|
||
|
||
XPT2046_Init();
|
||
app_touch_reset();
|
||
LOG_TPI("gpio reinit before touch task");
|
||
|
||
if (st == RT_THREAD_CLOSE)
|
||
{
|
||
rt_thread_init(&TaskTouchThread,
|
||
"TaskTouchThread",
|
||
TaskTouchThread_entry,
|
||
RT_NULL,
|
||
&TaskTouchThread_Stack,
|
||
sizeof(TaskTouchThread_Stack),
|
||
5,
|
||
20);
|
||
st = RT_THREAD_INIT;
|
||
}
|
||
if (st == RT_THREAD_INIT) {
|
||
rt_thread_startup(&TaskTouchThread);
|
||
LOG_TPI("touch task started stat=%u", (unsigned)TaskTouchThread.stat);
|
||
}
|
||
}
|
||
|
||
void StartScanTask(void)
|
||
{
|
||
rt_uint8_t st = (rt_uint8_t)(TaskScanThread.stat & RT_THREAD_STAT_MASK);
|
||
|
||
if (st == RT_THREAD_CLOSE)
|
||
{
|
||
rt_thread_init(&TaskScanThread,
|
||
"TaskScanThread",
|
||
TaskScanThread_entry,
|
||
RT_NULL,
|
||
&TaskScanThread_Stack,
|
||
sizeof(TaskScanThread_Stack),
|
||
5,
|
||
20);
|
||
st = RT_THREAD_INIT;
|
||
}
|
||
if (st == RT_THREAD_INIT)
|
||
rt_thread_startup(&TaskScanThread);
|
||
}
|
||
|
||
void StopFullTask(void)
|
||
{
|
||
LOG_I("TASK", "StopFullTask begin");
|
||
if((TaskScanThread.stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE) {
|
||
LOG_I("TASK", "stop ScanThread");
|
||
rt_thread_detach(&TaskScanThread);
|
||
}
|
||
/* 软关机 = 系统关闭:停触摸/扫描/BT/伴奏。
|
||
Main/UI 保留:Type-C 时要画 Charging Image,长按开机要收 POWER_ON。 */
|
||
if((TaskTouchThread.stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE) {
|
||
LOG_I("TASK", "stop TouchThread");
|
||
rt_thread_detach(&TaskTouchThread);
|
||
}
|
||
if((TaskBTHandleThread.stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE) {
|
||
LOG_I("TASK", "stop BTHandleThread");
|
||
rt_thread_detach(&TaskBTHandleThread);
|
||
}
|
||
if((TaskBTRecvThread.stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE) {
|
||
LOG_I("TASK", "stop BTRecvThread");
|
||
rt_thread_detach(&TaskBTRecvThread);
|
||
}
|
||
if((TaskAutobandThread.stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE) {
|
||
LOG_I("TASK", "stop AutobandThread");
|
||
rt_thread_detach(&TaskAutobandThread);
|
||
}
|
||
LOG_I("TASK", "StopFullTask done");
|
||
}
|
||
|
||
|
||
static void OutTime_Stop_timer_callback(void *parameter)
|
||
{
|
||
uint8_t AllNoteOff_buff[3] = {0xB0,0x7B,0x00};
|
||
SendMidiDataToDreamDSP(AllNoteOff_buff,sizeof(AllNoteOff_buff));
|
||
AutoBandTop1_Stop();
|
||
}
|
||
|
||
void timer_init(void)
|
||
{
|
||
OutTime_Stop_timer = rt_timer_create("OutTimeStopTimer",
|
||
OutTime_Stop_timer_callback,
|
||
RT_NULL,
|
||
1000,
|
||
RT_TIMER_FLAG_ONE_SHOT);
|
||
if (OutTime_Stop_timer != RT_NULL)
|
||
{
|
||
rt_timer_stop(OutTime_Stop_timer);
|
||
}
|
||
}
|