raspikeyer/src/winkeyer.cpp

112 lines
No EOL
4 KiB
C++

#include "pico/stdlib.h"
#include "tusb.h"
#include "utils.h"
#include "winkeyer.h"
void WinKeyer::run(queue_t &queue)
{
const uint8_t USB_IF = 0;
static uint8_t buf[64] {0};
if (tud_cdc_n_available(USB_IF)) {
if (m_commandState == CommandState::None) {
uint8_t value = tud_cdc_n_read_char(USB_IF);
switch (value) {
case ' ':
[[fallthrough]];
case '\"':
[[fallthrough]];
case '$':
[[fallthrough]];
case '\'':
[[fallthrough]];
case '(':
[[fallthrough]];
case ')':
[[fallthrough]];
case '+' ... ']': {
if (m_hostOpen) {
KeyerQueueData keyerQueueData {KeyerQueueCommand::SendMessage, 0, Mode::IambicB, value};
queue_add_blocking(&queue, &keyerQueueData);
}
break;
}
case 0x00: // ADMIN
m_commandState = CommandState::Admin;
break;
case 0x07: // GET SPEED POT
printf("INFO: Get Speed Pot currently not supported.\n");
break;
case 0x0A: {
// TODO: Implement abort sending message
KeyerQueueData keyerQueueData {KeyerQueueCommand::Stop, 0, Mode::IambicB, value};
queue_add_blocking(&queue, &keyerQueueData);
} break;
case 0x0B: // KEY IMMEDIATE
m_commandState = CommandState::KeyImmediate;
break;
case 0x0F: // LOAD DEFAULTS
m_commandState = CommandState::LoadDefaults;
break;
case 0x13: // NOP
break;
case 0x15: // REQUEST WINKEY STATUS
printf("INFO: Request WinKey Status currently not supported.\n");
usbSend(USB_IF, 0b11000000);
break;
default:
printf("Unknown command: %x\n", value);
m_commandState = CommandState::None;
break;
}
} else if (m_commandState == CommandState::Admin) {
uint8_t value = tud_cdc_n_read_char(USB_IF);
switch (value) {
case 0x02: // HOST OPEN
usbSend(USB_IF, 9); // Send v9 back (Winkeyer 1)
m_hostOpen = true;
m_commandState = CommandState::None;
break;
case 0x03: // HOST CLOSE
m_hostOpen = false;
break;
case 0x04:
m_commandState = CommandState::AdminEchoTest;
break;
case 0x0a: // SET WK1 MODE
m_wkMode = WkMode::WK1;
m_commandState = CommandState::None;
break;
default:
printf("Unknown admin command: %x.\n", value);
m_commandState = CommandState::None;
break;
}
} else if (m_commandState == CommandState::AdminEchoTest) {
uint8_t value = tud_cdc_n_read_char(USB_IF);
usbSend(USB_IF, value); // Send the received byte back
m_commandState = CommandState::None;
} else if (m_commandState == CommandState::LoadDefaults) {
if (tud_cdc_n_available(USB_IF) < 15) {
printf("LOAD DEFAULTS: Waiting for remaining bytes ...\n");
return;
}
tud_cdc_n_read(USB_IF, buf, 15);
printf("INFO: Loading defaults currently not supported.\n");
m_commandState = CommandState::None;
} else if (m_commandState == CommandState::KeyImmediate) {
tud_cdc_n_read_char(USB_IF); // Silently ignore byte
printf("INFO: Tune not supported.\n");
m_commandState = CommandState::None;
}
}
}
void WinKeyer::addObserver(std::function<void()> obs) {
m_observers.push_back(obs);
obs();
}