From 19ebf14e8c0f16f273c64dc39d84efff4bf73590 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Wed, 20 Jan 2021 11:03:39 +0100 Subject: [PATCH 01/52] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a98e2c54..32038c4e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -> ⚠ **BEFORE BUYING YOURS:** Beware of hardware mods that use a custom firmware, which are [NOT COMPATIBLE](https://github.com/eried/portapack-mayhem/issues/264) with older forks, and they do not follow the license. **ASK THE SELLER if the unit works with an specific firmware, for example, pointing to the [![GitHub release (latest by date)](https://img.shields.io/github/v/release/eried/portapack-mayhem?label=latest%20release&style=social)](https://github.com/eried/portapack-mayhem/releases/latest) on this repository** +> ⚠ **BEFORE BUYING YOURS:** ⚠ Beware of hardware mods that use a custom firmware, which are [NOT COMPATIBLE](https://github.com/eried/portapack-mayhem/issues/264) with older forks, and they do not follow the license. **ASK THE SELLER if the unit works with an specific firmware, for example, pointing to the [![GitHub release (latest by date)](https://img.shields.io/github/v/release/eried/portapack-mayhem?label=latest%20release&style=social)](https://github.com/eried/portapack-mayhem/releases/latest) on this repository** # PortaPack Mayhem From 50bab791dd6ac95e5d7e1b46ee59220e5e0c575a Mon Sep 17 00:00:00 2001 From: euquiq <31453004+euquiq@users.noreply.github.com> Date: Mon, 25 Jan 2021 23:41:19 -0300 Subject: [PATCH 02/52] Fix bug on radiosonde Meteoman Lat & lon calculation The underlying function used for calculating Latitude and Longitude -also used in other places inside the radiosonde app- was returning a positive value always. But it needs to cope with negative values also (i.e. Lat and Lon) Fixed by just changing the returning value into int32_t (even if the calculation is done in uint32_t, the actual sign is passed thru when returning the calculated value -those are the same 4 bytes, interpreted either as (before) unsigned or (now) signed) --- firmware/common/field_reader.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/field_reader.hpp b/firmware/common/field_reader.hpp index 03d0a24d..b325546d 100644 --- a/firmware/common/field_reader.hpp +++ b/firmware/common/field_reader.hpp @@ -49,7 +49,7 @@ public: /* The "start_bit" winds up being the MSB of the returned field value. */ /* The BitRemap functor determines which bits are read from the source * packet. */ - uint32_t read(const size_t start_bit, const size_t length) const { + int32_t read(const size_t start_bit, const size_t length) const { //Euquiq: was uint32_t, used for calculating lat / lon in radiosondes, can be negative too uint32_t value = 0; for(size_t i=start_bit; i<(start_bit + length); i++) { value = (value << 1) | data[bit_remap(i)]; From 1c1d3e9897f2d8e80233ca20b24c6d49d2194633 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 14:57:22 +0100 Subject: [PATCH 03/52] missing contructor --- firmware/common/spi_image.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/firmware/common/spi_image.hpp b/firmware/common/spi_image.hpp index 896340be..5ff88054 100644 --- a/firmware/common/spi_image.hpp +++ b/firmware/common/spi_image.hpp @@ -34,6 +34,7 @@ namespace portapack { namespace spi_flash { struct image_tag_t { + constexpr image_tag_t( ) : c { 0, 0, 0, 0 } { @@ -45,6 +46,14 @@ struct image_tag_t { { } + image_tag_t(const image_tag_t& other) + { + c[0] = other.c[0]; + c[1] = other.c[1]; + c[2] = other.c[2]; + c[3] = other.c[3]; + } + image_tag_t& operator=(const image_tag_t& other) { c[0] = other.c[0]; c[1] = other.c[1]; From e75677d366dc3f3951110040eabedd77229af4e3 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:09:02 +0100 Subject: [PATCH 04/52] Moved calibytes and calfrchk to cpp file to avoid unused warning --- firmware/common/sonde_packet.cpp | 3 +++ firmware/common/sonde_packet.hpp | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/common/sonde_packet.cpp b/firmware/common/sonde_packet.cpp index 9b13c486..8eb15a2a 100644 --- a/firmware/common/sonde_packet.cpp +++ b/firmware/common/sonde_packet.cpp @@ -27,6 +27,9 @@ namespace sonde { +static uint8_t calibytes[51*16]; //need these vars to survive +static uint8_t calfrchk[51]; //so subframes are preserved while populated + //Defines for Vaisala RS41, from https://github.com/rs1729/RS/blob/master/rs41/rs41sg.c #define MASK_LEN 64 diff --git a/firmware/common/sonde_packet.hpp b/firmware/common/sonde_packet.hpp index 54227db5..934a2077 100644 --- a/firmware/common/sonde_packet.hpp +++ b/firmware/common/sonde_packet.hpp @@ -32,9 +32,6 @@ namespace sonde { - static uint8_t calibytes[51*16]; //need these vars to survive - static uint8_t calfrchk[51]; //so subframes are preserved while populated - struct GPS_data { uint32_t alt { 0 }; float lat { 0 }; @@ -105,4 +102,4 @@ private: } /* namespace sonde */ -#endif/*__SONDE_PACKET_H__*/ \ No newline at end of file +#endif/*__SONDE_PACKET_H__*/ From 266e3982241bee215f9d4e7e91229aadaeb460a5 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:16:43 +0100 Subject: [PATCH 05/52] Fix __SIMD32 warning --- firmware/baseband/channel_stats_collector.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/baseband/channel_stats_collector.hpp b/firmware/baseband/channel_stats_collector.hpp index ca7d0eed..f1e9061a 100644 --- a/firmware/baseband/channel_stats_collector.hpp +++ b/firmware/baseband/channel_stats_collector.hpp @@ -35,7 +35,7 @@ class ChannelStatsCollector { public: template void feed(const buffer_c16_t& src, Callback callback) { - auto src_p = src.p; + void *src_p = src.p; while(src_p < &src.p[src.count]) { const uint32_t sample = *__SIMD32(src_p)++; const uint32_t mag_sq = __SMUAD(sample, sample); From 6c2950cfe842dc603fa119678fcecac6cd46162e Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:32:46 +0100 Subject: [PATCH 06/52] Fix warning: cast between incompatible function types from 'void (*)(void *)' to 'msg_t (*)(void *)' --- firmware/chibios/os/kernel/src/chsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/chibios/os/kernel/src/chsys.c b/firmware/chibios/os/kernel/src/chsys.c index f26218d6..2bc3110a 100755 --- a/firmware/chibios/os/kernel/src/chsys.c +++ b/firmware/chibios/os/kernel/src/chsys.c @@ -119,7 +119,7 @@ void chSysInit(void) { serve interrupts in its context while keeping the lowest energy saving mode compatible with the system status.*/ chThdCreateStatic(_idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO, - (tfunc_t)_idle_thread, NULL); + (void *)_idle_thread, NULL); #endif } From c3fe053eb20a555ac54c52f8ac225210e564e8ec Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:38:05 +0100 Subject: [PATCH 07/52] Fix adsb warnings --- firmware/common/adsb.cpp | 4 ++-- firmware/common/adsb_frame.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/common/adsb.cpp b/firmware/common/adsb.cpp index 3f8f4c23..862e375d 100644 --- a/firmware/common/adsb.cpp +++ b/firmware/common/adsb.cpp @@ -319,14 +319,14 @@ void encode_frame_velo(ADSBFrame& frame, const uint32_t ICAO_address, const uint // Decoding method from dump1090 adsb_vel decode_frame_velo(ADSBFrame& frame){ - adsb_vel velo {false, 0, 0}; + adsb_vel velo {false, 0, 0, 0}; uint8_t * frame_data = frame.get_raw_data(); uint8_t velo_type = frame.get_msg_sub(); if(velo_type >= 1 && velo_type <= 4){ //vertical rate is always present - velo.v_rate = (((frame_data[8] & 0x07 ) << 6) | ((frame_data[9]) >> 2) - 1) * 64; + velo.v_rate = (((frame_data[8] & 0x07 ) << 6) | ((frame_data[9] >> 2) - 1)) * 64; if((frame_data[8] & 0x8) >> 3) velo.v_rate *= -1; //check v_rate sign } diff --git a/firmware/common/adsb_frame.hpp b/firmware/common/adsb_frame.hpp index a93abe6f..6e5e7096 100644 --- a/firmware/common/adsb_frame.hpp +++ b/firmware/common/adsb_frame.hpp @@ -69,7 +69,7 @@ public: } uint8_t * get_raw_data() const { - return (uint8_t* const)raw_data; + return (uint8_t* )raw_data; } void make_CRC() { From 1483160df49a83026eee1f7a163e964148b902ad Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:45:04 +0100 Subject: [PATCH 08/52] removed unused variables --- firmware/baseband/tv_collector.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/firmware/baseband/tv_collector.cpp b/firmware/baseband/tv_collector.cpp index a18eaf46..d323d36d 100644 --- a/firmware/baseband/tv_collector.cpp +++ b/firmware/baseband/tv_collector.cpp @@ -88,11 +88,9 @@ void TvCollector::post_message(const buffer_c16_t& data) { // Called from baseband processing thread. float re, im; float mag; - float max; if( streaming && !channel_spectrum_request_update ) { for(size_t i=0; i<256; i++) { - const auto s = data.p[i]; re = (float)(data.p[i].real()); im = (float)(data.p[i].imag()); mag = __builtin_sqrtf((re * re) + (im * im)) ; From 961e115cc6162b6eb7095c8eb36440f665eee0a5 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:48:41 +0100 Subject: [PATCH 09/52] fix unused result --- firmware/baseband/proc_capture.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/firmware/baseband/proc_capture.cpp b/firmware/baseband/proc_capture.cpp index 41039484..fe2fddba 100644 --- a/firmware/baseband/proc_capture.cpp +++ b/firmware/baseband/proc_capture.cpp @@ -44,7 +44,11 @@ void CaptureProcessor::execute(const buffer_c8_t& buffer) { if( stream ) { const size_t bytes_to_write = sizeof(*decimator_out.p) * decimator_out.count; - const auto result = stream->write(decimator_out.p, bytes_to_write); + const size_t written = stream->write(decimator_out.p, bytes_to_write); + if( written != bytes_to_write ) + { + //TODO eventually report error somewhere + } } feed_channel_stats(channel); From 3166a667560e542b8ce37aeeb8693b5d852166df Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:52:17 +0100 Subject: [PATCH 10/52] Quoted out unused variable --- firmware/baseband/proc_am_audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/baseband/proc_am_audio.cpp b/firmware/baseband/proc_am_audio.cpp index 23bbbcb1..9934488a 100644 --- a/firmware/baseband/proc_am_audio.cpp +++ b/firmware/baseband/proc_am_audio.cpp @@ -87,7 +87,7 @@ void NarrowbandAMAudio::configure(const AMConfigureMessage& message) { constexpr size_t decim_2_output_fs = decim_2_input_fs / decim_2_decimation_factor; constexpr size_t channel_filter_input_fs = decim_2_output_fs; - const size_t channel_filter_output_fs = channel_filter_input_fs / channel_filter_decimation_factor; + //const size_t channel_filter_output_fs = channel_filter_input_fs / channel_filter_decimation_factor; decim_0.configure(message.decim_0_filter.taps, 33554432); decim_1.configure(message.decim_1_filter.taps, 131072); From 3c14d382864201ec93a150071b3d5b9a75d54409 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:54:45 +0100 Subject: [PATCH 11/52] Added missing initialisation --- firmware/baseband/proc_audiotx.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/baseband/proc_audiotx.hpp b/firmware/baseband/proc_audiotx.hpp index 3f1bace7..2eecc588 100644 --- a/firmware/baseband/proc_audiotx.hpp +++ b/firmware/baseband/proc_audiotx.hpp @@ -50,7 +50,7 @@ private: int32_t sample { 0 }, delta { }; int8_t re { 0 }, im { 0 }; - size_t progress_interval_samples, progress_samples = 0; + size_t progress_interval_samples = 0 , progress_samples = 0; bool configured { false }; uint32_t bytes_read { 0 }; From b7eb095dd840fa1207cb19b4c3bc63d5ee196f27 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 15:58:56 +0100 Subject: [PATCH 12/52] Quoted unused vars and voided one --- firmware/baseband/proc_am_tv.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/firmware/baseband/proc_am_tv.cpp b/firmware/baseband/proc_am_tv.cpp index 4c2c7e9d..c5353a57 100644 --- a/firmware/baseband/proc_am_tv.cpp +++ b/firmware/baseband/proc_am_tv.cpp @@ -43,14 +43,15 @@ void WidebandFMAudio::execute(const buffer_c8_t& buffer) { const buffer_c16_t buffer_c16 {spectrum.data(),spectrum.size(),buffer.sampling_rate}; channel_spectrum.feed(buffer_c16); - int8_t re, im; - int8_t mag; + int8_t re ; + //int8_t im; + //int8_t mag; for (size_t i = 0; i < 128; i++) { re = buffer.p[i].real(); - im = buffer.p[i].imag(); - mag = __builtin_sqrtf((re * re) + (im * im)) ; + //im = buffer.p[i].imag(); + //mag = __builtin_sqrtf((re * re) + (im * im)) ; const unsigned int v = re + 127.0f; //timescope audio_spectrum.db[i] = std::max(0U, std::min(255U, v)); } @@ -75,6 +76,7 @@ void WidebandFMAudio::on_message(const Message* const message) { } void WidebandFMAudio::configure(const WFMConfigureMessage& message) { + (void)message; // avoid warning configured = true; } From 486c1d6bcdc0fad815ca21e031f853499a365c6b Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:02:59 +0100 Subject: [PATCH 13/52] Quoted CRC calculus as it's unused, voided message --- firmware/baseband/proc_btlerx.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/firmware/baseband/proc_btlerx.cpp b/firmware/baseband/proc_btlerx.cpp index f4e15571..66a369ed 100644 --- a/firmware/baseband/proc_btlerx.cpp +++ b/firmware/baseband/proc_btlerx.cpp @@ -53,7 +53,6 @@ void BTLERxProcessor::execute(const buffer_c8_t& buffer) { auto audio_oversampled = demod.execute(buffer_c16, work_audio_buffer);*/ // Audio signal processing for (size_t c = 0; c < audio_oversampled.count; c++) { - int result; /*const int32_t sample_int = audio_oversampled.p[c] * 32768.0f; int32_t current_sample = __SSAT(sample_int, 16); @@ -107,9 +106,9 @@ void BTLERxProcessor::execute(const buffer_c8_t& buffer) { uint8_t packet_data[500]; int packet_length; uint32_t packet_crc; - uint32_t calced_crc; + //uint32_t calced_crc; // NOTE: restore when CRC is passing uint64_t packet_addr_l; - uint32_t result; + //uint32_t result; // NOTE: restore when CRC is passing uint8_t crc[3]; uint8_t packet_header_arr[2]; @@ -255,21 +254,21 @@ void BTLERxProcessor::execute(const buffer_c8_t& buffer) { counter = counter + 1; } for (v=0;v<3;v++) crc_result=(crc_result<<8)|crc[v]; - calced_crc = crc_result; + //calced_crc = crc_result; // NOTE: restore when CRC is passing packet_crc=0; for (int c=0;c<3;c++) packet_crc=(packet_crc<<8)|packet_data[packet_length+2+c]; if (packet_addr_l==0x8E89BED6) - //if (packet_crc==calced_crc) + //if (packet_crc==calced_crc) // NOTE: restore when CRC is passing { uint8_t mac_data[6]; int counter = 0; for (int i = 7; i >= 2; i--) { uint8_t byte_temp6 = (uint8_t) (((packet_data[i] * 0x0802LU & 0x22110LU) | (packet_data[i] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); - //result = byte_temp6; - mac_data[counter] = byte_temp6; + //result = byte_temp6; // NOTE: restore when CRC is passing + mac_data[counter] = byte_temp6; counter = counter + 1; } @@ -325,6 +324,7 @@ void BTLERxProcessor::on_message(const Message* const message) { } void BTLERxProcessor::configure(const BTLERxConfigureMessage& message) { + (void)message; //avoid warning decim_0.configure(taps_200k_wfm_decim_0.taps, 33554432); decim_1.configure(taps_200k_wfm_decim_1.taps, 131072); demod.configure(audio_fs, 5000); From ec520bf08c9600060c9ece51fa062a5c978f70b5 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:07:03 +0100 Subject: [PATCH 14/52] Added missing initialisations --- firmware/baseband/proc_pocsag.hpp | 2 +- firmware/common/pocsag_packet.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/baseband/proc_pocsag.hpp b/firmware/baseband/proc_pocsag.hpp index 2f907b5e..b437aac8 100644 --- a/firmware/baseband/proc_pocsag.hpp +++ b/firmware/baseband/proc_pocsag.hpp @@ -95,7 +95,7 @@ private: bool configured = false; rx_states rx_state { WAITING }; pocsag::BitRate bitrate { pocsag::BitRate::FSK1200 }; - bool phase; + bool phase = false ; uint32_t codeword_count { 0 }; pocsag::POCSAGPacket packet { }; diff --git a/firmware/common/pocsag_packet.hpp b/firmware/common/pocsag_packet.hpp index 39a71060..53f1ada8 100644 --- a/firmware/common/pocsag_packet.hpp +++ b/firmware/common/pocsag_packet.hpp @@ -87,7 +87,7 @@ public: private: BitRate bitrate_ { UNKNOWN }; PacketFlag flag_ { NORMAL }; - std::array codewords; + std::array codewords { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; Timestamp timestamp_ { }; }; From e9e4d2030217e04766210af533c4b0c9cbc363ea Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:11:20 +0100 Subject: [PATCH 15/52] Removed unused and voided a var --- firmware/baseband/proc_nrfrx.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/firmware/baseband/proc_nrfrx.cpp b/firmware/baseband/proc_nrfrx.cpp index 277bc7f3..b27eb148 100644 --- a/firmware/baseband/proc_nrfrx.cpp +++ b/firmware/baseband/proc_nrfrx.cpp @@ -37,7 +37,6 @@ void NRFRxProcessor::execute(const buffer_c8_t& buffer) { auto audio_oversampled = demod.execute(decim_0_out, work_audio_buffer); // Audio signal processing for (size_t c = 0; c < audio_oversampled.count; c++) { - int result; int g_srate = 4; //4 for 250KPS //int g_srate = 1; //1 for 1MPS, not working yet int32_t current_sample = audio_oversampled.p[c]; //if I directly use this, some results can pass crc but not correct. @@ -48,11 +47,8 @@ void NRFRxProcessor::execute(const buffer_c8_t& buffer) { skipSamples = skipSamples - 1; - if (skipSamples<1) { - - int32_t threshold_tmp=0; for (int c=0;c<8*g_srate;c++) { @@ -272,6 +268,7 @@ void NRFRxProcessor::on_message(const Message* const message) { } void NRFRxProcessor::configure(const NRFRxConfigureMessage& message) { + (void)message; //avoir unused warning decim_0.configure(taps_200k_wfm_decim_0.taps, 33554432); decim_1.configure(taps_200k_wfm_decim_1.taps, 131072); demod.configure(audio_fs, 5000); From 42113434f0a18a684127d5e97616239df67372d7 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:30:09 +0100 Subject: [PATCH 16/52] Fixed redefined define, possibly overflowing variable, missing constructors --- .../application/apps/ui_looking_glass_app.cpp | 20 +++++++++---------- .../application/apps/ui_looking_glass_app.hpp | 10 +++++++--- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp index e18bba62..54d347e1 100644 --- a/firmware/application/apps/ui_looking_glass_app.cpp +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -100,7 +100,7 @@ void GlassView::on_channel_spectrum(const ChannelSpectrum &spectrum) } if (pixel_index) - f_center += SEARCH_SLICE_WIDTH; //Move into the next bandwidth slice NOTE: spectrum.sampling_rate = SEARCH_SLICE_WIDTH + f_center += LOOKING_GLASS_SLICE_WIDTH; //Move into the next bandwidth slice NOTE: spectrum.sampling_rate = LOOKING_GLASS_SLICE_WIDTH else f_center = f_center_ini; //Start a new sweep @@ -143,8 +143,8 @@ void GlassView::on_range_changed() else field_marker.set_step(marker_step); //step needs to be a pixel wide. - f_center_ini = f_min + (SEARCH_SLICE_WIDTH / 2); //Initial center frequency for sweep - f_center_ini += SEARCH_SLICE_WIDTH; //euquiq: Why do I need to move the center ???!!! (shift needed for marker accuracy) + f_center_ini = f_min + (LOOKING_GLASS_SLICE_WIDTH / 2); //Initial center frequency for sweep + f_center_ini += LOOKING_GLASS_SLICE_WIDTH; //euquiq: Why do I need to move the center ???!!! (shift needed for marker accuracy) PlotMarker(field_marker.value()); //Refresh marker on screen @@ -153,13 +153,13 @@ void GlassView::on_range_changed() max_power = 0; bins_Hz_size = 0; //reset amount of Hz filled up by pixels - baseband::set_spectrum(SEARCH_SLICE_WIDTH, field_trigger.value()); + baseband::set_spectrum(LOOKING_GLASS_SLICE_WIDTH, field_trigger.value()); receiver_model.set_tuning_frequency(f_center_ini); //tune rx for this slice } -void GlassView::PlotMarker(rf::Frequency pos) +void GlassView::PlotMarker(rf::Frequency fpos) { - pos = pos * MHZ_DIV; + int64_t pos = fpos * MHZ_DIV; pos -= f_min; pos = pos / marker_pixel_step; //Real pixel @@ -240,11 +240,11 @@ GlassView::GlassView( field_trigger.set_value(32); //Defaults to 32, as normal triggering resolution field_trigger.on_change = [this](int32_t v) { - baseband::set_spectrum(SEARCH_SLICE_WIDTH, v); + baseband::set_spectrum(LOOKING_GLASS_SLICE_WIDTH, v); }; display.scroll_set_area( 109, 319); - baseband::set_spectrum(SEARCH_SLICE_WIDTH, field_trigger.value()); //trigger: + baseband::set_spectrum(LOOKING_GLASS_SLICE_WIDTH, field_trigger.value()); //trigger: // Discord User jteich: WidebandSpectrum::on_message to set the trigger value. In WidebandSpectrum::execute , // it keeps adding the output of the fft to the buffer until "trigger" number of calls are made, //at which time it pushes the buffer up with channel_spectrum.feed @@ -252,8 +252,8 @@ GlassView::GlassView( on_range_changed(); receiver_model.set_modulation(ReceiverModel::Mode::SpectrumAnalysis); - receiver_model.set_sampling_rate(SEARCH_SLICE_WIDTH); //20mhz - receiver_model.set_baseband_bandwidth(SEARCH_SLICE_WIDTH); // possible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz + receiver_model.set_sampling_rate(LOOKING_GLASS_SLICE_WIDTH); //20mhz + receiver_model.set_baseband_bandwidth(LOOKING_GLASS_SLICE_WIDTH); // possible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz receiver_model.set_squelch_level(0); receiver_model.enable(); } diff --git a/firmware/application/apps/ui_looking_glass_app.hpp b/firmware/application/apps/ui_looking_glass_app.hpp index 3313a55f..df93a819 100644 --- a/firmware/application/apps/ui_looking_glass_app.hpp +++ b/firmware/application/apps/ui_looking_glass_app.hpp @@ -33,7 +33,7 @@ namespace ui { - #define SEARCH_SLICE_WIDTH 20000000 // Each slice bandwidth 20 MHz + #define LOOKING_GLASS_SLICE_WIDTH 20000000 // Each slice bandwidth 20 MHz #define MHZ_DIV 1000000 #define X2_MHZ_DIV 2000000 @@ -41,6 +41,10 @@ { public: GlassView(NavigationView &nav); + + GlassView( const GlassView &); + GlassView& operator=(const GlassView &nav); + ~GlassView(); std::string title() const override { return "Looking Glass"; }; @@ -77,7 +81,7 @@ rf::Frequency f_center { 0 }; rf::Frequency f_center_ini { 0 }; rf::Frequency marker_pixel_step { 0 }; - rf::Frequency each_bin_size { SEARCH_SLICE_WIDTH / 240 }; + rf::Frequency each_bin_size { LOOKING_GLASS_SLICE_WIDTH / 240 }; rf::Frequency bins_Hz_size { 0 }; uint8_t min_color_power { 0 }; uint32_t pixel_index { 0 }; @@ -180,4 +184,4 @@ }; } - \ No newline at end of file + From 45b874694ea704165390dfab2ba2a003e9d9cc4d Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:36:44 +0100 Subject: [PATCH 17/52] Added missing default constructor --- firmware/common/ais_packet.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/firmware/common/ais_packet.hpp b/firmware/common/ais_packet.hpp index 47bf902e..eabd88d2 100644 --- a/firmware/common/ais_packet.hpp +++ b/firmware/common/ais_packet.hpp @@ -42,6 +42,7 @@ struct DateTime { template struct LatLonBase { + constexpr LatLonBase( ) : LatLonBase { raw_not_available } { @@ -58,6 +59,8 @@ struct LatLonBase { ) : raw_ { other.raw_ } { } + + LatLonBase& operator=( const LatLonBase &)=default; int32_t normalized() const { return static_cast(raw() << sign_extend_shift) / (1 << sign_extend_shift); From 5d73175a17990c7d88810cdde8f5a370211a927f Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:39:50 +0100 Subject: [PATCH 18/52] Added missing brace --- firmware/application/ui_navigation.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index b2e85093..b35073d0 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -625,10 +625,12 @@ SystemView::SystemView( navigation_view.push(); if (portapack::persistent_memory::config_splash()) + { navigation_view.push(); status_view.set_back_enabled(false); status_view.set_title_image_enabled(true); status_view.set_dirty(); + } //else // navigation_view.push(); From f0457c106db68c1843e936c7ad5cb9c51c036184 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:43:13 +0100 Subject: [PATCH 19/52] Added missing default constructor --- firmware/application/apps/ert_app.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/application/apps/ert_app.hpp b/firmware/application/apps/ert_app.hpp index d7488860..14eb61c0 100644 --- a/firmware/application/apps/ert_app.hpp +++ b/firmware/application/apps/ert_app.hpp @@ -50,6 +50,8 @@ struct ERTKey { { } + ERTKey( const ERTKey& other ) = default; + ERTKey& operator=(const ERTKey& other) { id = other.id; commodity_type = other.commodity_type; From c3c680fc045d590c99e7e16b136870d18d885bc3 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:46:58 +0100 Subject: [PATCH 20/52] removed unused var --- firmware/application/ui/ui_tv.cpp | 2 +- firmware/application/ui/ui_tv.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/application/ui/ui_tv.cpp b/firmware/application/ui/ui_tv.cpp index 59c99e07..5c3f0fbc 100644 --- a/firmware/application/ui/ui_tv.cpp +++ b/firmware/application/ui/ui_tv.cpp @@ -182,7 +182,7 @@ void TVView::clear() { /* TVWidget *******************************************************/ -TVWidget::TVWidget(const bool cursor) { +TVWidget::TVWidget() { add_children({ &tv_view, &field_xcorr diff --git a/firmware/application/ui/ui_tv.hpp b/firmware/application/ui/ui_tv.hpp index 1fb7887a..7accf7d4 100644 --- a/firmware/application/ui/ui_tv.hpp +++ b/firmware/application/ui/ui_tv.hpp @@ -92,7 +92,7 @@ class TVWidget : public View { public: std::function on_select { }; - TVWidget(const bool cursor = false); + TVWidget(); TVWidget(const TVWidget&) = delete; TVWidget(TVWidget&&) = delete; From 8bfeba0d8925e8756a58550a3e99088b23a21fc4 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:50:48 +0100 Subject: [PATCH 21/52] Added a voided v --- firmware/application/apps/ui_fileman.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/application/apps/ui_fileman.cpp b/firmware/application/apps/ui_fileman.cpp index 8fd0a5b6..16812d8a 100644 --- a/firmware/application/apps/ui_fileman.cpp +++ b/firmware/application/apps/ui_fileman.cpp @@ -216,6 +216,7 @@ FileSaveView::FileSaveView( }*/ void FileLoadView::refresh_widgets(const bool v) { + (void)v; //avoid unused warning set_dirty(); } From 8c84719598ffcf1fdc6ef30354f1aaa6296c08f5 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:54:17 +0100 Subject: [PATCH 22/52] Added two voided vars --- firmware/application/apps/ui_looking_glass_app.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp index 54d347e1..73ff1428 100644 --- a/firmware/application/apps/ui_looking_glass_app.cpp +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -216,10 +216,12 @@ GlassView::GlassView( filter_config.set_selected_index(0); filter_config.on_change = [this](size_t n, OptionsField::value_t v) { + (void)n; min_color_power = v; }; range_presets.on_change = [this](size_t n, OptionsField::value_t v) { + (void)n; field_frequency_min.set_value(presets_db[v].min,false); field_frequency_max.set_value(presets_db[v].max,false); this->on_range_changed(); From b75ef345a5637380c94b5908f31973638bc557d5 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 16:57:42 +0100 Subject: [PATCH 23/52] added a voided var --- firmware/application/apps/ui_morse.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/application/apps/ui_morse.cpp b/firmware/application/apps/ui_morse.cpp index b0465970..ebe44b6d 100644 --- a/firmware/application/apps/ui_morse.cpp +++ b/firmware/application/apps/ui_morse.cpp @@ -226,6 +226,7 @@ MorseView::MorseView( }; options_loop.on_change = [this](size_t i, uint32_t n) { + (void)i; //avoid unused warning loop = n; }; From 02d69e54eb28cfd2b021fb2796d6beb8acee9d8b Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 17:03:20 +0100 Subject: [PATCH 24/52] Fixed uninitialized / missing switch cases, unused --- firmware/application/apps/ui_scanner.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp index 17f5cc0a..6874280a 100644 --- a/firmware/application/apps/ui_scanner.cpp +++ b/firmware/application/apps/ui_scanner.cpp @@ -172,7 +172,7 @@ void ScannerView::show_max() { //show total number of freqs to scan ScannerView::ScannerView( NavigationView& nav - ) : nav_ { nav } + ) : nav_ { nav } , loaded_file_name { "SCANNER" } { add_children({ &labels, @@ -364,7 +364,7 @@ ScannerView::ScannerView( big_display.set(frequency_list[current_index]); //After showing an error } else { - auto result = scanner_file.append(freq_file_path); //Second: append if it is not there + scanner_file.append(freq_file_path); //Second: append if it is not there scanner_file.write_line(frequency_to_add + ",d=ADD FQ"); } } else @@ -409,7 +409,12 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor case FM_2: def_step = 50000; break ; case N_1: def_step = 25000; break ; case N_2: def_step = 250000; break ; - case AIRBAND:def_step= 8330; break ; + case AIRBAND: def_step= 8330; break ; + case ERROR_STEP: + case STEP_DEF: + default: + def_step = step_mode.selected_index_value(); //Use def_step from manual selector + break ; } frequency_list.push_back(entry.frequency_a); //Store starting freq and description description_list.push_back("R" + to_string_short_freq(entry.frequency_a) @@ -435,7 +440,7 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor } else { - loaded_file_name = 'SCANNER'; // back to the default frequency file + loaded_file_name = "SCANNER"; // back to the default frequency file desc_cycle.set(" NO " + file_name + ".TXT FILE ..." ); } audio::output::stop(); @@ -504,7 +509,9 @@ size_t ScannerView::change_mode(uint8_t new_mod) { //Before this, do a scan_thre using option_t = std::pair; using options_t = std::vector; options_t bw; - field_bw.on_change = [this](size_t n, OptionsField::value_t) { }; + field_bw.on_change = [this](size_t n, OptionsField::value_t) { + (void)n; //avoid unused warning + }; switch (new_mod) { case NFM: //bw 16k (2) default @@ -556,4 +563,4 @@ void ScannerView::start_scan_thread() { scan_thread = std::make_unique(frequency_list); } -} /* namespace ui */ \ No newline at end of file +} /* namespace ui */ From a6a41ca5a5c0dbaa69057ac98a1435d102dca11e Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 17:08:09 +0100 Subject: [PATCH 25/52] Added missing initialize --- firmware/application/apps/ui_settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index c6ccb817..7525b8dd 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -155,7 +155,7 @@ SetRadioView::SetRadioView( }); SetFrequencyCorrectionModel model { - static_cast(portapack::persistent_memory::correction_ppb() / 1000) + static_cast(portapack::persistent_memory::correction_ppb() / 1000) , 0 }; form_init(model); From ca7b5e110c93bce4e2910160875f87a779a95b28 Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 17:10:37 +0100 Subject: [PATCH 26/52] Added missing initializer --- firmware/application/apps/ui_sonde.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/application/apps/ui_sonde.hpp b/firmware/application/apps/ui_sonde.hpp index d7da2443..65a397f1 100644 --- a/firmware/application/apps/ui_sonde.hpp +++ b/firmware/application/apps/ui_sonde.hpp @@ -68,9 +68,9 @@ private: uint32_t target_frequency_ { 402700000 }; bool logging { false }; bool use_crc { false }; - sonde::GPS_data gps_info; - sonde::temp_humid temp_humid_info; - std::string sonde_id; + sonde::GPS_data gps_info { }; + sonde::temp_humid temp_humid_info { }; + std::string sonde_id { }; Labels labels { { { 4 * 8, 2 * 16 }, "Type:", Color::light_grey() }, From fb61ad55c025740226958a0d972aac4fd9364abf Mon Sep 17 00:00:00 2001 From: GullCode Date: Wed, 27 Jan 2021 17:20:07 +0100 Subject: [PATCH 27/52] added a voided var --- firmware/application/apps/soundboard_app.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/application/apps/soundboard_app.cpp b/firmware/application/apps/soundboard_app.cpp index 337c8935..4682d985 100644 --- a/firmware/application/apps/soundboard_app.cpp +++ b/firmware/application/apps/soundboard_app.cpp @@ -130,6 +130,7 @@ void SoundBoardView::start_tx(const uint32_t id) { }*/ void SoundBoardView::on_tx_progress(const uint32_t progress) { + (void)progress ; // avoid warning //progressbar.set_value(progress); } From 1a48fb8c5a1256a8c189a75fcf805c2f99bb58e9 Mon Sep 17 00:00:00 2001 From: GullCode Date: Thu, 28 Jan 2021 10:08:57 +0100 Subject: [PATCH 28/52] removed a var, added a void, removed a unused initializer --- firmware/application/apps/analog_tv_app.cpp | 3 ++- firmware/application/apps/analog_tv_app.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/application/apps/analog_tv_app.cpp b/firmware/application/apps/analog_tv_app.cpp index 8f498078..b3710573 100644 --- a/firmware/application/apps/analog_tv_app.cpp +++ b/firmware/application/apps/analog_tv_app.cpp @@ -199,7 +199,7 @@ void AnalogTvView::on_show_options_rf_gain() { void AnalogTvView::on_show_options_modulation() { std::unique_ptr widget; - const auto modulation = static_cast(receiver_model.modulation()); + static_cast(receiver_model.modulation()); tv.show_audio_spectrum_view(true); set_options_widget(std::move(widget)); @@ -216,6 +216,7 @@ void AnalogTvView::on_reference_ppm_correction_changed(int32_t v) { } void AnalogTvView::on_headphone_volume_changed(int32_t v) { + (void)v; //avoid warning //tv::TVView::set_headphone_volume(this,v); } diff --git a/firmware/application/apps/analog_tv_app.hpp b/firmware/application/apps/analog_tv_app.hpp index 552f7f6b..6f90a55c 100644 --- a/firmware/application/apps/analog_tv_app.hpp +++ b/firmware/application/apps/analog_tv_app.hpp @@ -107,7 +107,7 @@ private: std::unique_ptr options_widget { }; - tv::TVWidget tv { true }; + tv::TVWidget tv { }; void on_tuning_frequency_changed(rf::Frequency f); void on_baseband_bandwidth_changed(uint32_t bandwidth_hz); From 4f90c5efee15ee886728658887ba42ba8076d276 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Wed, 3 Feb 2021 22:23:12 +0100 Subject: [PATCH 29/52] Updating contributors list --- firmware/application/apps/ui_about_simple.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/application/apps/ui_about_simple.cpp b/firmware/application/apps/ui_about_simple.cpp index 533c8462..dceb869d 100644 --- a/firmware/application/apps/ui_about_simple.cpp +++ b/firmware/application/apps/ui_about_simple.cpp @@ -28,9 +28,9 @@ namespace ui console.writeln("\x1B\x06Mayhem:\x1B\x10"); console.writeln("eried,euquiq,gregoryfenton"); console.writeln("johnelder,jwetzell,nnemanjan00"); - console.writeln("N0vaPixel,klockee,jamesshao8"); - console.writeln("ITAxReal,rascafr,mcules"); - console.writeln("dqs105,strijar"); + console.writeln("N0vaPixel,klockee,GullCode"); + console.writeln("jamesshao8,ITAxReal,rascafr"); + console.writeln("mcules,dqs105,strijar"); console.writeln(""); break; @@ -74,4 +74,4 @@ namespace ui button_ok.focus(); } -} /* namespace ui */ \ No newline at end of file +} /* namespace ui */ From cd8732c24f6c73166fcc330178e07d817810706c Mon Sep 17 00:00:00 2001 From: GullCode Date: Fri, 5 Feb 2021 23:08:54 +0100 Subject: [PATCH 30/52] Direct casting to int instead of new var --- firmware/application/apps/ui_looking_glass_app.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp index 73ff1428..1f478fb3 100644 --- a/firmware/application/apps/ui_looking_glass_app.cpp +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -164,9 +164,9 @@ void GlassView::PlotMarker(rf::Frequency fpos) pos = pos / marker_pixel_step; //Real pixel portapack::display.fill_rectangle({0, 100, 240, 8}, Color::black()); //Clear old marker and whole marker rectangle btw - portapack::display.fill_rectangle({pos - 2, 100, 5, 3}, Color::red()); //Red marker middle - portapack::display.fill_rectangle({pos - 1, 103, 3, 3}, Color::red()); //Red marker middle - portapack::display.fill_rectangle({pos, 106, 1, 2}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({(int16_t)pos - 2, 100, 5, 3}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({(int16_t)pos - 1, 103, 3, 3}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({(int16_t)pos, 106, 1, 2}, Color::red()); //Red marker middle } GlassView::GlassView( From 62c1e4e028ecd22c77026325f737fc0a250f18ef Mon Sep 17 00:00:00 2001 From: ImDroided Date: Sun, 14 Feb 2021 12:52:56 -0600 Subject: [PATCH 31/52] Added Pocsag bitrate I added 3200 to the bitrates in pocsag per a user request on Facebook. --- firmware/application/apps/pocsag_app.hpp | 3 ++- firmware/common/pocsag.hpp | 5 +++-- firmware/common/pocsag_packet.hpp | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/firmware/application/apps/pocsag_app.hpp b/firmware/application/apps/pocsag_app.hpp index 58fef242..faa47954 100644 --- a/firmware/application/apps/pocsag_app.hpp +++ b/firmware/application/apps/pocsag_app.hpp @@ -90,7 +90,8 @@ private: { { "512bps ", 0 }, { "1200bps", 1 }, - { "2400bps", 2 } + { "2400bps", 2 }, + { "3200bps", 3 } } }; OptionsField options_phase { diff --git a/firmware/common/pocsag.hpp b/firmware/common/pocsag.hpp index 2614b418..49346af4 100644 --- a/firmware/common/pocsag.hpp +++ b/firmware/common/pocsag.hpp @@ -65,10 +65,11 @@ struct POCSAGState { std::string output; }; -const pocsag::BitRate pocsag_bitrates[3] = { +const pocsag::BitRate pocsag_bitrates[4] = { pocsag::BitRate::FSK512, pocsag::BitRate::FSK1200, - pocsag::BitRate::FSK2400 + pocsag::BitRate::FSK2400, + pocsag::BitRate::FSK3200 }; std::string bitrate_str(BitRate bitrate); diff --git a/firmware/common/pocsag_packet.hpp b/firmware/common/pocsag_packet.hpp index 53f1ada8..b0933c7c 100644 --- a/firmware/common/pocsag_packet.hpp +++ b/firmware/common/pocsag_packet.hpp @@ -34,7 +34,8 @@ enum BitRate : uint32_t { UNKNOWN, FSK512 = 512, FSK1200 = 1200, - FSK2400 = 2400 + FSK2400 = 2400, + FSK3200 = 3200 }; enum PacketFlag : uint32_t { From 3c30c127e24eaa4469b15baa698b559b95ccbbe0 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Tue, 16 Feb 2021 09:09:49 +0100 Subject: [PATCH 32/52] Update ui_navigation.cpp --- firmware/application/ui_navigation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index b35073d0..9c583aed 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -627,10 +627,10 @@ SystemView::SystemView( if (portapack::persistent_memory::config_splash()) { navigation_view.push(); + } status_view.set_back_enabled(false); status_view.set_title_image_enabled(true); status_view.set_dirty(); - } //else // navigation_view.push(); From 27f354f8418529011224396b7f8f33594c74fbcf Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Tue, 16 Feb 2021 09:49:48 +0100 Subject: [PATCH 33/52] Latest pip broken https://stackoverflow.com/questions/65896334/python-pip-broken-wiith-sys-stderr-writeferror-exc --- dockerfile-nogit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockerfile-nogit b/dockerfile-nogit index 114b6bc8..580d4115 100644 --- a/dockerfile-nogit +++ b/dockerfile-nogit @@ -15,7 +15,7 @@ RUN apt-get update && \ apt-get -qy autoremove #Install current pip from PyPa -RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ +RUN curl https://bootstrap.pypa.io/3.4/get-pip.py -o get-pip.py && \ python3 get-pip.py #Fetch additional dependencies from Python 3.x pip @@ -38,4 +38,4 @@ RUN mkdir ~/bin && cd ~/bin && \ for tool in gcc g++ cpp c++;do ln -s $(which ccache) arm-none-eabi-$tool;done CMD cd .. && cd build && \ - cmake .. && make firmware \ No newline at end of file + cmake .. && make firmware From de92faf67b17b597ae7da68de9b2a76260cf385b Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Tue, 16 Feb 2021 09:50:34 +0100 Subject: [PATCH 34/52] Same as the other dockerfile, using get-pip.py 3.4 https://stackoverflow.com/questions/65896334/python-pip-broken-wiith-sys-stderr-writeferror-exc --- dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockerfile b/dockerfile index 1f065ce0..753a86fa 100644 --- a/dockerfile +++ b/dockerfile @@ -18,7 +18,7 @@ RUN apt-get update && \ apt-get -qy autoremove #Install current pip from PyPa -RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ +RUN curl https://bootstrap.pypa.io/3.4/get-pip.py -o get-pip.py && \ python get-pip.py #Fetch additional dependencies from Python 2.x pip From f98c96e98a9a706896b4b9184f0ac6d2b821577b Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Thu, 11 Mar 2021 10:33:54 +0100 Subject: [PATCH 35/52] Update dockerfile-nogit --- dockerfile-nogit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockerfile-nogit b/dockerfile-nogit index 580d4115..b317a834 100644 --- a/dockerfile-nogit +++ b/dockerfile-nogit @@ -15,7 +15,7 @@ RUN apt-get update && \ apt-get -qy autoremove #Install current pip from PyPa -RUN curl https://bootstrap.pypa.io/3.4/get-pip.py -o get-pip.py && \ +RUN curl https://bootstrap.pypa.io/pip/3.4/get-pip.py -o get-pip.py && \ python3 get-pip.py #Fetch additional dependencies from Python 3.x pip From f56e8930dc00612a52322eb08dddd9404f42ada7 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Thu, 11 Mar 2021 10:34:10 +0100 Subject: [PATCH 36/52] Update dockerfile --- dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockerfile b/dockerfile index 753a86fa..3f688bd4 100644 --- a/dockerfile +++ b/dockerfile @@ -18,7 +18,7 @@ RUN apt-get update && \ apt-get -qy autoremove #Install current pip from PyPa -RUN curl https://bootstrap.pypa.io/3.4/get-pip.py -o get-pip.py && \ +RUN curl https://bootstrap.pypa.io/pip/3.4/get-pip.py -o get-pip.py && \ python get-pip.py #Fetch additional dependencies from Python 2.x pip From f15cf781012f6f37f39af0cb05d4bd240963d587 Mon Sep 17 00:00:00 2001 From: East2West <1129491+East2West@users.noreply.github.com> Date: Sun, 7 Mar 2021 16:05:23 -0600 Subject: [PATCH 37/52] Add APRS Receiving App --- firmware/application/CMakeLists.txt | 2 + firmware/application/apps/ui_about_simple.cpp | 1 + firmware/application/apps/ui_aprs_rx.cpp | 409 +++++++++++++++ firmware/application/apps/ui_aprs_rx.hpp | 276 ++++++++++ firmware/application/baseband_api.cpp | 7 + firmware/application/baseband_api.hpp | 1 + firmware/application/recent_entries.hpp | 20 +- firmware/application/ui/ui_geomap.cpp | 5 + firmware/application/ui_navigation.cpp | 4 +- firmware/baseband/CMakeLists.txt | 8 + firmware/baseband/proc_aprsrx.cpp | 258 +++++++++ firmware/baseband/proc_aprsrx.hpp | 148 ++++++ firmware/common/aprs_packet.cpp | 27 + firmware/common/aprs_packet.hpp | 495 ++++++++++++++++++ firmware/common/message.hpp | 28 + firmware/common/spi_image.hpp | 1 + firmware/common/ui_widget.cpp | 44 +- firmware/common/ui_widget.hpp | 4 +- 18 files changed, 1722 insertions(+), 16 deletions(-) create mode 100644 firmware/application/apps/ui_aprs_rx.cpp create mode 100644 firmware/application/apps/ui_aprs_rx.hpp create mode 100644 firmware/baseband/proc_aprsrx.cpp create mode 100644 firmware/baseband/proc_aprsrx.hpp create mode 100644 firmware/common/aprs_packet.cpp create mode 100644 firmware/common/aprs_packet.hpp diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index 3ee7d074..064452be 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -140,6 +140,7 @@ set(CPPSRC ${COMMON}/png_writer.cpp ${COMMON}/pocsag.cpp ${COMMON}/pocsag_packet.cpp + ${COMMON}/aprs_packet.cpp ${COMMON}/portapack_io.cpp ${COMMON}/portapack_persistent_memory.cpp ${COMMON}/portapack_shared_memory.cpp @@ -218,6 +219,7 @@ set(CPPSRC apps/ui_adsb_rx.cpp apps/ui_adsb_tx.cpp apps/ui_afsk_rx.cpp + apps/ui_aprs_rx.cpp apps/ui_btle_rx.cpp apps/ui_nrf_rx.cpp apps/ui_aprs_tx.cpp diff --git a/firmware/application/apps/ui_about_simple.cpp b/firmware/application/apps/ui_about_simple.cpp index dceb869d..ff0852db 100644 --- a/firmware/application/apps/ui_about_simple.cpp +++ b/firmware/application/apps/ui_about_simple.cpp @@ -31,6 +31,7 @@ namespace ui console.writeln("N0vaPixel,klockee,GullCode"); console.writeln("jamesshao8,ITAxReal,rascafr"); console.writeln("mcules,dqs105,strijar"); + console.writeln("East2West"); console.writeln(""); break; diff --git a/firmware/application/apps/ui_aprs_rx.cpp b/firmware/application/apps/ui_aprs_rx.cpp new file mode 100644 index 00000000..db898a69 --- /dev/null +++ b/firmware/application/apps/ui_aprs_rx.cpp @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2017 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "ui_aprs_rx.hpp" + +#include "audio.hpp" +#include "rtc_time.hpp" +#include "baseband_api.hpp" +#include "string_format.hpp" +#include "portapack_persistent_memory.hpp" + +using namespace portapack; + +void APRSLogger::log_raw_data(const std::string& data) { + rtc::RTC datetime; + rtcGetTime(&RTCD1, &datetime); + + log_file.write_entry(datetime, data); +} + +namespace ui { + +template<> +void RecentEntriesTable::draw( + const Entry& entry, + const Rect& target_rect, + Painter& painter, + const Style& style +) { + char aged_color; + Color target_color; + auto entry_age = entry.age; + + target_color = Color::green(); + + aged_color = 0x10; + std::string entry_string = "\x1B"; + entry_string += aged_color; + + entry_string += entry.source_formatted; + entry_string.append(10 - entry.source_formatted.size(),' '); + entry_string += " "; + entry_string += (entry.hits <= 999 ? to_string_dec_uint(entry.hits, 4) : "999+"); + entry_string += " "; + entry_string += entry.time_string; + + painter.draw_string( + target_rect.location(), + style, + entry_string + ); + + if (entry.has_position){ + painter.draw_bitmap(target_rect.location() + Point(12 * 8, 0), bitmap_target, target_color, style.background); + } +} + + +void APRSRxView::focus() { + options_region.focus(); +} + +void APRSRxView::update_freq(rf::Frequency f) { + receiver_model.set_tuning_frequency(f); +} + +APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect) : View(parent_rect) { + baseband::run_image(portapack::spi_flash::image_tag_aprs_rx); + + add_children({ + &rssi, + &channel, + &field_rf_amp, + &field_lna, + &field_vga, + &options_region, + &field_frequency, + &record_view, + &console + }); + + // DEBUG + record_view.on_error = [&nav](std::string message) { + nav.display_modal("Error", message); + }; + + record_view.set_sampling_rate(24000); + + options_region.on_change = [this](size_t, int32_t i) { + if (i == 0){ + field_frequency.set_value(144390000); + } + if(i == 1){ + field_frequency.set_value(144800000); + } + if(i == 2){ + field_frequency.set_value(145175000); + } + }; + + field_frequency.set_value(receiver_model.tuning_frequency()); + field_frequency.set_step(100); + field_frequency.on_change = [this](rf::Frequency f) { + update_freq(f); + }; + field_frequency.on_edit = [this, &nav]() { + auto new_view = nav.push(receiver_model.tuning_frequency()); + new_view->on_changed = [this](rf::Frequency f) { + update_freq(f); + field_frequency.set_value(f); + }; + }; + + options_region.set_selected_index(0, true); + + logger = std::make_unique(); + if (logger) + logger->append("APRS_RX_LOG.TXT"); + + baseband::set_aprs(1200); + + audio::set_rate(audio::Rate::Hz_24000); + audio::output::start(); + + receiver_model.set_sampling_rate(3072000); + receiver_model.set_baseband_bandwidth(1750000); + receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); + receiver_model.enable(); +} + +void APRSRxView::on_packet(const APRSPacketMessage* message){ + std::string str_console = "\x1B"; + + aprs::APRSPacket packet = message->packet; + + std::string stream_text = packet.get_stream_text(); + str_console += (char)((console_color++ & 3) + 9); + str_console += stream_text; + + if(logger){ + logger->log_raw_data(stream_text); + } + + //if(reset_console){ //having more than one console causes issues when switching tabs where one is disabled, and the other enabled breaking the scoll setup. + // console.on_hide(); + // console.on_show(); + // reset_console = false; + //} + + console.writeln(str_console); +} + +void APRSRxView::on_data(uint32_t value, bool is_data) { + std::string str_console = "\x1B"; + std::string str_byte = ""; + + if (is_data) { + // Colorize differently after message splits + str_console += (char)((console_color & 3) + 9); + + if (value == '\n') { + // Message split + console.writeln(""); + console_color++; + + if (logger) { + logger->log_raw_data(str_log); + str_log = ""; + } + } + else { + if ((value >= 32) && (value < 127)) { + str_console += (char)value; // Printable + str_byte += (char)value; + } else { + str_console += "[" + to_string_hex(value, 2) + "]"; // Not printable + str_byte += "[" + to_string_hex(value, 2) + "]"; + } + + console.write(str_console); + + if (logger) str_log += str_byte; + } + } else { + + } +} + +void APRSRxView::on_show(){ + //some bug where the display scroll area is set to the entire screen when switching from the list tab with details showing back to the stream view. + //reset_console = true; +} + +APRSRxView::~APRSRxView() { + audio::output::stop(); + receiver_model.disable(); + baseband::shutdown(); +} + +void APRSTableView::on_show_list() { + details_view.hidden(true); + recent_entries_view.hidden(false); + send_updates = false; + focus(); +} + +void APRSTableView::on_show_detail(const APRSRecentEntry& entry) { + recent_entries_view.hidden(true); + details_view.hidden(false); + details_view.set_entry(entry); + details_view.update(); + details_view.focus(); + detailed_entry_key = entry.key(); + send_updates = true; +} + +APRSTableView::APRSTableView(NavigationView& nav, Rect parent_rec) : View(parent_rec), nav_ {nav} { + add_children({ + &recent_entries_view, + &details_view + }); + + hidden(true); + + details_view.hidden(true); + + recent_entries_view.set_parent_rect({0, 0, 240, 280}); + details_view.set_parent_rect({0, 0, 240, 280}); + + recent_entries_view.on_select = [this](const APRSRecentEntry& entry) { + this->on_show_detail(entry); + }; + + details_view.on_close = [this]() { + this->on_show_list(); + }; + + +/* for(size_t i = 0; i <32 ; i++){ + std::string id = "test" + i; + auto& entry = ::on_packet(recent, i); + entry.set_source_formatted(id); + } + + recent_entries_view.set_dirty(); */ + + /* + + std::string str1 = "test1"; + std::string str12 = "test2"; + std::string str13 = "test2"; + + auto& entry = ::on_packet(recent, 0x1); + entry.set_source_formatted(str1); + + auto& entry2 = ::on_packet(recent, 0x2); + entry2.set_source_formatted(str12); + + auto& entry3 = ::on_packet(recent, 0x2); + entry2.set_source_formatted(str13); + + recent_entries_view.set_dirty(); + + */ +} + +void APRSTableView::on_pkt(const APRSPacketMessage* message){ + aprs::APRSPacket packet = message->packet; + rtc::RTC datetime; + std::string str_timestamp; + std::string source_formatted = packet.get_source_formatted(); + std::string info_string = packet.get_stream_text(); + + rtcGetTime(&RTCD1, &datetime); + auto& entry = ::on_packet(recent, packet.get_source()); + entry.reset_age(); + entry.inc_hit(); + str_timestamp = to_string_datetime(datetime, HMS); + entry.set_time_string(str_timestamp); + entry.set_info_string(info_string); + + entry.set_source_formatted(source_formatted); + + if(entry.has_position && !packet.has_position()){ + //maintain position info + } + else { + entry.set_has_position(packet.has_position()); + entry.set_pos(packet.get_position()); + } + + if( entry.key() == details_view.entry().key() ) { + details_view.set_entry(entry); + details_view.update(); + } + + recent_entries_view.set_dirty(); +} + +void APRSTableView::on_show(){ + on_show_list(); +} + +void APRSTableView::on_hide(){ + details_view.hidden(true); +} + +void APRSTableView::focus(){ + recent_entries_view.focus(); +} + +APRSTableView::~APRSTableView(){ + +} + +void APRSDetailsView::focus() { + button_done.focus(); +} + +void APRSDetailsView::set_entry(const APRSRecentEntry& entry){ + entry_copy = entry; +} + +void APRSDetailsView::update() { + if(!hidden()){ + uint32_t age = entry_copy.age; + + console.clear(true); + console.write(entry_copy.info_string); + + button_see_map.hidden(!entry_copy.has_position); + } + + if (send_updates) + geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude, 0); +} + +APRSDetailsView::~APRSDetailsView() { +} + +APRSDetailsView::APRSDetailsView( + NavigationView& nav +) +{ + add_children({ + &console, + &button_done, + &button_see_map + }); + + button_done.on_select = [this, &nav](Button&) { + console.clear(true); + this->on_close(); + }; + + button_see_map.on_select = [this, &nav](Button&) { + geomap_view = nav.push( + entry_copy.source_formatted, + 0, //entry_copy.pos.altitude, + GeoPos::alt_unit::FEET, + entry_copy.pos.latitude, + entry_copy.pos.longitude, + 0, /*entry_copy.velo.heading,*/ + [this]() { + send_updates = false; + hidden(false); + update(); + }); + send_updates = true; + hidden(true); + + }; +}; + +APRSRXView::APRSRXView(NavigationView& nav) : nav_ {nav} { + add_children({ + &tab_view, + &view_stream, + &view_table + }); +} + +void APRSRXView::focus(){ + tab_view.focus(); +} + +APRSRXView::~APRSRXView() { + +} +} /* namespace ui */ diff --git a/firmware/application/apps/ui_aprs_rx.hpp b/firmware/application/apps/ui_aprs_rx.hpp new file mode 100644 index 00000000..e392e62f --- /dev/null +++ b/firmware/application/apps/ui_aprs_rx.hpp @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2017 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __UI_APRS_RX_H__ +#define __UI_APRS_RX_H__ + +#include "ui.hpp" +#include "ui_navigation.hpp" +#include "ui_receiver.hpp" +#include "ui_record_view.hpp" // DEBUG +#include "ui_geomap.hpp" + +#include "recent_entries.hpp" +#include "ui_tabview.hpp" + +#include "log_file.hpp" +#include "utility.hpp" + +class APRSLogger { +public: + Optional append(const std::string& filename) { + return log_file.append(filename); + } + + void log_raw_data(const std::string& data); + +private: + LogFile log_file { }; +}; + +namespace ui { + +struct APRSRecentEntry { + using Key = uint64_t; + + static constexpr Key invalid_key = 0xffffffffffffffff; + + uint16_t hits { 0 }; + uint32_t age { 0 }; + + uint64_t source; + std::string source_formatted { " " }; + std::string time_string { "" }; + std::string info_string { "" }; + + aprs::aprs_pos pos; + bool has_position = false; + APRSRecentEntry(uint64_t src) + { + source = src; + } + + Key key() const { + return source; + } + + void set_source_formatted(std::string& new_source) { + source_formatted = new_source; + } + + void inc_hit() { + hits++; + } + + void set_info_string(std::string& new_info_string) { + info_string = new_info_string; + } + + void set_time_string(std::string& new_time_string) { + time_string = new_time_string; + } + + void set_pos(aprs::aprs_pos pos_in){ + pos = pos_in; + } + + void set_has_position(bool has_pos){ + has_position = has_pos; + } + + void reset_age() { + age = 0; + } + + void inc_age() { + age++; + } +}; + +class APRSDetailsView : public View { +public: + APRSDetailsView(NavigationView&); + ~APRSDetailsView(); + + APRSDetailsView(const APRSDetailsView&) = delete; + APRSDetailsView(APRSDetailsView&&) = delete; + APRSDetailsView& operator=(const APRSDetailsView&) = delete; + APRSDetailsView& operator=(APRSDetailsView&&) = delete; + + void focus() override; + + void update(); + void set_entry(const APRSRecentEntry& entry); + + const APRSRecentEntry& entry() const { return entry_copy; }; + + std::string title() const override { return "Details"; }; + std::function on_close { }; + +private: + APRSRecentEntry entry_copy { 0 }; + GeoMapView* geomap_view { nullptr }; + bool send_updates { false }; + + Console console { + { 0, 0 * 16, 240, 224 } + }; + + Button button_done { + { 160, 14 * 16, 8 * 8, 3 * 16 }, + "Close" + }; + + Button button_see_map { + { 80, 14 * 16, 8 * 8, 3 * 16 }, + "Map" + }; +}; + +using APRSRecentEntries = RecentEntries; + +class APRSTableView: public View { +public: + APRSTableView(NavigationView& nav, Rect parent_rec); + ~APRSTableView(); + + void on_show() override; + void on_hide() override; + void focus() override; + void on_pkt(const APRSPacketMessage* message); + + std::string title() const override { return "Stations"; }; +private: + NavigationView& nav_; + const RecentEntriesColumns columns { { + { "Source", 9 }, + { "Loc", 6 }, + { "Hits", 4 }, + { "Time", 8 } + } }; + APRSRecentEntries recent { }; + RecentEntriesView> recent_entries_view { columns, recent }; + APRSDetailsView details_view { nav_ }; + uint32_t detailed_entry_key { 0 }; + bool send_updates { false }; + + void on_show_list(); + void on_show_detail(const APRSRecentEntry& entry); +}; + +class APRSRxView : public View { +public: + APRSRxView(NavigationView& nav, Rect parent_rect); + ~APRSRxView(); + + void on_show() override; + void focus() override; + + std::string title() const override { return "APRS RX"; }; + void on_packet(const APRSPacketMessage* message); + +private: + void on_data(uint32_t value, bool is_data); + bool reset_console = false; + + uint8_t console_color { 0 }; + std::string str_log { "" }; + + RFAmpField field_rf_amp { + { 13 * 8, 0 * 16 } + }; + LNAGainField field_lna { + { 15 * 8, 0 * 16 } + }; + VGAGainField field_vga { + { 18 * 8, 0 * 16 } + }; + RSSI rssi { + { 21 * 8, 0, 6 * 8, 4 }, + }; + Channel channel { + { 21 * 8, 5, 6 * 8, 4 }, + }; + + OptionsField options_region { + { 0 * 8, 0 * 8 }, + 3, + { + { "NA ", 0 }, + { "EUR", 1 }, + { "AUS", 2 } + } + }; + + FrequencyField field_frequency { + { 3 * 8, 0 * 16 }, + }; + + // DEBUG + RecordView record_view { + { 0 * 8, 1 * 16, 30 * 8, 1 * 16 }, + u"AFS_????", RecordView::FileType::WAV, 4096, 4 + }; + + Console console { + { 0, 2 * 16, 240, 240 } + }; + + void update_freq(rf::Frequency f); + + std::unique_ptr logger { }; +}; + +class APRSRXView : public View { +public: + APRSRXView(NavigationView& nav); + ~APRSRXView(); + + void focus() override; + + std::string title() const override { return "APRS RX"; }; + +private: + NavigationView& nav_; + Rect view_rect = { 0, 3 * 8, 240, 280 }; + + APRSRxView view_stream { nav_, view_rect }; + APRSTableView view_table { nav_, view_rect }; + + TabView tab_view { + { "Stream", Color::cyan(), &view_stream }, + { "List", Color::yellow(), &view_table } + }; + + MessageHandlerRegistration message_handler_packet { + Message::ID::APRSPacket, + [this](Message* const p) { + const auto message = static_cast(p); + this->view_stream.on_packet(message); + this->view_table.on_pkt(message); + } + }; +}; + +} /* namespace ui */ + +#endif/*__UI_APRS_RX_H__*/ diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 2bff3c53..e570458a 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -130,6 +130,13 @@ void set_afsk(const uint32_t baudrate, const uint32_t word_length, const uint32_ send_message(&message); } +void set_aprs(const uint32_t baudrate) { + const APRSRxConfigureMessage message { + baudrate + }; + send_message(&message); +} + void set_btle(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word) { const BTLERxConfigureMessage message { baudrate, diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index 43d0eebe..4d19e800 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -68,6 +68,7 @@ void set_afsk_data(const uint32_t afsk_samples_per_bit, const uint32_t afsk_phas const uint8_t afsk_repeat, const uint32_t afsk_bw, const uint8_t symbol_count); void kill_afsk(); void set_afsk(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word); +void set_aprs(const uint32_t baudrate); void set_btle(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word); diff --git a/firmware/application/recent_entries.hpp b/firmware/application/recent_entries.hpp index 90fd5203..661d7660 100644 --- a/firmware/application/recent_entries.hpp +++ b/firmware/application/recent_entries.hpp @@ -179,6 +179,24 @@ public: } } } + else if( event == ui::KeyEvent::Up ) { + if(selected_key == recent.front().key()){ + return false; + } + else { + advance(-1); + return true; + } + } + else if( event == ui::KeyEvent::Down ) { + if( selected_key == recent.back().key()) { + return false; + } + else { + advance(1); + return true; + } + } return false; } @@ -264,7 +282,7 @@ public: // TODO: What happens here shouldn't matter if I do proper damage detection! } - void on_focus() override { + void focus() override { _table.focus(); } diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index 91fcb545..0f4809dc 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -264,8 +264,13 @@ void GeoMapView::focus() { void GeoMapView::update_position(float lat, float lon, uint16_t angle) { lat_ = lat; lon_ = lon; + + // Stupid hack to avoid an event loop + geopos.set_report_change(false); geopos.set_lat(lat_); geopos.set_lon(lon_); + geopos.set_report_change(true); + geomap.set_angle(angle); geomap.move(lon_, lat_); geomap.set_dirty(); diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 9c583aed..c44e7b6e 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -34,6 +34,7 @@ #include "ui_adsb_rx.hpp" #include "ui_adsb_tx.hpp" #include "ui_afsk_rx.hpp" +#include "ui_aprs_rx.hpp" #include "ui_btle_rx.hpp" #include "ui_nrf_rx.hpp" #include "ui_aprs_tx.hpp" @@ -468,7 +469,8 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) { { "POCSAG", ui::Color::green(), &bitmap_icon_pocsag, [&nav](){ nav.push(); } }, { "Radiosnde", ui::Color::green(), &bitmap_icon_sonde, [&nav](){ nav.push(); } }, { "TPMS Cars", ui::Color::green(), &bitmap_icon_tpms, [&nav](){ nav.push(); } }, - /*{ "APRS", ui::Color::dark_grey(), &bitmap_icon_aprs, [&nav](){ nav.push(); } }, + { "APRS", ui::Color::green(), &bitmap_icon_aprs, [&nav](){ nav.push(); } } + /* { "DMR", ui::Color::dark_grey(), &bitmap_icon_dmr, [&nav](){ nav.push(); } }, { "SIGFOX", ui::Color::dark_grey(), &bitmap_icon_fox, [&nav](){ nav.push(); } }, // SIGFRXView { "LoRa", ui::Color::dark_grey(), &bitmap_icon_lora, [&nav](){ nav.push(); } }, diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index c4aafa56..0344ac68 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -312,6 +312,14 @@ set(MODE_CPPSRC proc_afskrx.cpp ) DeclareTargets(PAFR afskrx) + +### APRS RX + +set(MODE_CPPSRC + proc_aprsrx.cpp +) +DeclareTargets(PAPR aprsrx) + ### NRF RX set(MODE_CPPSRC diff --git a/firmware/baseband/proc_aprsrx.cpp b/firmware/baseband/proc_aprsrx.cpp new file mode 100644 index 00000000..56249ce1 --- /dev/null +++ b/firmware/baseband/proc_aprsrx.cpp @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "proc_aprsrx.hpp" +#include "portapack_shared_memory.hpp" + +#include "event_m4.hpp" + +#include "stdio.h" + +void APRSRxProcessor::execute(const buffer_c8_t& buffer) { + // This is called at 3072000 / 2048 = 1500Hz + + if (!configured) return; + + // FM demodulation + const auto decim_0_out = decim_0.execute(buffer, dst_buffer); // 2048 / 8 = 256 (512 I/Q samples) + const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer); // 256 / 8 = 32 (64 I/Q samples) + const auto channel_out = channel_filter.execute(decim_1_out, dst_buffer); // 32 / 2 = 16 (32 I/Q samples) + + feed_channel_stats(channel_out); + + auto audio = demod.execute(channel_out, audio_buffer); + + audio_output.write(audio); + + // Audio signal processing + for (size_t c = 0; c < audio.count; c++) { + + const int32_t sample_int = audio.p[c] * 32768.0f; + int32_t current_sample = __SSAT(sample_int, 16); + + current_sample /= 128; + + // Delay line put + delay_line[delay_line_index & 0x3F] = current_sample; + + // Delay line get, and LPF + sample_mixed = (delay_line[(delay_line_index - (samples_per_bit/2)) & 0x3F] * current_sample) / 4; + sample_filtered = prev_mixed + sample_mixed + (prev_filtered / 2); + + delay_line_index++; + + prev_filtered = sample_filtered; + prev_mixed = sample_mixed; + + // Slice + sample_bits <<= 1; + + uint8_t bit = (sample_filtered < -20) ? 1 : 0; + sample_bits |= bit; + +/* + int16_t scaled = bit == 1 ? 32767 : -32767; + + if( stream ) { + const size_t bytes_to_write = sizeof(scaled) * 1; + const auto result = stream->write(&scaled, bytes_to_write); + } +*/ + + // Check for "clean" transition: either 0011 or 1100 + if ((((sample_bits >> 2) ^ sample_bits) & 3) == 3) { + // Adjust phase + if (phase < 0x8000) + phase += 0x800; // Is this a proper value ? + else + phase -= 0x800; + } + + phase += phase_inc; + + if (phase >= 0x10000) { + phase &= 0xFFFF; + + if (true) { + uint8_t bit; + if(__builtin_popcount(sample_bits & 0xFF) >= 0x05){ + bit = 0x1; + } + else { + bit = 0x0; + } + + if(parse_bit(bit)){ + parse_packet(); + } + } + } + } +} + +void APRSRxProcessor::parse_packet(){ + //validate crc + if(packet_buffer_size >= aprs::APRS_MIN_LENGTH){ + uint16_t crc = 0xFFFF; + + for(size_t i = 0; i < packet_buffer_size; i++){ + uint8_t byte = packet_buffer[i]; + crc = ((crc >> 8) ^ crc_ccitt_tab[(crc ^ byte) & 0xFF]) & 0xFFFF; + } + + if(crc == 0xF0B8){ + parse_ax25(); + } + } +} + +void APRSRxProcessor::parse_ax25(){ + aprs_packet.clear(); + aprs_packet.set_valid_checksum(true); + + for(size_t i = 0; i < packet_buffer_size; i++){ + aprs_packet.set(i, packet_buffer[i]); + } + + APRSPacketMessage packet_message { aprs_packet }; + shared_memory.application_queue.push(packet_message); +} + +bool APRSRxProcessor::parse_bit(const uint8_t current_bit){ + uint8_t decoded_bit = ~(current_bit ^ last_bit) & 0x1; + last_bit = current_bit; + + int16_t log = decoded_bit == 0 ? -32768 : 32767; + + //if( stream ) { + // const size_t bytes_to_write = sizeof(log) * 1; +// const auto result = stream->write(&log, bytes_to_write); +// } + + if(decoded_bit & 0x1){ + if(ones_count < 8){ + ones_count++; + } + } + else { + if(ones_count > 6){ //not valid + state = WAIT_FLAG; + current_byte = 0; + ones_count = 0; + byte_index = 0; + packet_buffer_size = 0; + return false; + } + else if(ones_count == 6){ //flag + bool done = false; + if(state == IN_FRAME){ + done = true; + } + else { + packet_buffer_size = 0; + } + state = WAIT_FRAME; + current_byte = 0; + ones_count = 0; + byte_index = 0; + + return done; + } + else if(ones_count == 5){ //bit stuff + ones_count = 0; + return false; + } + else { + ones_count = 0; + } + } + + //store + current_byte = current_byte >> 1; + current_byte |= (decoded_bit == 0x1 ? 0x80 : 0x0); + byte_index++; + + if(byte_index >= 8){ + byte_index = 0; + if(state == WAIT_FRAME){ + state = IN_FRAME; + } + + if(state == IN_FRAME){ + if(packet_buffer_size + 1 >= 256){ + state = WAIT_FLAG; + current_byte = 0; + ones_count = 0; + byte_index = 0; + packet_buffer_size = 0; + return false; + } + packet_buffer[packet_buffer_size++] = current_byte; + } + } + + return false; +} + +void APRSRxProcessor::on_message(const Message* const message) { + if (message->id == Message::ID::APRSRxConfigure) + configure(*reinterpret_cast(message)); + if(message->id == Message::ID::CaptureConfig) + capture_config(*reinterpret_cast(message)); +} + +void APRSRxProcessor::capture_config(const CaptureConfigMessage& message) { + if( message.config ) { + //stream = std::make_unique(message.config); + audio_output.set_stream(std::make_unique(message.config)); + } else { + //stream.reset(); + audio_output.set_stream(nullptr); + } +} + +void APRSRxProcessor::configure(const APRSRxConfigureMessage& message) { + decim_0.configure(taps_11k0_decim_0.taps, 33554432); + decim_1.configure(taps_11k0_decim_1.taps, 131072); + channel_filter.configure(taps_11k0_channel.taps, 2); + demod.configure(audio_fs, 5000); + + audio_output.configure(audio_24k_hpf_300hz_config, audio_24k_deemph_300_6_config, 0); + + samples_per_bit = audio_fs / message.baudrate; + + phase_inc = (0x10000 * message.baudrate) / audio_fs; + phase = 0; + + // Delay line + delay_line_index = 0; + + state = WAIT_FLAG; + + configured = true; +} + +int main() { + EventDispatcher event_dispatcher { std::make_unique() }; + event_dispatcher.run(); + return 0; +} diff --git a/firmware/baseband/proc_aprsrx.hpp b/firmware/baseband/proc_aprsrx.hpp new file mode 100644 index 00000000..2d3c4568 --- /dev/null +++ b/firmware/baseband/proc_aprsrx.hpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __PROC_APRSRX_H__ +#define __PROC_APRSRX_H__ + +#include "baseband_processor.hpp" +#include "baseband_thread.hpp" +#include "rssi_thread.hpp" + +#include "dsp_decimate.hpp" +#include "dsp_demodulate.hpp" +#include "stream_input.hpp" + +#include "audio_output.hpp" + +#include "fifo.hpp" +#include "message.hpp" + +#include "aprs_packet.hpp" + +static uint16_t crc_ccitt_tab[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +class APRSRxProcessor : public BasebandProcessor { +public: + void execute(const buffer_c8_t& buffer) override; + + void on_message(const Message* const message) override; + +private: + static constexpr size_t baseband_fs = 3072000; + static constexpr size_t audio_fs = baseband_fs / 8 / 8 / 2; + + size_t samples_per_bit { }; + + enum State { + WAIT_FLAG, + WAIT_FRAME, + IN_FRAME + }; + + BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive }; + RSSIThread rssi_thread { NORMALPRIO + 10 }; + + std::array dst { }; + const buffer_c16_t dst_buffer { + dst.data(), + dst.size() + }; + std::array audio { }; + const buffer_f32_t audio_buffer { + audio.data(), + audio.size() + }; + + // Array size ok down to 375 bauds (24000 / 375) + std::array delay_line { 0 }; + + dsp::decimate::FIRC8xR16x24FS4Decim8 decim_0 { }; + dsp::decimate::FIRC16xR16x32Decim8 decim_1 { }; + dsp::decimate::FIRAndDecimateComplex channel_filter { }; + + std::unique_ptr stream { }; + + dsp::demodulate::FM demod { }; + + AudioOutput audio_output { }; + + State state { }; + size_t delay_line_index { }; + uint32_t bit_counter { 0 }; + uint32_t word_bits { 0 }; + uint32_t sample_bits { 0 }; + uint32_t phase { }, phase_inc { }; + int32_t sample_mixed { }, prev_mixed { }, sample_filtered { }, prev_filtered { }; + uint8_t last_bit; + uint8_t ones_count = 0; + uint8_t current_byte = 0; + uint8_t byte_index = 0; + uint8_t packet_buffer[256]; + size_t packet_buffer_size = 0; + + bool configured { false }; + bool wait_start { }; + bool bit_value { }; + + aprs::APRSPacket aprs_packet; + + void configure(const APRSRxConfigureMessage& message); + void capture_config(const CaptureConfigMessage& message); + void parse_packet(); + bool parse_bit(const uint8_t bit); + void parse_ax25(); +}; + +#endif/*__PROC_TPMS_H__*/ diff --git a/firmware/common/aprs_packet.cpp b/firmware/common/aprs_packet.cpp new file mode 100644 index 00000000..e7347ca0 --- /dev/null +++ b/firmware/common/aprs_packet.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "aprs_packet.hpp" + +namespace aprs { + +} /* namespace zwave */ diff --git a/firmware/common/aprs_packet.hpp b/firmware/common/aprs_packet.hpp new file mode 100644 index 00000000..e3d76ece --- /dev/null +++ b/firmware/common/aprs_packet.hpp @@ -0,0 +1,495 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __APRS_PACKET_H__ +#define __APRS_PACKET_H__ + +#include +#include +#include + +#include "baseband.hpp" + +namespace aprs { + +const int APRS_MIN_LENGTH = 18; //14 bytes address, control byte and pid. 2 CRC. + +struct aprs_pos{ + float latitude; + float longitude; + uint8_t symbol_code; + uint8_t sym_table_id; +}; + +enum ADDRESS_TYPE { + SOURCE, + DESTINATION, + REPEATER +}; + +class APRSPacket { +public: + void set_timestamp(const Timestamp& value) { + timestamp_ = value; + } + + Timestamp timestamp() const { + return timestamp_; + } + + void set(const size_t index, const uint8_t data) { + payload[index] = data; + + if(index + 1 > payload_size){ + payload_size = index + 1; + } + } + + uint32_t operator[](const size_t index) const { + return payload[index]; + } + + + uint8_t size() const { + return payload_size; + } + + void set_valid_checksum(const bool valid) { + valid_checksum = valid; + } + + bool is_valid_checksum() const { + return valid_checksum; + } + + uint64_t get_source(){ + uint64_t source = 0x0; + + for(uint8_t i = SOURCE_START; i < SOURCE_START + ADDRESS_SIZE; i++){ + source |= ( ((uint64_t)payload[i]) << ((i - SOURCE_START) * 8)); + } + + return source; + } + + std::string get_source_formatted(){ + parse_address(SOURCE_START, SOURCE); + return std::string(address_buffer); + } + + std::string get_destination_formatted(){ + parse_address(DESTINATION_START, DESTINATION); + return std::string(address_buffer); + } + + std::string get_digipeaters_formatted(){ + uint8_t position = DIGIPEATER_START; + bool has_more = parse_address(SOURCE_START, REPEATER); + + std::string repeaters = ""; + while(has_more){ + has_more = parse_address(position, REPEATER); + repeaters += std::string(address_buffer); + + position += ADDRESS_SIZE; + + if(has_more){ + repeaters += ">"; + } + } + + return repeaters; + } + + uint8_t get_number_of_digipeaters(){ + uint8_t position = DIGIPEATER_START; + bool has_more = parse_address(SOURCE_START, REPEATER); + uint8_t repeaters = 0; + while(has_more){ + has_more = parse_address(position, REPEATER); + position += ADDRESS_SIZE; + repeaters++; + } + + return repeaters; + } + + uint8_t get_information_start_index(){ + return DIGIPEATER_START + (get_number_of_digipeaters() * ADDRESS_SIZE) + 2; + } + + std::string get_information_text_formatted(){ + std::string information_text = ""; + for(uint8_t i = get_information_start_index(); i < payload_size - 2; i++){ + information_text += payload[i]; + } + + return information_text; + } + + std::string get_stream_text(){ + std::string stream = get_source_formatted() + ">" + get_destination_formatted() + ";" + get_digipeaters_formatted() + ";" + get_information_text_formatted(); + + return stream; + } + + char get_data_type_identifier(){ + char ident = '\0'; + for(uint8_t i = get_information_start_index(); i < payload_size - 2; i++){ + ident = payload[i]; + break; + } + return ident; + } + + bool has_position(){ + char ident = get_data_type_identifier(); + + return + ident == '!' || + ident == '=' || + ident == '/' || + ident == '@' || + ident == ';' || + ident == '`' || + ident == '\''|| + ident == 0x1d|| + ident == 0x1c; + } + + aprs_pos get_position(){ + aprs::aprs_pos pos; + + char ident = get_data_type_identifier(); + std::string info_text = get_information_text_formatted(); + + std::string lat_str, lng_str; + char first; + //bool supports_compression = true; + bool is_mic_e_format = false; + std::string::size_type start; + + switch(ident){ + case '/': + case '@': + start = 8; + break; + case '=': + case '!': + start = 1; + break; + case ';': + start = 18; + //supports_compression = false; + break; + case '`': + case '\'': + case 0x1c: + case 0x1d: + is_mic_e_format = true; + break; + default: + return pos; + } + if(is_mic_e_format){ + parse_mic_e_format(pos); + } + else { + if(start < info_text.size()){ + first = info_text.at(start); + + if(std::isdigit(first)){ + if(start + 18 < info_text.size()){ + lat_str = info_text.substr(start, 8); + pos.sym_table_id = info_text.at(start + 8); + lng_str = info_text.substr(start + 9, 9); + pos.symbol_code = info_text.at(start + 18); + + pos.latitude = parse_lat_str(lat_str); + pos.longitude = parse_lng_str(lng_str); + } + + } + else { + if(start + 9 < info_text.size()){ + pos.sym_table_id = info_text.at(start); + lat_str = info_text.substr(start + 1, 4); + lng_str = info_text.substr(start + 5, 4); + pos.symbol_code = info_text.at(start + 9); + + pos.latitude = parse_lat_str_cmp(lat_str); + pos.longitude = parse_lng_str_cmp(lng_str); + } + } + } + } + + return pos; + } + + void clear() { + payload_size = 0; + } + +private: + const uint8_t DIGIPEATER_START = 14; + const uint8_t SOURCE_START = 7; + const uint8_t DESTINATION_START = 0; + const uint8_t ADDRESS_SIZE = 7; + + bool valid_checksum = false; + uint8_t payload[256]; + char address_buffer[15]; + uint8_t payload_size; + Timestamp timestamp_ { }; + + float parse_lat_str_cmp(const std::string& lat_str){ + return 90.0 - ( (lat_str.at(0) - 33) * (91*91*91) + (lat_str.at(1) - 33) * (91*91) + (lat_str.at(2) - 33) * 91 + (lat_str.at(3)) ) / 380926.0; + } + + float parse_lng_str_cmp(const std::string& lng_str){ + return -180.0 + ( (lng_str.at(0) - 33) * (91*91*91) + (lng_str.at(1) - 33) * (91*91) + (lng_str.at(2) - 33) * 91 + (lng_str.at(3)) ) / 190463.0; + } + + uint8_t parse_digits(const std::string& str){ + if(str.at(0) == ' '){ + return 0; + } + uint8_t end = str.find_last_not_of(' ') + 1; + std::string sub = str.substr(0, end); + + if(!is_digits(sub)){ + return 0; + } + else { + return std::stoi(sub); + } + } + + bool is_digits(const std::string& str){ + return str.find_last_not_of("0123456789") == std::string::npos; + } + + float parse_lat_str(const std::string& lat_str){ + float lat = 0.0; + + std::string str_lat_deg = lat_str.substr(0, 2); + std::string str_lat_min = lat_str.substr(2, 2); + std::string str_lat_hund = lat_str.substr(5, 2); + std::string dir = lat_str.substr(7, 1); + + uint8_t lat_deg = parse_digits(str_lat_deg); + uint8_t lat_min = parse_digits(str_lat_min); + uint8_t lat_hund = parse_digits(str_lat_hund); + + lat += lat_deg; + lat += (lat_min + (lat_hund/ 100.0))/60.0; + + if(dir.c_str()[0] == 'S'){ + lat = -lat; + } + + return lat; + + } + + float parse_lng_str(std::string& lng_str){ + float lng = 0.0; + + std::string str_lng_deg = lng_str.substr(0, 3); + std::string str_lng_min = lng_str.substr(3, 2); + std::string str_lng_hund = lng_str.substr(6, 2); + std::string dir = lng_str.substr(8, 1); + + uint8_t lng_deg = parse_digits(str_lng_deg); + uint8_t lng_min = parse_digits(str_lng_min); + uint8_t lng_hund = parse_digits(str_lng_hund); + + lng += lng_deg; + lng += (lng_min + (lng_hund/ 100.0))/60.0; + + if(dir.c_str()[0] == 'W'){ + lng = -lng; + } + + return lng; + + } + + void parse_mic_e_format(aprs::aprs_pos& pos){ + std::string lat_str = ""; + std::string lng_str = ""; + + bool is_north; + bool is_west; + uint8_t lng_offset; + for(uint8_t i = DESTINATION_START; i < DESTINATION_START + ADDRESS_SIZE - 1; i++){ + uint8_t ascii = payload[i] >> 1; + + lat_str += get_mic_e_lat_digit(ascii); + + if(i - DESTINATION_START == 3){ + lat_str += "."; + } + if(i - DESTINATION_START == 3){ + is_north = is_mic_e_lat_N(ascii); + } + if(i - DESTINATION_START == 4){ + lng_offset = get_mic_e_lng_offset(ascii); + } + if(i - DESTINATION_START == 5){ + is_west = is_mic_e_lng_W(ascii); + } + } + if(is_north){ + lat_str += "N"; + } + else { + lat_str += "S"; + } + + pos.latitude = parse_lat_str(lat_str); + + float lng = 0.0; + uint8_t information_start = get_information_start_index() + 1; + for(uint8_t i = information_start; i < information_start + 3 && i < payload_size - 2; i++){ + uint8_t ascii = payload[i]; + + if(i - information_start == 0){ //deg + ascii -=28; + ascii += lng_offset; + + if(ascii >= 180 && ascii <= 189){ + ascii -= 80; + } + else if (ascii >= 190 && ascii <= 199){ + ascii -= 190; + } + + lng += ascii; + } + else if(i - information_start == 1){ //min + ascii -= 28; + if(ascii >= 60){ + ascii -= 60; + } + lng += ascii/60.0; + } + else if(i - information_start == 2){ //hundredth minutes + ascii -= 28; + + lng += (ascii/100.0)/60.0; + } + } + + if(is_west){ + lng = -lng; + } + + pos.longitude = lng; + + } + + uint8_t get_mic_e_lat_digit(uint8_t ascii){ + if(ascii >= '0' && ascii <= '9'){ + return ascii; + } + if(ascii >= 'A' && ascii <= 'J'){ + return ascii - 17; + } + if(ascii >= 'P' && ascii <='Y'){ + return ascii - 32; + } + if(ascii == 'K' || ascii == 'L' || ascii == 'Z'){ + return ' '; + } + + return '\0'; + } + + bool is_mic_e_lat_N(uint8_t ascii){ + if(ascii >= 'P' && ascii <='Z'){ + return true; + } + return false; //not technical definition, but the other case is invalid + } + + bool is_mic_e_lng_W(uint8_t ascii){ + if(ascii >= 'P' && ascii <='Z'){ + return true; + } + return false; //not technical definition, but the other case is invalid + } + + uint8_t get_mic_e_lng_offset(uint8_t ascii){ + if(ascii >= 'P' && ascii <='Z'){ + return 100; + } + return 0; //not technical definition, but the other case is invalid + } + + bool parse_address(uint8_t start, ADDRESS_TYPE address_type){ + uint8_t byte = 0; + uint8_t has_more = false; + uint8_t ssid = 0; + uint8_t buffer_index = 0; + + for(uint8_t i = start; i < start + ADDRESS_SIZE && i < payload_size - 2; i++){ + byte = payload[i]; + + if(i - start == 6){ + has_more = (byte & 0x1) == 0; + ssid = (byte >> 1) & 0x0F; + + if(ssid != 0 || address_type == REPEATER){ + address_buffer[buffer_index++] = '-'; + + if(ssid < 10){ + address_buffer[buffer_index++] = '0' + ssid; + address_buffer[buffer_index++] = '\0'; + } + else { + address_buffer[buffer_index++] = '1'; + address_buffer[buffer_index++] = '0' + ssid - 10; + address_buffer[buffer_index++] = '\0'; + } + } + else { + address_buffer[buffer_index++] = '\0'; + } + } + else { + byte >>= 1; + + if(byte != ' '){ + address_buffer[buffer_index++] = byte; + } + } + } + + return has_more; + } +}; + +} /* namespace aprs */ + +#endif/*__APRS_PACKET_H__*/ diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 32a8fc7b..239c1530 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -36,6 +36,7 @@ #include "adsb_frame.hpp" #include "ert_packet.hpp" #include "pocsag_packet.hpp" +#include "aprs_packet.hpp" #include "sonde_packet.hpp" #include "tpms_packet.hpp" #include "jammer.hpp" @@ -111,6 +112,8 @@ public: AudioLevelReport = 51, CodedSquelch = 52, AudioSpectrum = 53, + APRSPacket = 54, + APRSRxConfigure = 55, MAX }; @@ -725,6 +728,18 @@ public: const bool trigger_word; }; +class APRSRxConfigureMessage : public Message { +public: + constexpr APRSRxConfigureMessage( + const uint32_t baudrate + ) : Message { ID::APRSRxConfigure }, + baudrate(baudrate) + { + } + + const uint32_t baudrate; +}; + class BTLERxConfigureMessage : public Message { public: constexpr BTLERxConfigureMessage( @@ -1002,6 +1017,19 @@ public: const bool phase; }; +class APRSPacketMessage : public Message { +public: + constexpr APRSPacketMessage( + const aprs::APRSPacket& packet + ) : Message { ID::APRSPacket }, + packet { packet } + { + } + + aprs::APRSPacket packet; +}; + + class ADSBConfigureMessage : public Message { public: constexpr ADSBConfigureMessage( diff --git a/firmware/common/spi_image.hpp b/firmware/common/spi_image.hpp index 5ff88054..758429c8 100644 --- a/firmware/common/spi_image.hpp +++ b/firmware/common/spi_image.hpp @@ -77,6 +77,7 @@ private: constexpr image_tag_t image_tag_acars { 'P', 'A', 'C', 'A' }; constexpr image_tag_t image_tag_adsb_rx { 'P', 'A', 'D', 'R' }; constexpr image_tag_t image_tag_afsk_rx { 'P', 'A', 'F', 'R' }; +constexpr image_tag_t image_tag_aprs_rx { 'P', 'A', 'P', 'R' }; constexpr image_tag_t image_tag_btle_rx { 'P', 'B', 'T', 'R' }; constexpr image_tag_t image_tag_nrf_rx { 'P', 'N', 'R', 'R' }; constexpr image_tag_t image_tag_ais { 'P', 'A', 'I', 'S' }; diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index 12bf1927..85ad91f1 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -597,11 +597,14 @@ Console::Console( void Console::clear(bool clear_buffer = false) { if(clear_buffer) buffer.clear(); - - display.fill_rectangle( - screen_rect(), - Color::black() - ); + + if(!hidden() && visible()){ + display.fill_rectangle( + screen_rect(), + Color::black() + ); + } + pos = { 0, 0 }; } @@ -648,8 +651,7 @@ void Console::write(std::string message) { } void Console::writeln(std::string message) { - write(message); - write("\n"); + write(message + "\n"); //crlf(); } @@ -658,18 +660,31 @@ void Console::paint(Painter&) { } void Console::on_show() { - const auto screen_r = screen_rect(); - display.scroll_set_area(screen_r.top(), screen_r.bottom()); - display.scroll_set_position(0); + enable_scrolling(true); clear(); //visible = true; } +bool Console::scrolling_enabled = false; + +void Console::enable_scrolling(bool enable){ + if(enable){ + const auto screen_r = screen_rect(); + display.scroll_set_area(screen_r.top(), screen_r.bottom()); + display.scroll_set_position(0); + scrolling_enabled = true; + } + else { + display.scroll_disable(); + scrolling_enabled = false; + } +} + void Console::on_hide() { /* TODO: Clear region to eliminate brief flash of content at un-shifted * position? */ - display.scroll_disable(); + enable_scrolling(false); //visible = false; } @@ -682,6 +697,9 @@ void Console::crlf() { pos = { 0, pos.y() + line_height }; const int32_t y_excess = pos.y() + line_height - sr.height(); if( y_excess > 0 ) { + if(!scrolling_enabled){ + enable_scrolling(true); + } display.scroll(-y_excess); pos = { pos.x(), pos.y() - y_excess }; @@ -1293,9 +1311,9 @@ size_t OptionsField::selected_index_value() const { return options[selected_index_].second; } -void OptionsField::set_selected_index(const size_t new_index) { +void OptionsField::set_selected_index(const size_t new_index, bool trigger_change) { if( new_index < options.size() ) { - if( new_index != selected_index() ) { + if( new_index != selected_index() || trigger_change) { selected_index_ = new_index; if( on_change ) { on_change(selected_index(), options[selected_index()].second); diff --git a/firmware/common/ui_widget.hpp b/firmware/common/ui_widget.hpp index f66da710..71cd8f91 100644 --- a/firmware/common/ui_widget.hpp +++ b/firmware/common/ui_widget.hpp @@ -325,6 +325,7 @@ public: void paint(Painter&) override; + void enable_scrolling(bool enable); void on_show() override; void on_hide() override; @@ -332,6 +333,7 @@ private: //bool visible = false; Point pos { 0, 0 }; std::string buffer { }; + static bool scrolling_enabled; void crlf(); }; @@ -545,7 +547,7 @@ public: size_t selected_index() const; size_t selected_index_value() const; - void set_selected_index(const size_t new_index); + void set_selected_index(const size_t new_index, bool trigger_change = true); void set_by_value(value_t v); From f65852ff05b1b4ba22ad0536c263afb04a662032 Mon Sep 17 00:00:00 2001 From: "DESKTOP-R56EVJP\\Alex" Date: Sun, 21 Mar 2021 20:11:40 -0500 Subject: [PATCH 38/52] Rebased code from new eried repo commits. Changed to to reflect strijar implementation. Fixed previous issue with old ssb-am-tx ui_mictx code. --- firmware/application/apps/soundboard_app.cpp | 6 +- firmware/application/apps/ui_mictx.cpp | 84 ++- firmware/application/apps/ui_mictx.cpp.1 | 526 +++++++++++++++++++ firmware/application/apps/ui_mictx.hpp | 32 +- firmware/application/apps/ui_mictx.hpp.1 | 344 ++++++++++++ firmware/application/baseband_api.cpp | 9 +- firmware/application/baseband_api.hpp | 3 +- firmware/baseband/CMakeLists.txt | 3 + firmware/baseband/dsp_hilbert.cpp | 57 ++ firmware/baseband/dsp_hilbert.hpp | 44 ++ firmware/baseband/dsp_modulate.cpp | 137 +++++ firmware/baseband/dsp_modulate.hpp | 96 ++++ firmware/baseband/proc_mictx.cpp | 38 +- firmware/baseband/proc_mictx.hpp | 10 +- firmware/common/dsp_iir.cpp | 26 + firmware/common/dsp_iir.hpp | 20 + firmware/common/dsp_sos.cpp | 22 + firmware/common/dsp_sos.hpp | 51 ++ firmware/common/dsp_sos_config.hpp | 37 ++ firmware/common/message.hpp | 16 +- 20 files changed, 1545 insertions(+), 16 deletions(-) create mode 100644 firmware/application/apps/ui_mictx.cpp.1 create mode 100644 firmware/application/apps/ui_mictx.hpp.1 create mode 100644 firmware/baseband/dsp_hilbert.cpp create mode 100644 firmware/baseband/dsp_hilbert.hpp create mode 100644 firmware/baseband/dsp_modulate.cpp create mode 100644 firmware/baseband/dsp_modulate.hpp create mode 100644 firmware/common/dsp_sos.cpp create mode 100644 firmware/common/dsp_sos.hpp create mode 100644 firmware/common/dsp_sos_config.hpp diff --git a/firmware/application/apps/soundboard_app.cpp b/firmware/application/apps/soundboard_app.cpp index 4682d985..2c93822f 100644 --- a/firmware/application/apps/soundboard_app.cpp +++ b/firmware/application/apps/soundboard_app.cpp @@ -110,7 +110,11 @@ void SoundBoardView::start_tx(const uint32_t id) { 1536000 / 20, // Update vu-meter at 20Hz transmitter_model.channel_bandwidth(), 0, // Gain is unused - TONES_F2D(tone_key_frequency(tone_key_index), 1536000) + TONES_F2D(tone_key_frequency(tone_key_index), 1536000), + 0, //AM + 0, //DSB + 0, //USB + 0 //LSB ); baseband::set_sample_rate(sample_rate); diff --git a/firmware/application/apps/ui_mictx.cpp b/firmware/application/apps/ui_mictx.cpp index 82e66408..0e2c9c47 100644 --- a/firmware/application/apps/ui_mictx.cpp +++ b/firmware/application/apps/ui_mictx.cpp @@ -65,8 +65,13 @@ void MicTXView::configure_baseband() { sampling_rate / 20, // Update vu-meter at 20Hz transmitting ? transmitter_model.channel_bandwidth() : 0, mic_gain, - TONES_F2D(tone_key_frequency(tone_key_index), sampling_rate) + TONES_F2D(tone_key_frequency(tone_key_index), sampling_rate), + enable_am, + enable_dsb, + enable_usb, + enable_lsb ); + } void MicTXView::set_tx(bool enable) { @@ -143,8 +148,20 @@ void MicTXView::rxaudio(bool is_on) { if (is_on) { audio::input::stop(); baseband::shutdown(); - baseband::run_image(portapack::spi_flash::image_tag_nfm_audio); - receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); + + if (enable_am || enable_usb || enable_lsb || enable_dsb) { + baseband::run_image(portapack::spi_flash::image_tag_am_audio); + receiver_model.set_modulation(ReceiverModel::Mode::AMAudio); + if (options_mode.selected_index() < 4) + receiver_model.set_am_configuration(options_mode.selected_index() - 1); + else + receiver_model.set_am_configuration(0); + } + else { + baseband::run_image(portapack::spi_flash::image_tag_nfm_audio); + receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); + + } receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000); // receiver_model.set_tuning_frequency(field_frequency.value()); //probably this too can be commented out. @@ -155,15 +172,15 @@ void MicTXView::rxaudio(bool is_on) { receiver_model.enable(); audio::output::start(); } else { //These incredibly convoluted steps are required for the vumeter to reappear when stopping RX. + receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); //This fixes something with AM RX... receiver_model.disable(); baseband::shutdown(); + baseband::run_image(portapack::spi_flash::image_tag_mic_tx); - audio::input::start(); -// transmitter_model.enable(); + audio::output::stop(); + audio::input::start(); portapack::pin_i2s0_rx_sda.mode(3); -// transmitting = false; configure_baseband(); -// transmitter_model.disable(); } } @@ -198,11 +215,13 @@ MicTXView::MicTXView( &field_bw, &field_rfgain, &field_rfamp, + &options_mode, &field_frequency, &options_tone_key, &check_rogerbeep, &check_rxactive, &field_volume, + &field_rxbw, &field_squelch, &field_rxfrequency, &field_rxlna, @@ -262,6 +281,42 @@ MicTXView::MicTXView( }; field_rfamp.set_value(rf_amp ? 14 : 0); + options_mode.on_change = [this](size_t, int32_t v) { + enable_am = false; + enable_usb = false; + enable_lsb = false; + enable_dsb = false; + switch(v) { + case 0: + enable_am = false; + enable_usb = false; + enable_lsb = false; + enable_dsb = false; + field_bw.set_value(transmitter_model.channel_bandwidth() / 1000); + //if (rx_enabled) + rxaudio(rx_enabled); //Update now if we have RX audio on + break; + case 1: + enable_am = true; + rxaudio(rx_enabled); //Update now if we have RX audio on + break; + case 2: + enable_usb = true; + rxaudio(rx_enabled); //Update now if we have RX audio on + break; + case 3: + enable_lsb = true; + rxaudio(rx_enabled); //Update now if we have RX audio on + break; + case 4: + enable_dsb = true; + rxaudio(rx_enabled); //Update now if we have RX audio on + break; + } + //configure_baseband(); + }; + + /* check_va.on_select = [this](Checkbox&, bool v) { va_enabled = v; @@ -331,6 +386,21 @@ MicTXView::MicTXView( field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99); field_volume.on_change = [this](int32_t v) { this->on_headphone_volume_changed(v); }; + field_rxbw.on_change = [this](size_t, int32_t v) { + switch(v) { + case 0: + receiver_model.set_nbfm_configuration(0); + break; + case 1: + receiver_model.set_nbfm_configuration(1); + break; + case 2: + receiver_model.set_nbfm_configuration(2); + break; + } + }; + field_rxbw.set_selected_index(2); + field_squelch.on_change = [this](int32_t v) { receiver_model.set_squelch_level(100 - v); }; diff --git a/firmware/application/apps/ui_mictx.cpp.1 b/firmware/application/apps/ui_mictx.cpp.1 new file mode 100644 index 00000000..9476584b --- /dev/null +++ b/firmware/application/apps/ui_mictx.cpp.1 @@ -0,0 +1,526 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "ui_mictx.hpp" + +#include "baseband_api.hpp" +#include "audio.hpp" +#include "tonesets.hpp" +#include "portapack_hal.hpp" +#include "string_format.hpp" +#include "irq_controls.hpp" + + +#include + +using namespace tonekey; +using namespace portapack; + +namespace ui { + +void MicTXView::focus() { + switch(focused_ui) { + case 0: + field_frequency.focus(); + break; + case 1: + field_rxfrequency.focus(); + break; + default: + //field_va.focus(); + tx_button.focus(); + break; + } +} + +void MicTXView::update_vumeter() { + vumeter.set_value(audio_level); +} + +void MicTXView::on_tx_progress(const bool done) { + // Roger beep played, stop transmitting + if (done) + set_tx(false); +} + +void MicTXView::configure_baseband() { + baseband::set_audiotx_config( + sampling_rate / 20, // Update vu-meter at 20Hz + transmitting ? transmitter_model.channel_bandwidth() : 0, + mic_gain, + TONES_F2D(tone_key_frequency(tone_key_index), sampling_rate), + enable_am, + am_carrier_lvl, + 0, + enable_usb, + enable_lsb + ); + +} + +void MicTXView::set_tx(bool enable) { + if (enable) { + if (rx_enabled) //If audio RX is enabled + rxaudio(false); //Then turn off audio RX + receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); // Weird workaround for FM TX + transmitting = true; + configure_baseband(); + transmitter_model.set_tuning_frequency(tx_frequency); + transmitter_model.set_tx_gain(tx_gain); + transmitter_model.set_rf_amp(rf_amp); + 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 { + if (transmitting && rogerbeep_enabled) { + baseband::request_beep(); //Transmit the roger beep + transmitting = false; //And flag the end of the transmission so ... + } else { // (if roger beep was enabled, this will be executed after the beep ends transmitting. + transmitting = false; + configure_baseband(); + transmitter_model.disable(); + if (rx_enabled) //If audio RX is enabled and we've been transmitting + rxaudio(true); //Turn back on audio RX + } + } +} + +void MicTXView::do_timing() { + if (va_enabled) { + if (!transmitting) { + // Attack + if (audio_level >= va_level) { + if ((attack_timer >> 8) >= attack_ms) { + decay_timer = 0; + attack_timer = 0; + set_tx(true); + } else { + attack_timer += lcd_frame_duration; + } + } else { + attack_timer = 0; + } + } else { + // Decay + if (audio_level < va_level) { + if ((decay_timer >> 8) >= decay_ms) { + decay_timer = 0; + attack_timer = 0; + set_tx(false); + } else { + decay_timer += lcd_frame_duration; + } + } else { + decay_timer = 0; + } + } + } else { + // Check for PTT release + const auto switches_state = get_switches_state(); + if (!switches_state[4] && transmitting && !button_touch) // Select button + set_tx(false); + } +} + +/* Hmmmm. Maybe useless now. +void MicTXView::on_tuning_frequency_changed(rf::Frequency f) { + transmitter_model.set_tuning_frequency(f); + //if ( rx_enabled ) + receiver_model.set_tuning_frequency(f); //Update freq also for RX +} +*/ + +void MicTXView::rxaudio(bool is_on) { + if (is_on) { + audio::input::stop(); + baseband::shutdown(); + + if (enable_am || enable_usb || enable_lsb) { + baseband::run_image(portapack::spi_flash::image_tag_am_audio); + receiver_model.set_modulation(ReceiverModel::Mode::AMAudio); + if (options_mode.selected_index() < 4) + receiver_model.set_am_configuration(options_mode.selected_index() - 1); + else + receiver_model.set_am_configuration(0); + } + else { + baseband::run_image(portapack::spi_flash::image_tag_nfm_audio); + receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); + + } + receiver_model.set_sampling_rate(3072000); + receiver_model.set_baseband_bandwidth(1750000); +// receiver_model.set_tuning_frequency(field_frequency.value()); //probably this too can be commented out. + receiver_model.set_tuning_frequency(rx_frequency); // Now with seperate controls! + receiver_model.set_lna(rx_lna); + receiver_model.set_vga(rx_vga); + receiver_model.set_rf_amp(rx_amp); + receiver_model.enable(); + audio::output::start(); + } else { //These incredibly convoluted steps are required for the vumeter to reappear when stopping RX. + //baseband::run_image(portapack::spi_flash::image_tag_nfm_audio); //There is something seriously wrong if these two lines fixes the issue with AM TX... + receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); + receiver_model.disable(); + baseband::shutdown(); + + baseband::run_image(portapack::spi_flash::image_tag_mic_tx); + audio::output::stop(); + audio::input::start(); +// transmitter_model.enable(); + portapack::pin_i2s0_rx_sda.mode(3); +// transmitting = false; + configure_baseband(); +// transmitter_model.disable(); + } +} + +void MicTXView::on_headphone_volume_changed(int32_t v) { + //if (rx_enabled) { + const auto new_volume = volume_t::decibel(v - 99) + audio::headphone::volume_range().max; + receiver_model.set_headphone_volume(new_volume); + //} +} + +void MicTXView::set_ptt_visibility(bool v) { + tx_button.hidden(!v); +} + +MicTXView::MicTXView( + NavigationView& nav +) +{ + portapack::pin_i2s0_rx_sda.mode(3); // This is already done in audio::init but gets changed by the CPLD overlay reprogramming + + baseband::run_image(portapack::spi_flash::image_tag_mic_tx); + + + + add_children({ + &labels, + &vumeter, + &options_gain, +// &check_va, + &field_va, + &field_rxbw, + &field_va_level, + &field_va_attack, + &field_va_decay, +// &field_carrier, + &field_bw, + &field_rfgain, + &field_rfamp, + &field_frequency, + &options_tone_key, + &options_mode, + &check_rogerbeep, + &check_rxactive, + &field_volume, + &field_squelch, + &field_rxfrequency, + &field_rxlna, + &field_rxvga, + &field_rxamp, + &tx_button + }); + + + + tone_keys_populate(options_tone_key); + options_tone_key.on_change = [this](size_t i, int32_t) { + tone_key_index = i; + }; + options_tone_key.set_selected_index(0); + + options_gain.on_change = [this](size_t, int32_t v) { + mic_gain = v / 10.0; + configure_baseband(); + }; + options_gain.set_selected_index(1); // x1.0 + + options_mode.on_change = [this](size_t, int32_t v) { + enable_am = false; + enable_usb = false; + enable_lsb = false; + switch(v) { + case 0: + enable_am = false; + enable_usb = false; + enable_lsb = false; + field_bw.set_value(transmitter_model.channel_bandwidth() / 1000); + //if (rx_enabled) + rxaudio(rx_enabled); + break; + case 1: + enable_am = true; + am_carrier_lvl = 20; + //if (rx_enabled) + rxaudio(rx_enabled); + break; + case 2: + enable_am = true; + enable_usb = true; + //if (rx_enabled) + rxaudio(rx_enabled); + break; + case 3: + enable_am = true; + enable_lsb = true; + + //if (rx_enabled) + rxaudio(rx_enabled); + break; + case 4: + enable_usb = false; + enable_lsb = false; + enable_am = true; + am_carrier_lvl = 0; + //if (rx_enabled) + rxaudio(rx_enabled); + break; + } + //configure_baseband(); + }; + + tx_frequency = transmitter_model.tuning_frequency(); + field_frequency.set_value(transmitter_model.tuning_frequency()); + field_frequency.set_step(receiver_model.frequency_step()); + field_frequency.on_change = [this](rf::Frequency f) { + tx_frequency = f; + if(!rx_enabled) + transmitter_model.set_tuning_frequency(f); + }; + field_frequency.on_edit = [this, &nav]() { + focused_ui = 0; + // TODO: Provide separate modal method/scheme? + auto new_view = nav.push(tx_frequency); + new_view->on_changed = [this](rf::Frequency f) { + tx_frequency = f; + if(!rx_enabled) + transmitter_model.set_tuning_frequency(f); + this->field_frequency.set_value(f); + set_dirty(); + }; + }; + + field_rxbw.on_change = [this](size_t, int32_t v) { + switch(v) { + case 0: + receiver_model.set_nbfm_configuration(0); + break; + case 1: + receiver_model.set_nbfm_configuration(1); + break; + case 2: + receiver_model.set_nbfm_configuration(2); + break; + } + }; + field_rxbw.set_selected_index(2); + + field_bw.on_change = [this](uint32_t v) { + transmitter_model.set_channel_bandwidth(v * 1000); + }; + field_bw.set_value(10); + +// field_carrier.on_change = [this](uint32_t v) { +// am_carrier_lvl = v; +// }; +// field_carrier.set_value(am_carrier_lvl); + tx_gain = transmitter_model.tx_gain(); + + field_rfgain.on_change = [this](int32_t v) { + tx_gain = v; + + }; + + field_rfgain.set_value(tx_gain); + + rf_amp = transmitter_model.rf_amp(); + field_rfamp.on_change = [this](int32_t v) { + rf_amp = (bool)v; + }; + field_rfamp.set_value(rf_amp ? 14 : 0); + +/* + check_va.on_select = [this](Checkbox&, bool v) { + va_enabled = v; + text_ptt.hidden(v); //hide / show PTT text + check_rxactive.hidden(v); //hide / show the RX AUDIO + set_dirty(); //Refresh display + }; */ + + field_va.set_selected_index(1); + field_va.on_change = [this](size_t, int32_t v) { + switch(v) { + case 0: + va_enabled = 0; + this->set_ptt_visibility(0); + check_rxactive.hidden(0); + ptt_enabled = 0; + break; + case 1: + va_enabled = 0; + this->set_ptt_visibility(1); + check_rxactive.hidden(0); + ptt_enabled = 1; + break; + case 2: + if (!rx_enabled) { + va_enabled = 1; + this->set_ptt_visibility(0); + check_rxactive.hidden(1); + ptt_enabled = 0; + } else { + field_va.set_selected_index(1); + } + break; + } + set_dirty(); + }; + + check_rogerbeep.on_select = [this](Checkbox&, bool v) { + rogerbeep_enabled = v; + }; + + field_va_level.on_change = [this](int32_t v) { + va_level = v; + vumeter.set_mark(v); + }; + field_va_level.set_value(40); + + field_va_attack.on_change = [this](int32_t v) { + attack_ms = v; + }; + field_va_attack.set_value(500); + + field_va_decay.on_change = [this](int32_t v) { + decay_ms = v; + }; + field_va_decay.set_value(1000); + + check_rxactive.on_select = [this](Checkbox&, bool v) { +// vumeter.set_value(0); //Start with a clean vumeter + rx_enabled = v; +// check_va.hidden(v); //Hide or show voice activation + rxaudio(v); //Activate-Deactivate audio rx accordingly + set_dirty(); //Refresh interface + }; + + + + //field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99); + field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99); + field_volume.on_change = [this](int32_t v) { this->on_headphone_volume_changed(v); }; + + field_squelch.on_change = [this](int32_t v) { + receiver_model.set_squelch_level(100 - v); + }; + field_squelch.set_value(0); + receiver_model.set_squelch_level(0); + + rx_frequency = receiver_model.tuning_frequency(); + field_rxfrequency.set_value(rx_frequency); + field_rxfrequency.set_step(receiver_model.frequency_step()); + + field_rxfrequency.on_change = [this](rf::Frequency f) { + rx_frequency = f; + if(rx_enabled) + receiver_model.set_tuning_frequency(f); + }; + field_rxfrequency.on_edit = [this, &nav]() { + focused_ui = 1; + // TODO: Provide separate modal method/scheme? + auto new_view = nav.push(rx_frequency); + new_view->on_changed = [this](rf::Frequency f) { + rx_frequency = f; + if(rx_enabled) + receiver_model.set_tuning_frequency(f); + this->field_rxfrequency.set_value(f); + set_dirty(); + }; + }; + + + rx_lna = receiver_model.lna(); + field_rxlna.on_change = [this](int32_t v) { + rx_lna = v; + if(rx_enabled) + receiver_model.set_lna(v); + }; + field_rxlna.set_value(rx_lna); + + rx_vga = receiver_model.vga(); + field_rxvga.on_change = [this](int32_t v) { + rx_vga = v; + if(rx_enabled) + receiver_model.set_vga(v); + }; + field_rxvga.set_value(rx_vga); + + rx_amp = receiver_model.rf_amp(); + + field_rxamp.on_change = [this](int32_t v) { + rx_amp = v; + if(rx_enabled) + receiver_model.set_rf_amp(rx_amp); + }; + field_rxamp.set_value(rx_amp); + receiver_model.set_rf_amp(rx_amp); + + tx_button.on_select = [this](Button&) { + if(ptt_enabled && !transmitting) { + set_tx(true); + } + }; + + tx_button.on_touch_release = [this](Button&) { + if(button_touch) { + button_touch = false; + set_tx(false); + } + }; + + tx_button.on_touch_press = [this](Button&) { + if(!transmitting) { + button_touch = true; + } + }; + + transmitter_model.set_sampling_rate(sampling_rate); + transmitter_model.set_baseband_bandwidth(1750000); + + set_tx(false); + + audio::set_rate(audio::Rate::Hz_24000); + audio::input::start(); +} + +MicTXView::~MicTXView() { + + audio::input::stop(); + transmitter_model.set_tuning_frequency(tx_frequency); // Save Tx frequency instead of Rx. Or maybe we need some "System Wide" changes to seperate Tx and Rx frequency. + transmitter_model.disable(); + if (rx_enabled) //Also turn off audio rx if enabled + rxaudio(false); + baseband::shutdown(); +} + +} diff --git a/firmware/application/apps/ui_mictx.hpp b/firmware/application/apps/ui_mictx.hpp index 2b7853da..9084047a 100644 --- a/firmware/application/apps/ui_mictx.hpp +++ b/firmware/application/apps/ui_mictx.hpp @@ -99,19 +99,27 @@ private: int32_t focused_ui { 2 }; bool button_touch { false }; + //AM TX Stuff + bool enable_am { false }; + bool enable_dsb { false }; + bool enable_usb { false }; + bool enable_lsb { false }; + Labels labels { { { 3 * 8, 1 * 8 }, "MIC. GAIN:", Color::light_grey() }, { { 3 * 8, 3 * 8 }, "F:", Color::light_grey() }, - { { 15 * 8, 3 * 8 }, "BW: kHz", Color::light_grey() }, + { { 15 * 8, 3 * 8 }, "BW: FM kHz", Color::light_grey() }, { { 3 * 8, 5 * 8 }, "GAIN:", Color::light_grey() }, { {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() }, + { { 18 * 8, (5 * 8) }, "Mode:", Color::light_grey() }, { { 3 * 8, 8 * 8 }, "TX Activation:", Color::light_grey() }, { { 4 * 8, 10 * 8 }, "LVL:", Color::light_grey() }, { {12 * 8, 10 * 8 }, "ATT:", Color::light_grey() }, { {20 * 8, 10 * 8 }, "DEC:", Color::light_grey() }, { { 4 * 8, ( 13 * 8 ) - 2 }, "TONE KEY:", Color::light_grey() }, { { 9 * 8, 23 * 8 }, "VOL:", Color::light_grey() }, + { {17 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() }, { {17 * 8, 25 * 8 }, "SQ:", Color::light_grey() }, { { 5 * 8, 25 * 8 }, "F:", Color::light_grey() }, { { 5 * 8, 27 * 8 }, "LNA:", Color::light_grey()}, @@ -162,6 +170,18 @@ private: 14, ' ' }; + + OptionsField options_mode { + { 24 * 8, 5 * 8 }, + 3, + { + { "FM", 0 }, + { "AM", 1 }, + { "USB", 2 }, + { "LSB", 3 }, + { "DSB", 4 } + } + }; /* Checkbox check_va { { 3 * 8, (10 * 8) - 4 }, @@ -231,6 +251,16 @@ private: ' ', }; + OptionsField field_rxbw { + { 25 * 8, 23 * 8}, + 3, + { + {"8k5", 0}, + {"11k", 1}, + {"16k", 2} + } + }; + NumberField field_squelch { { 20 * 8, 25 * 8 }, 2, diff --git a/firmware/application/apps/ui_mictx.hpp.1 b/firmware/application/apps/ui_mictx.hpp.1 new file mode 100644 index 00000000..3761c401 --- /dev/null +++ b/firmware/application/apps/ui_mictx.hpp.1 @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __UI_MICTX_H__ +#define __UI_MICTX_H__ + +#include "ui.hpp" +#include "ui_widget.hpp" +#include "ui_navigation.hpp" +#include "ui_receiver.hpp" +#include "transmitter_model.hpp" +#include "tone_key.hpp" +#include "message.hpp" +#include "receiver_model.hpp" + +namespace ui { + +class MicTXView : public View { +public: + MicTXView(NavigationView& nav); + ~MicTXView(); + + MicTXView(const MicTXView&) = delete; + MicTXView(MicTXView&&) = delete; + MicTXView& operator=(const MicTXView&) = delete; + MicTXView& operator=(MicTXView&&) = delete; + + void focus() override; + + // PTT: Enable through KeyEvent (only works with presses), disable by polling :( + // This is the old "RIGHT BUTTON" method. + +/* bool on_key(const KeyEvent key) { + if ((key == KeyEvent::Right) && (!va_enabled) && ptt_enabled) { + set_tx(true); + return true; + } else + return false; + }; */ + + + std::string title() const override { return "Mic TX RX"; }; + +private: + static constexpr uint32_t sampling_rate = 1536000U; + static constexpr uint32_t lcd_frame_duration = (256 * 1000UL) / 60; // 1 frame @ 60fps in ms .8 fixed point /60 + + void update_vumeter(); + void do_timing(); + void set_tx(bool enable); +// void on_tuning_frequency_changed(rf::Frequency f); + void on_tx_progress(const bool done); + void configure_baseband(); + + void rxaudio(bool is_on); + void on_headphone_volume_changed(int32_t v); + + void set_ptt_visibility(bool v); + + bool transmitting { false }; + bool va_enabled { false }; + bool ptt_enabled { true }; + bool rogerbeep_enabled { false }; + bool rx_enabled { false }; + uint32_t tone_key_index { }; + float mic_gain { 1.0 }; + uint32_t audio_level { 0 }; + uint32_t va_level { }; + uint32_t attack_ms { }; + uint32_t decay_ms { }; + uint32_t attack_timer { 0 }; + uint32_t decay_timer { 0 }; + int32_t tx_gain { 47 }; + bool rf_amp { false }; + int32_t rx_lna { 32 }; + int32_t rx_vga { 32 }; + bool rx_amp { false }; + rf::Frequency tx_frequency { 0 }; + rf::Frequency rx_frequency { 0 }; + int32_t focused_ui { 2 }; + bool button_touch { false }; + + //AM TX Stuff + bool enable_usb { false }; + bool enable_lsb { false }; + bool enable_am { false }; + uint32_t am_carrier_lvl { 20 }; +// uint32_t am_mod_div { 1 }; + + + Labels labels { + { { 3 * 8, 1 * 8 }, "MIC. GAIN:", Color::light_grey() }, + { { 3 * 8, 3 * 8 }, "F:", Color::light_grey() }, + { { 15 * 8, 3 * 8 }, "BW: FM kHz", Color::light_grey() }, + { { 3 * 8, 5 * 8 }, "GAIN:", Color::light_grey() }, + { {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() }, + { { 18 * 8, (5 * 8) }, "Mode:", Color::light_grey() }, +// { { 21 * 8, (1 * 8) }, "AM Car:", Color::light_grey() }, +// { { 20 * 8, (16 * 8) + 2 }, "AMCAR:", Color::light_grey() }, + { { 3 * 8, 8 * 8 }, "TX Activation:", Color::light_grey() }, + { { 4 * 8, 10 * 8 }, "LVL:", Color::light_grey() }, + { {12 * 8, 10 * 8 }, "ATT:", Color::light_grey() }, + { {20 * 8, 10 * 8 }, "DEC:", Color::light_grey() }, + { { 4 * 8, ( 13 * 8 ) - 2 }, "TONE KEY:", Color::light_grey() }, + { { 5 * 8, 23 * 8 }, "VOL:", Color::light_grey() }, + { {17 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() }, + { {17 * 8, 25 * 8 }, "SQ:", Color::light_grey() }, + { { 5 * 8, 25 * 8 }, "F:", Color::light_grey() }, + { { 5 * 8, 27 * 8 }, "LNA:", Color::light_grey()}, + { {12 * 8, 27 * 8 }, "VGA:", Color::light_grey()}, + { {19 * 8, 27 * 8 }, "AMP:", Color::light_grey()} + }; + + VuMeter vumeter { + { 0 * 8, 1 * 8, 2 * 8, 33 * 8 }, + 12, + true + }; + + + OptionsField options_gain { + { 13 * 8, 1 * 8 }, + 4, + { + { "x0.5", 5 }, + { "x1.0", 10 }, + { "x1.5", 15 }, + { "x2.0", 20 } + } + }; + OptionsField options_mode { + { 24 * 8, 5 * 8 }, + 3, + { + { "FM", 0 }, + { "AM", 1 }, + { "USB", 2 }, + { "LSB", 3 }, + { "DSB", 4 } + } + }; + + FrequencyField field_frequency { + { 5 * 8, 3 * 8 }, + }; + NumberField field_bw { + { 18 * 8, 3 * 8 }, + 3, + { 0, 150 }, + 1, + ' ' + }; + +/* NumberField field_carrier { + { 28 * 8, 1 * 8}, + 2, + { 0, 99}, + 1, + ' ' + };*/ + + NumberField field_rfgain { + { 8 * 8, 5 * 8 }, + 2, + { 0, 47 }, + 1, + ' ' + }; + NumberField field_rfamp { + { 15 * 8, 5 * 8 }, + 2, + { 0, 14 }, + 14, + ' ' + }; + + /*Checkbox check_va { + { 3 * 8, (10 * 8) - 4 }, + 7, + "Voice activation", + false + };*/ + + + OptionsField field_va { + { 17 * 8, 8 * 8 }, + 3, + { + {" OFF", 0}, + {" PTT", 1}, + {"AUTO", 2} + } + }; + + OptionsField field_rxbw { + { 25 * 8, 23 * 8}, + 3, + { + {"8k5", 0}, + {"11k", 1}, + {"16k", 2} + } + }; + + NumberField field_va_level { + { 8 * 8, 10 * 8 }, + 3, + { 0, 255 }, + 2, + ' ' + }; + NumberField field_va_attack { + { 16 * 8, 10 * 8 }, + 3, + { 0, 999 }, + 20, + ' ' + }; + NumberField field_va_decay { + { 24 * 8, 10 * 8 }, + 4, + { 0, 9999 }, + 100, + ' ' + }; + + OptionsField options_tone_key { + { 10 * 8, ( 15 * 8 ) - 2 }, + 23, + { } + }; + + Checkbox check_rogerbeep { + { 3 * 8, ( 16 * 8 ) + 4 }, + 10, + "Roger beep", + false + }; + + Checkbox check_rxactive { + { 3 * 8, ( 21 * 8 ) - 4 }, + 8, + "RX audio listening", + true + }; + + NumberField field_volume { + { 10 * 8, 23 * 8 }, + 2, + { 0, 99 }, + 1, + ' ', + }; + + NumberField field_squelch { + { 20 * 8, 25 * 8 }, + 2, + { 0, 99 }, + 1, + ' ', + }; + + FrequencyField field_rxfrequency { + { 7 * 8, 25 * 8 }, + }; + + NumberField field_rxlna { + { 9 * 8, 27 * 8 }, + 2, + { 0, 40 }, + 8, + ' ', + }; + + NumberField field_rxvga { + { 16 * 8, 27 * 8 }, + 2, + { 0, 62 }, + 2, + ' ', + }; + + NumberField field_rxamp { + { 23 * 8, 27 * 8 }, + 1, + { 0, 1 }, + 1, + ' ', + }; + + Button tx_button { + { 10 * 8, 30 * 8, 10 * 8, 5 * 8 }, + "TX", + true + }; + + + MessageHandlerRegistration message_handler_lcd_sync { + Message::ID::DisplayFrameSync, + [this](const Message* const) { + this->do_timing(); + this->update_vumeter(); + } + }; + + MessageHandlerRegistration message_handler_audio_level { + Message::ID::AudioLevelReport, + [this](const Message* const p) { + const auto message = static_cast(p); + this->audio_level = message->value; + } + }; + + MessageHandlerRegistration message_handler_tx_progress { + Message::ID::TXProgress, + [this](const Message* const p) { + const auto message = *reinterpret_cast(p); + this->on_tx_progress(message.done); + } + }; +}; + +} /* namespace ui */ + +#endif/*__UI_MICTX_H__*/ diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 2bff3c53..a3e1cab3 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -176,13 +176,18 @@ void kill_afsk() { } void set_audiotx_config(const uint32_t divider, const float deviation_hz, const float audio_gain, - const uint32_t tone_key_delta) { + const uint32_t tone_key_delta, const bool am_enabled, const bool dsb_enabled, + const bool usb_enabled, const bool lsb_enabled) { const AudioTXConfigMessage message { divider, deviation_hz, audio_gain, tone_key_delta, - (float)persistent_memory::tone_mix() / 100.0f + (float)persistent_memory::tone_mix() / 100.0f, + am_enabled, + dsb_enabled, + usb_enabled, + lsb_enabled }; send_message(&message); } diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index 43d0eebe..8a50782b 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -61,7 +61,8 @@ void set_tones_config(const uint32_t bw, const uint32_t pre_silence, const uint1 void kill_tone(); void set_sstv_data(const uint8_t vis_code, const uint32_t pixel_duration); void set_audiotx_config(const uint32_t divider, const float deviation_hz, const float audio_gain, - const uint32_t tone_key_delta); + const uint32_t tone_key_delta, const bool am_enabled, const bool dsb_enabled, + const bool usb_enabled, const bool lsb_enabled); void set_fifo_data(const int8_t * data); void set_pitch_rssi(int32_t avg, bool enabled); void set_afsk_data(const uint32_t afsk_samples_per_bit, const uint32_t afsk_phase_inc_mark, const uint32_t afsk_phase_inc_space, diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index c4aafa56..227e59fb 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -113,6 +113,8 @@ set(CPPSRC baseband_stats_collector.cpp dsp_decimate.cpp dsp_demodulate.cpp + dsp_hilbert.cpp + dsp_modulate.cpp dsp_goertzel.cpp matched_filter.cpp spectrum_collector.cpp @@ -125,6 +127,7 @@ set(CPPSRC ${COMMON}/dsp_fft.cpp ${COMMON}/dsp_fir_taps.cpp ${COMMON}/dsp_iir.cpp + ${COMMON}/dsp_sos.cpp fxpt_atan2.cpp rssi.cpp rssi_dma.cpp diff --git a/firmware/baseband/dsp_hilbert.cpp b/firmware/baseband/dsp_hilbert.cpp new file mode 100644 index 00000000..ff9e793c --- /dev/null +++ b/firmware/baseband/dsp_hilbert.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 Belousov Oleg + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "dsp_hilbert.hpp" +#include "dsp_sos_config.hpp" + +namespace dsp { + +HilbertTransform::HilbertTransform() { + n = 0; + + sos_i.configure(half_band_lpf_config); + sos_q.configure(half_band_lpf_config); +} + +void HilbertTransform::execute(float in, float &out_i, float &out_q) { + float a = 0, b = 0; + + switch (n) { + case 0: a = in; b = 0; break; + case 1: a = 0; b = -in; break; + case 2: a = -in; b = 0; break; + case 3: a = 0; b = in; break; + } + + float i = sos_i.execute(a) * 2.0f; + float q = sos_q.execute(b) * 2.0f; + + switch (n) { + case 0: out_i = i; out_q = q; break; + case 1: out_i = -q; out_q = i; break; + case 2: out_i = -i; out_q = -q; break; + case 3: out_i = q; out_q = -i; break; + } + + n = (n + 1) % 4; +} + +} /* namespace dsp */ diff --git a/firmware/baseband/dsp_hilbert.hpp b/firmware/baseband/dsp_hilbert.hpp new file mode 100644 index 00000000..a4b56cd5 --- /dev/null +++ b/firmware/baseband/dsp_hilbert.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 Belousov Oleg + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __DSP_HILBERT_H__ +#define __DSP_HILBERT_H__ + +#include "dsp_sos.hpp" +#include "dsp_types.hpp" + +namespace dsp { + +class HilbertTransform { +public: + + HilbertTransform(); + void execute(float in, float &out_i, float &out_q); + +private: + uint8_t n = 0; + SOSFilter<5> sos_i; + SOSFilter<5> sos_q; +}; + +} /* namespace dsp */ + +#endif/*__DSP_HILBERT_H__*/ diff --git a/firmware/baseband/dsp_modulate.cpp b/firmware/baseband/dsp_modulate.cpp new file mode 100644 index 00000000..d59c7e3e --- /dev/null +++ b/firmware/baseband/dsp_modulate.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2020 Belousov Oleg + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "dsp_modulate.hpp" +#include "sine_table_int8.hpp" + +namespace dsp { +namespace modulate { + +Modulator::~Modulator() { +} + +Mode Modulator::get_mode() { + return mode; +} + +void Modulator::set_mode(Mode new_mode) { + mode = new_mode; +} + +void Modulator::set_over(uint32_t new_over) { + over = new_over; +} + +/// + +SSB::SSB() : hilbert() { + mode = Mode::LSB; +} + +void SSB::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer) { + int32_t sample = 0; + int8_t re = 0, im = 0; + + for (size_t counter = 0; counter < buffer.count; counter++) { + if (counter % 128 == 0) { + float i = 0.0, q = 0.0; + + sample = audio.p[counter / over] >> 2; + //switch (mode) { + //case Mode::LSB: + hilbert.execute(sample / 32768.0f, i, q); + //case Mode::USB: hilbert.execute(sample / 32768.0f, q, i); + //default: break; + //} + + i *= 64.0f; + q *= 64.0f; + switch (mode) { + case Mode::LSB: re = q; im = i; break; + case Mode::USB: re = i; im = q; break; + default: re = 0; im = 0; break; + } + //re = q; + //im = i; + //break; + } + + buffer.p[counter] = { re, im }; + } +} + +/// + +FM::FM() { + mode = Mode::FM; +} + +void FM::set_fm_delta(uint32_t new_delta) { + fm_delta = new_delta; +} + +void FM::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer) { + int32_t sample = 0; + int8_t re, im; + + for (size_t counter = 0; counter < buffer.count; counter++) { + if (counter % over == 0) { + sample = audio.p[counter / over] >> 8; + delta = sample * fm_delta; + } + + phase += delta; + sphase = phase >> 24; + + re = (sine_table_i8[(sphase + 64) & 255]); + im = (sine_table_i8[sphase]); + + buffer.p[counter] = { re, im }; + } +} + +AM::AM() { + mode = Mode::AM; +} + +void AM::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer) { + int32_t sample = 0; + int8_t re, im; + float q = 0.0; + + for (size_t counter = 0; counter < buffer.count; counter++) { + if (counter % 128 == 0) { + sample = audio.p[counter / over] >> 2; + } + + q = sample / 32768.0f; + q *= 64.0f; + switch (mode) { + case Mode::AM: re = q + 20; im = q + 20; + case Mode::DSB: re = q; im = q; + default: break; + } + buffer.p[counter] = { re, im }; + } +} + +} +} diff --git a/firmware/baseband/dsp_modulate.hpp b/firmware/baseband/dsp_modulate.hpp new file mode 100644 index 00000000..fdc6e95f --- /dev/null +++ b/firmware/baseband/dsp_modulate.hpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 Belousov Oleg + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __DSP_MODULATE_H__ +#define __DSP_MODULATE_H__ + +#include "dsp_types.hpp" +#include "dsp_hilbert.hpp" + +namespace dsp { +namespace modulate { + +enum class Mode { + None, + AM, + DSB, + LSB, + USB, + FM +}; + +/// + +class Modulator { +public: + virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer) = 0; + virtual ~Modulator(); + + Mode get_mode(); + void set_mode(Mode new_mode); + + void set_over(uint32_t new_over); + +protected: + uint32_t over = 1; + Mode mode = Mode::None; +}; + +/// + +class SSB : public Modulator { +public: + SSB(); + + virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer); + +private: + dsp::HilbertTransform hilbert; +}; + +/// + +class FM : public Modulator { +public: + FM(); + + virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer); + void set_fm_delta(uint32_t new_delta); + +/// + +private: + uint32_t fm_delta { 0 }; + uint32_t phase { 0 }, sphase { 0 }; + int32_t sample { 0 }, delta { }; +}; + +class AM : public Modulator { +public: + AM(); + + virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer); +}; + +} /* namespace modulate */ +} /* namespace dsp */ + +#endif/*__DSP_MODULATE_H__*/ diff --git a/firmware/baseband/proc_mictx.cpp b/firmware/baseband/proc_mictx.cpp index 0a45df78..d5c0040c 100644 --- a/firmware/baseband/proc_mictx.cpp +++ b/firmware/baseband/proc_mictx.cpp @@ -35,6 +35,7 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){ if (!configured) return; audio_input.read_audio_buffer(audio_buffer); + modulator->execute(audio_buffer, buffer); for (size_t i = 0; i < buffer.count; i++) { @@ -70,6 +71,7 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){ sample = beep_gen.process(0); } + /* sample = tone_gen.process(sample); // FM @@ -87,6 +89,7 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){ } buffer.p[i] = { re, im }; + */ } } @@ -96,7 +99,40 @@ void MicTXProcessor::on_message(const Message* const msg) { switch(msg->id) { case Message::ID::AudioTXConfig: - fm_delta = config_message.deviation_hz * (0xFFFFFFUL / baseband_fs); + if (fm_enabled) { + dsp::modulate::FM *fm = new dsp::modulate::FM(); + + fm->set_fm_delta(config_message.deviation_hz * (0xFFFFFFUL / baseband_fs)); + modulator = fm; + } + + if (usb_enabled) { + modulator = new dsp::modulate::SSB(); + modulator->set_mode(dsp::modulate::Mode::USB); + } + + if (lsb_enabled) { + modulator = new dsp::modulate::SSB(); + modulator->set_mode(dsp::modulate::Mode::LSB); + } + if (am_enabled) { + modulator = new dsp::modulate::AM(); + modulator->set_mode(dsp::modulate::Mode::AM); + } + if (dsb_enabled) { + modulator = new dsp::modulate::AM(); + modulator->set_mode(dsp::modulate::Mode::DSB); + } + + modulator->set_over(baseband_fs / 24000); + + am_enabled = config_message.am_enabled; + usb_enabled = config_message.usb_enabled; + lsb_enabled = config_message.lsb_enabled; + dsb_enabled = config_message.dsb_enabled; + if (!am_enabled || !usb_enabled || !lsb_enabled || !dsb_enabled) { + fm_enabled = true; + } audio_gain = config_message.audio_gain; divider = config_message.divider; diff --git a/firmware/baseband/proc_mictx.hpp b/firmware/baseband/proc_mictx.hpp index 986b1017..6220835c 100644 --- a/firmware/baseband/proc_mictx.hpp +++ b/firmware/baseband/proc_mictx.hpp @@ -27,6 +27,7 @@ #include "baseband_thread.hpp" #include "audio_input.hpp" #include "tone_gen.hpp" +#include "dsp_modulate.hpp" class MicTXProcessor : public BasebandProcessor { public: @@ -50,7 +51,14 @@ private: AudioInput audio_input { }; ToneGen tone_gen { }; ToneGen beep_gen { }; - + dsp::modulate::Modulator *modulator; + + bool am_enabled { false }; + bool fm_enabled { true }; + bool usb_enabled { false }; + bool lsb_enabled { false }; + bool dsb_enabled { false }; + uint32_t divider { }; float audio_gain { }; uint64_t power_acc { 0 }; diff --git a/firmware/common/dsp_iir.cpp b/firmware/common/dsp_iir.cpp index 443183ba..98e627ff 100644 --- a/firmware/common/dsp_iir.cpp +++ b/firmware/common/dsp_iir.cpp @@ -55,3 +55,29 @@ void IIRBiquadFilter::execute(const buffer_f32_t& buffer_in, const buffer_f32_t& void IIRBiquadFilter::execute_in_place(const buffer_f32_t& buffer) { execute(buffer, buffer); } + +void IIRBiquadDF2Filter::configure(const iir_biquad_df2_config_t& config) { + b0 = config[0] / config[3]; + b1 = config[1] / config[3]; + b2 = config[2] / config[3]; + a1 = config[4] / config[3]; + a2 = config[5] / config[3]; +} + +// scipy.signal.sosfilt +// +// x_n = x[i, n] # make a temporary copy +// # Use direct II transposed structure: +// x[i, n] = b[s, 0] * x_n + zi[i, s, 0] +// zi[i, s, 0] = (b[s, 1] * x_n - a[s, 0] * x[i, n] + zi[i, s, 1]) +// zi[i, s, 1] = (b[s, 2] * x_n - a[s, 1] * x[i, n]) + +float IIRBiquadDF2Filter::execute(float x) { + float y; + + y = b0 * x + z0; + z0 = b1 * x - a1 * y + z1; + z1 = b2 * x - a2 * y; + + return y; +} diff --git a/firmware/common/dsp_iir.hpp b/firmware/common/dsp_iir.hpp index 0ecc996a..9929c31c 100644 --- a/firmware/common/dsp_iir.hpp +++ b/firmware/common/dsp_iir.hpp @@ -31,6 +31,9 @@ struct iir_biquad_config_t { std::array a; }; +// 0..2 - b, 3..5 - a +typedef std::array iir_biquad_df2_config_t; + constexpr iir_biquad_config_t iir_config_passthrough { { { 1.0f, 0.0f, 0.0f } }, { { 0.0f, 0.0f, 0.0f } }, @@ -67,4 +70,21 @@ private: std::array y { { 0.0f, 0.0f, 0.0f } }; }; +class IIRBiquadDF2Filter { +public: + + void configure(const iir_biquad_df2_config_t& config); + float execute(float z); + +private: + float b0 = 0; + float b1 = 0; + float b2 = 0; + float a1 = 0; + float a2 = 0; + + float z0 = 0; + float z1 = 0; +}; + #endif/*__DSP_IIR_H__*/ diff --git a/firmware/common/dsp_sos.cpp b/firmware/common/dsp_sos.cpp new file mode 100644 index 00000000..cf0ccfa5 --- /dev/null +++ b/firmware/common/dsp_sos.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 Belousov Oleg + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "dsp_sos.hpp" diff --git a/firmware/common/dsp_sos.hpp b/firmware/common/dsp_sos.hpp new file mode 100644 index 00000000..b7446636 --- /dev/null +++ b/firmware/common/dsp_sos.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 Belousov Oleg + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __DSP_SOS_H__ +#define __DSP_SOS_H__ + +#include "dsp_iir.hpp" + +#include +#include + +template +class SOSFilter { + +public: + + void configure(const iir_biquad_df2_config_t config[N]) { + for (size_t i = 0; i < N; i++) + filters[i].configure(config[i]); + } + + float execute(float value) { + for (auto &filter : filters) + value = filter.execute(value); + return value; + } + +private: + + IIRBiquadDF2Filter filters[N]; +}; + +#endif/*__DSP_SOS_H__*/ diff --git a/firmware/common/dsp_sos_config.hpp b/firmware/common/dsp_sos_config.hpp new file mode 100644 index 00000000..23c36622 --- /dev/null +++ b/firmware/common/dsp_sos_config.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 Belousov Oleg + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __DSP_SOS_CONFIG_H__ +#define __DSP_SOS_CONFIG_H__ + +#include "dsp_iir.hpp" + +// scipy.signal.iirfilter(ftype="ellip", N = 10, rp = 0.5, rs = 60.0, Wn = 0.5, btype = 'lowpass', output="sos") + +constexpr iir_biquad_df2_config_t half_band_lpf_config[5] = { + { 0.02339042f, 0.0411599f, 0.02339042f, 1.0f, -0.95317621f, 0.33446485f }, + { 1.0f, 0.82196114f, 1.0f, 1.0f, -0.50327735f, 0.63611027f }, + { 1.0f, 0.32515305f, 1.0f, 1.0f, -0.18144446f, 0.85269598f }, + { 1.0f, 0.14394122f, 1.0f, 1.0f, -0.04368236f, 0.94798064f }, + { 1.0f, 0.08720754, 1.0f, 1.0f, 0.00220944f, 0.98743139f } +}; + +#endif/*__DSP_SOS_CONFIG_H__*/ diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 32a8fc7b..3d288d7c 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -856,13 +856,21 @@ public: const float deviation_hz, const float audio_gain, const uint32_t tone_key_delta, - const float tone_key_mix_weight + const float tone_key_mix_weight, + const bool am_enabled, + const bool dsb_enabled, + const bool usb_enabled, + const bool lsb_enabled ) : Message { ID::AudioTXConfig }, divider(divider), deviation_hz(deviation_hz), audio_gain(audio_gain), tone_key_delta(tone_key_delta), - tone_key_mix_weight(tone_key_mix_weight) + tone_key_mix_weight(tone_key_mix_weight), + am_enabled(am_enabled), + dsb_enabled(dsb_enabled), + usb_enabled(usb_enabled), + lsb_enabled(lsb_enabled) { } @@ -871,6 +879,10 @@ public: const float audio_gain; const uint32_t tone_key_delta; const float tone_key_mix_weight; + const bool am_enabled; + const bool dsb_enabled; + const bool usb_enabled; + const bool lsb_enabled; }; class SigGenConfigMessage : public Message { From 133bfbf07b482a0d9c7793246ad2149c473c53e6 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Mon, 22 Mar 2021 10:09:41 +0100 Subject: [PATCH 39/52] Delete ui_mictx.hpp.1 --- firmware/application/apps/ui_mictx.hpp.1 | 344 ----------------------- 1 file changed, 344 deletions(-) delete mode 100644 firmware/application/apps/ui_mictx.hpp.1 diff --git a/firmware/application/apps/ui_mictx.hpp.1 b/firmware/application/apps/ui_mictx.hpp.1 deleted file mode 100644 index 3761c401..00000000 --- a/firmware/application/apps/ui_mictx.hpp.1 +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2016 Furrtek - * - * This file is part of PortaPack. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __UI_MICTX_H__ -#define __UI_MICTX_H__ - -#include "ui.hpp" -#include "ui_widget.hpp" -#include "ui_navigation.hpp" -#include "ui_receiver.hpp" -#include "transmitter_model.hpp" -#include "tone_key.hpp" -#include "message.hpp" -#include "receiver_model.hpp" - -namespace ui { - -class MicTXView : public View { -public: - MicTXView(NavigationView& nav); - ~MicTXView(); - - MicTXView(const MicTXView&) = delete; - MicTXView(MicTXView&&) = delete; - MicTXView& operator=(const MicTXView&) = delete; - MicTXView& operator=(MicTXView&&) = delete; - - void focus() override; - - // PTT: Enable through KeyEvent (only works with presses), disable by polling :( - // This is the old "RIGHT BUTTON" method. - -/* bool on_key(const KeyEvent key) { - if ((key == KeyEvent::Right) && (!va_enabled) && ptt_enabled) { - set_tx(true); - return true; - } else - return false; - }; */ - - - std::string title() const override { return "Mic TX RX"; }; - -private: - static constexpr uint32_t sampling_rate = 1536000U; - static constexpr uint32_t lcd_frame_duration = (256 * 1000UL) / 60; // 1 frame @ 60fps in ms .8 fixed point /60 - - void update_vumeter(); - void do_timing(); - void set_tx(bool enable); -// void on_tuning_frequency_changed(rf::Frequency f); - void on_tx_progress(const bool done); - void configure_baseband(); - - void rxaudio(bool is_on); - void on_headphone_volume_changed(int32_t v); - - void set_ptt_visibility(bool v); - - bool transmitting { false }; - bool va_enabled { false }; - bool ptt_enabled { true }; - bool rogerbeep_enabled { false }; - bool rx_enabled { false }; - uint32_t tone_key_index { }; - float mic_gain { 1.0 }; - uint32_t audio_level { 0 }; - uint32_t va_level { }; - uint32_t attack_ms { }; - uint32_t decay_ms { }; - uint32_t attack_timer { 0 }; - uint32_t decay_timer { 0 }; - int32_t tx_gain { 47 }; - bool rf_amp { false }; - int32_t rx_lna { 32 }; - int32_t rx_vga { 32 }; - bool rx_amp { false }; - rf::Frequency tx_frequency { 0 }; - rf::Frequency rx_frequency { 0 }; - int32_t focused_ui { 2 }; - bool button_touch { false }; - - //AM TX Stuff - bool enable_usb { false }; - bool enable_lsb { false }; - bool enable_am { false }; - uint32_t am_carrier_lvl { 20 }; -// uint32_t am_mod_div { 1 }; - - - Labels labels { - { { 3 * 8, 1 * 8 }, "MIC. GAIN:", Color::light_grey() }, - { { 3 * 8, 3 * 8 }, "F:", Color::light_grey() }, - { { 15 * 8, 3 * 8 }, "BW: FM kHz", Color::light_grey() }, - { { 3 * 8, 5 * 8 }, "GAIN:", Color::light_grey() }, - { {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() }, - { { 18 * 8, (5 * 8) }, "Mode:", Color::light_grey() }, -// { { 21 * 8, (1 * 8) }, "AM Car:", Color::light_grey() }, -// { { 20 * 8, (16 * 8) + 2 }, "AMCAR:", Color::light_grey() }, - { { 3 * 8, 8 * 8 }, "TX Activation:", Color::light_grey() }, - { { 4 * 8, 10 * 8 }, "LVL:", Color::light_grey() }, - { {12 * 8, 10 * 8 }, "ATT:", Color::light_grey() }, - { {20 * 8, 10 * 8 }, "DEC:", Color::light_grey() }, - { { 4 * 8, ( 13 * 8 ) - 2 }, "TONE KEY:", Color::light_grey() }, - { { 5 * 8, 23 * 8 }, "VOL:", Color::light_grey() }, - { {17 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() }, - { {17 * 8, 25 * 8 }, "SQ:", Color::light_grey() }, - { { 5 * 8, 25 * 8 }, "F:", Color::light_grey() }, - { { 5 * 8, 27 * 8 }, "LNA:", Color::light_grey()}, - { {12 * 8, 27 * 8 }, "VGA:", Color::light_grey()}, - { {19 * 8, 27 * 8 }, "AMP:", Color::light_grey()} - }; - - VuMeter vumeter { - { 0 * 8, 1 * 8, 2 * 8, 33 * 8 }, - 12, - true - }; - - - OptionsField options_gain { - { 13 * 8, 1 * 8 }, - 4, - { - { "x0.5", 5 }, - { "x1.0", 10 }, - { "x1.5", 15 }, - { "x2.0", 20 } - } - }; - OptionsField options_mode { - { 24 * 8, 5 * 8 }, - 3, - { - { "FM", 0 }, - { "AM", 1 }, - { "USB", 2 }, - { "LSB", 3 }, - { "DSB", 4 } - } - }; - - FrequencyField field_frequency { - { 5 * 8, 3 * 8 }, - }; - NumberField field_bw { - { 18 * 8, 3 * 8 }, - 3, - { 0, 150 }, - 1, - ' ' - }; - -/* NumberField field_carrier { - { 28 * 8, 1 * 8}, - 2, - { 0, 99}, - 1, - ' ' - };*/ - - NumberField field_rfgain { - { 8 * 8, 5 * 8 }, - 2, - { 0, 47 }, - 1, - ' ' - }; - NumberField field_rfamp { - { 15 * 8, 5 * 8 }, - 2, - { 0, 14 }, - 14, - ' ' - }; - - /*Checkbox check_va { - { 3 * 8, (10 * 8) - 4 }, - 7, - "Voice activation", - false - };*/ - - - OptionsField field_va { - { 17 * 8, 8 * 8 }, - 3, - { - {" OFF", 0}, - {" PTT", 1}, - {"AUTO", 2} - } - }; - - OptionsField field_rxbw { - { 25 * 8, 23 * 8}, - 3, - { - {"8k5", 0}, - {"11k", 1}, - {"16k", 2} - } - }; - - NumberField field_va_level { - { 8 * 8, 10 * 8 }, - 3, - { 0, 255 }, - 2, - ' ' - }; - NumberField field_va_attack { - { 16 * 8, 10 * 8 }, - 3, - { 0, 999 }, - 20, - ' ' - }; - NumberField field_va_decay { - { 24 * 8, 10 * 8 }, - 4, - { 0, 9999 }, - 100, - ' ' - }; - - OptionsField options_tone_key { - { 10 * 8, ( 15 * 8 ) - 2 }, - 23, - { } - }; - - Checkbox check_rogerbeep { - { 3 * 8, ( 16 * 8 ) + 4 }, - 10, - "Roger beep", - false - }; - - Checkbox check_rxactive { - { 3 * 8, ( 21 * 8 ) - 4 }, - 8, - "RX audio listening", - true - }; - - NumberField field_volume { - { 10 * 8, 23 * 8 }, - 2, - { 0, 99 }, - 1, - ' ', - }; - - NumberField field_squelch { - { 20 * 8, 25 * 8 }, - 2, - { 0, 99 }, - 1, - ' ', - }; - - FrequencyField field_rxfrequency { - { 7 * 8, 25 * 8 }, - }; - - NumberField field_rxlna { - { 9 * 8, 27 * 8 }, - 2, - { 0, 40 }, - 8, - ' ', - }; - - NumberField field_rxvga { - { 16 * 8, 27 * 8 }, - 2, - { 0, 62 }, - 2, - ' ', - }; - - NumberField field_rxamp { - { 23 * 8, 27 * 8 }, - 1, - { 0, 1 }, - 1, - ' ', - }; - - Button tx_button { - { 10 * 8, 30 * 8, 10 * 8, 5 * 8 }, - "TX", - true - }; - - - MessageHandlerRegistration message_handler_lcd_sync { - Message::ID::DisplayFrameSync, - [this](const Message* const) { - this->do_timing(); - this->update_vumeter(); - } - }; - - MessageHandlerRegistration message_handler_audio_level { - Message::ID::AudioLevelReport, - [this](const Message* const p) { - const auto message = static_cast(p); - this->audio_level = message->value; - } - }; - - MessageHandlerRegistration message_handler_tx_progress { - Message::ID::TXProgress, - [this](const Message* const p) { - const auto message = *reinterpret_cast(p); - this->on_tx_progress(message.done); - } - }; -}; - -} /* namespace ui */ - -#endif/*__UI_MICTX_H__*/ From 41864f06e72eeba73fc3085a2e57a659c44f446c Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Mon, 22 Mar 2021 10:10:01 +0100 Subject: [PATCH 40/52] Delete ui_mictx.cpp.1 --- firmware/application/apps/ui_mictx.cpp.1 | 526 ----------------------- 1 file changed, 526 deletions(-) delete mode 100644 firmware/application/apps/ui_mictx.cpp.1 diff --git a/firmware/application/apps/ui_mictx.cpp.1 b/firmware/application/apps/ui_mictx.cpp.1 deleted file mode 100644 index 9476584b..00000000 --- a/firmware/application/apps/ui_mictx.cpp.1 +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2016 Furrtek - * - * This file is part of PortaPack. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#include "ui_mictx.hpp" - -#include "baseband_api.hpp" -#include "audio.hpp" -#include "tonesets.hpp" -#include "portapack_hal.hpp" -#include "string_format.hpp" -#include "irq_controls.hpp" - - -#include - -using namespace tonekey; -using namespace portapack; - -namespace ui { - -void MicTXView::focus() { - switch(focused_ui) { - case 0: - field_frequency.focus(); - break; - case 1: - field_rxfrequency.focus(); - break; - default: - //field_va.focus(); - tx_button.focus(); - break; - } -} - -void MicTXView::update_vumeter() { - vumeter.set_value(audio_level); -} - -void MicTXView::on_tx_progress(const bool done) { - // Roger beep played, stop transmitting - if (done) - set_tx(false); -} - -void MicTXView::configure_baseband() { - baseband::set_audiotx_config( - sampling_rate / 20, // Update vu-meter at 20Hz - transmitting ? transmitter_model.channel_bandwidth() : 0, - mic_gain, - TONES_F2D(tone_key_frequency(tone_key_index), sampling_rate), - enable_am, - am_carrier_lvl, - 0, - enable_usb, - enable_lsb - ); - -} - -void MicTXView::set_tx(bool enable) { - if (enable) { - if (rx_enabled) //If audio RX is enabled - rxaudio(false); //Then turn off audio RX - receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); // Weird workaround for FM TX - transmitting = true; - configure_baseband(); - transmitter_model.set_tuning_frequency(tx_frequency); - transmitter_model.set_tx_gain(tx_gain); - transmitter_model.set_rf_amp(rf_amp); - 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 { - if (transmitting && rogerbeep_enabled) { - baseband::request_beep(); //Transmit the roger beep - transmitting = false; //And flag the end of the transmission so ... - } else { // (if roger beep was enabled, this will be executed after the beep ends transmitting. - transmitting = false; - configure_baseband(); - transmitter_model.disable(); - if (rx_enabled) //If audio RX is enabled and we've been transmitting - rxaudio(true); //Turn back on audio RX - } - } -} - -void MicTXView::do_timing() { - if (va_enabled) { - if (!transmitting) { - // Attack - if (audio_level >= va_level) { - if ((attack_timer >> 8) >= attack_ms) { - decay_timer = 0; - attack_timer = 0; - set_tx(true); - } else { - attack_timer += lcd_frame_duration; - } - } else { - attack_timer = 0; - } - } else { - // Decay - if (audio_level < va_level) { - if ((decay_timer >> 8) >= decay_ms) { - decay_timer = 0; - attack_timer = 0; - set_tx(false); - } else { - decay_timer += lcd_frame_duration; - } - } else { - decay_timer = 0; - } - } - } else { - // Check for PTT release - const auto switches_state = get_switches_state(); - if (!switches_state[4] && transmitting && !button_touch) // Select button - set_tx(false); - } -} - -/* Hmmmm. Maybe useless now. -void MicTXView::on_tuning_frequency_changed(rf::Frequency f) { - transmitter_model.set_tuning_frequency(f); - //if ( rx_enabled ) - receiver_model.set_tuning_frequency(f); //Update freq also for RX -} -*/ - -void MicTXView::rxaudio(bool is_on) { - if (is_on) { - audio::input::stop(); - baseband::shutdown(); - - if (enable_am || enable_usb || enable_lsb) { - baseband::run_image(portapack::spi_flash::image_tag_am_audio); - receiver_model.set_modulation(ReceiverModel::Mode::AMAudio); - if (options_mode.selected_index() < 4) - receiver_model.set_am_configuration(options_mode.selected_index() - 1); - else - receiver_model.set_am_configuration(0); - } - else { - baseband::run_image(portapack::spi_flash::image_tag_nfm_audio); - receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); - - } - receiver_model.set_sampling_rate(3072000); - receiver_model.set_baseband_bandwidth(1750000); -// receiver_model.set_tuning_frequency(field_frequency.value()); //probably this too can be commented out. - receiver_model.set_tuning_frequency(rx_frequency); // Now with seperate controls! - receiver_model.set_lna(rx_lna); - receiver_model.set_vga(rx_vga); - receiver_model.set_rf_amp(rx_amp); - receiver_model.enable(); - audio::output::start(); - } else { //These incredibly convoluted steps are required for the vumeter to reappear when stopping RX. - //baseband::run_image(portapack::spi_flash::image_tag_nfm_audio); //There is something seriously wrong if these two lines fixes the issue with AM TX... - receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); - receiver_model.disable(); - baseband::shutdown(); - - baseband::run_image(portapack::spi_flash::image_tag_mic_tx); - audio::output::stop(); - audio::input::start(); -// transmitter_model.enable(); - portapack::pin_i2s0_rx_sda.mode(3); -// transmitting = false; - configure_baseband(); -// transmitter_model.disable(); - } -} - -void MicTXView::on_headphone_volume_changed(int32_t v) { - //if (rx_enabled) { - const auto new_volume = volume_t::decibel(v - 99) + audio::headphone::volume_range().max; - receiver_model.set_headphone_volume(new_volume); - //} -} - -void MicTXView::set_ptt_visibility(bool v) { - tx_button.hidden(!v); -} - -MicTXView::MicTXView( - NavigationView& nav -) -{ - portapack::pin_i2s0_rx_sda.mode(3); // This is already done in audio::init but gets changed by the CPLD overlay reprogramming - - baseband::run_image(portapack::spi_flash::image_tag_mic_tx); - - - - add_children({ - &labels, - &vumeter, - &options_gain, -// &check_va, - &field_va, - &field_rxbw, - &field_va_level, - &field_va_attack, - &field_va_decay, -// &field_carrier, - &field_bw, - &field_rfgain, - &field_rfamp, - &field_frequency, - &options_tone_key, - &options_mode, - &check_rogerbeep, - &check_rxactive, - &field_volume, - &field_squelch, - &field_rxfrequency, - &field_rxlna, - &field_rxvga, - &field_rxamp, - &tx_button - }); - - - - tone_keys_populate(options_tone_key); - options_tone_key.on_change = [this](size_t i, int32_t) { - tone_key_index = i; - }; - options_tone_key.set_selected_index(0); - - options_gain.on_change = [this](size_t, int32_t v) { - mic_gain = v / 10.0; - configure_baseband(); - }; - options_gain.set_selected_index(1); // x1.0 - - options_mode.on_change = [this](size_t, int32_t v) { - enable_am = false; - enable_usb = false; - enable_lsb = false; - switch(v) { - case 0: - enable_am = false; - enable_usb = false; - enable_lsb = false; - field_bw.set_value(transmitter_model.channel_bandwidth() / 1000); - //if (rx_enabled) - rxaudio(rx_enabled); - break; - case 1: - enable_am = true; - am_carrier_lvl = 20; - //if (rx_enabled) - rxaudio(rx_enabled); - break; - case 2: - enable_am = true; - enable_usb = true; - //if (rx_enabled) - rxaudio(rx_enabled); - break; - case 3: - enable_am = true; - enable_lsb = true; - - //if (rx_enabled) - rxaudio(rx_enabled); - break; - case 4: - enable_usb = false; - enable_lsb = false; - enable_am = true; - am_carrier_lvl = 0; - //if (rx_enabled) - rxaudio(rx_enabled); - break; - } - //configure_baseband(); - }; - - tx_frequency = transmitter_model.tuning_frequency(); - field_frequency.set_value(transmitter_model.tuning_frequency()); - field_frequency.set_step(receiver_model.frequency_step()); - field_frequency.on_change = [this](rf::Frequency f) { - tx_frequency = f; - if(!rx_enabled) - transmitter_model.set_tuning_frequency(f); - }; - field_frequency.on_edit = [this, &nav]() { - focused_ui = 0; - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(tx_frequency); - new_view->on_changed = [this](rf::Frequency f) { - tx_frequency = f; - if(!rx_enabled) - transmitter_model.set_tuning_frequency(f); - this->field_frequency.set_value(f); - set_dirty(); - }; - }; - - field_rxbw.on_change = [this](size_t, int32_t v) { - switch(v) { - case 0: - receiver_model.set_nbfm_configuration(0); - break; - case 1: - receiver_model.set_nbfm_configuration(1); - break; - case 2: - receiver_model.set_nbfm_configuration(2); - break; - } - }; - field_rxbw.set_selected_index(2); - - field_bw.on_change = [this](uint32_t v) { - transmitter_model.set_channel_bandwidth(v * 1000); - }; - field_bw.set_value(10); - -// field_carrier.on_change = [this](uint32_t v) { -// am_carrier_lvl = v; -// }; -// field_carrier.set_value(am_carrier_lvl); - tx_gain = transmitter_model.tx_gain(); - - field_rfgain.on_change = [this](int32_t v) { - tx_gain = v; - - }; - - field_rfgain.set_value(tx_gain); - - rf_amp = transmitter_model.rf_amp(); - field_rfamp.on_change = [this](int32_t v) { - rf_amp = (bool)v; - }; - field_rfamp.set_value(rf_amp ? 14 : 0); - -/* - check_va.on_select = [this](Checkbox&, bool v) { - va_enabled = v; - text_ptt.hidden(v); //hide / show PTT text - check_rxactive.hidden(v); //hide / show the RX AUDIO - set_dirty(); //Refresh display - }; */ - - field_va.set_selected_index(1); - field_va.on_change = [this](size_t, int32_t v) { - switch(v) { - case 0: - va_enabled = 0; - this->set_ptt_visibility(0); - check_rxactive.hidden(0); - ptt_enabled = 0; - break; - case 1: - va_enabled = 0; - this->set_ptt_visibility(1); - check_rxactive.hidden(0); - ptt_enabled = 1; - break; - case 2: - if (!rx_enabled) { - va_enabled = 1; - this->set_ptt_visibility(0); - check_rxactive.hidden(1); - ptt_enabled = 0; - } else { - field_va.set_selected_index(1); - } - break; - } - set_dirty(); - }; - - check_rogerbeep.on_select = [this](Checkbox&, bool v) { - rogerbeep_enabled = v; - }; - - field_va_level.on_change = [this](int32_t v) { - va_level = v; - vumeter.set_mark(v); - }; - field_va_level.set_value(40); - - field_va_attack.on_change = [this](int32_t v) { - attack_ms = v; - }; - field_va_attack.set_value(500); - - field_va_decay.on_change = [this](int32_t v) { - decay_ms = v; - }; - field_va_decay.set_value(1000); - - check_rxactive.on_select = [this](Checkbox&, bool v) { -// vumeter.set_value(0); //Start with a clean vumeter - rx_enabled = v; -// check_va.hidden(v); //Hide or show voice activation - rxaudio(v); //Activate-Deactivate audio rx accordingly - set_dirty(); //Refresh interface - }; - - - - //field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99); - field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99); - field_volume.on_change = [this](int32_t v) { this->on_headphone_volume_changed(v); }; - - field_squelch.on_change = [this](int32_t v) { - receiver_model.set_squelch_level(100 - v); - }; - field_squelch.set_value(0); - receiver_model.set_squelch_level(0); - - rx_frequency = receiver_model.tuning_frequency(); - field_rxfrequency.set_value(rx_frequency); - field_rxfrequency.set_step(receiver_model.frequency_step()); - - field_rxfrequency.on_change = [this](rf::Frequency f) { - rx_frequency = f; - if(rx_enabled) - receiver_model.set_tuning_frequency(f); - }; - field_rxfrequency.on_edit = [this, &nav]() { - focused_ui = 1; - // TODO: Provide separate modal method/scheme? - auto new_view = nav.push(rx_frequency); - new_view->on_changed = [this](rf::Frequency f) { - rx_frequency = f; - if(rx_enabled) - receiver_model.set_tuning_frequency(f); - this->field_rxfrequency.set_value(f); - set_dirty(); - }; - }; - - - rx_lna = receiver_model.lna(); - field_rxlna.on_change = [this](int32_t v) { - rx_lna = v; - if(rx_enabled) - receiver_model.set_lna(v); - }; - field_rxlna.set_value(rx_lna); - - rx_vga = receiver_model.vga(); - field_rxvga.on_change = [this](int32_t v) { - rx_vga = v; - if(rx_enabled) - receiver_model.set_vga(v); - }; - field_rxvga.set_value(rx_vga); - - rx_amp = receiver_model.rf_amp(); - - field_rxamp.on_change = [this](int32_t v) { - rx_amp = v; - if(rx_enabled) - receiver_model.set_rf_amp(rx_amp); - }; - field_rxamp.set_value(rx_amp); - receiver_model.set_rf_amp(rx_amp); - - tx_button.on_select = [this](Button&) { - if(ptt_enabled && !transmitting) { - set_tx(true); - } - }; - - tx_button.on_touch_release = [this](Button&) { - if(button_touch) { - button_touch = false; - set_tx(false); - } - }; - - tx_button.on_touch_press = [this](Button&) { - if(!transmitting) { - button_touch = true; - } - }; - - transmitter_model.set_sampling_rate(sampling_rate); - transmitter_model.set_baseband_bandwidth(1750000); - - set_tx(false); - - audio::set_rate(audio::Rate::Hz_24000); - audio::input::start(); -} - -MicTXView::~MicTXView() { - - audio::input::stop(); - transmitter_model.set_tuning_frequency(tx_frequency); // Save Tx frequency instead of Rx. Or maybe we need some "System Wide" changes to seperate Tx and Rx frequency. - transmitter_model.disable(); - if (rx_enabled) //Also turn off audio rx if enabled - rxaudio(false); - baseband::shutdown(); -} - -} From 9402634602a2af161de6cf5b76752e09579a7e84 Mon Sep 17 00:00:00 2001 From: eried <1091420+eried@users.noreply.github.com> Date: Thu, 25 Mar 2021 14:50:22 +0100 Subject: [PATCH 41/52] Update hackrf --- hackrf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hackrf b/hackrf index 43e6f99f..e6eb4ba2 160000 --- a/hackrf +++ b/hackrf @@ -1 +1 @@ -Subproject commit 43e6f99fe8543094d18ff3a6550ed2066c398862 +Subproject commit e6eb4ba29bbe5dc2fcd092e394188bc10a8bad54 From a0eaa70ff4720386e3c57960516221bfcc1d3443 Mon Sep 17 00:00:00 2001 From: zhang00963 <14372128+zhang00963@users.noreply.github.com> Date: Sun, 11 Apr 2021 02:19:31 +0800 Subject: [PATCH 42/52] Realize the automatic recognition of audio chip, including ak4951en/wm8731/wm8731s,Try to fix the max2837 temperature problem --- firmware/application/apps/ui_debug.cpp | 3 ++- firmware/application/portapack.cpp | 17 ++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/firmware/application/apps/ui_debug.cpp b/firmware/application/apps/ui_debug.cpp index 8622911c..2bec78fa 100644 --- a/firmware/application/apps/ui_debug.cpp +++ b/firmware/application/apps/ui_debug.cpp @@ -121,7 +121,8 @@ void TemperatureWidget::paint(Painter& painter) { } TemperatureWidget::temperature_t TemperatureWidget::temperature(const sample_t sensor_value) const { - return -35 + sensor_value * 4; //max2837 datasheet temp 25ºC has sensor value: 15 + /*It seems to be a temperature difference of 25C*/ + return -40 +(sensor_value * 4.31)+25; //max2837 datasheet temp 25ºC has sensor value: 15 } std::string TemperatureWidget::temperature_str(const temperature_t temperature) const { diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index 99843aec..44fc1db7 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -179,20 +179,23 @@ static PortaPackModel portapack_model() { static Optional model; if( !model.is_valid() ) { - if( audio_codec_wm8731.detected() ) { - model = PortaPackModel::R1_20150901; - } else { + /*For the time being, it is impossible to distinguish the hardware of R1 and R2 from the software level*/ + /*At this point, I2c is not ready.*/ + //if( audio_codec_wm8731.detected() ) { + // model = PortaPackModel::R1_20150901; + //} else { model = PortaPackModel::R2_20170522; - } + //} } return model.value(); } static audio::Codec* portapack_audio_codec() { - return (portapack_model() == PortaPackModel::R2_20170522) - ? static_cast(&audio_codec_ak4951) - : static_cast(&audio_codec_wm8731) + /* I2C ready OK, Automatic recognition of audio chip */ + return (audio_codec_wm8731.detected()) + ? static_cast(&audio_codec_wm8731) + : static_cast(&audio_codec_ak4951) ; } From 594890744be49ed6b7ff4c9392c44da3f61d95cd Mon Sep 17 00:00:00 2001 From: eried <1091420+eried@users.noreply.github.com> Date: Mon, 12 Apr 2021 12:46:34 +0200 Subject: [PATCH 43/52] New GSM-FR.TXT file for sdcard/FREQMAN https: //github.com/eried/portapack-mayhem/issues/334 Co-Authored-By: RedFox-Fr <82333326+RedFox-Fr@users.noreply.github.com> --- sdcard/FREQMAN/GSM-FR.TXT | 61 ++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/sdcard/FREQMAN/GSM-FR.TXT b/sdcard/FREQMAN/GSM-FR.TXT index 9df34deb..b38505b9 100644 --- a/sdcard/FREQMAN/GSM-FR.TXT +++ b/sdcard/FREQMAN/GSM-FR.TXT @@ -1,8 +1,53 @@ -a=935000000,b=945000000,d=GSM900 Orange FR -a=1808000000,b=1832000000,d=GSM1800 Orange FR -a=950000000,b=960000000,d=GSM900 SFR FR -a=1832000000,b=1853000000,d=GSM1800 SFR FR -a=925000000,b=935000000,d=GSM900 Bouygues FR -a=1858000000,b=1880000000,d=GSM1800 Bouygues FR -a=945000000,b=950000000,d=GSM Free FR -a=921000000,b=925000000,d=GSM-R FR +a=703000000,b=708000000,d=LTE 700u SFR +a=708000000,b=718000000,d=LTE 700u Orange +a=718000000,b=723000000,d=LTE 700u Bouygues +a=723000000,b=733000000,d=LTE 700u Free +a=758000000,b=763000000,d=LTE 700d SFR +a=763000000,b=773000000,d=LTE 700d Orange +a=773000000,b=778000000,d=LTE 700d Bouygues +a=778000000,b=788000000,d=LTE 700d Free +a=791000000,b=801000000,d=LTE 800d Bouygues +a=801000000,b=811000000,d=LTE 800d SFR +a=811000000,b=821000000,d=LTE 800d Orange +a=832000000,b=842000000,d=LTE 800u Bouygues +a=842000000,b=852000000,d=LTE 800u SFR +a=852000000,b=862000000,d=LTE 800u Orange +a=876000000,b=880000000,d=GSM-R 900u RFF +a=880100000,b=889900000,d=GSM_UMTS 900u Bouygues +a=889900000,b=898600000,d=GSM_UMTS 900u Orange +a=898600000,b=906200000,d=GSM_UMTS 900u Free +a=906200000,b=914900000,d=GSM_UMTS 900u SFR +a=921000000,b=925000000,d=GSM-R 900d RFF +a=925100000,b=934900000,d=GSM_UMTS 900d Bouygues +a=934900000,b=943600000,d=GSM_UMTS 900d Orange +a=943600000,b=951200000,d=GSM_UMTS 900d Free +a=951200000,b=959900000,d=GSM_UMTS 900d SFR +a=1710000000,b=1730000000,d=GSM_LTE 1800u Orange +a=1730000000,b=1750000000,d=GSM_LTE 1800u SFR +a=1750000000,b=1765000000,d=GSM_LTE 1800u Free +a=1765000000,b=1785000000,d=GSM_LTE 1800u Bouygues +a=1805000000,b=1825000000,d=GSM_LTE 1800d Orange +a=1825000000,b=1845000000,d=GSM_LTE 1800d SFR +a=1845000000,b=1860000000,d=GSM_LTE 1800d Free +a=1860000000,b=1880000000,d=GSM_LTE 1800d Bouygues +a=1900100000,b=1905100000,d=UMTS_TDD 1900 Bouygues +a=1920500000,b=1935300000,d=GSM_UMTS 2100u SFR +a=1935300000,b=1950100000,d=GSM_UMTS 2100u Bouygues +a=1950100000,b=1964900000,d=GSM_UMTS 2100u Free +a=1964900000,b=1979700000,d=GSM_UMTS 2100u Orange +a=2110500000,b=2125300000,d=GSM_UMTS 2100d SFR +a=2125300000,b=2140100000,d=GSM_UMTS 2100d Bouygues +a=2140100000,b=2154900000,d=GSM_UMTS 2100d Free +a=2154900000,b=2169700000,d=GSM_UMTS 2100d Orange +a=2500000000,b=2515000000,d=LTE 2600u SFR +a=2515000000,b=2535000000,d=LTE 2600u Orange +a=2535000000,b=2550000000,d=LTE 2600u Bouygues +a=2550000000,b=2570000000,d=LTE 2600u Free +a=2620000000,b=2635000000,d=LTE 2600d SFR +a=2635000000,b=2655000000,d=LTE 2600d Orange +a=2655000000,b=2670000000,d=LTE 2600d Bouygues +a=2670000000,b=2690000000,d=LTE 2600d Free +a=3490000000,b=3570000000,d=5G 3500 SFR +a=3570000000,b=3640000000,d=5G 3500 Bouygues +a=3640000000,b=3710000000,d=5G 3500 Free +a=3710000000,b=3800000000,d=5G 3500 Orange From 4c50401df24924d63dbeeacfe58640071794f69a Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Mon, 12 Apr 2021 13:29:01 +0200 Subject: [PATCH 44/52] Update ui_about_simple.cpp --- firmware/application/apps/ui_about_simple.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/application/apps/ui_about_simple.cpp b/firmware/application/apps/ui_about_simple.cpp index dceb869d..b348c421 100644 --- a/firmware/application/apps/ui_about_simple.cpp +++ b/firmware/application/apps/ui_about_simple.cpp @@ -31,6 +31,7 @@ namespace ui console.writeln("N0vaPixel,klockee,GullCode"); console.writeln("jamesshao8,ITAxReal,rascafr"); console.writeln("mcules,dqs105,strijar"); + console.writeln("RedFox-Fr"); console.writeln(""); break; From d0200164134c132e66814d27f735df5ce27c67c9 Mon Sep 17 00:00:00 2001 From: RedFox-Fr Date: Wed, 14 Apr 2021 00:45:13 +0200 Subject: [PATCH 45/52] Update somes sdcard/FREQMAN files. --- sdcard/FREQMAN/DMR.TXT | 8 ------- sdcard/FREQMAN/{DPMR.TXT => DPMR446.TXT} | 0 sdcard/FREQMAN/DVB-T_FR.TXT | 28 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) delete mode 100644 sdcard/FREQMAN/DMR.TXT rename sdcard/FREQMAN/{DPMR.TXT => DPMR446.TXT} (100%) create mode 100644 sdcard/FREQMAN/DVB-T_FR.TXT diff --git a/sdcard/FREQMAN/DMR.TXT b/sdcard/FREQMAN/DMR.TXT deleted file mode 100644 index 94146f4f..00000000 --- a/sdcard/FREQMAN/DMR.TXT +++ /dev/null @@ -1,8 +0,0 @@ -f=446106250,d=DMR T1 CH1 -f=446118750,d=DMR T1 CH2 -f=446131250,d=DMR T1 CH3 -f=446143750,d=DMR T1 CH4 -f=446156250,d=DMR T1 CH5 -f=446168750,d=DMR T1 CH6 -f=446181250,d=DMR T1 CH7 -f=446193750,d=DMR T1 CH8 diff --git a/sdcard/FREQMAN/DPMR.TXT b/sdcard/FREQMAN/DPMR446.TXT similarity index 100% rename from sdcard/FREQMAN/DPMR.TXT rename to sdcard/FREQMAN/DPMR446.TXT diff --git a/sdcard/FREQMAN/DVB-T_FR.TXT b/sdcard/FREQMAN/DVB-T_FR.TXT new file mode 100644 index 00000000..b2115d19 --- /dev/null +++ b/sdcard/FREQMAN/DVB-T_FR.TXT @@ -0,0 +1,28 @@ +f=474000000,d=Channel 21 +f=482000000,d=Channel 22 +f=490000000,d=Channel 23 +f=498000000,d=Channel 24 +f=506000000,d=Channel 25 +f=514000000,d=Channel 26 +f=522000000,d=Channel 27 +f=530000000,d=Channel 28 +f=538000000,d=Channel 29 +f=546000000,d=Channel 30 +f=554000000,d=Channel 31 +f=562000000,d=Channel 32 +f=570000000,d=Channel 33 +f=578000000,d=Channel 34 +f=586000000,d=Channel 35 +f=594000000,d=Channel 36 +f=602000000,d=Channel 37 +f=610000000,d=Channel 38 +f=618000000,d=Channel 39 +f=626000000,d=Channel 40 +f=634000000,d=Channel 41 +f=642000000,d=Channel 42 +f=650000000,d=Channel 43 +f=658000000,d=Channel 44 +f=666000000,d=Channel 45 +f=674000000,d=Channel 46 +f=682000000,d=Channel 47 +f=690000000,d=Channel 48 From f9685517eadd2b0963fc53ed4cfe72c52a5f52fb Mon Sep 17 00:00:00 2001 From: RedFox-Fr Date: Wed, 14 Apr 2021 00:54:10 +0200 Subject: [PATCH 46/52] Update somes sdcard/FREQMAN files --- sdcard/FREQMAN/DABPLUS.TXT | 19 ++++++++------- sdcard/FREQMAN/DPMR446.TXT | 48 +++++++++++++++++++++++++------------- sdcard/FREQMAN/PMR446.TXT | 24 ++++++++++++------- sdcard/FREQMAN/WLAN2_4.TXT | 1 + sdcard/FREQMAN/WLAN5_8.TXT | 9 +++++++ 5 files changed, 69 insertions(+), 32 deletions(-) diff --git a/sdcard/FREQMAN/DABPLUS.TXT b/sdcard/FREQMAN/DABPLUS.TXT index d52610dc..20545ef7 100644 --- a/sdcard/FREQMAN/DABPLUS.TXT +++ b/sdcard/FREQMAN/DABPLUS.TXT @@ -18,19 +18,22 @@ f=202928000,d=Channel 9A f=204648000,d=Channel 9B f=206358000,d=Channel 9C f=208068000,d=Channel 9D -f=209938000,d=Channel 10A +f=209938000,d=Channel 10A +f=210096000,d=Channel 10N f=211648000,d=Channel 10B f=213368000,d=Channel 10C -f=215078000,d=Channel 10D +f=215078000,d=Channel 10D f=216928000,d=Channel 11A -f=218648000,d=Channel 11B -f=220358000,d=Channel 11C -f=222068000,d=Channel 11D +f=217088000,d=Channel 11N +f=218648000,d=Channel 11B +f=220358000,d=Channel 11C +f=222068000,d=Channel 11D f=223938000,d=Channel 12A -f=225648000,d=Channel 12B -f=227368000,d=Channel 12C +f=224096000,d=Channel 12N +f=225648000,d=Channel 12B +f=227368000,d=Channel 12C f=229078000,d=Channel 12D -f=230788000,d=Channel 13A +f=230788000,d=Channel 13A f=232498000,d=Channel 13B f=234208000,d=Channel 13C f=235778000,d=Channel 13D diff --git a/sdcard/FREQMAN/DPMR446.TXT b/sdcard/FREQMAN/DPMR446.TXT index 60cadc9a..b43e7d71 100644 --- a/sdcard/FREQMAN/DPMR446.TXT +++ b/sdcard/FREQMAN/DPMR446.TXT @@ -1,16 +1,32 @@ -f=446103125,d=dPMR CH1 -f=446109375,d=dPMR CH2 -f=446115625,d=dPMR CH3 -f=446121875,d=dPMR CH4 -f=446128125,d=dPMR CH5 -f=446134375,d=dPMR CH6 -f=446140625,d=dPMR CH7 -f=446146875,d=dPMR CH8 -f=446153125,d=dPMR CH9 -f=446159375,d=dPMR CH10 -f=446165625,d=dPMR CH11 -f=446171875,d=dPMR CH12 -f=446178125,d=dPMR CH13 -f=446184375,d=dPMR CH14 -f=446190625,d=dPMR CH15 -f=446196875,d=dPMR CH16 +f=446003125,d=dPMR446 CH1 +f=446009375,d=dPMR446 CH2 +f=446015625,d=dPMR446 CH3 +f=446021875,d=dPMR446 CH4 +f=446028125,d=dPMR446 CH5 +f=446034375,d=dPMR446 CH6 +f=446040625,d=dPMR446 CH7 +f=446046875,d=dPMR446 CH8 +f=446053125,d=dPMR446 CH9 +f=446059375,d=dPMR446 CH10 +f=446065625,d=dPMR446 CH11 +f=446071875,d=dPMR446 CH12 +f=446078125,d=dPMR446 CH13 +f=446084375,d=dPMR446 CH14 +f=446090625,d=dPMR446 CH15 +f=446096875,d=dPMR446 CH16 +f=446103125,d=dPMR446 CH17 +f=446109375,d=dPMR446 CH18 +f=446115625,d=dPMR446 CH19 +f=446121875,d=dPMR446 CH20 +f=446128125,d=dPMR446 CH21 +f=446134375,d=dPMR446 CH22 +f=446140625,d=dPMR446 CH23 +f=446146875,d=dPMR446 CH24 +f=446153125,d=dPMR446 CH25 +f=446159375,d=dPMR446 CH26 +f=446165625,d=dPMR446 CH27 +f=446171875,d=dPMR446 CH28 +f=446178125,d=dPMR446 CH29 +f=446184375,d=dPMR446 CH30 +f=446190625,d=dPMR446 CH31 +f=446196875,d=dPMR446 CH32 diff --git a/sdcard/FREQMAN/PMR446.TXT b/sdcard/FREQMAN/PMR446.TXT index ac9f41d6..46898a75 100644 --- a/sdcard/FREQMAN/PMR446.TXT +++ b/sdcard/FREQMAN/PMR446.TXT @@ -1,8 +1,16 @@ -f=446006250,d=PMR CH1 -f=446018750,d=PMR CH2 -f=446031250,d=PMR CH3 -f=446043750,d=PMR CH4 -f=446056250,d=PMR CH5 -f=446068750,d=PMR CH6 -f=446081250,d=PMR CH7 -f=446093750,d=PMR CH8 +f=446006250,d=PMR446/DMR_T1 CH1 +f=446018750,d=PMR446/DMR_T1 CH2 +f=446031250,d=PMR446/DMR_T1 CH3 +f=446043750,d=PMR446/DMR_T1 CH4 +f=446056250,d=PMR446/DMR_T1 CH5 +f=446068750,d=PMR446/DMR_T1 CH6 +f=446081250,d=PMR446/DMR_T1 CH7 +f=446093750,d=PMR446/DMR_T1 CH8 +f=446106250,d=PMR446/DMR_T1 CH9 +f=446118750,d=PMR446/DMR_T1 CH10 +f=446131250,d=PMR446/DMR_T1 CH11 +f=446143750,d=PMR446/DMR_T1 CH12 +f=446156250,d=PMR446/DMR_T1 CH13 +f=446168750,d=PMR446/DMR_T1 CH14 +f=446181250,d=PMR446/DMR_T1 CH15 +f=446193750,d=PMR446/DMR_T1 CH16 diff --git a/sdcard/FREQMAN/WLAN2_4.TXT b/sdcard/FREQMAN/WLAN2_4.TXT index c14ab007..a7299b39 100644 --- a/sdcard/FREQMAN/WLAN2_4.TXT +++ b/sdcard/FREQMAN/WLAN2_4.TXT @@ -11,3 +11,4 @@ a=2446000000,b=2468000000,d=WLAN 2.4G CH10 a=2451000000,b=2473000000,d=WLAN 2.4G CH11 a=2456000000,b=2478000000,d=WLAN 2.4G CH12 a=2461000000,b=2483000000,d=WLAN 2.4G CH13 +a=2473000000,b=2495000000,d=WLAN 2.4G CH14 diff --git a/sdcard/FREQMAN/WLAN5_8.TXT b/sdcard/FREQMAN/WLAN5_8.TXT index a24d5fb6..b4b4d5d7 100644 --- a/sdcard/FREQMAN/WLAN5_8.TXT +++ b/sdcard/FREQMAN/WLAN5_8.TXT @@ -1,3 +1,5 @@ +a=5150000000,b=5170000000,d=WLAN 5G CH32 +a=5150000000,b=5190000000,d=WLAN 5G CH34 a=5170000000,b=5190000000,d=WLAN 5G CH36 a=5170000000,b=5210000000,d=WLAN 5G CH38 a=5190000000,b=5210000000,d=WLAN 5G CH40 @@ -13,6 +15,8 @@ a=5250000000,b=5330000000,d=WLAN 5G CH58 a=5290000000,b=5310000000,d=WLAN 5G CH60 a=5290000000,b=5330000000,d=WLAN 5G CH62 a=5310000000,b=5330000000,d=WLAN 5G CH64 +a=5330000000,b=5350000000,d=WLAN 5G CH68 +a=5470000000,b=5490000000,d=WLAN 5G CH96 a=5490000000,b=5510000000,d=WLAN 5G CH100 a=5490000000,b=5530000000,d=WLAN 5G CH102 a=5510000000,b=5530000000,d=WLAN 5G CH104 @@ -42,6 +46,11 @@ a=5735000000,b=5815000000,d=WLAN 5G CH155 a=5775000000,b=5795000000,d=WLAN 5G CH157 a=5775000000,b=5815000000,d=WLAN 5G CH159 a=5795000000,b=5815000000,d=WLAN 5G CH161 +a=5735000000,b=5895000000,d=WLAN 5G CH163 a=5815000000,b=5835000000,d=WLAN 5G CH165 +a=5815000000,b=5855000000,d=WLAN 5G CH167 a=5835000000,b=5855000000,d=WLAN 5G CH169 +a=5825000000,b=5885000000,d=WLAN 5G CH171 a=5855000000,b=5875000000,d=WLAN 5G CH173 +a=5855000000,b=5885000000,d=WLAN 5G CH175 +a=5875000000,b=5895000000,d=WLAN 5G CH177 From 136209dc8d276a06414c7851a523e0626735baa2 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Wed, 14 Apr 2021 09:25:38 +0200 Subject: [PATCH 47/52] Update ui_about_simple.cpp --- firmware/application/apps/ui_about_simple.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/apps/ui_about_simple.cpp b/firmware/application/apps/ui_about_simple.cpp index b348c421..5e39def5 100644 --- a/firmware/application/apps/ui_about_simple.cpp +++ b/firmware/application/apps/ui_about_simple.cpp @@ -31,7 +31,7 @@ namespace ui console.writeln("N0vaPixel,klockee,GullCode"); console.writeln("jamesshao8,ITAxReal,rascafr"); console.writeln("mcules,dqs105,strijar"); - console.writeln("RedFox-Fr"); + console.writeln("zhang00963,RedFox-Fr"); console.writeln(""); break; From dfa1a9857588a483992c92210b2d855c5309aef4 Mon Sep 17 00:00:00 2001 From: eried <1091420+eried@users.noreply.github.com> Date: Wed, 14 Apr 2021 09:29:45 +0200 Subject: [PATCH 48/52] Update hackrf --- hackrf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hackrf b/hackrf index 43e6f99f..e6eb4ba2 160000 --- a/hackrf +++ b/hackrf @@ -1 +1 @@ -Subproject commit 43e6f99fe8543094d18ff3a6550ed2066c398862 +Subproject commit e6eb4ba29bbe5dc2fcd092e394188bc10a8bad54 From d60299af957ada1634ca461c0a938e18f2eecef4 Mon Sep 17 00:00:00 2001 From: Eric Fossum Date: Sat, 17 Apr 2021 22:20:28 +0000 Subject: [PATCH 49/52] Added a couple snap values to the calls app. --- firmware/application/apps/ui_search.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/firmware/application/apps/ui_search.hpp b/firmware/application/apps/ui_search.hpp index 7e186c2e..8dc6f48e 100644 --- a/firmware/application/apps/ui_search.hpp +++ b/firmware/application/apps/ui_search.hpp @@ -212,12 +212,14 @@ private: true }; OptionsField options_snap { - { 17 * 8, 15 * 8 }, - 7, - { + { 17 * 8, 15 * 8 }, // Position + 7, // Length + { // Options { "25kHz ", 25000 }, { "12.5kHz", 12500 }, - { "8.33kHz", 8333 } + { "8.33kHz", 8333 }, + { "2.5kHz", 2500 }, + { "500Hz", 500 } } }; From 5f778c173469a7e4a3ce1faf989bdd146c2bc515 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Mon, 19 Apr 2021 10:04:50 +0200 Subject: [PATCH 50/52] Update ui_about_simple.cpp --- firmware/application/apps/ui_about_simple.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/apps/ui_about_simple.cpp b/firmware/application/apps/ui_about_simple.cpp index 80c6da20..241bbb4a 100644 --- a/firmware/application/apps/ui_about_simple.cpp +++ b/firmware/application/apps/ui_about_simple.cpp @@ -32,7 +32,7 @@ namespace ui console.writeln("jamesshao8,ITAxReal,rascafr"); console.writeln("mcules,dqs105,strijar"); console.writeln("zhang00963,RedFox-Fr"); - console.writeln("East2West"); + console.writeln("East2West,fossum"); console.writeln(""); break; From 85e4a43cbd7e4ba615ed62e39373e4e1ac07de63 Mon Sep 17 00:00:00 2001 From: eried <1091420+eried@users.noreply.github.com> Date: Thu, 22 Apr 2021 09:34:52 +0200 Subject: [PATCH 51/52] Version bump --- firmware/application/ui_navigation.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index f9ac3bc0..f7b7f45e 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -214,7 +214,7 @@ public: InformationView(NavigationView& nav); private: - static constexpr auto version_string = "v1.3.1"; + static constexpr auto version_string = "v1.4.0"; NavigationView& nav_; Rectangle backdrop { From f1fd9a3db1a6d1620b9a8c40a4741b2f8962ba51 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Thu, 22 Apr 2021 12:11:32 +0200 Subject: [PATCH 52/52] Removing the warning Does not applies anymore with the latest release --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 32038c4e..5d853679 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -> ⚠ **BEFORE BUYING YOURS:** ⚠ Beware of hardware mods that use a custom firmware, which are [NOT COMPATIBLE](https://github.com/eried/portapack-mayhem/issues/264) with older forks, and they do not follow the license. **ASK THE SELLER if the unit works with an specific firmware, for example, pointing to the [![GitHub release (latest by date)](https://img.shields.io/github/v/release/eried/portapack-mayhem?label=latest%20release&style=social)](https://github.com/eried/portapack-mayhem/releases/latest) on this repository** - # PortaPack Mayhem [![Build Status](https://travis-ci.com/eried/portapack-mayhem.svg?branch=master)](https://travis-ci.com/eried/portapack-mayhem) [![buddy pipeline](https://app.buddy.works/eried/portapack/pipelines/pipeline/252276/badge.svg?token=48cd59d53de0589a8fbe26bc751d77a59a011cf72581da049343879402991c34 "buddy pipeline")](https://app.buddy.works/eried/portapack/pipelines/pipeline/252276) [![CodeScene Code Health](https://codescene.io/projects/8381/status-badges/code-health)](https://codescene.io/projects/8381) [![GitHub All Releases](https://img.shields.io/github/downloads/eried/portapack-mayhem/total)](https://github.com/eried/portapack-mayhem/releases) [![GitHub Releases](https://img.shields.io/github/downloads/eried/portapack-mayhem/latest/total)](https://github.com/eried/portapack-mayhem/releases/latest) [![Docker Hub Pulls](https://img.shields.io/docker/pulls/eried/portapack.svg)](https://hub.docker.com/r/eried/portapack) [![Discord Chat](https://img.shields.io/discord/719669764804444213.svg)](https://discord.gg/tuwVMv3) [![Check bounties!](https://img.shields.io/bountysource/team/portapack-mayhem/activity?color=%2333ccff&label=bountysource%20%28USD%29&style=plastic)](https://www.bountysource.com/teams/portapack-mayhem/issues)