diff --git a/CMakeLists.txt b/CMakeLists.txt index 4092bfd..a574f0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ target_link_libraries(raspi_keyer hardware_pwm pico_flash pico_multicore + hardware_adc tinyusb_device tinyusb_board hardware_pio diff --git a/src/raspi_keyer.cpp b/src/raspi_keyer.cpp index f3acf9b..8c01d96 100644 --- a/src/raspi_keyer.cpp +++ b/src/raspi_keyer.cpp @@ -1,6 +1,8 @@ +#include #include #include "bsp/board.h" +#include "hardware/adc.h" #include "pico/multicore.h" #include "pico/stdlib.h" #include "pico/util/queue.h" @@ -21,6 +23,7 @@ extern const uint RIGHT_PADDLE_PIN = 15; extern const uint BUZZER_PIN = 18; extern const uint CW_OUT_PIN = 17; extern const uint AUDIO_OUT_PIN = 16; +extern const uint ADC_PIN = 26; // Stuff for communicating between cores enum class KeyerQueueCommand { @@ -54,11 +57,17 @@ void setup() gpio_init(CW_OUT_PIN); gpio_set_dir(CW_OUT_PIN, GPIO_OUT); gpio_put(CW_OUT_PIN, 0); + + // Setup ADC + adc_init(); + gpio_init(ADC_PIN); + adc_select_input(0); } /* Let's do all the keying stuff in the second core, so there are no timing problems. */ void core1_main() { + flash_safe_execute_core_init(); printf("Hello from core1!\n"); KeyerQueueData data; queue_remove_blocking(&keyerQueue, &data); @@ -89,15 +98,13 @@ void core1_main() } } -[[maybe_unused]] -static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) +[[maybe_unused]] static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) { - for(uint32_t i=0; i 1) { printf("Command received …\n"); switch (buf[0]) { - case 0: // ADMIN COMMAND + case 0: // ADMIN COMMAND switch (buf[1]) { - case 2: // Host Open - // TODO: send back revision code - default: + case 2: // Host Open + // TODO: send back revision code + default: printf("Unknown admin command.\n"); } break; @@ -126,9 +133,27 @@ void cdc_task() } } +/* Returns the voltage level in percent (3,3V == 100%) */ +float potiRead() +{ + // 12-bit conversion, assume max value == ADC_VREF == 3.3 V + const float conversion_factor = 3.3f / (1 << 12); + float voltage = adc_read() * conversion_factor; + + return voltage * 100 / 3.3; +} + +/* Calculates the WPM speed from the volt percentage */ +uint8_t calcWPM(float percent, uint8_t wpmMin, uint8_t wpmMax) +{ + auto wpm = (percent * (wpmMax - wpmMin) / 100) + wpmMin; + uint8_t result = static_cast(std::round(wpm)); + return result; +} + int main() { - // timer_hw->dbgpause = 2; // workaround for problem with debug and sleep_ms + timer_hw->dbgpause = 0; // workaround for problem with debug and sleep_ms // https://github.com/raspberrypi/pico-sdk/issues/1152#issuecomment-1418248639 setup(); @@ -137,19 +162,36 @@ int main() printf("Hello from core0!\n"); - Settings settings {read_settings()}; - settings.wpm = 25; // TODO: remove! + //Settings settings {read_settings()}; + Settings settings; + uint8_t currentWpm, lastWpm {0}; + if (settings.wpm == 0) { + currentWpm = calcWPM(potiRead(), settings.wpmPotiMin, settings.wpmPotiMax); + } else { + currentWpm = settings.wpm; + } + lastWpm = currentWpm; queue_init(&keyerQueue, sizeof(KeyerQueueData), 2); multicore_reset_core1(); multicore_launch_core1(core1_main); - KeyerQueueData keyerQueueData {KeyerQueueCommand::Run, settings.wpm, settings.mode}; + KeyerQueueData keyerQueueData {KeyerQueueCommand::Run, currentWpm, settings.mode}; queue_add_blocking(&keyerQueue, &keyerQueueData); while (true) { tud_task(); cdc_task(); + + currentWpm = calcWPM(potiRead(), settings.wpmPotiMin, settings.wpmPotiMax); + if (currentWpm != lastWpm) { + KeyerQueueData keyerQueueData {KeyerQueueCommand::Config, currentWpm, settings.mode}; + queue_add_blocking(&keyerQueue, &keyerQueueData); + printf("WPM has changed to: %d\n", currentWpm); + lastWpm = currentWpm; + } + + busy_wait_ms(1000); } return 0;