diff --git a/src/keyer.cpp b/src/keyer.cpp index d2734f0..2a334cc 100644 --- a/src/keyer.cpp +++ b/src/keyer.cpp @@ -4,7 +4,9 @@ #include "keyer.h" +extern const uint LED_PIN; extern const uint LEFT_PADDLE_PIN; +extern const uint RIGHT_PADDLE_PIN; bool left_paddle_pressed() { @@ -15,42 +17,84 @@ bool left_paddle_pressed() return false; } +bool right_paddle_pressed() +{ + if (!gpio_get(RIGHT_PADDLE_PIN)) + { + return true; + } + return false; +} + +uint64_t calcElementDurationUs(uint8_t wpm) +{ + uint64_t duration = static_cast(1.2 / static_cast(wpm) * 1000 * 1000); + return duration; +} + +Keyer::Keyer(uint8_t wpm) : m_wpm(wpm) +{ + m_elementDuration = calcElementDurationUs(m_wpm); +} + void Keyer::run() { + auto timestamp = get_absolute_time(); + switch (state) { case State::Wait: - if (left_paddle_pressed()) + if (left_paddle_pressed()) { state = State::Dit; - break; - case State::Dit: - printf("."); - - if (left_paddle_pressed()) - state = State::InterCharSpace; - else - state = State::Wait; - break; - case State::Dah: - printf("-"); - ++numElements; - if (numElements == 3) - { - numElements = 0; - if (left_paddle_pressed()) - state = State::InterCharSpace; - else - state = State::Wait; + } else if (right_paddle_pressed()) { + state = State::Dah; } break; - - case State::InterCharSpace: - printf("(.)"); - - if (left_paddle_pressed()) - state = State::Dit; + case State::Dit: + if (!m_currentlyKeying) + { + m_currentlyKeying = true; + m_keying_until = make_timeout_time_us(m_elementDuration); + gpio_put(LED_PIN, 1); + } else + { + if (absolute_time_diff_us(timestamp, m_keying_until) <= 0) + { + m_currentlyKeying = false; + gpio_put(LED_PIN, 0); + m_previousState = State::Dit; + state = State::InterCharSpace; + } + } + break; + case State::Dah: + if(!m_currentlyKeying) { + m_currentlyKeying = true; + m_keying_until = make_timeout_time_us(m_elementDuration * 3); + gpio_put(LED_PIN, 1); + } else { + if (absolute_time_diff_us(timestamp, m_keying_until) <= 0) + { + m_currentlyKeying = false; + gpio_put(LED_PIN, 0); + m_previousState = State::Dah; + state = State::InterCharSpace; + } + + } + break; + case State::InterCharSpace: + if (m_previousState != State::InterCharSpace) + { + m_pausing_until = make_timeout_time_us(m_elementDuration); + m_previousState = State::InterCharSpace; + } + + if(absolute_time_diff_us(timestamp, m_pausing_until) <= 0) { state = State::Wait; + } + break; default: diff --git a/src/keyer.h b/src/keyer.h index 622ed28..b0d67cf 100644 --- a/src/keyer.h +++ b/src/keyer.h @@ -12,18 +12,20 @@ public: InterCharSpace, }; + Keyer(uint8_t wpm); void run(); private: + Keyer() {}; State state{State::Wait}; - uint8_t numElements{0}; + State m_previousState{State::Wait}; + uint8_t m_wpm{18}; + uint64_t m_elementDuration{0}; + bool m_currentlyKeying {false}; + absolute_time_t m_keying_until{0}; + absolute_time_t m_pausing_until{0}; }; -inline uint64_t element_duration_us(uint8_t wpm) -{ - uint64_t duration = static_cast(1.2 / static_cast(wpm) * 1000 * 1000); - return duration; -} #endif \ No newline at end of file diff --git a/src/pico_keyer.cpp b/src/pico_keyer.cpp index 3f0a4cb..38db9f7 100644 --- a/src/pico_keyer.cpp +++ b/src/pico_keyer.cpp @@ -8,15 +8,16 @@ namespace { - const uint LED_PIN = PICO_DEFAULT_LED_PIN; - - const uint RIGHT_PADDLE_PIN = 15; + } + +extern const uint LED_PIN = PICO_DEFAULT_LED_PIN; extern const uint LEFT_PADDLE_PIN = 14; +extern const uint RIGHT_PADDLE_PIN = 15; void setup() { - + stdio_init_all(); gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); gpio_put(LED_PIN, 0); @@ -28,27 +29,26 @@ void setup() gpio_init(RIGHT_PADDLE_PIN); gpio_set_dir(RIGHT_PADDLE_PIN, GPIO_IN); gpio_pull_up(RIGHT_PADDLE_PIN); + sleep_ms(1000); } int main() { - stdio_init_all(); timer_hw->dbgpause = 0; // fix problem with debug and sleep_ms https://github.com/raspberrypi/pico-sdk/issues/1152#issuecomment-1418248639 - sleep_ms(1000); setup(); Settings settings{read_settings()}; - printf("\nIambic mode (loaded): %d\n", static_cast(settings.mode)); - printf("WPM (loaded): %d\n", settings.wpm); - printf("Element duration (u_sec): %" PRIu64 "\n", element_duration_us(settings.wpm)); + // printf("\nIambic mode (loaded): %d\n", static_cast(settings.mode)); + // printf("WPM (loaded): %d\n", settings.wpm); + // printf("Element duration (u_sec): %" PRIu64 "\n", element_duration_us(settings.wpm)); + printf("\n"); - Keyer keyer; + Keyer keyer(settings.wpm); while (true) { - sleep_us(element_duration_us(settings.wpm)); keyer.run(); }