mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
Added tabs to BHT TX and Jammer
Updated firmware binary
This commit is contained in:
commit
e5fef6bb89
18
.travis.yml
18
.travis.yml
@ -13,12 +13,10 @@ notifications:
|
||||
# TODO: The "build_number.1" in this URL is almost certainly wrong, but correct value not available from Travis?
|
||||
- "Firmware download : https://portapack-h1-builds.s3.amazonaws.com/%{repository_slug}/%{build_number}/%{build_number}.1/build/firmware/portapack-h1-firmware-%{commit}.tar.bz2"
|
||||
|
||||
before_script:
|
||||
- wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 -O /tmp/gcc-arm.tar.bz2
|
||||
- tar -xf /tmp/gcc-arm.tar.bz2
|
||||
- export PATH=$PWD/gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH
|
||||
- export CC="arm-none-eabi-gcc"
|
||||
- export CXX="arm-none-eabi-g++"
|
||||
before_install:
|
||||
- sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa -y
|
||||
- sudo apt-get update -q
|
||||
- sudo apt-get install gcc-arm-embedded -y
|
||||
|
||||
script:
|
||||
# TODO: Introduce top-level Makefile, this is lame.
|
||||
@ -29,14 +27,6 @@ script:
|
||||
- popd
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- lib32bz2-1.0
|
||||
- lib32ncurses5
|
||||
- lib32z1
|
||||
- cmake
|
||||
sources:
|
||||
- kalakris-cmake
|
||||
artifacts:
|
||||
paths:
|
||||
- $(ls build/firmware/portapack-h1-havoc-*.tar.bz2 | tr "\n" ":")
|
||||
|
@ -34,7 +34,9 @@ namespace audio {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr i2s::ConfigTX i2s0_config_tx {
|
||||
// "Master": I2S peripheral generates SCK/WS, transmits to audio codec.
|
||||
|
||||
constexpr i2s::ConfigTX i2s0_config_tx_master_base_clk {
|
||||
.dao = i2s::DAO {
|
||||
.wordwidth = i2s::WordWidth::Bits16,
|
||||
.mono = 0,
|
||||
@ -56,9 +58,10 @@ constexpr i2s::ConfigTX i2s0_config_tx {
|
||||
.four_pin = 0,
|
||||
.mclk_out_en = 1,
|
||||
},
|
||||
.sck_in_sel = 1,
|
||||
};
|
||||
|
||||
constexpr i2s::ConfigRX i2s0_config_rx {
|
||||
constexpr i2s::ConfigRX i2s0_config_rx_four_wire {
|
||||
.dai = i2s::DAI {
|
||||
.wordwidth = i2s::WordWidth::Bits16,
|
||||
.mono = 0,
|
||||
@ -75,10 +78,38 @@ constexpr i2s::ConfigRX i2s0_config_rx {
|
||||
.bitrate = 7,
|
||||
},
|
||||
.rxmode = i2s::Mode {
|
||||
.clksel = i2s::ClockSelect::BaseAudioClkOrExternalMCLK,
|
||||
.clksel = i2s::ClockSelect::FractionalDivider,
|
||||
.four_pin = 1,
|
||||
.mclk_out_en = 0,
|
||||
},
|
||||
.sck_in_sel = 0,
|
||||
};
|
||||
|
||||
// "Slave": I2S controlled by external SCK/WS, received from audio codec.
|
||||
|
||||
constexpr i2s::ConfigTX i2s0_config_tx_slave_base_clk {
|
||||
.dao = i2s::DAO {
|
||||
.wordwidth = i2s::WordWidth::Bits16,
|
||||
.mono = 0,
|
||||
.stop = 1,
|
||||
.reset = 0,
|
||||
.ws_sel = 1,
|
||||
.ws_halfperiod = 0x0f,
|
||||
.mute = 1,
|
||||
},
|
||||
.txrate = i2s::MCLKRate {
|
||||
.x_divider = 0,
|
||||
.y_divider = 0,
|
||||
},
|
||||
.txbitrate = i2s::BitRate {
|
||||
.bitrate = 0,
|
||||
},
|
||||
.txmode = i2s::Mode {
|
||||
.clksel = i2s::ClockSelect::FractionalDivider,
|
||||
.four_pin = 0,
|
||||
.mclk_out_en = 1,
|
||||
},
|
||||
.sck_in_sel = 1,
|
||||
};
|
||||
|
||||
constexpr i2s::ConfigDMA i2s0_config_dma {
|
||||
@ -171,17 +202,18 @@ size_t reg_bits() {
|
||||
} /* namespace debug */
|
||||
|
||||
void init(audio::Codec* const codec) {
|
||||
audio_codec = codec;
|
||||
|
||||
clock_manager.start_audio_pll();
|
||||
audio_codec->init();
|
||||
|
||||
// Configure I2S before activating codec interface.
|
||||
i2s::i2s0::configure(
|
||||
i2s0_config_tx,
|
||||
i2s0_config_rx,
|
||||
i2s0_config_tx_master_base_clk,
|
||||
i2s0_config_rx_four_wire,
|
||||
i2s0_config_dma
|
||||
);
|
||||
|
||||
audio_codec = codec;
|
||||
audio_codec->init();
|
||||
|
||||
// Set pin mode, since it's likely GPIO (as left after CPLD JTAG interactions).
|
||||
portapack::pin_i2s0_rx_sda.mode(3);
|
||||
}
|
||||
|
@ -551,6 +551,28 @@ static constexpr Bitmap bitmap_more {
|
||||
{ 8, 8 }, bitmap_more_data
|
||||
};
|
||||
|
||||
static constexpr uint8_t bitmap_icon_transmit_data[] = {
|
||||
0xC0, 0x10,
|
||||
0x00, 0x21,
|
||||
0x1C, 0x22,
|
||||
0x63, 0x42,
|
||||
0x5D, 0x44,
|
||||
0xA2, 0x44,
|
||||
0xAA, 0x44,
|
||||
0xAA, 0x44,
|
||||
0x5D, 0x44,
|
||||
0x6B, 0x42,
|
||||
0x1C, 0x22,
|
||||
0x1C, 0x21,
|
||||
0xDD, 0x10,
|
||||
0x3E, 0x08,
|
||||
0x2A, 0x04,
|
||||
0x2A, 0x03,
|
||||
};
|
||||
static constexpr Bitmap bitmap_icon_transmit {
|
||||
{ 16, 16 }, bitmap_icon_transmit_data
|
||||
};
|
||||
|
||||
static constexpr uint8_t bitmap_icon_freqman_data[] = {
|
||||
0x00, 0x00,
|
||||
0x0E, 0x00,
|
||||
@ -1034,22 +1056,22 @@ static constexpr uint8_t bitmap_tab_edge_data[] = {
|
||||
0x03,
|
||||
0x07,
|
||||
0x07,
|
||||
0x07,
|
||||
0x0F,
|
||||
0x0F,
|
||||
0x0F,
|
||||
0x1F,
|
||||
0x1F,
|
||||
0x1F,
|
||||
0x1F,
|
||||
0x3F,
|
||||
0x3F,
|
||||
0x3F,
|
||||
0x7F,
|
||||
0x7F,
|
||||
0x7F,
|
||||
0xFF,
|
||||
0xFF,
|
||||
0x07,
|
||||
0x0F,
|
||||
0x0F,
|
||||
0x0F,
|
||||
0x1F,
|
||||
0x1F,
|
||||
0x1F,
|
||||
0x1F,
|
||||
0x3F,
|
||||
0x3F,
|
||||
0x3F,
|
||||
0x7F,
|
||||
0x7F,
|
||||
0x7F,
|
||||
0xFF,
|
||||
0xFF,
|
||||
};
|
||||
static constexpr Bitmap bitmap_tab_edge {
|
||||
{ 8, 24 }, bitmap_tab_edge_data
|
||||
|
@ -132,11 +132,7 @@ AboutView::AboutView(
|
||||
NavigationView& nav
|
||||
)
|
||||
{
|
||||
add_children({
|
||||
&text_cpld_hackrf,
|
||||
&text_cpld_hackrf_status,
|
||||
&button_ok,
|
||||
});
|
||||
add_child(&button_ok);
|
||||
|
||||
for (auto& text : text_line) {
|
||||
text.set("");
|
||||
@ -148,12 +144,6 @@ AboutView::AboutView(
|
||||
add_child(&text);
|
||||
}
|
||||
|
||||
if( hackrf::cpld::verify_eeprom() ) {
|
||||
text_cpld_hackrf_status.set(" OK");
|
||||
} else {
|
||||
text_cpld_hackrf_status.set("BAD");
|
||||
}
|
||||
|
||||
button_ok.on_select = [&nav](Button&){
|
||||
nav.pop();
|
||||
};
|
||||
|
@ -106,16 +106,6 @@ private:
|
||||
|
||||
std::array<Text, 10> text_line { };
|
||||
|
||||
Text text_cpld_hackrf {
|
||||
{ 0, 252, 11*8, 16 },
|
||||
"HackRF CPLD",
|
||||
};
|
||||
|
||||
Text text_cpld_hackrf_status {
|
||||
{ 240 - 3*8, 252, 3*8, 16 },
|
||||
"???"
|
||||
};
|
||||
|
||||
Button button_ok {
|
||||
{ 72, 272, 96, 24 },
|
||||
"OK"
|
||||
|
@ -33,7 +33,7 @@ using namespace portapack;
|
||||
namespace ui {
|
||||
|
||||
void BHTView::focus() {
|
||||
relay_states[0].focus();
|
||||
tx_view.focus();
|
||||
}
|
||||
|
||||
BHTView::~BHTView() {
|
||||
@ -41,34 +41,15 @@ BHTView::~BHTView() {
|
||||
baseband::shutdown();
|
||||
}
|
||||
|
||||
void BHTView::generate_message() {
|
||||
if (tx_mode == SINGLE) {
|
||||
text_message.set(
|
||||
gen_message_xy(header_code_a.value(), header_code_b.value(), city_code_xy.value(), family_code_xy.value(),
|
||||
checkbox_wcsubfamily.value(), subfamily_code.value(), checkbox_wcid.value(), receiver_code.value(),
|
||||
relay_states[0].selected_index(), relay_states[1].selected_index(),
|
||||
relay_states[2].selected_index(), relay_states[3].selected_index())
|
||||
);
|
||||
/*} else {
|
||||
text_message.set(
|
||||
gen_message_ep(city_code_ep.value(), family_code_ep.selected_index_value(),
|
||||
relay_states[0].selected_index(), relay_states[1].selected_index())
|
||||
);*/
|
||||
} else if (tx_mode == SEQUENCE) {
|
||||
text_message.set(
|
||||
gen_message_xy(sequence_matin[seq_index].code)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void BHTView::start_tx() {
|
||||
uint8_t c;
|
||||
|
||||
generate_message();
|
||||
view_xylos.generate_message();
|
||||
view_EPAR.generate_message();
|
||||
|
||||
if (tx_mode == SINGLE)
|
||||
if (view_xylos.tx_mode == XylosView::tx_modes::SINGLE)
|
||||
progressbar.set_max(20);
|
||||
else if (tx_mode == SEQUENCE)
|
||||
else if (view_xylos.tx_mode == XylosView::tx_modes::SEQUENCE)
|
||||
progressbar.set_max(20 * XY_SEQ_COUNT);
|
||||
|
||||
transmitter_model.set_sampling_rate(1536000);
|
||||
@ -85,155 +66,166 @@ void BHTView::start_tx() {
|
||||
|
||||
void BHTView::on_tx_progress(const int progress, const bool done) {
|
||||
uint8_t c;
|
||||
uint8_t rs;
|
||||
|
||||
if (tx_mode == SINGLE) {
|
||||
if (view_xylos.tx_mode == XylosView::tx_modes::SINGLE) {
|
||||
if (done) {
|
||||
transmitter_model.disable();
|
||||
progressbar.set_value(0);
|
||||
|
||||
if (!checkbox_cligno.value()) {
|
||||
tx_mode = IDLE;
|
||||
view_xylos.tx_mode = XylosView::tx_modes::IDLE;
|
||||
tx_view.set_transmitting(false);
|
||||
} else {
|
||||
chThdSleepMilliseconds(tempo_cligno.value() * 1000); // Dirty :(
|
||||
chThdSleepMilliseconds(field_tempo.value() * 1000); // Dirty :(
|
||||
|
||||
// Invert first relay's state
|
||||
rs = relay_states[0].selected_index();
|
||||
if (rs > 0) relay_states[0].set_selected_index(rs ^ 3);
|
||||
view_EPAR.flip_relays();
|
||||
view_xylos.flip_relays();
|
||||
|
||||
start_tx();
|
||||
}
|
||||
} else {
|
||||
progressbar.set_value(progress);
|
||||
}
|
||||
} else if (tx_mode == SEQUENCE) {
|
||||
} else if (view_xylos.tx_mode == XylosView::tx_modes::SEQUENCE) {
|
||||
if (done) {
|
||||
transmitter_model.disable();
|
||||
|
||||
if (seq_index < (XY_SEQ_COUNT - 1)) {
|
||||
for (c = 0; c < sequence_matin[seq_index].delay; c++)
|
||||
if (view_xylos.seq_index < (XY_SEQ_COUNT - 1)) {
|
||||
for (c = 0; c < view_xylos.sequence_matin[view_xylos.seq_index].delay; c++)
|
||||
chThdSleepMilliseconds(1000);
|
||||
|
||||
seq_index++;
|
||||
view_xylos.seq_index++;
|
||||
|
||||
start_tx();
|
||||
} else {
|
||||
progressbar.set_value(0);
|
||||
tx_mode = IDLE;
|
||||
view_xylos.tx_mode = XylosView::tx_modes::IDLE;
|
||||
tx_view.set_transmitting(false);
|
||||
}
|
||||
} else {
|
||||
progressbar.set_value((seq_index * 20) + progress);
|
||||
progressbar.set_value((view_xylos.seq_index * 20) + progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BHTView::BHTView(NavigationView& nav) {
|
||||
void EPARView::flip_relays() {
|
||||
// Invert first relay's state
|
||||
relay_states[0].set_selected_index(relay_states[0].selected_index() ^ 1);
|
||||
}
|
||||
|
||||
void EPARView::generate_message() {
|
||||
//text_message.set(
|
||||
gen_message_ep(field_city.value(), field_group.selected_index_value(),
|
||||
relay_states[0].selected_index(), relay_states[1].selected_index());
|
||||
//);
|
||||
}
|
||||
|
||||
EPARView::EPARView() {
|
||||
size_t n;
|
||||
|
||||
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
||||
//baseband::run_image(portapack::spi_flash::image_tag_encoders);
|
||||
hidden(true);
|
||||
|
||||
//baseband::run_image(portapack::spi_flash::image_tag_ook);
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
&options_mode,
|
||||
&header_code_a,
|
||||
&header_code_b,
|
||||
&city_code_xy,
|
||||
&family_code_xy,
|
||||
&subfamily_code,
|
||||
&checkbox_wcsubfamily,
|
||||
&receiver_code,
|
||||
&checkbox_wcid,
|
||||
&progressbar,
|
||||
&text_message,
|
||||
&checkbox_cligno,
|
||||
&tempo_cligno,
|
||||
&button_seq,
|
||||
&tx_view
|
||||
&field_city,
|
||||
&field_group,
|
||||
&button_scan
|
||||
});
|
||||
|
||||
field_city.set_value(220);
|
||||
field_group.set_selected_index(2);
|
||||
|
||||
options_mode.set_selected_index(0); // Start up in Xy mode
|
||||
header_code_a.set_value(0);
|
||||
header_code_b.set_value(0);
|
||||
city_code_xy.set_value(10);
|
||||
//city_code_ep.set_value(220);
|
||||
family_code_xy.set_value(1);
|
||||
//family_code_ep.set_selected_index(2);
|
||||
subfamily_code.set_value(1);
|
||||
receiver_code.set_value(1);
|
||||
tempo_cligno.set_value(0);
|
||||
field_city.on_change = [this](int32_t) { generate_message(); };
|
||||
field_group.on_change = [this](size_t, int32_t) { generate_message(); };
|
||||
|
||||
/* options_mode.on_change = [this](size_t mode, OptionsField::value_t) {
|
||||
_mode = mode;
|
||||
|
||||
if (_mode) {
|
||||
// EP layout
|
||||
remove_children({
|
||||
&header_code_a,
|
||||
&header_code_b,
|
||||
&checkbox_speaker,
|
||||
&bmp_speaker,
|
||||
&city_code_xy,
|
||||
&family_code_xy,
|
||||
&subfamily_code,
|
||||
&checkbox_wcsubfamily,
|
||||
&receiver_code,
|
||||
&checkbox_wcid,
|
||||
&relay_states[2],
|
||||
&relay_states[3]
|
||||
});
|
||||
add_children({
|
||||
&city_code_ep,
|
||||
&family_code_ep
|
||||
});
|
||||
set_dirty();
|
||||
} else {
|
||||
// Xy layout
|
||||
remove_children({
|
||||
&city_code_ep,
|
||||
&family_code_ep
|
||||
});
|
||||
add_children({
|
||||
&header_code_a,
|
||||
&header_code_b,
|
||||
&checkbox_speaker,
|
||||
&bmp_speaker,
|
||||
&city_code_xy,
|
||||
&family_code_xy,
|
||||
&subfamily_code,
|
||||
&checkbox_wcsubfamily,
|
||||
&receiver_code,
|
||||
&checkbox_wcid,
|
||||
&relay_states[2],
|
||||
&relay_states[3]
|
||||
});
|
||||
set_dirty();
|
||||
};
|
||||
generate_message();
|
||||
};*/
|
||||
const auto relay_state_fn = [this](size_t, OptionsField::value_t) {
|
||||
this->generate_message();
|
||||
};
|
||||
|
||||
header_code_a.on_change = [this](int32_t) { generate_message(); };
|
||||
header_code_b.on_change = [this](int32_t) { generate_message(); };
|
||||
city_code_xy.on_change = [this](int32_t) { generate_message(); };
|
||||
family_code_xy.on_change = [this](int32_t) { generate_message(); };
|
||||
subfamily_code.on_change = [this](int32_t) { generate_message(); };
|
||||
receiver_code.on_change = [this](int32_t) { generate_message(); };
|
||||
n = 0;
|
||||
for (auto& relay_state : relay_states) {
|
||||
relay_state.on_change = relay_state_fn;
|
||||
relay_state.set_parent_rect({
|
||||
static_cast<Coord>(90 + (n * 36)),
|
||||
80,
|
||||
24, 24
|
||||
});
|
||||
relay_state.set_options(relay_options);
|
||||
add_child(&relay_state);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
void EPARView::focus() {
|
||||
field_city.focus();
|
||||
}
|
||||
|
||||
void XylosView::flip_relays() {
|
||||
size_t rs;
|
||||
|
||||
// Invert first relay's state
|
||||
rs = relay_states[0].selected_index();
|
||||
if (rs > 0) relay_states[0].set_selected_index(rs ^ 3);
|
||||
}
|
||||
|
||||
void XylosView::generate_message() {
|
||||
if (tx_mode == SINGLE) {
|
||||
//text_message.set(
|
||||
gen_message_xy(field_header_a.value(), field_header_b.value(), field_city.value(), field_family.value(),
|
||||
checkbox_wcsubfamily.value(), field_subfamily.value(), checkbox_wcid.value(), field_receiver.value(),
|
||||
relay_states[0].selected_index(), relay_states[1].selected_index(),
|
||||
relay_states[2].selected_index(), relay_states[3].selected_index());
|
||||
//);
|
||||
} else if (tx_mode == SEQUENCE) {
|
||||
//text_message.set(
|
||||
gen_message_xy(sequence_matin[seq_index].code);
|
||||
//);
|
||||
}
|
||||
}
|
||||
|
||||
XylosView::XylosView() {
|
||||
size_t n;
|
||||
|
||||
hidden(true);
|
||||
|
||||
//baseband::run_image(portapack::spi_flash::image_tag_tones);
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
&field_header_a,
|
||||
&field_header_b,
|
||||
&field_city,
|
||||
&field_family,
|
||||
&field_subfamily,
|
||||
&checkbox_wcsubfamily,
|
||||
&field_receiver,
|
||||
&checkbox_wcid,
|
||||
&button_seq,
|
||||
});
|
||||
|
||||
field_header_a.set_value(0);
|
||||
field_header_b.set_value(0);
|
||||
field_city.set_value(10);
|
||||
field_family.set_value(1);
|
||||
field_subfamily.set_value(1);
|
||||
field_receiver.set_value(1);
|
||||
|
||||
field_header_a.on_change = [this](int32_t) { generate_message(); };
|
||||
field_header_b.on_change = [this](int32_t) { generate_message(); };
|
||||
field_city.on_change = [this](int32_t) { generate_message(); };
|
||||
field_family.on_change = [this](int32_t) { generate_message(); };
|
||||
field_subfamily.on_change = [this](int32_t) { generate_message(); };
|
||||
field_receiver.on_change = [this](int32_t) { generate_message(); };
|
||||
|
||||
checkbox_wcsubfamily.on_select = [this](Checkbox&, bool v) {
|
||||
if (v)
|
||||
subfamily_code.set_focusable(false);
|
||||
else
|
||||
subfamily_code.set_focusable(true);
|
||||
field_subfamily.set_focusable(!v);
|
||||
generate_message();
|
||||
};
|
||||
|
||||
checkbox_wcid.on_select = [this](Checkbox&, bool v) {
|
||||
if (v)
|
||||
receiver_code.set_focusable(false);
|
||||
else
|
||||
receiver_code.set_focusable(true);
|
||||
field_receiver.set_focusable(!v);
|
||||
generate_message();
|
||||
};
|
||||
|
||||
@ -248,16 +240,41 @@ 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>(4 + (n * 36)),
|
||||
150,
|
||||
static_cast<Coord>(54 + (n * 36)),
|
||||
134,
|
||||
24, 24
|
||||
});
|
||||
relay_state.set_options(relay_options);
|
||||
add_child(&relay_state);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
void XylosView::focus() {
|
||||
field_city.focus();
|
||||
}
|
||||
|
||||
BHTView::BHTView(NavigationView& nav) {
|
||||
Rect view_rect = { 0, 3 * 8, 240, 192 };
|
||||
|
||||
generate_message();
|
||||
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
||||
|
||||
add_children({
|
||||
&tab_view,
|
||||
&labels,
|
||||
&view_xylos,
|
||||
&view_EPAR,
|
||||
&checkbox_cligno,
|
||||
&field_tempo,
|
||||
&progressbar,
|
||||
&text_message,
|
||||
&tx_view
|
||||
});
|
||||
|
||||
view_xylos.set_parent_rect(view_rect);
|
||||
view_EPAR.set_parent_rect(view_rect);
|
||||
|
||||
field_tempo.set_value(0);
|
||||
|
||||
tx_view.on_edit_frequency = [this, &nav]() {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
|
||||
@ -266,18 +283,18 @@ BHTView::BHTView(NavigationView& nav) {
|
||||
};
|
||||
};
|
||||
|
||||
button_seq.on_select = [this, &nav](Button&) {
|
||||
/*button_seq.on_select = [this, &nav](Button&) {
|
||||
if (tx_mode == IDLE) {
|
||||
seq_index = 0;
|
||||
tx_mode = SEQUENCE;
|
||||
tx_view.set_transmitting(true);
|
||||
start_tx();
|
||||
}
|
||||
};
|
||||
};*/
|
||||
|
||||
tx_view.on_start = [this]() {
|
||||
if (tx_mode == IDLE) {
|
||||
tx_mode = SINGLE;
|
||||
if (view_xylos.tx_mode == XylosView::tx_modes::IDLE) {
|
||||
view_xylos.tx_mode = XylosView::tx_modes::SINGLE;
|
||||
tx_view.set_transmitting(true);
|
||||
start_tx();
|
||||
}
|
||||
@ -286,7 +303,7 @@ BHTView::BHTView(NavigationView& nav) {
|
||||
tx_view.on_stop = [this]() {
|
||||
transmitter_model.disable();
|
||||
tx_view.set_transmitting(false);
|
||||
tx_mode = IDLE;
|
||||
view_xylos.tx_mode = XylosView::tx_modes::IDLE;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "ui.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_tabview.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_transmitter.hpp"
|
||||
#include "ui_font_fixed_8x16.hpp"
|
||||
@ -37,23 +38,30 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
class BHTView : public View {
|
||||
class XylosView : public View {
|
||||
public:
|
||||
BHTView(NavigationView& nav);
|
||||
~BHTView();
|
||||
|
||||
XylosView();
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "BHT transmit"; };
|
||||
|
||||
private:
|
||||
void flip_relays();
|
||||
void generate_message();
|
||||
|
||||
enum tx_modes {
|
||||
IDLE = 0,
|
||||
SINGLE,
|
||||
SEQUENCE
|
||||
};
|
||||
|
||||
tx_modes tx_mode = IDLE;
|
||||
|
||||
uint32_t seq_index { 0 };
|
||||
|
||||
struct sequence_t {
|
||||
const std::string code;
|
||||
const uint32_t delay;
|
||||
};
|
||||
|
||||
|
||||
const sequence_t sequence_matin[XY_SEQ_COUNT] = {
|
||||
{ "0000189000B1002B0000", 19 }, // 18:9:0:00 R1=OFF (1)
|
||||
{ "0000189200B2110B0000", 16 }, // 18:9:2:00 R1=ON (4)
|
||||
@ -70,124 +78,71 @@ private:
|
||||
{ "0000181AAAB1000B0000", 17 }, // 18:1:A:AA
|
||||
{ "0000189400B0100B0000", 17 } // 18:9:4:00 R2=OFF (8)
|
||||
};
|
||||
|
||||
enum tx_modes {
|
||||
IDLE = 0,
|
||||
SINGLE,
|
||||
SEQUENCE
|
||||
};
|
||||
|
||||
tx_modes tx_mode = IDLE;
|
||||
|
||||
void generate_message();
|
||||
void on_tx_progress(const int progress, const bool done);
|
||||
void start_tx();
|
||||
|
||||
const Style style_val {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
.foreground = Color::green(),
|
||||
};
|
||||
const Style style_cancel {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
.foreground = Color::red(),
|
||||
};
|
||||
const Style style_grey {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
.foreground = Color::grey(),
|
||||
};
|
||||
|
||||
private:
|
||||
Labels labels {
|
||||
{ { 8 * 8, 3 * 8 }, "Header:", Color::light_grey() },
|
||||
{ { 4 * 8, 5 * 8 }, "Code ville:", Color::light_grey() },
|
||||
{ { 7 * 8, 7 * 8 }, "Famille:", Color::light_grey() },
|
||||
{ { 2 * 8, 9 * 8 + 2 }, "Sous-famille:", Color::light_grey() },
|
||||
{ { 2 * 8, 13 * 8 }, "ID recepteur:", Color::light_grey() },
|
||||
{ { 1 * 8, 16 * 8 }, "Relais:", Color::light_grey() },
|
||||
{ { 27 * 8 + 4, 19 * 8 + 4 }, "s.", Color::light_grey() }
|
||||
{ { 8 * 8, 1 * 8 }, "Header:", Color::light_grey() },
|
||||
{ { 4 * 8, 3 * 8 }, "Code ville:", Color::light_grey() },
|
||||
{ { 7 * 8, 5 * 8 }, "Famille:", Color::light_grey() },
|
||||
{ { 2 * 8, 7 * 8 + 2 }, "Sous-famille:", Color::light_grey() },
|
||||
{ { 2 * 8, 11 * 8 }, "ID recepteur:", Color::light_grey() },
|
||||
{ { 2 * 8, 14 * 8 }, "Relais:", Color::light_grey() }
|
||||
};
|
||||
|
||||
OptionsField options_mode {
|
||||
{ 10 * 8, 4 },
|
||||
10,
|
||||
{
|
||||
{ "Mode Xy.", 0 },
|
||||
{ "Mode EP.", 1 }
|
||||
}
|
||||
NumberField field_header_a {
|
||||
{ 16 * 8, 1 * 8 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
'0'
|
||||
};
|
||||
NumberField field_header_b {
|
||||
{ 18 * 8, 1 * 8 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
'0'
|
||||
};
|
||||
|
||||
NumberField header_code_a {
|
||||
NumberField field_city {
|
||||
{ 16 * 8, 3 * 8 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
'0'
|
||||
};
|
||||
NumberField header_code_b {
|
||||
{ 18 * 8, 3 * 8 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
'0'
|
||||
};
|
||||
|
||||
NumberField city_code_xy {
|
||||
{ 16 * 8, 5 * 8 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
/*NumberField city_code_ep {
|
||||
{ 16 * 8, 5 * 8 },
|
||||
3,
|
||||
{ 0, 255 },
|
||||
1,
|
||||
' '
|
||||
};*/
|
||||
|
||||
NumberField family_code_xy {
|
||||
{ 16 * 8, 7 * 8 },
|
||||
NumberField field_family {
|
||||
{ 16 * 8, 5 * 8 },
|
||||
1,
|
||||
{ 0, 9 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
/*OptionsField family_code_ep {
|
||||
{ 16 * 8, 7 * 8 },
|
||||
2,
|
||||
{
|
||||
{ "A ", 2 }, // See receiver PCB
|
||||
{ "B ", 1 },
|
||||
{ "C ", 0 },
|
||||
{ "TP", 3 }
|
||||
}
|
||||
};*/
|
||||
|
||||
NumberField subfamily_code {
|
||||
{ 16 * 8, 9 * 8 + 2 },
|
||||
|
||||
NumberField field_subfamily {
|
||||
{ 16 * 8, 7 * 8 + 2 },
|
||||
1,
|
||||
{ 0, 9 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
||||
Checkbox checkbox_wcsubfamily {
|
||||
{ 20 * 8, 8 * 8 + 6 },
|
||||
{ 20 * 8, 6 * 8 + 6 },
|
||||
6,
|
||||
"Toutes"
|
||||
};
|
||||
|
||||
NumberField receiver_code {
|
||||
{ 16 * 8, 13 * 8 },
|
||||
NumberField field_receiver {
|
||||
{ 16 * 8, 11 * 8 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
'0'
|
||||
};
|
||||
Checkbox checkbox_wcid {
|
||||
{ 20 * 8, 12 * 8 + 4 },
|
||||
{ 20 * 8, 10 * 8 + 4 },
|
||||
4,
|
||||
"Tous"
|
||||
};
|
||||
@ -200,30 +155,104 @@ private:
|
||||
{ &bitmap_bulb_on, 2 }
|
||||
};
|
||||
|
||||
ProgressBar progressbar {
|
||||
{ 3 * 8, 12 * 16, 20 * 8, 16 },
|
||||
Button button_seq {
|
||||
{ 24 * 8, 1 * 8, 40, 32 },
|
||||
"Seq"
|
||||
};
|
||||
Text text_message {
|
||||
{ 3 * 8, 13 * 16, 20 * 8, 16 },
|
||||
""
|
||||
};
|
||||
|
||||
class EPARView : public View {
|
||||
public:
|
||||
EPARView();
|
||||
|
||||
void focus() override;
|
||||
|
||||
void flip_relays();
|
||||
void generate_message();
|
||||
|
||||
private:
|
||||
Labels labels {
|
||||
{ { 4 * 8, 1 * 8 }, "Code ville:", Color::light_grey() },
|
||||
{ { 8 * 8, 3 * 8 }, "Groupe:", Color::light_grey() },
|
||||
{ { 8 * 8, 7 * 8 }, "Relais:", Color::light_grey() }
|
||||
};
|
||||
|
||||
Checkbox checkbox_cligno {
|
||||
{ 18 * 8 + 4, 19 * 8 },
|
||||
NumberField field_city {
|
||||
{ 16 * 8, 1 * 8 },
|
||||
3,
|
||||
"Alt"
|
||||
};
|
||||
NumberField tempo_cligno {
|
||||
{ 25 * 8 + 4, 19 * 8 + 4 },
|
||||
2,
|
||||
{ 1, 99 },
|
||||
{ 0, 255 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
||||
Button button_seq {
|
||||
{ 24 * 8, 13 * 16, 40, 32 },
|
||||
"Seq"
|
||||
OptionsField field_group {
|
||||
{ 16 * 8, 3 * 8 },
|
||||
2,
|
||||
{
|
||||
{ "A ", 2 }, // See receiver PCB
|
||||
{ "B ", 1 },
|
||||
{ "C ", 0 },
|
||||
{ "TP", 3 }
|
||||
}
|
||||
};
|
||||
|
||||
std::array<ImageOptionsField, 2> relay_states { };
|
||||
|
||||
ImageOptionsField::options_t relay_options = {
|
||||
{ &bitmap_bulb_off, 0 },
|
||||
{ &bitmap_bulb_on, 1 }
|
||||
};
|
||||
|
||||
Button button_scan {
|
||||
{ 22 * 8, 1 * 8, 56, 32 },
|
||||
"Scan"
|
||||
};
|
||||
};
|
||||
|
||||
class BHTView : public View {
|
||||
public:
|
||||
BHTView(NavigationView& nav);
|
||||
~BHTView();
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "BHT transmit"; };
|
||||
|
||||
private:
|
||||
void on_tx_progress(const int progress, const bool done);
|
||||
void start_tx();
|
||||
|
||||
XylosView view_xylos { };
|
||||
EPARView view_EPAR { };
|
||||
|
||||
TabView tab_view {
|
||||
{ "Xylos", Color::cyan(), &view_xylos },
|
||||
{ "EPAR", Color::green(), &view_EPAR }
|
||||
};
|
||||
|
||||
Labels labels {
|
||||
{ { 29 * 8, 14 * 16 + 4 }, "s", Color::light_grey() }
|
||||
};
|
||||
|
||||
ProgressBar progressbar {
|
||||
{ 1 * 8, 14 * 16, 20 * 8, 16 },
|
||||
};
|
||||
Text text_message {
|
||||
{ 1 * 8, 15 * 16, 20 * 8, 16 },
|
||||
""
|
||||
};
|
||||
|
||||
Checkbox checkbox_cligno {
|
||||
{ 22 * 8, 14 * 16 },
|
||||
1,
|
||||
"~"
|
||||
};
|
||||
NumberField field_tempo {
|
||||
{ 27 * 8, 14 * 16 + 4 },
|
||||
2,
|
||||
{ 1, 99 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
|
||||
TransmitterView tx_view {
|
||||
|
@ -173,9 +173,9 @@ void RegistersWidget::paint(Painter& painter) {
|
||||
void RegistersWidget::draw_legend(const Coord left, Painter& painter) {
|
||||
const auto pos = screen_pos();
|
||||
|
||||
for(int i=0; i<config.registers_count; i+=config.registers_per_row()) {
|
||||
for(size_t i=0; i<config.registers_count; i+=config.registers_per_row()) {
|
||||
const Point offset {
|
||||
left, (i / config.registers_per_row()) * row_height
|
||||
left, static_cast<int>((i / config.registers_per_row()) * row_height)
|
||||
};
|
||||
|
||||
const auto text = to_string_hex(i, config.legend_length());
|
||||
@ -193,10 +193,10 @@ void RegistersWidget::draw_values(
|
||||
) {
|
||||
const auto pos = screen_pos();
|
||||
|
||||
for(int i=0; i<config.registers_count; i++) {
|
||||
for(size_t i=0; i<config.registers_count; i++) {
|
||||
const Point offset = {
|
||||
left + config.legend_width() + 8 + (i % config.registers_per_row()) * (config.value_width() + 8),
|
||||
(i / config.registers_per_row()) * row_height
|
||||
static_cast<int>(left + config.legend_width() + 8 + (i % config.registers_per_row()) * (config.value_width() + 8)),
|
||||
static_cast<int>((i / config.registers_per_row()) * row_height)
|
||||
};
|
||||
|
||||
const auto value = reader(i);
|
||||
|
@ -130,42 +130,42 @@ private:
|
||||
};
|
||||
|
||||
struct RegistersWidgetConfig {
|
||||
int registers_count;
|
||||
int register_bits;
|
||||
size_t registers_count;
|
||||
size_t register_bits;
|
||||
|
||||
constexpr int legend_length() const {
|
||||
constexpr size_t legend_length() const {
|
||||
return (registers_count >= 0x10) ? 2 : 1;
|
||||
}
|
||||
|
||||
constexpr int legend_width() const {
|
||||
constexpr size_t legend_width() const {
|
||||
return legend_length() * 8;
|
||||
}
|
||||
|
||||
constexpr int value_length() const {
|
||||
constexpr size_t value_length() const {
|
||||
return (register_bits + 3) / 4;
|
||||
}
|
||||
|
||||
constexpr int value_width() const {
|
||||
constexpr size_t value_width() const {
|
||||
return value_length() * 8;
|
||||
}
|
||||
|
||||
constexpr int registers_per_row() const {
|
||||
constexpr size_t registers_per_row() const {
|
||||
return (value_length() >= 3) ? 4 : 8;
|
||||
}
|
||||
|
||||
constexpr int registers_row_length() const {
|
||||
constexpr size_t registers_row_length() const {
|
||||
return (registers_per_row() * (value_length() + 1)) - 1;
|
||||
}
|
||||
|
||||
constexpr int registers_row_width() const {
|
||||
constexpr size_t registers_row_width() const {
|
||||
return registers_row_length() * 8;
|
||||
}
|
||||
|
||||
constexpr int row_width() const {
|
||||
constexpr size_t row_width() const {
|
||||
return legend_width() + 8 + registers_row_width();
|
||||
}
|
||||
|
||||
constexpr int rows() const {
|
||||
constexpr size_t rows() const {
|
||||
return registers_count / registers_per_row();
|
||||
}
|
||||
};
|
||||
@ -185,7 +185,7 @@ private:
|
||||
const RegistersWidgetConfig config;
|
||||
const std::function<uint32_t(const size_t register_number)> reader;
|
||||
|
||||
static constexpr int row_height = 16;
|
||||
static constexpr size_t row_height = 16;
|
||||
|
||||
void draw_legend(const Coord left, Painter& painter);
|
||||
void draw_values(const Coord left, Painter& painter);
|
||||
|
@ -33,28 +33,95 @@
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace portapack;
|
||||
using namespace jammer;
|
||||
|
||||
namespace ui {
|
||||
|
||||
void JammerView::focus() {
|
||||
options_preset.focus();
|
||||
void RangeView::focus() {
|
||||
check_enabled.focus();
|
||||
}
|
||||
|
||||
extern constexpr jammer_range_t RangeView::range_presets[];
|
||||
extern constexpr Style RangeView::style_info;
|
||||
|
||||
RangeView::RangeView(NavigationView& nav) {
|
||||
hidden(true);
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
&check_enabled,
|
||||
&options_preset,
|
||||
&button_min,
|
||||
&button_max,
|
||||
&text_info
|
||||
});
|
||||
|
||||
check_enabled.set_value(false);
|
||||
|
||||
check_enabled.on_select = [this](Checkbox&, bool v) {
|
||||
frequency_range.enabled = v;
|
||||
};
|
||||
|
||||
button_min.on_select = [this, &nav](Button& button) {
|
||||
rf::Frequency * value_ptr;
|
||||
|
||||
value_ptr = &frequency_range.min;
|
||||
|
||||
auto new_view = nav.push<FrequencyKeypadView>(*value_ptr);
|
||||
new_view->on_changed = [this, value_ptr, &button](rf::Frequency f) {
|
||||
*value_ptr = f;
|
||||
update_button(button, f);
|
||||
update_range();
|
||||
};
|
||||
|
||||
//update_button(button, f);
|
||||
};
|
||||
|
||||
button_max.on_select = [this, &nav](Button& button) {
|
||||
rf::Frequency * value_ptr;
|
||||
|
||||
value_ptr = &frequency_range.max;
|
||||
|
||||
auto new_view = nav.push<FrequencyKeypadView>(*value_ptr);
|
||||
new_view->on_changed = [this, value_ptr, &button](rf::Frequency f) {
|
||||
*value_ptr = f;
|
||||
update_button(button, f);
|
||||
update_range();
|
||||
};
|
||||
|
||||
//update_button(button, f);
|
||||
};
|
||||
|
||||
text_info.set_style(&style_info);
|
||||
|
||||
options_preset.set_selected_index(8); // ISM 868
|
||||
|
||||
options_preset.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
frequency_range.min = range_presets[v].min;
|
||||
frequency_range.max = range_presets[v].max;
|
||||
check_enabled.set_value(true);
|
||||
update_button(button_min, frequency_range.min);
|
||||
update_button(button_max, frequency_range.max);
|
||||
update_range();
|
||||
};
|
||||
}
|
||||
|
||||
JammerView::~JammerView() {
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
|
||||
void JammerView::update_range(const uint32_t n) {
|
||||
void RangeView::update_button(Button& button, rf::Frequency f) {
|
||||
std::string label;
|
||||
|
||||
auto f_mhz = to_string_dec_int(f / 1000000, 4);
|
||||
auto f_hz100 = to_string_dec_int((f / 1000) % 1000, 3, '0');
|
||||
|
||||
label = f_mhz + "." + f_hz100 + "M";
|
||||
|
||||
button.set_text(label);
|
||||
}
|
||||
|
||||
void RangeView::update_range() {
|
||||
std::string label;
|
||||
jammer_range_t * range_ptr;
|
||||
rf::Frequency center, bw_khz;
|
||||
|
||||
range_ptr = &frequency_range[n];
|
||||
|
||||
center = (range_ptr->min + range_ptr->max) / 2;
|
||||
bw_khz = abs(range_ptr->max - range_ptr->min) / 1000;
|
||||
center = (frequency_range.min + frequency_range.max) / 2;
|
||||
bw_khz = abs(frequency_range.max - frequency_range.min) / 1000;
|
||||
|
||||
label = "C:" + to_string_short_freq(center) + "M W:";
|
||||
|
||||
@ -68,24 +135,16 @@ void JammerView::update_range(const uint32_t n) {
|
||||
while (label.length() < 23)
|
||||
label += " ";
|
||||
|
||||
texts_info[n].set(label);
|
||||
text_info.set(label);
|
||||
}
|
||||
|
||||
void JammerView::update_button(const uint32_t id) {
|
||||
std::string label;
|
||||
rf::Frequency f;
|
||||
|
||||
if (id & 1)
|
||||
f = frequency_range[id / 2].max;
|
||||
else
|
||||
f = frequency_range[id / 2].min;
|
||||
|
||||
auto f_mhz = to_string_dec_int(f / 1000000, 4);
|
||||
auto f_hz100 = to_string_dec_int((f / 1000) % 1000, 3, '0');
|
||||
void JammerView::focus() {
|
||||
tab_view.focus();
|
||||
}
|
||||
|
||||
label = f_mhz + "." + f_hz100 + "M";
|
||||
|
||||
buttons_freq[id].set_text(label);
|
||||
JammerView::~JammerView() {
|
||||
transmitter_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
|
||||
void JammerView::on_retune(const rf::Frequency freq, const uint32_t range) {
|
||||
@ -95,9 +154,11 @@ void JammerView::on_retune(const rf::Frequency freq, const uint32_t range) {
|
||||
}
|
||||
}
|
||||
|
||||
JammerView::JammerView(NavigationView& nav) {
|
||||
size_t n;
|
||||
|
||||
JammerView::JammerView(
|
||||
NavigationView& nav
|
||||
) : nav_ { nav }
|
||||
{
|
||||
Rect view_rect = { 0, 3 * 8, 240, 80 };
|
||||
baseband::run_image(portapack::spi_flash::image_tag_jammer);
|
||||
|
||||
static constexpr Style style_val {
|
||||
@ -112,107 +173,28 @@ JammerView::JammerView(NavigationView& nav) {
|
||||
.foreground = Color::red(),
|
||||
};
|
||||
|
||||
static constexpr Style style_info {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
.foreground = Color::grey(),
|
||||
};
|
||||
|
||||
JammerChannel * jammer_channels = (JammerChannel*)shared_memory.bb_data.data;
|
||||
|
||||
add_children({
|
||||
&tab_view,
|
||||
&view_range_a,
|
||||
&view_range_b,
|
||||
&view_range_c,
|
||||
&labels,
|
||||
&options_type,
|
||||
&text_range_number,
|
||||
&text_range_total,
|
||||
&options_speed,
|
||||
&options_preset,
|
||||
&options_hop,
|
||||
&button_transmit
|
||||
});
|
||||
|
||||
const auto button_freq_fn = [this, &nav](Button& button) {
|
||||
rf::Frequency * value_ptr;
|
||||
uint32_t id = button.id;
|
||||
|
||||
if (id & 1)
|
||||
value_ptr = &frequency_range[id >> 1].max;
|
||||
else
|
||||
value_ptr = &frequency_range[id >> 1].min;
|
||||
|
||||
auto new_view = nav.push<FrequencyKeypadView>(*value_ptr);
|
||||
new_view->on_changed = [this, value_ptr, id](rf::Frequency f) {
|
||||
*value_ptr = f;
|
||||
update_button(id);
|
||||
update_range(id >> 1);
|
||||
};
|
||||
|
||||
update_button(id);
|
||||
};
|
||||
|
||||
const auto checkbox_fn = [this](Checkbox& checkbox, bool v) {
|
||||
frequency_range[checkbox.id].enabled = v;
|
||||
};
|
||||
|
||||
n = 0;
|
||||
for (auto& button : buttons_freq) {
|
||||
button.on_select = button_freq_fn;
|
||||
button.set_parent_rect({
|
||||
static_cast<Coord>(13 * 8),
|
||||
static_cast<Coord>(76 + ((n >> 1) * 58) + (20 * (n & 1))),
|
||||
96, 20
|
||||
});
|
||||
button.id = n;
|
||||
add_child(&button);
|
||||
n++;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
for (auto& checkbox : checkboxes) {
|
||||
checkbox.on_select = checkbox_fn;
|
||||
checkbox.set_parent_rect({
|
||||
static_cast<Coord>(8),
|
||||
static_cast<Coord>(86 + (n * 58)),
|
||||
24, 24
|
||||
});
|
||||
checkbox.id = n;
|
||||
checkbox.set_text("Range " + to_string_dec_uint(n + 1));
|
||||
add_child(&checkbox);
|
||||
n++;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
for (auto& text : texts_info) {
|
||||
text.set_parent_rect({
|
||||
static_cast<Coord>(3 * 8),
|
||||
static_cast<Coord>(116 + (n * 58)),
|
||||
25 * 8, 16
|
||||
});
|
||||
text.set_style(&style_info);
|
||||
add_child(&text);
|
||||
n++;
|
||||
}
|
||||
|
||||
options_preset.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
const jammer_range_t * preset_ptr;
|
||||
uint32_t c;
|
||||
|
||||
for (c = 0; c < 3; c++) {
|
||||
preset_ptr = &range_presets[v][c];
|
||||
|
||||
frequency_range[c].min = preset_ptr->min;
|
||||
frequency_range[c].max = preset_ptr->max;
|
||||
checkboxes[c].set_value(preset_ptr->enabled);
|
||||
update_button(c * 2);
|
||||
update_button(c * 2 + 1);
|
||||
update_range(c);
|
||||
}
|
||||
|
||||
};
|
||||
view_range_a.set_parent_rect(view_rect);
|
||||
view_range_b.set_parent_rect(view_rect);
|
||||
view_range_c.set_parent_rect(view_rect);
|
||||
|
||||
options_type.set_selected_index(2); // Sweep
|
||||
options_speed.set_selected_index(3); // 10kHz
|
||||
options_preset.set_selected_index(8); // ISM 868
|
||||
options_hop.set_selected_index(1); // 50ms
|
||||
button_transmit.set_style(&style_val);
|
||||
|
||||
@ -239,14 +221,14 @@ JammerView::JammerView(NavigationView& nav) {
|
||||
// Convert ranges min/max to center/bw
|
||||
for (size_t r = 0; r < 3; r++) {
|
||||
|
||||
if (frequency_range[r].enabled) {
|
||||
range_bw = abs(frequency_range[r].max - frequency_range[r].min);
|
||||
if (range_views[r]->frequency_range.enabled) {
|
||||
range_bw = abs(range_views[r]->frequency_range.max - range_views[r]->frequency_range.min);
|
||||
|
||||
// Sort
|
||||
if (frequency_range[r].min < frequency_range[r].max)
|
||||
start_freq = frequency_range[r].min;
|
||||
if (range_views[r]->frequency_range.min < range_views[r]->frequency_range.max)
|
||||
start_freq = range_views[r]->frequency_range.min;
|
||||
else
|
||||
start_freq = frequency_range[r].max;
|
||||
start_freq = range_views[r]->frequency_range.max;
|
||||
|
||||
if (range_bw >= JAMMER_CH_WIDTH) {
|
||||
num_channels = 0;
|
||||
|
@ -24,12 +24,162 @@
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_font_fixed_8x16.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_tabview.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "message.hpp"
|
||||
#include "jammer.hpp"
|
||||
|
||||
using namespace jammer;
|
||||
|
||||
namespace ui {
|
||||
|
||||
class RangeView : public View {
|
||||
public:
|
||||
RangeView(NavigationView& nav);
|
||||
|
||||
void focus() override;
|
||||
|
||||
jammer_range_t frequency_range { };
|
||||
|
||||
private:
|
||||
void update_button(Button& button, rf::Frequency f);
|
||||
void update_range();
|
||||
|
||||
static constexpr Style style_info {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
.foreground = Color::grey(),
|
||||
};
|
||||
|
||||
static constexpr jammer_range_t range_presets[] = {
|
||||
// GSM900 Orange
|
||||
{ true, 935000000, 945000000 }, // BW:10M
|
||||
// GSM1800 Orange
|
||||
{ false, 1808000000, 1832000000 }, // BW:24M
|
||||
|
||||
// GSM900 SFR
|
||||
{ true, 950000000, 960000000 }, // BW:10M
|
||||
// GSM1800 SFR
|
||||
{ false, 1832000000, 1853000000 }, // BW:21M
|
||||
|
||||
// GSM900 Bouygues
|
||||
{ true, 925000000, 935000000 }, // BW:10M
|
||||
// GSM1800 Bouygues
|
||||
{ false, 1858000000, 1880000000 }, // BW:22M
|
||||
|
||||
// GSM900 Free
|
||||
{ true, 945000000, 950000000 }, // BW:5M
|
||||
|
||||
// GSM-R
|
||||
{ true, 921000000, 925000000 }, // BW:4M
|
||||
|
||||
// DECT
|
||||
{ true, 1880000000, 1900000000 }, // BW: 20MHz
|
||||
|
||||
// PMV AFSK
|
||||
{ true, 162930000, 162970000 }, // BW: 40kHz
|
||||
|
||||
// ISM 433
|
||||
{ true, 433050000, 434790000 }, // Center: 433.92MHz BW: 0.2%
|
||||
|
||||
// ISM 868
|
||||
{ true, 868000000, 868200000 }, // Center: 868.2MHz BW: 40kHz
|
||||
|
||||
// GPS L1
|
||||
{ true, 1575420000 - 500000, 1575420000 + 500000 }, // BW: 1MHz
|
||||
// GPS L2
|
||||
{ false, 1227600000 - 1000000, 1227600000 + 1000000 }, // BW: 2MHz
|
||||
|
||||
// WLAN 2.4G CH1
|
||||
{ true, 2412000000 - 11000000, 2412000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH2
|
||||
{ true, 2417000000 - 11000000, 2417000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH3
|
||||
{ true, 2422000000 - 11000000, 2422000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH4
|
||||
{ true, 2427000000 - 11000000, 2427000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH5
|
||||
{ true, 2432000000 - 11000000, 2432000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH6
|
||||
{ true, 2437000000 - 11000000, 2437000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH7
|
||||
{ true, 2442000000 - 11000000, 2442000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH8
|
||||
{ true, 2447000000 - 11000000, 2447000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH9
|
||||
{ true, 2452000000 - 11000000, 2452000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH10
|
||||
{ true, 2457000000 - 11000000, 2457000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH11
|
||||
{ true, 2462000000 - 11000000, 2462000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH12
|
||||
{ true, 2467000000 - 11000000, 2467000000 + 11000000}, // BW: 22MHz
|
||||
// WLAN 2.4G CH13
|
||||
{ true, 2472000000 - 11000000, 2472000000 + 11000000}, // BW: 22MHz
|
||||
};
|
||||
|
||||
Labels labels {
|
||||
{ { 2 * 8, 5 * 8 }, "Preset:", Color::light_grey() },
|
||||
{ { 5 * 8, 9 * 8 }, "Start:", Color::light_grey() },
|
||||
{ { 6 * 8, 13 * 8 }, "Stop:", Color::light_grey() },
|
||||
};
|
||||
|
||||
Checkbox check_enabled {
|
||||
{ 44, 1 * 8 },
|
||||
12,
|
||||
"Enable range",
|
||||
false
|
||||
};
|
||||
|
||||
OptionsField options_preset {
|
||||
{ 9 * 8, 5 * 8 },
|
||||
19,
|
||||
{
|
||||
{ "GSM900 Orange FR", 0 },
|
||||
{ "GSM1800 Orange FR", 1 },
|
||||
{ "GSM900 SFR FR", 2 },
|
||||
{ "GSM1800 SFR FR", 3 },
|
||||
{ "GSM900 Bouygues FR", 4 },
|
||||
{ "GSM1800 Bouygues FR", 5 },
|
||||
{ "GSM Free FR ", 6 },
|
||||
{ "GSM-R FR ", 7 },
|
||||
{ "DECT ", 8 },
|
||||
{ "Optifib ", 9 },
|
||||
{ "ISM 433 ", 10 },
|
||||
{ "ISM 868 ", 11 },
|
||||
{ "GPS L1 ", 12 },
|
||||
{ "GPS L2 ", 13 },
|
||||
{ "WLAN 2.4G CH1 ", 14 },
|
||||
{ "WLAN 2.4G CH2 ", 15 },
|
||||
{ "WLAN 2.4G CH3 ", 16 },
|
||||
{ "WLAN 2.4G CH4 ", 17 },
|
||||
{ "WLAN 2.4G CH5 ", 18 },
|
||||
{ "WLAN 2.4G CH6 ", 19 },
|
||||
{ "WLAN 2.4G CH7 ", 20 },
|
||||
{ "WLAN 2.4G CH8 ", 21 },
|
||||
{ "WLAN 2.4G CH9 ", 22 },
|
||||
{ "WLAN 2.4G CH10 ", 23 },
|
||||
{ "WLAN 2.4G CH11 ", 24 },
|
||||
{ "WLAN 2.4G CH12 ", 25 },
|
||||
{ "WLAN 2.4G CH13 ", 26 }
|
||||
}
|
||||
};
|
||||
|
||||
Button button_min {
|
||||
{ 13 * 8, 4 * 16, 120, 28 },
|
||||
""
|
||||
};
|
||||
Button button_max {
|
||||
{ 13 * 8, 6 * 16, 120, 28 },
|
||||
""
|
||||
};
|
||||
|
||||
Text text_info {
|
||||
{ 3 * 8, 8 * 16, 25 * 8, 16 },
|
||||
""
|
||||
};
|
||||
};
|
||||
|
||||
class JammerView : public View {
|
||||
public:
|
||||
JammerView(NavigationView& nav);
|
||||
@ -38,137 +188,34 @@ public:
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "Jammer"; };
|
||||
|
||||
|
||||
private:
|
||||
typedef struct jammer_range {
|
||||
bool enabled;
|
||||
rf::Frequency min;
|
||||
rf::Frequency max;
|
||||
} jammer_range_t;
|
||||
|
||||
jammer_range_t frequency_range[3];
|
||||
NavigationView& nav_;
|
||||
|
||||
void update_range(const uint32_t n);
|
||||
void update_button(const uint32_t n);
|
||||
void on_retune(const rf::Frequency freq, const uint32_t range);
|
||||
|
||||
const jammer_range_t range_presets[23][3] = {
|
||||
// Orange
|
||||
{{ true, 935000000, 945000000 }, // GSM 900 BW:10M
|
||||
{ false, 1808000000, 1832000000 }, // GSM 1800 BW:24M
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// SFR
|
||||
{{ true, 950000000, 960000000 }, // GSM 900 BW:10M
|
||||
{ false, 1832000000, 1853000000 }, // GSM 1800 BW:21M
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// Bouygues
|
||||
{{ true, 925000000, 935000000 }, // GSM 900 BW:10M
|
||||
{ false, 1858000000, 1880000000 }, // GSM 1800 BW:22M
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// Free
|
||||
{{ true, 945000000, 950000000 }, // GSM 900 BW:5M
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// GSM-R
|
||||
{{ true, 921000000, 925000000 }, // GSM 900 BW:4M
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// DECT
|
||||
{{ true, 1880000000, 1900000000 }, // BW: 20MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// PMV AFSK
|
||||
{{ true, 162930000, 162970000 }, // BW: 40kHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// ISM 433
|
||||
{{ true, 433050000, 434790000 }, // Center: 433.92MHz BW: 0.2%
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// ISM 868
|
||||
{{ true, 868000000, 868200000 }, // Center: 868.2MHz BW: 40kHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// GPS L1 & L2
|
||||
{{ true, 1575420000 - 500000, 1575420000 + 500000 }, // BW: 1MHz
|
||||
{ false, 1227600000 - 1000000, 1227600000 + 1000000 }, // BW: 2MHz
|
||||
{ false, 0, 0 }},
|
||||
|
||||
// WLAN 2.4G CH1
|
||||
{{ true, 2412000000 - 11000000, 2412000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH2
|
||||
{{ true, 2417000000 - 11000000, 2417000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH3
|
||||
{{ true, 2422000000 - 11000000, 2422000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH4
|
||||
{{ true, 2427000000 - 11000000, 2427000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH5
|
||||
{{ true, 2432000000 - 11000000, 2432000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH6
|
||||
{{ true, 2437000000 - 11000000, 2437000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH7
|
||||
{{ true, 2442000000 - 11000000, 2442000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH8
|
||||
{{ true, 2447000000 - 11000000, 2447000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH9
|
||||
{{ true, 2452000000 - 11000000, 2452000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH10
|
||||
{{ true, 2457000000 - 11000000, 2457000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH11
|
||||
{{ true, 2462000000 - 11000000, 2462000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH12
|
||||
{{ true, 2467000000 - 11000000, 2467000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
// WLAN 2.4G CH13
|
||||
{{ true, 2472000000 - 11000000, 2472000000 + 11000000}, // BW: 22MHz
|
||||
{ false, 0, 0 },
|
||||
{ false, 0, 0 }},
|
||||
|
||||
};
|
||||
|
||||
bool jamming { false };
|
||||
|
||||
RangeView view_range_a { nav_ };
|
||||
RangeView view_range_b { nav_ };
|
||||
RangeView view_range_c { nav_ };
|
||||
|
||||
std::array<RangeView*, 3> range_views { &view_range_a, &view_range_b, &view_range_c };
|
||||
|
||||
TabView tab_view {
|
||||
{ "Range 1", Color::white(), range_views[0] },
|
||||
{ "Range 2", Color::white(), range_views[1] },
|
||||
{ "Range 3", Color::white(), range_views[2] },
|
||||
};
|
||||
|
||||
Labels labels {
|
||||
{ { 3 * 8, 4 }, "Type:", Color::light_grey() },
|
||||
{ { 2 * 8, 20 }, "Speed:", Color::light_grey() },
|
||||
{ { 1 * 8, 36 }, "Preset:", Color::light_grey() },
|
||||
{ { 5 * 8, 52 }, "Hop:", Color::light_grey() }
|
||||
{ { 3 * 8, 12 * 16 }, "Type:", Color::light_grey() },
|
||||
{ { 2 * 8, 13 * 16 }, "Speed:", Color::light_grey() },
|
||||
{ { 5 * 8, 14 * 16 }, "Hop:", Color::light_grey() }
|
||||
};
|
||||
|
||||
OptionsField options_type {
|
||||
{ 9 * 8, 4 },
|
||||
{ 9 * 8, 12 * 16 },
|
||||
5,
|
||||
{
|
||||
{ "FSK ", 0 },
|
||||
@ -178,16 +225,16 @@ private:
|
||||
};
|
||||
|
||||
Text text_range_number {
|
||||
{ 18 * 8, 4, 2 * 8, 16 },
|
||||
{ 18 * 8, 12 * 16, 2 * 8, 16 },
|
||||
"--"
|
||||
};
|
||||
Text text_range_total {
|
||||
{ 20 * 8, 4, 3 * 8, 16 },
|
||||
{ 20 * 8, 12 * 16, 3 * 8, 16 },
|
||||
"/--"
|
||||
};
|
||||
|
||||
OptionsField options_speed {
|
||||
{ 9 * 8, 20 },
|
||||
{ 9 * 8, 13 * 16 },
|
||||
6,
|
||||
{
|
||||
{ "10Hz ", 10 },
|
||||
@ -198,38 +245,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
OptionsField options_preset {
|
||||
{ 9 * 8, 36 },
|
||||
16,
|
||||
{
|
||||
{ "GSM Orange FR ", 0 },
|
||||
{ "GSM SFR FR ", 1 },
|
||||
{ "GSM Bouygues FR", 2 },
|
||||
{ "GSM Free FR ", 3 },
|
||||
{ "GSM-R FR ", 4 },
|
||||
{ "DECT ", 5 },
|
||||
{ "Optifib ", 6 },
|
||||
{ "ISM 433 ", 7 },
|
||||
{ "ISM 868 ", 8 },
|
||||
{ "GPS ", 9 },
|
||||
{ "WLAN 2.4G CH1 ", 10 },
|
||||
{ "WLAN 2.4G CH2 ", 11 },
|
||||
{ "WLAN 2.4G CH3 ", 12 },
|
||||
{ "WLAN 2.4G CH4 ", 13 },
|
||||
{ "WLAN 2.4G CH5 ", 14 },
|
||||
{ "WLAN 2.4G CH6 ", 15 },
|
||||
{ "WLAN 2.4G CH7 ", 16 },
|
||||
{ "WLAN 2.4G CH8 ", 17 },
|
||||
{ "WLAN 2.4G CH9 ", 18 },
|
||||
{ "WLAN 2.4G CH10 ", 19 },
|
||||
{ "WLAN 2.4G CH11 ", 20 },
|
||||
{ "WLAN 2.4G CH12 ", 21 },
|
||||
{ "WLAN 2.4G CH13 ", 22 }
|
||||
}
|
||||
};
|
||||
|
||||
OptionsField options_hop {
|
||||
{ 9 * 8, 52 },
|
||||
{ 9 * 8, 14 * 16 },
|
||||
5,
|
||||
{
|
||||
{ "10ms ", 1 },
|
||||
@ -241,10 +258,6 @@ private:
|
||||
{ "10s ", 1000 }
|
||||
}
|
||||
};
|
||||
|
||||
std::array<Checkbox, 3> checkboxes { };
|
||||
std::array<Button, 6> buttons_freq { };
|
||||
std::array<Text, 3> texts_info { };
|
||||
|
||||
Button button_transmit {
|
||||
{ 1 * 8, 16 * 16, 80, 48 },
|
||||
|
@ -349,7 +349,7 @@ SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
add_items({
|
||||
{ "Play dead", ui::Color::red(), &bitmap_icon_playdead, [&nav](){ nav.push<PlayDeadView>(); } },
|
||||
{ "Receivers", ui::Color::cyan(), &bitmap_icon_receivers, [&nav](){ nav.push<ReceiversMenuView>(); } },
|
||||
{ "Transmitters", ui::Color::green(), nullptr, [&nav](){ nav.push<TransmittersMenuView>(); } },
|
||||
{ "Transmitters", ui::Color::green(), &bitmap_icon_transmit, [&nav](){ nav.push<TransmittersMenuView>(); } },
|
||||
{ "Capture", ui::Color::blue(), &bitmap_icon_capture, [&nav](){ nav.push<CaptureAppView>(); } },
|
||||
{ "Replay", ui::Color::grey(), &bitmap_icon_replay, [&nav](){ nav.push<ReplayAppView>(); } },
|
||||
{ "Scanner/search", ui::Color::orange(), &bitmap_icon_closecall, [&nav](){ nav.push<ScannerView>(); } },
|
||||
|
@ -566,8 +566,8 @@ buffer_c16_t DecimateBy2CIC3::execute(
|
||||
uint32_t t1 = _iq0;
|
||||
uint32_t t2 = _iq1;
|
||||
const uint32_t taps = 0x00000003;
|
||||
auto s = src.p;
|
||||
auto d = dst.p;
|
||||
void* s = src.p;
|
||||
void* d = dst.p;
|
||||
const auto d_end = &dst.p[src.count / 2];
|
||||
while(d < d_end) {
|
||||
uint32_t i = __SXTH(t1, 0); /* 1: I0 */
|
||||
@ -665,21 +665,21 @@ buffer_c16_t FIRAndDecimateComplex::execute(
|
||||
const auto output_sampling_rate = src.sampling_rate / decimation_factor_;
|
||||
const size_t output_samples = src.count / decimation_factor_;
|
||||
|
||||
sample_t* dst_p = dst.p;
|
||||
void* dst_p = dst.p;
|
||||
const buffer_c16_t result { dst.p, output_samples, output_sampling_rate };
|
||||
|
||||
const sample_t* src_p = src.p;
|
||||
const void* src_p = src.p;
|
||||
size_t outer_count = output_samples;
|
||||
while(outer_count > 0) {
|
||||
/* Put new samples into delay buffer */
|
||||
auto z_new_p = &samples_[taps_count_ - decimation_factor_];
|
||||
void* z_new_p = &samples_[taps_count_ - decimation_factor_];
|
||||
for(size_t i=0; i<decimation_factor_; i++) {
|
||||
*__SIMD32(z_new_p)++ = *__SIMD32(src_p)++;
|
||||
}
|
||||
|
||||
size_t loop_count = taps_count_ / 8;
|
||||
auto t_p = &taps_reversed_[0];
|
||||
auto z_p = &samples_[0];
|
||||
void* t_p = &taps_reversed_[0];
|
||||
void* z_p = &samples_[0];
|
||||
|
||||
int64_t t_real = 0;
|
||||
int64_t t_imag = 0;
|
||||
@ -741,8 +741,8 @@ buffer_c16_t FIRAndDecimateComplex::execute(
|
||||
const size_t unroll_factor = 4;
|
||||
size_t shift_count = (taps_count_ - decimation_factor_) / unroll_factor;
|
||||
|
||||
sample_t* t = &samples_[0];
|
||||
const sample_t* s = &samples_[decimation_factor_];
|
||||
void* t = &samples_[0];
|
||||
const void* s = &samples_[decimation_factor_];
|
||||
|
||||
while(shift_count > 0) {
|
||||
*__SIMD32(t)++ = *__SIMD32(s)++;
|
||||
@ -754,7 +754,7 @@ buffer_c16_t FIRAndDecimateComplex::execute(
|
||||
|
||||
shift_count = (taps_count_ - decimation_factor_) % unroll_factor;
|
||||
while(shift_count > 0) {
|
||||
*(t++) = *(s++);
|
||||
*__SIMD32(t)++ = *__SIMD32(s)++;
|
||||
shift_count--;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ buffer_f32_t AM::execute(
|
||||
const buffer_c16_t& src,
|
||||
const buffer_f32_t& dst
|
||||
) {
|
||||
const auto src_p = src.p;
|
||||
const void* src_p = src.p;
|
||||
const auto src_end = &src.p[src.count];
|
||||
auto dst_p = dst.p;
|
||||
while(src_p < src_end) {
|
||||
@ -90,7 +90,7 @@ buffer_f32_t FM::execute(
|
||||
) {
|
||||
auto z = z_;
|
||||
|
||||
const auto src_p = src.p;
|
||||
const void* src_p = src.p;
|
||||
const auto src_end = &src.p[src.count];
|
||||
auto dst_p = dst.p;
|
||||
while(src_p < src_end) {
|
||||
@ -113,9 +113,9 @@ buffer_s16_t FM::execute(
|
||||
) {
|
||||
auto z = z_;
|
||||
|
||||
const auto src_p = src.p;
|
||||
const void* src_p = src.p;
|
||||
const auto src_end = &src.p[src.count];
|
||||
auto dst_p = dst.p;
|
||||
void* dst_p = dst.p;
|
||||
while(src_p < src_end) {
|
||||
const auto s0 = *__SIMD32(src_p)++;
|
||||
const auto s1 = *__SIMD32(src_p)++;
|
||||
|
@ -41,6 +41,19 @@ extern "C" {
|
||||
* @brief Product name title=UM10503 Chapter title=LPC43xx Configuration Registers (CREG) Modification date=1/28/2014 Major revision=1 Minor revision=8
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t ETHMODE : 3;
|
||||
uint32_t RESERVED0 : 1;
|
||||
__IO uint32_t CTOUTCTRL : 1;
|
||||
uint32_t RESERVED1 : 7;
|
||||
__IO uint32_t I2S0_TX_SCK_IN_SEL : 1;
|
||||
__IO uint32_t I2S0_RX_SCK_IN_SEL : 1;
|
||||
__IO uint32_t I2S1_TX_SCK_IN_SEL : 1;
|
||||
__IO uint32_t I2S1_RX_SCK_IN_SEL : 1;
|
||||
__IO uint32_t EMC_CLK_SEL : 1;
|
||||
uint32_t RESERVED2 : 15;
|
||||
} LPC_CREG_CREG6_Type;
|
||||
|
||||
typedef struct {
|
||||
uint32_t RESERVED0;
|
||||
__IO uint32_t CREG0;
|
||||
@ -52,7 +65,7 @@ typedef struct {
|
||||
__IO uint32_t FLASHCFGA;
|
||||
__IO uint32_t FLASHCFGB;
|
||||
__IO uint32_t ETBCFG;
|
||||
__IO uint32_t CREG6;
|
||||
LPC_CREG_CREG6_Type CREG6;
|
||||
__IO uint32_t M4TXEVENT;
|
||||
uint32_t RESERVED3[51];
|
||||
__I uint32_t CHIPID;
|
||||
|
@ -29,7 +29,7 @@ using namespace portapack;
|
||||
namespace asahi_kasei {
|
||||
namespace ak4951 {
|
||||
|
||||
void AK4951::configure_digital_interface() {
|
||||
void AK4951::configure_digital_interface_i2s() {
|
||||
// Configure for external slave mode.
|
||||
map.r.mode_control_1.DIF = 0b11; // I2S compatible
|
||||
map.r.mode_control_1.BCKO = 0; // BICK = 32fs
|
||||
@ -38,22 +38,28 @@ void AK4951::configure_digital_interface() {
|
||||
map.r.mode_control_2.CM = 0b00; // MCKI = 256fs
|
||||
map.r.mode_control_2.FS = 0b1011; // fs = 48kHz
|
||||
update(Register::ModeControl2);
|
||||
}
|
||||
|
||||
// map.r.mode_control_3.DVOLC = 1; // Control L/R channels with DVL (LchDigitalVolumeControl)
|
||||
// update(Register::ModeControl3);
|
||||
|
||||
void AK4951::configure_digital_interface_external_slave() {
|
||||
map.r.power_management_2.MS = 0; // Slave mode
|
||||
map.r.power_management_2.PMPLL = 0; // EXT mode
|
||||
update(Register::PowerManagement2);
|
||||
}
|
||||
|
||||
void AK4951::configure_digital_interface_external_master() {
|
||||
map.r.power_management_2.MS = 1; // Master mode
|
||||
map.r.power_management_2.PMPLL = 0; // EXT mode
|
||||
update(Register::PowerManagement2);
|
||||
}
|
||||
|
||||
void AK4951::init() {
|
||||
reset();
|
||||
|
||||
// Write dummy address to "release" the reset.
|
||||
write(0x00, 0x00);
|
||||
|
||||
configure_digital_interface();
|
||||
configure_digital_interface_i2s();
|
||||
configure_digital_interface_external_slave();
|
||||
|
||||
map.r.power_management_1.PMVCM = 1;
|
||||
update(Register::PowerManagement1);
|
||||
|
@ -864,7 +864,9 @@ private:
|
||||
Line,
|
||||
};
|
||||
|
||||
void configure_digital_interface();
|
||||
void configure_digital_interface_i2s();
|
||||
void configure_digital_interface_external_slave();
|
||||
void configure_digital_interface_external_master();
|
||||
void set_digtal_volume_control(const reg_t value);
|
||||
void set_dac_power(const bool enable);
|
||||
void set_headphone_power(const bool enable);
|
||||
|
@ -138,6 +138,7 @@ struct ConfigTX {
|
||||
uint32_t txrate;
|
||||
uint32_t txbitrate;
|
||||
uint32_t txmode;
|
||||
uint32_t sck_in_sel;
|
||||
};
|
||||
|
||||
struct ConfigRX {
|
||||
@ -145,6 +146,7 @@ struct ConfigRX {
|
||||
uint32_t rxrate;
|
||||
uint32_t rxbitrate;
|
||||
uint32_t rxmode;
|
||||
uint32_t sck_in_sel;
|
||||
};
|
||||
|
||||
struct ConfigDMA {
|
||||
@ -161,21 +163,13 @@ public:
|
||||
) {
|
||||
reset();
|
||||
|
||||
/* I2S operates in master mode, use PLL0AUDIO as MCLK source for TX. */
|
||||
/* NOTE: Documentation of CREG6 is quite confusing. Refer to "I2S clocking and
|
||||
* pin connections" and other I2S diagrams for more clarity.
|
||||
*/
|
||||
if( &p() == LPC_I2S0 ) {
|
||||
LPC_CREG->CREG6 |=
|
||||
(1U << 12)
|
||||
| (1U << 13)
|
||||
;
|
||||
LPC_CREG->CREG6.I2S0_TX_SCK_IN_SEL = config_tx.sck_in_sel;
|
||||
LPC_CREG->CREG6.I2S0_RX_SCK_IN_SEL = config_rx.sck_in_sel;
|
||||
}
|
||||
if( &p() == LPC_I2S1 ) {
|
||||
LPC_CREG->CREG6 |=
|
||||
(1U << 14)
|
||||
| (1U << 15)
|
||||
;
|
||||
LPC_CREG->CREG6.I2S1_TX_SCK_IN_SEL = config_tx.sck_in_sel;
|
||||
LPC_CREG->CREG6.I2S1_RX_SCK_IN_SEL = config_rx.sck_in_sel;
|
||||
}
|
||||
|
||||
p().DAO = config_tx.dao;
|
||||
|
@ -28,6 +28,12 @@
|
||||
|
||||
namespace jammer {
|
||||
|
||||
typedef struct jammer_range {
|
||||
bool enabled;
|
||||
int64_t min;
|
||||
int64_t max;
|
||||
} jammer_range_t;
|
||||
|
||||
enum JammerType : uint32_t {
|
||||
TYPE_FSK = 0,
|
||||
TYPE_TONE = 1,
|
||||
|
@ -78,7 +78,7 @@ constexpr Pin pins[] = {
|
||||
[P2_11] = { 2, 11, { .mode=0, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* RX_AMP/P49: U12.V1(I), U14.V3(I) */
|
||||
[P2_12] = { 2, 12, { .mode=0, .pd=0, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* !RX_AMP_PWR/P52: 10K PU, Q1.G(I), power to U13 (RX amp) */
|
||||
[P2_13] = { 2, 13, { .mode=0, .pd=0, .pu=0, .fast=0, .input=1, .ifilt=1 } }, /* P2_13: PortaPack P2_13/DIR */
|
||||
[P3_0] = { 3, 0, { .mode=2, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* I2S0_TX_SCK: PortaPack I2S0_TX_SCK(I) */
|
||||
[P3_0] = { 3, 0, { .mode=2, .pd=0, .pu=1, .fast=0, .input=1, .ifilt=1 } }, /* I2S0_TX_SCK: PortaPack I2S0_TX_SCK(I) */
|
||||
[P3_1] = { 3, 1, { .mode=0, .pd=0, .pu=1, .fast=0, .input=1, .ifilt=1 } }, /* I2S0_RX_WS: PortaPack I2S0_TX_WS(I). Input enabled to fold back into RX. */
|
||||
[P3_2] = { 3, 2, { .mode=0, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* I2S0_RX_SDA: PortaPack I2S0_TX_SDA(I) */
|
||||
//[P3_3] = { 3, 3, { .mode=3, .pd=1, .pu=0, .fast=1, .input=1, .ifilt=0 } }, /* SPIFI_SCK: W25Q80BV.CLK(I), enable input buffer for timing feedback */
|
||||
|
@ -108,7 +108,7 @@ Optional<Reading> Packet::reading_ook_8k4_schrader() const {
|
||||
* Those bits assumed to be 0b0100", which may not be entirely true...
|
||||
*/
|
||||
constexpr uint8_t first_nibble = 0x4;
|
||||
const auto system_id = (first_nibble << 20) | reader_.read(0, 20);
|
||||
// const auto system_id = (first_nibble << 20) | reader_.read(0, 20);
|
||||
const auto id = reader_.read(20, 32);
|
||||
const auto value_0 = reader_.read(52, 8);
|
||||
const auto value_1 = reader_.read(60, 8);
|
||||
|
@ -25,6 +25,30 @@
|
||||
namespace wolfson {
|
||||
namespace wm8731 {
|
||||
|
||||
void WM8731::configure_interface_i2s_slave() {
|
||||
write(DigitalAudioInterfaceFormat {
|
||||
.format = 2,
|
||||
.iwl = 0,
|
||||
.lrp = 0,
|
||||
.lrswap = 0,
|
||||
.ms = 0,
|
||||
.bclkinv = 0,
|
||||
.reserved0 = 0,
|
||||
});
|
||||
}
|
||||
|
||||
void WM8731::configure_interface_i2s_master() {
|
||||
write(DigitalAudioInterfaceFormat {
|
||||
.format = 2,
|
||||
.iwl = 0,
|
||||
.lrp = 0,
|
||||
.lrswap = 0,
|
||||
.ms = 1,
|
||||
.bclkinv = 0,
|
||||
.reserved0 = 0,
|
||||
});
|
||||
}
|
||||
|
||||
void WM8731::init() {
|
||||
reset();
|
||||
|
||||
@ -49,15 +73,7 @@ void WM8731::init() {
|
||||
// .reserved0 = 0,
|
||||
// });
|
||||
|
||||
write(DigitalAudioInterfaceFormat {
|
||||
.format = 2,
|
||||
.iwl = 0,
|
||||
.lrp = 0,
|
||||
.lrswap = 0,
|
||||
.ms = 0,
|
||||
.bclkinv = 0,
|
||||
.reserved0 = 0,
|
||||
});
|
||||
configure_interface_i2s_slave();
|
||||
|
||||
write(DigitalAudioPathControl {
|
||||
.adchpd = 0,
|
||||
|
@ -375,6 +375,9 @@ private:
|
||||
RegisterMap map { default_after_reset };
|
||||
volume_t headphone_volume = -60.0_dB;
|
||||
|
||||
void configure_interface_i2s_slave();
|
||||
void configure_interface_i2s_master();
|
||||
|
||||
bool write(const Register reg);
|
||||
|
||||
bool write(const address_t reg_address, const reg_t value);
|
||||
|
BIN
firmware/graphics/icon_transmit.png
Normal file
BIN
firmware/graphics/icon_transmit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 152 B |
Binary file not shown.
Loading…
Reference in New Issue
Block a user