- Fixed drawing of round objects (Circles, Rounded Rects) using a lookup table
- Added function to read out the display_buffer via USB-Serial - Added basic structure and files for later complete firmware (still in progress) - Added Doc folder with schematic in it - Added Python script and batch file to read out the display buffer and open the image in gimp
This commit is contained in:
157
Firmware/Core1_MIDI_Receiver.c
Normal file
157
Firmware/Core1_MIDI_Receiver.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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<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_Note = 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)
|
||||
{
|
||||
_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);
|
||||
}
|
||||
Reference in New Issue
Block a user