/* * Core1_MIDI_Receiver.c * * Created: Thu Jan 13 2022 15:35:28 * Author Chris */ // ============================================================================================ // Includes #include "Core1_MIDI_Receiver.h" #include "UART0.h" #include "Command_Definition.h" #include "pico/time.h" // ============================================================================================ // Defines #define NOTE_UNDEFINED 255 // ============================================================================================ // Variables enum PARSING_STATE_e { WAITING_FOR_COMMAND, WAITING_FOR_DATA1, WAITING_FOR_DATA2 }; struct PARSING_s { enum PARSING_STATE_e State; uint8_t MIDI_Event; uint8_t MIDI_Channel; uint8_t MIDI_Data1; }; volatile struct PARSING_s _Parsing; History_Buffer_t _MIDI_History_Buffer[RECEIVED_MIDI_HISTORY_BUFFER_SIZE]; // ============================================================================================ // Function Declarations void Core1_MIDI_Receiver_Histroy_Update (uint8_t data); void Core1_MIDI_Receiver_Issue_Event_On_Off_Received(uint8_t midi_channel, uint8_t midi_event); void Core1_MIDI_Receiver_Issue_Data_Received (uint8_t midi_data); void Core1_MIDI_Receiver_Issue_Full_Event_Received (uint8_t midi_event, uint8_t midi_channel, uint8_t midi_data1, uint8_t midi_data2); /******************************************************************* Interrupt Service Routines *******************************************************************/ /******************************************************************* Functions *******************************************************************/ void Core1_MIDI_Receiver_Init(void) { UART0_Init(); for(uint i=0;i 0) { uint8_t Data = UART0_Get_Byte(); Core1_MIDI_Receiver_Histroy_Update(Data); switch(_Parsing.State) { case WAITING_FOR_COMMAND: if(MIDI_EVENT_FROM_COMMAND(Data) == MIDI_EVENT_NOTE_ON || MIDI_EVENT_FROM_COMMAND(Data) == MIDI_EVENT_NOTE_OFF) { _Parsing.MIDI_Event = MIDI_EVENT_FROM_COMMAND(Data); _Parsing.MIDI_Channel = MIDI_CHANNEL_FROM_COMMAND(Data); _Parsing.State = WAITING_FOR_DATA1; Core1_MIDI_Receiver_Issue_Event_On_Off_Received(_Parsing.MIDI_Channel, _Parsing.MIDI_Event); break; } Core1_MIDI_Receiver_Issue_Data_Received(Data); break; case WAITING_FOR_DATA1: if(IS_MIDI_DATA(Data)) { _Parsing.MIDI_Data1 = Data; _Parsing.State = WAITING_FOR_DATA2; } else { // Received another command after just receiving a command. This should not happen, but // in case it does, reset the parsing state machine _Parsing.State = WAITING_FOR_COMMAND; } break; case WAITING_FOR_DATA2: if(IS_MIDI_DATA(Data)) { Core1_MIDI_Receiver_Issue_Full_Event_Received(_Parsing.MIDI_Event, _Parsing.MIDI_Channel, _Parsing.MIDI_Data1, Data); } // Reset State Machine and wait for next MIDI Command _Parsing.State = WAITING_FOR_COMMAND; break; default: break; } } } /******************************************************************* Internal Functions *******************************************************************/ void Core1_MIDI_Receiver_Histroy_Update(uint8_t data) { for(uint i=RECEIVED_MIDI_HISTORY_BUFFER_SIZE-1;i>0;i--) { _MIDI_History_Buffer[i] = _MIDI_History_Buffer[i-1]; } _MIDI_History_Buffer[0].Data = data; _MIDI_History_Buffer[0].Timestamp_ms = to_ms_since_boot(get_absolute_time()); } void Core1_MIDI_Receiver_Issue_Event_On_Off_Received(uint8_t midi_channel, uint8_t midi_event) { Core1_Light_Controller_MIDI_OnOff_Event_Received(midi_event, midi_channel); } void Core1_MIDI_Receiver_Issue_Data_Received(uint8_t midi_data) { Core1_Light_Controller_MIDI_Other_Event_Received(midi_data); } void Core1_MIDI_Receiver_Issue_Full_Event_Received(uint8_t midi_event, uint8_t midi_channel, uint8_t midi_data1, uint8_t midi_data2) { if(midi_event == MIDI_EVENT_CONTROL_CHANGE) { Core1_Light_Controller_MIDI_Full_CC_Received(midi_event, midi_channel, midi_data1, midi_data2); } else { Core1_Light_Controller_MIDI_Full_Note_Received(midi_event, midi_channel, midi_data1, midi_data2); } }