PicoWaveTracker/RP2040_Tracker.ino

110 lines
2.4 KiB
C++

#include <SPI.h>
#include <Wire.h>
#include <EEPROM.h>
#include "TrackerTypes.h"
#include "MidiDriver.h"
#include "UIManager.h"
#include "config.h"
#include "UIThread.h"
#include "PlaybackThread.h"
#include "SharedState.h"
// Watchdog
volatile unsigned long lastLoop0Time = 0;
volatile unsigned long lastLoop1Time = 0;
volatile bool watchdogActive = false;
// Encoder State
static uint8_t prevNextCode = 0;
static uint16_t store = 0;
// --- ENCODER INTERRUPT ---
// Robust Rotary Encoder reading
void readEncoder() {
static int8_t rot_enc_table[] = {0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0};
prevNextCode <<= 2;
if (digitalRead(ENC_DT)) prevNextCode |= 0x02;
if (digitalRead(ENC_CLK)) prevNextCode |= 0x01;
prevNextCode &= 0x0f;
// If valid state
if (rot_enc_table[prevNextCode]) {
store <<= 4;
store |= prevNextCode;
if ((store & 0xff) == 0x2b) encoderDelta--;
if ((store & 0xff) == 0x17) encoderDelta++;
}
}
void setup() {
Serial.begin(115200);
// Use random ADC noise for seed
delay(5000);
Serial.println(F("Starting."));
// 1. Setup Encoder
pinMode(ENC_CLK, INPUT_PULLUP);
pinMode(ENC_DT, INPUT_PULLUP);
pinMode(ENC_SW, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENC_CLK), readEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENC_DT), readEncoder, CHANGE);
ui.begin();
midi.begin();
// 5. Init Sequence
randomSeed(micros());
Serial.println(F("Loading sequence."));
EEPROM.begin(512);
if (!loadSequence()) {
Serial.println(F("Starting fresh instead."));
numSteps = NUM_STEPS;
for(int i=0; i<NUM_TRACKS; i++) {
midiChannels[i] = i + 1;
melodySeeds[i] = random(10000);
currentStrategyIndices[i] = 0;
trackMute[i] = false;
}
generateRandomScale();
generateTheme(1);
}
isPlaying = false; // Don't start playing on boot
Serial.println(F("Started."));
// Enable Watchdog
lastLoop0Time = millis();
lastLoop1Time = millis();
watchdogActive = true;
}
void loop1() {
if (!watchdogActive) {
delay(100);
return;
}
unsigned long now = millis();
lastLoop1Time = now;
if (watchdogActive && (now - lastLoop0Time > 1000)) {
Serial.println("Core 0 Freeze detected");
rp2040.reboot();
}
loopPlayback();
}
void loop() {
unsigned long now = millis();
lastLoop0Time = now;
if (watchdogActive && (now - lastLoop1Time > 1000)) {
Serial.println("Core 1 Freeze detected");
rp2040.reboot();
}
loopUI();
}