mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 06:49:24 -05:00
Splash screen and Play Dead functionality
This commit is contained in:
parent
ec26f587f1
commit
30531a20f2
@ -162,6 +162,7 @@ CPPSRC = main.cpp \
|
||||
ui_debug.cpp \
|
||||
ui_rds.cpp \
|
||||
ui_lcr.cpp \
|
||||
ui_afsksetup.cpp \
|
||||
ui_console.cpp \
|
||||
ui_receiver.cpp \
|
||||
ui_spectrum.cpp \
|
||||
|
@ -475,6 +475,8 @@ message_handlers[Message::ID::TestResults] = [&system_view](const Message* const
|
||||
*/
|
||||
|
||||
int main(void) {
|
||||
ui::Context context;
|
||||
|
||||
portapack::init();
|
||||
|
||||
if( !cpld_update_if_necessary() ) {
|
||||
@ -484,7 +486,7 @@ int main(void) {
|
||||
init_message_queues();
|
||||
|
||||
portapack::io.init();
|
||||
ui::Context context;
|
||||
|
||||
portapack::display.init();
|
||||
|
||||
sdcStart(&SDCD1, nullptr);
|
||||
@ -503,13 +505,19 @@ int main(void) {
|
||||
{ 0, 0, 240, 320 }
|
||||
};
|
||||
ui::Painter painter;
|
||||
EventDispatcher event_dispatcher { &system_view, painter, context };
|
||||
|
||||
|
||||
context.message_map[Message::ID::FSKPacket] = [](const Message* const p) {
|
||||
const auto message = static_cast<const FSKPacketMessage*>(p);
|
||||
(void)message;
|
||||
};
|
||||
|
||||
context.message_map[Message::ID::TXDone] = [](const Message* const p) {
|
||||
const auto message = static_cast<const TXDoneMessage*>(p);
|
||||
(void)message;
|
||||
};
|
||||
|
||||
EventDispatcher event_dispatcher { &system_view, painter, context };
|
||||
|
||||
m4txevent_interrupt_enable();
|
||||
|
||||
m4_init(portapack::spi_flash::baseband, portapack::spi_flash::m4_text_ram_base);
|
||||
|
BIN
firmware/application/splash.bmp
Normal file
BIN
firmware/application/splash.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
1075
firmware/application/splash.hpp
Normal file
1075
firmware/application/splash.hpp
Normal file
File diff suppressed because it is too large
Load Diff
121
firmware/application/ui_afsksetup.cpp
Normal file
121
firmware/application/ui_afsksetup.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* 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_rds.hpp"
|
||||
#include "ui_afsksetup.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#include "ff.h"
|
||||
#include "hackrf_gpio.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "radio.hpp"
|
||||
|
||||
#include "hackrf_hal.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace hackrf::one;
|
||||
|
||||
namespace ui {
|
||||
|
||||
void AFSKSetupView::focus() {
|
||||
button_setfreq.focus();
|
||||
}
|
||||
|
||||
void AFSKSetupView::paint(Painter& painter) {
|
||||
|
||||
}
|
||||
|
||||
void AFSKSetupView::updfreq(rf::Frequency f) {
|
||||
char finalstr[9] = {0};
|
||||
|
||||
persistent_memory::set_tuned_frequency(f);
|
||||
transmitter_model.set_tuning_frequency(f);
|
||||
|
||||
auto mhz = to_string_dec_int(f / 1000000, 3);
|
||||
auto hz100 = to_string_dec_int((f / 100) % 10000, 4, '0');
|
||||
|
||||
strcat(finalstr, mhz.c_str());
|
||||
strcat(finalstr, ".");
|
||||
strcat(finalstr, hz100.c_str());
|
||||
|
||||
this->button_setfreq.set_text(finalstr);
|
||||
}
|
||||
|
||||
AFSKSetupView::AFSKSetupView(
|
||||
NavigationView& nav,
|
||||
TransmitterModel& transmitter_model
|
||||
) : transmitter_model(transmitter_model)
|
||||
{
|
||||
|
||||
add_children({ {
|
||||
&text_title,
|
||||
&button_setfreq,
|
||||
&button_setbps,
|
||||
&text_mark,
|
||||
&field_mark,
|
||||
&text_space,
|
||||
&field_space,
|
||||
&button_done
|
||||
} });
|
||||
|
||||
updfreq(persistent_memory::tuned_frequency());
|
||||
|
||||
field_mark.set_value(persistent_memory::afsk_mark_freq()*100);
|
||||
field_space.set_value(persistent_memory::afsk_space_freq()*100);
|
||||
|
||||
button_setfreq.on_select = [this,&nav](Button&){
|
||||
auto new_view = new FrequencyKeypadView { nav, this->transmitter_model.tuning_frequency() };
|
||||
new_view->on_changed = [this](rf::Frequency f) {
|
||||
updfreq(f);
|
||||
};
|
||||
nav.push(new_view);
|
||||
};
|
||||
|
||||
if (persistent_memory::afsk_bitrate() == 1200) {
|
||||
button_setbps.set_text("1200 bps");
|
||||
} else {
|
||||
button_setbps.set_text("2400 bps");
|
||||
}
|
||||
|
||||
button_setbps.on_select = [this](Button&){
|
||||
if (persistent_memory::afsk_bitrate() == 1200) {
|
||||
persistent_memory::set_afsk_bitrate(2400);
|
||||
button_setbps.set_text("2400 bps");
|
||||
} else {
|
||||
persistent_memory::set_afsk_bitrate(1200);
|
||||
button_setbps.set_text("1200 bps");
|
||||
}
|
||||
};
|
||||
|
||||
button_done.on_select = [this,&nav](Button&){
|
||||
persistent_memory::set_afsk_mark(field_mark.value()/100);
|
||||
persistent_memory::set_afsk_space(field_space.value()/100);
|
||||
nav.pop();
|
||||
};
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
93
firmware/application/ui_afsksetup.hpp
Normal file
93
firmware/application/ui_afsksetup.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* 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_font_fixed_8x16.hpp"
|
||||
#include "clock_manager.hpp"
|
||||
#include "message.hpp"
|
||||
#include "rf_path.hpp"
|
||||
#include "max2837.hpp"
|
||||
#include "volume.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class AFSKSetupView : public View {
|
||||
public:
|
||||
AFSKSetupView(NavigationView& nav, TransmitterModel& transmitter_model);
|
||||
|
||||
void updfreq(rf::Frequency f);
|
||||
void focus() override;
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
private:
|
||||
//rf::Frequency f = 162950000;
|
||||
TransmitterModel& transmitter_model;
|
||||
|
||||
Text text_title {
|
||||
{ 40, 32, 160, 16 },
|
||||
"AFSK modulator setup"
|
||||
};
|
||||
|
||||
Button button_setfreq {
|
||||
{ 8, 64, 104, 32 },
|
||||
"---.----M"
|
||||
};
|
||||
Button button_setbps {
|
||||
{ 128, 64, 96, 32 },
|
||||
"----bps"
|
||||
};
|
||||
|
||||
Text text_mark {
|
||||
{ 16, 104, 48, 16 },
|
||||
"Mark: Hz"
|
||||
};
|
||||
NumberField field_mark {
|
||||
{ 64, 104 },
|
||||
5,
|
||||
{ 100, 32000 },
|
||||
100,
|
||||
' '
|
||||
};
|
||||
|
||||
Text text_space {
|
||||
{ 16, 120, 48, 16 },
|
||||
"Space: Hz"
|
||||
};
|
||||
NumberField field_space {
|
||||
{ 64, 120 },
|
||||
5,
|
||||
{ 100, 32000 },
|
||||
100,
|
||||
' '
|
||||
};
|
||||
|
||||
Button button_done {
|
||||
{ 72, 200, 96, 48 },
|
||||
"Save"
|
||||
};
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
@ -27,6 +27,7 @@
|
||||
#include "led.hpp"
|
||||
#include "hackrf_gpio.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
#include "radio.hpp"
|
||||
|
||||
@ -229,15 +230,71 @@ void DebugSDView::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
// LCR debug view
|
||||
|
||||
void DebugLCRView::paint(Painter& painter) {
|
||||
const Point offset = {
|
||||
static_cast<Coord>(32),
|
||||
static_cast<Coord>(32)
|
||||
};
|
||||
|
||||
const auto text = to_string_hex(fr, 2);
|
||||
painter.draw_string(
|
||||
screen_pos() + offset,
|
||||
style(),
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
char hexify(char in) {
|
||||
if (in > 9) in += 7;
|
||||
return in + 0x30;
|
||||
}
|
||||
|
||||
DebugLCRView::DebugLCRView(NavigationView& nav, char* lcrstring, uint8_t checksum) {
|
||||
char cstr[15] = "Checksum: 0x ";
|
||||
|
||||
add_children({ {
|
||||
&text_lcr1,
|
||||
&text_lcr2,
|
||||
&text_lcr3,
|
||||
&text_lcr4,
|
||||
&text_lcr5,
|
||||
&text_lcr6,
|
||||
&text_checksum,
|
||||
&button_done
|
||||
} });
|
||||
|
||||
std::string b = std::string(lcrstring);
|
||||
|
||||
text_lcr1.set(b.substr(8+(0*26),26));
|
||||
text_lcr2.set(b.substr(8+(1*26),26));
|
||||
text_lcr3.set(b.substr(8+(2*26),26));
|
||||
text_lcr4.set(b.substr(8+(3*26),26));
|
||||
text_lcr5.set(b.substr(8+(4*26),26));
|
||||
text_lcr6.set(b.substr(8+(5*26),26));
|
||||
|
||||
cstr[12] = hexify(checksum >> 4);
|
||||
cstr[13] = hexify(checksum & 15);
|
||||
|
||||
text_checksum.set(cstr);
|
||||
|
||||
button_done.on_select = [&nav](Button&){ nav.pop(); };
|
||||
}
|
||||
|
||||
void DebugLCRView::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
add_items<7>({ {
|
||||
{ "Memory", [&nav](){ nav.push(new DebugMemoryView { nav }); } },
|
||||
{ "Radio State", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "SD Card", [&nav](){ nav.push(new DebugSDView { nav }); } },
|
||||
{ "RFFC5072", [&nav](){ nav.push(new DebugRFFC5072View { nav }); } },
|
||||
{ "MAX2837", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "Si5351C", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "WM8731", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "Memory", ui::Color::white(), [&nav](){ nav.push(new DebugMemoryView { nav }); } },
|
||||
{ "Radio State", ui::Color::white(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "SD Card", ui::Color::white(), [&nav](){ nav.push(new DebugSDView { nav }); } },
|
||||
{ "RFFC5072", ui::Color::white(), [&nav](){ nav.push(new DebugRFFC5072View { nav }); } },
|
||||
{ "MAX2837", ui::Color::white(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "Si5351C", ui::Color::white(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "WM8731", ui::Color::white(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
} });
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
@ -188,6 +188,51 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
class DebugLCRView : public View {
|
||||
public:
|
||||
DebugLCRView(NavigationView& nav, char* lcrstring, uint8_t checksum);
|
||||
|
||||
void focus() override;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
private:
|
||||
Text text_lcr1 {
|
||||
{ 16, 32, 208, 8 },
|
||||
""
|
||||
};
|
||||
Text text_lcr2 {
|
||||
{ 16, 32+16, 208, 8 },
|
||||
""
|
||||
};
|
||||
Text text_lcr3 {
|
||||
{ 16, 32+16+16, 208, 8 },
|
||||
""
|
||||
};
|
||||
Text text_lcr4 {
|
||||
{ 16, 32+16+16+16, 208, 8 },
|
||||
""
|
||||
};
|
||||
Text text_lcr5 {
|
||||
{ 16, 32+16+16+16+16, 208, 8 },
|
||||
""
|
||||
};
|
||||
Text text_lcr6 {
|
||||
{ 16, 32+16+16+16+16+16, 208, 8 },
|
||||
""
|
||||
};
|
||||
|
||||
Text text_checksum {
|
||||
{ 16, 32+16+16+16+16+16+32, 208, 8 },
|
||||
""
|
||||
};
|
||||
|
||||
Button button_done {
|
||||
{ 72, 240, 96, 24 },
|
||||
"Done"
|
||||
};
|
||||
};
|
||||
|
||||
class DebugMenuView : public MenuView {
|
||||
public:
|
||||
DebugMenuView(NavigationView& nav);
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "ui_rds.hpp"
|
||||
#include "ui_lcr.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
#include "ui_afsksetup.hpp"
|
||||
#include "ui_debug.hpp"
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
@ -37,6 +39,12 @@
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
//TODO: Repeats
|
||||
//TODO: Shared memory semaphore for doing/done
|
||||
//TODO: Scan
|
||||
//TODO: Text showing status in LCRView
|
||||
//TODO: Checkboxes for AMs
|
||||
|
||||
using namespace hackrf::one;
|
||||
|
||||
namespace ui {
|
||||
@ -49,18 +57,70 @@ LCRView::~LCRView() {
|
||||
transmitter_model.disable();
|
||||
}
|
||||
|
||||
char hexify(char in) {
|
||||
if (in > 9) in += 7;
|
||||
return in + 0x30;
|
||||
}
|
||||
|
||||
void LCRView::paint(Painter& painter) {
|
||||
void LCRView::make_frame() {
|
||||
char eom[3] = { 3, 0, 0 };
|
||||
uint8_t checksum = 0, i;
|
||||
char teststr[16];
|
||||
uint8_t i;
|
||||
uint16_t dp;
|
||||
uint8_t cp, pp, cur_byte, new_byte;
|
||||
|
||||
// Testing: 7 char pad for litterals
|
||||
for (i = 0; i < 5; i++) {
|
||||
while (strlen(litteral[i]) < 7) {
|
||||
strcat(litteral[i], " ");
|
||||
}
|
||||
}
|
||||
|
||||
// Recreate LCR frame
|
||||
memset(lcrframe, 0, 256);
|
||||
lcrframe[0] = 127;
|
||||
lcrframe[1] = 127;
|
||||
lcrframe[2] = 127;
|
||||
lcrframe[3] = 127;
|
||||
lcrframe[4] = 127;
|
||||
lcrframe[5] = 127;
|
||||
lcrframe[6] = 127;
|
||||
lcrframe[7] = 15;
|
||||
strcat(lcrframe, rgsb);
|
||||
strcat(lcrframe, "PA AM=1 AF=\"");
|
||||
strcat(lcrframe, litteral[0]);
|
||||
strcat(lcrframe, "\" CL=0 AM=2 AF=\"");
|
||||
strcat(lcrframe, litteral[1]);
|
||||
strcat(lcrframe, "\" CL=0 AM=3 AF=\"");
|
||||
strcat(lcrframe, litteral[2]);
|
||||
strcat(lcrframe, "\" CL=0 AM=4 AF=\"");
|
||||
strcat(lcrframe, litteral[3]);
|
||||
strcat(lcrframe, "\" CL=0 AM=5 AF=\"");
|
||||
strcat(lcrframe, litteral[4]);
|
||||
strcat(lcrframe, "\" CL=0 EC=A SAB=0"); //TODO: EC=A,J,N
|
||||
|
||||
memcpy(lcrstring, lcrframe, 256);
|
||||
|
||||
//Checksum
|
||||
checksum = 0;
|
||||
i = 7;
|
||||
while (lcrframe[i]) {
|
||||
checksum ^= lcrframe[i];
|
||||
i++;
|
||||
}
|
||||
checksum ^= 3;
|
||||
checksum &= 0x7F;
|
||||
eom[1] = checksum;
|
||||
|
||||
strcat(lcrframe, eom);
|
||||
|
||||
for (dp=0;dp<strlen(lcrframe);dp++) {
|
||||
pp = 0;
|
||||
new_byte = 0;
|
||||
cur_byte = lcrframe[dp];
|
||||
for (cp=0;cp<7;cp++) {
|
||||
if ((cur_byte>>cp)&1) pp++;
|
||||
new_byte |= ((cur_byte>>cp)&1)<<(7-cp);
|
||||
}
|
||||
lcrframe_f[dp] = new_byte|(pp&1);
|
||||
}
|
||||
}
|
||||
|
||||
void LCRView::paint(Painter& painter) {
|
||||
static constexpr Style style_orange {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
@ -102,108 +162,65 @@ void LCRView::paint(Painter& painter) {
|
||||
litteral[3]
|
||||
);
|
||||
|
||||
// Testing: 7 char pad for litterals
|
||||
for (i = 0; i < 4; i++) {
|
||||
while (strlen(litteral[i]) < 7) {
|
||||
strcat(litteral[i], " ");
|
||||
}
|
||||
}
|
||||
offset.y += 40;
|
||||
|
||||
// Recreate LCR frame
|
||||
memset(lcrframe, 0, 256);
|
||||
lcrframe[0] = 127;
|
||||
lcrframe[1] = 127;
|
||||
lcrframe[2] = 127;
|
||||
lcrframe[3] = 127;
|
||||
lcrframe[4] = 127;
|
||||
lcrframe[5] = 127;
|
||||
lcrframe[6] = 127;
|
||||
lcrframe[7] = 15;
|
||||
strcat(lcrframe, rgsb);
|
||||
strcat(lcrframe, "PA AM=1 AF=\"");
|
||||
strcat(lcrframe, litteral[0]);
|
||||
strcat(lcrframe, "\" CL=0 AM=2 AF=\"");
|
||||
strcat(lcrframe, litteral[1]);
|
||||
strcat(lcrframe, "\" CL=0 AM=3 AF=\"");
|
||||
strcat(lcrframe, litteral[2]);
|
||||
strcat(lcrframe, "\" CL=0 AM=4 AF=\"");
|
||||
strcat(lcrframe, litteral[3]);
|
||||
strcat(lcrframe, "\" CL=0 EC=A SAB=0"); //TODO: EC=A,J,N
|
||||
|
||||
//Checksum
|
||||
i = 7;
|
||||
while (lcrframe[i]) {
|
||||
checksum ^= lcrframe[i];
|
||||
i++;
|
||||
}
|
||||
checksum ^= 3;
|
||||
checksum &= 0x7F;
|
||||
eom[1] = checksum;
|
||||
|
||||
strcat(lcrframe, eom);
|
||||
|
||||
for (dp=0;dp<strlen(lcrframe);dp++) {
|
||||
pp = 0;
|
||||
new_byte = 0;
|
||||
cur_byte = lcrframe[dp];
|
||||
for (cp=0;cp<7;cp++) {
|
||||
if ((cur_byte>>cp)&1) pp++;
|
||||
new_byte |= ((cur_byte>>cp)&1)<<(7-cp);
|
||||
}
|
||||
lcrframe[dp] = new_byte|(pp&1);
|
||||
}
|
||||
|
||||
teststr[0] = hexify(eom[1] >> 4);
|
||||
teststr[1] = hexify(eom[1] & 15);
|
||||
teststr[2] = 0;
|
||||
offset.x = 220;
|
||||
painter.draw_string(
|
||||
screen_pos() + offset,
|
||||
style(),
|
||||
teststr
|
||||
style_orange,
|
||||
litteral[4]
|
||||
);
|
||||
}
|
||||
|
||||
void LCRView::updfreq(rf::Frequency f) {
|
||||
char finalstr[9] = {0};
|
||||
transmitter_model.set_tuning_frequency(f);
|
||||
|
||||
auto mhz = to_string_dec_int(f / 1000000, 3);
|
||||
auto hz100 = to_string_dec_int((f / 100) % 10000, 4, '0');
|
||||
|
||||
strcat(finalstr, mhz.c_str());
|
||||
strcat(finalstr, ".");
|
||||
strcat(finalstr, hz100.c_str());
|
||||
|
||||
this->button_setfreq.set_text(finalstr);
|
||||
}
|
||||
|
||||
LCRView::LCRView(
|
||||
NavigationView& nav,
|
||||
TransmitterModel& transmitter_model
|
||||
) : transmitter_model(transmitter_model)
|
||||
{
|
||||
char finalstr[24] = {0};
|
||||
|
||||
static constexpr Style style_val {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::green(),
|
||||
.foreground = Color::black(),
|
||||
};
|
||||
|
||||
transmitter_model.set_modulation(16);
|
||||
transmitter_model.set_tuning_frequency(f);
|
||||
memset(litteral, 0, 4*8);
|
||||
transmitter_model.set_tuning_frequency(persistent_memory::tuned_frequency());
|
||||
memset(litteral, 0, 5*8);
|
||||
memset(rgsb, 0, 5);
|
||||
|
||||
strcpy(rgsb, RGSB_list[0]);
|
||||
|
||||
add_children({ {
|
||||
&text_recap,
|
||||
&button_setrgsb,
|
||||
&button_txsetup,
|
||||
&button_setam_a,
|
||||
&button_setam_b,
|
||||
&button_setam_c,
|
||||
&button_setam_d,
|
||||
&button_setfreq,
|
||||
&button_setbps,
|
||||
&button_setam_e,
|
||||
&text_status,
|
||||
&button_lcrdebug,
|
||||
&button_transmit,
|
||||
&button_transmit_scan,
|
||||
&button_exit
|
||||
} });
|
||||
|
||||
// Recap: tx freq @ bps
|
||||
auto fstr = to_string_dec_int(persistent_memory::tuned_frequency() / 1000, 6);
|
||||
auto bstr = to_string_dec_int(persistent_memory::afsk_bitrate(), 4);
|
||||
|
||||
strcat(finalstr, fstr.c_str());
|
||||
strcat(finalstr, " @ ");
|
||||
strcat(finalstr, bstr.c_str());
|
||||
strcat(finalstr, "bps");
|
||||
|
||||
text_recap.set(finalstr);
|
||||
|
||||
button_transmit.set_style(&style_val);
|
||||
button_transmit_scan.set_style(&style_val);
|
||||
|
||||
button_setrgsb.on_select = [this,&nav](Button&){
|
||||
auto an_view = new AlphanumView { nav, rgsb, 4 };
|
||||
an_view->on_changed = [this](char *rgsb) {
|
||||
@ -211,13 +228,6 @@ LCRView::LCRView(
|
||||
};
|
||||
nav.push(an_view);
|
||||
};
|
||||
button_setfreq.on_select = [this,&nav](Button&){
|
||||
auto new_view = new FrequencyKeypadView { nav, this->transmitter_model.tuning_frequency() };
|
||||
new_view->on_changed = [this](rf::Frequency f) {
|
||||
updfreq(f);
|
||||
};
|
||||
nav.push(new_view);
|
||||
};
|
||||
|
||||
button_setam_a.on_select = [this,&nav](Button&){
|
||||
auto an_view = new AlphanumView { nav, litteral[0], 7 };
|
||||
@ -239,28 +249,46 @@ LCRView::LCRView(
|
||||
an_view->on_changed = [this](char *) {};
|
||||
nav.push(an_view);
|
||||
};
|
||||
button_setbps.on_select = [this](Button&){
|
||||
if (persistent_memory::afsk_bitrate() == 1200) {
|
||||
persistent_memory::set_afsk_bitrate(2400);
|
||||
button_setbps.set_text("2400 bps");
|
||||
} else {
|
||||
persistent_memory::set_afsk_bitrate(1200);
|
||||
button_setbps.set_text("1200 bps");
|
||||
}
|
||||
button_setam_e.on_select = [this,&nav](Button&){
|
||||
auto an_view = new AlphanumView { nav, litteral[4], 7 };
|
||||
an_view->on_changed = [this](char *) {};
|
||||
nav.push(an_view);
|
||||
};
|
||||
|
||||
button_lcrdebug.on_select = [this,&nav](Button&){
|
||||
make_frame();
|
||||
nav.push(new DebugLCRView { nav, lcrstring, checksum });
|
||||
};
|
||||
|
||||
button_transmit.on_select = [this,&transmitter_model](Button&){
|
||||
uint16_t c;
|
||||
ui::Context context;
|
||||
|
||||
make_frame();
|
||||
|
||||
shared_memory.afsk_samples_per_bit = 228000/persistent_memory::afsk_bitrate();
|
||||
shared_memory.afsk_phase_inc_mark = persistent_memory::afsk_mark_freq()*(65536*1024)/228000;
|
||||
shared_memory.afsk_phase_inc_space = persistent_memory::afsk_space_freq()*(65536*1024)/228000;
|
||||
shared_memory.afsk_phase_inc_mark = persistent_memory::afsk_mark_freq()*(65536*1024)/2280;
|
||||
shared_memory.afsk_phase_inc_space = persistent_memory::afsk_space_freq()*(65536*1024)/2280;
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
shared_memory.lcrdata[c] = this->lcrframe[c];
|
||||
}
|
||||
|
||||
shared_memory.afsk_transmit_done = false;
|
||||
shared_memory.afsk_repeat = 5; // DEFAULT
|
||||
|
||||
/*context.message_map[Message::ID::TXDone] = [this](const Message* const p) {
|
||||
text_status.set("Sent ! ");
|
||||
};*/
|
||||
|
||||
text_status.set("Send...");
|
||||
|
||||
transmitter_model.enable();
|
||||
};
|
||||
|
||||
button_txsetup.on_select = [&nav, &transmitter_model](Button&){
|
||||
nav.push(new AFSKSetupView { nav, transmitter_model });
|
||||
};
|
||||
|
||||
button_exit.on_select = [&nav](Button&){
|
||||
nav.pop();
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
LCRView(NavigationView& nav, TransmitterModel& transmitter_model);
|
||||
~LCRView();
|
||||
|
||||
void updfreq(rf::Frequency f);
|
||||
void make_frame();
|
||||
void focus() override;
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
@ -56,12 +56,25 @@ private:
|
||||
"AJ40", "AJ50", "AJ60", "AJ70",
|
||||
"AK10"
|
||||
};
|
||||
char litteral[4][8];
|
||||
char litteral[5][8];
|
||||
char rgsb[5];
|
||||
char lcrstring[256];
|
||||
char checksum = 0;
|
||||
char lcrframe[256];
|
||||
char lcrframe_f[256];
|
||||
rf::Frequency f = 162950000;
|
||||
TransmitterModel& transmitter_model;
|
||||
|
||||
Text text_status {
|
||||
{ 136, 128, 64, 16 },
|
||||
"Ready"
|
||||
};
|
||||
|
||||
Text text_recap {
|
||||
{ 32, 6, 192, 16 },
|
||||
"-"
|
||||
};
|
||||
|
||||
Button button_setrgsb {
|
||||
{ 16, 24, 96, 32 },
|
||||
"Set RGSB"
|
||||
@ -91,21 +104,22 @@ private:
|
||||
"AM 4"
|
||||
};
|
||||
|
||||
Button button_setfreq {
|
||||
{ 8, 232, 96, 32 },
|
||||
"162.9500"
|
||||
Button button_setam_e {
|
||||
{ 16, 64+40+40+40+40, 48, 32 },
|
||||
"AM 5"
|
||||
};
|
||||
Button button_setbps {
|
||||
{ 128, 232, 96, 32 },
|
||||
"1200bps"
|
||||
|
||||
Button button_lcrdebug {
|
||||
{ 152, 224, 64, 32 },
|
||||
"DEBUG"
|
||||
};
|
||||
|
||||
Button button_transmit {
|
||||
{ 8, 270, 48, 32 },
|
||||
{ 24, 270, 48, 32 },
|
||||
"TX"
|
||||
};
|
||||
Button button_transmit_scan {
|
||||
{ 60, 270, 64, 32 },
|
||||
{ 76, 270, 72, 32 },
|
||||
"SCAN TX"
|
||||
};
|
||||
Button button_exit {
|
||||
|
@ -50,10 +50,20 @@ void MenuItemView::paint(Painter& painter) {
|
||||
r,
|
||||
paint_style.background
|
||||
);
|
||||
|
||||
|
||||
ui::Color final_item_color = item.color;
|
||||
|
||||
if (final_item_color.v == paint_style.background.v) final_item_color = paint_style.foreground;
|
||||
|
||||
Style text_style {
|
||||
.font = paint_style.font,
|
||||
.background = paint_style.background,
|
||||
.foreground = final_item_color
|
||||
};
|
||||
|
||||
painter.draw_string(
|
||||
{ static_cast<Coord>(r.pos.x + 8), static_cast<Coord>(r.pos.y + (r.size.h - font_height) / 2) },
|
||||
paint_style,
|
||||
text_style,
|
||||
item.text
|
||||
);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace ui {
|
||||
|
||||
struct MenuItem {
|
||||
std::string text;
|
||||
ui::Color color;
|
||||
std::function<void(void)> on_select;
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,9 @@
|
||||
|
||||
#include "receiver_model.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include "splash.hpp"
|
||||
|
||||
#include "ui_setup.hpp"
|
||||
#include "ui_debug.hpp"
|
||||
@ -98,16 +101,17 @@ void NavigationView::focus() {
|
||||
/* SystemMenuView ********************************************************/
|
||||
|
||||
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
add_items<9>({ {
|
||||
{ "Receiver", [&nav](){ nav.push(new ReceiverView { nav, receiver_model }); } },
|
||||
{ "Capture", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "Analyze", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "RDS TX", [&nav](){ nav.push(new RDSView { nav, transmitter_model }); } },
|
||||
{ "LCR TX", [&nav](){ nav.push(new LCRView { nav, transmitter_model }); } },
|
||||
{ "Setup", [&nav](){ nav.push(new SetupMenuView { nav }); } },
|
||||
{ "About", [&nav](){ nav.push(new AboutView { nav }); } },
|
||||
{ "Debug", [&nav](){ nav.push(new DebugMenuView { nav }); } },
|
||||
{ "HackRF", [&nav](){ nav.push(new HackRFFirmwareView { nav }); } },
|
||||
add_items<10>({ {
|
||||
{ "Play dead", ui::Color::red(), [&nav](){ nav.push(new PlayDeadView { nav }); } },
|
||||
{ "Receiver", ui::Color::white(), [&nav](){ nav.push(new ReceiverView { nav, receiver_model }); } },
|
||||
{ "Capture", ui::Color::white(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "Analyze", ui::Color::white(), [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "RDS TX", ui::Color::orange(), [&nav](){ nav.push(new RDSView { nav, transmitter_model }); } },
|
||||
{ "LCR TX", ui::Color::orange(), [&nav](){ nav.push(new LCRView { nav, transmitter_model }); } },
|
||||
{ "Setup", ui::Color::white(), [&nav](){ nav.push(new SetupMenuView { nav }); } },
|
||||
{ "About", ui::Color::white(), [&nav](){ nav.push(new AboutView { nav }); } },
|
||||
{ "Debug", ui::Color::white(), [&nav](){ nav.push(new DebugMenuView { nav }); } },
|
||||
{ "HackRF", ui::Color::white(), [&nav](){ nav.push(new HackRFFirmwareView { nav }); } },
|
||||
} });
|
||||
}
|
||||
|
||||
@ -143,13 +147,104 @@ SystemView::SystemView(
|
||||
|
||||
// Initial view.
|
||||
// TODO: Restore from non-volatile memory?
|
||||
navigation_view.push(new SystemMenuView { navigation_view });
|
||||
navigation_view.push(new BMPView { navigation_view }); //SystemMenuView
|
||||
}
|
||||
|
||||
Context& SystemView::context() const {
|
||||
return context_;
|
||||
}
|
||||
|
||||
/* ***********************************************************************/
|
||||
|
||||
void BMPView::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
BMPView::BMPView(NavigationView& nav) {
|
||||
add_children({ {
|
||||
&text_info,
|
||||
&button_done
|
||||
} });
|
||||
|
||||
button_done.on_select = [this,&nav](Button&){
|
||||
nav.pop();
|
||||
nav.push(new SystemMenuView { nav });
|
||||
};
|
||||
}
|
||||
|
||||
void BMPView::paint(Painter& painter) {
|
||||
uint32_t pixel_data;
|
||||
uint8_t p, by, c, count;
|
||||
ui::Color linebuffer[185];
|
||||
ui::Coord px = 0, py = 302;
|
||||
ui::Color palette[16];
|
||||
|
||||
// RLE_4 BMP loader with hardcoded size and no delta :(
|
||||
|
||||
pixel_data = splash_bmp[0x0A];
|
||||
p = 0;
|
||||
for (c = 0x36; c < (0x36+(16*4)); c+=4) {
|
||||
palette[p++] = ui::Color(splash_bmp[c+2], splash_bmp[c+1], splash_bmp[c]);
|
||||
}
|
||||
|
||||
do {
|
||||
by = splash_bmp[pixel_data++];
|
||||
if (by) {
|
||||
count = by;
|
||||
by = splash_bmp[pixel_data++];
|
||||
for (c = 0; c < count; c+=2) {
|
||||
linebuffer[px++] = palette[by >> 4];
|
||||
if (px < 185) linebuffer[px++] = palette[by & 15];
|
||||
}
|
||||
if (pixel_data & 1) pixel_data++;
|
||||
} else {
|
||||
by = splash_bmp[pixel_data++];
|
||||
if (by == 0) {
|
||||
portapack::display.render_line({27, py}, 185, linebuffer);
|
||||
py--;
|
||||
px = 0;
|
||||
} else if (by == 1) {
|
||||
break;
|
||||
} else if (by == 2) {
|
||||
// Delta
|
||||
} else {
|
||||
count = by;
|
||||
for (c = 0; c < count; c+=2) {
|
||||
by = splash_bmp[pixel_data++];
|
||||
linebuffer[px++] = palette[by >> 4];
|
||||
if (px < 185) linebuffer[px++] = palette[by & 15];
|
||||
}
|
||||
if (pixel_data & 1) pixel_data++;
|
||||
}
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
/* PlayDeadView **********************************************************/
|
||||
|
||||
void PlayDeadView::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
PlayDeadView::PlayDeadView(NavigationView& nav) {
|
||||
add_children({ {
|
||||
&text_playdead1,
|
||||
&text_playdead2,
|
||||
&button_done,
|
||||
} });
|
||||
|
||||
button_done.on_dir = [this,&nav](Button&, KeyEvent key){
|
||||
sequence = (sequence<<3) | static_cast<std::underlying_type<KeyEvent>::type>(key);
|
||||
};
|
||||
|
||||
button_done.on_select = [this,&nav](Button&){
|
||||
if (sequence == persistent_memory::playdead_sequence())
|
||||
nav.pop();
|
||||
else
|
||||
sequence = 0;
|
||||
};
|
||||
}
|
||||
|
||||
/* HackRFFirmwareView ****************************************************/
|
||||
|
||||
HackRFFirmwareView::HackRFFirmwareView(NavigationView& nav) {
|
||||
|
@ -41,8 +41,8 @@ public:
|
||||
|
||||
private:
|
||||
Text portapack {
|
||||
{ 0, 0, 9 * 8, 1 * 16 },
|
||||
"PortaPack",
|
||||
{ 0, 0, 15 * 8, 1 * 16 },
|
||||
"PortaPack/HAVOC"
|
||||
};
|
||||
};
|
||||
|
||||
@ -70,6 +70,25 @@ public:
|
||||
SystemMenuView(NavigationView& nav);
|
||||
};
|
||||
|
||||
class BMPView : public View {
|
||||
public:
|
||||
BMPView(NavigationView& nav);
|
||||
void paint(Painter& painter) override;
|
||||
void focus() override;
|
||||
|
||||
private:
|
||||
Text text_info {
|
||||
{ 5 * 8, 284, 20 * 8, 16 },
|
||||
"shrbrnd-sig-ftk 2015"
|
||||
};
|
||||
|
||||
Button button_done {
|
||||
{ 240, 0, 1, 1 },
|
||||
""
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class SystemView : public View {
|
||||
public:
|
||||
SystemView(
|
||||
@ -85,6 +104,28 @@ private:
|
||||
Context& context_;
|
||||
};
|
||||
|
||||
class PlayDeadView : public View {
|
||||
public:
|
||||
PlayDeadView(NavigationView& nav);
|
||||
void focus() override;
|
||||
|
||||
private:
|
||||
uint32_t sequence = 0;
|
||||
Text text_playdead1 {
|
||||
{ 6 * 8, 7 * 16, 14 * 8, 16 },
|
||||
"Firmware error"
|
||||
};
|
||||
Text text_playdead2 {
|
||||
{ 6 * 8, 9 * 16, 16 * 8, 16 },
|
||||
"0x1400_0000 : 2C"
|
||||
};
|
||||
|
||||
Button button_done {
|
||||
{ 240, 0, 1, 1 },
|
||||
""
|
||||
};
|
||||
};
|
||||
|
||||
class HackRFFirmwareView : public View {
|
||||
public:
|
||||
HackRFFirmwareView(NavigationView& nav);
|
||||
|
@ -26,8 +26,10 @@
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
|
||||
#include <math.h>
|
||||
#include <cstring>
|
||||
|
||||
using namespace lpc43xx;
|
||||
using namespace portapack;
|
||||
|
||||
namespace ui {
|
||||
|
||||
@ -184,11 +186,56 @@ bool SetTouchCalibView::on_touch(const TouchEvent event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SetPlayDeadView::SetPlayDeadView(NavigationView& nav) {
|
||||
add_children({{
|
||||
&text_sequence,
|
||||
&button_enter,
|
||||
&button_cancel
|
||||
}});
|
||||
|
||||
button_enter.on_select = [this,&nav](Button&){
|
||||
if (entermode == false) {
|
||||
sequence = 0;
|
||||
memset(sequence_txt,0,11);
|
||||
text_sequence.set("");
|
||||
keycount = 0;
|
||||
entermode = true;
|
||||
button_cancel.hidden(true);
|
||||
} else {
|
||||
persistent_memory::set_playdead_sequence(sequence);
|
||||
nav.pop();
|
||||
}
|
||||
};
|
||||
button_enter.on_dir = [this,&nav](Button&, KeyEvent key){
|
||||
if ((entermode == true) && (keycount < 10)) {
|
||||
key_code = static_cast<std::underlying_type<KeyEvent>::type>(key);
|
||||
if (key_code == 0)
|
||||
sequence_txt[keycount] = 'R';
|
||||
else if (key_code == 1)
|
||||
sequence_txt[keycount] = 'L';
|
||||
else if (key_code == 2)
|
||||
sequence_txt[keycount] = 'D';
|
||||
else if (key_code == 3)
|
||||
sequence_txt[keycount] = 'U';
|
||||
text_sequence.set(sequence_txt);
|
||||
sequence = (sequence<<3) | key_code;
|
||||
keycount++;
|
||||
|
||||
}
|
||||
};
|
||||
button_cancel.on_select = [&nav](Button&){ nav.pop(); };
|
||||
}
|
||||
|
||||
void SetPlayDeadView::focus() {
|
||||
button_enter.focus();
|
||||
}
|
||||
|
||||
SetupMenuView::SetupMenuView(NavigationView& nav) {
|
||||
add_items<3>({ {
|
||||
{ "Date/Time", [&nav](){ nav.push(new SetDateTimeView { nav }); } },
|
||||
{ "Frequency Correction", [&nav](){ nav.push(new SetFrequencyCorrectionView { nav }); } },
|
||||
{ "Touch", [&nav](){ nav.push(new SetTouchCalibView { nav }); } },
|
||||
add_items<4>({ {
|
||||
{ "Date/Time", ui::Color::white(), [&nav](){ nav.push(new SetDateTimeView { nav }); } },
|
||||
{ "Frequency correction", ui::Color::white(), [&nav](){ nav.push(new SetFrequencyCorrectionView { nav }); } },
|
||||
{ "Touch", ui::Color::white(), [&nav](){ nav.push(new SetTouchCalibView { nav }); } },
|
||||
{ "Play dead", ui::Color::white(), [&nav](){ nav.push(new SetPlayDeadView { nav }); } },
|
||||
} });
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_menu.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@ -190,7 +191,7 @@ private:
|
||||
|
||||
Text text_firmware {
|
||||
{ 0, 128, 240, 16 },
|
||||
"Firmware Version git-??????",
|
||||
"Firmware Version HAVOC 0.10",
|
||||
};
|
||||
|
||||
Text text_cpld_hackrf {
|
||||
@ -237,6 +238,31 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
class SetPlayDeadView : public View {
|
||||
public:
|
||||
SetPlayDeadView(NavigationView& nav);
|
||||
void focus() override;
|
||||
private:
|
||||
bool entermode = false;
|
||||
uint32_t sequence = 0;
|
||||
uint8_t keycount, key_code;
|
||||
char sequence_txt[11];
|
||||
|
||||
Text text_sequence {
|
||||
{ 64, 32, 14 * 8, 16 },
|
||||
"Enter sequence",
|
||||
};
|
||||
|
||||
Button button_enter {
|
||||
{ 16, 192, 96, 24 },
|
||||
"Enter"
|
||||
};
|
||||
Button button_cancel {
|
||||
{ 128, 192, 96, 24 },
|
||||
"Cancel"
|
||||
};
|
||||
};
|
||||
|
||||
class SetupMenuView : public MenuView {
|
||||
public:
|
||||
SetupMenuView(NavigationView& nav);
|
||||
|
@ -762,12 +762,6 @@ private:
|
||||
|
||||
class LCRFSKProcessor : public BasebandProcessor {
|
||||
public:
|
||||
void BasebandProcessor() {
|
||||
afsk_samples_per_bit = shared_memory.afsk_samples_per_bit;
|
||||
phase_inc_mark = shared_memory.afsk_phase_inc_mark;
|
||||
phase_inc_space = shared_memory.afsk_phase_inc_space;
|
||||
}
|
||||
|
||||
void execute(buffer_c8_t buffer) override {
|
||||
|
||||
for (size_t i = 0; i<buffer.count; i++) {
|
||||
@ -776,14 +770,22 @@ public:
|
||||
if (s >= 9) {
|
||||
s = 0;
|
||||
|
||||
if (sample_count >= afsk_samples_per_bit) {
|
||||
cur_byte = shared_memory.lcrdata[byte_pos];
|
||||
if (sample_count >= shared_memory.afsk_samples_per_bit) {
|
||||
if (shared_memory.afsk_transmit_done == false)
|
||||
cur_byte = shared_memory.lcrdata[byte_pos];
|
||||
if (!cur_byte) {
|
||||
bit_pos = 0;
|
||||
byte_pos = 0;
|
||||
cur_byte = shared_memory.lcrdata[0];
|
||||
if (shared_memory.afsk_repeat) {
|
||||
shared_memory.afsk_repeat--;
|
||||
bit_pos = 0;
|
||||
byte_pos = 0;
|
||||
cur_byte = shared_memory.lcrdata[0];
|
||||
} else {
|
||||
shared_memory.afsk_transmit_done = true; // TODO: Remove, unused
|
||||
//shared_memory.application_queue.push(&message);
|
||||
cur_byte = 0;
|
||||
}
|
||||
}
|
||||
cur_byte = (0x55<<1); //DEBUG
|
||||
//cur_byte = (0x55<<1); //DEBUG
|
||||
|
||||
//SdddddddpD
|
||||
//0dddddddp1
|
||||
@ -808,9 +810,9 @@ public:
|
||||
sample_count++;
|
||||
}
|
||||
if (cur_bit)
|
||||
aphase += phase_inc_mark; //(353205)
|
||||
aphase += shared_memory.afsk_phase_inc_mark; //(353205)
|
||||
else
|
||||
aphase += phase_inc_space; //(647542)
|
||||
aphase += shared_memory.afsk_phase_inc_space; //(647542)
|
||||
|
||||
sample = sintab[(aphase & 0x03FF0000)>>16];
|
||||
} else {
|
||||
@ -833,8 +835,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t afsk_samples_per_bit;
|
||||
uint32_t phase_inc_mark, phase_inc_space;
|
||||
int8_t re, im;
|
||||
uint8_t s;
|
||||
uint8_t bit_pos, byte_pos;
|
||||
@ -844,6 +844,7 @@ private:
|
||||
uint32_t sample_count;
|
||||
uint32_t aphase, phase, sphase;
|
||||
int32_t sample, sig, frq;
|
||||
TXDoneMessage message;
|
||||
};
|
||||
|
||||
static BasebandProcessor* baseband_processor { nullptr };
|
||||
|
@ -241,6 +241,11 @@ void ILI9341::fill_rectangle(ui::Rect r, const ui::Color c) {
|
||||
}
|
||||
}
|
||||
|
||||
void ILI9341::render_line(const ui::Point p, const uint8_t count, const ui::Color* line_buffer) {
|
||||
lcd_start_ram_write(p, { count, 1 });
|
||||
io.lcd_write_pixels(line_buffer, count);
|
||||
}
|
||||
|
||||
void ILI9341::draw_line(const ui::Point start, const ui::Point end, const ui::Color color) {
|
||||
int x0 = start.x;
|
||||
int y0 = start.y;
|
||||
|
@ -54,6 +54,7 @@ public:
|
||||
);
|
||||
|
||||
void draw_pixel(const ui::Point p, const ui::Color color);
|
||||
void render_line(const ui::Point p, const uint8_t count, const ui::Color* line_buffer);
|
||||
|
||||
template<size_t N>
|
||||
void draw_pixels(
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
FSKConfiguration = 6,
|
||||
FSKPacket = 7,
|
||||
TestResults = 8,
|
||||
TXDone = 9,
|
||||
MAX
|
||||
};
|
||||
|
||||
@ -251,6 +252,14 @@ public:
|
||||
FSKPacket packet;
|
||||
};
|
||||
|
||||
class TXDoneMessage : public Message {
|
||||
public:
|
||||
TXDoneMessage(
|
||||
) : Message { ID::TXDone }
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class MessageHandlerMap {
|
||||
public:
|
||||
using MessageHandler = std::function<void(const Message* const p)>;
|
||||
|
@ -55,14 +55,14 @@ using ppb_range_t = range_t<ppb_t>;
|
||||
constexpr ppb_range_t ppb_range { -99000, 99000 };
|
||||
constexpr ppb_t ppb_reset_value { 0 };
|
||||
|
||||
using afsk_freq_range_t = range_t<int16_t>;
|
||||
constexpr afsk_freq_range_t afsk_freq_range { 100, 32000 };
|
||||
constexpr int16_t afsk_mark_reset_value { 1200 };
|
||||
constexpr int16_t afsk_space_reset_value { 2200 };
|
||||
using afsk_freq_range_t = range_t<int32_t>;
|
||||
constexpr afsk_freq_range_t afsk_freq_range { 1, 60 };
|
||||
constexpr int32_t afsk_mark_reset_value { 12 };
|
||||
constexpr int32_t afsk_space_reset_value { 22 };
|
||||
|
||||
using afsk_bitrate_range_t = range_t<int16_t>;
|
||||
using afsk_bitrate_range_t = range_t<int32_t>;
|
||||
constexpr afsk_bitrate_range_t afsk_bitrate_range { 600, 9600 };
|
||||
constexpr int16_t afsk_bitrate_reset_value { 1200 };
|
||||
constexpr int32_t afsk_bitrate_reset_value { 1200 };
|
||||
|
||||
/* struct must pack the same way on M4 and M0 cores. */
|
||||
struct data_t {
|
||||
@ -71,10 +71,14 @@ struct data_t {
|
||||
int32_t correction_ppb;
|
||||
|
||||
// AFSK modem
|
||||
int16_t afsk_mark_freq;
|
||||
int16_t afsk_space_freq;
|
||||
int16_t afsk_bitrate;
|
||||
int32_t afsk_mark_freq;
|
||||
int32_t afsk_space_freq;
|
||||
int32_t afsk_bitrate;
|
||||
uint8_t afsk_config;
|
||||
|
||||
// Play dead unlock
|
||||
bool playing_dead;
|
||||
uint32_t playdead_sequence;
|
||||
};
|
||||
|
||||
static_assert(sizeof(data_t) <= 0x100, "Persistent memory structure too large for VBAT-maintained region");
|
||||
@ -99,30 +103,30 @@ void set_correction_ppb(const ppb_t new_value) {
|
||||
data->correction_ppb = ppb_range.clip(new_value);
|
||||
}
|
||||
|
||||
int16_t afsk_mark_freq() {
|
||||
int32_t afsk_mark_freq() {
|
||||
afsk_freq_range.reset_if_outside(data->afsk_mark_freq, afsk_mark_reset_value);
|
||||
return data->correction_ppb;
|
||||
return data->afsk_mark_freq;
|
||||
}
|
||||
|
||||
void set_afsk_mark(const int16_t new_value) {
|
||||
void set_afsk_mark(const int32_t new_value) {
|
||||
data->afsk_mark_freq = afsk_freq_range.clip(new_value);
|
||||
}
|
||||
|
||||
int16_t afsk_space_freq() {
|
||||
int32_t afsk_space_freq() {
|
||||
afsk_freq_range.reset_if_outside(data->afsk_space_freq, afsk_space_reset_value);
|
||||
return data->correction_ppb;
|
||||
return data->afsk_space_freq;
|
||||
}
|
||||
|
||||
void set_afsk_space(const int16_t new_value) {
|
||||
void set_afsk_space(const int32_t new_value) {
|
||||
data->afsk_space_freq = afsk_freq_range.clip(new_value);
|
||||
}
|
||||
|
||||
int16_t afsk_bitrate() {
|
||||
int32_t afsk_bitrate() {
|
||||
afsk_bitrate_range.reset_if_outside(data->afsk_bitrate, afsk_bitrate_reset_value);
|
||||
return data->correction_ppb;
|
||||
return data->afsk_bitrate;
|
||||
}
|
||||
|
||||
void set_afsk_bitrate(const int16_t new_value) {
|
||||
void set_afsk_bitrate(const int32_t new_value) {
|
||||
data->afsk_bitrate = afsk_bitrate_range.clip(new_value);
|
||||
}
|
||||
|
||||
@ -134,5 +138,21 @@ void set_afsk_config(const uint8_t new_value) {
|
||||
data->afsk_config = new_value;
|
||||
}
|
||||
|
||||
bool playing_dead() {
|
||||
return data->playing_dead;
|
||||
}
|
||||
|
||||
void set_playing_dead(const bool new_value) {
|
||||
data->playing_dead = new_value;
|
||||
}
|
||||
|
||||
uint32_t playdead_sequence() {
|
||||
return data->playdead_sequence;
|
||||
}
|
||||
|
||||
void set_playdead_sequence(const uint32_t new_value) {
|
||||
data->playdead_sequence = new_value;
|
||||
}
|
||||
|
||||
} /* namespace persistent_memory */
|
||||
} /* namespace portapack */
|
||||
|
@ -37,18 +37,24 @@ void set_tuned_frequency(const rf::Frequency new_value);
|
||||
ppb_t correction_ppb();
|
||||
void set_correction_ppb(const ppb_t new_value);
|
||||
|
||||
int16_t afsk_mark_freq();
|
||||
void set_afsk_mark(const int16_t new_value);
|
||||
int32_t afsk_mark_freq();
|
||||
void set_afsk_mark(const int32_t new_value);
|
||||
|
||||
int16_t afsk_space_freq();
|
||||
void set_afsk_space(const int16_t new_value);
|
||||
int32_t afsk_space_freq();
|
||||
void set_afsk_space(const int32_t new_value);
|
||||
|
||||
int16_t afsk_bitrate();
|
||||
void set_afsk_bitrate(const int16_t new_value);
|
||||
int32_t afsk_bitrate();
|
||||
void set_afsk_bitrate(const int32_t new_value);
|
||||
|
||||
uint8_t afsk_config();
|
||||
void set_afsk_config(const uint8_t new_value);
|
||||
|
||||
bool playing_dead();
|
||||
void set_playing_dead(const bool new_value);
|
||||
|
||||
uint32_t playdead_sequence();
|
||||
void set_playdead_sequence(const uint32_t new_value);
|
||||
|
||||
} /* namespace persistent_memory */
|
||||
} /* namespace portapack */
|
||||
|
||||
|
@ -47,6 +47,8 @@ struct SharedMemory {
|
||||
uint32_t afsk_samples_per_bit;
|
||||
uint32_t afsk_phase_inc_mark;
|
||||
uint32_t afsk_phase_inc_space;
|
||||
uint8_t afsk_repeat;
|
||||
bool afsk_transmit_done;
|
||||
};
|
||||
|
||||
extern SharedMemory& shared_memory;
|
||||
|
@ -401,6 +401,11 @@ bool Button::on_key(const KeyEvent key) {
|
||||
on_select(*this);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if( on_dir ) {
|
||||
on_dir(*this, key);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -212,6 +212,7 @@ private:
|
||||
class Button : public Widget {
|
||||
public:
|
||||
std::function<void(Button&)> on_select;
|
||||
std::function<void(Button&,KeyEvent)> on_dir;
|
||||
|
||||
Button(
|
||||
Rect parent_rect,
|
||||
|
Loading…
Reference in New Issue
Block a user