Files
RP2350_MIDI_Lighter/Firmware/Core1_MIDI_Receiver.c
Christian Leibold 43f37e0b57 - Added POGRAM CHANGES to switch Mode via MIDI
- Added Control Change to switch On/Off Pause Light
2025-11-24 09:37:03 +01:00

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;
}
}