#include #include "pico/stdlib.h" #include "keyer.h" extern const uint LED_PIN; extern const uint LEFT_PADDLE_PIN; extern const uint RIGHT_PADDLE_PIN; bool left_paddle_pressed() { if (!gpio_get(LEFT_PADDLE_PIN)) { return true; } 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()) { state = State::Dit; } else if (right_paddle_pressed()) { state = State::Dah; } break; 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: break; } }