now with sidetone

This commit is contained in:
Martin Brodbeck 2024-02-12 15:57:50 +01:00
parent c8ab1c7741
commit 10d56f8a8b
7 changed files with 63 additions and 1 deletions

View file

@ -49,6 +49,7 @@ target_include_directories(pico_keyer PRIVATE
target_link_libraries(pico_keyer target_link_libraries(pico_keyer
hardware_flash hardware_flash
hardware_exception hardware_exception
hardware_pwm
pico_flash pico_flash
) )

View file

@ -2,4 +2,5 @@ target_sources(pico_keyer PRIVATE
pico_keyer.cpp pico_keyer.cpp
settings.cpp settings.cpp
keyer.cpp keyer.cpp
sidetone.cpp
) )

View file

@ -3,11 +3,15 @@
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "keyer.h" #include "keyer.h"
#include "sidetone.h"
extern const uint LED_PIN; extern const uint LED_PIN;
extern const uint LEFT_PADDLE_PIN; extern const uint LEFT_PADDLE_PIN;
extern const uint RIGHT_PADDLE_PIN; extern const uint RIGHT_PADDLE_PIN;
const uint SIDETONE_FREQ = 622;
bool left_paddle_pressed() bool left_paddle_pressed()
{ {
if (!gpio_get(LEFT_PADDLE_PIN)) if (!gpio_get(LEFT_PADDLE_PIN))
@ -68,6 +72,7 @@ void Keyer::run()
m_currentlyKeying = true; m_currentlyKeying = true;
m_keying_until = make_timeout_time_us(m_elementDuration); m_keying_until = make_timeout_time_us(m_elementDuration);
gpio_put(LED_PIN, 1); gpio_put(LED_PIN, 1);
m_Sidetone.on(SIDETONE_FREQ);
m_lastSymbolWas = Symbol::Dit; m_lastSymbolWas = Symbol::Dit;
} }
else else
@ -76,6 +81,7 @@ void Keyer::run()
{ {
m_currentlyKeying = false; m_currentlyKeying = false;
gpio_put(LED_PIN, 0); gpio_put(LED_PIN, 0);
m_Sidetone.off();
m_previousState = State::Dit; m_previousState = State::Dit;
state = State::InterCharSpace; state = State::InterCharSpace;
} }
@ -87,6 +93,7 @@ void Keyer::run()
m_currentlyKeying = true; m_currentlyKeying = true;
m_keying_until = make_timeout_time_us(m_elementDuration * 3); m_keying_until = make_timeout_time_us(m_elementDuration * 3);
gpio_put(LED_PIN, 1); gpio_put(LED_PIN, 1);
m_Sidetone.on(SIDETONE_FREQ);
m_lastSymbolWas = Symbol::Dah; m_lastSymbolWas = Symbol::Dah;
} }
else else
@ -95,6 +102,7 @@ void Keyer::run()
{ {
m_currentlyKeying = false; m_currentlyKeying = false;
gpio_put(LED_PIN, 0); gpio_put(LED_PIN, 0);
m_Sidetone.off();
m_previousState = State::Dah; m_previousState = State::Dah;
state = State::InterCharSpace; state = State::InterCharSpace;
} }

View file

@ -1,6 +1,10 @@
#ifndef KEYER_H #ifndef KEYER_H
#define KEYER_H #define KEYER_H
#include "sidetone.h"
extern const uint BUZZER_PIN;
class Keyer final class Keyer final
{ {
public: public:
@ -31,6 +35,7 @@ private:
absolute_time_t m_keying_until{0}; absolute_time_t m_keying_until{0};
absolute_time_t m_pausing_until{0}; absolute_time_t m_pausing_until{0};
Symbol m_lastSymbolWas{Symbol::Dit}; Symbol m_lastSymbolWas{Symbol::Dit};
Sidetone m_Sidetone{BUZZER_PIN};
}; };
#endif #endif

View file

@ -14,6 +14,7 @@ namespace
extern const uint LED_PIN = PICO_DEFAULT_LED_PIN; extern const uint LED_PIN = PICO_DEFAULT_LED_PIN;
extern const uint LEFT_PADDLE_PIN = 14; extern const uint LEFT_PADDLE_PIN = 14;
extern const uint RIGHT_PADDLE_PIN = 15; extern const uint RIGHT_PADDLE_PIN = 15;
extern const uint BUZZER_PIN = 13;
void setup() void setup()
{ {
@ -29,6 +30,7 @@ void setup()
gpio_init(RIGHT_PADDLE_PIN); gpio_init(RIGHT_PADDLE_PIN);
gpio_set_dir(RIGHT_PADDLE_PIN, GPIO_IN); gpio_set_dir(RIGHT_PADDLE_PIN, GPIO_IN);
gpio_pull_up(RIGHT_PADDLE_PIN); gpio_pull_up(RIGHT_PADDLE_PIN);
sleep_ms(1000); sleep_ms(1000);
} }
@ -45,7 +47,7 @@ int main()
// printf("Element duration (u_sec): %" PRIu64 "\n", element_duration_us(settings.wpm)); // printf("Element duration (u_sec): %" PRIu64 "\n", element_duration_us(settings.wpm));
printf("\n"); printf("\n");
Keyer keyer(15); Keyer keyer(25);
while (true) while (true)
{ {

29
src/sidetone.cpp Normal file
View file

@ -0,0 +1,29 @@
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "sidetone.h"
Sidetone::Sidetone(uint gpio) : m_gpio(gpio)
{
gpio_set_function(gpio, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(gpio);
pwm_config config = pwm_get_default_config();
pwm_init(slice_num, &config, true);
}
void Sidetone::on(uint freq)
{
// Calculate and cofigure new clock divider according to the frequency
// This formula is assuming we are running at 125MHz.
// TODO: Make this work for any frequency
float clkdiv = (1.f / freq) * 2000.f;
uint slice_num = pwm_gpio_to_slice_num(m_gpio);
pwm_set_clkdiv(slice_num, clkdiv);
// Configure duty to 50% ((2**16)-1)/2) to generate a square wave
pwm_set_gpio_level(m_gpio, 32768U);
}
void Sidetone::off()
{
pwm_set_gpio_level(m_gpio, 0);
}

16
src/sidetone.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef SIDETONE_H
#define SIDETONE_H
class Sidetone
{
public:
Sidetone(uint gpio);
void on(uint freq);
void off();
private:
Sidetone(){};
uint m_gpio{0};
};
#endif