Added source
parent
46df35be9e
commit
6073eab934
@ -0,0 +1,108 @@
|
|||||||
|
#include "TimedPin.h"
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief Constructor
|
||||||
|
*******************************************************************************/
|
||||||
|
TimedPin::TimedPin(uint8_t pin_id, bool inverted) {
|
||||||
|
PinId = pin_id;
|
||||||
|
PinInvert = inverted;
|
||||||
|
PinMode = TPM_OFF;
|
||||||
|
OnTime = 0;
|
||||||
|
OffTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedPin::begin() {
|
||||||
|
pinMode(PinId, OUTPUT);
|
||||||
|
PinOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedPin::loop() {
|
||||||
|
uint32_t t = millis();
|
||||||
|
int32_t tdif = t - RefTime;
|
||||||
|
switch (PinMode) {
|
||||||
|
case TPM_OFF:
|
||||||
|
break;
|
||||||
|
case TPM_ON:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TPM_BLINK: {
|
||||||
|
if (PinState) { // pin == on
|
||||||
|
if (tdif >= OnTime) { // on time expired
|
||||||
|
RefTime = t;
|
||||||
|
PinOff(); // toggle pin
|
||||||
|
}
|
||||||
|
} else { // pin == off
|
||||||
|
if (tdif >= OffTime) { // off time expired
|
||||||
|
RefTime = t;
|
||||||
|
PinOn(); // toggle pin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TPM_TIMED_ON: {
|
||||||
|
if (tdif >= OnTime) { // on time expired
|
||||||
|
PinOff();
|
||||||
|
PinMode = TPM_OFF;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TPM_TIMED_OFF: {
|
||||||
|
if (tdif >= OffTime) { // off time expired
|
||||||
|
PinOn();
|
||||||
|
PinMode = TPM_ON;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
PinMode = TPM_OFF;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedPin::OffTimed(uint32_t t) {
|
||||||
|
PinOff();
|
||||||
|
PinMode = TPM_TIMED_OFF;
|
||||||
|
RefTime = millis();
|
||||||
|
OffTime = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedPin::OnTimed(uint32_t t) {
|
||||||
|
PinOn();
|
||||||
|
PinMode = TPM_TIMED_ON;
|
||||||
|
RefTime = millis();
|
||||||
|
OffTime = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedPin::Blink(uint32_t t_on, uint32_t t_off) {
|
||||||
|
if (PinMode != TPM_BLINK) {
|
||||||
|
PinMode = TPM_BLINK;
|
||||||
|
PinOn();
|
||||||
|
}
|
||||||
|
RefTime = millis();
|
||||||
|
OnTime = t_on;
|
||||||
|
OffTime = t_off;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedPin::On() {
|
||||||
|
PinOn();
|
||||||
|
PinMode = TPM_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedPin::Off() {
|
||||||
|
PinOff();
|
||||||
|
PinMode = TPM_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Internal functions
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
void TimedPin::PinOn() {
|
||||||
|
PinState = true;
|
||||||
|
digitalWrite(PinId, PinInvert ? LOW : HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedPin::PinOff() {
|
||||||
|
PinState = false;
|
||||||
|
digitalWrite(PinId, PinInvert ? HIGH : LOW);
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef __TIMED_PIN__H__
|
||||||
|
#define __TIMED_PIN__H__
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
enum TPinModes {
|
||||||
|
TPM_OFF, // On
|
||||||
|
TPM_ON, // Off
|
||||||
|
TPM_BLINK, // Blink
|
||||||
|
TPM_ASYM, // asymmetric blink
|
||||||
|
TPM_TIMED_ON, // timed on, then off
|
||||||
|
TPM_TIMED_OFF // timed off, then on
|
||||||
|
};
|
||||||
|
|
||||||
|
class TimedPin {
|
||||||
|
private:
|
||||||
|
uint8_t PinId;
|
||||||
|
TPinModes PinMode;
|
||||||
|
bool PinState;
|
||||||
|
bool PinInvert;
|
||||||
|
uint32_t RefTime;
|
||||||
|
uint32_t OnTime;
|
||||||
|
uint32_t OffTime;
|
||||||
|
uint16_t CycleCnt;
|
||||||
|
|
||||||
|
void PinOn();
|
||||||
|
void PinOff();
|
||||||
|
|
||||||
|
public:
|
||||||
|
TimedPin(uint8_t pin, bool inverted = false);
|
||||||
|
void begin();
|
||||||
|
void loop();
|
||||||
|
void Blink(uint32_t t_on, uint32_t t_off);
|
||||||
|
void Blink(uint32_t t) { Blink(t, t); }
|
||||||
|
// void BlinkCycles(uint32_t t_on, uint32_t t_off, uint16_t cycles);
|
||||||
|
void Off();
|
||||||
|
void OffTimed(uint32_t t);
|
||||||
|
void On();
|
||||||
|
void OnTimed(uint32_t t);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,169 @@
|
|||||||
|
#include <MIDI.h>
|
||||||
|
#include "TimedPin.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief Timer class for generate cyclic signals
|
||||||
|
*******************************************************************************/
|
||||||
|
struct Tmr {
|
||||||
|
int32_t Period; // cycle length (it must be initialized!)
|
||||||
|
uint32_t TrefMillis;
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
bool Check(uint32_t t) { // check with external timebase
|
||||||
|
int32_t tdif = t - TrefMillis;
|
||||||
|
if (tdif >= Period) { // period expired
|
||||||
|
TrefMillis += Period;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool Check() { // check with millisec timebase
|
||||||
|
uint32_t t = millis();
|
||||||
|
int32_t tdif = t - TrefMillis;
|
||||||
|
if (tdif >= Period) { // period expired
|
||||||
|
TrefMillis += Period;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Tmr Tmr10ms = { .Period = 10 };
|
||||||
|
Tmr Tmr100ms = { .Period = 100 };
|
||||||
|
Tmr Tmr1s = { .Period = 1000 };
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief Button - port assignment
|
||||||
|
*******************************************************************************/
|
||||||
|
const uint8_t pinBtnInc1 = 8;
|
||||||
|
const uint8_t pinBtnDec1 = 9;
|
||||||
|
const uint8_t pinBtnInc2 = 10;
|
||||||
|
const uint8_t pinBtnDec2 = 11;
|
||||||
|
const uint8_t pinBtnChOn1 = 12;
|
||||||
|
const uint8_t pinBtnChOn2 = 13;
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief Button codes
|
||||||
|
*******************************************************************************/
|
||||||
|
enum _BTN_CODES {
|
||||||
|
BTN_INC1 = 0,
|
||||||
|
BTN_DEC1,
|
||||||
|
BTN_INC2,
|
||||||
|
BTN_DEC2,
|
||||||
|
BTN_CH_ON1,
|
||||||
|
BTN_CH_ON2,
|
||||||
|
|
||||||
|
BTN_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief LED
|
||||||
|
*******************************************************************************/
|
||||||
|
TimedPin LedBoard(LED_BUILTIN);
|
||||||
|
TimedPin LedChOn1(2);
|
||||||
|
TimedPin LedChOn2(3);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief MIDI instance (serial port)
|
||||||
|
*******************************************************************************/
|
||||||
|
MIDI_CREATE_DEFAULT_INSTANCE();
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// This function will be automatically called when a NoteOn is received.
|
||||||
|
// It must be a void-returning function with the correct parameters, see documentation here:
|
||||||
|
// https://github.com/FortySevenEffects/arduino_midi_library/wiki/Using-Callbacks
|
||||||
|
void handleNoteOn(byte channel, byte pitch, byte velocity) {
|
||||||
|
// Do whatever you want when a note is pressed.
|
||||||
|
|
||||||
|
// Try to keep your callbacks short (no delays ect) otherwise it would slow down the loop() and have a bad impact on real-time performance.
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleNoteOff(byte channel, byte pitch, byte velocity) {
|
||||||
|
// Do something when the note is released. Note that NoteOn messages with 0 velocity are interpreted as NoteOffs.
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(pinBtnInc1, INPUT_PULLUP);
|
||||||
|
pinMode(pinBtnDec1, INPUT_PULLUP);
|
||||||
|
pinMode(pinBtnInc2, INPUT_PULLUP);
|
||||||
|
pinMode(pinBtnDec2, INPUT_PULLUP);
|
||||||
|
pinMode(pinBtnChOn1, INPUT_PULLUP);
|
||||||
|
pinMode(pinBtnChOn2, INPUT_PULLUP);
|
||||||
|
|
||||||
|
LedBoard.begin();
|
||||||
|
LedChOn1.begin();
|
||||||
|
LedChOn2.begin();
|
||||||
|
|
||||||
|
// Connect the handleNoteOn function to the library, so it is called upon reception of a NoteOn.
|
||||||
|
MIDI.setHandleNoteOn(handleNoteOn); // Put only the name of the function
|
||||||
|
MIDI.setHandleNoteOff(handleNoteOff); // Do the same for NoteOffs
|
||||||
|
MIDI.begin(MIDI_CHANNEL_OMNI); // Initiate MIDI communications, listen to all channels
|
||||||
|
|
||||||
|
UI_Init(); // Start user interface (main state machine)
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief Main loop
|
||||||
|
*******************************************************************************/
|
||||||
|
void loop() {
|
||||||
|
MIDI.read(); // Call MIDI.read the fastest you can for real-time performance.
|
||||||
|
|
||||||
|
uint32_t t = millis();
|
||||||
|
// execute every 10ms *******************************************************
|
||||||
|
if (Tmr10ms.Check(t)) {
|
||||||
|
static uint8_t BtnPrev = 0xFF;
|
||||||
|
static uint8_t BtnNew = 0;
|
||||||
|
static uint8_t BtnRel = 0;
|
||||||
|
uint8_t btn = (digitalRead(pinBtnInc1) ? (1 << BTN_INC1 ) : 0)
|
||||||
|
| (digitalRead(pinBtnDec1) ? (1 << BTN_DEC1 ) : 0)
|
||||||
|
| (digitalRead(pinBtnInc2) ? (1 << BTN_INC2 ) : 0)
|
||||||
|
| (digitalRead(pinBtnInc2) ? (1 << BTN_DEC2 ) : 0)
|
||||||
|
| (digitalRead(pinBtnChOn1) ? (1 << BTN_CH_ON1) : 0)
|
||||||
|
| (digitalRead(pinBtnChOn1) ? (1 << BTN_CH_ON2) : 0);
|
||||||
|
BtnNew |= (~btn) & BtnPrev;
|
||||||
|
BtnRel |= btn & (~BtnPrev);
|
||||||
|
uint8_t mask = 1;
|
||||||
|
if (BtnNew) {
|
||||||
|
for (uint_fast8_t i = 0; i < BTN_MAX; i++) {
|
||||||
|
if (BtnNew & mask) {
|
||||||
|
BtnNew &= ~mask; // Bit clr
|
||||||
|
UI_EventProc(EV_UI_KEY_PRESS + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mask <<= 1;
|
||||||
|
}
|
||||||
|
}else if (BtnRel) { // released button
|
||||||
|
for (uint_fast8_t i = 0; i < BTN_MAX; i++) {
|
||||||
|
if (BtnRel & mask) {
|
||||||
|
BtnRel &= ~mask; // Bit clr
|
||||||
|
UI_EventProc(EV_UI_KEY_REL + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mask <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UI_EventProc(EV_TIMER_TICK);
|
||||||
|
UI_EventProc(EV_UI_TICK_10MS);
|
||||||
|
UI_CheckEvent();
|
||||||
|
|
||||||
|
LedBoard.loop();
|
||||||
|
LedChOn1.loop();
|
||||||
|
LedChOn2.loop();
|
||||||
|
}
|
||||||
|
// execute every 100ms ******************************************************
|
||||||
|
if (Tmr100ms.Check(t)) {
|
||||||
|
UI_EventProc(EV_UI_TICK_100MS);
|
||||||
|
}
|
||||||
|
// execute every 1s *********************************************************
|
||||||
|
if (Tmr1s.Check(t)) {
|
||||||
|
UI_EventProc(EV_UI_TICK_1S);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/***************************************************************************//**
|
||||||
|
* @file statemachine.cpp
|
||||||
|
*
|
||||||
|
* Simple finite state machine
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "statemachine.h"
|
||||||
|
|
||||||
|
void StateMachine(STATE_MACHINE* const me, uint16_t ev) {
|
||||||
|
me->State(me, ev); // call actual state
|
||||||
|
if (me->StateNew != NULL) { // new state request
|
||||||
|
me->StateReturn = me->State; // remeber last state
|
||||||
|
me->State(me, EV_STATE_EXIT); // closing last state
|
||||||
|
me->State = me->StateNew; // switching state
|
||||||
|
me->StateNew = NULL;
|
||||||
|
me->State(me, EV_STATE_ENTER); // init new state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SM_ST_StateDelayed(STATE_MACHINE* const me, uint16_t event) {
|
||||||
|
switch (event) {
|
||||||
|
case EV_TIMER_TICK: {
|
||||||
|
if (me->Timer_StateDelay) {
|
||||||
|
me->Timer_StateDelay--;
|
||||||
|
}else {
|
||||||
|
SM_SET_STATE(me->StateDelayed);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineInit(STATE_MACHINE* const me, SM_STATE_FUNC* const init_state) {
|
||||||
|
me->State = init_state;
|
||||||
|
me->StateNew = NULL;
|
||||||
|
me->StateDelayed = init_state;
|
||||||
|
me->StateReturn = init_state;
|
||||||
|
|
||||||
|
me->State(me, EV_STATE_ENTER); // enter into initial state (initial transition)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef __STATEMACHINE_H__
|
||||||
|
#define __STATEMACHINE_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
} // workaround for CB folding bug
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
enum SM_EVENTS {
|
||||||
|
EV_STATE_ENTER,
|
||||||
|
EV_STATE_EXIT,
|
||||||
|
EV_TIMER_TICK,
|
||||||
|
|
||||||
|
EV_USER_FIRST
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SM_SET_STATE(st) do { \
|
||||||
|
((STATE_MACHINE*)me)->StateNew = (SM_STATE_FUNC*)(st); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SM_SET_STATE_DELAYED(st, delay) do { \
|
||||||
|
((STATE_MACHINE*)me)->StateDelayed = (SM_STATE_FUNC*)(st); \
|
||||||
|
((STATE_MACHINE*)me)->Timer_StateDelay = delay; \
|
||||||
|
((STATE_MACHINE*)me)->StateNew = &SM_ST_StateDelayed; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
struct _STATE_MACHINE;
|
||||||
|
typedef struct _STATE_MACHINE STATE_MACHINE;
|
||||||
|
typedef void SM_STATE_FUNC(STATE_MACHINE* me, uint16_t event);
|
||||||
|
|
||||||
|
struct _STATE_MACHINE {
|
||||||
|
SM_STATE_FUNC* State; // actual state
|
||||||
|
SM_STATE_FUNC* StateNew; // new state
|
||||||
|
SM_STATE_FUNC* StateDelayed; // auto state switch after delay
|
||||||
|
SM_STATE_FUNC* StateReturn; // return state for nested states
|
||||||
|
uint16_t Timer_StateDelay;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void StateMachineInit(STATE_MACHINE* const me, SM_STATE_FUNC* const init_state);
|
||||||
|
extern void StateMachine(STATE_MACHINE* const me, uint16_t ev);
|
||||||
|
extern void SM_ST_StateDelayed(STATE_MACHINE* const me, uint16_t event);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
{ // workaround for CB folding bug
|
||||||
|
#endif
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __STATEMACHINE_H__
|
@ -0,0 +1,157 @@
|
|||||||
|
/***************************************************************************//**
|
||||||
|
* @file ui.cpp
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
|
||||||
|
//#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 MIDI_NAMESPACE::SerialMIDI<HardwareSerial> serialMIDI;
|
||||||
|
extern MIDI_NAMESPACE::MidiInterface<MIDI_NAMESPACE::SerialMIDI<HardwareSerial>> MIDI;
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
|
||||||
|
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(50, 450);
|
||||||
|
}break;
|
||||||
|
case EV_STATE_EXIT: {
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case EV_UI_TICK_100MS: {
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case EV_UI_TICK_1S: {
|
||||||
|
if (++me->Timer == 15) {
|
||||||
|
SM_SET_STATE(&UiSt_Home); //u MixerStartup -left-> Home : timeout
|
||||||
|
}
|
||||||
|
static uint8_t MuteVal = 0;
|
||||||
|
MIDI.sendControlChange(21, MuteVal, 2); // Send Mute: CH2, 21-26: Aux1-6
|
||||||
|
MuteVal = MuteVal ? 0 : 127;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//u }
|
||||||
|
|
||||||
|
|
||||||
|
//u state Home {
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief Standby (home) state
|
||||||
|
*******************************************************************************/
|
||||||
|
void UiSt_Home(UI_SM* const me, uint16_t event) {
|
||||||
|
switch (event) {
|
||||||
|
case EV_STATE_ENTER: {
|
||||||
|
LedBoard.Blink(1900, 100);
|
||||||
|
}break;
|
||||||
|
case EV_STATE_EXIT: {
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case EV_UI_TICK_10MS: {
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//u }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//u }
|
||||||
|
|
||||||
|
//u @enduml
|
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __UI_H__
|
||||||
|
#define __UI_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "statemachine.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum UI_EVENTS {
|
||||||
|
EV_UI_TICK_10MS = EV_USER_FIRST,
|
||||||
|
EV_UI_TICK_100MS,
|
||||||
|
EV_UI_TICK_1S,
|
||||||
|
EV_UI_KEY_PRESS = 0x0100,
|
||||||
|
EV_UI_KEY_PRESS_MAX = 0x01FF,
|
||||||
|
EV_UI_KEY_REL = 0x0200,
|
||||||
|
EV_UI_KEY_REL_MAX = 0x02FF,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern void UI_Init();
|
||||||
|
extern void UI_EventProc(uint16_t event);
|
||||||
|
extern void UI_EventSend(uint16_t event);
|
||||||
|
extern void UI_CheckEvent();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue