diff --git a/.gitignore b/.gitignore index 489b779b..0ed41f35 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/firmware/baseband/baseband_dtmf_tx.img /firmware/baseband/baseband.img /firmware/baseband/baseband_afsk.img /firmware/baseband/baseband_ais.img diff --git a/firmware/application/ui_nuoptix.cpp b/firmware/application/ui_nuoptix.cpp index e2aa27f4..11849f29 100644 --- a/firmware/application/ui_nuoptix.cpp +++ b/firmware/application/ui_nuoptix.cpp @@ -24,7 +24,7 @@ #include "ch.h" -//#include "lfsr_random.hpp" +#include "lfsr_random.hpp" #include "ui_alphanum.hpp" #include "portapack.hpp" #include "string_format.hpp" @@ -50,15 +50,21 @@ void NuoptixView::transmit(bool setup) { uint8_t mod; uint8_t c; - if (!txing) { + if (!tx_mode) { transmitter_model.disable(); return; } + if (tx_mode == IMPROVISE) + timecode = lfsr_iterate(timecode) % 1999; // Should be 9999 but that would be one long audio track ! + if (setup) { pbar.set_max(4); - timecode = number_timecode.value(); + if (tx_mode == NORMAL) + timecode = number_timecode.value(); + else + timecode = 0125; transmitter_model.set_baseband_configuration({ .mode = 0, @@ -82,7 +88,6 @@ void NuoptixView::transmit(bool setup) { pbar.set_value(0); - //strcpy("#00028", shared_memory.tx_data); shared_memory.tx_data[2] = (timecode / 100) % 10; shared_memory.tx_data[3] = (timecode / 10) % 10; shared_memory.tx_data[4] = timecode % 10; @@ -98,9 +103,9 @@ void NuoptixView::transmit(bool setup) { shared_memory.tx_data[5] = mod; - shared_memory.tx_data[6] = 0xFF; + shared_memory.tx_data[6] = 0xFF; // End of message - baseband::set_dtmf_data(number_bw.value(), 49, 49); // 49ms tone, 49ms space + baseband::set_dtmf_data(number_bw.value(), 49, 49); // 49ms tone, 49ms space timecode++; } @@ -109,7 +114,6 @@ NuoptixView::NuoptixView( NavigationView& nav ) { - baseband::run_image(portapack::spi_flash::image_tag_dtmf_tx); add_children({ { @@ -121,6 +125,7 @@ NuoptixView::NuoptixView( &text_mod, &pbar, &button_tx, + &button_impro, &button_exit } }); @@ -143,10 +148,23 @@ NuoptixView::NuoptixView( }; button_tx.on_select = [this](Button&){ - if (txing) { - txing = false; - } else { - txing = true; + if (tx_mode == NORMAL) { + tx_mode = IDLE; + button_tx.set_text("TX"); + } else if (tx_mode == IDLE) { + tx_mode = NORMAL; + button_tx.set_text("STOP"); + transmit(true); + } + }; + + button_impro.on_select = [this](Button&){ + if (tx_mode == IMPROVISE) { + tx_mode = IDLE; + button_impro.set_text("IMPROVISE"); + } else if (tx_mode == IDLE) { + tx_mode = IMPROVISE; + button_impro.set_text("STOP"); transmit(true); } }; diff --git a/firmware/application/ui_nuoptix.hpp b/firmware/application/ui_nuoptix.hpp index 514daeea..9fb2c723 100644 --- a/firmware/application/ui_nuoptix.hpp +++ b/firmware/application/ui_nuoptix.hpp @@ -43,17 +43,17 @@ public: std::string title() const override { return "Nuoptix sync"; }; private: - /*enum tx_modes { - NORMAL = 0, - RANDOM + enum tx_modes { + IDLE = 0, + NORMAL, + IMPROVISE }; - tx_modes tx_mode = NORMAL;*/ + tx_modes tx_mode = IDLE; void on_tuning_frequency_changed(rf::Frequency f); void transmit(bool setup); - bool txing = false; uint32_t timecode; FrequencyField field_frequency { @@ -102,10 +102,15 @@ private: };*/ Button button_tx { - { 32, 270, 64, 32 }, + { 70, 128, 100, 40 }, "TX" }; + Button button_impro { + { 70, 184, 100, 40 }, + "IMPROVISE" + }; + Button button_exit { { 160, 270, 64, 32 }, "Exit" @@ -115,7 +120,7 @@ private: Message::ID::TXDone, [this](const Message* const p) { const auto message = *reinterpret_cast(p); - if (message.n == 64) + if (message.n == 0xFF) transmit(false); else pbar.set_value(message.n); diff --git a/firmware/baseband/proc_dtmf_tx.cpp b/firmware/baseband/proc_dtmf_tx.cpp index 0bcb64e5..e8477875 100644 --- a/firmware/baseband/proc_dtmf_tx.cpp +++ b/firmware/baseband/proc_dtmf_tx.cpp @@ -28,9 +28,6 @@ #include -// 153600 = 1000ms -// - void DTMFTXProcessor::execute(const buffer_c8_t& buffer){ // This is called at 1536000/2048 = 750Hz @@ -38,7 +35,6 @@ void DTMFTXProcessor::execute(const buffer_c8_t& buffer){ if (!configured) return; - //ai = 0; for (size_t i = 0; i(msg); if (message.id == Message::ID::DTMFTXConfig) { + + // Translate DTMF message to index in DTMF frequencies table + tone_ptr = &shared_memory.tx_data[0]; + for (;;) { + tone_code = *tone_ptr; + if (tone_code == 0xFF) + break; // End of message + else if (tone_code <= 9) + // That's already fine bro. + *tone_ptr = tone_code; + else if (tone_code == 'A') + *tone_ptr = 10; + else if (tone_code == 'B') + *tone_ptr = 11; + else if (tone_code == 'C') + *tone_ptr = 12; + else if (tone_code == 'D') + *tone_ptr = 13; + else if (tone_code == '#') + *tone_ptr = 14; + else if (tone_code == '*') + *tone_ptr = 15; + else { + *tone_ptr = 0xFF; // Invalid character, stop here + } + tone_ptr++; + } + // 1<<18 = 262144 // m = (262144 * a) / 1536000 // a = 262144 / 1536000 (*1000 = 171) bw = 171 * (message.bw); - tone_length = message.tone_length; - pause_length = message.pause_length; + tone_length = message.tone_length * 154; // 153.6 + pause_length = message.pause_length * 154; // 153.6 as = 0; - //memcpy(tone_list, shared_memory.tx_data, 32); - //tone_list[31] = 0; tone = false; timer = 0; tone_idx = 0; diff --git a/firmware/baseband/proc_dtmf_tx.hpp b/firmware/baseband/proc_dtmf_tx.hpp index 8389f205..b04f5802 100644 --- a/firmware/baseband/proc_dtmf_tx.hpp +++ b/firmware/baseband/proc_dtmf_tx.hpp @@ -26,7 +26,15 @@ #include "baseband_processor.hpp" #include "baseband_thread.hpp" -#define DTMF_PHASEINC (436.91) // (65536*1024)/1536000*10 +#define DTMF_PHASEINC 436.91 // (65536*1024)/1536000*10 +#define DTMF_C0 (uint32_t)(1209*DTMF_PHASEINC) +#define DTMF_C1 (uint32_t)(1336*DTMF_PHASEINC) +#define DTMF_C2 (uint32_t)(1477*DTMF_PHASEINC) +#define DTMF_C3 (uint32_t)(1633*DTMF_PHASEINC) +#define DTMF_R0 (uint32_t)(697*DTMF_PHASEINC) +#define DTMF_R1 (uint32_t)(770*DTMF_PHASEINC) +#define DTMF_R2 (uint32_t)(852*DTMF_PHASEINC) +#define DTMF_R3 (uint32_t)(941*DTMF_PHASEINC) class DTMFTXProcessor : public BasebandProcessor { public: @@ -41,32 +49,31 @@ private: // 0123456789ABCD#* const uint32_t DTMF_LUT[16][2] = { - { (uint32_t)(1336*DTMF_PHASEINC), (uint32_t)(941*DTMF_PHASEINC) }, - { (uint32_t)(1209*DTMF_PHASEINC), (uint32_t)(697*DTMF_PHASEINC) }, - { (uint32_t)(1336*DTMF_PHASEINC), (uint32_t)(697*DTMF_PHASEINC) }, - { (uint32_t)(1477*DTMF_PHASEINC), (uint32_t)(697*DTMF_PHASEINC) }, - { (uint32_t)(1209*DTMF_PHASEINC), (uint32_t)(770*DTMF_PHASEINC) }, - { (uint32_t)(1336*DTMF_PHASEINC), (uint32_t)(770*DTMF_PHASEINC) }, - { (uint32_t)(1477*DTMF_PHASEINC), (uint32_t)(770*DTMF_PHASEINC) }, - { (uint32_t)(1209*DTMF_PHASEINC), (uint32_t)(852*DTMF_PHASEINC) }, - { (uint32_t)(1336*DTMF_PHASEINC), (uint32_t)(852*DTMF_PHASEINC) }, - { (uint32_t)(1477*DTMF_PHASEINC), (uint32_t)(852*DTMF_PHASEINC) }, - { (uint32_t)(1633*DTMF_PHASEINC), (uint32_t)(697*DTMF_PHASEINC) }, - { (uint32_t)(1633*DTMF_PHASEINC), (uint32_t)(770*DTMF_PHASEINC) }, - { (uint32_t)(1633*DTMF_PHASEINC), (uint32_t)(852*DTMF_PHASEINC) }, - { (uint32_t)(1633*DTMF_PHASEINC), (uint32_t)(941*DTMF_PHASEINC) }, - { (uint32_t)(1477*DTMF_PHASEINC), (uint32_t)(941*DTMF_PHASEINC) }, - { (uint32_t)(1209*DTMF_PHASEINC), (uint32_t)(941*DTMF_PHASEINC) } + { DTMF_C1, DTMF_R3 }, + { DTMF_C0, DTMF_R0 }, + { DTMF_C1, DTMF_R0 }, + { DTMF_C2, DTMF_R0 }, + { DTMF_C0, DTMF_R1 }, + { DTMF_C1, DTMF_R1 }, + { DTMF_C2, DTMF_R1 }, + { DTMF_C0, DTMF_R2 }, + { DTMF_C1, DTMF_R2 }, + { DTMF_C2, DTMF_R2 }, + { DTMF_C3, DTMF_R0 }, + { DTMF_C3, DTMF_R1 }, + { DTMF_C3, DTMF_R2 }, + { DTMF_C3, DTMF_R3 }, + { DTMF_C2, DTMF_R3 }, + { DTMF_C0, DTMF_R3 } }; uint32_t tone_length, pause_length; uint32_t as, bw; - uint8_t tone_list[32]; uint8_t tone_idx = 0, tone_code = 0; uint32_t timer = 0; - bool tone = false; + bool tone = false; // Tone / pause int8_t re, im; int8_t sample; diff --git a/firmware/portapack-h1-havoc.bin b/firmware/portapack-h1-havoc.bin index 55c13bcb..d652b5a4 100644 Binary files a/firmware/portapack-h1-havoc.bin and b/firmware/portapack-h1-havoc.bin differ