Compare commits
2 commits
6f51f5e962
...
d147059531
Author | SHA1 | Date | |
---|---|---|---|
d147059531 | |||
e4bc705f04 |
6 changed files with 150 additions and 111 deletions
|
@ -17,5 +17,7 @@ target_sources(raspi_keyer PRIVATE
|
|||
keyer.cpp
|
||||
sidetone.cpp
|
||||
morse.cpp
|
||||
winkeyer.cpp
|
||||
utils.cpp
|
||||
usb_descriptors.c
|
||||
)
|
||||
|
|
|
@ -12,11 +12,8 @@
|
|||
#include "settings.h"
|
||||
#include <config.h>
|
||||
#include "tusb_config.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
}
|
||||
#include "utils.h"
|
||||
#include "winkeyer.h"
|
||||
|
||||
extern const uint LED_PIN = PICO_DEFAULT_LED_PIN;
|
||||
extern const uint LEFT_PADDLE_PIN = 14;
|
||||
|
@ -26,21 +23,6 @@ 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 {
|
||||
Run,
|
||||
Stop,
|
||||
Config,
|
||||
Wait,
|
||||
SendMessage,
|
||||
};
|
||||
struct KeyerQueueData {
|
||||
KeyerQueueCommand cmd;
|
||||
uint8_t wpm;
|
||||
Mode mode;
|
||||
char message;
|
||||
};
|
||||
|
||||
queue_t keyerQueue;
|
||||
|
||||
void setup()
|
||||
|
@ -65,13 +47,17 @@ void setup()
|
|||
adc_init();
|
||||
gpio_init(ADC_PIN);
|
||||
adc_select_input(0);
|
||||
|
||||
// Setup USB
|
||||
board_init();
|
||||
tud_init(BOARD_TUD_RHPORT);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
|
@ -105,100 +91,12 @@ void core1_main()
|
|||
}
|
||||
}
|
||||
|
||||
static void usbSend(uint8_t itf, uint8_t buf[], uint32_t count)
|
||||
{
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
tud_cdc_n_write_char(itf, buf[i]);
|
||||
}
|
||||
|
||||
tud_cdc_n_write_flush(itf);
|
||||
}
|
||||
|
||||
static void usbSend(uint8_t itf, uint8_t value)
|
||||
{
|
||||
tud_cdc_n_write_char(itf, value);
|
||||
tud_cdc_n_write_flush(itf);
|
||||
}
|
||||
|
||||
void cdc_task()
|
||||
{
|
||||
const uint8_t USB_IF = 0;
|
||||
|
||||
if (tud_cdc_n_available(USB_IF)) {
|
||||
uint8_t buf[64];
|
||||
|
||||
//printf("AHA!!! %d\n", (int)tud_cdc_n_available(USB_IF));
|
||||
uint32_t count = tud_cdc_n_read(USB_IF, buf, sizeof(buf));
|
||||
|
||||
if (count > 0) {
|
||||
switch (buf[0]) {
|
||||
case 'a' ... 'z':
|
||||
[[fallthrough]];
|
||||
case 'A' ... 'Z':
|
||||
[[fallthrough]];
|
||||
case '0' ... '9':
|
||||
[[fallthrough]];
|
||||
case ' ':
|
||||
[[fallthrough]];
|
||||
case '+':
|
||||
[[fallthrough]];
|
||||
case '=':
|
||||
[[fallthrough]];
|
||||
case '?':
|
||||
[[fallthrough]];
|
||||
case ',':
|
||||
[[fallthrough]];
|
||||
case '.':
|
||||
{
|
||||
KeyerQueueData keyerQueueData {KeyerQueueCommand::SendMessage, 0, Mode::IambicB, buf[0]};
|
||||
queue_add_blocking(&keyerQueue, &keyerQueueData);
|
||||
break;
|
||||
}
|
||||
case 0x00: // ADMIN COMMAND
|
||||
switch (buf[1]) {
|
||||
case 0x02: // HOST OPEN
|
||||
usbSend(USB_IF, 9); // Send WK1 (v9) for now (no WinKeyer PTT control)
|
||||
break;
|
||||
case 0x04: // ECHO TEST
|
||||
usbSend(USB_IF, &buf[2], 1); // Send the received byte back
|
||||
break;
|
||||
default:
|
||||
printf("Unknown admin command: %x\n", buf[1]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("Unknown command: %d.\n", buf[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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<uint8_t>(std::round(wpm));
|
||||
return result;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
timer_hw->dbgpause = 0; // workaround for problem with debug and sleep_ms
|
||||
// https://github.com/raspberrypi/pico-sdk/issues/1152#issuecomment-1418248639
|
||||
|
||||
setup();
|
||||
board_init();
|
||||
tud_init(BOARD_TUD_RHPORT);
|
||||
|
||||
printf("RaspiKeyer Version %s\n", PROJECT_VERSION);
|
||||
|
||||
|
@ -222,6 +120,8 @@ int main()
|
|||
KeyerQueueData keyerQueueData {KeyerQueueCommand::Run, currentWpm, settings.mode, 0};
|
||||
queue_add_blocking(&keyerQueue, &keyerQueueData);
|
||||
|
||||
WinKeyer winKeyer;
|
||||
|
||||
while (true) {
|
||||
currentWpm = calcWPM(potiRead(), settings.wpmPotiMin, settings.wpmPotiMax);
|
||||
|
||||
|
@ -233,8 +133,9 @@ int main()
|
|||
lastWpm = currentWpm;
|
||||
}
|
||||
|
||||
tud_task();
|
||||
cdc_task();
|
||||
tud_task(); // Internal PICO purposes
|
||||
|
||||
winKeyer.run(keyerQueue);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
38
src/utils.cpp
Normal file
38
src/utils.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <cmath>
|
||||
|
||||
#include "hardware/adc.h"
|
||||
#include "pico/stdlib.h"
|
||||
#include "tusb.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
uint8_t calcWPM(float percent, uint8_t wpmMin, uint8_t wpmMax)
|
||||
{
|
||||
auto wpm = (percent * (wpmMax - wpmMin) / 100) + wpmMin;
|
||||
uint8_t result = static_cast<uint8_t>(std::round(wpm));
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void usbSend(uint8_t itf, uint8_t buf[], uint32_t count)
|
||||
{
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
tud_cdc_n_write_char(itf, buf[i]);
|
||||
}
|
||||
|
||||
tud_cdc_n_write_flush(itf);
|
||||
}
|
||||
|
||||
void usbSend(uint8_t itf, uint8_t value)
|
||||
{
|
||||
tud_cdc_n_write_char(itf, value);
|
||||
tud_cdc_n_write_flush(itf);
|
||||
}
|
29
src/utils.h
Normal file
29
src/utils.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
// Stuff for communicating between cores
|
||||
enum class KeyerQueueCommand {
|
||||
Run,
|
||||
Stop,
|
||||
Config,
|
||||
Wait,
|
||||
SendMessage,
|
||||
};
|
||||
|
||||
struct KeyerQueueData {
|
||||
KeyerQueueCommand cmd;
|
||||
uint8_t wpm;
|
||||
Mode mode;
|
||||
uint8_t message;
|
||||
};
|
||||
|
||||
/* Calculates the WPM speed from the volt percentage */
|
||||
uint8_t calcWPM(float percent, uint8_t wpmMin, uint8_t wpmMax);
|
||||
|
||||
/* Returns the voltage level in percent (3,3V == 100%) */
|
||||
float potiRead();
|
||||
|
||||
// Sending bytes over USB
|
||||
void usbSend(uint8_t itf, uint8_t buf[], uint32_t count);
|
||||
void usbSend(uint8_t itf, uint8_t value);
|
58
src/winkeyer.cpp
Normal file
58
src/winkeyer.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "pico/stdlib.h"
|
||||
#include "tusb.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "winkeyer.h"
|
||||
|
||||
void WinKeyer::run(queue_t &queue)
|
||||
{
|
||||
const uint8_t USB_IF = 0;
|
||||
|
||||
if (tud_cdc_n_available(USB_IF)) {
|
||||
uint8_t buf[64];
|
||||
|
||||
// printf("AHA!!! %d\n", (int)tud_cdc_n_available(USB_IF));
|
||||
uint32_t count = tud_cdc_n_read(USB_IF, buf, sizeof(buf));
|
||||
|
||||
if (count > 0) {
|
||||
switch (buf[0]) {
|
||||
case 'a' ... 'z':
|
||||
[[fallthrough]];
|
||||
case 'A' ... 'Z':
|
||||
[[fallthrough]];
|
||||
case '0' ... '9':
|
||||
[[fallthrough]];
|
||||
case ' ':
|
||||
[[fallthrough]];
|
||||
case '+':
|
||||
[[fallthrough]];
|
||||
case '=':
|
||||
[[fallthrough]];
|
||||
case '?':
|
||||
[[fallthrough]];
|
||||
case ',':
|
||||
[[fallthrough]];
|
||||
case '.': {
|
||||
KeyerQueueData keyerQueueData {KeyerQueueCommand::SendMessage, 0, Mode::IambicB, buf[0]};
|
||||
queue_add_blocking(&queue, &keyerQueueData);
|
||||
break;
|
||||
}
|
||||
case 0x00: // ADMIN COMMAND
|
||||
switch (buf[1]) {
|
||||
case 0x02: // HOST OPEN
|
||||
usbSend(USB_IF, 9); // Send WK1 (v9) for now (no WinKeyer PTT control)
|
||||
break;
|
||||
case 0x04: // ECHO TEST
|
||||
usbSend(USB_IF, &buf[2], 1); // Send the received byte back
|
||||
break;
|
||||
default:
|
||||
printf("Unknown admin command: %x\n", buf[1]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("Unknown command: %d.\n", buf[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
src/winkeyer.h
Normal file
11
src/winkeyer.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "pico/util/queue.h"
|
||||
|
||||
class WinKeyer final
|
||||
{
|
||||
public:
|
||||
void run(queue_t &queue);
|
||||
|
||||
private:
|
||||
};
|
Loading…
Reference in a new issue