K1Guitar/protocol/bl_uart_parse.c

768 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "includes.h"
// Э<><D0AD>֡ͷ/֡β
#define FRAME_SYS_HEAD 0xF0
#define FRAME_SYS_TAIL 0xF7
#define FRAME_MIDI_NOTEON 0x90
#define FRAME_MIDI_NOTEOFF 0x80
#define FRAME_MIDI_PROCHANGE 0xC0
#define UART4_RCV_TIMEOUT_MS 50
/**
* @brief UART4<54><34><EFBFBD><EFBFBD>״̬ö<CCAC><C3B6>
*/
typedef enum
{
UART4_RCV_BUFF_IDLE, // <20><><EFBFBD><EFBFBD>״̬
UART4_RCV_BUFF_HEAD, // <20><><EFBFBD><EFBFBD>֡ͷ<D6A1><CDB7>̶<EFBFBD><CCB6>ֽ<EFBFBD>(0x60/0x51)
UART4_RCV_BUFF_CMD1, // <20><>ָ<EFBFBD><D6B8>
UART4_RCV_BUFF_CMD2, // <20><>ָ<EFBFBD><D6B8>
UART4_RCV_BUFF_DATA, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
UART4_RCV_BUFF_END, // ֡β<D6A1><CEB2><EFBFBD><EFBFBD>
UART4_RCV_BUFF_MIDI1,
UART4_RCV_BUFF_MIDI2,
UART4_RCV_BUFF_MIDIEND
} UART4_RCV_StatusType;
#define UART4_PROCESS_BUFF_SIZE 64 /* 02 04 full chord-map frame is 47 bytes */
// UART4<54><34><EFBFBD><EFBFBD>ȫ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>
static UART4_RCV_StatusType UART4_RCV_Status = UART4_RCV_BUFF_IDLE;
static uint8_t UART4_Process_Buff[UART4_PROCESS_BUFF_SIZE];
static uint8_t UART4_RCV_cnt = 0;
//static uint32_t UART4_RCV_Last_Tick = 0;
//static uint8_t expect_data_len = 0;
/**
* @brief ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5A3A8>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>UART3<54><33><EFBFBD>
*/
typedef struct
{
uint8_t cmd[2]; // <20><>ָ<EFBFBD><D6B8>+<2B><>ָ<EFBFBD><D6B8>
void (*handler)(uint8_t *data);// <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
} BLE_SysExCmdItem;
// ==============================
// ָ<><EFBFBD><EEB4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB> static<69><63>
// ==============================
static void handleDevDisconnect(uint8_t *data);
static void handleDevConnect(uint8_t *data);
static void handleDevName(uint8_t *data);
static void handleFwMainVer(uint8_t *data);
static void handleSoundVer(uint8_t *data);
static void handleUIVer(uint8_t *data);
static void handleOtherInfo(uint8_t *data);
static void handleDevCode(uint8_t *data);
static void handleAutoPowerOff(uint8_t *data);
static void handleUserFwVer(uint8_t *data);
static void handleAutoPowerOffSet(uint8_t *data);
static void handleFwCode(uint8_t *data);
static void handleReadRhythmMap(uint8_t *data);
static void handlePitchOffset(uint8_t *data);
static void handleChordOffset(uint8_t *data);
static void handleResetChordMap(uint8_t *data);
static void handleRhythmStyle(uint8_t *data);
static void handleStringTimbre(uint8_t *data);
static void handleBPM(uint8_t *data);
static void handleTranspose(uint8_t *data);
static void handleLED0(uint8_t *data);
static void handleLED1(uint8_t *data);
static void handleLED2(uint8_t *data);
static void handleLED3(uint8_t *data);
static void handleLED4(uint8_t *data);
static void handleLED5(uint8_t *data);
static void handleLED6(uint8_t *data);
static void handleDeviceReset(uint8_t *data);
static void handleIntro(uint8_t *data);
static void handleInterlude(uint8_t *data);
static void handleOutro(uint8_t *data);
static void handleEnd(uint8_t *data);
static void handleSectionA(uint8_t *data);
static void handleSectionB(uint8_t *data);
static void handleSectionC(uint8_t *data);
static void handleSectionD(uint8_t *data);
/*************************************************
* <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><CFB8><EFBFBD><EFBFBD>Э<EFBFBD><D0AD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>
*************************************************/
static const BLE_SysExCmdItem bleSysExCmdTable[] =
{
/*======== 1. device info 0x01 ========*/
{{0x01, 0x00}, handleDevDisconnect}, /* disconnect */
{{0x01, 0x01}, handleDevConnect}, /* connect */
{{0x01, 0x02}, handleDevName}, /* device name */
{{0x01, 0x03}, handleFwMainVer}, /* fw main version */
{{0x01, 0x04}, handleSoundVer}, /* sound version */
{{0x01, 0x05}, handleUIVer}, /* UI version */
{{0x01, 0x06}, handleOtherInfo}, /* other info */
{{0x01, 0x07}, handleDevCode}, /* device code (96bit UID) */
{{0x01, 0x0A}, handleAutoPowerOff}, /* auto power-off read (minutes) */
{{0x01, 0x0C}, handleUserFwVer}, /* user fw version */
{{0x01, 0x11}, handleAutoPowerOffSet}, /* auto power-off set (minutes) */
{{0x01, 0xFF}, handleFwCode}, /* fw code */
/*======== 2. chord map 0x02 ========*/
{{0x02, 0x01}, handleReadRhythmMap}, /* read chord/pitch map */
{{0x02, 0x02}, handlePitchOffset}, /* pitch offset */
{{0x02, 0x03}, handleChordOffset}, /* chord offset */
{{0x02, 0x04}, handleResetChordMap}, /* write whole map (default reset) */
/*======== 3. guitar params 0x03 ========*/
{{0x03, 0x04}, handleRhythmStyle}, /* rhythm style r/w + user list */
{{0x03, 0x05}, handleStringTimbre}, /* string timbre r/w */
{{0x03, 0x06}, handleBPM}, /* BPM r/w */
{{0x03, 0x07}, handleTranspose}, /* transpose r/w */
/*======== 4. play / LED 0x04 ========*/
{{0x04, 0x00}, handleLED0}, /* LED 1 */
{{0x04, 0x01}, handleLED1}, /* LED 2 */
{{0x04, 0x02}, handleLED2}, /* LED 3 */
{{0x04, 0x03}, handleLED3}, /* LED 4 */
{{0x04, 0x04}, handleLED4}, /* LED 5 */
{{0x04, 0x05}, handleLED5}, /* LED 6 */
{{0x04, 0x06}, handleLED6}, /* LED 7 */
{{0x04, 0x07}, handleEnd}, /* end / stop play */
/*======== 5. reset / power off 0x05 ========*/
{{0x05, 0x00}, handleDeviceReset}, /* device reset -> soft power off */
/*======== 6. section jump 0x06 ========*/
{{0x06, 0x01}, handleIntro}, /* intro */
{{0x06, 0x02}, handleInterlude}, /* interlude */
{{0x06, 0x03}, handleOutro}, /* outro */
{{0x06, 0x05}, handleSectionA}, /* section A */
{{0x06, 0x06}, handleSectionB}, /* section B */
{{0x06, 0x07}, handleSectionC}, /* section C */
{{0x06, 0x08}, handleSectionD}, /* section D */
};
// ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define BLE_SYS_EX_CMD_COUNT (sizeof(bleSysExCmdTable) / sizeof(BLE_SysExCmdItem))
/**
* @brief <20><><EFBFBD><EFBFBD>SysExָ<78><D6B8>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
* @param data: <20><><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
* @param cnt: ֡<><D6A1><EFBFBD><EFBFBD>
*/
void processBLESysEXData(uint8_t* data, uint8_t cnt)
{
//ResetAutoPowerCount();
// <20><><EFBFBD><EFBFBD>֡У<D6A1><D0A3>
if (data[0] != FRAME_SYS_HEAD || data[cnt - 1] != FRAME_SYS_TAIL || cnt > UART4_PROCESS_BUFF_SIZE || data[1] != 0x60)
{
return;
}
// <20><>ȡ <20><>ָ<EFBFBD><D6B8> + <20><>ָ<EFBFBD><D6B8>
uint8_t cmd[2] = {data[2], data[3]};
// <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>ƥ<EFBFBD><C6A5>
for (uint8_t i = 0; i < BLE_SYS_EX_CMD_COUNT; i++)
{
if (memcmp(cmd, bleSysExCmdTable[i].cmd, 2) == 0)
{
if (bleSysExCmdTable[i].handler != NULL)
{
bleSysExCmdTable[i].handler(data);
}
return;
}
}
}
void UART4_Data_Process(volatile uint8_t* data)
{
uint8_t rcv = *data;
uint32_t now = rt_tick_get();
static uint32_t last_tick;
if(now - last_tick >= UART4_RCV_TIMEOUT_MS)
{
last_tick = now;
memset(UART4_Process_Buff, 0, sizeof(UART4_Process_Buff));
UART4_RCV_cnt = 0;
}
switch (UART4_RCV_Status)
{
case UART4_RCV_BUFF_IDLE:
memset(UART4_Process_Buff, 0, sizeof(UART4_Process_Buff));
UART4_RCV_cnt = 0;
switch(rcv & 0xF0)
{
case FRAME_SYS_HEAD:
UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
UART4_RCV_Status = UART4_RCV_BUFF_HEAD;
break;
case FRAME_MIDI_NOTEON:
case FRAME_MIDI_NOTEOFF:
case FRAME_MIDI_PROCHANGE:
UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
UART4_RCV_Status = UART4_RCV_BUFF_MIDI1;
break;
default:UART4_RCV_Status = UART4_RCV_BUFF_IDLE; return; break;
}
//UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
break;
case UART4_RCV_BUFF_MIDI1:
if((UART4_Process_Buff[0] & 0xF0) == FRAME_MIDI_PROCHANGE)
{
USART2_SendData(UART4_Process_Buff,UART4_RCV_cnt);
UART4_RCV_Status = UART4_RCV_BUFF_IDLE;
}
else
{
UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
UART4_RCV_Status = UART4_RCV_BUFF_MIDI2;
}
break;
case UART4_RCV_BUFF_MIDI2:
UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
USART2_SendData(UART4_Process_Buff,UART4_RCV_cnt);
UART4_RCV_Status = UART4_RCV_BUFF_IDLE;
break;
case UART4_RCV_BUFF_HEAD:
if (UART4_RCV_cnt < UART4_PROCESS_BUFF_SIZE)
{
UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
}
if (rcv == 0x60)
{
UART4_RCV_Status = UART4_RCV_BUFF_CMD1;
}
else
{
// <20>Ƿ<EFBFBD><C7B7>ֽڣ<D6BD><DAA3><EFBFBD>λ
UART4_RCV_Status = UART4_RCV_BUFF_IDLE;
}
break;
case UART4_RCV_BUFF_CMD1:
// <20><>ָ<EFBFBD><D6B8>
if (UART4_RCV_cnt < UART4_PROCESS_BUFF_SIZE)
{
UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
}
UART4_RCV_Status = UART4_RCV_BUFF_CMD2;
break;
case UART4_RCV_BUFF_CMD2:
// <20><>ָ<EFBFBD><D6B8>
if (UART4_RCV_cnt < UART4_PROCESS_BUFF_SIZE)
{
UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
}
UART4_RCV_Status = UART4_RCV_BUFF_DATA;
break;
case UART4_RCV_BUFF_DATA:
// <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD>ݣ<EFBFBD>ֱ<EFBFBD><D6B1>֡β 0xF7
if (UART4_RCV_cnt < UART4_PROCESS_BUFF_SIZE)
{
UART4_Process_Buff[UART4_RCV_cnt++] = rcv;
}
if (rcv == FRAME_SYS_TAIL)
{
// ִ<><D6B4>ָ<EFBFBD><EFBFBD><EEB4A6>
processBLESysEXData(UART4_Process_Buff, UART4_RCV_cnt);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD>λ״̬<D7B4><CCAC>
UART4_RCV_Status = UART4_RCV_BUFF_IDLE;
}
break;
default:
// δ֪״̬ǿ<CCAC>Ƹ<EFBFBD>λ
UART4_RCV_Status = UART4_RCV_BUFF_IDLE;
break;
}
}
static void handleStringTimbre(uint8_t *data)
{
switch(data[4])
{
case 0:
{
uint8_t ReturnTimbre[8] = {0xF0,0x60,0x03,0x05,0x00,0x00,0x00,0xF7};
ReturnTimbre[6] = mGuiData[GUI_TIMBRE_SELECT].Current;
USART4_SendData(ReturnTimbre,sizeof(ReturnTimbre));
}
break;
case 1:
{
NvmParam_Type * nvm = drv_nvm_param_ptr();
uint8_t new_val = data[6]; // <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ɫֵ
// <20><><EFBFBD>ֵû<D6B5>䣬ֱ<E4A3AC><D6B1><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD>ˢ<EFBFBD><CBA2>
if (new_val == mGuiData[GUI_TIMBRE_SELECT].Current)
{
return;
}
mGuiData[GUI_TIMBRE_SELECT].Current = new_val;
if(mGuiData[GUI_TAB_INDEX].Current != 3)
{
//Refresh_StringTimbre(last_value, &UI_Label[GUI_TIMBRE_SELECT], &mGuiData[GUI_TIMBRE_SELECT]);
}
if(nvm->param.Timbre != mGuiData[GUI_TIMBRE_SELECT].Current)
{
nvm->param.Timbre = mGuiData[GUI_TIMBRE_SELECT].Current;
drv_nvm_save_to_flash();
}
// uint8_t buff[10] = {0,};
// LCD_ShowString(200,30, Num_To_String(mGuiData[GUI_TIMBRE_SELECT].Current,buff,4), RED, WHITE, 16, 0);
}
break;
}
}
//extern int8_t delta;
extern STRING_MIDI USE_MIDI;
static void handleTranspose(uint8_t *data)
{
//uint8_t last_value;
switch(data[4])
{
case 0:
{
uint8_t ReturnTranspose[8] = {0xF0,0x60,0x03,0x07,0x00,0x00,0x00,0xF7};
ReturnTranspose[5] = mGuiData[GUI_TRANSPOSE].Current;
USART4_SendData(ReturnTranspose,sizeof(ReturnTranspose));
}
break;
case 1:
{
NvmParam_Type * nvm = drv_nvm_param_ptr();
uint8_t new_val = data[5]; // <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ɫֵ
// <20><><EFBFBD>ֵû<D6B5>䣬ֱ<E4A3AC><D6B1><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD>ˢ<EFBFBD><CBA2>
if (new_val == mGuiData[GUI_TRANSPOSE].Current)
{
return;
}
mGuiData[GUI_TRANSPOSE].Current = new_val;
if(mGuiData[GUI_TAB_INDEX].Current != 3)
{
Refresh_Transpose(&UI_Label[GUI_TRANSPOSE], &mGuiData[GUI_TRANSPOSE]);
}
if(nvm->param.Transpose != mGuiData[GUI_TRANSPOSE].Current)
{
nvm->param.Transpose = mGuiData[GUI_TRANSPOSE].Current;
drv_nvm_save_to_flash();
}
// delta = new_trans - last_value;
// USE_MIDI.Midi_1 += delta;
// USE_MIDI.Midi_2 += delta;
// USE_MIDI.Midi_3 += delta;
// USE_MIDI.Midi_4 += delta;
// USE_MIDI.Midi_5 += delta;
// USE_MIDI.Midi_6 += delta;
//AutoBandTop1_Note_On(USE_MIDI.Midi_6,0x50);
}
break;
}
}
// <20>յ<EFBFBD>˫<EFBFBD>ֽ<EFBFBD> hi, lo<6C><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>BPM
uint16_t Calc_BPM(uint8_t bpmHi, uint8_t bpmLo)
{
return (uint16_t)bpmHi * 128 + bpmLo;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>BPM<50><4D><EFBFBD><EFBFBD>ֳ<EFBFBD>hi<68><69>lo˫<6F>ֽ<EFBFBD>
void Split_BPM(uint16_t target_bpm, uint8_t *hi_out, uint8_t *lo_out)
{
*hi_out = target_bpm / 128;
*lo_out = target_bpm % 128;
}
static void handleBPM(uint8_t *data)
{
switch(data[4])
{
case 0:
{
uint8_t ReturnSpeed[8] = {0xF0,0x60,0x03,0x06,0x00,0x00,0x00,0xF7};
ReturnSpeed[5] = mGuiData[GUI_SPEED].Current / 128;
ReturnSpeed[6] = mGuiData[GUI_SPEED].Current % 128;
USART4_SendData(ReturnSpeed,sizeof(ReturnSpeed));
}
break;
case 1:
{
NvmParam_Type * nvm = drv_nvm_param_ptr();
uint16_t new_val = Calc_BPM(data[5],data[6]);
// <20><><EFBFBD>ֵû<D6B5>䣬ֱ<E4A3AC><D6B1><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD>ˢ<EFBFBD><CBA2>
if (new_val == mGuiData[GUI_SPEED].Current)
{
return;
}
mGuiData[GUI_SPEED].Current = new_val;
if(mGuiData[GUI_TAB_INDEX].Current != 3)
{
Refresh_Transpose(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]);
}
if(nvm->param.BPM != mGuiData[GUI_SPEED].Current)
{
nvm->param.BPM = mGuiData[GUI_SPEED].Current;
drv_nvm_save_to_flash();
}
AutoBandTop1_ChangeBPM(mGuiData[GUI_SPEED].Current);
}
break;
}
}
static void handleLED0(uint8_t *data)
{
// DefaultTask_SendMsg(MSG_ID_LIGHT_LED, LED_L1, data[5], 0);
BL_Sendmsg(MSG_ID_LIGHT_LED, LED_L1, data[5], 0);
}
static void handleLED1(uint8_t *data)
{
BL_Sendmsg(MSG_ID_LIGHT_LED, LED_L2, data[5], 0);
}
static void handleLED2(uint8_t *data)
{
BL_Sendmsg(MSG_ID_LIGHT_LED, LED_L3, data[5], 0);
}
static void handleLED3(uint8_t *data)
{
BL_Sendmsg(MSG_ID_LIGHT_LED, LED_L4, data[5], 0);
}
static void handleLED4(uint8_t *data)
{
BL_Sendmsg(MSG_ID_LIGHT_LED, LED_L5, data[5], 0);
}
static void handleLED5(uint8_t *data)
{
BL_Sendmsg(MSG_ID_LIGHT_LED, LED_L6, data[5], 0);
}
static void handleLED6(uint8_t *data)
{
BL_Sendmsg(MSG_ID_LIGHT_LED, LED_L7, data[5], 0);
}
static void handlePitchOffset(uint8_t *data)
{
BL_Sendmsg(MSG_ID_PITCH_OFFSET, data[4]+1, data[5], 0);
}
static void handleChordOffset(uint8_t *data)
{
BL_Sendmsg(MSG_ID_CHORD_OFFSET, data[4]+1, data[5], 0);
}
extern CHORD_TYPE_INDEX chord_type_index_map[22];
static void handleReadRhythmMap(uint8_t *data)
{
uint8_t ReadChordMap[47] = {0xF0, 0x60, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7};
uint8_t chord_map = 0;
for(uint8_t i = 1;i < 22;i ++)
{
ReadChordMap[3+i] = chord_type_index_map[i].PitchOffset;
}
for(uint8_t i = 25;i < 46;i ++)
{
switch(chord_type_index_map[i-24].type)
{
case 0:
chord_map = 0;
break;
case 1:
chord_map = 8;
break;
case 2:
chord_map = 2;
break;
case 3:
chord_map = 13;
break;
case 4:
chord_map = 10;
break;
case 5:
chord_map = 31;
break;
case 6:
chord_map = 30;
break;
case 7:
chord_map = 4;
break;
case 8:
chord_map = 11;
break;
}
ReadChordMap[i] = chord_map;
}
USART4_SendData(ReadChordMap,sizeof(ReadChordMap));
}
static void handleIntro(uint8_t *data)
{
BL_Sendmsg(MSG_ID_ADCIN1KEY, 3, 0, 0);
}
static void handleInterlude(uint8_t *data)
{
BL_Sendmsg(MSG_ID_ADCIN1KEY, 0, 0, 0);
}
static void handleOutro(uint8_t *data)
{
BL_Sendmsg(MSG_ID_ADCIN1KEY, 1, 0, 0);
}
static void handleEnd(uint8_t *data)
{
//DefaultTask_SendMsg(MSG_ID_ADCIN1KEY, 2, 0, 0);
// osMutexAcquire(Tm1629Mutex,osWaitForever);
// TM1629D_AllLedOff();
// TM1629D_AllLedOn(LED_COLOR_G);
// TM1629D_UpdateDisplay(0);
// osMutexRelease(Tm1629Mutex);
BL_Sendmsg(MSG_ID_ADCIN1KEY, 2, 0, 0); /* End -> Postamble(1), distinct from Outro(key=1) */
}
static void handleSectionA(uint8_t *data)
{
BL_Sendmsg(MSG_ID_KEY_1617, 3, 0, 0);
}
static void handleSectionB(uint8_t *data)
{
BL_Sendmsg(MSG_ID_KEY_1617, 2, 0, 0);
}
static void handleSectionC(uint8_t *data)
{
BL_Sendmsg(MSG_ID_KEY_1617, 1, 0, 0);
}
static void handleSectionD(uint8_t *data)
{
BL_Sendmsg(MSG_ID_KEY_1617, 0, 0, 0);
}
static void BL_Sendmsg(uint16_t Data1, uint16_t Data2, uint16_t Data3, uint16_t Data4)
{
BLTask_Sendmsg(Data1, Data2, Data3, Data4);
}
/* ======================================================================
* Appended protocol handlers (per Doc/指令测试.docx)
* ==================================================================== */
/*-------- 1. device info 0x01 --------*/
#define BLE_DEVICE_NAME "PHON_145" /* must match BLE module broadcast name */
#define AT32_UID_BASE 0x1FFFF7E8UL /* 96-bit unique device ID */
/* placeholders: sound fw lives on Dream DSP side, UI/user-fw ver bumped per release */
static const uint8_t SOUND_VER[4] = {0x4D, 0x06, 0x7F, 0x01};
static const uint8_t UI_VER[4] = {0x21, 0x05, 0x7F, 0x01};
static const uint8_t USER_FW_VER[4] = {0x4D, 0x06, 0x7F, 0x01};
static void handleDevDisconnect(uint8_t *data)
{
uint8_t resp[6] = {0xF0, 0x60, 0x01, 0x00, 0x01, 0xF7};
(void)data;
USART4_SendData(resp, sizeof(resp));
}
static void handleDevConnect(uint8_t *data)
{
uint8_t resp[6] = {0xF0, 0x60, 0x01, 0x01, 0x01, 0xF7};
(void)data;
ResetAutoPowerCount();
USART4_SendData(resp, sizeof(resp));
}
static void handleDevName(uint8_t *data)
{
uint8_t resp[4 + sizeof(BLE_DEVICE_NAME)]; /* head4 + name + tail1 */
(void)data;
resp[0] = 0xF0; resp[1] = 0x60; resp[2] = 0x01; resp[3] = 0x02;
memcpy(&resp[4], BLE_DEVICE_NAME, sizeof(BLE_DEVICE_NAME) - 1);
resp[sizeof(resp) - 1] = 0xF7;
USART4_SendData(resp, sizeof(resp));
}
static void handleFwMainVer(uint8_t *data)
{
uint8_t resp[9] = {0xF0, 0x60, 0x01, 0x03, Version[0], Version[1], Version[2], 0x01, 0xF7};
(void)data;
USART4_SendData(resp, sizeof(resp));
}
static void handleSoundVer(uint8_t *data)
{
uint8_t resp[9] = {0xF0, 0x60, 0x01, 0x04, SOUND_VER[0], SOUND_VER[1], SOUND_VER[2], SOUND_VER[3], 0xF7};
(void)data;
USART4_SendData(resp, sizeof(resp));
}
static void handleUIVer(uint8_t *data)
{
uint8_t resp[9] = {0xF0, 0x60, 0x01, 0x05, UI_VER[0], UI_VER[1], UI_VER[2], UI_VER[3], 0xF7};
(void)data;
USART4_SendData(resp, sizeof(resp));
}
static void handleOtherInfo(uint8_t *data)
{
uint8_t resp[13] = {0xF0, 0x60, 0x01, 0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0xF7};
(void)data;
USART4_SendData(resp, sizeof(resp));
}
static void handleDevCode(uint8_t *data)
{
uint8_t resp[17] = {0xF0, 0x60, 0x01, 0x07};
(void)data;
memcpy(&resp[4], (const void *)AT32_UID_BASE, 12);
resp[16] = 0xF7;
USART4_SendData(resp, sizeof(resp));
}
static void handleAutoPowerOff(uint8_t *data)
{
uint8_t resp[6] = {0xF0, 0x60, 0x01, 0x0A, 0x00, 0xF7};
(void)data;
resp[4] = AutoCloseTime;
USART4_SendData(resp, sizeof(resp));
}
static void handleUserFwVer(uint8_t *data)
{
uint8_t resp[9] = {0xF0, 0x60, 0x01, 0x0C, USER_FW_VER[0], USER_FW_VER[1], USER_FW_VER[2], USER_FW_VER[3], 0xF7};
(void)data;
USART4_SendData(resp, sizeof(resp));
}
/* F0 60 01 11 <minutes> F7 : set auto power-off, 0 = disable */
static void handleAutoPowerOffSet(uint8_t *data)
{
NvmParam_Type *nvm = drv_nvm_param_ptr();
uint8_t resp[6] = {0xF0, 0x60, 0x01, 0x11, 0x00, 0xF7};
AutoCloseTime = data[4];
if (nvm->param.AutoCloseTime != AutoCloseTime)
{
nvm->param.AutoCloseTime = AutoCloseTime;
drv_nvm_save_to_flash();
}
ResetAutoPowerCount();
resp[4] = AutoCloseTime;
USART4_SendData(resp, sizeof(resp));
}
static void handleFwCode(uint8_t *data)
{
uint8_t resp[16];
uint8_t len = (uint8_t)strlen(fwname); /* "BRS08L" */
(void)data;
resp[0] = 0xF0; resp[1] = 0x60; resp[2] = 0x01; resp[3] = 0xFF;
memcpy(&resp[4], fwname, len);
resp[4 + len] = 0xF7;
USART4_SendData(resp, (uint16_t)(4 + len + 1));
}
/*-------- 2. chord map 0x02 --------*/
/* F0 60 02 04 <21B pitch> <21B chord> F7 : write whole map; reply in 02 01 format */
static void handleResetChordMap(uint8_t *data)
{
uint8_t key;
for (key = 1; key <= 21; key++)
{
BT_Pitch_offset_map(key, data[3 + key]); /* data[4..24] pitch offsets */
BT_Chord_offset_map(key, data[24 + key]); /* data[25..45] chord types */
}
handleReadRhythmMap(data);
}
/*-------- 3. rhythm style 0x03 0x04 --------*/
static void handleRhythmStyle(uint8_t *data)
{
switch (data[4])
{
case 0: /* read current style: F0 60 03 04 00 <src> <idHi> <idLo> F7 */
{
uint8_t resp[9] = {0xF0, 0x60, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0xF7};
uint8_t src = (uint8_t)(mGuiData[GUI_AUTOBAND_SW].Current ? 1 : 0);
uint16_t id = src ? ParamGuiData[EXPRESS_MODE_PARAM].Current
: ParamGuiData[SONG_MODE_PARAM].Current;
resp[5] = src;
resp[6] = (uint8_t)(id / 128);
resp[7] = (uint8_t)(id % 128);
USART4_SendData(resp, sizeof(resp));
}
break;
case 1: /* set style: F0 60 03 04 01 <src:0 sys/1 user> <idHi> <idLo> F7, reply BPM */
{
uint8_t src = (data[5] != 0) ? 1 : 0;
uint16_t id = (uint16_t)data[6] * 128 + data[7];
GUI_SWITCH *slot = src ? &ParamGuiData[EXPRESS_MODE_PARAM]
: &ParamGuiData[SONG_MODE_PARAM];
uint8_t resp[7] = {0xF0, 0x60, 0x03, 0x04, 0x01, 0x00, 0xF7};
if (src)
slot->Max = (LOCAL_SONG_COUNT > 0) ? (uint16_t)(LOCAL_SONG_COUNT - 1) : 0;
if (id > slot->Max)
id = slot->Max;
mGuiData[GUI_AUTOBAND_SW].Current = src;
slot->Current = id;
StartFlag = 0;
AutoBandTop1_Stop();
UI_ReloadTonePreset();
resp[5] = (uint8_t)(mGuiData[GUI_SPEED].Current & 0x7F); /* doc: single-byte bpm */
USART4_SendData(resp, sizeof(resp));
}
break;
case 2: /* user style list page: reply total count */
case 3: /* user style total */
{
uint8_t resp[8] = {0xF0, 0x60, 0x03, 0x04, 0x00, 0x00, 0x00, 0xF7};
resp[4] = data[4];
resp[5] = (uint8_t)(LOCAL_SONG_COUNT / 128);
resp[6] = (uint8_t)(LOCAL_SONG_COUNT % 128);
USART4_SendData(resp, sizeof(resp));
}
break;
default:
break;
}
}
/*-------- 5. reset / power off 0x05 --------*/
/* F0 60 05 00 F7 : ack then soft power off (executed in main-loop context) */
static void handleDeviceReset(uint8_t *data)
{
uint8_t resp[6] = {0xF0, 0x60, 0x05, 0x00, 0x01, 0xF7};
(void)data;
USART4_SendData(resp, sizeof(resp));
System_RequestPowerOff();
}