From f1d865ab6806d3449884c48de4908f661a8816fd Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Thu, 29 Feb 2024 16:50:53 +0100 Subject: [PATCH] more on wk emulation --- src/keyer.cpp | 6 ++- src/raspikeyer.cpp | 4 +- src/utils.h | 1 - src/winkeyer.cpp | 98 +++++++++++++++++++++++++++++++++++----------- src/winkeyer.h | 16 ++++++++ 5 files changed, 98 insertions(+), 27 deletions(-) diff --git a/src/keyer.cpp b/src/keyer.cpp index 553ed5c..6b12321 100644 --- a/src/keyer.cpp +++ b/src/keyer.cpp @@ -341,4 +341,8 @@ void Keyer::run() } } -void Keyer::stop() { m_paddleKeyingState = State::Abort; } \ No newline at end of file +void Keyer::stop() +{ + m_paddleKeyingState = State::Abort; + m_messageKeyingState = MessageState::Abort; +} \ No newline at end of file diff --git a/src/raspikeyer.cpp b/src/raspikeyer.cpp index 7730e1f..b6b3ac7 100644 --- a/src/raspikeyer.cpp +++ b/src/raspikeyer.cpp @@ -72,7 +72,7 @@ void core1_main() break; case KeyerQueueCommand::Stop: keyer.stop(); - data.cmd = KeyerQueueCommand::Wait; + data.cmd = KeyerQueueCommand::Run; break; case KeyerQueueCommand::Config: keyer.setSpeed(data.wpm); @@ -83,8 +83,6 @@ void core1_main() keyer.sendCharacter(data.message); data.cmd = KeyerQueueCommand::Run; break; - case KeyerQueueCommand::Wait: - break; default: break; } diff --git a/src/utils.h b/src/utils.h index 5bf3153..1981afc 100644 --- a/src/utils.h +++ b/src/utils.h @@ -7,7 +7,6 @@ enum class KeyerQueueCommand { Run, Stop, Config, - Wait, SendMessage, }; diff --git a/src/winkeyer.cpp b/src/winkeyer.cpp index 8b0b75b..c0c53fb 100644 --- a/src/winkeyer.cpp +++ b/src/winkeyer.cpp @@ -8,15 +8,15 @@ 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)) { - uint8_t buf[64]; - // printf("AHA!!! %d\n", (int)tud_cdc_n_available(USB_IF)); - uint32_t count = tud_cdc_n_read(USB_IF, buf, sizeof(buf)); - - if (count > 0) { - switch (buf[0]) { + if (m_commandState == CommandState::None) { + uint8_t value = tud_cdc_n_read_char(USB_IF); + switch (value) { + case ' ': + [[fallthrough]]; case '\"': [[fallthrough]]; case '$': @@ -28,25 +28,79 @@ void WinKeyer::run(queue_t &queue) case ')': [[fallthrough]]; case '+' ... ']': { - KeyerQueueData keyerQueueData {KeyerQueueCommand::SendMessage, 0, Mode::IambicB, buf[0]}; - queue_add_blocking(&queue, &keyerQueueData); - break; - } - case 0x00: // ADMIN COMMAND - switch (buf[1]) { - case 0x02: // HOST OPEN - usbSend(USB_IF, 9); // Send WK1 (v9) for now (no WinKeyer PTT control) - break; - case 0x04: // ECHO TEST - usbSend(USB_IF, &buf[2], 1); // Send the received byte back - break; - default: - printf("Unknown admin command: %x\n", buf[1]); + if (m_hostOpen) { + KeyerQueueData keyerQueueData {KeyerQueueCommand::SendMessage, 0, Mode::IambicB, value}; + queue_add_blocking(&queue, &keyerQueueData); } break; - default: - printf("Unknown command: %d.\n", buf[0]); } + 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; } } } \ No newline at end of file diff --git a/src/winkeyer.h b/src/winkeyer.h index a4afaaa..e0aabee 100644 --- a/src/winkeyer.h +++ b/src/winkeyer.h @@ -8,4 +8,20 @@ class WinKeyer final void run(queue_t &queue); private: + enum class CommandState { + None, + Admin, + AdminEchoTest, + LoadDefaults, + KeyImmediate, + }; + enum class WkMode { + WK1, + WK2, + WK3, + }; + + CommandState m_commandState {CommandState::None}; + WkMode m_wkMode {WkMode::WK1}; + bool m_hostOpen {false}; }; \ No newline at end of file