#765 unlimited range for manual mode

* fix for #765, manual mode has unlimited range now
* speedup for button_add.on_select (roughly x70 times faster)
* fix for random freezes while switching to Audio
This commit is contained in:
rusty.labs 2022-12-26 17:18:30 -05:00
parent 25c267a3d9
commit 1f7b800c2a
2 changed files with 122 additions and 42 deletions

View File

@ -31,13 +31,23 @@ ScannerThread::ScannerThread(
std::vector<rf::Frequency> frequency_list
) : frequency_list_ { std::move(frequency_list) }
{
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, ScannerThread::static_fn, this);
create_thread();
}
ScannerThread::ScannerThread(const jammer::jammer_range_t& frequency_range, size_t def_step) : frequency_range_(frequency_range), def_step_(def_step)
{
create_thread();
}
ScannerThread::~ScannerThread() {
stop();
}
void ScannerThread::create_thread()
{
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, ScannerThread::static_fn, this);
}
void ScannerThread::stop() {
if( thread ) {
chThdTerminate(thread);
@ -102,12 +112,13 @@ void ScannerThread::run() {
else
restart_scan=false; //Effectively skipping first retuning, giving system time
}
message.freq = frequency_list_[frequency_index];
message.range = frequency_index; //Inform freq (for coloring purposes also!)
EventDispatcher::send_message(message);
}
else { //NOT scanning
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
for (uint32_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);
@ -126,16 +137,58 @@ void ScannerThread::run() {
}
chThdSleepMilliseconds(50); //Needed to (eventually) stabilize the receiver into new freq
}
}else if(def_step_ > 0) // manual mode
{
RetuneMessage message { };
int64_t frequency_index = 0;
int64_t size = (frequency_range_.max - frequency_range_.min) / def_step_;
bool restart_scan = false; //Flag whenever scanning is restarting after a pause
while( !chThdShouldTerminate() ) {
if (_scanning) { //Scanning
if (_freq_lock == 0) { //normal scanning (not performing freq_lock)
if (!restart_scan) { //looping at full speed
if (_fwd) { //forward
frequency_index++;
if (frequency_index >= size)
frequency_index = 0;
} else { //reverse
if (frequency_index < 1)
frequency_index = size;
frequency_index--;
}
receiver_model.set_tuning_frequency(frequency_range_.min + frequency_index * def_step_); // Retune
}
else
restart_scan=false; //Effectively skipping first retuning, giving system time
}
message.freq = frequency_range_.min + frequency_index * def_step_;
message.range = 0; //Inform freq (for coloring purposes also!)
EventDispatcher::send_message(message);
}
else { //NOT scanning
restart_scan=true; //Flag the need for skipping a cycle when restarting scan
}
chThdSleepMilliseconds(50); //Needed to (eventually) stabilize the receiver into new freq
}
}
}
void ScannerView::handle_retune(uint32_t i) {
void ScannerView::handle_retune(int64_t freq, uint32_t freq_idx) {
current_index = freq_idx; //since it is an ongoing scan, this is a new index
current_frequency = freq;
switch (scan_thread->is_freq_lock())
{
case 0: //NO FREQ LOCK, ONGOING STANDARD SCANNING
text_cycle.set( to_string_dec_uint(i + 1,3) );
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
if (frequency_list.size() > 0) {
text_cycle.set( to_string_dec_uint(freq_idx + 1,3) );
}
if (freq_idx < description_list.size() && description_list[freq_idx].size() > 0) {
desc_cycle.set( description_list[freq_idx] ); //Show new description
}
break;
case 1: //STARTING LOCK FREQ
big_display.set_style(&style_yellow);
@ -146,7 +199,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[current_index]); //UPDATE the big Freq after 0, 1 or MAX_FREQ_LOCK (at least, for color synching)
big_display.set(freq); //UPDATE the big Freq after 0, 1 or MAX_FREQ_LOCK (at least, for color synching)
}
void ScannerView::focus() {
@ -154,6 +207,8 @@ void ScannerView::focus() {
}
ScannerView::~ScannerView() {
// make sure to stop the thread before shutting down the receiver
scan_thread.reset();
audio::output::stop();
receiver_model.disable();
baseband::shutdown();
@ -297,23 +352,15 @@ ScannerView::ScannerView(
description_list.clear();
def_step = step_mode.selected_index_value(); //Use def_step from manual selector
description_list.push_back(
"M" + to_string_short_freq(frequency_range.min) + ">"
+ to_string_short_freq(frequency_range.max) + "S"
+ to_string_short_freq(def_step).erase(0,1) //euquiq: lame kludge to reduce spacing in step freq
);
rf::Frequency frequency = frequency_range.min;
while (frequency_list.size() < FREQMAN_MAX_PER_FILE && frequency <= frequency_range.max) { //add manual range
frequency_list.push_back(frequency);
description_list.push_back(""); //If empty, will keep showing the last description
frequency+=def_step;
}
show_max();
desc_cycle.set("");
text_max.set("");
text_cycle.set("");
if ( userpause ) //If user-paused, resume
user_resume();
big_display.set_style(&style_grey); //Back to grey color
start_scan_thread(); //RESTART SCANNER THREAD
start_scan_thread(frequency_range, def_step); //RESTART SCANNER THREAD
}
};
@ -333,35 +380,56 @@ ScannerView::ScannerView(
big_display.set_style(&style_grey); //Back to grey color
};
button_add.on_select = [this](Button&) { //frequency_list[current_index]
button_add.on_select = [this](Button&) { // current_frequency
File scanner_file;
std::string freq_file_path = "FREQMAN/" + loaded_file_name + ".TXT";
const std::string freq_file_path = "FREQMAN/" + loaded_file_name + ".TXT";
auto result = scanner_file.open(freq_file_path); //First search if freq is already in txt
if (!result.is_valid()) {
std::string frequency_to_add = "f="
+ to_string_dec_uint(frequency_list[current_index] / 1000)
+ to_string_dec_uint(frequency_list[current_index] % 1000UL, 3, '0');
char one_char[1]; //Read it char by char
std::string line; //and put read line in here
const std::string frequency_to_add = "f="
+ to_string_dec_uint(current_frequency / 1000)
+ to_string_dec_uint(current_frequency % 1000UL, 3, '0');
bool found=false;
for (size_t pointer=0; pointer < scanner_file.size();pointer++) {
constexpr size_t buffer_size = 1024;
char buffer[buffer_size];
for (size_t pointer = 0, freq_str_idx = 0; pointer < scanner_file.size(); pointer += buffer_size) {
size_t adjusted_buffer_size;
if (pointer + buffer_size >= scanner_file.size()) {
memset(buffer, 0, sizeof(buffer));
adjusted_buffer_size = scanner_file.size() - pointer;
}
else {
adjusted_buffer_size = buffer_size;
}
scanner_file.seek(pointer);
scanner_file.read(one_char, 1);
if ((int)one_char[0] > 31) { //ascii space upwards
line += one_char[0]; //Add it to the textline
}
else if (one_char[0] == '\n') { //New Line
if (line.compare(0, frequency_to_add.size(),frequency_to_add) == 0) {
found=true;
break;
scanner_file.read(buffer, adjusted_buffer_size);
for (size_t i = 0; i < adjusted_buffer_size; ++i) {
if (buffer[i] == frequency_to_add.data()[freq_str_idx]) {
++freq_str_idx;
if (freq_str_idx >= frequency_to_add.size()) {
found = true;
break;
}
}
else {
freq_str_idx = 0;
}
line.clear(); //Ready for next textline
}
}
if (found) {
break;
}
}
if (found) {
nav_.display_modal("Error", "Frequency already exists");
big_display.set(frequency_list[current_index]); //After showing an error
big_display.set(current_frequency); //After showing an error
}
else {
scanner_file.append(freq_file_path); //Second: append if it is not there
@ -370,7 +438,7 @@ ScannerView::ScannerView(
} else
{
nav_.display_modal("Error", "Cannot open " + loaded_file_name + ".TXT\nfor appending freq.");
big_display.set(frequency_list[current_index]); //After showing an error
big_display.set(current_frequency); //After showing an error
}
};
@ -566,4 +634,10 @@ void ScannerView::start_scan_thread() {
scan_thread = std::make_unique<ScannerThread>(frequency_list);
}
void ScannerView::start_scan_thread(const jammer::jammer_range_t& frequency_range, size_t def_step) {
receiver_model.enable();
receiver_model.set_squelch_level(0);
scan_thread = std::make_unique<ScannerThread>(frequency_range, def_step);
}
} /* namespace ui */

View File

@ -46,6 +46,7 @@ size_t const mod_step[3] = {9000, 100000, 12500 };
class ScannerThread {
public:
ScannerThread(std::vector<rf::Frequency> frequency_list);
ScannerThread(const jammer::jammer_range_t& frequency_range, size_t def_step);
~ScannerThread();
void set_scanning(const bool v);
@ -67,6 +68,8 @@ public:
private:
std::vector<rf::Frequency> frequency_list_ { };
jammer::jammer_range_t frequency_range_ {false, 0, 0};
size_t def_step_ { 0 };
Thread* thread { nullptr };
bool _scanning { true };
@ -75,6 +78,7 @@ private:
uint32_t _freq_del { 0 };
static msg_t static_fn(void* arg);
void run();
void create_thread();
};
class ScannerView : public View {
@ -120,6 +124,7 @@ private:
NavigationView& nav_;
void start_scan_thread();
void start_scan_thread(const jammer::jammer_range_t& frequency_range, size_t def_step);
size_t change_mode(uint8_t mod_type);
void show_max();
void scan_pause();
@ -129,7 +134,7 @@ private:
void on_statistics_update(const ChannelStatistics& statistics);
void on_headphone_volume_changed(int32_t v);
void handle_retune(uint32_t i);
void handle_retune(int64_t freq, uint32_t freq_idx);
jammer::jammer_range_t frequency_range { false, 0, 0 }; //perfect for manual scan task too...
int32_t squelch { 0 };
@ -139,6 +144,7 @@ private:
freqman_db database { };
std::string loaded_file_name;
uint32_t current_index { 0 };
rf::Frequency current_frequency { 0 };
bool userpause { false };
Labels labels {
@ -295,7 +301,7 @@ private:
Message::ID::Retune,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const RetuneMessage*>(p);
this->handle_retune(message.range);
this->handle_retune(message.freq, message.range);
}
};