diff --git a/firmware/application/apps/ui_about_simple.cpp b/firmware/application/apps/ui_about_simple.cpp index f527b4853..6af138ba1 100644 --- a/firmware/application/apps/ui_about_simple.cpp +++ b/firmware/application/apps/ui_about_simple.cpp @@ -31,8 +31,9 @@ namespace ui console.writeln("N0vaPixel,klockee,GullCode"); console.writeln("jamesshao8,ITAxReal,rascafr"); console.writeln("mcules,dqs105,strijar"); - console.writeln("zhang00963,RedFox-Fr"); + console.writeln("zhang00963,RedFox-Fr,aldude999"); console.writeln("East2West,fossum,ArjanOnwezen"); + console.writeln("vXxOinvizioNxX,teixeluis"); console.writeln(""); break; diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index b91771b4c..25667fe63 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -20,6 +20,7 @@ * Boston, MA 02110-1301, USA. */ +#include #include "ui_adsb_rx.hpp" #include "ui_alphanum.hpp" @@ -234,49 +235,38 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { entry.set_frame_pos(frame, raw_data[6] & 4); if (entry.pos.valid) { - std::string latitude_str(8, '\0'); - std::string longitude_str(8, '\0'); - - int written = std::snprintf(&latitude_str[0], latitude_str.size(), "%.2f", entry.pos.latitude); - latitude_str.resize(written); - - written = std::snprintf(&longitude_str[0], longitude_str.size(), "%.2f", entry.pos.longitude); - longitude_str.resize(written); - str_info = "Alt:" + to_string_dec_int(entry.pos.altitude) + - " Lat:" + latitude_str + - " Lon:" + longitude_str; + " Lat:" + to_string_decimal(entry.pos.latitude, 2) + + " Lon:" + to_string_decimal(entry.pos.longitude, 2); // printing the coordinates in the log file with more // resolution, as we are not constrained by screen // real estate there: - latitude_str.resize(13, '\0'); - longitude_str.resize(13, '\0'); - - written = std::snprintf(&latitude_str[0], latitude_str.size(), "%.7f", entry.pos.latitude); - latitude_str.resize(written); - - written = std::snprintf(&longitude_str[0], longitude_str.size(), "%.7f", entry.pos.longitude); - longitude_str.resize(written); - std::string log_info = "Alt:" + to_string_dec_int(entry.pos.altitude) + - " Lat:" + latitude_str + - " Lon:" + longitude_str; + " Lat:" + to_string_decimal(entry.pos.latitude, 7) + + " Lon:" + to_string_decimal(entry.pos.longitude, 7); entry.set_info_string(str_info); logentry+=log_info + " "; - if (send_updates) + // we only want to update the details view if the frame + // we received has the same ICAO address, i.e. belongs to + // the same aircraft: + if(send_updates && details_view->get_current_entry().ICAO_address == ICAO_address) { details_view->update(entry); + } } } else if(msg_type == AIRBORNE_VEL && msg_sub >= VEL_GND_SUBSONIC && msg_sub <= VEL_AIR_SUPERSONIC){ entry.set_frame_velo(frame); logentry += "Type:" + to_string_dec_uint(msg_sub) + " Hdg:" + to_string_dec_uint(entry.velo.heading) + " Spd: "+ to_string_dec_int(entry.velo.speed); - if (send_updates) + + // same here: + if (send_updates && details_view->get_current_entry().ICAO_address == ICAO_address) { details_view->update(entry); + } } } recent_entries_view.set_dirty(); diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index a63b7eb26..c55ec6805 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -161,6 +161,8 @@ public: void update(const AircraftRecentEntry& entry); std::string title() const override { return "Details"; }; + + AircraftRecentEntry get_current_entry() { return entry_copy; } private: AircraftRecentEntry entry_copy { 0 }; diff --git a/firmware/application/radio.cpp b/firmware/application/radio.cpp index 60981c70e..617f22ac7 100644 --- a/firmware/application/radio.cpp +++ b/firmware/application/radio.cpp @@ -111,14 +111,12 @@ void set_direction(const rf::Direction new_direction) { // Hack to fix the CPLD (clocking ?) bug: toggle CPLD SRAM overlay depending on new direction // Use CPLD's EEPROM config when transmitting // Use the SRAM overlay when receiving - if (direction != new_direction) { - if (new_direction == rf::Direction::Transmit) { - hackrf::cpld::init_from_eeprom(); - } else { - if( !hackrf::cpld::load_sram() ) { - chSysHalt(); - } - } + + // teixeluis: undone "Hack to fix the CPLD (clocking ?) bug". + // Apparently with current CPLD code from the hackrf repo, + // toggling CPLD overlay should no longer be necessary: + if (direction != new_direction && new_direction == rf::Direction::Transmit) { + hackrf::cpld::init_from_eeprom(); } direction = new_direction; diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index c3216654e..bef08025e 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -171,7 +171,11 @@ void ReceiverModel::enable() { update_baseband_bandwidth(); update_sampling_rate(); update_modulation(); + + // TODO: would challenge if this should belong to the + // receiver_model namespace: update_headphone_volume(); + led_rx.on(); } @@ -182,6 +186,10 @@ void ReceiverModel::disable() { // TODO: Responsibility for enabling/disabling the radio is muddy. // Some happens in ReceiverModel, some inside radio namespace. radio::disable(); + + // TODO: we are doing this repeatedly in different levels of the + // call stack. Keeping it for now, but there seem to be too many + // redundant calls: led_rx.off(); } diff --git a/firmware/application/string_format.cpp b/firmware/application/string_format.cpp index 1aa365e68..22b02d0b8 100644 --- a/firmware/application/string_format.cpp +++ b/firmware/application/string_format.cpp @@ -112,6 +112,23 @@ std::string to_string_dec_int( return q; } +std::string to_string_decimal(float decimal, int8_t precision) { + double integer_part; + double fractional_part; + + std::string result; + + fractional_part = modf(decimal, &integer_part) * pow(10, precision); + + if (fractional_part < 0) { + fractional_part = -fractional_part; + } + + result = to_string_dec_int(integer_part) + "." + to_string_dec_uint(fractional_part, precision, '0'); + + return result; +} + std::string to_string_short_freq(const uint64_t f) { auto final_str = to_string_dec_int(f / 1000000,4) + "." + to_string_dec_int((f / 100) % 10000, 4, '0'); return final_str; diff --git a/firmware/application/string_format.hpp b/firmware/application/string_format.hpp index 0555db8e4..a588ef959 100644 --- a/firmware/application/string_format.hpp +++ b/firmware/application/string_format.hpp @@ -43,6 +43,8 @@ const char unit_prefix[7] { 'n', 'u', 'm', 0, 'k', 'M', 'G' }; std::string to_string_bin(const uint32_t n, const uint8_t l = 0); std::string to_string_dec_uint(const uint32_t n, const int32_t l = 0, const char fill = ' '); std::string to_string_dec_int(const int32_t n, const int32_t l = 0, const char fill = 0); +std::string to_string_decimal(float decimal, int8_t precision); + std::string to_string_hex(const uint64_t n, const int32_t l = 0); std::string to_string_hex_array(uint8_t * const array, const int32_t l = 0); diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index 0f4809dc8..1d09880df 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -63,17 +63,9 @@ GeoPos::GeoPos( const auto changed_fn = [this](int32_t) { float lat_value = lat(); float lon_value = lon(); - double integer_part; - double fractional_part; - - fractional_part = modf(lat_value, &integer_part) * 100000; - if (fractional_part < 0) - fractional_part = -fractional_part; - text_lat_decimal.set(to_string_dec_int(integer_part) + "." + to_string_dec_uint(fractional_part, 5)); - fractional_part = modf(lon_value, &integer_part) * 100000; - if (fractional_part < 0) - fractional_part = -fractional_part; - text_lon_decimal.set(to_string_dec_int(integer_part) + "." + to_string_dec_uint(fractional_part, 5)); + + text_lat_decimal.set(to_string_decimal(lat_value, 5)); + text_lon_decimal.set(to_string_decimal(lon_value, 5)); if (on_change && report_change) on_change(altitude(), lat_value, lon_value); diff --git a/firmware/application/ui/ui_transmitter.cpp b/firmware/application/ui/ui_transmitter.cpp index acc305746..6cfb19bf0 100644 --- a/firmware/application/ui/ui_transmitter.cpp +++ b/firmware/application/ui/ui_transmitter.cpp @@ -103,6 +103,7 @@ void TransmitterView::set_transmitting(const bool transmitting) { void TransmitterView::on_show() { field_frequency.set_value(transmitter_model.tuning_frequency()); + field_frequency_step.set_by_value(receiver_model.frequency_step()); field_gain.set_value(transmitter_model.tx_gain()); field_amp.set_value(transmitter_model.rf_amp() ? 14 : 0); @@ -122,6 +123,7 @@ TransmitterView::TransmitterView( add_children({ &field_frequency, + &field_frequency_step, &text_gain, &field_gain, &button_start, @@ -157,6 +159,10 @@ TransmitterView::TransmitterView( if (on_edit_frequency) on_edit_frequency(); }; + + field_frequency_step.on_change = [this](size_t, OptionsField::value_t v) { + this->field_frequency.set_step(v); + }; field_gain.on_change = [this](uint32_t tx_gain) { on_tx_gain_changed(tx_gain); diff --git a/firmware/application/ui/ui_transmitter.hpp b/firmware/application/ui/ui_transmitter.hpp index da5ce7998..e38aea834 100644 --- a/firmware/application/ui/ui_transmitter.hpp +++ b/firmware/application/ui/ui_transmitter.hpp @@ -124,11 +124,11 @@ private: }; Text text_bw { - { 11 * 8, 1 * 8, 9 * 8, 1 * 16 }, - "BW: kHz" + { 18 * 8, 1 * 8, 3 * 8, 1 * 16 }, + "kHz" }; NumberField field_bw { - { 14 * 8, 1 * 8 }, + { 15 * 8, 1 * 8 }, 3, { 1, 150 }, 1, @@ -152,6 +152,10 @@ private: { 21 * 8, 1 * 8, 9 * 8, 32 }, "START" }; + + FrequencyStepView field_frequency_step { + { 10 * 8 - 4, 1 * 8 }, + }; void on_tuning_frequency_changed(rf::Frequency f); void on_channel_bandwidth_changed(uint32_t channel_bandwidth); diff --git a/firmware/common/adsb.cpp b/firmware/common/adsb.cpp index f43ff4787..d1d117073 100644 --- a/firmware/common/adsb.cpp +++ b/firmware/common/adsb.cpp @@ -160,7 +160,9 @@ int cpr_NL_approx(float lat) { int cpr_NL(float lat) { // TODO prove that the approximate function is good // enough for the precision we need. Uncomment if - // that is true: + // that is true. No performance penalty was noticed + // from testing, but if you find it might be an issue, + // switch to cpr_NL_approx() instead: //return cpr_NL_approx(lat); @@ -199,18 +201,18 @@ void encode_frame_pos(ADSBFrame& frame, const uint32_t ICAO_address, const int32 // CPR encoding // Info from: http://antena.fe.uni-lj.si/literatura/Razno/Avionika/modes/CPRencoding.pdf - delta_lat = 360.0 / ((4.0 * 15.0) - time_parity); // NZ = 15 - yz = floor(131072.0 * (cpr_mod(latitude, delta_lat) / delta_lat) + 0.5); - rlat = delta_lat * ((yz / 131072.0) + floor(latitude / delta_lat)); + delta_lat = 360.0 / ((4.0 * NZ) - time_parity); // NZ = 15 + yz = floor(CPR_MAX_VALUE * (cpr_mod(latitude, delta_lat) / delta_lat) + 0.5); + rlat = delta_lat * ((yz / CPR_MAX_VALUE) + floor(latitude / delta_lat)); if ((cpr_NL(rlat) - time_parity) > 0) delta_lon = 360.0 / cpr_N(rlat, time_parity); else delta_lon = 360.0; - xz = floor(131072.0 * (cpr_mod(longitude, delta_lon) / delta_lon) + 0.5); + xz = floor(CPR_MAX_VALUE * (cpr_mod(longitude, delta_lon) / delta_lon) + 0.5); - lat = cpr_mod(yz, 131072.0); - lon = cpr_mod(xz, 131072.0); + lat = cpr_mod(yz, CPR_MAX_VALUE); + lon = cpr_mod(xz, CPR_MAX_VALUE); frame.push_byte((altitude_coded << 4) | ((uint32_t)time_parity << 2) | (lat >> 15)); // T = 0 frame.push_byte(lat >> 7); diff --git a/firmware/common/adsb.hpp b/firmware/common/adsb.hpp index f3a2f3ac0..7e4d3bce8 100644 --- a/firmware/common/adsb.hpp +++ b/firmware/common/adsb.hpp @@ -85,7 +85,7 @@ const float adsb_lat_lut[58] = { const float PI = 3.14159265358979323846; -const float NZ = 15; +const float NZ = 15.0; void make_frame_adsb(ADSBFrame& frame, const uint32_t ICAO_address);