/***************************************************************************//** * @file ui.cpp *******************************************************************************/ #include #include #include #include #include //#include "gitinfo.h" #include "MIDI.h" #include "TimedPin.h" #include "ui.h" #define ELEMCNT(x) (sizeof(x) / sizeof((x)[0])) // Extern variables ============================================================ extern TimedPin LedBoard; extern TimedPin LedChOn1; extern TimedPin LedChOn2; extern TimedPin LedInc1; extern TimedPin LedDec1; extern MIDI_NAMESPACE::SerialMIDI serialMIDI; extern MIDI_NAMESPACE::MidiInterface> MIDI; extern MixerMuteState AirMutes[2]; extern MixerFaderState AirFaders[2]; extern bool ButtonCheck(uint8_t btn); // Typedefs ==================================================================== struct UI_SM { STATE_MACHINE sm; uint32_t Events; uint16_t Timer; uint16_t KeyTimer; }; typedef void UI_STATE_FUNC(UI_SM* me, uint16_t event); // Local variables ============================================================= static UI_SM UiSm; #define DEFINE_MY_OBJECT() UI_SM* const me = &UiSm; TimedPin DummyRelay; const uint16_t ToutProg = 30; // [s] // Local function declarations ================================================= static void UiSt_MixerStartup(UI_SM* me, uint16_t event); static void UiSt_Home(UI_SM* me, uint16_t event); // Function definitions ======================================================== //u @startuml //u skinparam defaultTextAlignment left //u state UserInterface { /***************************************************************************//** * @brief Initialize state machine for user interface *******************************************************************************/ void UI_Init() { DEFINE_MY_OBJECT(); me->Events = 0; StateMachineInit(&me->sm, (SM_STATE_FUNC*)&UiSt_MixerStartup); //u [*] -> MixerStartup } /***************************************************************************//** * @brief Execute event handler *******************************************************************************/ void UI_EventProc(uint16_t event) { DEFINE_MY_OBJECT(); StateMachine((STATE_MACHINE*)me, event); } /***************************************************************************//** * @brief Check and execute asynchron event (from event buffer) *******************************************************************************/ void UI_CheckEvent() { DEFINE_MY_OBJECT(); if (me->Events) { uint32_t mask = 1; uint8_t ev; for (ev = 0; ev < 32; ev++) { if (me->Events & mask) { me->Events &= ~mask; StateMachine((STATE_MACHINE*)me, ev); break; } mask <<= 1; // shift left } } } /***************************************************************************//** * @brief Send (asynchron) event to state machine to process it later *******************************************************************************/ static inline void EventSend(UI_SM* const me, uint16_t event) { me->Events |= (1 << event); } // State definitions =========================================================== //u state MixerStartup { /***************************************************************************//** * @brief MixerStartup *******************************************************************************/ void UiSt_MixerStartup(UI_SM* const me, uint16_t event) { switch (event) { case EV_STATE_ENTER: { //u MixerStartup: entry: me->Timer = 0; LedBoard.Blink(30, 270, 5); LedChOn1.Blink(10, 1990); LedChOn2.Blink(10, 1990); LedInc1.Blink(10, 1990); LedDec1.Blink(10, 1990); }break; case EV_STATE_EXIT: { }break; case EV_UI_RX_MIDI: case EV_UI_RX_MUTE_CH1_ON: case EV_UI_RX_MUTE_CH1_OFF: case EV_UI_RX_MUTE_CH2_ON: case EV_UI_RX_MUTE_CH2_OFF: { // mixer alive SM_SET_STATE(&UiSt_Home); }break; case EV_UI_TICK_1S: { if ((me->Timer % 2) == 0) { MixerFaderState& fader = AirFaders[0]; MIDI.sendControlChange(fader.MidiCtrlNr, fader.FaderStd - ((me->Timer >> 1) % 2), 1); // ping mixer with changing value (std, std-1, std,...) } if (++me->Timer == 15) { SM_SET_STATE(&UiSt_Home); //u MixerStartup -left-> Home : timeout } }break; } } //u } //u state Home { /***************************************************************************//** * @brief Standby (home) state *******************************************************************************/ void UiSt_Home(UI_SM* const me, uint16_t event) { uint8_t btn = 0; if (event >= EV_UI_KEY_PRESS && event <= EV_UI_KEY_PRESS_MAX) { btn = event - EV_UI_KEY_PRESS; event = EV_UI_KEY_PRESS; }else if (event >= EV_UI_KEY_REL && event <= EV_UI_KEY_REL_MAX) { btn = event - EV_UI_KEY_REL; event = EV_UI_KEY_REL; } switch (event) { case EV_STATE_ENTER: { LedBoard.Blink(30, 270, 5); // initialize mixer for (uint_fast8_t i=0; i