185 lines
5.2 KiB
C
185 lines
5.2 KiB
C
/*
|
|
* 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<RECEIVED_MIDI_HISTORY_BUFFER_SIZE;i++)
|
|
{
|
|
_MIDI_History_Buffer[i].Data = HISTORY_ENTRY_UNDEFINED;
|
|
_MIDI_History_Buffer[i].Timestamp_ms = 0;
|
|
}
|
|
|
|
_Parsing.State = WAITING_FOR_COMMAND;
|
|
_Parsing.MIDI_Event = MIDI_EVENT_NOTE_ON;
|
|
_Parsing.MIDI_Channel = MIDI_CHANNEL_1;
|
|
_Parsing.MIDI_Data1 = NOTE_UNDEFINED;
|
|
}
|
|
|
|
void Core1_MIDI_Receiver_Process(void)
|
|
{
|
|
while(UART0_Data_Available() > 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 ||
|
|
MIDI_EVENT_FROM_COMMAND(Data) == MIDI_EVENT_CONTROL_CHANGE ||
|
|
MIDI_EVENT_FROM_COMMAND(Data) == MIDI_EVENT_PROGRAM_CHANGE
|
|
)
|
|
{
|
|
_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;
|
|
|
|
if(_Parsing.MIDI_Event == MIDI_EVENT_PROGRAM_CHANGE) {
|
|
_Parsing.State = WAITING_FOR_COMMAND;
|
|
Core1_MIDI_Receiver_Issue_Full_Event_Received(_Parsing.MIDI_Event, _Parsing.MIDI_Channel, _Parsing.MIDI_Data1, NOTE_UNDEFINED);
|
|
}
|
|
else {
|
|
_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)
|
|
{
|
|
switch (midi_event)
|
|
{
|
|
case MIDI_EVENT_NOTE_ON:
|
|
case MIDI_EVENT_NOTE_OFF:
|
|
Core1_Light_Controller_MIDI_Full_Note_Received(midi_event, midi_channel, midi_data1, midi_data2);
|
|
break;
|
|
|
|
case MIDI_EVENT_PROGRAM_CHANGE:
|
|
Core1_Light_Controller_MIDI_Full_ProgramChange_Received(midi_event, midi_channel, midi_data1);
|
|
break;
|
|
|
|
case MIDI_EVENT_CONTROL_CHANGE:
|
|
Core1_Light_Controller_MIDI_Full_ControlChange_Received(midi_event, midi_channel, midi_data1, midi_data2);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} |