mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
Morse special chars and tx duration indication
This commit is contained in:
parent
445503c606
commit
0ba05fea5e
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
//TEST: Imperial in whipcalc
|
//TEST: Imperial in whipcalc
|
||||||
|
|
||||||
//TODO: Morse transmition time estimate
|
//TODO: Morse use prosigns
|
||||||
//TODO: Morse live keying mode ?
|
//TODO: Morse live keying mode ?
|
||||||
/*
|
/*
|
||||||
Keying speed: 60 or 75 PARIS
|
Keying speed: 60 or 75 PARIS
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "hackrf_gpio.hpp"
|
#include "hackrf_gpio.hpp"
|
||||||
#include "portapack_shared_memory.hpp"
|
#include "portapack_shared_memory.hpp"
|
||||||
#include "ui_textentry.hpp"
|
#include "ui_textentry.hpp"
|
||||||
|
#include "string_format.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -53,6 +54,7 @@ MorseView::~MorseView() {
|
|||||||
void MorseView::paint(Painter&) {
|
void MorseView::paint(Painter&) {
|
||||||
message = buffer;
|
message = buffer;
|
||||||
text_message.set(message);
|
text_message.set(message);
|
||||||
|
update_tx_duration();
|
||||||
}
|
}
|
||||||
|
|
||||||
static WORKING_AREA(ookthread_wa, 256);
|
static WORKING_AREA(ookthread_wa, 256);
|
||||||
@ -87,11 +89,9 @@ static msg_t ookthread_fn(void * arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MorseView::start_tx() {
|
bool MorseView::start_tx() {
|
||||||
if (checkbox_foxhunt.value())
|
// Re-generate message, just in case
|
||||||
message = foxhunt_codes[options_foxhunt.selected_index_value()];
|
|
||||||
|
|
||||||
time_unit_ms = field_time_unit.value();
|
time_unit_ms = field_time_unit.value();
|
||||||
symbol_count = morse_encode(message, time_unit_ms, field_tone.value());
|
symbol_count = morse_encode(message, time_unit_ms, field_tone.value(), &time_units);
|
||||||
|
|
||||||
if (!symbol_count) {
|
if (!symbol_count) {
|
||||||
nav_.display_modal("Error", "Message too long.", INFO, nullptr);
|
nav_.display_modal("Error", "Message too long.", INFO, nullptr);
|
||||||
@ -116,6 +116,20 @@ bool MorseView::start_tx() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MorseView::update_tx_duration() {
|
||||||
|
uint32_t duration_ms;
|
||||||
|
|
||||||
|
time_unit_ms = field_time_unit.value();
|
||||||
|
symbol_count = morse_encode(message, time_unit_ms, field_tone.value(), &time_units);
|
||||||
|
|
||||||
|
if (symbol_count) {
|
||||||
|
duration_ms = time_units * time_unit_ms;
|
||||||
|
text_tx_duration.set(to_string_dec_uint(duration_ms / 1000) + "." + to_string_dec_uint((duration_ms / 100) % 10, 1) + "s ");
|
||||||
|
} else {
|
||||||
|
text_tx_duration.set("-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MorseView::on_tx_progress(const int progress, const bool done) {
|
void MorseView::on_tx_progress(const int progress, const bool done) {
|
||||||
if (done) {
|
if (done) {
|
||||||
transmitter_model.disable();
|
transmitter_model.disable();
|
||||||
@ -129,7 +143,6 @@ MorseView::MorseView(
|
|||||||
NavigationView& nav
|
NavigationView& nav
|
||||||
) : nav_ (nav)
|
) : nav_ (nav)
|
||||||
{
|
{
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
@ -139,6 +152,7 @@ MorseView::MorseView(
|
|||||||
&field_time_unit,
|
&field_time_unit,
|
||||||
&field_tone,
|
&field_tone,
|
||||||
&options_modulation,
|
&options_modulation,
|
||||||
|
&text_tx_duration,
|
||||||
&text_message,
|
&text_message,
|
||||||
&button_message,
|
&button_message,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
@ -149,6 +163,24 @@ MorseView::MorseView(
|
|||||||
field_tone.set_value(700); // 700Hz
|
field_tone.set_value(700); // 700Hz
|
||||||
options_modulation.set_selected_index(0); // CW
|
options_modulation.set_selected_index(0); // CW
|
||||||
|
|
||||||
|
checkbox_foxhunt.on_select = [this](Checkbox&, bool v) {
|
||||||
|
if (v) {
|
||||||
|
message = foxhunt_codes[options_foxhunt.selected_index_value()];
|
||||||
|
strncpy(buffer, message.c_str(), sizeof(buffer));
|
||||||
|
text_message.set(message);
|
||||||
|
update_tx_duration();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
options_foxhunt.on_change = [this](size_t, int32_t) {
|
||||||
|
if (checkbox_foxhunt.value())
|
||||||
|
update_tx_duration();
|
||||||
|
};
|
||||||
|
|
||||||
|
field_time_unit.on_change = [this](int32_t) {
|
||||||
|
update_tx_duration();
|
||||||
|
};
|
||||||
|
|
||||||
button_message.on_select = [this, &nav](Button&) {
|
button_message.on_select = [this, &nav](Button&) {
|
||||||
this->on_set_text(nav);
|
this->on_set_text(nav);
|
||||||
};
|
};
|
||||||
@ -169,7 +201,6 @@ MorseView::MorseView(
|
|||||||
chThdTerminate(ookthread);
|
chThdTerminate(ookthread);
|
||||||
tx_view.set_transmitting(false);
|
tx_view.set_transmitting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
@ -63,8 +63,10 @@ private:
|
|||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
char buffer[29] = "PORTAPACK";
|
char buffer[29] = "PORTAPACK";
|
||||||
std::string message { };
|
std::string message { };
|
||||||
|
uint32_t time_units { 0 };
|
||||||
|
|
||||||
bool start_tx();
|
bool start_tx();
|
||||||
|
void update_tx_duration();
|
||||||
void on_set_text(NavigationView& nav);
|
void on_set_text(NavigationView& nav);
|
||||||
|
|
||||||
size_t modulation { 0 };
|
size_t modulation { 0 };
|
||||||
@ -74,6 +76,7 @@ private:
|
|||||||
{ { 4 * 8, 6 * 8 }, "Time unit: ms", Color::light_grey() },
|
{ { 4 * 8, 6 * 8 }, "Time unit: ms", Color::light_grey() },
|
||||||
{ { 4 * 8, 8 * 8 }, "Tone: Hz", Color::light_grey() },
|
{ { 4 * 8, 8 * 8 }, "Tone: Hz", Color::light_grey() },
|
||||||
{ { 4 * 8, 10 * 8 }, "Modulation:", Color::light_grey() },
|
{ { 4 * 8, 10 * 8 }, "Modulation:", Color::light_grey() },
|
||||||
|
{ { 1 * 8, 14 * 8 }, "TX will last", Color::light_grey() }
|
||||||
};
|
};
|
||||||
|
|
||||||
Checkbox checkbox_foxhunt {
|
Checkbox checkbox_foxhunt {
|
||||||
@ -124,18 +127,23 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Text text_tx_duration {
|
||||||
|
{ 14 * 8, 14 * 8, 4 * 8, 16 },
|
||||||
|
"-"
|
||||||
|
};
|
||||||
|
|
||||||
Text text_message {
|
Text text_message {
|
||||||
{ 1 * 8, 14 * 8, 28 * 8, 16 },
|
{ 1 * 8, 18 * 8, 28 * 8, 16 },
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
Button button_message {
|
Button button_message {
|
||||||
{ 1 * 8, 16 * 8, 12 * 8, 28 },
|
{ 1 * 8, 20 * 8, 12 * 8, 28 },
|
||||||
"Set message"
|
"Set message"
|
||||||
};
|
};
|
||||||
|
|
||||||
ProgressBar progressbar {
|
ProgressBar progressbar {
|
||||||
{ 2 * 8, 14 * 16, 208, 16 }
|
{ 2 * 8, 28 * 8, 208, 16 }
|
||||||
};
|
};
|
||||||
|
|
||||||
TransmitterView tx_view {
|
TransmitterView tx_view {
|
||||||
|
@ -31,43 +31,48 @@ using namespace portapack;
|
|||||||
namespace morse {
|
namespace morse {
|
||||||
|
|
||||||
// Returns 0 if message is too long
|
// Returns 0 if message is too long
|
||||||
size_t morse_encode(std::string& message, const uint32_t time_unit_ms, const uint32_t tone) {
|
size_t morse_encode(std::string& message, const uint32_t time_unit_ms,
|
||||||
|
const uint32_t tone, uint32_t * const time_units) {
|
||||||
|
|
||||||
size_t i, c;
|
size_t i, c;
|
||||||
uint8_t code, code_size;
|
uint16_t code, code_size;
|
||||||
uint8_t morse_message[256];
|
uint8_t morse_message[256];
|
||||||
|
|
||||||
|
*time_units = 0;
|
||||||
|
|
||||||
ToneDef * tone_defs = shared_memory.bb_data.tones_data.tone_defs;
|
ToneDef * tone_defs = shared_memory.bb_data.tones_data.tone_defs;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (char& ch : message) {
|
for (char& ch : message) {
|
||||||
if ((ch >= 'a') && (ch <= 'z')) // Make uppercase
|
if (i > 256) return 0;
|
||||||
|
|
||||||
|
if ((ch >= 'a') && (ch <= 'z')) // Make uppercase
|
||||||
ch -= 32;
|
ch -= 32;
|
||||||
|
|
||||||
if ((ch >= 'A') && (ch <= 'Z')) {
|
if ((ch >= '!') && (ch <= '_')) {
|
||||||
code = morse_ITU[ch - 'A' + 10];
|
code = morse_ITU[ch - '!'];
|
||||||
} else if ((ch >= '0') && (ch <= '9')) {
|
} else {
|
||||||
code = morse_ITU[ch - '0'];
|
code = 0; // Default to space char
|
||||||
} else {
|
|
||||||
ch = ' '; // Default to space char
|
|
||||||
code = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == ' ') {
|
if (!code) {
|
||||||
if (i)
|
if (i)
|
||||||
morse_message[i - 1] = 4; // Word space
|
morse_message[i - 1] = 4; // Word space
|
||||||
} else {
|
} else {
|
||||||
code_size = code & 7;
|
code_size = code & 7;
|
||||||
|
|
||||||
for (c = 0; c < code_size; c++) {
|
for (c = 0; c < code_size; c++) {
|
||||||
morse_message[i++] = ((code << c) & 0x80) ? 1 : 0; // Dot/dash
|
morse_message[i++] = ((code << c) & 0x8000) ? 1 : 0; // Dot/dash
|
||||||
morse_message[i++] = 2; // Symbol space
|
morse_message[i++] = 2; // Symbol space
|
||||||
}
|
}
|
||||||
morse_message[i - 1] = 3; // Letter space
|
morse_message[i - 1] = 3; // Letter space
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i > 256) return 0;
|
// Count time units
|
||||||
|
for (c = 0; c < i; c++) {
|
||||||
|
*time_units += morse_symbols[morse_message[c]];
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(shared_memory.bb_data.tones_data.message, morse_message, i);
|
memcpy(shared_memory.bb_data.tones_data.message, morse_message, i);
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "tonesets.hpp"
|
#include "tonesets.hpp"
|
||||||
#include "portapack_shared_memory.hpp"
|
#include "portapack_shared_memory.hpp"
|
||||||
|
|
||||||
//#define MORSE_UNIT (MORSE_SAMPLE_RATE * 0.05) // 1536000*0.05 (50ms)
|
|
||||||
#define MORSE_DOT 1
|
#define MORSE_DOT 1
|
||||||
#define MORSE_DASH 3
|
#define MORSE_DASH 3
|
||||||
#define MORSE_SYMBOL_SPACE 1
|
#define MORSE_SYMBOL_SPACE 1
|
||||||
@ -43,7 +42,8 @@ const uint32_t morse_symbols[5] = {
|
|||||||
MORSE_WORD_SPACE
|
MORSE_WORD_SPACE
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t morse_encode(std::string& message, const uint32_t time_unit_ms, const uint32_t tone);
|
size_t morse_encode(std::string& message, const uint32_t time_unit_ms,
|
||||||
|
const uint32_t tone, uint32_t * const time_units);
|
||||||
|
|
||||||
const std::string foxhunt_codes[11] = {
|
const std::string foxhunt_codes[11] = {
|
||||||
{ "MOE" }, // -----.
|
{ "MOE" }, // -----.
|
||||||
@ -60,48 +60,8 @@ const std::string foxhunt_codes[11] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 0=dot 1=dash
|
// 0=dot 1=dash
|
||||||
const uint8_t morse_ITU[36] = {
|
const uint16_t morse_ITU[63] = {
|
||||||
// Code Size
|
// Code Size
|
||||||
0b11111101, // 0: 11111 101
|
|
||||||
0b01111101, // 1: 01111 101
|
|
||||||
0b00111101, // 2: 00111 101
|
|
||||||
0b00011101, // 3: 00011 101
|
|
||||||
0b00001101, // 4: 00001 101
|
|
||||||
0b00000101, // 5: 00000 101
|
|
||||||
0b10000101, // 6: 10000 101
|
|
||||||
0b11000101, // 7: 11000 101
|
|
||||||
0b11100101, // 8: 11100 101
|
|
||||||
0b11110101, // 9: 11110 101
|
|
||||||
0b01000010, // A: 01--- 010
|
|
||||||
0b10000100, // B: 1000- 100
|
|
||||||
0b10100100, // C: 1010- 100
|
|
||||||
0b10000011, // D: 100-- 011
|
|
||||||
0b00000001, // E: 0---- 001
|
|
||||||
0b00100100, // F: 0010- 100
|
|
||||||
0b11000011, // G: 110-- 011
|
|
||||||
0b00000100, // H: 0000- 100
|
|
||||||
0b00000010, // I: 00--- 010
|
|
||||||
0b01110100, // J: 0111- 100
|
|
||||||
0b10100011, // K: 101-- 011
|
|
||||||
0b01000100, // L: 0100- 100
|
|
||||||
0b11000010, // M: 11--- 010
|
|
||||||
0b10000010, // N: 10--- 010
|
|
||||||
0b11100011, // O: 111-- 011
|
|
||||||
0b01100100, // P: 0110- 100 .#-###-###.# ##.#-### ##.#-###.# ##.#.# ##.#.#.# = 48 units
|
|
||||||
0b11010100, // Q: 1101- 100 60s: 1.25s/unit
|
|
||||||
0b01000011, // R: 010-- 011 75s: 1.5625s/unit
|
|
||||||
0b00000011, // S: 000-- 011
|
|
||||||
0b10000001, // T: 1---- 001
|
|
||||||
0b00100011, // U: 001-- 011
|
|
||||||
0b00010100, // V: 0001- 100
|
|
||||||
0b01100011, // W: 011-- 011
|
|
||||||
0b10010100, // X: 1001- 100
|
|
||||||
0b10110100, // Y: 1011- 100
|
|
||||||
0b11000100 // Z: 1100- 100
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint16_t morse_special[23] = {
|
|
||||||
// Code Size
|
|
||||||
0b1010110000000110, // !: 101011- 110
|
0b1010110000000110, // !: 101011- 110
|
||||||
0b0100100000000110, // ": 010010- 110
|
0b0100100000000110, // ": 010010- 110
|
||||||
0, // #
|
0, // #
|
||||||
@ -117,7 +77,16 @@ const uint16_t morse_special[23] = {
|
|||||||
0b1000010000000110, // -: 100001- 110
|
0b1000010000000110, // -: 100001- 110
|
||||||
0b0101010000000110, // .: 010101- 110
|
0b0101010000000110, // .: 010101- 110
|
||||||
0b1001000000000101, // /: 10010-- 101
|
0b1001000000000101, // /: 10010-- 101
|
||||||
|
0b1111100000000101, // 0: 11111-- 101
|
||||||
|
0b0111100000000101, // 1: 01111-- 101
|
||||||
|
0b0011100000000101, // 2: 00111-- 101
|
||||||
|
0b0001100000000101, // 3: 00011-- 101
|
||||||
|
0b0000100000000101, // 4: 00001-- 101
|
||||||
|
0b0000000000000101, // 5: 00000-- 101
|
||||||
|
0b1000000000000101, // 6: 10000-- 101
|
||||||
|
0b1100000000000101, // 7: 11000-- 101
|
||||||
|
0b1110000000000101, // 8: 11100-- 101
|
||||||
|
0b1111000000000101, // 9: 11110-- 101
|
||||||
0b1110000000000110, // :: 111000- 110
|
0b1110000000000110, // :: 111000- 110
|
||||||
0b1010100000000110, // ;: 101010- 110
|
0b1010100000000110, // ;: 101010- 110
|
||||||
0, // <
|
0, // <
|
||||||
@ -125,7 +94,36 @@ const uint16_t morse_special[23] = {
|
|||||||
0, // >
|
0, // >
|
||||||
0b0011000000000110, // ?: 001100- 110
|
0b0011000000000110, // ?: 001100- 110
|
||||||
0b0110100000000110, // @: 011010- 110
|
0b0110100000000110, // @: 011010- 110
|
||||||
|
0b0100000000000010, // A: 01----- 010
|
||||||
|
0b1000000000000100, // B: 1000--- 100
|
||||||
|
0b1010000000000100, // C: 1010--- 100
|
||||||
|
0b1000000000000011, // D: 100---- 011
|
||||||
|
0b0000000000000001, // E: 0------ 001
|
||||||
|
0b0010000000000100, // F: 0010--- 100
|
||||||
|
0b1100000000000011, // G: 110---- 011
|
||||||
|
0b0000000000000100, // H: 0000--- 100
|
||||||
|
0b0000000000000010, // I: 00----- 010
|
||||||
|
0b0111000000000100, // J: 0111--- 100
|
||||||
|
0b1010000000000011, // K: 101---- 011
|
||||||
|
0b0100000000000100, // L: 0100--- 100
|
||||||
|
0b1100000000000010, // M: 11----- 010
|
||||||
|
0b1000000000000010, // N: 10----- 010
|
||||||
|
0b1110000000000011, // O: 111---- 011
|
||||||
|
0b0110000000000100, // P: 0110--- 100 .#-###-###.# ##.#-### ##.#-###.# ##.#.# ##.#.#.# = 48 units
|
||||||
|
0b1101000000000100, // Q: 1101--- 100
|
||||||
|
0b0100000000000011, // R: 010---- 011
|
||||||
|
0b0000000000000011, // S: 000---- 011
|
||||||
|
0b1000000000000001, // T: 1------ 001
|
||||||
|
0b0010000000000011, // U: 001---- 011
|
||||||
|
0b0001000000000100, // V: 0001--- 100
|
||||||
|
0b0110000000000011, // W: 011---- 011
|
||||||
|
0b1001000000000100, // X: 1001--- 100
|
||||||
|
0b1011000000000100, // Y: 1011--- 100
|
||||||
|
0b1100000000000100, // Z: 1100--- 100
|
||||||
|
0, // [
|
||||||
|
0, // Back-slash
|
||||||
|
0, // ]
|
||||||
|
0, // ^
|
||||||
0b0011010000000110 // _: 001101- 110
|
0b0011010000000110 // _: 001101- 110
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user