From 43f37e0b5703aa3fc154a1cc2edc742c0d5a72d6 Mon Sep 17 00:00:00 2001 From: Christian Leibold Date: Mon, 24 Nov 2025 09:37:03 +0100 Subject: [PATCH] - Added POGRAM CHANGES to switch Mode via MIDI - Added Control Change to switch On/Off Pause Light --- Firmware/Command_Definition.h | 7 +- Firmware/Core1.c | 14 +++- Firmware/Core1_Light_Controller.c | 119 ++++++++++++++++++++++-------- Firmware/Core1_Light_Controller.h | 7 +- Firmware/Core1_MIDI_Receiver.c | 41 +++++++--- Firmware/Mode_Manager.c | 13 ++++ Firmware/build/build_number.txt | 2 +- 7 files changed, 159 insertions(+), 44 deletions(-) diff --git a/Firmware/Command_Definition.h b/Firmware/Command_Definition.h index 9b85397..46ae71d 100644 --- a/Firmware/Command_Definition.h +++ b/Firmware/Command_Definition.h @@ -82,6 +82,10 @@ #define MULTICORE_COMMAND_GET_LED_ENABLE_PIN 'c' #define MULTICORE_COMMAND_GET_LED_ALERT_PIN 'd' +// Mode Change via MIDI // +#define MULTICORE_COMMAND_GET_MODE_CHANGE_RECEIVED 'e' +#define MULTICORE_COMMAND_GET_MODE_CHANGE_NEW_MODE 'f' + // ============================================================================================ // Datatypes @@ -284,7 +288,8 @@ enum Idle_Screen #define MIDI_SYSTEM_RESET 0xF // Reset // MIDI Control Changes -#define MIDI_CC_ALL_NOTES_OFF 0x7B // [Channel Mode Message] All Notes Off +#define MIDI_CC_GENERAL_PURPOSE_ONOFF_1 0x52 // Generic on/off switch ≤63 off, ≥64 on (82) +#define MIDI_CC_ALL_NOTES_OFF 0x7B // [Channel Mode Message] All Notes Off (123) ///////////////////////////////////////// diff --git a/Firmware/Core1.c b/Firmware/Core1.c index 6e9d43b..8c5a5e1 100644 --- a/Firmware/Core1.c +++ b/Firmware/Core1.c @@ -102,14 +102,22 @@ void Core1_Parse_Command(uint8_t command, uint8_t parameter, int16_t value) case MULTICORE_COMMAND_SET_INA260_BUSVOLTAGE: Core1_LED_Enable_Update_INA260_BusVoltage((uint16_t)value); break; - /////////////////// - // Get Functions // - /////////////////// + /////////////////////////////////////// + // Get Functions Voltage Supervision // + /////////////////////////////////////// case MULTICORE_COMMAND_GET_ANALOG_VOLTAGE: Core1_Send_Multicore_Answer(command, 0, (int16_t)Core1_ADC_Get_Result_mV()); break; case MULTICORE_COMMAND_GET_LED_POWER_ERROR: Core1_Send_Multicore_Answer(command, 0, (int16_t)Core1_LED_Enable_Get_Error()); break; case MULTICORE_COMMAND_GET_LED_ENABLE_PIN: Core1_Send_Multicore_Answer(command, 0, (int16_t)Core1_LED_Enable_Get_Enable_Pin()); break; case MULTICORE_COMMAND_GET_LED_ALERT_PIN: Core1_Send_Multicore_Answer(command, 0, (int16_t)Core1_LED_Enable_Get_Alert_Pin()); break; + + //////////////////////////////////////// + // Get Functions Mode Change via MIDI // + //////////////////////////////////////// + case MULTICORE_COMMAND_GET_MODE_CHANGE_RECEIVED: Core1_Send_Multicore_Answer(command, 0, (int16_t)Core1_Light_Controller_Get_Mode_Change_Received(LED_Channel_1)); break; + case MULTICORE_COMMAND_GET_MODE_CHANGE_NEW_MODE: Core1_Send_Multicore_Answer(command, 0, (int16_t)Core1_Light_Controller_Get_Mode_Change_New_Mode(LED_Channel_1)); break; + + default: break; } } diff --git a/Firmware/Core1_Light_Controller.c b/Firmware/Core1_Light_Controller.c index ab8110d..748e77a 100644 --- a/Firmware/Core1_Light_Controller.c +++ b/Firmware/Core1_Light_Controller.c @@ -27,8 +27,6 @@ #define NOTE_COLOR_COUNT_RESET_THRESHOLD_TICKS (_EEPROM_Content.Channel_MIDI_Configuration[ch].Note_Reset_Timeout * (1000 / TIMER_INTERVALL_LED_UPDATE_ms)) -// #define COUNT_APPLIED_NOTES - // ============================================================================================ // Datatypes @@ -45,6 +43,9 @@ volatile Pause_Light_Timer_s _Pause_Light_Timer[NUM_LED_CHANNELS]; volatile int _NoteOn_Color_Counter[NUM_LED_CHANNELS][NUM_LED_COLORS]; volatile int _NoteOn_Color_Reset_Counter; +static bool _Mode_Change_Received[NUM_LED_CHANNELS]; +static Mode _Mode_Change_New_Mode[NUM_LED_CHANNELS]; + // 1 LED Channel, 3 LED Colors, 2 Event Types (Note On & Off) int32_t _Event_Received_Counter[NUM_LED_CHANNELS][NUM_LED_COLORS][2]; @@ -120,6 +121,9 @@ void Core1_Light_Controller_Init(void) _Event_Received_Counter[ch][col][MIDI_EVENT_NOTE_OFF - MIDI_EVENT_NOTE_OFF] = 0; _Event_Received_Counter[ch][col][MIDI_EVENT_NOTE_ON - MIDI_EVENT_NOTE_OFF] = 0; } + + _Mode_Change_Received[ch] = false; + _Mode_Change_New_Mode[ch] = MIDI; } Core1_Light_Controller_Reset_NoteOn_Counter(); @@ -322,32 +326,68 @@ void Core1_Light_Controller_MIDI_Full_Note_Received(uint8_t midi_event, uint8_t } } -void Core1_Light_Controller_MIDI_Full_CC_Received(uint8_t midi_event, uint8_t midi_channel, uint8_t controller_number, uint8_t controller_value) +void Core1_Light_Controller_MIDI_Full_ProgramChange_Received(uint8_t midi_event, uint8_t midi_channel, uint8_t program_number) +{ + Core1_Light_Controller_Pause_Light_Trigger(midi_event, midi_channel); + + if(midi_event != MIDI_EVENT_PROGRAM_CHANGE) { + return; + } + + for(uint32_t ch=0;ch= 64); - Core1_LED_Control_Set_DC_Direct(ch, R, 0); - Core1_LED_Control_Set_DC_Direct(ch, G, 0); - Core1_LED_Control_Set_DC_Direct(ch, B, 0); - break; + if(!_EEPROM_Content.Pause_Light_Configuration[ch].Enabled) + { + _Pause_Light_Timer[ch].Timer = 0; + Core1_LED_Control_Set_Fade_Speed(ch, 0); + } + break; + + case MIDI_CC_ALL_NOTES_OFF: + Core1_Light_Controller_Reset_NoteOn_Counter(); + break; - default: - break; - } - } + default: + break; + } } } @@ -355,12 +395,34 @@ void Core1_Light_Controller_Set_MIDI_To_Light_Enabled(bool enabled) { _MIDI_To_Light_Enabled = enabled; - for(uint ch=0;ch= NUM_LED_CHANNELS) { + return false; + } + + bool Return_Value = _Mode_Change_Received[channel]; + + _Mode_Change_Received[channel] = false; + + return Return_Value; +} + +Mode Core1_Light_Controller_Get_Mode_Change_New_Mode(enum LED_Channel channel) +{ + if(channel >= NUM_LED_CHANNELS) { + return MIDI; + } + + return _Mode_Change_New_Mode[channel]; +} + /******************************************************************* Internal Functions @@ -389,7 +451,7 @@ bool Core1_Light_Controller_Check_Octave_Match(enum LED_Channel channel, uint mi void Core1_Light_Controller_Pause_Light_Trigger(uint8_t midi_event, uint8_t midi_channel) { - for(uint ch=0;ch 0) { - Core1_LED_Control_Set_DC_Direct(ch, l, 0); - } - - _NoteOn_Color_Counter[ch][l] = 0; - } + if(_NoteOn_Color_Counter[ch][R] > 0) { Core1_LED_Control_Set_DC_Direct(ch, R, 0); } + if(_NoteOn_Color_Counter[ch][G] > 0) { Core1_LED_Control_Set_DC_Direct(ch, G, 0); } + if(_NoteOn_Color_Counter[ch][B] > 0) { Core1_LED_Control_Set_DC_Direct(ch, B, 0); } + + _NoteOn_Color_Counter[ch][R] = 0; + _NoteOn_Color_Counter[ch][G] = 0; + _NoteOn_Color_Counter[ch][B] = 0; } } diff --git a/Firmware/Core1_Light_Controller.h b/Firmware/Core1_Light_Controller.h index 006cd4c..2766cb6 100644 --- a/Firmware/Core1_Light_Controller.h +++ b/Firmware/Core1_Light_Controller.h @@ -14,6 +14,7 @@ #include "pico/types.h" +#include "Mode_Manager.h" #include "EEPROM_M24C64.h" #include "Command_Definition.h" @@ -34,10 +35,14 @@ void Core1_Light_Controller_Tick(void); void Core1_Light_Controller_MIDI_OnOff_Event_Received(uint8_t midi_command_shifted_right, uint8_t midi_channel); void Core1_Light_Controller_MIDI_Other_Event_Received(uint8_t midi_data); void Core1_Light_Controller_MIDI_Full_Note_Received(uint8_t midi_event, uint8_t midi_channel, uint8_t midi_note, uint8_t value); -void Core1_Light_Controller_MIDI_Full_CC_Received(uint8_t midi_event, uint8_t midi_channel, uint8_t controller_number, uint8_t controller_value); +void Core1_Light_Controller_MIDI_Full_ProgramChange_Received(uint8_t midi_event, uint8_t midi_channel, uint8_t program_number); +void Core1_Light_Controller_MIDI_Full_ControlChange_Received(uint8_t midi_event, uint8_t midi_channel, uint8_t controller_number, uint8_t controller_value); void Core1_Light_Controller_Set_MIDI_To_Light_Enabled(bool enabled); Note_t Core1_Light_Controller_Get_Octave_Note_For_Channel(enum LED_Channel channel); Value_t Core1_Light_Controller_Get_Note_Value_For_Channel(enum LED_Channel channel); + +bool Core1_Light_Controller_Get_Mode_Change_Received(enum LED_Channel channel); +Mode Core1_Light_Controller_Get_Mode_Change_New_Mode(enum LED_Channel channel); #endif /* CORE1_LIGHT_CONTROLLER_H_ */ diff --git a/Firmware/Core1_MIDI_Receiver.c b/Firmware/Core1_MIDI_Receiver.c index 1802c56..c2c69b3 100644 --- a/Firmware/Core1_MIDI_Receiver.c +++ b/Firmware/Core1_MIDI_Receiver.c @@ -83,13 +83,17 @@ void Core1_MIDI_Receiver_Process(void) 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) + 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); + // Core1_MIDI_Receiver_Issue_Event_On_Off_Received(_Parsing.MIDI_Channel, _Parsing.MIDI_Event); break; } @@ -100,7 +104,14 @@ void Core1_MIDI_Receiver_Process(void) if(IS_MIDI_DATA(Data)) { _Parsing.MIDI_Data1 = Data; - _Parsing.State = WAITING_FOR_DATA2; + + 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 { @@ -153,10 +164,22 @@ 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) { - 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); - } + 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; + } } \ No newline at end of file diff --git a/Firmware/Mode_Manager.c b/Firmware/Mode_Manager.c index d7ad31c..542d301 100644 --- a/Firmware/Mode_Manager.c +++ b/Firmware/Mode_Manager.c @@ -54,6 +54,19 @@ void Mode_Manager_Init(void) void Mode_Manager_Tick(void) { + Command_Issue_Get_Request(MULTICORE_COMMAND_GET_MODE_CHANGE_RECEIVED, 0); + bool New_Mode_Received = Command_Get_Request_Response_By_Command_Only(MULTICORE_COMMAND_GET_MODE_CHANGE_RECEIVED, 100) > 0; + + if(New_Mode_Received) { + Command_Issue_Get_Request(MULTICORE_COMMAND_GET_MODE_CHANGE_NEW_MODE, 0); + _Current_Mode = Command_Get_Request_Response_By_Command_Only(MULTICORE_COMMAND_GET_MODE_CHANGE_NEW_MODE, 100); + + Mode_Manager_Set_Mode(_Current_Mode); + Screen_Setup_Mode_Change(TRANSITION_NONE, TRANSITION_NONE, SCREEN_TRANSITION_DEFAULT_EASING, SCREEN_TRANSITION_DEFAULT_FRAMES, _Current_Mode); + + return; + } + if(_Current_Mode != JAM) { return; } diff --git a/Firmware/build/build_number.txt b/Firmware/build/build_number.txt index 7c660e8..9d34ca8 100644 --- a/Firmware/build/build_number.txt +++ b/Firmware/build/build_number.txt @@ -1 +1 @@ -841 +852