From d5f20c45b9dc8e5fb85a19add41baa934cffe3e1 Mon Sep 17 00:00:00 2001 From: Brumi-2021 Date: Tue, 2 May 2023 17:19:23 +0200 Subject: [PATCH 1/4] Adding 16 bit LFSR , to Noise Signal Generator App --- firmware/application/apps/ui_siggen.hpp | 36 +++++++++++++------------ firmware/baseband/proc_siggen.cpp | 15 +++++++++-- firmware/baseband/proc_siggen.hpp | 7 +++-- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/firmware/application/apps/ui_siggen.hpp b/firmware/application/apps/ui_siggen.hpp index 58ed49b8..bb5b76e0 100644 --- a/firmware/application/apps/ui_siggen.hpp +++ b/firmware/application/apps/ui_siggen.hpp @@ -48,29 +48,30 @@ private: void update_tone(); void on_tx_progress(const uint32_t progress, const bool done); - const std::string shape_strings[9] = { - "CW ", - "Sine ", - "Triangle ", - "Saw up ", - "Saw down ", - "Square ", - "Noise n20Khz", - "Noise n10khz", - "Noise n5khz " + const std::string shape_strings[10] = { + "CW-no mod", + "Sine ", + "Triangle ", + "Saw up ", + "Saw down ", + "Square ", + "Noise 8-nx20Khz", // using 8 bits LFSR register, 6 order polynomial feedback. + "Noise 8-nx10khz", // using 8 bits LFSR register, 7 order polynomial feedback. + "Noise 8 -nx5khz ", // using 8 bits LFSR register, 8 order polynomial feedback. + "Noise 16-nx1khz" // using 16 bits LFSR register, 16 order polynomial feedback. }; bool auto_update { false }; Labels labels { - { { 6 * 8, 4 + 10 }, "Shape:", Color::light_grey() }, - { { 7 * 8, 7 * 8 }, "Tone: Hz", Color::light_grey() }, + { { 3 * 8, 4 + 10 }, "Shape:", Color::light_grey() }, + { { 6 * 8, 7 * 8 }, "Tone: Hz", Color::light_grey() }, { { 22 * 8, 15 * 8 + 4 }, "s.", Color::light_grey() }, { { 8 * 8, 20 * 8 }, "Modulation: FM", Color::light_grey() } }; ImageOptionsField options_shape { - { 13 * 8, 4, 32, 32 }, + { 10 * 8, 4, 32, 32 }, Color::white(), Color::black(), { @@ -82,12 +83,13 @@ private: { &bitmap_sig_square, 5 }, { &bitmap_sig_noise, 6 }, { &bitmap_sig_noise, 7 }, - { &bitmap_sig_noise, 8 } + { &bitmap_sig_noise, 8 }, + { &bitmap_sig_noise, 9 } } }; Text text_shape { - { 18 * 8, 4 + 10, 8 * 8, 16 }, + { 15 * 8, 4 + 10, 8 * 8, 16 }, "" }; @@ -98,12 +100,12 @@ private: }; Button button_update { - { 6 * 8, 10 * 8, 8 * 8, 3 * 8 }, + { 5 * 8, 10 * 8, 8 * 8, 3 * 8 }, "Update" }; Checkbox checkbox_auto { - { 16 * 8, 10 * 8 }, + { 15 * 8, 10 * 8 }, 4, "Auto" }; diff --git a/firmware/baseband/proc_siggen.cpp b/firmware/baseband/proc_siggen.cpp index 2fdc5545..714f5120 100644 --- a/firmware/baseband/proc_siggen.cpp +++ b/firmware/baseband/proc_siggen.cpp @@ -75,6 +75,17 @@ void SigGenProcessor::execute(const buffer_c8_t& buffer) { bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1; lfsr = (lfsr >> 1) | (bit << 7); sample = lfsr; + } else if (tone_shape == 9) { // 16 bits LFSR .taps: 16, 15, 13, 4 ;feedback polynomial: x^16 + x^15 + x^13 + x^4 + 1 + // Periode 65535= 2^n-1, harmonics every < 1Khz , quite continuous . + if (counter == 0) { + bit_16 = ((lfsr_16 >> 0) ^ (lfsr_16 >> 1) ^ (lfsr_16 >> 3) ^ (lfsr_16 >> 4) ^ (lfsr_16 >> 12) & 1); + lfsr_16 = (lfsr_16 >> 1) | (bit_16 << 15); + sample = (lfsr_16 & 0x00FF); + counter++; + } else { // counter == 1 , no need to shift the register again, just use the top 8 bits. + // sample = ((lfsr_16 & 0XFF00) >> 8); // it becomes less continuous the spectrum. Better skip it . + counter = 0; + } } if (tone_shape < 6) { @@ -114,8 +125,8 @@ void SigGenProcessor::on_message(const Message* const msg) { fm_delta = message.bw * (0xFFFFFFULL / 1536000); tone_shape = message.shape; - // lfsr = 0x54DF0119; - lfsr = seed_value ; + lfsr = seed_value ; // init lfsr 8 bits. + lfsr_16 = seed_value_16; // init lfsr 16 bits. configured = true; break; diff --git a/firmware/baseband/proc_siggen.hpp b/firmware/baseband/proc_siggen.hpp index c4adcd8b..84c6b896 100644 --- a/firmware/baseband/proc_siggen.hpp +++ b/firmware/baseband/proc_siggen.hpp @@ -44,9 +44,12 @@ private: bool auto_off { }; int32_t phase { 0 }, sphase { 0 }, delta { 0 }; // they may have sign . int8_t sample { 0 }, re { 0 }, im { 0 }; // they may have sign . - uint8_t seed_value = {0x56}; // seed : any nonzero start state will work. + uint8_t seed_value = {0x56}; // seed 8 bits lfsr : any nonzero start state will work. + uint16_t seed_value_16 = {0xACE1}; // seed 16 bits lfsr : any nonzero start state will work. uint8_t lfsr { }, bit { }; // bit must be 8-bit to allow bit<<7 later in the code */ - + uint16_t lfsr_16 { }, bit_16 { }; // bit must be 8-bit to allow bit<<7 later in the code */ + uint8_t counter {0}; + TXProgressMessage txprogress_message { }; }; From 804fa0d3c4825ca465d6249942d742bd39dffb0f Mon Sep 17 00:00:00 2001 From: Brumi-2021 Date: Tue, 2 May 2023 17:41:00 +0200 Subject: [PATCH 2/4] Minor GUI corrections-Signal Generator --- firmware/application/apps/ui_siggen.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/firmware/application/apps/ui_siggen.hpp b/firmware/application/apps/ui_siggen.hpp index bb5b76e0..a4922d86 100644 --- a/firmware/application/apps/ui_siggen.hpp +++ b/firmware/application/apps/ui_siggen.hpp @@ -49,12 +49,12 @@ private: void on_tx_progress(const uint32_t progress, const bool done); const std::string shape_strings[10] = { - "CW-no mod", - "Sine ", - "Triangle ", - "Saw up ", - "Saw down ", - "Square ", + "CW-just carrier", + "Sine signal ", + "Triangle signal", + "Saw up signal ", + "Saw down signal", + "Square signal ", "Noise 8-nx20Khz", // using 8 bits LFSR register, 6 order polynomial feedback. "Noise 8-nx10khz", // using 8 bits LFSR register, 7 order polynomial feedback. "Noise 8 -nx5khz ", // using 8 bits LFSR register, 8 order polynomial feedback. From d77102426a8148575eb134f443d506032fceda85 Mon Sep 17 00:00:00 2001 From: Brumi-2021 Date: Tue, 2 May 2023 21:29:35 +0200 Subject: [PATCH 3/4] Finally Noise Signal with best option 16 bit LFSR --- firmware/application/apps/ui_siggen.hpp | 12 +++------- firmware/baseband/proc_siggen.cpp | 32 +++++++++++++------------ firmware/baseband/proc_siggen.hpp | 12 +++++----- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/firmware/application/apps/ui_siggen.hpp b/firmware/application/apps/ui_siggen.hpp index a4922d86..31954375 100644 --- a/firmware/application/apps/ui_siggen.hpp +++ b/firmware/application/apps/ui_siggen.hpp @@ -48,17 +48,14 @@ private: void update_tone(); void on_tx_progress(const uint32_t progress, const bool done); - const std::string shape_strings[10] = { + const std::string shape_strings[7] = { "CW-just carrier", "Sine signal ", "Triangle signal", "Saw up signal ", "Saw down signal", "Square signal ", - "Noise 8-nx20Khz", // using 8 bits LFSR register, 6 order polynomial feedback. - "Noise 8-nx10khz", // using 8 bits LFSR register, 7 order polynomial feedback. - "Noise 8 -nx5khz ", // using 8 bits LFSR register, 8 order polynomial feedback. - "Noise 16-nx1khz" // using 16 bits LFSR register, 16 order polynomial feedback. + "White Noise " // using 16 bits LFSR register, 16 order polynomial feedback. }; bool auto_update { false }; @@ -81,10 +78,7 @@ private: { &bitmap_sig_saw_up, 3 }, { &bitmap_sig_saw_down, 4 }, { &bitmap_sig_square, 5 }, - { &bitmap_sig_noise, 6 }, - { &bitmap_sig_noise, 7 }, - { &bitmap_sig_noise, 8 }, - { &bitmap_sig_noise, 9 } + { &bitmap_sig_noise, 6 } } }; diff --git a/firmware/baseband/proc_siggen.cpp b/firmware/baseband/proc_siggen.cpp index 714f5120..810477cf 100644 --- a/firmware/baseband/proc_siggen.cpp +++ b/firmware/baseband/proc_siggen.cpp @@ -61,21 +61,9 @@ void SigGenProcessor::execute(const buffer_c8_t& buffer) { } else if (tone_shape == 5) { // Square sample = (((tone_phase & 0xFF000000) >> 24) & 0x80) ? 127 : -128; - } else if (tone_shape == 6) { // taps: 6 5; feedback polynomial: x^6 + x^5 + 1 , Periode 63 = 2^n-1,it generates armonincs n x 20Khz - // White Noise generator, pseudo random noise generator, 8 bits linear-feedback shift register (LFSR) algorithm, variant Fibonacci. + } else if (tone_shape == 6) { // White Noise generator, pseudo random noise generator, 8 bits linear-feedback shift register (LFSR) algorithm, variant Fibonacci. // https://en.wikipedia.org/wiki/Linear-feedback_shift_register - bit = ((lfsr >> 2) ^ (lfsr >> 3)) & 1; - lfsr = (lfsr >> 1) | (bit << 7); - sample = lfsr; - } else if (tone_shape == 7) { // taps: 7 6; feedback polynomial: x^7 + x^6 + 1 , Periode 127 = 2^n-1,it generates armonincs n x 10Khz - bit = ((lfsr >> 1) ^ (lfsr >> 2)) & 1; - lfsr = (lfsr >> 1) | (bit << 7); - sample = lfsr; - } else if (tone_shape == 8) { //taps:8,6,5,4;feedback polynomial: x^8 + x^6 + x^5 + x^4 + 1,Periode 255= 2^n-1, armonics n x 5khz - bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1; - lfsr = (lfsr >> 1) | (bit << 7); - sample = lfsr; - } else if (tone_shape == 9) { // 16 bits LFSR .taps: 16, 15, 13, 4 ;feedback polynomial: x^16 + x^15 + x^13 + x^4 + 1 + // 16 bits LFSR .taps: 16, 15, 13, 4 ;feedback polynomial: x^16 + x^15 + x^13 + x^4 + 1 // Periode 65535= 2^n-1, harmonics every < 1Khz , quite continuous . if (counter == 0) { bit_16 = ((lfsr_16 >> 0) ^ (lfsr_16 >> 1) ^ (lfsr_16 >> 3) ^ (lfsr_16 >> 4) ^ (lfsr_16 >> 12) & 1); @@ -87,6 +75,20 @@ void SigGenProcessor::execute(const buffer_c8_t& buffer) { counter = 0; } } + + /* else if (tone_shape == 7) { // 8 bit options, finally not used- + bit = ((lfsr >> 2) ^ (lfsr >> 3)) & 1; // taps: 6 5; feedback polynomial: x^6 + x^5 + 1 , Periode 63 = 2^n-1,it generates armonincs n x 20Khz + lfsr = (lfsr >> 1) | (bit << 7); + sample = lfsr; + } else if (tone_shape == 8) { // taps: 7 6; feedback polynomial: x^7 + x^6 + 1 , Periode 127 = 2^n-1,it generates armonincs n x 10Khz + bit = ((lfsr >> 1) ^ (lfsr >> 2)) & 1; + lfsr = (lfsr >> 1) | (bit << 7); + sample = lfsr; + } else if (tone_shape == 9) { //taps:8,6,5,4;feedback polynomial: x^8 + x^6 + x^5 + x^4 + 1,Periode 255= 2^n-1, armonics n x 5khz + bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1; + lfsr = (lfsr >> 1) | (bit << 7); + sample = lfsr; } */ + if (tone_shape < 6) { tone_phase += tone_delta; @@ -125,7 +127,7 @@ void SigGenProcessor::on_message(const Message* const msg) { fm_delta = message.bw * (0xFFFFFFULL / 1536000); tone_shape = message.shape; - lfsr = seed_value ; // init lfsr 8 bits. + // lfsr = seed_value ; // Finally not used , init lfsr 8 bits. lfsr_16 = seed_value_16; // init lfsr 16 bits. configured = true; diff --git a/firmware/baseband/proc_siggen.hpp b/firmware/baseband/proc_siggen.hpp index 84c6b896..0bbcf36f 100644 --- a/firmware/baseband/proc_siggen.hpp +++ b/firmware/baseband/proc_siggen.hpp @@ -42,13 +42,13 @@ private: uint8_t tone_shape { }; uint32_t sample_count { 0 }; bool auto_off { }; - int32_t phase { 0 }, sphase { 0 }, delta { 0 }; // they may have sign . - int8_t sample { 0 }, re { 0 }, im { 0 }; // they may have sign . - uint8_t seed_value = {0x56}; // seed 8 bits lfsr : any nonzero start state will work. - uint16_t seed_value_16 = {0xACE1}; // seed 16 bits lfsr : any nonzero start state will work. - uint8_t lfsr { }, bit { }; // bit must be 8-bit to allow bit<<7 later in the code */ - uint16_t lfsr_16 { }, bit_16 { }; // bit must be 8-bit to allow bit<<7 later in the code */ + int32_t phase { 0 }, sphase { 0 }, delta { 0 }; // they may have sign in the pseudo random sample generation. + int8_t sample { 0 }, re { 0 }, im { 0 }; // they have sign + and -. + uint16_t seed_value_16 = {0xACE1}; // seed 16 bits lfsr : any nonzero start state will work. + uint16_t lfsr_16 { }, bit_16 { }; // bit must be 16-bit to allow bit<<15 later in the code */ uint8_t counter {0}; + // uint8_t seed_value = {0x56}; // Finally not used lfsr of 8 bits , seed 8blfsr : any nonzero start state will work. + // uint8_t lfsr { }, bit { }; // Finally not used lfsr of 8 bits , bit must be 8-bit to allow bit<<7 later in the code */ TXProgressMessage txprogress_message { }; }; From 5a336d5e71c8ad5613ba0676f750daa22e1acd9a Mon Sep 17 00:00:00 2001 From: Brumi-2021 Date: Wed, 3 May 2023 13:49:50 +0200 Subject: [PATCH 4/4] Compact with unique, best Noise Gererator option. --- firmware/application/apps/ui_siggen.hpp | 2 +- firmware/baseband/proc_siggen.cpp | 41 ++++++++++--------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/firmware/application/apps/ui_siggen.hpp b/firmware/application/apps/ui_siggen.hpp index 31954375..bb00ec41 100644 --- a/firmware/application/apps/ui_siggen.hpp +++ b/firmware/application/apps/ui_siggen.hpp @@ -55,7 +55,7 @@ private: "Saw up signal ", "Saw down signal", "Square signal ", - "White Noise " // using 16 bits LFSR register, 16 order polynomial feedback. + "Noise signal " // using 16 bits LFSR register, 16 order polynomial feedback. }; bool auto_update { false }; diff --git a/firmware/baseband/proc_siggen.cpp b/firmware/baseband/proc_siggen.cpp index 810477cf..ea796301 100644 --- a/firmware/baseband/proc_siggen.cpp +++ b/firmware/baseband/proc_siggen.cpp @@ -61,36 +61,29 @@ void SigGenProcessor::execute(const buffer_c8_t& buffer) { } else if (tone_shape == 5) { // Square sample = (((tone_phase & 0xFF000000) >> 24) & 0x80) ? 127 : -128; - } else if (tone_shape == 6) { // White Noise generator, pseudo random noise generator, 8 bits linear-feedback shift register (LFSR) algorithm, variant Fibonacci. + } else if (tone_shape == 6) { + // Noise generator, pseudo random noise generator, 16 bits linear-feedback shift register (LFSR) algorithm, variant Fibonacci. // https://en.wikipedia.org/wiki/Linear-feedback_shift_register // 16 bits LFSR .taps: 16, 15, 13, 4 ;feedback polynomial: x^16 + x^15 + x^13 + x^4 + 1 - // Periode 65535= 2^n-1, harmonics every < 1Khz , quite continuous . - if (counter == 0) { + // Periode 65535= 2^n-1, quite continuous . + if (counter == 0) { // we slow down the shift register, because the pseudo random noise clock freq was too high for modulator. bit_16 = ((lfsr_16 >> 0) ^ (lfsr_16 >> 1) ^ (lfsr_16 >> 3) ^ (lfsr_16 >> 4) ^ (lfsr_16 >> 12) & 1); lfsr_16 = (lfsr_16 >> 1) | (bit_16 << 15); - sample = (lfsr_16 & 0x00FF); - counter++; - } else { // counter == 1 , no need to shift the register again, just use the top 8 bits. - // sample = ((lfsr_16 & 0XFF00) >> 8); // it becomes less continuous the spectrum. Better skip it . - counter = 0; + sample = (lfsr_16 & 0x00FF); // main pseudo random noise generator. + } + if (counter == 5) { // after many empiric test, that combination mix of >>4 and >>5, gives a reasonable trade off white noise / good rf power level . + sample = ((lfsr_16 & 0b0000111111110000) >> 4); // just changing the spectrum shape . } - } - - /* else if (tone_shape == 7) { // 8 bit options, finally not used- - bit = ((lfsr >> 2) ^ (lfsr >> 3)) & 1; // taps: 6 5; feedback polynomial: x^6 + x^5 + 1 , Periode 63 = 2^n-1,it generates armonincs n x 20Khz - lfsr = (lfsr >> 1) | (bit << 7); - sample = lfsr; - } else if (tone_shape == 8) { // taps: 7 6; feedback polynomial: x^7 + x^6 + 1 , Periode 127 = 2^n-1,it generates armonincs n x 10Khz - bit = ((lfsr >> 1) ^ (lfsr >> 2)) & 1; - lfsr = (lfsr >> 1) | (bit << 7); - sample = lfsr; - } else if (tone_shape == 9) { //taps:8,6,5,4;feedback polynomial: x^8 + x^6 + x^5 + x^4 + 1,Periode 255= 2^n-1, armonics n x 5khz - bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1; - lfsr = (lfsr >> 1) | (bit << 7); - sample = lfsr; } */ + if (counter == 10) { + sample = ((lfsr_16 & 0b0001111111100000) >> 5); // just changing the spectrum shape . + } + counter++; + if (counter ==15) { + counter=0; + } + } - - if (tone_shape < 6) { + if (tone_shape < 6) { // we are in periodic signals, we need tone phases update. tone_phase += tone_delta; }