diff --git a/firmware/application/apps/gps_sim_app.cpp b/firmware/application/apps/gps_sim_app.cpp index 09267203..071e7ae6 100644 --- a/firmware/application/apps/gps_sim_app.cpp +++ b/firmware/application/apps/gps_sim_app.cpp @@ -173,6 +173,8 @@ GpsSimAppView::GpsSimAppView( &waterfall, }); + transmitter_model.set_baseband_bandwidth(15'000'000); // GPS L1 signal use to have wide band spectrum, still with lobule energy -30dB's at + - 15 Mhz + if (!settings_.radio_loaded()) { field_frequency.set_value(initial_target_frequency); transmitter_model.set_sampling_rate(2600000); diff --git a/firmware/application/apps/soundboard_app.cpp b/firmware/application/apps/soundboard_app.cpp index 2431e6c7..90f52155 100644 --- a/firmware/application/apps/soundboard_app.cpp +++ b/firmware/application/apps/soundboard_app.cpp @@ -120,6 +120,7 @@ void SoundBoardView::start_tx(const uint32_t id) { ); baseband::set_sample_rate(sample_rate); + transmitter_model.set_baseband_bandwidth(1'750'000); // the Minimum TX LPF 1M75 is fine. transmitter_model.enable(); tx_view.set_transmitting(true); diff --git a/firmware/application/apps/ui_adsb_tx.cpp b/firmware/application/apps/ui_adsb_tx.cpp index 913bbd6b..79581bdb 100644 --- a/firmware/application/apps/ui_adsb_tx.cpp +++ b/firmware/application/apps/ui_adsb_tx.cpp @@ -296,6 +296,10 @@ void ADSBTxView::generate_frames() { void ADSBTxView::start_tx() { generate_frames(); + /* Already tested , with SDR Angel + another Hackrf RX and dump1090 + SDR RLT. Final conclusion is TX LPF 6 Mhz is + * the best settings to fulfill ADSB transponder spectrum mask requirements (<=-20 dB's at +-7Mhz , <=-40 dB's at +-23Mhz ) + * and not showing any ADSB data decoding degradation.*/ + transmitter_model.set_baseband_bandwidth(6'000'000); // best settings for ADSB TX. transmitter_model.enable(); baseband::set_adsb(); diff --git a/firmware/application/apps/ui_aprs_tx.cpp b/firmware/application/apps/ui_aprs_tx.cpp index e5c6c79e..a9f0ea4d 100644 --- a/firmware/application/apps/ui_aprs_tx.cpp +++ b/firmware/application/apps/ui_aprs_tx.cpp @@ -57,6 +57,7 @@ void APRSTXView::start_tx() { // uint8_t * bb_data_ptr = shared_memory.bb_data.data; // text_payload.set(to_string_hex_array(bb_data_ptr + 56, 15)); + transmitter_model.set_baseband_bandwidth(1'750'000); // APRS Automatic Packet Reporting System (APRS).AFSK with NBFM , max BW= 12k5 , then TX LPF min 1M75 transmitter_model.enable(); baseband::set_afsk_data( diff --git a/firmware/application/apps/ui_coasterp.cpp b/firmware/application/apps/ui_coasterp.cpp index 9849b3d9..78431201 100644 --- a/firmware/application/apps/ui_coasterp.cpp +++ b/firmware/application/apps/ui_coasterp.cpp @@ -67,6 +67,7 @@ void CoasterPagerView::generate_frame() { void CoasterPagerView::start_tx() { generate_frame(); + transmitter_model.set_baseband_bandwidth(1'750'000); // AFSK narrowband ,low baud, max FM dev 150khz , std 10khz. TX LPF=1M75 the min. transmitter_model.enable(); baseband::set_fsk_data(19 * 8, 2280000 / 1000, 5000, 32); diff --git a/firmware/application/apps/ui_jammer.cpp b/firmware/application/apps/ui_jammer.cpp index 36fe9171..50945cb4 100644 --- a/firmware/application/apps/ui_jammer.cpp +++ b/firmware/application/apps/ui_jammer.cpp @@ -261,6 +261,7 @@ void JammerView::start_tx() { transmitter_model.set_rf_amp(field_amp.value()); transmitter_model.set_tx_gain(field_gain.value()); + transmitter_model.set_baseband_bandwidth(28'000'000); // Although tx is narrowband , let's use Max TX LPF . transmitter_model.enable(); baseband::set_jammer(true, (JammerType)options_type.selected_index(), options_speed.selected_index_value()); @@ -288,7 +289,8 @@ void JammerView::on_timer() { mscounter = 0; if (jamming) { if (cooling) { - if (++seconds >= field_timepause.value()) { // Re-start TX + if (++seconds >= field_timepause.value()) { // Re-start TX + transmitter_model.set_baseband_bandwidth(28'000'000); // Although tx is narrowband , let's use Max TX LPF . transmitter_model.enable(); button_transmit.set_text("STOP"); baseband::set_jammer(true, (JammerType)options_type.selected_index(), options_speed.selected_index_value()); diff --git a/firmware/application/apps/ui_mictx.cpp b/firmware/application/apps/ui_mictx.cpp index 441e4956..1706afc0 100644 --- a/firmware/application/apps/ui_mictx.cpp +++ b/firmware/application/apps/ui_mictx.cpp @@ -87,6 +87,10 @@ void MicTXView::set_tx(bool enable) { transmitting = true; configure_baseband(); transmitter_model.set_target_frequency(tx_frequency); // Now, no need: transmitter_model.set_tx_gain(tx_gain), nor (rf_amp); + + /* The max. Power Spectrum Densitiy in WFM with High tone mod level (80%) and high 32kHZ subtone as fmod. with max fdeviation 150k , + BW aprox = 2 *(150K + 32K) = 364khz, then we just select the minimum TX LPF 1M75. */ + transmitter_model.set_baseband_bandwidth(1'750'000); transmitter_model.enable(); portapack::pin_i2s0_rx_sda.mode(3); // This is already done in audio::init but gets changed by the CPLD overlay reprogramming } else { diff --git a/firmware/application/apps/ui_playlist.cpp b/firmware/application/apps/ui_playlist.cpp index 84df769b..88027593 100644 --- a/firmware/application/apps/ui_playlist.cpp +++ b/firmware/application/apps/ui_playlist.cpp @@ -273,7 +273,7 @@ void PlaylistView::send_current_track() { // ReplayThread starts immediately on construction; must be set before creating. transmitter_model.set_target_frequency(current()->metadata.center_frequency); transmitter_model.set_sampling_rate(get_actual_sample_rate(current()->metadata.sample_rate)); - transmitter_model.set_baseband_bandwidth(baseband_bandwidth); + transmitter_model.set_baseband_bandwidth(current()->metadata.sample_rate <= 500'000 ? 1'750'000 : 2'500'000); // TX LPF min 1M75 for SR <=500K, and 2M5 (by experimental test) for SR >500K transmitter_model.enable(); // Reset the transmit progress bar. diff --git a/firmware/application/apps/ui_playlist.hpp b/firmware/application/apps/ui_playlist.hpp index e77dcc66..b2b35f2d 100644 --- a/firmware/application/apps/ui_playlist.hpp +++ b/firmware/application/apps/ui_playlist.hpp @@ -60,7 +60,6 @@ class PlaylistView : public View { // More header == less spectrum view. static constexpr ui::Dim header_height = 6 * 16; - static constexpr uint32_t baseband_bandwidth = 2'500'000; struct playlist_entry { std::filesystem::path path{}; diff --git a/firmware/application/apps/ui_rds.cpp b/firmware/application/apps/ui_rds.cpp index a17e7a59..387d5b0e 100644 --- a/firmware/application/apps/ui_rds.cpp +++ b/firmware/application/apps/ui_rds.cpp @@ -187,6 +187,7 @@ void RDSView::start_tx() { else frame_datetime.clear(); + transmitter_model.set_baseband_bandwidth(1'750'000); // Big Spectrum harmonics reduction, and now quicker decoding time. transmitter_model.enable(); tx_thread = std::make_unique(frames); diff --git a/firmware/application/hw/max2837.cpp b/firmware/application/hw/max2837.cpp index 08351d24..71187980 100644 --- a/firmware/application/hw/max2837.cpp +++ b/firmware/application/hw/max2837.cpp @@ -122,7 +122,7 @@ void MAX2837::init() { _map.r.lpf_1.LPF_EN = 1; /* Enable low-pass filter */ _map.r.lpf_1.ModeCtrl = 0b01; /* Rx LPF */ - _map.r.lpf_1.FT = 0b0000; /* 5MHz LPF */ + _map.r.lpf_1.FT = 0b0000; /* 1,75MHz LPF */ _map.r.spi_en.EN_SPI = 1; /* enable chip functions when ENABLE pin set */ @@ -233,10 +233,28 @@ void MAX2837::set_vga_gain(const int_fast8_t db) { flush(); } -void MAX2837::set_lpf_rf_bandwidth(const uint32_t bandwidth_minimum) { +void MAX2837::set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum) { + _map.r.lpf_1.ModeCtrl = 0b01; /* Address reg 2, D3-D2, Set mode lowpass filter block to Rx LPF . Active when Address 6 D<9> = 1 */ _map.r.lpf_1.FT = filter::bandwidth_ordinal(bandwidth_minimum); - _dirty[Register::LPF_1] = 1; - flush(); + flush_one(Register::LPF_1); + + _map.r.vga_3_rx_top.LPF_MODE_SEL = 1; /* Address 6 reg, D9 bit:LPF mode mux, LPF_MODE_SEL 0 = Normal operation, 1 = Operating mode is programmed Address 2 D3:D2*/ + flush_one(Register::VGA_3_RX_TOP); + + _map.r.vga_3_rx_top.LPF_MODE_SEL = 0; /* Leave LPF_MODE_SEL 0 = Normal operation */ + flush_one(Register::VGA_3_RX_TOP); +} + +void MAX2837::set_lpf_rf_bandwidth_tx(const uint32_t bandwidth_minimum) { + _map.r.lpf_1.ModeCtrl = 0b10; /* Address 2 reg, D3-D2, Set mode lowpass filter block to Tx LPF . Active when Address 6 D<9> = 1 */ + _map.r.lpf_1.FT = filter::bandwidth_ordinal(bandwidth_minimum); + flush_one(Register::LPF_1); + + _map.r.vga_3_rx_top.LPF_MODE_SEL = 1; /* Address 6 reg, D9 bit:LPF mode mux, LPF_MODE_SEL 0 = Normal operation, 1 = Operating mode is programmed Address 2 D3:D2*/ + flush_one(Register::VGA_3_RX_TOP); + + _map.r.vga_3_rx_top.LPF_MODE_SEL = 0; /* Leave LPF_MODE_SEL 0 = Normal operation */ + flush_one(Register::VGA_3_RX_TOP); } bool MAX2837::set_frequency(const rf::Frequency lo_frequency) { diff --git a/firmware/application/hw/max2837.hpp b/firmware/application/hw/max2837.hpp index 3fd060f2..35ad59f8 100644 --- a/firmware/application/hw/max2837.hpp +++ b/firmware/application/hw/max2837.hpp @@ -783,7 +783,8 @@ class MAX2837 : public MAX283x { void set_tx_vga_gain(const int_fast8_t db) override; void set_lna_gain(const int_fast8_t db) override; void set_vga_gain(const int_fast8_t db) override; - void set_lpf_rf_bandwidth(const uint32_t bandwidth_minimum) override; + void set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum) override; + void set_lpf_rf_bandwidth_tx(const uint32_t bandwidth_minimum) override; #if 0 void rx_cal() { _map.r.spi_en.EN_SPI = 1; diff --git a/firmware/application/hw/max2839.cpp b/firmware/application/hw/max2839.cpp index bb229e6b..c207adf1 100644 --- a/firmware/application/hw/max2839.cpp +++ b/firmware/application/hw/max2839.cpp @@ -278,10 +278,32 @@ void MAX2839::set_vga_gain(const int_fast8_t db) { configure_rx_gain(); } -void MAX2839::set_lpf_rf_bandwidth(const uint32_t bandwidth_minimum) { +void MAX2839::set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum) { + _map.r.lpf_vga_1.ModeCtrl = 0b01; /* Address reg 5, D9-D8, Set mode lowpass filter block to Rx LPF . Active when Address 8 D<2> = 1 */ + flush_one(Register::LPF_VGA_1); + + _map.r.rx_top_1.LPF_MODE_SEL = 1; /* Address 8 reg, D2 bit:LPF mode mux, LPF_MODE_SEL 0 = Normal operation, 1 = Operating mode is programmed Address 5 D<9:8> */ + flush_one(Register::RX_TOP_1); + _map.r.lpf.FT = filter::bandwidth_ordinal(bandwidth_minimum); - _dirty[Register::LPF] = 1; - flush(); + flush_one(Register::LPF); + + _map.r.rx_top_1.LPF_MODE_SEL = 0; /* Address 8 reg, D2 bit:LPF mode mux, LPF_MODE_SEL 0 = Normal operation, 1 = Operating mode is programmed Address 5 D<9:8> */ + flush_one(Register::RX_TOP_1); /* Leave LPF_MODE_SEL 0 = Normal operation */ +} + +void MAX2839::set_lpf_rf_bandwidth_tx(const uint32_t bandwidth_minimum) { + _map.r.lpf_vga_1.ModeCtrl = 0b10; /* Address reg 5, D9-D8, Set mode lowpass filter block to Tx LPF . Active when Address 8 D<2> = 1 */ + flush_one(Register::LPF_VGA_1); + + _map.r.rx_top_1.LPF_MODE_SEL = 1; /* Address 8 reg, D2 bit:LPF mode mux, LPF_MODE_SEL 0 = Normal operation, 1 = Operating mode is programmed Address 5 D<9:8> */ + flush_one(Register::RX_TOP_1); + + _map.r.lpf.FT = filter::bandwidth_ordinal(bandwidth_minimum); + flush_one(Register::LPF); + + _map.r.rx_top_1.LPF_MODE_SEL = 0; /* Address 8 reg, D2 bit:LPF mode mux, LPF_MODE_SEL 0 = Normal operation, 1 = Operating mode is programmed Address 5 D<9:8> */ + flush_one(Register::RX_TOP_1); /* Leave LPF_MODE_SEL 0 = Normal operation */ } bool MAX2839::set_frequency(const rf::Frequency lo_frequency) { diff --git a/firmware/application/hw/max2839.hpp b/firmware/application/hw/max2839.hpp index ac75db6e..fd919068 100644 --- a/firmware/application/hw/max2839.hpp +++ b/firmware/application/hw/max2839.hpp @@ -686,7 +686,8 @@ class MAX2839 : public MAX283x { void set_tx_vga_gain(const int_fast8_t db) override; void set_lna_gain(const int_fast8_t db) override; void set_vga_gain(const int_fast8_t db) override; - void set_lpf_rf_bandwidth(const uint32_t bandwidth_minimum) override; + void set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum) override; + void set_lpf_rf_bandwidth_tx(const uint32_t bandwidth_minimum) override; bool set_frequency(const rf::Frequency lo_frequency) override; void set_rx_lo_iq_calibration(const size_t v) override; void set_rx_buff_vcm(const size_t v) override; diff --git a/firmware/application/hw/max283x.hpp b/firmware/application/hw/max283x.hpp index e997ea69..5e75e531 100644 --- a/firmware/application/hw/max283x.hpp +++ b/firmware/application/hw/max283x.hpp @@ -123,7 +123,8 @@ class MAX283x { virtual void set_tx_vga_gain(const int_fast8_t db); virtual void set_lna_gain(const int_fast8_t db); virtual void set_vga_gain(const int_fast8_t db); - virtual void set_lpf_rf_bandwidth(const uint32_t bandwidth_minimum); + virtual void set_lpf_rf_bandwidth_rx(const uint32_t bandwidth_minimum); + virtual void set_lpf_rf_bandwidth_tx(const uint32_t bandwidth_minimum); virtual bool set_frequency(const rf::Frequency lo_frequency); diff --git a/firmware/application/radio.cpp b/firmware/application/radio.cpp index ea5f07a3..0408cfac 100644 --- a/firmware/application/radio.cpp +++ b/firmware/application/radio.cpp @@ -232,8 +232,12 @@ void set_tx_gain(const int_fast8_t db) { second_if->set_tx_vga_gain(db); } -void set_baseband_filter_bandwidth(const uint32_t bandwidth_minimum) { - second_if->set_lpf_rf_bandwidth(bandwidth_minimum); +void set_baseband_filter_bandwidth_rx(const uint32_t bandwidth_minimum) { + second_if->set_lpf_rf_bandwidth_rx(bandwidth_minimum); +} + +void set_baseband_filter_bandwidth_tx(const uint32_t bandwidth_minimum) { + second_if->set_lpf_rf_bandwidth_tx(bandwidth_minimum); } void set_baseband_rate(const uint32_t rate) { diff --git a/firmware/application/radio.hpp b/firmware/application/radio.hpp index 03412630..fca124cd 100644 --- a/firmware/application/radio.hpp +++ b/firmware/application/radio.hpp @@ -50,7 +50,8 @@ void set_rf_amp(const bool rf_amp); void set_lna_gain(const int_fast8_t db); void set_vga_gain(const int_fast8_t db); void set_tx_gain(const int_fast8_t db); -void set_baseband_filter_bandwidth(const uint32_t bandwidth_minimum); +void set_baseband_filter_bandwidth_rx(const uint32_t bandwidth_minimum); +void set_baseband_filter_bandwidth_tx(const uint32_t bandwidth_minimum); void set_baseband_rate(const uint32_t rate); void set_antenna_bias(const bool on); diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index d490356f..0c0044a2 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -270,7 +270,7 @@ void ReceiverModel::update_tuning_frequency() { } void ReceiverModel::update_baseband_bandwidth() { - radio::set_baseband_filter_bandwidth(baseband_bandwidth()); + radio::set_baseband_filter_bandwidth_rx(baseband_bandwidth()); } void ReceiverModel::update_sampling_rate() { diff --git a/firmware/application/transmitter_model.cpp b/firmware/application/transmitter_model.cpp index 159da018..e2cedb3c 100644 --- a/firmware/application/transmitter_model.cpp +++ b/firmware/application/transmitter_model.cpp @@ -139,7 +139,7 @@ void TransmitterModel::update_tuning_frequency() { } void TransmitterModel::update_baseband_bandwidth() { - radio::set_baseband_filter_bandwidth(baseband_bandwidth()); + radio::set_baseband_filter_bandwidth_tx(baseband_bandwidth()); } void TransmitterModel::update_sampling_rate() {