#include "includes.h" // Э��֡ͷ/֡β #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����״̬ö�� */ typedef enum { UART4_RCV_BUFF_IDLE, // ����״̬ UART4_RCV_BUFF_HEAD, // ����֡ͷ��̶��ֽ�(0x60/0x51) UART4_RCV_BUFF_CMD1, // ��ָ�� UART4_RCV_BUFF_CMD2, // ��ָ�� UART4_RCV_BUFF_DATA, // ������ UART4_RCV_BUFF_END, // ֡β���� UART4_RCV_BUFF_MIDI1, UART4_RCV_BUFF_MIDI2, UART4_RCV_BUFF_MIDIEND } UART4_RCV_StatusType; #define UART4_PROCESS_BUFF_SIZE 32 // UART4����ȫ�ֱ��� 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 ָ����ṹ�壨��ȫ����UART3��� */ typedef struct { uint8_t cmd[2]; // ��ָ��+��ָ�� void (*handler)(uint8_t *data);// ��Ӧ�������� } BLE_SysExCmdItem; // ============================== // ָ�������������ȫ�� static�� // ============================== //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 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 handleStopPlay(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); /************************************************* * ����ָ������ϸ����Э���ĵ��� *************************************************/ static const BLE_SysExCmdItem bleSysExCmdTable[] = { // //======== 1. ��ȡ������Ϣ 0x01 ======== // {{0x01, 0x00}, handleDevDisconnect}, // �Ͽ��豸 // {{0x01, 0x01}, handleDevConnect}, // �����豸 // {{0x01, 0x02}, handleDevName}, // ��ȡ�豸�� // {{0x01, 0x03}, handleFwMainVer}, // �̼����汾 // {{0x01, 0x04}, handleSoundVer}, // ��Դ�汾 // {{0x01, 0x05}, handleUIVer}, // UI�汾 // {{0x01, 0x06}, handleOtherInfo}, // ������Ϣ // {{0x01, 0x07}, handleDevCode}, // �豸���� // {{0x01, 0x0A}, handleAutoPowerOff}, // �Զ��ػ� // // //======== 2. ӳ������ 0x02 ======== {{0x02, 0x01}, handleReadRhythmMap}, // ��ȡ����/����ӳ��� {{0x02, 0x02}, handlePitchOffset}, // Pitchƫ�� {{0x02, 0x03}, handleChordOffset}, // Chordƫ�� // {{0x02, 0x04}, handleResetChordMap}, // ���ú���ӳ��Ĭ��ֵ //======== 3. ����������д 0x03 ======== // {{0x03, 0x04}, handleRhythmStyle}, // ��ȡ/���ý����� {{0x03, 0x05}, handleStringTimbre}, // ��ȡ/��������ɫ {{0x03, 0x06}, handleBPM}, // ��ȡ/����BPM {{0x03, 0x07}, handleTranspose}, // ��ȡ/�����Ƶ� //======== 4. ����/LED���� 0x04 ======== {{0x04, 0x00}, handleLED0}, // ��1��LED {{0x04, 0x01}, handleLED1}, // ��2��LED {{0x04, 0x02}, handleLED2}, // ��3��LED {{0x04, 0x03}, handleLED3}, // ��4��LED {{0x04, 0x04}, handleLED4}, // ��5��LED {{0x04, 0x05}, handleLED5}, // ��6��LED {{0x04, 0x06}, handleLED6}, // ��7��LED // {{0x04, 0x07}, handleStopPlay}, // �������� // //======== 5. ��λ/�ػ� 0x05 ======== // {{0x05, 0x00}, handleDeviceReset}, // �豸��λ // // //======== 6. ������ת 0x06 ======== {{0x06, 0x01}, handleIntro}, // ǰ�� {{0x06, 0x02}, handleInterlude}, // ���� {{0x06, 0x03}, handleOutro}, // β�� {{0x04, 0x07}, handleEnd}, // end {{0x06, 0x05}, handleSectionA}, // A�� {{0x06, 0x06}, handleSectionB}, // B�� {{0x06, 0x07}, handleSectionC}, // C�� {{0x06, 0x08}, handleSectionD}, // D�� }; // ָ������ #define BLE_SYS_EX_CMD_COUNT (sizeof(bleSysExCmdTable) / sizeof(BLE_SysExCmdItem)) /** * @brief ����SysExָ��ַ����� * @param data: ����֡���� * @param cnt: ֡���� */ void processBLESysEXData(uint8_t* data, uint8_t cnt) { //ResetAutoPowerCount(); // ����֡У�� if (data[0] != FRAME_SYS_HEAD || data[cnt - 1] != FRAME_SYS_TAIL || cnt > UART4_PROCESS_BUFF_SIZE || data[1] != 0x60) { return; } // ��ȡ ��ָ�� + ��ָ�� uint8_t cmd[2] = {data[2], data[3]}; // ����ָ���ƥ�� 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 { // �Ƿ��ֽڣ���λ UART4_RCV_Status = UART4_RCV_BUFF_IDLE; } break; case UART4_RCV_BUFF_CMD1: // ��ָ�� 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: // ��ָ�� 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: // �����м����ݣ�ֱ��֡β 0xF7 if (UART4_RCV_cnt < UART4_PROCESS_BUFF_SIZE) { UART4_Process_Buff[UART4_RCV_cnt++] = rcv; } if (rcv == FRAME_SYS_TAIL) { // ִ��ָ��� processBLESysEXData(UART4_Process_Buff, UART4_RCV_cnt); // ������ɣ���λ״̬�� UART4_RCV_Status = UART4_RCV_BUFF_IDLE; } break; default: // δ֪״̬ǿ�Ƹ�λ 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]; // �õ�����ɫֵ // ���ֵû�䣬ֱ���˳�����ˢ�� 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]; // �õ�����ɫֵ // ���ֵû�䣬ֱ���˳�����ˢ�� 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; } } // �յ�˫�ֽ� hi, lo������ʵ��BPM uint16_t Calc_BPM(uint8_t bpmHi, uint8_t bpmLo) { return (uint16_t)bpmHi * 128 + bpmLo; } // ������������Ŀ��BPM����ֳ�hi��lo˫�ֽ� 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]); // ���ֵû�䣬ֱ���˳�����ˢ�� 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, 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, 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, 1, 0, 0); } 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); }