Merge branch 'multicore'
This commit is contained in:
commit
20dc5c8a03
4 changed files with 120 additions and 13 deletions
|
@ -32,7 +32,7 @@ pico_set_program_name(raspi_keyer "raspi_keyer")
|
||||||
pico_set_program_version(raspi_keyer "0.0.1")
|
pico_set_program_version(raspi_keyer "0.0.1")
|
||||||
|
|
||||||
pico_enable_stdio_uart(raspi_keyer 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)
|
target_compile_options(raspi_keyer PRIVATE -Wall -Wextra -Werror)
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ target_link_libraries(raspi_keyer
|
||||||
hardware_exception
|
hardware_exception
|
||||||
hardware_pwm
|
hardware_pwm
|
||||||
pico_flash
|
pico_flash
|
||||||
|
pico_multicore
|
||||||
)
|
)
|
||||||
|
|
||||||
pico_add_extra_outputs(raspi_keyer)
|
pico_add_extra_outputs(raspi_keyer)
|
||||||
|
|
|
@ -141,16 +141,56 @@ void Keyer::run()
|
||||||
m_pausing_until = make_timeout_time_us(m_elementDuration);
|
m_pausing_until = make_timeout_time_us(m_elementDuration);
|
||||||
m_currentlyPausing = true;
|
m_currentlyPausing = true;
|
||||||
}
|
}
|
||||||
|
// Handle the case when the other paddle is pressed during the inter character space
|
||||||
if (absolute_time_diff_us(timestamp, m_pausing_until) <= 0)
|
else if (absolute_time_diff_us(timestamp, m_pausing_until) > 0)
|
||||||
{
|
{
|
||||||
m_currentlyPausing = false;
|
if (left_paddle_pressed() && m_previousState == State::Dah && m_nextState == State::Wait)
|
||||||
state = 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;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Keyer::stop()
|
||||||
|
{
|
||||||
|
state = State::Abort;
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ public:
|
||||||
Dit,
|
Dit,
|
||||||
Dah,
|
Dah,
|
||||||
InterCharSpace,
|
InterCharSpace,
|
||||||
|
Abort,
|
||||||
};
|
};
|
||||||
Keyer() = delete;
|
Keyer() = delete;
|
||||||
Keyer(uint8_t wpm, Mode mode);
|
Keyer(uint8_t wpm, Mode mode);
|
||||||
|
@ -23,10 +24,12 @@ public:
|
||||||
void setSpeed(uint8_t wpm);
|
void setSpeed(uint8_t wpm);
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
void stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
State state{State::Wait};
|
State state{State::Wait};
|
||||||
State m_previousState{State::Wait};
|
State m_previousState{State::Wait};
|
||||||
|
State m_nextState{State::Wait};
|
||||||
uint8_t m_wpm{18};
|
uint8_t m_wpm{18};
|
||||||
Mode m_mode{Mode::IAMBIC_B};
|
Mode m_mode{Mode::IAMBIC_B};
|
||||||
uint64_t m_elementDuration{0};
|
uint64_t m_elementDuration{0};
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/multicore.h"
|
||||||
|
#include "pico/util/queue.h"
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "keyer.h"
|
#include "keyer.h"
|
||||||
|
@ -13,7 +15,24 @@ 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;
|
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()
|
void setup()
|
||||||
{
|
{
|
||||||
|
@ -30,23 +49,67 @@ void setup()
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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()
|
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
|
// https://github.com/raspberrypi/pico-sdk/issues/1152#issuecomment-1418248639
|
||||||
|
|
||||||
setup();
|
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)
|
while (true)
|
||||||
{
|
{
|
||||||
keyer.run();
|
// Currently there's nothing to do on core0
|
||||||
|
sleep_ms(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue