121 lines
2.9 KiB
C++
121 lines
2.9 KiB
C++
// Copyright 2020 Neale Pickett
|
|
// Distributed under the MIT license
|
|
// Please see https://github.com/nealey/vail-adapter/
|
|
|
|
// MIDIUSB - Version: Latest
|
|
#include <MIDIUSB.h>
|
|
#include <Keyboard.h>
|
|
#include <Adafruit_FreeTouch.h>
|
|
#include "bounce2.h"
|
|
#include "touchbounce.h"
|
|
#include "adapter.h"
|
|
|
|
#define DIT_PIN 2
|
|
#define DAH_PIN 1
|
|
#define KEY_PIN 0
|
|
#define QT_DIT_PIN A6
|
|
#define QT_DAH_PIN A7
|
|
#define QT_KEY_PIN A8
|
|
#define PIEZO 10
|
|
#define LED_ON false // Xiao inverts this logic for some reason
|
|
#define LED_OFF (!LED_ON)
|
|
|
|
#define DIT_KEYBOARD_KEY KEY_LEFT_CTRL
|
|
#define DAH_KEYBOARD_KEY KEY_RIGHT_CTRL
|
|
#define TONE 3000
|
|
|
|
#define MILLISECOND 1
|
|
#define SECOND (1 * MILLISECOND)
|
|
|
|
bool trs = false; // true if a TRS plug is in a TRRS jack
|
|
uint16_t iambicDelay = 80 * MILLISECOND;
|
|
Bounce dit = Bounce();
|
|
Bounce dah = Bounce();
|
|
Bounce key = Bounce();
|
|
TouchBounce qt_dit = TouchBounce();
|
|
TouchBounce qt_dah = TouchBounce();
|
|
TouchBounce qt_key = TouchBounce();
|
|
VailAdapter adapter = VailAdapter(PIEZO);
|
|
|
|
void setup() {
|
|
pinMode(LED_BUILTIN, OUTPUT);
|
|
dit.attach(DIT_PIN, INPUT_PULLUP);
|
|
dah.attach(DAH_PIN, INPUT_PULLUP);
|
|
key.attach(KEY_PIN, INPUT_PULLUP);
|
|
qt_dit.attach(QT_DIT_PIN);
|
|
qt_dah.attach(QT_DAH_PIN);
|
|
qt_key.attach(QT_KEY_PIN);
|
|
|
|
Keyboard.begin();
|
|
|
|
// To auto-sense a straight key in a TRRS jack,
|
|
// we just check to see if DAH is closed.
|
|
// The sleeve on the straight key's TRS plug
|
|
// will short the second ring to the sleeve.
|
|
for (int i = 0; i < 16; i++) {
|
|
delay(20);
|
|
dah.update();
|
|
}
|
|
if (dah.read() == LOW) {
|
|
trs = true;
|
|
key = dit;
|
|
}
|
|
}
|
|
|
|
// A reentrant doodad to blink out the letter V at startup
|
|
// After startup, display the status of the keyboard
|
|
#define HELLO_BITS 0b0000101010111000
|
|
void setLED() {
|
|
static bool beepin = false;
|
|
int beat = millis() / iambicDelay;
|
|
bool on = adapter.KeyboardMode(); // If we're not in intro, display status of keyboard
|
|
|
|
if (beat < 16) {
|
|
on = HELLO_BITS & (1 << (15-beat));
|
|
if (on != beepin) {
|
|
if (on) {
|
|
tone(PIEZO, TONE);
|
|
} else {
|
|
noTone(PIEZO);
|
|
}
|
|
beepin = on;
|
|
}
|
|
}
|
|
|
|
digitalWrite(LED_BUILTIN, on?LED_ON:LED_OFF);
|
|
}
|
|
|
|
void loop() {
|
|
unsigned now = millis();
|
|
midiEventPacket_t event = MidiUSB.read();
|
|
|
|
setLED();
|
|
adapter.Tick(now);
|
|
|
|
if (event.header) {
|
|
adapter.HandleMIDI(event);
|
|
}
|
|
|
|
// Monitor straight key pin
|
|
if (key.update() || qt_key.update()) {
|
|
bool pressed = !key.read() || qt_key.read();
|
|
adapter.HandlePaddle(PADDLE_STRAIGHT, pressed);
|
|
}
|
|
|
|
// If we made dit = dah, we have a straight key on the dit pin,
|
|
// so we skip other keys polling.
|
|
if (trs) {
|
|
return;
|
|
}
|
|
|
|
if (dit.update() || qt_dit.update()) {
|
|
bool pressed = !dit.read() || qt_dit.read();
|
|
adapter.HandlePaddle(PADDLE_DIT, pressed);
|
|
}
|
|
|
|
if (dah.update() || qt_dah.update()) {
|
|
bool pressed = !dah.read() || qt_dah.read();
|
|
adapter.HandlePaddle(PADDLE_DAH, pressed);
|
|
}
|
|
}
|