/* * 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_NOTE, WAITING_FOR_VALUE }; struct PARSING_s { enum PARSING_STATE_e State; uint8_t MIDI_Event; uint8_t MIDI_Channel; uint8_t MIDI_Note; }; 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_Note_Received (uint8_t midi_event, uint8_t midi_channel, uint8_t midi_note, uint8_t value); /******************************************************************* 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_NOTE; 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_NOTE: if(IS_MIDI_DATA(Data)) { _Parsing.MIDI_Note = Data; _Parsing.State = WAITING_FOR_VALUE; } 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_VALUE: if(IS_MIDI_DATA(Data)) { Core1_MIDI_Receiver_Issue_Full_Note_Received(_Parsing.MIDI_Event, _Parsing.MIDI_Channel, _Parsing.MIDI_Note, 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_Note_Received(uint8_t midi_event, uint8_t midi_channel, uint8_t midi_note, uint8_t value) { Core1_Light_Controller_MIDI_Full_Note_Received(midi_event, midi_channel, midi_note, value); }