#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 obs) { m_observers.push_back(obs); obs(); }