refacturing compiles

This commit is contained in:
Martin Brodbeck 2024-02-27 12:56:32 +01:00
parent 6f51f5e962
commit e4bc705f04
6 changed files with 149 additions and 110 deletions

View file

@ -17,5 +17,7 @@ target_sources(raspi_keyer PRIVATE
keyer.cpp keyer.cpp
sidetone.cpp sidetone.cpp
morse.cpp morse.cpp
winkeyer.cpp
utils.cpp
usb_descriptors.c usb_descriptors.c
) )

View file

@ -12,11 +12,8 @@
#include "settings.h" #include "settings.h"
#include <config.h> #include <config.h>
#include "tusb_config.h" #include "tusb_config.h"
#include "utils.h"
namespace #include "winkeyer.h"
{
}
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;
@ -26,21 +23,6 @@ extern const uint CW_OUT_PIN = 17;
// extern const uint AUDIO_OUT_PIN = 16; // extern const uint AUDIO_OUT_PIN = 16;
extern const uint ADC_PIN = 26; 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; queue_t keyerQueue;
void setup() void setup()
@ -65,6 +47,10 @@ void setup()
adc_init(); adc_init();
gpio_init(ADC_PIN); gpio_init(ADC_PIN);
adc_select_input(0); 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. */ /* Let's do all the keying stuff in the second core, so there are no timing problems. */
@ -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() int main()
{ {
timer_hw->dbgpause = 0; // 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 // https://github.com/raspberrypi/pico-sdk/issues/1152#issuecomment-1418248639
setup(); setup();
board_init();
tud_init(BOARD_TUD_RHPORT);
printf("RaspiKeyer Version %s\n", PROJECT_VERSION); printf("RaspiKeyer Version %s\n", PROJECT_VERSION);
@ -222,6 +120,8 @@ int main()
KeyerQueueData keyerQueueData {KeyerQueueCommand::Run, currentWpm, settings.mode, 0}; KeyerQueueData keyerQueueData {KeyerQueueCommand::Run, currentWpm, settings.mode, 0};
queue_add_blocking(&keyerQueue, &keyerQueueData); queue_add_blocking(&keyerQueue, &keyerQueueData);
WinKeyer winKeyer;
while (true) { while (true) {
currentWpm = calcWPM(potiRead(), settings.wpmPotiMin, settings.wpmPotiMax); currentWpm = calcWPM(potiRead(), settings.wpmPotiMin, settings.wpmPotiMax);
@ -233,8 +133,9 @@ int main()
lastWpm = currentWpm; lastWpm = currentWpm;
} }
tud_task(); tud_task(); // Internal PICO purposes
cdc_task();
winKeyer.run(keyerQueue);
} }
return 0; return 0;

38
src/utils.cpp Normal file
View 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
View 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
View 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
View file

@ -0,0 +1,11 @@
#pragma once
#include "pico/util/queue.h"
class WinKeyer final
{
public:
void run(queue_t &queue);
private:
};