diff --git a/firmware/application/ui_lcr.cpp b/firmware/application/ui_lcr.cpp index 09ae9858..ec65f5fa 100644 --- a/firmware/application/ui_lcr.cpp +++ b/firmware/application/ui_lcr.cpp @@ -32,6 +32,7 @@ #include "hackrf_hal.hpp" #include "portapack_shared_memory.hpp" +#include "portapack_persistent_memory.hpp" #include #include @@ -57,23 +58,23 @@ void LCRView::paint(Painter& painter) { char eom[3] = { 3, 0, 0 }; uint8_t checksum = 0, i; char teststr[16]; + uint16_t dp; + uint8_t cp, pp, cur_byte, new_byte; + + static constexpr Style style_orange { + .font = font::fixed_8x16, + .background = Color::black(), + .foreground = Color::orange(), + }; Point offset = { - static_cast(120), - static_cast(32) + static_cast(72), + static_cast(72) }; painter.draw_string( screen_pos() + offset, - style(), - rgsb - ); - - offset.y += 40; - - painter.draw_string( - screen_pos() + offset, - style(), + style_orange, litteral[0] ); @@ -81,7 +82,7 @@ void LCRView::paint(Painter& painter) { painter.draw_string( screen_pos() + offset, - style(), + style_orange, litteral[1] ); @@ -89,7 +90,7 @@ void LCRView::paint(Painter& painter) { painter.draw_string( screen_pos() + offset, - style(), + style_orange, litteral[2] ); @@ -97,10 +98,11 @@ void LCRView::paint(Painter& painter) { painter.draw_string( screen_pos() + offset, - style(), + style_orange, litteral[3] ); + // Testing: 7 char pad for litterals for (i = 0; i < 4; i++) { while (strlen(litteral[i]) < 7) { strcat(litteral[i], " "); @@ -114,7 +116,9 @@ void LCRView::paint(Painter& painter) { lcrframe[2] = 127; lcrframe[3] = 127; lcrframe[4] = 127; - lcrframe[5] = 15; + lcrframe[5] = 127; + lcrframe[6] = 127; + lcrframe[7] = 15; strcat(lcrframe, rgsb); strcat(lcrframe, "PA AM=1 AF=\""); strcat(lcrframe, litteral[0]); @@ -124,10 +128,10 @@ void LCRView::paint(Painter& painter) { strcat(lcrframe, litteral[2]); strcat(lcrframe, "\" CL=0 AM=4 AF=\""); strcat(lcrframe, litteral[3]); - strcat(lcrframe, "\" CL=0 EC=A SAB=0"); + strcat(lcrframe, "\" CL=0 EC=A SAB=0"); //TODO: EC=A,J,N //Checksum - i = 5; + i = 7; while (lcrframe[i]) { checksum ^= lcrframe[i]; i++; @@ -138,6 +142,17 @@ void LCRView::paint(Painter& painter) { strcat(lcrframe, eom); + for (dp=0;dp>cp)&1) pp++; + new_byte |= ((cur_byte>>cp)&1)<<(7-cp); + } + lcrframe[dp] = new_byte|(pp&1); + } + teststr[0] = hexify(eom[1] >> 4); teststr[1] = hexify(eom[1] & 15); teststr[2] = 0; @@ -163,8 +178,6 @@ void LCRView::updfreq(rf::Frequency f) { this->button_setfreq.set_text(finalstr); } -//TODO: 7 char pad for litterals - LCRView::LCRView( NavigationView& nav, TransmitterModel& transmitter_model @@ -175,25 +188,27 @@ LCRView::LCRView( memset(litteral, 0, 4*8); memset(rgsb, 0, 5); - rgsb[0] = 'E'; - rgsb[1] = 'b'; - rgsb[2] = 'G'; - rgsb[3] = '0'; // Predef. + strcpy(rgsb, RGSB_list[0]); add_children({ { &button_setrgsb, + &button_txsetup, &button_setam_a, &button_setam_b, &button_setam_c, &button_setam_d, &button_setfreq, - &button_setbaud, + &button_setbps, &button_transmit, + &button_transmit_scan, &button_exit } }); button_setrgsb.on_select = [this,&nav](Button&){ auto an_view = new AlphanumView { nav, rgsb, 4 }; + an_view->on_changed = [this](char *rgsb) { + button_setrgsb.set_text(rgsb); + }; nav.push(an_view); }; button_setfreq.on_select = [this,&nav](Button&){ @@ -206,36 +221,40 @@ LCRView::LCRView( button_setam_a.on_select = [this,&nav](Button&){ auto an_view = new AlphanumView { nav, litteral[0], 7 }; + an_view->on_changed = [this](char *) {}; nav.push(an_view); }; button_setam_b.on_select = [this,&nav](Button&){ auto an_view = new AlphanumView { nav, litteral[1], 7 }; + an_view->on_changed = [this](char *) {}; nav.push(an_view); }; button_setam_c.on_select = [this,&nav](Button&){ auto an_view = new AlphanumView { nav, litteral[2], 7 }; + an_view->on_changed = [this](char *) {}; nav.push(an_view); }; button_setam_d.on_select = [this,&nav](Button&){ auto an_view = new AlphanumView { nav, litteral[3], 7 }; + an_view->on_changed = [this](char *) {}; nav.push(an_view); }; - button_setbaud.on_select = [this](Button&){ - if (baudrate == 1200) { - baudrate = 2400; - button_setbaud.set_text("2400 bps"); + button_setbps.on_select = [this](Button&){ + if (persistent_memory::afsk_bitrate() == 1200) { + persistent_memory::set_afsk_bitrate(2400); + button_setbps.set_text("2400 bps"); } else { - baudrate = 1200; - button_setbaud.set_text("1200 bps"); + persistent_memory::set_afsk_bitrate(1200); + button_setbps.set_text("1200 bps"); } }; button_transmit.on_select = [this,&transmitter_model](Button&){ uint16_t c; - if (baudrate == 1200) - shared_memory.fskspb = 190; - else - shared_memory.fskspb = 95; + + shared_memory.afsk_samples_per_bit = 228000/persistent_memory::afsk_bitrate(); + shared_memory.afsk_phase_inc_mark = persistent_memory::afsk_mark_freq()*(65536*1024)/228000; + shared_memory.afsk_phase_inc_space = persistent_memory::afsk_space_freq()*(65536*1024)/228000; for (c = 0; c < 256; c++) { shared_memory.lcrdata[c] = this->lcrframe[c]; diff --git a/firmware/application/ui_lcr.hpp b/firmware/application/ui_lcr.hpp index fd05f291..3e7e320f 100644 --- a/firmware/application/ui_lcr.hpp +++ b/firmware/application/ui_lcr.hpp @@ -44,53 +44,72 @@ public: void paint(Painter& painter) override; private: + const char RGSB_list[37][5] = { + "EAA0", "EAB0", "EAC0", "EAD0", + "EbA0", "EbB0", "EbC0", "EbD0", + "EbE0", "EbF0", "EbG0", "EbH0", + "EbI0", "EbJ0", "EbK0", "EbL0", + "EbM0", "EbN0", "EbO0", "EbP0", + "EbS0", "EAD0", "AI10", "AI20", + "AI30", "AI40", "AI50", "AI60", + "AI70", "AJ10", "AJ20", "AJ30", + "AJ40", "AJ50", "AJ60", "AJ70", + "AK10" + }; char litteral[4][8]; char rgsb[5]; char lcrframe[256]; - uint16_t baudrate = 1200; - rf::Frequency f = 160000000; + rf::Frequency f = 162950000; TransmitterModel& transmitter_model; Button button_setrgsb { { 16, 24, 96, 32 }, "Set RGSB" }; + Button button_txsetup { + { 120, 24, 96, 32 }, + "TX setup" + }; Button button_setam_a { - { 16, 64, 96, 32 }, + { 16, 64, 48, 32 }, "AM 1" }; Button button_setam_b { - { 16, 64+40, 96, 32 }, + { 16, 64+40, 48, 32 }, "AM 2" }; Button button_setam_c { - { 16, 64+40+40, 96, 32 }, + { 16, 64+40+40, 48, 32 }, "AM 3" }; Button button_setam_d { - { 16, 64+40+40+40, 96, 32 }, + { 16, 64+40+40+40, 48, 32 }, "AM 4" }; Button button_setfreq { - { 4, 232, 96, 32 }, - "160.0000" + { 8, 232, 96, 32 }, + "162.9500" }; - Button button_setbaud { - { 4, 270, 96, 32 }, + Button button_setbps { + { 128, 232, 96, 32 }, "1200bps" }; Button button_transmit { - { 120, 232, 96, 32 }, - "Transmit" + { 8, 270, 48, 32 }, + "TX" + }; + Button button_transmit_scan { + { 60, 270, 64, 32 }, + "SCAN TX" }; Button button_exit { - { 120, 270, 96, 32 }, + { 176, 270, 48, 32 }, "Exit" }; }; diff --git a/firmware/application/ui_rds.cpp b/firmware/application/ui_rds.cpp index fecd341f..1df16d82 100644 --- a/firmware/application/ui_rds.cpp +++ b/firmware/application/ui_rds.cpp @@ -102,6 +102,7 @@ AlphanumView::AlphanumView( add_child(&button_done); button_done.on_select = [this, &nav, txt, max_len](Button&) { memcpy(txt, txtinput, max_len+1); + on_changed(this->value()); nav.pop(); }; diff --git a/firmware/application/ui_rds.hpp b/firmware/application/ui_rds.hpp index 2f777d20..52396553 100644 --- a/firmware/application/ui_rds.hpp +++ b/firmware/application/ui_rds.hpp @@ -36,7 +36,7 @@ namespace ui { class AlphanumView : public View { public: - //std::function on_changed; + std::function on_changed; AlphanumView(NavigationView& nav, char txt[], uint8_t max_len); diff --git a/firmware/baseband/main.cpp b/firmware/baseband/main.cpp index 1ad86f06..a1e62619 100755 --- a/firmware/baseband/main.cpp +++ b/firmware/baseband/main.cpp @@ -762,40 +762,65 @@ private: class LCRFSKProcessor : public BasebandProcessor { public: + void BasebandProcessor() { + afsk_samples_per_bit = shared_memory.afsk_samples_per_bit; + phase_inc_mark = shared_memory.afsk_phase_inc_mark; + phase_inc_space = shared_memory.afsk_phase_inc_space; + } + void execute(buffer_c8_t buffer) override { for (size_t i = 0; i= 9) { + //Sample generation 2.28M/10 = 228kHz + if (s >= 9) { s = 0; - fsk_samples_per_bit = shared_memory.fskspb; - if(sample_count >= fsk_samples_per_bit) { - cur_byte = shared_memory.lcrdata[bit_pos / 8]; + + if (sample_count >= afsk_samples_per_bit) { + cur_byte = shared_memory.lcrdata[byte_pos]; if (!cur_byte) { - //TransmitterModel::disable(); bit_pos = 0; + byte_pos = 0; cur_byte = shared_memory.lcrdata[0]; } - cur_bit = cur_byte >> (7-(bit_pos % 8)) & 1; + cur_byte = (0x55<<1); //DEBUG + + //SdddddddpD + //0dddddddp1 + + gbyte = 0; + gbyte = cur_byte << 1; + gbyte |= 1; + + cur_bit = gbyte >> (9-bit_pos) & 1; - bit_pos++; + if (bit_pos == 9) { + bit_pos = 0; + byte_pos++; + } else { + bit_pos++; + } + + //aphase = 0x2FFFFFF; + sample_count = 0; + } else { + sample_count++; } - sample_count++; - if (cur_bit) - aphase += 267187; + aphase += phase_inc_mark; //(353205) else - aphase += 489844; + aphase += phase_inc_space; //(647542) sample = sintab[(aphase & 0x03FF0000)>>16]; } else { s++; } + sample = sintab[(aphase & 0x03FF0000)>>16]; + //FM - frq = sample * 967; + frq = sample * 850; //TODO: Put in config (channel bandwidth) phase = (phase + frq); sphase = phase + (256<<16); @@ -808,11 +833,13 @@ public: } private: - uint32_t fsk_samples_per_bit; + uint32_t afsk_samples_per_bit; + uint32_t phase_inc_mark, phase_inc_space; int8_t re, im; uint8_t s; - uint32_t bit_pos; + uint8_t bit_pos, byte_pos; uint8_t cur_byte = 0; + uint16_t gbyte; uint8_t cur_bit = 0; uint32_t sample_count; uint32_t aphase, phase, sphase; diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 6c44f0fd..06f01177 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -55,10 +55,26 @@ using ppb_range_t = range_t; constexpr ppb_range_t ppb_range { -99000, 99000 }; constexpr ppb_t ppb_reset_value { 0 }; +using afsk_freq_range_t = range_t; +constexpr afsk_freq_range_t afsk_freq_range { 100, 32000 }; +constexpr int16_t afsk_mark_reset_value { 1200 }; +constexpr int16_t afsk_space_reset_value { 2200 }; + +using afsk_bitrate_range_t = range_t; +constexpr afsk_bitrate_range_t afsk_bitrate_range { 600, 9600 }; +constexpr int16_t afsk_bitrate_reset_value { 1200 }; + /* struct must pack the same way on M4 and M0 cores. */ struct data_t { + // General config int64_t tuned_frequency; int32_t correction_ppb; + + // AFSK modem + int16_t afsk_mark_freq; + int16_t afsk_space_freq; + int16_t afsk_bitrate; + uint8_t afsk_config; }; static_assert(sizeof(data_t) <= 0x100, "Persistent memory structure too large for VBAT-maintained region"); @@ -83,5 +99,40 @@ void set_correction_ppb(const ppb_t new_value) { data->correction_ppb = ppb_range.clip(new_value); } +int16_t afsk_mark_freq() { + afsk_freq_range.reset_if_outside(data->afsk_mark_freq, afsk_mark_reset_value); + return data->correction_ppb; +} + +void set_afsk_mark(const int16_t new_value) { + data->afsk_mark_freq = afsk_freq_range.clip(new_value); +} + +int16_t afsk_space_freq() { + afsk_freq_range.reset_if_outside(data->afsk_space_freq, afsk_space_reset_value); + return data->correction_ppb; +} + +void set_afsk_space(const int16_t new_value) { + data->afsk_space_freq = afsk_freq_range.clip(new_value); +} + +int16_t afsk_bitrate() { + afsk_bitrate_range.reset_if_outside(data->afsk_bitrate, afsk_bitrate_reset_value); + return data->correction_ppb; +} + +void set_afsk_bitrate(const int16_t new_value) { + data->afsk_bitrate = afsk_bitrate_range.clip(new_value); +} + +uint8_t afsk_config() { + return data->afsk_config; +} + +void set_afsk_config(const uint8_t new_value) { + data->afsk_config = new_value; +} + } /* namespace persistent_memory */ } /* namespace portapack */ diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 3e1a6c14..947947cc 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -37,6 +37,18 @@ void set_tuned_frequency(const rf::Frequency new_value); ppb_t correction_ppb(); void set_correction_ppb(const ppb_t new_value); +int16_t afsk_mark_freq(); +void set_afsk_mark(const int16_t new_value); + +int16_t afsk_space_freq(); +void set_afsk_space(const int16_t new_value); + +int16_t afsk_bitrate(); +void set_afsk_bitrate(const int16_t new_value); + +uint8_t afsk_config(); +void set_afsk_config(const uint8_t new_value); + } /* namespace persistent_memory */ } /* namespace portapack */ diff --git a/firmware/common/portapack_shared_memory.hpp b/firmware/common/portapack_shared_memory.hpp index ab19ba13..289cbf30 100644 --- a/firmware/common/portapack_shared_memory.hpp +++ b/firmware/common/portapack_shared_memory.hpp @@ -42,8 +42,11 @@ struct SharedMemory { int test; uint32_t rdsdata[16]; + char lcrdata[256]; - uint32_t fskspb; + uint32_t afsk_samples_per_bit; + uint32_t afsk_phase_inc_mark; + uint32_t afsk_phase_inc_space; }; extern SharedMemory& shared_memory; diff --git a/firmware/common/ui.hpp b/firmware/common/ui.hpp index dc738aec..862d3495 100644 --- a/firmware/common/ui.hpp +++ b/firmware/common/ui.hpp @@ -63,6 +63,10 @@ struct Color { static constexpr Color red() { return { 255, 0, 0 }; } + + static constexpr Color orange() { + return { 255, 127, 0 }; + } static constexpr Color yellow() { return { 255, 255, 0 };