K1Guitar/task/task_init.c

486 lines
17 KiB
C
Raw Normal View History

#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_HEAVY_BOOT : UITask_Sendmsg(MSG_ID_HEAVY_BOOT, 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);
Audio_AbortIfNotReady();
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);
}
}