Morse special chars and tx duration indication

This commit is contained in:
furrtek 2017-02-15 04:27:51 +00:00
parent 445503c606
commit 0ba05fea5e
7 changed files with 115 additions and 73 deletions

View File

@ -29,7 +29,7 @@
//TEST: Imperial in whipcalc
//TODO: Morse transmition time estimate
//TODO: Morse use prosigns
//TODO: Morse live keying mode ?
/*
Keying speed: 60 or 75 PARIS

View File

@ -27,6 +27,7 @@
#include "hackrf_gpio.hpp"
#include "portapack_shared_memory.hpp"
#include "ui_textentry.hpp"
#include "string_format.hpp"
#include <cstring>
#include <stdio.h>
@ -53,6 +54,7 @@ MorseView::~MorseView() {
void MorseView::paint(Painter&) {
message = buffer;
text_message.set(message);
update_tx_duration();
}
static WORKING_AREA(ookthread_wa, 256);
@ -87,11 +89,9 @@ static msg_t ookthread_fn(void * arg) {
}
bool MorseView::start_tx() {
if (checkbox_foxhunt.value())
message = foxhunt_codes[options_foxhunt.selected_index_value()];
// Re-generate message, just in case
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) {
nav_.display_modal("Error", "Message too long.", INFO, nullptr);
@ -116,6 +116,20 @@ bool MorseView::start_tx() {
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) {
if (done) {
transmitter_model.disable();
@ -129,7 +143,6 @@ MorseView::MorseView(
NavigationView& nav
) : nav_ (nav)
{
baseband::run_image(portapack::spi_flash::image_tag_tones);
add_children({
@ -139,6 +152,7 @@ MorseView::MorseView(
&field_time_unit,
&field_tone,
&options_modulation,
&text_tx_duration,
&text_message,
&button_message,
&progressbar,
@ -149,6 +163,24 @@ MorseView::MorseView(
field_tone.set_value(700); // 700Hz
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&) {
this->on_set_text(nav);
};
@ -169,7 +201,6 @@ MorseView::MorseView(
chThdTerminate(ookthread);
tx_view.set_transmitting(false);
};
}
} /* namespace ui */

View File

@ -63,8 +63,10 @@ private:
NavigationView& nav_;
char buffer[29] = "PORTAPACK";
std::string message { };
uint32_t time_units { 0 };
bool start_tx();
void update_tx_duration();
void on_set_text(NavigationView& nav);
size_t modulation { 0 };
@ -74,6 +76,7 @@ private:
{ { 4 * 8, 6 * 8 }, "Time unit: ms", Color::light_grey() },
{ { 4 * 8, 8 * 8 }, "Tone: Hz", Color::light_grey() },
{ { 4 * 8, 10 * 8 }, "Modulation:", Color::light_grey() },
{ { 1 * 8, 14 * 8 }, "TX will last", Color::light_grey() }
};
Checkbox checkbox_foxhunt {
@ -124,18 +127,23 @@ private:
}
};
Text text_tx_duration {
{ 14 * 8, 14 * 8, 4 * 8, 16 },
"-"
};
Text text_message {
{ 1 * 8, 14 * 8, 28 * 8, 16 },
{ 1 * 8, 18 * 8, 28 * 8, 16 },
""
};
Button button_message {
{ 1 * 8, 16 * 8, 12 * 8, 28 },
{ 1 * 8, 20 * 8, 12 * 8, 28 },
"Set message"
};
ProgressBar progressbar {
{ 2 * 8, 14 * 16, 208, 16 }
{ 2 * 8, 28 * 8, 208, 16 }
};
TransmitterView tx_view {

View File

@ -31,43 +31,48 @@ using namespace portapack;
namespace morse {
// 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;
uint8_t code, code_size;
uint16_t code, code_size;
uint8_t morse_message[256];
*time_units = 0;
ToneDef * tone_defs = shared_memory.bb_data.tones_data.tone_defs;
i = 0;
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;
if ((ch >= 'A') && (ch <= 'Z')) {
code = morse_ITU[ch - 'A' + 10];
} else if ((ch >= '0') && (ch <= '9')) {
code = morse_ITU[ch - '0'];
} else {
ch = ' '; // Default to space char
code = 0;
if ((ch >= '!') && (ch <= '_')) {
code = morse_ITU[ch - '!'];
} else {
code = 0; // Default to space char
}
if (ch == ' ') {
if (!code) {
if (i)
morse_message[i - 1] = 4; // Word space
morse_message[i - 1] = 4; // Word space
} else {
code_size = code & 7;
for (c = 0; c < code_size; c++) {
morse_message[i++] = ((code << c) & 0x80) ? 1 : 0; // Dot/dash
morse_message[i++] = 2; // Symbol space
morse_message[i++] = ((code << c) & 0x8000) ? 1 : 0; // Dot/dash
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);

View File

@ -26,7 +26,6 @@
#include "tonesets.hpp"
#include "portapack_shared_memory.hpp"
//#define MORSE_UNIT (MORSE_SAMPLE_RATE * 0.05) // 1536000*0.05 (50ms)
#define MORSE_DOT 1
#define MORSE_DASH 3
#define MORSE_SYMBOL_SPACE 1
@ -43,7 +42,8 @@ const uint32_t morse_symbols[5] = {
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] = {
{ "MOE" }, // -----.
@ -60,48 +60,8 @@ const std::string foxhunt_codes[11] = {
};
// 0=dot 1=dash
const uint8_t morse_ITU[36] = {
// 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
const uint16_t morse_ITU[63] = {
// Code Size
0b1010110000000110, // !: 101011- 110
0b0100100000000110, // ": 010010- 110
0, // #
@ -117,7 +77,16 @@ const uint16_t morse_special[23] = {
0b1000010000000110, // -: 100001- 110
0b0101010000000110, // .: 010101- 110
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
0b1010100000000110, // ;: 101010- 110
0, // <
@ -125,7 +94,36 @@ const uint16_t morse_special[23] = {
0, // >
0b0011000000000110, // ?: 001100- 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
};

Binary file not shown.

Binary file not shown.