From 03084251c5c1b901bf43bee2edeae6600b65bb46 Mon Sep 17 00:00:00 2001
From: euquiq <31453004+euquiq@users.noreply.github.com>
Date: Tue, 28 Jul 2020 01:21:52 -0300
Subject: [PATCH] Added MIC TX and FREQ DEL buttons

MIC TX button :Shortcut for jumping into TX -> MIC app.

FREQ DEL button: Deletes currently displayed frequency from temporary scanning memory. Ideal to get rid of those not wanted "noisy" freqs in the middle of a range scan.

Also, some code optimizations thrown in.
---
 firmware/application/apps/ui_scanner.cpp | 123 ++++++++++++++++-------
 firmware/application/apps/ui_scanner.hpp |  40 ++++++--
 2 files changed, 114 insertions(+), 49 deletions(-)

diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp
index 26c5c776..eafdf4d1 100644
--- a/firmware/application/apps/ui_scanner.cpp
+++ b/firmware/application/apps/ui_scanner.cpp
@@ -24,8 +24,6 @@
 #include "portapack_persistent_memory.hpp"
 #include "baseband_api.hpp"
 #include "string_format.hpp"
-#include "audio.hpp"
-
 
 using namespace portapack;
 
@@ -58,14 +56,6 @@ bool ScannerThread::is_scanning() {
 	return _scanning;
 }
 
-void ScannerThread::set_userpause(const bool v) {
-	_userpause = v;
-}
-
-bool ScannerThread::is_userpause() {
-	return _userpause;
-}
-
 void ScannerThread::set_freq_lock(const uint32_t v) {
 	_freq_lock = v;
 }
@@ -74,6 +64,10 @@ uint32_t ScannerThread::is_freq_lock() {
 	return _freq_lock;
 }
 
+void ScannerThread::set_freq_del(const uint32_t v) {
+	_freq_del = v;
+}
+
 msg_t ScannerThread::static_fn(void* arg) {
 	auto obj = static_cast<ScannerThread*>(arg);
 	obj->run();
@@ -81,25 +75,42 @@ msg_t ScannerThread::static_fn(void* arg) {
 }
 
 void ScannerThread::run() {
-	if (frequency_list_.size())	{				//IF THERE IS A FREQUENCY LIST ...	
+	if (frequency_list_.size())	{					//IF THERE IS A FREQUENCY LIST ...	
 		RetuneMessage message { };
 		uint32_t frequency_index = frequency_list_.size();
-		uint32_t freqlock_counter=0;
 		while( !chThdShouldTerminate() ) {
-			if (_scanning) {
-				if (_freq_lock == 0) {	//normal scanning 
+			if (_scanning) 
+			{						//Scanning
+				if (_freq_lock == 0) {				//normal scanning (not performing freq_lock)
 					frequency_index++;
 					if (frequency_index >= frequency_list_.size())
 						frequency_index = 0;		
 					receiver_model.set_tuning_frequency(frequency_list_[frequency_index]);	// Retune
-				} else {
-					chThdSleepMilliseconds(25); //Extra time ?
 				}
-		
 				message.range = frequency_index;	//Inform freq (for coloring purposes also!)
 				EventDispatcher::send_message(message);
+			} 
+			else 
+			{ 									//If not scanning, check for user asking to delete a freq:
+				if (_freq_del != 0) {			//There is a frequency to delete
+					for (uint16_t i = 0; i < frequency_list_.size(); i++) {	//Search for the freq to delete
+						if (frequency_list_[i] == _freq_del) 
+						{						//found: Erase it
+							frequency_list_.erase(frequency_list_.begin() + i);
+							if (i==0)			//set scan index one place back to compensate
+								i=frequency_list_.size();
+							else
+								i--;
+							
+							break;
+						}
+					}
+					_freq_del = 0;		//deleted.
+				}
+
 			}
-			chThdSleepMilliseconds(50);
+			chThdSleepMilliseconds(60);		//This value on 50, when scan resume, it does not stabilize for the next freq in list, it jumped one more ahead. 
+			//With 100 it worked fine but scanner is slow. This may need fixing 
 		}
 	}
 }
@@ -107,9 +118,10 @@ void ScannerThread::run() {
 void ScannerView::handle_retune(uint32_t i) {
 	switch (scan_thread->is_freq_lock())
 	{
-	case 0:		//NO FREQ LOCK, ONGOING STANDARD SCANNING
+	case 0:										//NO FREQ LOCK, ONGOING STANDARD SCANNING
 		text_cycle.set( to_string_dec_uint(i + 1,3) );
-		if (description_list[i].size() > 0) desc_cycle.set( description_list[i] );	//If this is a new description: show
+		current_index = i;		//since it is an ongoing scan, this is a new index
+		if (description_list[current_index].size() > 0) desc_cycle.set( description_list[current_index] );	//Show new description	
 		break;
 	case 1:
 		big_display.set_style(&style_yellow);	//STARTING LOCK FREQ
@@ -120,7 +132,7 @@ void ScannerView::handle_retune(uint32_t i) {
 	default:	//freq lock is checking the signal, do not update display
 		return;
 	}
-	big_display.set(frequency_list[i]);	//UPDATE the big Freq after 0, 1 or MAX_FREQ_LOCK (at least, for color synching)
+	big_display.set(frequency_list[current_index]);	//UPDATE the big Freq after 0, 1 or MAX_FREQ_LOCK (at least, for color synching)
 }
 
 void ScannerView::focus() {
@@ -164,7 +176,9 @@ ScannerView::ScannerView(
 		&step_mode,
 		&button_manual_scan,
 		&button_pause,
-		&button_audio_app
+		&button_audio_app,
+		&button_remove,
+		&button_mic_app
 	});
 
 	def_step = change_mode(AM);	//Start on AM
@@ -196,25 +210,47 @@ ScannerView::ScannerView(
 	};
 
 	button_pause.on_select = [this](Button&) {
-		if (scan_thread->is_userpause()) { 
-			timer = wait * 10;					//Unlock timer pause on_statistics_update
-			button_pause.set_text("PAUSE");		//resume scanning (show button for pause)	
-			scan_thread->set_userpause(false);	//Signal user's will
-		} else {
+		if ( userpause )
+			user_resume();
+		else {
 			scan_pause();
-			scan_thread->set_userpause(true);
-			button_pause.set_text("RESUME");		//PAUSED, show resume	
+			button_pause.set_text("RESUME");	//PAUSED, show resume
+			userpause=true;
 		}
 	};
 
 	button_audio_app.on_select = [this](Button&) {
-		if (scan_thread->is_scanning())
-		 	scan_thread->set_scanning(false);
+		//if (scan_thread->is_scanning())
+		// 	scan_thread->set_scanning(false);
 		scan_thread->stop();
 		nav_.pop();
 		nav_.push<AnalogAudioView>();
 	};
 
+		button_mic_app.on_select = [this](Button&) {
+		//if (scan_thread->is_scanning())
+		// 	scan_thread->set_scanning(false);
+		scan_thread->stop();
+		nav_.pop();
+		nav_.push<MicTXView>();
+	};
+
+	button_remove.on_select = [this](Button&) {
+		if (frequency_list.size() > current_index) {
+			if (scan_thread->is_scanning())			//STOP Scanning if necessary
+				scan_thread->set_scanning(false);
+			scan_thread->set_freq_del(frequency_list[current_index]);
+			description_list.erase(description_list.begin() + current_index);
+			frequency_list.erase(frequency_list.begin() + current_index);
+			show_max();								//UPDATE new list size on screen
+			chThdSleepMilliseconds(300);			//"debouncing" pause so user take finger off 
+			timer = wait * 10;						//Unlock timer pause on_statistics_update
+			scan_thread->set_freq_lock(0); 			//Reset the scanner lock
+			if ( userpause ) 						//If user-paused, resume
+				user_resume();
+		}
+	};
+
 	button_manual_scan.on_select = [this](Button&) {
 		if (!frequency_range.min || !frequency_range.max) {
 			nav_.display_modal("Error", "Both START and END freqs\nneed a value");
@@ -239,21 +275,25 @@ ScannerView::ScannerView(
 			description_list.push_back("");				//If empty, will keep showing the last description
 			frequency+=def_step;
 		}
-
 		show_max();
+		if ( userpause ) 						//If user-paused, resume
+			user_resume();
+		big_display.set_style(&style_grey);		//Back to grey color
 		start_scan_thread(); //RESTART SCANNER THREAD
 		}
 	};
 
 	field_mode.on_change = [this](size_t, OptionsField::value_t v) {
 		if (scan_thread->is_scanning())
-			scan_thread->set_scanning(false); // WE STOP SCANNING
+			scan_thread->set_scanning(false); 	//STOP SCANNING
 		audio::output::stop();
 		scan_thread->stop();
 		receiver_model.disable();
 		baseband::shutdown();
 		chThdSleepMilliseconds(50);
 		change_mode(v);
+		if ( userpause ) 						//If user-paused, resume
+			user_resume();
 		start_scan_thread();
 	};
 
@@ -310,7 +350,7 @@ ScannerView::ScannerView(
 }
 
 void ScannerView::on_statistics_update(const ChannelStatistics& statistics) {
-	if (!scan_thread->is_userpause()) 
+	if ( !userpause ) 
 	{
 		if (timer >= (wait * 10) ) 
 		{
@@ -349,11 +389,16 @@ void ScannerView::scan_pause() {
 }
 
 void ScannerView::scan_resume() {
-	if (!scan_thread->is_scanning()) {
-		audio::output::stop();
-		big_display.set_style(&style_grey);	//Back to grey color
-		scan_thread->set_scanning(true);   // WE RESCAN
-	}
+	audio::output::stop();
+	big_display.set_style(&style_grey);		//Back to grey color
+	if (!scan_thread->is_scanning())
+		scan_thread->set_scanning(true);   // RESUME!
+}
+
+void ScannerView::user_resume() {
+	timer = wait * 10;					//Unlock timer pause on_statistics_update ( will trigger a scan_resume() )
+	button_pause.set_text("PAUSE");		//Show button for pause
+	userpause=false;					//Resume scanning
 }
 
 void ScannerView::on_headphone_volume_changed(int32_t v) {
diff --git a/firmware/application/apps/ui_scanner.hpp b/firmware/application/apps/ui_scanner.hpp
index f9ee3aa7..010a28fe 100644
--- a/firmware/application/apps/ui_scanner.hpp
+++ b/firmware/application/apps/ui_scanner.hpp
@@ -26,6 +26,8 @@
 #include "ui_font_fixed_8x16.hpp"
 #include "freqman.hpp"
 #include "analog_audio_app.hpp"
+#include "audio.hpp"
+#include "ui_mictx.hpp"
 
 
 #define MAX_DB_ENTRY 500
@@ -46,12 +48,11 @@ public:
 	void set_scanning(const bool v);
 	bool is_scanning();
 
-	void set_userpause(const bool v);
-	bool is_userpause();
-
 	void set_freq_lock(const uint32_t v);
 	uint32_t is_freq_lock();
 
+	void set_freq_del(const uint32_t v);
+
 	void stop();
 
 	ScannerThread(const ScannerThread&) = delete;
@@ -64,8 +65,8 @@ private:
 	Thread* thread { nullptr };
 	
 	bool _scanning { true };
-	bool _userpause { false };
 	uint32_t _freq_lock { 0 };
+	uint32_t _freq_del { 0 };
 	static msg_t static_fn(void* arg);
 	void run();
 };
@@ -97,6 +98,12 @@ public:
 		.foreground = Color::green(),
 	};
 
+	const Style style_red {		//erasing freq
+		.font = font::fixed_8x16,
+		.background = Color::black(),
+		.foreground = Color::red(),
+	};
+
 	std::string title() const override { return "SCANNER"; };
 	std::vector<rf::Frequency> frequency_list{ };
 	std::vector<string> description_list { };
@@ -111,6 +118,7 @@ private:
 	void show_max();
 	void scan_pause();
 	void scan_resume();
+	void user_resume();
 
 	void on_statistics_update(const ChannelStatistics& statistics);
 	void on_headphone_volume_changed(int32_t v);
@@ -122,13 +130,15 @@ private:
 	uint32_t wait { 0 };
 	size_t	def_step { 0 };
 	freqman_db database { };
+	uint32_t current_index { 0 };
+	bool userpause { false };
 	
 	Labels labels {
 		{ { 0 * 8, 0 * 16 }, "LNA:   VGA:   AMP:  VOL:", Color::light_grey() },
 		{ { 0 * 8, 1* 16 }, "BW:    SQUELCH:  /99 WAIT:", Color::light_grey() },
 		{ { 3 * 8, 10 * 16 }, "START        END     MANUAL", Color::light_grey() },
-		{ { 0 * 8, 14 * 16 }, "MODE:", Color::light_grey() },
-		{ { 11 * 8, 14 * 16 }, "STEP:", Color::light_grey() },
+		{ { 0 * 8, 27 * 8 }, "MODE:", Color::light_grey() },
+		{ { 11 * 8, 27 * 8 }, "STEP:", Color::light_grey() },
 	};
 	
 	LNAGainField field_lna {
@@ -210,7 +220,7 @@ private:
 	};
 
 	OptionsField field_mode {
-		{ 5 * 8, 14 * 16 },
+		{ 5 * 8, 27 * 8 },
 		6,
 		{
 			{ " AM  ", 0 },
@@ -220,7 +230,7 @@ private:
 	};
 
 	OptionsField step_mode {
-		{ 17 * 8, 14 * 16 },
+		{ 17 * 8, 27 * 8 },
 		12,
 		{
 			{ "5Khz (SA AM)", 	5000 },
@@ -237,14 +247,24 @@ private:
 	};
 
 	Button button_pause {
-		{ 12, 17 * 16, 96, 24 },
+		{ 12, 15 * 16, 96, 24 },
 		"PAUSE"
 	};
 
 	Button button_audio_app {
-		{ 124, 17 * 16, 96, 24 },
+		{ 124, 15 * 16, 96, 24 },
 		"AUDIO APP"
 	};
+
+		Button button_remove {
+		{ 12, 17 * 16, 96, 24 },
+		"DEL FREQ"
+	};
+
+	Button button_mic_app {
+		{ 124, 17 * 16, 96, 24 },
+		"MIC TX APP"
+	};
 	
 	std::unique_ptr<ScannerThread> scan_thread { };
 	
-- 
GitLab