Upload files to 'Software'
This commit is contained in:
parent
e3bca42d2e
commit
f55627daf1
|
@ -0,0 +1,694 @@
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "editor-modes.h"
|
||||||
|
#include "editor.h"
|
||||||
|
#include "panel-scanner.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "pattern.h"
|
||||||
|
|
||||||
|
extern PanelScanner theScanner;
|
||||||
|
extern Player thePlayer;
|
||||||
|
extern Pattern thePattern;
|
||||||
|
extern Editor theEditor;
|
||||||
|
|
||||||
|
// Local definitions
|
||||||
|
|
||||||
|
|
||||||
|
static const int32_t PATTERN_SEL_INDICATOR = 0x10;
|
||||||
|
static const int32_t PATTERN_CHAIN_INDICATOR = 0x11;
|
||||||
|
static const int32_t STEP_EDIT_INDICATOR = 0x12;
|
||||||
|
static const int32_t STEP_ACCENT_INDICATOR = 0x13;
|
||||||
|
static const int32_t VOICE_SEL_INDICATOR = 0x14;
|
||||||
|
static const int32_t MUTE_SEL_INDICATOR = 0x15;
|
||||||
|
static const int32_t UTILITY_SEL_INDICATOR = 0x16;
|
||||||
|
static const int32_t PLAY_INDICATOR = 0x17;
|
||||||
|
/*
|
||||||
|
static const int32_t PATTERN_SEL_INDICATOR = 0x17;
|
||||||
|
static const int32_t PATTERN_CHAIN_INDICATOR = 0x16;
|
||||||
|
static const int32_t STEP_EDIT_INDICATOR = 0x15;
|
||||||
|
static const int32_t STEP_ACCENT_INDICATOR = 0x14;
|
||||||
|
static const int32_t VOICE_SEL_INDICATOR = 0x13;
|
||||||
|
static const int32_t MUTE_SEL_INDICATOR = 0x12;
|
||||||
|
static const int32_t UTILITY_SEL_INDICATOR = 0x11;
|
||||||
|
static const int32_t PLAY_INDICATOR = 0x10;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// common implementation because chain display
|
||||||
|
// is used by chain and patt sel modes.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void doChainLeds()
|
||||||
|
{
|
||||||
|
if(thePlayer.chainIsActive())
|
||||||
|
{
|
||||||
|
theScanner.clearAllBlinkingLEDs();
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < Pattern::NUM_PATTERNS; i++)
|
||||||
|
{
|
||||||
|
theScanner.setBlinkingLED(i, thePlayer.checkChainMembership(i));
|
||||||
|
}
|
||||||
|
// blinking overrides background, so
|
||||||
|
// to mark current pattern, unset blinking,
|
||||||
|
// set background
|
||||||
|
theScanner.clearBlinkingLED(thePattern.getCurrentPattern());
|
||||||
|
theScanner.setBackgroundLED(thePattern.getCurrentPattern());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doPlayingLed()
|
||||||
|
{
|
||||||
|
theScanner.clearAllOverlayLEDs();
|
||||||
|
|
||||||
|
if(thePlayer.isPlaying())
|
||||||
|
{
|
||||||
|
theScanner.setOverlayLED(thePlayer.getCurrentStep());
|
||||||
|
theScanner.setBackgroundLED(PLAY_INDICATOR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theScanner.clearBackgroundLED(PLAY_INDICATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////// Base Class
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// constructor...
|
||||||
|
pvEditorMode::pvEditorMode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Common handling for the start/stop key
|
||||||
|
void pvEditorMode::HandlePlayButton(bool pressed)
|
||||||
|
{
|
||||||
|
Serial.write("Play/Pause");
|
||||||
|
if(pressed )
|
||||||
|
{
|
||||||
|
if(thePlayer.isPlaying())
|
||||||
|
{
|
||||||
|
thePlayer.stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thePlayer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////// Step Editor
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
StepEdit::StepEdit(): pvEditorMode()
|
||||||
|
{
|
||||||
|
//current_voice = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepEdit::HandleKey(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
bool setting;
|
||||||
|
|
||||||
|
if (keynum == PLAY_INDICATOR) //start/stop key
|
||||||
|
{
|
||||||
|
HandlePlayButton(pressed);
|
||||||
|
}
|
||||||
|
else if((keynum >= 0) && (keynum <= 15))
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
setting = thePattern.toggleBit(keynum);
|
||||||
|
|
||||||
|
// If we're clearing a bit, lose it's accent, too.
|
||||||
|
if(!setting)
|
||||||
|
{
|
||||||
|
if(thePattern.getAccentBit(keynum))
|
||||||
|
thePattern.toggleAccentBit(keynum);
|
||||||
|
}
|
||||||
|
|
||||||
|
setLEDs(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == VOICE_SEL_INDICATOR) // voice select mode
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_VOICE_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == STEP_ACCENT_INDICATOR) // voice select mode
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_STEP_ACCENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(keynum == MUTE_SEL_INDICATOR)
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_MUTE_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == PATTERN_SEL_INDICATOR) // pattern select mode
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_PATT_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == UTILITY_SEL_INDICATOR)
|
||||||
|
{
|
||||||
|
if(pressed)// && (!thePlayer.isPlaying()))
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_UTILITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
else// other, unmapped keys, just show they work.
|
||||||
|
{
|
||||||
|
theScanner.setBackgroundLED(keynum, pressed);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepEdit::setLEDs(bool entry)
|
||||||
|
{
|
||||||
|
// Initialize LEDs
|
||||||
|
if(entry)
|
||||||
|
{
|
||||||
|
doPlayingLed();
|
||||||
|
|
||||||
|
theScanner.setBackgroundLED(STEP_EDIT_INDICATOR);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < Pattern::PATTERN_LEN; i++)
|
||||||
|
{
|
||||||
|
theScanner.setBackgroundLED(i, thePattern.getVoiceBit(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // on exit
|
||||||
|
{
|
||||||
|
theScanner.clearAllHalfLEDs();
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
theScanner.clearAllBlinkingLEDs();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////// Accent Editor
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
StepAccent::StepAccent(): pvEditorMode()
|
||||||
|
{
|
||||||
|
//current_voice = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepAccent::HandleKey(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
bool setting;
|
||||||
|
Serial.write("Step Accent");
|
||||||
|
|
||||||
|
if(keynum == STEP_ACCENT_INDICATOR)
|
||||||
|
{
|
||||||
|
if(!pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_STEP_EDIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keynum == PLAY_INDICATOR) //start/stop key
|
||||||
|
{
|
||||||
|
HandlePlayButton(pressed);
|
||||||
|
}
|
||||||
|
else if((keynum >= 0) && (keynum <= 15))
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
setting = thePattern.toggleAccentBit(keynum);
|
||||||
|
|
||||||
|
// If we just added an accent, but note isn't triggered, trigger it.
|
||||||
|
// Likewise, if we cleared and accent, clear the trigger.
|
||||||
|
// Don't leave stranded accents, because they're an ugly surprise later...
|
||||||
|
if( (setting && !thePattern.getVoiceBit(keynum) ) ||
|
||||||
|
(!setting && thePattern.getVoiceBit(keynum)))
|
||||||
|
{
|
||||||
|
thePattern.toggleBit(keynum);
|
||||||
|
}
|
||||||
|
|
||||||
|
setLEDs(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepAccent::setLEDs(bool entry)
|
||||||
|
{
|
||||||
|
// Initialize LEDs
|
||||||
|
if(entry)
|
||||||
|
{
|
||||||
|
doPlayingLed();
|
||||||
|
|
||||||
|
theScanner.setBackgroundLED(STEP_ACCENT_INDICATOR);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < Pattern::PATTERN_LEN; i++)
|
||||||
|
{
|
||||||
|
theScanner.setBackgroundLED(i, thePattern.getAccentBit(i));
|
||||||
|
theScanner.setHalfLED(i, thePattern.getVoiceBit(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // on exit
|
||||||
|
{
|
||||||
|
theScanner.clearAllHalfLEDs();
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
theScanner.clearAllBlinkingLEDs();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////// Voice Selector
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
VoiceSelect::VoiceSelect(): pvEditorMode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoiceSelect::HandleKey(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
Serial.write("Voice select");
|
||||||
|
|
||||||
|
if(keynum == VOICE_SEL_INDICATOR) // voice select mode
|
||||||
|
{
|
||||||
|
if(!pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_STEP_EDIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keynum == PLAY_INDICATOR) //start/stop key
|
||||||
|
{
|
||||||
|
HandlePlayButton(pressed);
|
||||||
|
}
|
||||||
|
else if((keynum >= 0) && (keynum <= 10))
|
||||||
|
{
|
||||||
|
// TBD - more voices means accept more input
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
thePattern.setCurrentVoice(keynum);
|
||||||
|
setLEDs(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoiceSelect::setLEDs(bool entry)
|
||||||
|
{
|
||||||
|
uint32_t bitnum;
|
||||||
|
|
||||||
|
if(entry)
|
||||||
|
{
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
|
||||||
|
doPlayingLed();
|
||||||
|
|
||||||
|
// Mode indication
|
||||||
|
theScanner.setBackgroundLED(VOICE_SEL_INDICATOR);
|
||||||
|
|
||||||
|
// Present voice indication
|
||||||
|
bitnum = thePattern.getCurrentVoice();
|
||||||
|
theScanner.setBackgroundLED(bitnum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////// Mute Selector
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
MuteSelect::MuteSelect(): pvEditorMode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MuteSelect::HandleKey(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
// bool setting;
|
||||||
|
Serial.write("Mute select");
|
||||||
|
|
||||||
|
if(keynum == STEP_EDIT_INDICATOR) // voice select mode
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_STEP_EDIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == PATTERN_SEL_INDICATOR) // pattern select mode
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_PATT_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keynum == PLAY_INDICATOR) //start/stop key
|
||||||
|
{
|
||||||
|
HandlePlayButton(pressed);
|
||||||
|
}
|
||||||
|
else if(keynum == UTILITY_SEL_INDICATOR)
|
||||||
|
{
|
||||||
|
if(pressed)// && (!thePlayer.isPlaying()))
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_UTILITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if((keynum >= 0) && (keynum <= 10))
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
bool setting;
|
||||||
|
setting = thePlayer.toggleMuteBit(keynum);
|
||||||
|
setLEDs(true);
|
||||||
|
if (setting == true) {};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MuteSelect::setLEDs(bool entry)
|
||||||
|
{
|
||||||
|
if(entry)
|
||||||
|
{
|
||||||
|
doPlayingLed();
|
||||||
|
|
||||||
|
// set mode indicator
|
||||||
|
theScanner.setBackgroundLED(MUTE_SEL_INDICATOR);
|
||||||
|
|
||||||
|
// and display data on editor buttons
|
||||||
|
for(uint32_t i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
theScanner.setBackgroundLED(i, thePlayer.getMuteBit(i));
|
||||||
|
// blinking overrides background
|
||||||
|
theScanner.setBlinkingLED(i, thePlayer.getPendingMuteBit(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
theScanner.clearAllBlinkingLEDs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////// Pattern Selector
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
PatternSelect::PatternSelect()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PatternSelect::HandleKey(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
Serial.write("Pattern select");
|
||||||
|
|
||||||
|
if(keynum == STEP_EDIT_INDICATOR)
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_STEP_EDIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == MUTE_SEL_INDICATOR)
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_MUTE_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == UTILITY_SEL_INDICATOR)
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_UTILITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == PATTERN_CHAIN_INDICATOR)
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
thePlayer.initChain();
|
||||||
|
theEditor.setMode(Editor::eMODE_CHAIN_EDIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keynum == PLAY_INDICATOR) //start/stop key
|
||||||
|
{
|
||||||
|
HandlePlayButton(pressed);
|
||||||
|
}
|
||||||
|
else if((keynum >= 0) && (keynum <= 15))
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
// if there was a chain, end it
|
||||||
|
if(thePlayer.chainIsActive())
|
||||||
|
{
|
||||||
|
thePlayer.initChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
thePlayer.setNextPattern(keynum);
|
||||||
|
setLEDs(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PatternSelect::setLEDs(bool entry)
|
||||||
|
{
|
||||||
|
int32_t pending;
|
||||||
|
|
||||||
|
if(entry)
|
||||||
|
{
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
theScanner.clearAllBlinkingLEDs();
|
||||||
|
|
||||||
|
doPlayingLed();
|
||||||
|
|
||||||
|
// set mode indicator
|
||||||
|
theScanner.setBackgroundLED(PATTERN_SEL_INDICATOR);
|
||||||
|
|
||||||
|
if(!thePlayer.chainIsActive())
|
||||||
|
{
|
||||||
|
theScanner.setBackgroundLED(thePattern.getCurrentPattern());
|
||||||
|
pending = thePlayer.getPendingPattern();
|
||||||
|
if(pending != -1)
|
||||||
|
{
|
||||||
|
theScanner.setBlinkingLED(pending);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doChainLeds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
theScanner.clearAllBlinkingLEDs();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////// Chain Editor
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
ChainEdit::ChainEdit()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChainEdit::HandleKey(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
Serial.write("Chain editor");
|
||||||
|
|
||||||
|
if(keynum == PATTERN_CHAIN_INDICATOR)
|
||||||
|
{
|
||||||
|
if(!pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_PATT_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == PLAY_INDICATOR) //start/stop key
|
||||||
|
{
|
||||||
|
HandlePlayButton(pressed);
|
||||||
|
}
|
||||||
|
else if((keynum >= 0) && (keynum <= 15))
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
thePlayer.addToChain(keynum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChainEdit::setLEDs(bool entry)
|
||||||
|
{
|
||||||
|
if(entry)
|
||||||
|
{
|
||||||
|
doPlayingLed();
|
||||||
|
|
||||||
|
doChainLeds();
|
||||||
|
|
||||||
|
// set mode indicator
|
||||||
|
theScanner.setBackgroundLED(PATTERN_CHAIN_INDICATOR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
theScanner.clearAllBlinkingLEDs();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////// Utility mode
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
UtilityMode::UtilityMode(): pvEditorMode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UtilityMode::HandleKey(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
Serial.write("Utility mode");
|
||||||
|
|
||||||
|
if(keynum == STEP_EDIT_INDICATOR) // voice select mode
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_STEP_EDIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == MUTE_SEL_INDICATOR)
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_MUTE_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keynum == PATTERN_SEL_INDICATOR) // pattern select mode
|
||||||
|
{
|
||||||
|
if(pressed)
|
||||||
|
{
|
||||||
|
theEditor.setMode(Editor::eMODE_PATT_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keynum == PLAY_INDICATOR) //start/stop key
|
||||||
|
{
|
||||||
|
HandlePlayButton(pressed);
|
||||||
|
}
|
||||||
|
else if((keynum >= 0) && (keynum <= 15))
|
||||||
|
{
|
||||||
|
doUtilMode(keynum, pressed);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UtilityMode::setLEDs(bool entry)
|
||||||
|
{
|
||||||
|
//uint32_t bitnum;
|
||||||
|
|
||||||
|
if(entry)
|
||||||
|
{
|
||||||
|
doPlayingLed();
|
||||||
|
|
||||||
|
// Mode indication
|
||||||
|
theScanner.setBackgroundLED(UTILITY_SEL_INDICATOR);
|
||||||
|
|
||||||
|
// Present data indication
|
||||||
|
theScanner.setBackgroundLED(0x2, thePlayer.getSwing());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theScanner.clearAllBackgroundLEDs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UtilityMode::doUtilMode(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
bool playing = thePlayer.isPlaying();
|
||||||
|
|
||||||
|
if(!pressed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(keynum)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
if(!playing)
|
||||||
|
{
|
||||||
|
thePattern.clearCurrentPattern();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
if(!playing)
|
||||||
|
{
|
||||||
|
thePattern.randomizeCurrentPattern();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
thePlayer.toggleSwing();
|
||||||
|
setLEDs(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
{
|
||||||
|
if(!playing)
|
||||||
|
{
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
thePattern.writeToCard();
|
||||||
|
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
{
|
||||||
|
if(!playing)
|
||||||
|
{
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
thePattern.readFromCard();
|
||||||
|
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
#ifndef _EDITOR_MODES_H_
|
||||||
|
#define _EDITOR_MODES_H_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class pvEditorMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
pvEditorMode();
|
||||||
|
|
||||||
|
virtual void HandleKey(uint32_t keynum, bool pressed) = 0;
|
||||||
|
virtual void setLEDs(bool entry) = 0;
|
||||||
|
|
||||||
|
void HandlePlayButton(bool pressed);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class StepEdit: public pvEditorMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
StepEdit();
|
||||||
|
virtual void HandleKey(uint32_t keynum, bool pressed);
|
||||||
|
virtual void setLEDs(bool entry);
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class StepAccent: public pvEditorMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
StepAccent();
|
||||||
|
virtual void HandleKey(uint32_t keynum, bool pressed);
|
||||||
|
virtual void setLEDs(bool entry);
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class VoiceSelect: public pvEditorMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
VoiceSelect();
|
||||||
|
virtual void HandleKey(uint32_t keynum, bool pressed);
|
||||||
|
virtual void setLEDs(bool entry);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class MuteSelect: public pvEditorMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
MuteSelect();
|
||||||
|
virtual void HandleKey(uint32_t keynum, bool pressed);
|
||||||
|
virtual void setLEDs(bool entry);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class PatternSelect: public pvEditorMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PatternSelect();
|
||||||
|
virtual void HandleKey(uint32_t keynum, bool pressed);
|
||||||
|
virtual void setLEDs(bool entry);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChainEdit: public pvEditorMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ChainEdit();
|
||||||
|
virtual void HandleKey(uint32_t keynum, bool pressed);
|
||||||
|
virtual void setLEDs(bool entry);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class UtilityMode: public pvEditorMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
UtilityMode();
|
||||||
|
virtual void HandleKey(uint32_t keynum, bool pressed);
|
||||||
|
virtual void setLEDs(bool entry);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void doUtilMode(uint32_t keynum, bool pressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // keepout
|
|
@ -0,0 +1,102 @@
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "editor.h"
|
||||||
|
#include "player.h"
|
||||||
|
|
||||||
|
extern PanelScanner theScanner;
|
||||||
|
extern Player thePlayer;
|
||||||
|
|
||||||
|
|
||||||
|
// decls for the mode objects
|
||||||
|
static StepEdit stepEditor;
|
||||||
|
static StepAccent accentEditor;
|
||||||
|
static ChainEdit chainEditor;
|
||||||
|
static VoiceSelect voiceSelector;
|
||||||
|
static MuteSelect muteSelector;
|
||||||
|
static PatternSelect patternSelector;
|
||||||
|
static UtilityMode utilityMode;
|
||||||
|
|
||||||
|
// constructor...
|
||||||
|
Editor::Editor()
|
||||||
|
{
|
||||||
|
// don't refer to other classes here, they may not yet be constructed/init'd
|
||||||
|
// IE: the pattern may not be constructed, to pull initial LED modes from.
|
||||||
|
// We'll call setMode from setup() to get it to register.
|
||||||
|
|
||||||
|
current_mode_p = &patternSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::setMode(EditorMode newmode)
|
||||||
|
{
|
||||||
|
switch(newmode)
|
||||||
|
{
|
||||||
|
case eMODE_VOICE_SEL:
|
||||||
|
{
|
||||||
|
current_mode_p->setLEDs(false);
|
||||||
|
current_mode_p = &voiceSelector;
|
||||||
|
current_mode_p->setLEDs(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eMODE_MUTE_SEL:
|
||||||
|
{
|
||||||
|
current_mode_p->setLEDs(false);
|
||||||
|
current_mode_p = &muteSelector;
|
||||||
|
current_mode_p->setLEDs(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eMODE_PATT_SEL:
|
||||||
|
{
|
||||||
|
current_mode_p->setLEDs(false);
|
||||||
|
current_mode_p = &patternSelector;
|
||||||
|
current_mode_p->setLEDs(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eMODE_UTILITY:
|
||||||
|
{
|
||||||
|
current_mode_p->setLEDs(false);
|
||||||
|
current_mode_p = &utilityMode;
|
||||||
|
current_mode_p->setLEDs(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eMODE_CHAIN_EDIT:
|
||||||
|
{
|
||||||
|
current_mode_p->setLEDs(false);
|
||||||
|
current_mode_p = &chainEditor;
|
||||||
|
current_mode_p->setLEDs(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eMODE_STEP_ACCENT:
|
||||||
|
{
|
||||||
|
current_mode_p->setLEDs(false);
|
||||||
|
current_mode_p = &accentEditor;
|
||||||
|
current_mode_p->setLEDs(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
current_mode_p->setLEDs(false);
|
||||||
|
current_mode_p = &stepEditor;
|
||||||
|
current_mode_p->setLEDs(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::receiveKey(uint32_t keynum, bool pressed)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
Serial.print("Ed Key: ");
|
||||||
|
Serial.print(keynum, HEX);
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.println(pressed);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
current_mode_p->HandleKey(keynum, pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::forceLEDs()
|
||||||
|
{
|
||||||
|
current_mode_p->setLEDs(true);
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef _EDITOR_H_
|
||||||
|
#define _EDITOR_H_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// fwd decl for other headers
|
||||||
|
class Editor;
|
||||||
|
|
||||||
|
#include "panel-scanner.h"
|
||||||
|
#include "editor-modes.h"
|
||||||
|
|
||||||
|
class Editor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum EditorMode
|
||||||
|
{
|
||||||
|
eMODE_STEP_EDIT = 0,
|
||||||
|
eMODE_STEP_ACCENT,
|
||||||
|
eMODE_VOICE_SEL,
|
||||||
|
eMODE_MUTE_SEL,
|
||||||
|
eMODE_PATT_SEL,
|
||||||
|
eMODE_CHAIN_EDIT,
|
||||||
|
eMODE_UTILITY
|
||||||
|
};
|
||||||
|
|
||||||
|
Editor();
|
||||||
|
|
||||||
|
void receiveKey(uint32_t keynum, bool pressed);
|
||||||
|
void setMode(EditorMode);
|
||||||
|
void forceLEDs();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
pvEditorMode* current_mode_p;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // keepout
|
|
@ -0,0 +1,385 @@
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "panel-scanner.h"
|
||||||
|
#include "player.h"
|
||||||
|
|
||||||
|
static const int32_t CHIPSEL_BTNS = 8;
|
||||||
|
static const int32_t CHIPSEL_LEDS = 5;
|
||||||
|
|
||||||
|
extern Editor theEditor;
|
||||||
|
extern Player thePlayer;
|
||||||
|
|
||||||
|
static const SPISettings registersettings(100000, MSBFIRST, SPI_MODE0 );
|
||||||
|
|
||||||
|
|
||||||
|
// constructor...
|
||||||
|
PanelScanner::PanelScanner()
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
led_half_buffer[i] = 0;
|
||||||
|
led_background_buffer[i] = 0;
|
||||||
|
led_blinking_buffer[i] = 0;
|
||||||
|
led_overlay_buffer[i] = 0;
|
||||||
|
old_buttons[i] = 0;
|
||||||
|
new_buttons[i] = 0;
|
||||||
|
//setBlinkingLED(22,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::initScanning()
|
||||||
|
{
|
||||||
|
// SPI is shared with SD card, initialized in setup()
|
||||||
|
SPI.setSCK(14);
|
||||||
|
SPI.setMOSI(7);
|
||||||
|
SPI.setMISO(12);
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
pinMode(CHIPSEL_BTNS, OUTPUT);
|
||||||
|
digitalWrite(CHIPSEL_BTNS, LOW);
|
||||||
|
pinMode(CHIPSEL_LEDS, OUTPUT);
|
||||||
|
digitalWrite(CHIPSEL_LEDS, LOW);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::tick()
|
||||||
|
{
|
||||||
|
doTransaction();
|
||||||
|
parseButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PanelScanner::clearAllLED()
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
led_half_buffer[i] = 0;
|
||||||
|
led_background_buffer[i] = 0;
|
||||||
|
led_blinking_buffer[i] = 0;
|
||||||
|
led_overlay_buffer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PanelScanner::setHalfLED(uint32_t num, bool on)
|
||||||
|
{
|
||||||
|
uint32_t byte_idx, bit_num;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
Serial.print("set half: ");
|
||||||
|
Serial.print(num);
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.println(on);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!on)
|
||||||
|
{
|
||||||
|
clearHalfLED(num);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funny math at play here.
|
||||||
|
// LEDs are out of order WRT the buttons...the first bit shifted in is the
|
||||||
|
// last bit shifted out on the SPI ring.
|
||||||
|
// So we'll flop that around here by doing the shifting and indexing
|
||||||
|
// math from the top down, rather than bottom up.
|
||||||
|
|
||||||
|
if (num < (NUM_PANELS * 8))
|
||||||
|
{
|
||||||
|
byte_idx = NUM_PANELS - 1 - (num / 8);
|
||||||
|
bit_num = num % 8;
|
||||||
|
|
||||||
|
led_half_buffer[byte_idx] |= 0x80 >> bit_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::clearHalfLED(uint32_t num)
|
||||||
|
{
|
||||||
|
uint32_t byte_idx, bit_num;
|
||||||
|
|
||||||
|
// see note above.
|
||||||
|
|
||||||
|
if (num < (NUM_PANELS * 8))
|
||||||
|
{
|
||||||
|
byte_idx = NUM_PANELS - 1 - (num / 8);
|
||||||
|
bit_num = num % 8;
|
||||||
|
|
||||||
|
led_half_buffer[byte_idx] &= ~(0x80 >> bit_num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::clearAllHalfLEDs()
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
led_half_buffer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void PanelScanner::setBackgroundLED(uint32_t num, bool on)
|
||||||
|
{
|
||||||
|
uint32_t byte_idx, bit_num;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
Serial.print("set background: ");
|
||||||
|
Serial.print(num);
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.println(on);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!on)
|
||||||
|
{
|
||||||
|
clearBackgroundLED(num);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funny math at play here.
|
||||||
|
// LEDs are out of order WRT the buttons...the first bit shifted in is the
|
||||||
|
// last bit shifted out on the SPI ring.
|
||||||
|
// So we'll flop that around here by doing the shifting and indexing
|
||||||
|
// math from the top down, rather than bottom up.
|
||||||
|
|
||||||
|
if (num < (NUM_PANELS * 8))
|
||||||
|
{
|
||||||
|
byte_idx = NUM_PANELS - 1 - (num / 8);
|
||||||
|
bit_num = num % 8;
|
||||||
|
|
||||||
|
led_background_buffer[byte_idx] |= 0x80 >> bit_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::clearBackgroundLED(uint32_t num)
|
||||||
|
{
|
||||||
|
uint32_t byte_idx, bit_num;
|
||||||
|
|
||||||
|
// see note above.
|
||||||
|
|
||||||
|
if (num < (NUM_PANELS * 8))
|
||||||
|
{
|
||||||
|
byte_idx = NUM_PANELS - 1 - (num / 8);
|
||||||
|
bit_num = num % 8;
|
||||||
|
|
||||||
|
led_background_buffer[byte_idx] &= ~(0x80 >> bit_num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::clearAllBackgroundLEDs()
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
led_background_buffer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
void PanelScanner::setBlinkingLED(uint32_t num, bool on)
|
||||||
|
{
|
||||||
|
uint32_t byte_idx, bit_num;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
Serial.print("set blinking: ");
|
||||||
|
Serial.println(num);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!on)
|
||||||
|
{
|
||||||
|
clearBlinkingLED(num);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funny math at play here.
|
||||||
|
// LEDs are out of order WRT the buttons...the first bit shifted in is the
|
||||||
|
// last bit shifted out on the SPI ring.
|
||||||
|
// So we'll flop that around here by doing the shifting and indexing
|
||||||
|
// math from the top down, rather than bottom up.
|
||||||
|
|
||||||
|
if (num < (NUM_PANELS * 8))
|
||||||
|
{
|
||||||
|
byte_idx = NUM_PANELS - 1 - (num / 8);
|
||||||
|
bit_num = num % 8;
|
||||||
|
|
||||||
|
led_blinking_buffer[byte_idx] |= 0x80 >> bit_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::clearBlinkingLED(uint32_t num)
|
||||||
|
{
|
||||||
|
uint32_t byte_idx, bit_num;
|
||||||
|
|
||||||
|
// see note above.
|
||||||
|
|
||||||
|
if (num < (NUM_PANELS * 8))
|
||||||
|
{
|
||||||
|
byte_idx = NUM_PANELS - 1 - (num / 8);
|
||||||
|
bit_num = num % 8;
|
||||||
|
|
||||||
|
led_blinking_buffer[byte_idx] &= ~(0x80 >> bit_num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::clearAllBlinkingLEDs()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
Serial.println("Clear all blinking");
|
||||||
|
#endif
|
||||||
|
for (uint32_t i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
led_blinking_buffer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///////////////////////////////////
|
||||||
|
|
||||||
|
void PanelScanner::setOverlayLED(uint32_t num)
|
||||||
|
{
|
||||||
|
uint32_t byte_idx, bit_num;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
Serial.print("OL on #");
|
||||||
|
Serial.println(num);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Funny math at play here.
|
||||||
|
// LEDs are out of order WRT the buttons...the first bit shifted in is the
|
||||||
|
// last bit shifted out on the SPI ring.
|
||||||
|
// So we'll flop that around here by doing the shifting and indexing
|
||||||
|
// math from the top down, rather than bottom up.
|
||||||
|
|
||||||
|
if (num < (NUM_PANELS * 8))
|
||||||
|
{
|
||||||
|
byte_idx = NUM_PANELS - 1 - (num / 8);
|
||||||
|
bit_num = num % 8;
|
||||||
|
|
||||||
|
led_overlay_buffer[byte_idx] |= 0x80 >> bit_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::clearOverlayLED(uint32_t num)
|
||||||
|
{
|
||||||
|
uint32_t byte_idx, bit_num;
|
||||||
|
|
||||||
|
// see note above.
|
||||||
|
|
||||||
|
if (num < (NUM_PANELS * 8))
|
||||||
|
{
|
||||||
|
byte_idx = NUM_PANELS - 1 - (num / 8);
|
||||||
|
bit_num = num % 8;
|
||||||
|
|
||||||
|
led_overlay_buffer[byte_idx] &= ~(0x80 >> bit_num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::clearAllOverlayLEDs()
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
led_overlay_buffer[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PanelScanner::parseButtons()
|
||||||
|
{
|
||||||
|
uint8_t diff;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
// in each byte, see if anything changed from last invocation
|
||||||
|
diff = new_buttons[i] ^ old_buttons[i];
|
||||||
|
|
||||||
|
for (uint32_t j = 0, mask = 0x01; j < 8; j++, mask <<= 1)
|
||||||
|
{
|
||||||
|
if (diff & mask)
|
||||||
|
{
|
||||||
|
//Serial.println(new_buttons[i]);
|
||||||
|
theEditor.receiveKey((i * 8) + j, (new_buttons[i] & mask));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// then store the new state for comparison next time
|
||||||
|
old_buttons[i] = new_buttons[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanelScanner::dumpLEDs()
|
||||||
|
{
|
||||||
|
Serial.print(led_background_buffer[0], HEX);
|
||||||
|
Serial.print(led_background_buffer[1], HEX);
|
||||||
|
Serial.println(led_background_buffer[2], HEX);
|
||||||
|
|
||||||
|
Serial.print(led_blinking_buffer[0], HEX);
|
||||||
|
Serial.print(led_blinking_buffer[1], HEX);
|
||||||
|
Serial.println(led_blinking_buffer[2], HEX);
|
||||||
|
|
||||||
|
Serial.print(led_overlay_buffer[0], HEX);
|
||||||
|
Serial.print(led_overlay_buffer[1], HEX);
|
||||||
|
Serial.println(led_overlay_buffer[2], HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PanelScanner::doTransaction()
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
//static uint32_t count = 0;
|
||||||
|
uint8_t trans_buffer[NUM_PANELS];
|
||||||
|
|
||||||
|
//count++;
|
||||||
|
|
||||||
|
// Ask the player for 1/32 step info for sync'd blinking
|
||||||
|
bool blink_phase = thePlayer.getBlinkPhase();
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
if (blink_phase)
|
||||||
|
{
|
||||||
|
trans_buffer[i] = led_half_buffer[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trans_buffer[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
trans_buffer[i] |= led_background_buffer[i];
|
||||||
|
trans_buffer[i] ^= led_overlay_buffer[i];
|
||||||
|
|
||||||
|
// Blinking supersedes static state...if blinking, it should blink,
|
||||||
|
// regardless of underlying static setting.
|
||||||
|
if (blink_phase)
|
||||||
|
{
|
||||||
|
trans_buffer[i] |= led_blinking_buffer[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trans_buffer[i] &= ~led_blinking_buffer[i];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//LEDs korrekt
|
||||||
|
//S1-S8 und S17-S24 tauschen
|
||||||
|
|
||||||
|
SPI.beginTransaction(registersettings);
|
||||||
|
|
||||||
|
digitalWrite(CHIPSEL_BTNS, HIGH);
|
||||||
|
|
||||||
|
SPI.transfer(trans_buffer, NUM_PANELS);
|
||||||
|
|
||||||
|
digitalWrite(CHIPSEL_LEDS, HIGH);
|
||||||
|
digitalWrite(CHIPSEL_BTNS, LOW);
|
||||||
|
digitalWrite(CHIPSEL_LEDS, LOW);
|
||||||
|
|
||||||
|
SPI.endTransaction();
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_PANELS; i++)
|
||||||
|
{
|
||||||
|
// Button lines are pulled high by resistors, shorted
|
||||||
|
// to ground when button is pressed.
|
||||||
|
// Invert what we read to make active high
|
||||||
|
new_buttons[i] = ~trans_buffer[2-i];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue