Transmitter config widget

Frequency manager duplicate alert
Tone sets
This commit is contained in:
furrtek 2017-01-30 13:10:30 +00:00
parent 0642d633c3
commit 688a012443
29 changed files with 759 additions and 203 deletions

View File

@ -175,6 +175,7 @@ set(CPPSRC
ui_record_view.cpp
ui_replay_view.cpp
ui_rssi.cpp
ui_script.cpp
ui_sd_card_status_view.cpp
ui_sd_wipe.cpp
# ui_sd_card_debug.cpp
@ -183,6 +184,7 @@ set(CPPSRC
ui_spectrum.cpp
ui_textentry.cpp
ui_touch_calibration.cpp
ui_transmitter.cpp
ui_whipcalc.cpp
ui_whistle.cpp
# ui_loadmodule.cpp

View File

@ -5000,6 +5000,33 @@ ui_rssi.cpp.s:
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_rssi.cpp.s
.PHONY : ui_rssi.cpp.s
ui_script.obj: ui_script.cpp.obj
.PHONY : ui_script.obj
# target to build an object file
ui_script.cpp.obj:
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_script.cpp.obj
.PHONY : ui_script.cpp.obj
ui_script.i: ui_script.cpp.i
.PHONY : ui_script.i
# target to preprocess a source file
ui_script.cpp.i:
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_script.cpp.i
.PHONY : ui_script.cpp.i
ui_script.s: ui_script.cpp.s
.PHONY : ui_script.s
# target to generate assembly for a file
ui_script.cpp.s:
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_script.cpp.s
.PHONY : ui_script.cpp.s
ui_sd_card_status_view.obj: ui_sd_card_status_view.cpp.obj
.PHONY : ui_sd_card_status_view.obj
@ -5189,6 +5216,33 @@ ui_touch_calibration.cpp.s:
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_touch_calibration.cpp.s
.PHONY : ui_touch_calibration.cpp.s
ui_transmitter.obj: ui_transmitter.cpp.obj
.PHONY : ui_transmitter.obj
# target to build an object file
ui_transmitter.cpp.obj:
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_transmitter.cpp.obj
.PHONY : ui_transmitter.cpp.obj
ui_transmitter.i: ui_transmitter.cpp.i
.PHONY : ui_transmitter.i
# target to preprocess a source file
ui_transmitter.cpp.i:
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_transmitter.cpp.i
.PHONY : ui_transmitter.cpp.i
ui_transmitter.s: ui_transmitter.cpp.s
.PHONY : ui_transmitter.s
# target to generate assembly for a file
ui_transmitter.cpp.s:
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/ui_transmitter.cpp.s
.PHONY : ui_transmitter.cpp.s
ui_whipcalc.obj: ui_whipcalc.cpp.obj
.PHONY : ui_whipcalc.obj
@ -5793,6 +5847,9 @@ help:
@echo "... ui_rssi.obj"
@echo "... ui_rssi.i"
@echo "... ui_rssi.s"
@echo "... ui_script.obj"
@echo "... ui_script.i"
@echo "... ui_script.s"
@echo "... ui_sd_card_status_view.obj"
@echo "... ui_sd_card_status_view.i"
@echo "... ui_sd_card_status_view.s"
@ -5814,6 +5871,9 @@ help:
@echo "... ui_touch_calibration.obj"
@echo "... ui_touch_calibration.i"
@echo "... ui_touch_calibration.s"
@echo "... ui_transmitter.obj"
@echo "... ui_transmitter.i"
@echo "... ui_transmitter.s"
@echo "... ui_whipcalc.obj"
@echo "... ui_whipcalc.i"
@echo "... ui_whipcalc.s"

View File

@ -79,7 +79,7 @@ void WFMConfig::apply() const {
audio::set_rate(audio::Rate::Hz_48000);
}
void set_tones_data(const uint64_t bw, const uint32_t pre_silence, const uint16_t tone_count,
void set_tones_data(const uint32_t bw, const uint32_t pre_silence, const uint16_t tone_count,
const bool dual_tone, const bool audio_out) {
const TonesConfigureMessage message {
(uint32_t)(262144 * bw) / 1536000,

View File

@ -54,7 +54,7 @@ struct WFMConfig {
void apply() const;
};
void set_tones_data(const uint64_t bw, const uint32_t pre_silence, const uint16_t tone_count,
void set_tones_data(const uint32_t bw, const uint32_t pre_silence, const uint16_t tone_count,
const bool dual_tone, const bool audio_out);
void set_audiotx_data(const uint32_t divider, const uint32_t bw, const bool ctcss_enabled, const uint32_t ctcss_phase_inc);
void set_fifo_data(const int8_t * data);

View File

@ -24,14 +24,14 @@
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "tonesets.hpp"
#include "encoders.hpp"
#include "portapack.hpp"
using namespace encoders;
#define CCIR_TONE_LENGTH (153600-1) // 1536000*0.1
#define CCIR_DELTA_COEF (43.691) // (65536*1024)/1536000
#define CCIR_SILENCE (614400-1) // 400ms
#define XY_TONE_LENGTH ((TONES_SAMPLERATE * 0.1) - 1) // 100ms
#define XY_SILENCE (TONES_SAMPLERATE * 0.4) // 400ms
struct bht_city {
std::string name;
@ -39,25 +39,6 @@ struct bht_city {
bool recent;
};
const uint32_t ccir_deltas[16] = {
(uint32_t)(1981 * CCIR_DELTA_COEF),
(uint32_t)(1124 * CCIR_DELTA_COEF),
(uint32_t)(1197 * CCIR_DELTA_COEF),
(uint32_t)(1275 * CCIR_DELTA_COEF),
(uint32_t)(1358 * CCIR_DELTA_COEF),
(uint32_t)(1446 * CCIR_DELTA_COEF),
(uint32_t)(1540 * CCIR_DELTA_COEF),
(uint32_t)(1640 * CCIR_DELTA_COEF),
(uint32_t)(1747 * CCIR_DELTA_COEF),
(uint32_t)(1860 * CCIR_DELTA_COEF),
(uint32_t)(2400 * CCIR_DELTA_COEF),
(uint32_t)(930 * CCIR_DELTA_COEF),
(uint32_t)(2247 * CCIR_DELTA_COEF),
(uint32_t)(991 * CCIR_DELTA_COEF),
(uint32_t)(2110 * CCIR_DELTA_COEF),
(uint32_t)(1055 * CCIR_DELTA_COEF)
};
const rf::Frequency bht_freqs[7] = { 31325000, 31387500, 31437500, 31475000, 31687500, 31975000, 88000000 };
std::string gen_message_ep(uint8_t city_code, size_t family_code_ep, uint32_t relay_state_A, uint32_t relay_state_B);

View File

@ -104,7 +104,7 @@ std::string freqman_item_string(freqman_entry &entry) {
to_string_dec_int((value / 100) % 10000, 4, '0');
if (entry.description.size() <= 19) {
item_string = entry.frequency_str + ":" + entry.description;
item_string = entry.frequency_str + "M: " + entry.description;
} else {
memcpy(temp_buffer, entry.description.c_str(), 16);
temp_buffer[16] = (char)0;

View File

@ -34,7 +34,8 @@ using namespace ui;
enum freqman_error {
NO_ERROR = 0,
ERROR_ACCESS,
ERROR_EMPTY
ERROR_EMPTY,
ERROR_DUPLICATE
};
struct freqman_entry {

View File

@ -23,6 +23,7 @@
// Color bitmaps generated with:
// Gimp image > indexed colors (16), then "xxd -i *.bmp"
//BUG: Set description in frequency save makes everything go crazy
//BUG: Distorted audio in WFM receiver
//BUG: (fixed ?) Bad console scroll init
//BUG: POCSAG misses alphanum messages, cuts them off sometimes
@ -33,8 +34,7 @@
//TEST: Numbers
//TEST: Jammer
//TODO: Frequency manager auto-remove duplicates
//TODO: "TX box" view or composite widget with frequency and bw settings, simple and advanced setup TX buttons...
//TODO: Script engine ?
//TODO: Morse coder for foxhunts
//TODO: Finish EPAR tx
//TODO: IQ replay

View File

@ -68,7 +68,7 @@ private:
static constexpr uint32_t sampling_rate = 1536000;
static constexpr uint32_t baseband_bandwidth = 1750000;
bool logging { true };
bool logging { false };
uint32_t batch_cnt = 0;
uint32_t address { 0 };
uint32_t function { 0 };

View File

@ -0,0 +1,119 @@
/*
* 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 __TONESETS_H__
#define __TONESETS_H__
#include "portapack.hpp"
#define TONES_SAMPLERATE 1536000
#define TONES_DELTA_COEF ((1ULL << 32) / 1536000)
#define TONES_F2D(f) (uint32_t)(f * TONES_DELTA_COEF)
#define DTMF_C0 TONES_F2D(1209)
#define DTMF_C1 TONES_F2D(1336)
#define DTMF_C2 TONES_F2D(1477)
#define DTMF_C3 TONES_F2D(1633)
#define DTMF_R0 TONES_F2D(697)
#define DTMF_R1 TONES_F2D(770)
#define DTMF_R2 TONES_F2D(852)
#define DTMF_R3 TONES_F2D(941)
const uint32_t ccir_deltas[16] = {
TONES_F2D(1981),
TONES_F2D(1124),
TONES_F2D(1197),
TONES_F2D(1275),
TONES_F2D(1358),
TONES_F2D(1446),
TONES_F2D(1540),
TONES_F2D(1640),
TONES_F2D(1747),
TONES_F2D(1860),
TONES_F2D(2400),
TONES_F2D(930),
TONES_F2D(2247),
TONES_F2D(991),
TONES_F2D(2110),
TONES_F2D(1055)
};
// 0123456789ABCD#*
const uint32_t dtmf_deltas[16][2] = {
{ DTMF_C1, DTMF_R3 },
{ DTMF_C0, DTMF_R0 },
{ DTMF_C1, DTMF_R0 },
{ DTMF_C2, DTMF_R0 },
{ DTMF_C0, DTMF_R1 },
{ DTMF_C1, DTMF_R1 },
{ DTMF_C2, DTMF_R1 },
{ DTMF_C0, DTMF_R2 },
{ DTMF_C1, DTMF_R2 },
{ DTMF_C2, DTMF_R2 },
{ DTMF_C3, DTMF_R0 },
{ DTMF_C3, DTMF_R1 },
{ DTMF_C3, DTMF_R2 },
{ DTMF_C3, DTMF_R3 },
{ DTMF_C2, DTMF_R3 },
{ DTMF_C0, DTMF_R3 }
};
const uint32_t eia_deltas[16] = {
TONES_F2D(600),
TONES_F2D(741),
TONES_F2D(882),
TONES_F2D(1023),
TONES_F2D(1164),
TONES_F2D(1305),
TONES_F2D(1446),
TONES_F2D(1587),
TONES_F2D(1728),
TONES_F2D(1869),
TONES_F2D(2151),
TONES_F2D(2433),
TONES_F2D(2010),
TONES_F2D(2292),
TONES_F2D(459),
TONES_F2D(1091)
};
const uint32_t zvei_deltas[16] = {
TONES_F2D(2400),
TONES_F2D(1060),
TONES_F2D(1160),
TONES_F2D(1270),
TONES_F2D(1400),
TONES_F2D(1530),
TONES_F2D(1670),
TONES_F2D(1830),
TONES_F2D(2000),
TONES_F2D(2200),
TONES_F2D(2800),
TONES_F2D(810),
TONES_F2D(970),
TONES_F2D(885),
TONES_F2D(2600),
TONES_F2D(680)
};
#endif/*__TONESETS_H__*/

View File

@ -79,6 +79,14 @@ void TransmitterModel::set_vga(int32_t v_db) {
update_vga();
}
uint32_t TransmitterModel::bandwidth() const {
return bandwidth_;
}
void TransmitterModel::set_bandwidth(uint32_t v) {
bandwidth_ = v;
}
uint32_t TransmitterModel::sampling_rate() const {
return sampling_rate_;
}
@ -88,6 +96,10 @@ void TransmitterModel::set_sampling_rate(uint32_t v) {
update_sampling_rate();
}
int32_t TransmitterModel::tx_gain() const {
return tx_gain_db_;
}
void TransmitterModel::set_tx_gain(int32_t v_db) {
tx_gain_db_ = v_db;
update_tx_gain();

View File

@ -52,6 +52,9 @@ public:
int32_t tx_gain() const;
void set_tx_gain(int32_t v_db);
uint32_t bandwidth() const;
void set_bandwidth(uint32_t v);
uint32_t sampling_rate() const;
void set_sampling_rate(uint32_t v);
@ -63,6 +66,7 @@ private:
bool enabled_ { false };
bool rf_amp_ { true };
int32_t lna_gain_db_ { 0 };
uint32_t bandwidth_ { 1 };
uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum };
int32_t vga_gain_db_ { 8 };
int32_t tx_gain_db_ { 47 };

View File

@ -63,7 +63,7 @@ void BHTView::start_tx() {
generate_message();
transmitter_model.set_tuning_frequency(bht_freqs[options_freq.selected_index()]);
//transmitter_model.set_tuning_frequency(bht_freqs[options_freq.selected_index()]);
transmitter_model.set_sampling_rate(1536000);
transmitter_model.set_rf_amp(true);
transmitter_model.set_lna(40);
@ -74,11 +74,11 @@ void BHTView::start_tx() {
// Setup for Xy
for (uint8_t c = 0; c < 16; c++) {
shared_memory.bb_data.tones_data.tone_defs[c].delta = ccir_deltas[c];
shared_memory.bb_data.tones_data.tone_defs[c].duration = CCIR_TONE_LENGTH;
shared_memory.bb_data.tones_data.tone_defs[c].duration = XY_TONE_LENGTH;
}
audio::set_rate(audio::Rate::Hz_24000);
baseband::set_tones_data(field_bw.value(), CCIR_SILENCE, 20, false, checkbox_speaker.value());
baseband::set_tones_data(transmitter_model.bandwidth(), XY_SILENCE, 20, false, checkbox_speaker.value());
}
void BHTView::on_tx_progress(const int progress, const bool done) {
@ -94,8 +94,7 @@ void BHTView::on_tx_progress(const int progress, const bool done) {
if (!checkbox_cligno.value()) {
tx_mode = IDLE;
button_transmit.set_style(&style_val);
button_transmit.set_text("START");
tx_view.set_transmitting(false);
} else {
chThdSleepMilliseconds(tempo_cligno.value() * 1000); // Dirty :(
@ -115,12 +114,11 @@ void BHTView::on_tx_progress(const int progress, const bool done) {
}
BHTView::BHTView(NavigationView& nav) {
(void)nav;
size_t n;
baseband::run_image(portapack::spi_flash::image_tag_tones);
//baseband::run_image(portapack::spi_flash::image_tag_encoders);
add_children({
&options_mode,
&text_header,
@ -138,16 +136,17 @@ BHTView::BHTView(NavigationView& nav) {
&text_receiver,
&receiver_code,
&checkbox_wcid,
&text_freq,
&options_freq,
&field_bw,
//&text_freq,
//&options_freq,
//&field_bw,
&text_relais,
&progressbar,
&text_message,
&button_transmit,
//&button_transmit,
&checkbox_cligno,
&tempo_cligno,
&text_cligno
&text_cligno,
&tx_view
});
options_mode.set_selected_index(0); // Start up in Xy mode
@ -159,12 +158,12 @@ BHTView::BHTView(NavigationView& nav) {
family_code_ep.set_selected_index(2);
subfamily_code.set_value(1);
receiver_code.set_value(1);
options_freq.set_selected_index(0);
//options_freq.set_selected_index(0);
tempo_cligno.set_value(1);
progressbar.set_max(20);
relay_states[0].set_selected_index(1); // R1 OFF
field_bw.set_value(10);
//field_bw.set_value(20);
options_mode.on_change = [this](size_t mode, OptionsField::value_t) {
_mode = mode;
@ -281,8 +280,8 @@ BHTView::BHTView(NavigationView& nav) {
for (auto& relay_state : relay_states) {
relay_state.on_change = relay_state_fn;
relay_state.set_parent_rect({
static_cast<Coord>(26 + (n * 53)),
174,
static_cast<Coord>(4 + (n * 36)),
158,
24, 24
});
relay_state.set_options(relay_options);
@ -290,22 +289,33 @@ BHTView::BHTView(NavigationView& nav) {
n++;
}
button_transmit.set_style(&style_val);
//button_transmit.set_style(&style_val);
generate_message();
button_transmit.on_select = [this, &nav](Button&) {
tx_view.on_edit_frequency = [this, &nav]() {
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
receiver_model.set_tuning_frequency(f);
};
};
tx_view.on_start = [this]() {
if ((tx_mode == IDLE) && (!_mode)) { // DEBUG
if (speaker_enabled)
chThdSleepMilliseconds(40 * 1000); // DEBUG 40s
//if (speaker_enabled && _mode)
// audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max);
tx_mode = SINGLE;
button_transmit.set_style(&style_cancel);
button_transmit.set_text("Wait");
tx_view.set_transmitting(true);
start_tx();
}
};
tx_view.on_stop = [this]() {
tx_view.set_transmitting(false);
tx_mode = IDLE;
};
}
} /* namespace ui */

View File

@ -23,6 +23,7 @@
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "ui_transmitter.hpp"
#include "ui_font_fixed_8x16.hpp"
#include "bmp_bulb_on.hpp"
@ -196,7 +197,7 @@ private:
"Tous"
};
Text text_freq {
/*Text text_freq {
{ 1 * 8, 8 * 16, 10 * 8, 16 },
"Frequence:"
};
@ -220,14 +221,14 @@ private:
{ 0, 99 },
1,
' '
};
};*/
Text text_relais {
{ 8, 19 * 8, 13 * 8, 16 },
"Etats relais:"
{ 1 * 8, 8 * 16 + 8, 7 * 8, 16 },
"Relais:"
};
std::array<ImageOptionsField, 4> relay_states;
std::array<ImageOptionsField, 4> relay_states { };
ImageOptionsField::options_t relay_options = {
{ &bulb_ignore_bmp[0], 0 },
@ -236,35 +237,41 @@ private:
};
ProgressBar progressbar {
{ 5 * 8, 27 * 8, 20 * 8, 16 },
{ 5 * 8, 13 * 16, 20 * 8, 16 },
};
Text text_message {
{ 5 * 8, 29 * 8, 20 * 8, 16 },
{ 5 * 8, 14 * 16, 20 * 8, 16 },
""
};
Button button_transmit {
/*Button button_transmit {
{ 2 * 8, 16 * 16, 12 * 8, 32 },
"START"
};
};*/
Checkbox checkbox_cligno {
{ 16 * 8, 16 * 16 + 4},
{ 18 * 8 + 4, 10 * 16},
3,
"J/N"
};
NumberField tempo_cligno {
{ 24 * 8, 16 * 16 + 8},
{ 25 * 8 + 4, 10 * 16 + 4},
2,
{ 1, 99 },
1,
' '
};
Text text_cligno {
{ 26 * 8, 16 * 16 + 8, 2 * 8, 16 },
{ 27 * 8 + 4, 10 * 16 + 4, 2 * 8, 16 },
"s."
};
TransmitterView tx_view {
16 * 16,
10000,
12
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
[this](const Message* const p) {

View File

@ -43,10 +43,13 @@ void FrequencySaveView::on_save_timestamp(NavigationView& nav) {
}
void FrequencySaveView::focus() {
if (error == ERROR_ACCESS)
if (error == ERROR_ACCESS) {
nav_.display_modal("Error", "File acces error", ABORT, nullptr);
else
} else {
if (error == ERROR_DUPLICATE)
nav_.display_modal("Error", "Frequency already saved", INFO, nullptr);
button_save_timestamp.focus();
}
}
void FrequencySaveView::on_tick_second() {
@ -68,6 +71,7 @@ FrequencySaveView::FrequencySaveView(
value_ (value)
{
File freqs_file;
size_t n;
if (!load_freqman_file(frequencies)) {
if (!create_freqman_file(freqs_file)) {
@ -76,6 +80,13 @@ FrequencySaveView::FrequencySaveView(
}
}
for (n = 0; n < frequencies.size(); n++) {
if (frequencies[n].value == value_) {
error = ERROR_DUPLICATE;
break;
}
}
signal_token_tick_second = rtc_time::signal_tick_second += [this]() {
this->on_tick_second();
};
@ -223,6 +234,7 @@ FreqManView::FreqManView(
add_children({
&menu_view,
&text_edit,
&button_edit_freq,
&button_edit_desc,
&button_del,

View File

@ -136,21 +136,25 @@ private:
MenuView menu_view { true };
Text text_edit {
{ 16, 194, 5 * 8, 16 },
"Edit:"
};
Button button_edit_freq {
{ 52, 194, 106, 30 },
"Edit freq."
{ 16, 194 + 16, 104, 32 },
"Frequency"
};
Button button_edit_desc {
{ 52, 192 + 32, 106, 30 },
"Edit desc."
{ 16, 194 + 16 + 34, 104, 32 },
"Description"
};
Button button_del {
{ 168, 192, 64, 64 },
"Del"
{ 160, 192, 72, 64 },
"Delete"
};
Button button_exit {
{ 168, 264, 64, 32 },
{ 160, 264, 72, 32 },
"Exit"
};
};

View File

@ -44,6 +44,8 @@ void MenuItemView::unhighlight() {
}
void MenuItemView::paint(Painter& painter) {
Coord offset_x;
const auto r = screen_rect();
const auto paint_style = (highlighted() && (parent()->has_focus() || keep_highlight_)) ? style().invert() : style();
@ -67,7 +69,9 @@ void MenuItemView::paint(Painter& painter) {
final_item_color,
final_bg_color
);
}
offset_x = 26;
} else
offset_x = 8;
Style text_style {
.font = paint_style.font,
@ -76,7 +80,7 @@ void MenuItemView::paint(Painter& painter) {
};
painter.draw_string(
{ r.location().x() + 26, r.location().y() + (r.size().height() - font_height) / 2 },
{ r.location().x() + offset_x, r.location().y() + (r.size().height() - font_height) / 2 },
text_style,
item.text
);

View File

@ -69,7 +69,7 @@ private:
class MenuView : public View {
public:
std::function<void(void)> on_left;
std::function<void(void)> on_left { };
MenuView(bool keep_highlight = false);
@ -102,9 +102,9 @@ private:
void update_items();
void on_tick_second();
bool keep_highlight_ = false;
bool keep_highlight_ { false };
SignalToken signal_token_tick_second;
SignalToken signal_token_tick_second { };
Image arrow_more {
{ 228, 320 - 8, 8, 8 },

View File

@ -71,7 +71,7 @@ private:
};
ImageButton button_back {
{ 0 * 8, 0 * 16, 16, 16 },
{ 2, 0 * 16, 16, 16 },
&bitmap_previous,
Color::white(),
Color::dark_grey()

View File

@ -37,7 +37,7 @@ using namespace portapack;
namespace ui {
void NuoptixView::focus() {
button_tx.focus();
number_timecode.focus();
}
NuoptixView::~NuoptixView() {
@ -45,10 +45,6 @@ NuoptixView::~NuoptixView() {
baseband::shutdown();
}
void NuoptixView::on_tuning_frequency_changed(rf::Frequency f) {
transmitter_model.set_tuning_frequency(f);
}
void NuoptixView::transmit(bool setup) {
uint8_t mod, tone_code;
uint8_t c;
@ -137,7 +133,7 @@ void NuoptixView::transmit(bool setup) {
shared_memory.bb_data.tones_data.silence = NUOPTIX_TONE_LENGTH; // 49ms tone, 49ms space
audio::set_rate(audio::Rate::Hz_24000);
baseband::set_tones_data(number_bw.value(), 0, 6 * 2, true, true);
baseband::set_tones_data(transmitter_model.bandwidth(), 0, 6 * 2, true, true);
timecode++;
}
@ -147,49 +143,37 @@ NuoptixView::NuoptixView(
)
{
baseband::run_image(portapack::spi_flash::image_tag_tones);
add_children({
&field_frequency,
&number_bw,
&text_kHz,
&tx_view,
&number_timecode,
&text_timecode,
&text_mod,
&pbar,
&button_tx,
&button_impro,
&button_exit
});
number_bw.set_value(15);
number_timecode.set_value(1);
field_frequency.set_value(transmitter_model.tuning_frequency());
field_frequency.set_step(10000);
field_frequency.on_change = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(transmitter_model.tuning_frequency());
tx_view.on_edit_frequency = [this, &nav]() {
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
this->field_frequency.set_value(f);
receiver_model.set_tuning_frequency(f);
};
};
button_tx.on_select = [this](Button&){
if (tx_mode == NORMAL) {
tx_mode = IDLE;
button_tx.set_text("TX");
} else if (tx_mode == IDLE) {
tx_mode = NORMAL;
button_tx.set_text("STOP");
transmit(true);
}
tx_view.on_start = [this]() {
tx_view.set_transmitting(true);
tx_mode = NORMAL;
transmit(true);
};
button_impro.on_select = [this](Button&){
tx_view.on_stop = [this]() {
tx_view.set_transmitting(false);
tx_mode = IDLE;
};
/*button_impro.on_select = [this](Button&){
if (tx_mode == IMPROVISE) {
tx_mode = IDLE;
button_impro.set_text("IMPROVISE");
@ -198,7 +182,7 @@ NuoptixView::NuoptixView(
button_impro.set_text("STOP");
transmit(true);
}
};
};*/
button_exit.on_select = [&nav](Button&){
nav.pop();

View File

@ -28,23 +28,14 @@
#include "ui_font_fixed_8x16.hpp"
#include "baseband_api.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "ui_transmitter.hpp"
#include "rtc_time.hpp"
#include "tonesets.hpp"
#include "message.hpp"
#include "volume.hpp"
#include "audio.hpp"
#define DTMF_DELTA_COEF (43.691) // (65536*1024)/1536000
#define DTMF_C0 (uint32_t)(1209 * DTMF_DELTA_COEF)
#define DTMF_C1 (uint32_t)(1336 * DTMF_DELTA_COEF)
#define DTMF_C2 (uint32_t)(1477 * DTMF_DELTA_COEF)
#define DTMF_C3 (uint32_t)(1633 * DTMF_DELTA_COEF)
#define DTMF_R0 (uint32_t)(697 * DTMF_DELTA_COEF)
#define DTMF_R1 (uint32_t)(770 * DTMF_DELTA_COEF)
#define DTMF_R2 (uint32_t)(852 * DTMF_DELTA_COEF)
#define DTMF_R3 (uint32_t)(941 * DTMF_DELTA_COEF)
#define NUOPTIX_TONE_LENGTH 75264 // 1536000*0.049s
#define NUOPTIX_TONE_LENGTH ((TONES_SAMPLERATE * 0.049) - 1) // 49ms
namespace ui {
@ -64,48 +55,17 @@ private:
IMPROVISE
};
tx_modes tx_mode = IDLE;
// 0123456789ABCD#*
const uint32_t dtmf_deltas[16][2] = {
{ DTMF_C1, DTMF_R3 },
{ DTMF_C0, DTMF_R0 },
{ DTMF_C1, DTMF_R0 },
{ DTMF_C2, DTMF_R0 },
{ DTMF_C0, DTMF_R1 },
{ DTMF_C1, DTMF_R1 },
{ DTMF_C2, DTMF_R1 },
{ DTMF_C0, DTMF_R2 },
{ DTMF_C1, DTMF_R2 },
{ DTMF_C2, DTMF_R2 },
{ DTMF_C3, DTMF_R0 },
{ DTMF_C3, DTMF_R1 },
{ DTMF_C3, DTMF_R2 },
{ DTMF_C3, DTMF_R3 },
{ DTMF_C2, DTMF_R3 },
{ DTMF_C0, DTMF_R3 }
};
tx_modes tx_mode { IDLE };
void on_tuning_frequency_changed(rf::Frequency f);
void transmit(bool setup);
uint32_t timecode { 0 };
FrequencyField field_frequency {
{ 1 * 8, 4 },
};
NumberField number_bw {
{ 13 * 8, 4 },
2,
{1, 99},
1,
' '
};
Text text_kHz {
{ 15 * 8, 4, 3 * 8, 16 },
"kHz"
TransmitterView tx_view {
11 * 16,
10000,
15
};
Text text_timecode {
@ -130,15 +90,10 @@ private:
{ 16, 236, 208, 16 }
};
Button button_tx {
{ 64, 128, 112, 40 },
"TX"
};
Button button_impro {
/*Button button_impro {
{ 64, 184, 112, 40 },
"IMPROVISE"
};
};*/
Button button_exit {
{ 88, 270, 64, 32 },

View File

@ -370,29 +370,4 @@ void VGAGainField::on_focus() {
}
}
/* TXGainField **********************************************************/
TXGainField::TXGainField(
Point parent_pos
) : NumberField {
parent_pos, 2,
{ max2837::tx::gain_db_range.minimum, max2837::tx::gain_db_range.maximum },
max2837::tx::gain_db_step,
' ',
}
{
set_value(receiver_model.tx_gain());
on_change = [](int32_t v) {
receiver_model.set_tx_gain(v);
};
}
void TXGainField::on_focus() {
//Widget::on_focus();
if( on_show_options ) {
on_show_options();
}
}
} /* namespace ui */

View File

@ -338,15 +338,6 @@ public:
void on_focus() override;
};
class TXGainField : public NumberField {
public:
std::function<void(void)> on_show_options { };
TXGainField(Point parent_pos);
void on_focus() override;
};
} /* namespace ui */
#endif/*__UI_RECEIVER_H__*/

View File

@ -0,0 +1,110 @@
/*
* 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_script.hpp"
#include "portapack.hpp"
#include "event_m0.hpp"
#include <cstring>
using namespace portapack;
namespace ui {
void ScriptView::on_frequency_select() {
//button_edit_freq.focus();
}
void ScriptView::on_edit_freq(rf::Frequency f) {
//frequencies[menu_view.highlighted()].value = f;
setup_list();
}
void ScriptView::on_edit_desc(NavigationView& nav) {
}
void ScriptView::on_delete() {
//frequencies.erase(frequencies.begin() + menu_view.highlighted());
setup_list();
}
void ScriptView::setup_list() {
size_t n;
menu_view.clear();
/*for (n = 0; n < frequencies.size(); n++) {
menu_view.add_item({ freqman_item_string(frequencies[n]), ui::Color::white(), nullptr, [this](){ on_frequency_select(); } });
}*/
menu_view.set_parent_rect({ 0, 0, 240, 168 });
menu_view.set_highlighted(menu_view.highlighted()); // Refresh
}
void ScriptView::focus() {
menu_view.focus();
}
ScriptView::ScriptView(
NavigationView& nav
) {
add_children({
&menu_view,
&text_edit,
&button_edit_freq,
&button_edit_desc,
&button_del,
&button_exit
});
setup_list();
button_edit_freq.on_select = [this, &nav](Button&) {
/*auto new_view = nav.push<FrequencyKeypadView>(frequencies[menu_view.highlighted()].value);
new_view->on_changed = [this](rf::Frequency f) {
on_edit_freq(f);
};*/
};
button_edit_desc.on_select = [this, &nav](Button&) {
on_edit_desc(nav);
};
button_del.on_select = [this, &nav](Button&) {
nav.push<ModalMessageView>("Confirm", "Are you sure ?", YESNO,
[this](bool choice) {
if (choice) {
on_delete();
}
}
);
};
button_exit.on_select = [this, &nav](Button&) {
nav.pop();
};
}
}

View File

@ -0,0 +1,91 @@
/*
* 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.hpp"
#include "ui_widget.hpp"
#include "ui_painter.hpp"
#include "ui_menu.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "ui_textentry.hpp"
#include "rtc_time.hpp"
namespace ui {
enum script_keyword {
STOP = 0,
WAIT_N,
WAIT_RTC,
IF,
LOOP,
END,
TX,
RX
};
struct script_line {
script_keyword keyword;
};
class ScriptView : public View {
public:
ScriptView(NavigationView& nav);
void focus() override;
std::string title() const override { return "Script editor"; };
private:
void on_frequency_select();
void on_edit_freq(rf::Frequency f);
void on_edit_desc(NavigationView& nav);
void on_delete();
void setup_list();
std::vector<script_line> script { };
MenuView menu_view { true };
Text text_edit {
{ 16, 194, 5 * 8, 16 },
"Edit:"
};
Button button_edit_freq {
{ 16, 194 + 16, 88, 32 },
"Frequency"
};
Button button_edit_desc {
{ 16, 194 + 16 + 34, 88, 32 },
"Description"
};
Button button_del {
{ 160, 192, 72, 64 },
"Delete"
};
Button button_exit {
{ 160, 264, 72, 32 },
"Exit"
};
};
} /* namespace ui */

View File

@ -0,0 +1,127 @@
/*
* Copyright (C) 2014 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_transmitter.hpp"
#include "portapack.hpp"
using namespace portapack;
#include "string_format.hpp"
#include "max2837.hpp"
namespace ui {
/* TXGainField **********************************************************/
TXGainField::TXGainField(
Point parent_pos
) : NumberField {
parent_pos, 2,
{ max2837::tx::gain_db_range.minimum, max2837::tx::gain_db_range.maximum },
max2837::tx::gain_db_step,
' ',
}
{
set_value(transmitter_model.tx_gain());
on_change = [](int32_t v) {
transmitter_model.set_tx_gain(v);
};
}
/* TransmitterView *******************************************************/
void TransmitterView::on_tuning_frequency_changed(rf::Frequency f) {
receiver_model.set_tuning_frequency(f);
}
void TransmitterView::on_bandwidth_changed(uint32_t bandwidth) {
transmitter_model.set_bandwidth(bandwidth);
}
void TransmitterView::set_transmitting(const bool transmitting) {
if (transmitting) {
button_start.set_text("STOP");
button_start.set_style(&style_stop);
} else {
button_start.set_text("START");
button_start.set_style(&style_start);
}
transmitting_ = transmitting;
}
void TransmitterView::on_show() {
field_frequency.set_value(receiver_model.tuning_frequency());
}
TransmitterView::TransmitterView(
const Coord y, const uint32_t frequency_step, const uint32_t bandwidth
) {
set_parent_rect({ 0 * 8, y, 30 * 8, 2 * 16 });
add_children({
&field_frequency,
&field_gain,
&field_bw,
&text_kHz,
&button_start
});
set_transmitting(false);
field_frequency.set_value(receiver_model.tuning_frequency());
field_frequency.set_step(frequency_step);
field_frequency.on_change = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
};
field_frequency.on_edit = [this]() {
if (on_edit_frequency)
on_edit_frequency();
};
field_bw.on_change = [this](int32_t bandwidth) {
transmitter_model.set_bandwidth(bandwidth);
};
field_bw.set_value(bandwidth);
button_start.on_select = [this](Button&){
if (transmitting_) {
if (on_stop)
on_stop();
} else {
if (on_start)
on_start();
}
};
}
TransmitterView::~TransmitterView() {
/*audio::output::stop();
transmitter_model.disable();
baseband::shutdown();*/
}
} /* namespace ui */

View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 2014 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_TRANSMITTER_H__
#define __UI_TRANSMITTER_H__
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "ui_painter.hpp"
#include "ui_widget.hpp"
#include "ui_receiver.hpp"
#include "ui_font_fixed_8x16.hpp"
#include "rf_path.hpp"
#include <cstddef>
#include <cstdint>
#include <algorithm>
#include <functional>
namespace ui {
class TXGainField : public NumberField {
public:
std::function<void(void)> on_show_options { };
TXGainField(Point parent_pos);
};
class TransmitterView : public View {
public:
std::function<void(void)> on_edit_frequency { };
std::function<void(void)> on_start { };
std::function<void(void)> on_stop { };
TransmitterView(const Coord y, const uint32_t frequency_step, const uint32_t bandwidth);
~TransmitterView();
void on_show() override;
void set_transmitting(const bool transmitting);
private:
const Style style_start {
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::green(),
};
const Style style_stop {
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::red(),
};
bool transmitting_ { false };
FrequencyField field_frequency {
{ 0 * 8, 0 * 16 }
};
TXGainField field_gain {
{ 11 * 8, 0 * 16 }
};
NumberField field_bw {
{ 14 * 8, 0 * 16 },
2,
{ 1, 99 },
1,
' '
};
Text text_kHz {
{ 16 * 8, 0 * 16, 3 * 8, 1 * 16 },
"kHz"
};
Button button_start {
{ 20 * 8, 0 * 16, 9 * 8, 32 },
"START"
};
void on_tuning_frequency_changed(rf::Frequency f);
void on_bandwidth_changed(uint32_t bandwidth);
};
} /* namespace ui */
#endif/*__UI_TRANSMITTER_H__*/

View File

@ -82,11 +82,11 @@ void TonesProcessor::execute(const buffer_c8_t& buffer) {
tone_sample = 0;
} else {
if (!dual_tone) {
tone_sample = (sine_table_i8[(tone_a_phase & 0x03FC0000U) >> 18]);
tone_sample = (sine_table_i8[(tone_a_phase & 0xFF000000U) >> 24]);
tone_a_phase += tone_a_delta;
} else {
tone_sample = sine_table_i8[(tone_a_phase & 0x03FC0000U) >> 18] >> 1;
tone_sample += sine_table_i8[(tone_b_phase & 0x03FC0000U) >> 18] >> 1;
tone_sample = sine_table_i8[(tone_a_phase & 0xFF000000U) >> 24] >> 1;
tone_sample += sine_table_i8[(tone_b_phase & 0xFF000000U) >> 24] >> 1;
tone_a_phase += tone_a_delta;
tone_b_phase += tone_b_delta;

Binary file not shown.