112 lines
No EOL
4 KiB
C++
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();
|
|
} |