diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 8011bc1e6..32c439203 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -155,6 +155,13 @@ void set_adsb() { send_message(&message); } +void set_jammer() { + const JammerConfigureMessage message { + 1 + }; + send_message(&message); +} + void set_rds_data(const uint16_t message_length) { const RDSConfigureMessage message { message_length diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index 22da8e2db..5bc3c82d8 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -65,6 +65,7 @@ void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint32_t pause_symbols); void set_pocsag(const pocsag::BitRate bitrate); void set_adsb(); +void set_jammer(); void set_rds_data(const uint16_t message_length); //void set_dtmf_data(const uint32_t bw, const uint32_t tone_length, const uint32_t pause_length); diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 84c10b05a..cfa0aef3e 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -23,7 +23,12 @@ // Color bitmaps generated with: // Gimp image > indexed colors (16), then "xxd -i *.bmp" -//BUG: Bad console scroll init +//BUG: (fixed ?) Bad console scroll init +//BUG: POCSAG misses alphanum messages, cuts them off sometimes +//BUG: Jammer channels are wrong (not enough) when using multiple ranges + +//TODO: Array for checkboxes and texts, options_preset "CUSTOM" on manual freq. entry, in jammer +//TODO: Digital mode for Waveform widget //TEST: Imperial in whipcalc //TEST: Numbers diff --git a/firmware/application/ui_encoders.cpp b/firmware/application/ui_encoders.cpp index 0fc395cc2..85c0e044f 100644 --- a/firmware/application/ui_encoders.cpp +++ b/firmware/application/ui_encoders.cpp @@ -239,45 +239,6 @@ void EncodersView::on_type_change(size_t index) { format_string += ' '; text_format.set(format_string); - - /*word_format = encoder_def->word_format; - size_t address_start = word_format.find_first_of("A"); - size_t data_start = word_format.find_first_of("D"); - size_t format_length = word_format.length(); - - if (address_start == std::string::npos) address_start = format_length; - if (data_start == std::string::npos) data_start = format_length; - - // Never did anything so dirty :( - if (!address_start) { - address_length = data_start; - data_length = format_length - address_length; - } else { - data_length = address_start; - address_length = format_length - data_length; - } - - if (address_length) { - text_format_a.hidden(false); - text_format_a.set_parent_rect( - { (2 + address_start) * 8, 12 * 8, address_length * 8, 16 } - ); - text_format_a.set_style(&style_address); - text_format_a.set(std::string(address_length, 'A')); - } else { - text_format_a.hidden(true); - } - - if (data_length) { - text_format_d.hidden(false); - text_format_d.set_parent_rect( - { (2 + data_start) * 8, 12 * 8, data_length * 8, 16 } - ); - text_format_d.set_style(&style_data); - text_format_d.set(std::string(data_length, 'D')); - } else { - text_format_d.hidden(true); - }*/ generate_frame(); } diff --git a/firmware/application/ui_jammer.cpp b/firmware/application/ui_jammer.cpp index 52a841c9c..184452cd6 100644 --- a/firmware/application/ui_jammer.cpp +++ b/firmware/application/ui_jammer.cpp @@ -90,9 +90,11 @@ void JammerView::update_text(uint8_t id, rf::Frequency f) { } } -void JammerView::on_retune(const rf::Frequency freq) { - if (freq > 0) +void JammerView::on_retune(const rf::Frequency freq, const uint32_t range) { + if (freq) { transmitter_model.set_tuning_frequency(freq); + text_range_number.set(to_string_dec_uint(range, 2, ' ')); + } } JammerView::JammerView(NavigationView& nav) { @@ -102,14 +104,14 @@ JammerView::JammerView(NavigationView& nav) { static constexpr Style style_val { .font = font::fixed_8x16, - .background = Color::green(), - .foreground = Color::black(), + .background = Color::black(), + .foreground = Color::green(), }; static constexpr Style style_cancel { .font = font::fixed_8x16, - .background = Color::red(), - .foreground = Color::black(), + .background = Color::black(), + .foreground = Color::red(), }; static constexpr Style style_info { @@ -122,6 +124,7 @@ JammerView::JammerView(NavigationView& nav) { add_children({ &text_type, + &text_range_number, &options_modulation, &text_sweep, &options_sweep, @@ -189,78 +192,86 @@ JammerView::JammerView(NavigationView& nav) { button_transmit.on_select = [this, &nav, jammer_ranges](Button&) { uint8_t c, i = 0; size_t num_ranges; - rf::Frequency start_freq, range_bw, ch_width; + rf::Frequency start_freq, range_bw, range_bw_sub, ch_width; bool out_of_ranges = false; // Disable all ranges by default - for (i = 0; i < 9; i++) - jammer_ranges[i].enabled = false; + for (c = 0; c < 9; c++) + jammer_ranges[c].enabled = false; // Generate jamming "channels", maximum: 9 // Convert ranges min/max to center/bw for (c = 0; c < 3; c++) { + range_bw = abs(frequency_range[c].max - frequency_range[c].min); // Total bw for range - if (frequency_range[c].min < frequency_range[c].max) - start_freq = frequency_range[c].min; - else - start_freq = frequency_range[c].max; - if (range_bw > 500000) { - // Example: 600kHz - // int(600000 / 500000) = 2 - // CH-BW = 600000 / 2 = 300000 - // Center-A = min + CH-BW / 2 = 150000 - // BW-A = CH-BW = 300000 - // Center-B = min + CH-BW + Center-A = 450000 - // BW-B = CH-BW = 300000 - num_ranges = 0; - while (range_bw > 500000) { - range_bw -= 500000; - num_ranges++; - } - ch_width = range_bw / num_ranges; - for (c = 0; c < num_ranges; c++) { + + if (range_bw) { + // Sort + if (frequency_range[c].min < frequency_range[c].max) + start_freq = frequency_range[c].min; + else + start_freq = frequency_range[c].max; + + if (range_bw > 500000) { + // Example: 600kHz + // int(600000 / 500000) = 2 + // CH-BW = 600000 / 2 = 300000 + // Center-A = min + CH-BW / 2 = 150000 + // BW-A = CH-BW = 300000 + // Center-B = min + CH-BW + Center-A = 450000 + // BW-B = CH-BW = 300000 + num_ranges = 0; + range_bw_sub = range_bw; + do { + range_bw_sub -= 500000; + num_ranges++; + } while (range_bw_sub > 500000); + ch_width = range_bw / num_ranges; + for (c = 0; c < num_ranges; c++) { + if (i >= 9) { + out_of_ranges = true; + break; + } + jammer_ranges[i].enabled = true; + jammer_ranges[i].width = ch_width; + jammer_ranges[i].center = start_freq + (ch_width / 2) + (ch_width * c); + jammer_ranges[i].duration = 15360 * options_hop.selected_index_value(); + i++; + } + } else { if (i >= 9) { out_of_ranges = true; - break; + } else { + jammer_ranges[i].enabled = true; + jammer_ranges[i].width = range_bw; + jammer_ranges[i].center = start_freq + (range_bw / 2); + jammer_ranges[i].duration = 15360 * options_hop.selected_index_value(); + i++; } - jammer_ranges[i].enabled = true; - jammer_ranges[i].width = ch_width; - jammer_ranges[i].center = start_freq + (ch_width / 2) + (ch_width * c); - jammer_ranges[i].duration = 2280000 / 10; // ? - i++; - } - } else { - if (i >= 9) { - out_of_ranges = true; - } else { - jammer_ranges[i].enabled = true; - jammer_ranges[i].width = range_bw; - jammer_ranges[i].center = start_freq + (range_bw / 2); - jammer_ranges[i].duration = 2280000 / 10; // ? - i++; } } - - if (!out_of_ranges) { - if (jamming == true) { - jamming = false; - button_transmit.set_style(&style_val); - button_transmit.set_text("START"); - radio::disable(); - } else { - jamming = true; - button_transmit.set_style(&style_cancel); - button_transmit.set_text("STOP"); - - //transmitter_model.set_tuning_frequency(433920000); // TODO - transmitter_model.set_sampling_rate(1536000U); - transmitter_model.set_rf_amp(true); - transmitter_model.set_baseband_bandwidth(1750000); - transmitter_model.enable(); - } + } + + if (!out_of_ranges) { + if (jamming == true) { + jamming = false; + button_transmit.set_style(&style_val); + button_transmit.set_text("START"); + radio::disable(); } else { - nav.display_modal("Error", "Jamming bandwidth too large."); + jamming = true; + button_transmit.set_style(&style_cancel); + button_transmit.set_text("STOP"); + + transmitter_model.set_sampling_rate(1536000U); + transmitter_model.set_rf_amp(true); + transmitter_model.set_baseband_bandwidth(1750000); + transmitter_model.enable(); + + baseband::set_jammer(); } + } else { + nav.display_modal("Error", "Jamming bandwidth too large."); } }; diff --git a/firmware/application/ui_jammer.hpp b/firmware/application/ui_jammer.hpp index 2d2439346..3fba8d3e6 100644 --- a/firmware/application/ui_jammer.hpp +++ b/firmware/application/ui_jammer.hpp @@ -49,7 +49,7 @@ private: freq_range_t frequency_range[3]; void update_text(uint8_t id, rf::Frequency f); - void on_retune(const rf::Frequency freq); + void on_retune(const rf::Frequency freq, const uint32_t range); // TODO: TDD UMTS, voir doc Arcep // TODO: BT: 2 400 et 2 483,5 MHz @@ -100,8 +100,8 @@ private: { false, 0, 0 }}, // GPS L1 & L2 - {{ true, 1575420000 - 50000, 1575420000 + 50000}, // BW: 100kHz - { true, 1227600000 - 50000, 1227600000 + 50000 }, // BW: 100kHz + {{ true, 1575420000 - 1000000, 1575420000 + 1000000}, // BW: 2MHz + { true, 1227600000 - 1000000, 1227600000 + 1000000 }, // BW: 2MHz { false, 0, 0 }}, // WLAN 2.4G CH1 @@ -177,6 +177,11 @@ private: } }; + Text text_range_number { + { 14 * 8, 1 * 16, 2 * 8, 16 }, + "--" + }; + Text text_sweep { { 1 * 8, 2 * 16, 6 * 8, 16 }, "Sweep:" @@ -202,14 +207,13 @@ private: }; OptionsField options_hop { { 12 * 8, 4 * 16 }, - 6, + 5, { - { " 10s", 0 }, - { " 5s", 1 }, - { " 1s", 2 }, - { " 0.1s", 3 }, - { " 10ms", 4 }, - { " 1ms", 5 } + { " 10ms", 1 }, + { "100ms", 10 }, + { " 1s", 100 }, + { " 5s", 500 }, + { " 10s", 1000 } } }; @@ -263,7 +267,7 @@ private: "Range 3" }; - std::array buttons_freq; + std::array buttons_freq { }; Text text_info1 { { 3 * 8, 8 * 16 - 4 + 2, 25 * 8, 16 }, @@ -294,7 +298,7 @@ private: Message::ID::Retune, [this](Message* const p) { const auto message = static_cast(p); - this->on_retune(message->freq); + this->on_retune(message->freq, message->range); } }; }; diff --git a/firmware/baseband/proc_jammer.cpp b/firmware/baseband/proc_jammer.cpp index 4e91476a1..1e0e4930a 100644 --- a/firmware/baseband/proc_jammer.cpp +++ b/firmware/baseband/proc_jammer.cpp @@ -27,27 +27,29 @@ #include -#define POLY_MASK_32 0xB4BCD35C - void JammerProcessor::execute(const buffer_c8_t& buffer) { - if (!configured) return; - for (size_t i = 0; i= 10000) { //shared_memory.jammer_ranges[ir].duration - s = 0; - for (;;) { - ir++; - if (ir > 15) ir = 0; - if (jammer_ranges[ir].enabled == true) break; + if (!jammer_duration) { + // Find next enabled range + for (ir = 0; ir < 9; ir++) { + current_range++; + if (current_range == 9) current_range = 0; + if (jammer_ranges[current_range].enabled) + break; } - jammer_bw = jammer_ranges[ir].width / 2; - message.freq = jammer_ranges[ir].center; + jammer_duration = jammer_ranges[current_range].duration; + jammer_bw = jammer_ranges[current_range].width / 6; // TODO: Exact value + + // Ask for retune + message.freq = jammer_ranges[current_range].center; + message.range = current_range; shared_memory.application_queue.push(message); } else { - s++; + jammer_duration--; } // Ramp @@ -61,7 +63,7 @@ void JammerProcessor::execute(const buffer_c8_t& buffer) { r++; }*/ - // Phase + // Phase noise if (r >= 70) { aphase += ((aphase>>4) ^ 0x4573) << 14; r = 0; @@ -70,69 +72,32 @@ void JammerProcessor::execute(const buffer_c8_t& buffer) { } aphase += 8830; - sample = sine_table_i8[(sphase & 0x03FC0000) >> 18]; + sample = sine_table_i8[(aphase & 0x03FC0000) >> 18]; // FM delta = sample * jammer_bw; - phase = (phase + delta); + phase += delta; sphase = phase + (64 << 18); re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]); im = (sine_table_i8[(phase & 0x03FC0000) >> 18]); - + buffer.p[i] = {(int8_t)re, (int8_t)im}; + //buffer.p[i] = {re, im}; } }; void JammerProcessor::on_message(const Message* const msg) { + const auto message = *reinterpret_cast(msg); - jammer_ranges = (JammerRange*)shared_memory.bb_data.data; - - /*const auto message = *reinterpret_cast(msg); - - if (message.id == Message::ID::DTMFTXConfig) { + if (message.id == Message::ID::JammerConfigure) { + jammer_ranges = (JammerRange*)shared_memory.bb_data.data; + jammer_duration = 0; + current_range = -1; - // 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 * 154; // 153.6 - pause_length = message.pause_length * 154; // 153.6 - as = 0; - tone = false; - timer = 0; - tone_idx = 0; - configured = true; - }*/ + } } int main() { diff --git a/firmware/baseband/proc_jammer.hpp b/firmware/baseband/proc_jammer.hpp index 7257d4484..c599427ef 100644 --- a/firmware/baseband/proc_jammer.hpp +++ b/firmware/baseband/proc_jammer.hpp @@ -38,18 +38,17 @@ private: BasebandThread baseband_thread { 1536000, this, NORMALPRIO + 20, baseband::Direction::Transmit }; - JammerRange * jammer_ranges; + JammerRange * jammer_ranges { }; - int32_t lfsr32 = 0xABCDE; - uint32_t s; - int8_t r, ir, re, im; - int64_t jammer_bw, jammer_center; - int feedback; - int32_t lfsr; - uint32_t sample_count; - uint32_t aphase, phase, sphase; - int32_t sample, delta; - RetuneMessage message; + uint32_t jammer_duration { 0 }; + int8_t r { 0 }, ir { 0 }; + int32_t current_range { 0 }; + int64_t jammer_center { 0 }; + uint32_t sample_count { 0 }; + uint32_t aphase { 0 }, phase { 0 }, delta { 0 }, sphase { 0 }; + int32_t sample { 0 }, jammer_bw { 0 }; + int8_t re, im; + RetuneMessage message { }; }; #endif diff --git a/firmware/baseband/proc_ook.cpp b/firmware/baseband/proc_ook.cpp index 4ce4bc319..167945835 100644 --- a/firmware/baseband/proc_ook.cpp +++ b/firmware/baseband/proc_ook.cpp @@ -28,12 +28,13 @@ #include void OOKProcessor::execute(const buffer_c8_t& buffer) { + int8_t re, im; // This is called at 2.28M/2048 = 1113Hz if (!configured) return; - for (size_t i = 0; i