Merge branch 'multicore'

This commit is contained in:
Martin Brodbeck 2024-02-15 13:54:05 +01:00
commit 20dc5c8a03
4 changed files with 120 additions and 13 deletions

View file

@ -32,7 +32,7 @@ pico_set_program_name(raspi_keyer "raspi_keyer")
pico_set_program_version(raspi_keyer "0.0.1")
pico_enable_stdio_uart(raspi_keyer 1)
pico_enable_stdio_usb(raspi_keyer 0)
pico_enable_stdio_usb(raspi_keyer 1)
target_compile_options(raspi_keyer PRIVATE -Wall -Wextra -Werror)
@ -52,6 +52,7 @@ target_link_libraries(raspi_keyer
hardware_exception
hardware_pwm
pico_flash
pico_multicore
)
pico_add_extra_outputs(raspi_keyer)

View file

@ -141,16 +141,56 @@ void Keyer::run()
m_pausing_until = make_timeout_time_us(m_elementDuration);
m_currentlyPausing = true;
}
if (absolute_time_diff_us(timestamp, m_pausing_until) <= 0)
// Handle the case when the other paddle is pressed during the inter character space
else if (absolute_time_diff_us(timestamp, m_pausing_until) > 0)
{
m_currentlyPausing = false;
state = State::Wait;
if (left_paddle_pressed() && m_previousState == State::Dah && m_nextState == State::Wait)
{
printf("--- Pause --- Next state is Dit!\n");
m_nextState = State::Dit;
m_keyNextIambicB = right_paddle_pressed() ? true : false;
}
else if (right_paddle_pressed() && m_previousState == State::Dit && m_nextState == State::Wait)
{
printf("--- Pause --- Next state is Dah!\n");
m_nextState = State::Dah;
m_keyNextIambicB = left_paddle_pressed() ? true : false;
}
else if (m_previousState == State::Wait)
{
m_nextState = State::Wait;
}
}
else
{
if (absolute_time_diff_us(timestamp, m_pausing_until) <= 0)
{
m_currentlyPausing = false;
state = m_nextState;
m_nextState = State::Wait;
}
}
break;
case State::Abort:
gpio_put(LED_PIN, 0);
m_Sidetone.off();
m_keyNextIambicB = false;
m_currentlyPausing = false;
m_currentlyKeying = false;
m_previousState = State::Abort;
m_nextState = State::Wait;
state = State::Wait;
break;
default:
break;
}
}
void Keyer::stop()
{
state = State::Abort;
}

View file

@ -15,6 +15,7 @@ public:
Dit,
Dah,
InterCharSpace,
Abort,
};
Keyer() = delete;
Keyer(uint8_t wpm, Mode mode);
@ -23,10 +24,12 @@ public:
void setSpeed(uint8_t wpm);
void run();
void stop();
private:
State state{State::Wait};
State m_previousState{State::Wait};
State m_nextState{State::Wait};
uint8_t m_wpm{18};
Mode m_mode{Mode::IAMBIC_B};
uint64_t m_elementDuration{0};

View file

@ -1,6 +1,8 @@
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/multicore.h"
#include "pico/util/queue.h"
#include "settings.h"
#include "keyer.h"
@ -13,7 +15,24 @@ namespace
extern const uint LED_PIN = PICO_DEFAULT_LED_PIN;
extern const uint LEFT_PADDLE_PIN = 14;
extern const uint RIGHT_PADDLE_PIN = 15;
extern const uint BUZZER_PIN = 13;
extern const uint BUZZER_PIN = 18;
// Stuff for communicating between cores
enum class KeyerQueueCommand
{
Run,
Stop,
Config,
Wait,
};
struct KeyerQueueData
{
KeyerQueueCommand cmd;
uint8_t wpm;
Mode mode;
};
queue_t keyerQueue;
void setup()
{
@ -30,23 +49,67 @@ void setup()
gpio_set_dir(RIGHT_PADDLE_PIN, GPIO_IN);
gpio_pull_up(RIGHT_PADDLE_PIN);
sleep_ms(1000);
//sleep_ms(1000);
}
/* Let's do all the keying stuff in the second core, so there are no timing problems. */
void core1_main()
{
printf("Hello from core1!\n");
KeyerQueueData data;
queue_remove_blocking(&keyerQueue, &data);
Keyer keyer(data.wpm, data.mode);
while (true)
{
queue_try_remove(&keyerQueue, &data);
switch (data.cmd)
{
case KeyerQueueCommand::Run:
keyer.run();
break;
case KeyerQueueCommand::Stop:
keyer.stop();
data.cmd = KeyerQueueCommand::Wait;
break;
case KeyerQueueCommand::Config:
keyer.setSpeed(data.wpm);
keyer.setMode(data.mode);
data.cmd = KeyerQueueCommand::Run;
break;
case KeyerQueueCommand::Wait:
break;
default:
break;
}
}
}
int main()
{
timer_hw->dbgpause = 0; // workaround for problem with debug and sleep_ms
timer_hw->dbgpause = 1; // workaround for problem with debug and sleep_ms
// https://github.com/raspberrypi/pico-sdk/issues/1152#issuecomment-1418248639
setup();
Settings settings{read_settings()};
printf("Hello from core0!\n");
Keyer keyer(settings.wpm, settings.mode);
Settings settings{read_settings()};
settings.wpm = 25; // TODO: remove!
queue_init(&keyerQueue, sizeof(KeyerQueueData), 2);
multicore_reset_core1();
multicore_launch_core1(core1_main);
KeyerQueueData keyerQueueData{KeyerQueueCommand::Run, settings.wpm, settings.mode};
queue_add_blocking(&keyerQueue, &keyerQueueData);
while (true)
{
keyer.run();
// Currently there's nothing to do on core0
sleep_ms(1000);
}
return 0;