Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
934f4b07c4 | ||
|
|
bf3f9cfe75 | ||
|
|
3c304b9fe3 | ||
|
|
2d765f8120 | ||
|
|
e4c9287af3 | ||
|
|
15c6285639 | ||
|
|
d525f9a9b3 | ||
|
|
89f953c75e | ||
|
|
0bda172f5e | ||
|
|
086f3098c4 | ||
|
|
7ca0d1eb3d | ||
|
|
c232287023 | ||
|
|
222e2c8530 | ||
|
|
c406e7b631 | ||
|
|
7426c7a7a5 | ||
|
|
4d839ea44e | ||
|
|
07e9b50abe | ||
|
|
a5721c5444 | ||
|
|
64bc4d4068 | ||
|
|
0afc88ea7b | ||
|
|
4b4aab640a | ||
|
|
cc75ed5eee | ||
|
|
43870e97bc | ||
|
|
0e75cfea12 | ||
|
|
993396a048 | ||
|
|
cb0a4da7e1 | ||
|
|
81d5ac4923 | ||
|
|
ef0336ac4f | ||
|
|
e3533594de | ||
|
|
db9d80dc0c | ||
|
|
b2286eec7e | ||
|
|
e737d3c678 | ||
|
|
7fa92868d7 | ||
|
|
79700fcddd | ||
|
|
bf01462bd6 | ||
|
|
eab4567ae8 | ||
|
|
dfe1ddfa9f | ||
|
|
38b6f334b2 | ||
|
|
92d9b677f7 | ||
|
|
8a6e04fc0b | ||
|
|
9446e64784 | ||
|
|
74f76348b3 | ||
|
|
a1a417d94b | ||
|
|
1c11a25571 | ||
|
|
eb3b7ac585 | ||
|
|
d7f3539cd9 | ||
|
|
853912733e | ||
|
|
21b69e1793 | ||
|
|
4b33d98cf8 | ||
|
|
2e65ce8f85 | ||
|
|
2437a510ed | ||
|
|
4dd73d201b | ||
|
|
4acaeea698 | ||
|
|
4e850df0fc | ||
|
|
f58b6b95c0 | ||
|
|
fd55c8e8e7 | ||
|
|
ce29411aa4 | ||
|
|
ae569cbd65 | ||
|
|
0d5798ac30 | ||
|
|
2cd2443eb2 | ||
|
|
e8792e446a | ||
|
|
59b310dff5 | ||
|
|
52b951f705 | ||
|
|
b6aa8e9b01 | ||
|
|
29457f0e46 | ||
|
|
7ef617946b | ||
|
|
b539b17a50 | ||
|
|
2cdd11d96a | ||
|
|
0d64da4a23 | ||
|
|
477635a100 | ||
|
|
6c7dfbfc89 | ||
|
|
589611c8bd | ||
|
|
9a1d6aabe4 | ||
|
|
25a660138b | ||
|
|
f2886715ce | ||
|
|
38a392e3ea | ||
|
|
defdd57ea3 | ||
|
|
acbb100d64 | ||
|
|
9b010686b6 | ||
|
|
9aa2d17753 | ||
|
|
1ce4c402e0 | ||
|
|
decce5cc17 | ||
|
|
125aa75553 | ||
|
|
687b1187d1 | ||
|
|
a467e74a78 | ||
|
|
e889a54e55 | ||
|
|
f501955dfd | ||
|
|
cfd1fe2b18 | ||
|
|
c80ea840d7 | ||
|
|
6e590d0764 | ||
|
|
9f72e62db7 | ||
|
|
f3bf8dbd2f | ||
|
|
739218116d | ||
|
|
bdeab6428b | ||
|
|
619fa00967 | ||
|
|
9f0b8852f6 | ||
|
|
e87a088842 | ||
|
|
4c60aed563 |
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -19,5 +19,11 @@ Steps to reproduce the behavior:
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Affected versions**
|
||||
Please try to reproduce the problem, and write any difference related with the Expected behavior, on the maximum number of versions:
|
||||
* Latest Stable Release
|
||||
* Original PortaPack (if possible; this firmware is also included inside the Release package)
|
||||
* Any previous version (if possible; i.e.: you remember this working on a previous Release)
|
||||
|
||||
**Additional**
|
||||
If the bug is difficult to explain, additionally to the text please include images and videos.
|
||||
|
||||
6
.gitignore
vendored
@@ -13,7 +13,6 @@
|
||||
/sdcard/FREQMAN/BHT*
|
||||
/sdcard/FREQMAN/R.TXT
|
||||
/sdcard/FREQMAN/XXX.TXT
|
||||
/sdcard/WAV/*
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
@@ -61,7 +60,6 @@ CMakeFiles/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# Host OS turds
|
||||
# Host OS leftovers
|
||||
.DS_Store
|
||||
/firmware/CMakeCache.txt
|
||||
/sdcard/ADSB/airlines.txt
|
||||
/firmware/CMakeCache.txt
|
||||
63
README.md
@@ -1,25 +1,50 @@
|
||||
## Fork of the unofficial HAVOC
|
||||
# PortaPack Mayhem
|
||||
|
||||
Keeping the latest release files and all features I found, and possible my own features in the future, around here. Check Releases
|
||||
[](https://travis-ci.com/eried/portapack-mayhem) [](https://app.buddy.works/eried/portapack/pipelines/pipeline/252276) [](https://codescene.io/projects/8381) [](https://hub.docker.com/r/eried/portapack)
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CBPQA4HRRPJQ6&source=url)
|
||||
This is a fork of the [Havoc](https://github.com/furrtek/portapack-havoc/), which was a fork of the [PortaPack](https://github.com/sharebrained/portapack-hackrf) firmware, an add-on for the [HackRF](http://greatscottgadgets.com/hackrf/). A fork means it is a derivated, so it is basically a clone that has extra features and fixes over the older versions.
|
||||
|
||||
I only have this [Portapack H2+HackRF+battery](https://s.click.aliexpress.com/e/_dSMPvNo), so that's the version I'll be using for testing the releases before I post them here. BTW, if you have the same H2 (I know... I know it is a *dirty* clone) you could print my case:
|
||||
[](https://www.thingiverse.com/thing:4260973)
|
||||
[<img src="https://raw.githubusercontent.com/wiki/eried/portapack-mayhem/img/hw_overview_h2_front.png" height="400">](https://github.com/eried/portapack-mayhem/wiki/Hardware-overview) [<img src="https://raw.githubusercontent.com/wiki/eried/portapack-mayhem/img/hw_overview_h2_inside.png" height="400">](https://github.com/eried/portapack-mayhem/wiki/Hardware-overview#portapack-internals)
|
||||
|
||||
<details>
|
||||
<summary>More details about the H2 case</summary>
|
||||
|
||||
[STL files](https://www.thingiverse.com/thing:4260973)
|
||||
*[PortaPack H2](https://s.click.aliexpress.com/e/_dSMPvNo) (clone) with a custom [3d printed case](https://github.com/eried/portapack-mayhem/wiki/H2-Enclosure)*
|
||||
|
||||
|
||||
</details>
|
||||
## FAQ
|
||||
|
||||
<details>
|
||||
<summary>Printed magnetic cover for the H2 case</summary>
|
||||
|
||||
[](https://www.thingiverse.com/thing:4278961)
|
||||
|
||||
[STL files](https://www.thingiverse.com/thing:4278961)
|
||||
|
||||
</details>
|
||||
The intention of the current repository is to try to get all the latest features and cleanest documentation for them, embracing any colaboration. To clarify any basic question, please read the following common ones:
|
||||
|
||||
### Does it work on H1/H2 PortaPack?
|
||||
|
||||
Yes, those are the [same](https://github.com/eried/portapack-mayhem/wiki/First-steps). The one I am using to test all changes is this [Portapack H2+HackRF+battery](https://s.click.aliexpress.com/e/_dSMPvNo), which is a clone that includes everything you need. Sadly, the people making the H2 never published the updated PCB, so it is not "optimal" for the community.
|
||||
|
||||
### Where is the latest firmware?
|
||||
|
||||
The current stable release is on the [Release](https://github.com/eried/portapack-mayhem/releases/latest) page. Follow the instructions you can find in the release description.
|
||||
|
||||
There is also [nightly builds](https://github.com/eried/portapack-mayhem/releases/tag/nightly) generated frequently, but these may contain incomplete functionality.
|
||||
|
||||
### Is this the newest firmware for my PortaPack?
|
||||
Probably **YES**.
|
||||
|
||||
### Which one is actually the newest?
|
||||
There is a lot of confusion of which is the latest version because no old version used any actual "version number". Additionally, since the files were distributed on facebook groups, github issue links and similar temporal sources, then there was no central location for them.
|
||||
|
||||
This fork (**Mayhem**) uses *major.minor.release* [semantic versioning](https://en.wikipedia.org/wiki/Software_versioning), so you can always compare your current version with the latest from [Releases](https://github.com/eried/portapack-mayhem/releases/latest).
|
||||
|
||||
### What about Havoc/GridRF/jamesshao8/jboone's?
|
||||
* jboone's PortaPack: the [vainilla](https://en.wikipedia.org/wiki/Vanilla_software) experience
|
||||
* Havoc: It was the most popular fork of jboone's PortaPack, right now is readonly so it is not being developed
|
||||
* jamesshao8: He keeps his own version of the fork, while not attached as a fork to anything
|
||||
* GridRF: They sell PortaPack clones with their own firmware based on a old version, which has no sourcecode available
|
||||
|
||||
### How can I colaborate
|
||||
You can write [documentation](https://github.com/eried/portapack-mayhem/wiki), fix bugs and [answer issues](https://github.com/eried/portapack-mayhem/issues) or add new functionality. Please check the following [guide](https://github.com/eried/portapack-mayhem/wiki/How-to-colaborate) with details.
|
||||
|
||||
Consider that the hardware and firmware has been created and maintain by a [lot](https://github.com/mossmann/hackrf/graphs/contributors) of [people](https://github.com/eried/portapack-mayhem/graphs/contributors), so always try colaborating your time and effort first.
|
||||
|
||||
As a last option, if you want to send money directly to me for getting more boards, antennas and such, please use:
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CBPQA4HRRPJQ6&source=url)
|
||||
|
||||
### What if I need help?
|
||||
First, check the [documentation](https://github.com/eried/portapack-mayhem/wiki). If you find a bug or you think the problem is related to the current repository, please open an [issue](https://github.com/eried/portapack-mayhem/issues/new/choose).
|
||||
|
||||
You can reach the [official community](https://www.facebook.com/groups/177623356165819) in Facebook.
|
||||
|
||||
12
dockerfile
@@ -14,10 +14,20 @@ COPY ./ /havocsrc
|
||||
|
||||
#Fetch dependencies from APT
|
||||
RUN apt-get update && \
|
||||
apt-get install -y tar wget dfu-util cmake python python-pip && \
|
||||
apt-get install -y tar wget dfu-util cmake python bzip2 curl && \
|
||||
apt-get -qy autoremove
|
||||
|
||||
#Install current pip from PyPa
|
||||
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
|
||||
python get-pip.py
|
||||
|
||||
#Fetch additional dependencies from Python 2.x pip
|
||||
RUN pip install pyyaml
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python && \
|
||||
ln -s /usr/bin/pip3 /usr/bin/pip
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
ENV LC_ALL C.UTF-8
|
||||
|
||||
#Grab the GNU ARM toolchain from arm.com
|
||||
#Then extract contents to /opt/build/armbin/
|
||||
|
||||
@@ -11,10 +11,20 @@ WORKDIR /havoc/firmware
|
||||
|
||||
# Fetch dependencies from APT
|
||||
RUN apt-get update && \
|
||||
apt-get install -y git tar wget dfu-util cmake python3 python-pip ccache && \
|
||||
apt-get install -y git tar wget dfu-util cmake python3 ccache bzip2 curl && \
|
||||
apt-get -qy autoremove
|
||||
|
||||
#Install current pip from PyPa
|
||||
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
|
||||
python3 get-pip.py
|
||||
|
||||
#Fetch additional dependencies from Python 3.x pip
|
||||
RUN pip install pyyaml
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python && \
|
||||
ln -s /usr/bin/pip3 /usr/bin/pip
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
ENV LC_ALL C.UTF-8
|
||||
|
||||
# Grab the GNU ARM toolchain from arm.com
|
||||
# Then extract contents to /opt/build/armbin/
|
||||
|
||||
@@ -82,7 +82,7 @@ void GpsSimAppView::on_file_changed(std::filesystem::path new_file_path) {
|
||||
auto file_size = data_file.size();
|
||||
auto duration = (file_size * 1000) / (1 * 2 * sample_rate);
|
||||
|
||||
progressbar.set_max(file_size);
|
||||
progressbar.set_max(file_size / 1024);
|
||||
text_filename.set(file_path.filename().string().substr(0, 12));
|
||||
text_duration.set(to_string_time_ms(duration));
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@ ReplayAppView::~ReplayAppView() {
|
||||
}
|
||||
|
||||
void ReplayAppView::on_hide() {
|
||||
stop(false);
|
||||
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
|
||||
// it's being shown or hidden.
|
||||
waterfall.on_hide();
|
||||
|
||||
@@ -207,8 +207,8 @@ SoundBoardView::SoundBoardView(
|
||||
&menu_view,
|
||||
&text_empty,
|
||||
&options_tone_key,
|
||||
&text_title,
|
||||
&text_duration,
|
||||
//&text_title,
|
||||
//&text_duration,
|
||||
&progressbar,
|
||||
&check_loop,
|
||||
&check_random,
|
||||
@@ -217,7 +217,7 @@ SoundBoardView::SoundBoardView(
|
||||
|
||||
refresh_list();
|
||||
|
||||
text_title.set(to_string_dec_uint(file_list.size()));
|
||||
//text_title.set(to_string_dec_uint(file_list.size()));
|
||||
|
||||
tone_keys_populate(options_tone_key);
|
||||
options_tone_key.set_selected_index(0);
|
||||
|
||||
@@ -80,12 +80,12 @@ private:
|
||||
void on_select_entry();
|
||||
|
||||
Labels labels {
|
||||
{ { 0, 20 * 8 + 4 }, "Title:", Color::light_grey() },
|
||||
{ { 0, 23 * 8 }, "Key:", Color::light_grey() }
|
||||
//{ { 0, 20 * 8 + 4 }, "Title:", Color::light_grey() },
|
||||
{ { 0, 180 }, "Key:", Color::light_grey() }
|
||||
};
|
||||
|
||||
MenuView menu_view {
|
||||
{ 0, 2 * 8, 240, 20 * 8 },
|
||||
{ 0, 0, 240, 175 },
|
||||
true
|
||||
};
|
||||
Text text_empty {
|
||||
@@ -93,22 +93,22 @@ private:
|
||||
"Empty directory !",
|
||||
};
|
||||
|
||||
Text text_title {
|
||||
/*Text text_title {
|
||||
{ 6 * 8, 20 * 8 + 4, 15 * 8, 16 }
|
||||
};
|
||||
};*/
|
||||
|
||||
Text text_duration {
|
||||
/*Text text_duration {
|
||||
{ 22 * 8, 20 * 8 + 4, 6 * 8, 16 }
|
||||
};
|
||||
};*/
|
||||
|
||||
OptionsField options_tone_key {
|
||||
{ 4 * 8, 23 * 8 },
|
||||
{ 32 , 180 },
|
||||
18,
|
||||
{ }
|
||||
};
|
||||
|
||||
Checkbox check_loop {
|
||||
{ 8, 25 * 8 + 4 },
|
||||
{ 0, 25 * 8 + 4 },
|
||||
4,
|
||||
"Loop"
|
||||
};
|
||||
|
||||
@@ -321,37 +321,39 @@ void DebugControlsView::focus() {
|
||||
|
||||
DebugPeripheralsMenuView::DebugPeripheralsMenuView(NavigationView& nav) {
|
||||
add_items({
|
||||
{ "RFFC5072", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
{ "RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav](){ nav.push<RegistersView>(
|
||||
"RFFC5072", RegistersWidgetConfig { 31, 16 },
|
||||
[](const size_t register_number) { return radio::debug::first_if::register_read(register_number); }
|
||||
); } },
|
||||
{ "MAX2837", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
{ "MAX2837", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav](){ nav.push<RegistersView>(
|
||||
"MAX2837", RegistersWidgetConfig { 32, 10 },
|
||||
[](const size_t register_number) { return radio::debug::second_if::register_read(register_number); }
|
||||
); } },
|
||||
{ "Si5351C", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
{ "Si5351C", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav](){ nav.push<RegistersView>(
|
||||
"Si5351C", RegistersWidgetConfig { 96, 8 },
|
||||
[](const size_t register_number) { return portapack::clock_generator.read_register(register_number); }
|
||||
); } },
|
||||
{ audio::debug::codec_name(), ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
{ audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav](){ nav.push<RegistersView>(
|
||||
audio::debug::codec_name(), RegistersWidgetConfig { audio::debug::reg_count(), audio::debug::reg_bits() },
|
||||
[](const size_t register_number) { return audio::debug::reg_read(register_number); }
|
||||
); } },
|
||||
});
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
set_max_rows(2); // allow wider buttons
|
||||
}
|
||||
|
||||
/* DebugMenuView *********************************************************/
|
||||
|
||||
DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
add_items({
|
||||
{ "Memory", ui::Color::white(), nullptr, [&nav](){ nav.push<DebugMemoryView>(); } },
|
||||
//{ "..", ui::Color::light_grey(),&bitmap_icon_previous, [&nav](){ nav.pop(); } },
|
||||
{ "Memory", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav](){ nav.push<DebugMemoryView>(); } },
|
||||
//{ "Radio State", ui::Color::white(), nullptr, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{ "SD Card", ui::Color::white(), nullptr, [&nav](){ nav.push<SDCardDebugView>(); } },
|
||||
{ "Peripherals", ui::Color::white(), nullptr, [&nav](){ nav.push<DebugPeripheralsMenuView>(); } },
|
||||
{ "Temperature", ui::Color::white(), nullptr, [&nav](){ nav.push<TemperatureView>(); } },
|
||||
{ "Controls", ui::Color::white(), nullptr, [&nav](){ nav.push<DebugControlsView>(); } }, });
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
{ "SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [&nav](){ nav.push<SDCardDebugView>(); } },
|
||||
{ "Peripherals", ui::Color::dark_cyan(), &bitmap_icon_peripherals, [&nav](){ nav.push<DebugPeripheralsMenuView>(); } },
|
||||
{ "Temperature", ui::Color::dark_cyan(), &bitmap_icon_temperature, [&nav](){ nav.push<TemperatureView>(); } },
|
||||
{ "Buttons test", ui::Color::dark_cyan(), &bitmap_icon_controls, [&nav](){ nav.push<DebugControlsView>(); } },
|
||||
});
|
||||
set_max_rows(2); // allow wider buttons
|
||||
}
|
||||
|
||||
/*DebugLCRView::DebugLCRView(NavigationView& nav, std::string lcr_string) {
|
||||
|
||||
@@ -287,14 +287,16 @@ private:
|
||||
};
|
||||
};*/
|
||||
|
||||
class DebugPeripheralsMenuView : public MenuView {
|
||||
class DebugPeripheralsMenuView : public BtnGridView {
|
||||
public:
|
||||
DebugPeripheralsMenuView(NavigationView& nav);
|
||||
std::string title() const override { return "Peripherals"; };
|
||||
};
|
||||
|
||||
class DebugMenuView : public MenuView {
|
||||
class DebugMenuView : public BtnGridView {
|
||||
public:
|
||||
DebugMenuView(NavigationView& nav);
|
||||
std::string title() const override { return "Debug"; };
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
@@ -55,7 +55,7 @@ private:
|
||||
//uint8_t scan_count;
|
||||
//double scan_progress;
|
||||
//unsigned int scan_index;
|
||||
int16_t waveform_buffer[512];
|
||||
int16_t waveform_buffer[550];
|
||||
const encoder_def_t * encoder_def { };
|
||||
//uint8_t enc_type = 0;
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace ui {
|
||||
void FileManBaseView::load_directory_contents(const std::filesystem::path& dir_path) {
|
||||
current_path = dir_path;
|
||||
|
||||
text_current.set(dir_path.string().substr(0, 30 - 8));
|
||||
|
||||
text_current.set(dir_path.string().length()? dir_path.string().substr(0, 30 - 6):"(sd root)");
|
||||
|
||||
entry_list.clear();
|
||||
|
||||
auto filtering = (bool)extension_filter.size();
|
||||
@@ -315,7 +315,7 @@ FileManagerView::FileManagerView(
|
||||
|
||||
button_delete.on_select = [this, &nav](Button&) {
|
||||
// Use display_modal ?
|
||||
nav.push<ModalMessageView>("Delete", "Delete " + entry_list[menu_view.highlighted_index()].entry_path.filename().string() + "\nAre you sure ?", YESNO,
|
||||
nav.push<ModalMessageView>("Delete", "Delete " + entry_list[menu_view.highlighted_index()].entry_path.filename().string() + "\nAre you sure?", YESNO,
|
||||
[this](bool choice) {
|
||||
if (choice)
|
||||
on_delete();
|
||||
|
||||
@@ -67,8 +67,9 @@ protected:
|
||||
{ ".TXT", &bitmap_icon_file_text, ui::Color::white() },
|
||||
{ ".PNG", &bitmap_icon_file_image, ui::Color::green() },
|
||||
{ ".BMP", &bitmap_icon_file_image, ui::Color::green() },
|
||||
{ ".C8", &bitmap_icon_file_iq, ui::Color::blue() },
|
||||
{ ".C16", &bitmap_icon_file_iq, ui::Color::blue() },
|
||||
{ ".WAV", &bitmap_icon_speaker, ui::Color::dark_magenta() },
|
||||
{ ".WAV", &bitmap_icon_file_wav, ui::Color::dark_magenta() },
|
||||
{ "", &bitmap_icon_file, ui::Color::light_grey() }
|
||||
};
|
||||
|
||||
@@ -84,10 +85,10 @@ protected:
|
||||
void refresh_list();
|
||||
|
||||
Labels labels {
|
||||
{ { 0, 0 }, "Current:", Color::light_grey() }
|
||||
{ { 0, 0 }, "Path:", Color::light_grey() }
|
||||
};
|
||||
Text text_current {
|
||||
{ 8 * 8, 0 * 8, 22 * 8, 16 },
|
||||
{ 6 * 8, 0 * 8, 24 * 8, 16 },
|
||||
"",
|
||||
};
|
||||
|
||||
@@ -97,7 +98,7 @@ protected:
|
||||
};
|
||||
|
||||
Button button_exit {
|
||||
{ 20 * 8, 34 * 8, 10 * 8, 4 * 8 },
|
||||
{ 16 * 8, 34 * 8, 14 * 8, 32 },
|
||||
"Exit"
|
||||
};
|
||||
};
|
||||
@@ -157,11 +158,11 @@ private:
|
||||
};
|
||||
|
||||
Button button_rename {
|
||||
{ 0 * 8, 29 * 8, 12 * 8, 32 },
|
||||
{ 0 * 8, 29 * 8, 14 * 8, 32 },
|
||||
"Rename"
|
||||
};
|
||||
Button button_delete {
|
||||
{ 18 * 8, 29 * 8, 12 * 8, 32 },
|
||||
{ 16 * 8, 29 * 8, 14 * 8, 32 },
|
||||
"Delete"
|
||||
};
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ void ScannerView::handle_retune(uint32_t i) {
|
||||
text_cycle.set( to_string_dec_uint(i) + "/" +
|
||||
to_string_dec_uint(frequency_list.size()) + " : " +
|
||||
to_string_dec_uint(frequency_list[i]) );
|
||||
desc_cycle.set( description_list[i] );
|
||||
}
|
||||
|
||||
void ScannerView::focus() {
|
||||
@@ -104,10 +105,12 @@ ScannerView::ScannerView(
|
||||
&field_rf_amp,
|
||||
&field_volume,
|
||||
&field_bw,
|
||||
&field_trigger,
|
||||
&field_squelch,
|
||||
&field_wait,
|
||||
//&record_view,
|
||||
&text_cycle,
|
||||
&desc_cycle,
|
||||
//&waterfall,
|
||||
});
|
||||
|
||||
@@ -118,19 +121,28 @@ ScannerView::ScannerView(
|
||||
if (entry.type == RANGE) {
|
||||
for (uint32_t i=entry.frequency_a; i < entry.frequency_b; i+= 1000000) {
|
||||
frequency_list.push_back(i);
|
||||
description_list.push_back("RNG " + to_string_dec_uint(entry.frequency_a) + ">" + to_string_dec_uint(entry.frequency_b));
|
||||
}
|
||||
} else {
|
||||
frequency_list.push_back(entry.frequency_a);
|
||||
description_list.push_back(entry.description);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// DEBUG
|
||||
// TODO: Clean this
|
||||
frequency_list.push_back(466025000);
|
||||
description_list.push_back("POCSAG-France");
|
||||
frequency_list.push_back(466050000);
|
||||
description_list.push_back("POCSAG-France");
|
||||
frequency_list.push_back(466075000);
|
||||
description_list.push_back("POCSAG-France");
|
||||
frequency_list.push_back(466175000);
|
||||
description_list.push_back("POCSAG-France");
|
||||
frequency_list.push_back(466206250);
|
||||
description_list.push_back("POCSAG-France");
|
||||
frequency_list.push_back(466231250);
|
||||
description_list.push_back("POCSAG-France");
|
||||
}
|
||||
|
||||
field_bw.set_selected_index(2);
|
||||
@@ -143,10 +155,17 @@ ScannerView::ScannerView(
|
||||
};
|
||||
field_wait.set_value(5);
|
||||
|
||||
field_trigger.on_change = [this](int32_t v) {
|
||||
trigger = v;
|
||||
};
|
||||
field_trigger.set_value(30);
|
||||
|
||||
field_squelch.set_value(receiver_model.squelch_level());
|
||||
field_squelch.on_change = [this](int32_t v) {
|
||||
squelch = v;
|
||||
receiver_model.set_squelch_level(v);
|
||||
};
|
||||
field_squelch.set_value(30);
|
||||
|
||||
|
||||
field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99);
|
||||
field_volume.on_change = [this](int32_t v) {
|
||||
@@ -175,7 +194,7 @@ void ScannerView::on_statistics_update(const ChannelStatistics& statistics) {
|
||||
if (timer <= wait)
|
||||
timer++;
|
||||
|
||||
if (max_db < -squelch) {
|
||||
if (max_db < -trigger) {
|
||||
if (timer == wait) {
|
||||
//audio::output::stop();
|
||||
scan_thread->set_scanning(true);
|
||||
|
||||
@@ -66,15 +66,17 @@ private:
|
||||
void handle_retune(uint32_t i);
|
||||
|
||||
std::vector<rf::Frequency> frequency_list { };
|
||||
std::vector<string> description_list { };
|
||||
int32_t trigger { 0 };
|
||||
int32_t squelch { 0 };
|
||||
uint32_t timer { 0 };
|
||||
uint32_t wait { 0 };
|
||||
freqman_db database { };
|
||||
|
||||
Labels labels {
|
||||
{ { 0 * 8, 0 * 16 }, "LNA: VGA: AMP: VOL:", Color::light_grey() },
|
||||
{ { 0 * 8, 1 * 16 }, "BW: SQUELCH: /99 WAIT:", Color::light_grey() },
|
||||
{ { 0 * 8, 3 * 16 }, "Work in progress...", Color::light_grey() }
|
||||
{ { 0 * 8, 0 * 16 }, "LNA: TRIGGER: /99 VOL:", Color::light_grey() },
|
||||
{ { 0 * 8, 1 * 16 }, "VGA: SQUELCH: /99 AMP:", Color::light_grey() },
|
||||
{ { 0 * 8, 2 * 16 }, " BW: WAIT:", Color::light_grey() },
|
||||
};
|
||||
|
||||
LNAGainField field_lna {
|
||||
@@ -82,15 +84,15 @@ private:
|
||||
};
|
||||
|
||||
VGAGainField field_vga {
|
||||
{ 11 * 8, 0 * 16 }
|
||||
{ 4 * 8, 1 * 16 }
|
||||
};
|
||||
|
||||
RFAmpField field_rf_amp {
|
||||
{ 18 * 8, 0 * 16 }
|
||||
{ 28 * 8, 1 * 16 }
|
||||
};
|
||||
|
||||
NumberField field_volume {
|
||||
{ 24 * 8, 0 * 16 },
|
||||
{ 28 * 8, 0 * 16 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
@@ -98,7 +100,7 @@ private:
|
||||
};
|
||||
|
||||
OptionsField field_bw {
|
||||
{ 3 * 8, 1 * 16 },
|
||||
{ 4 * 8, 2 * 16 },
|
||||
3,
|
||||
{
|
||||
{ "8k5", 0 },
|
||||
@@ -107,8 +109,16 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
NumberField field_trigger {
|
||||
{ 16 * 8, 0 * 16 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
' ',
|
||||
};
|
||||
|
||||
NumberField field_squelch {
|
||||
{ 15 * 8, 1 * 16 },
|
||||
{ 16 * 8, 1 * 16 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
@@ -116,7 +126,7 @@ private:
|
||||
};
|
||||
|
||||
NumberField field_wait {
|
||||
{ 26 * 8, 1 * 16 },
|
||||
{ 16 * 8, 2 * 16 },
|
||||
2,
|
||||
{ 0, 99 },
|
||||
1,
|
||||
@@ -127,6 +137,10 @@ private:
|
||||
{ 0, 5 * 16, 240, 16 },
|
||||
"--/--"
|
||||
};
|
||||
Text desc_cycle {
|
||||
{0, 6 * 16, 240, 16 },
|
||||
" "
|
||||
};
|
||||
|
||||
std::unique_ptr<ScannerThread> scan_thread { };
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ ScriptView::ScriptView(
|
||||
};
|
||||
|
||||
button_del.on_select = [this, &nav](Button&) {
|
||||
nav.push<ModalMessageView>("Confirm", "Are you sure ?", YESNO,
|
||||
nav.push<ModalMessageView>("Confirm", "Are you sure?", YESNO,
|
||||
[this](bool choice) {
|
||||
if (choice) {
|
||||
on_delete();
|
||||
|
||||
@@ -45,7 +45,7 @@ void WipeSDView::focus() {
|
||||
dummy.focus();
|
||||
|
||||
if (!confirmed) {
|
||||
nav_.push<ModalMessageView>("Warning !", "Wipe FAT of SD card ?", YESCANCEL, [this](bool choice) {
|
||||
nav_.push<ModalMessageView>("Warning !", "Wipe FAT of SD card?", YESCANCEL, [this](bool choice) {
|
||||
if (choice)
|
||||
confirmed = true;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
using namespace lpc43xx;
|
||||
|
||||
#include "audio.hpp"
|
||||
#include "portapack.hpp"
|
||||
using portapack::receiver_model;
|
||||
using namespace portapack;
|
||||
@@ -240,12 +241,14 @@ void SetPlayDeadView::focus() {
|
||||
SetUIView::SetUIView(NavigationView& nav) {
|
||||
add_children({
|
||||
//&checkbox_login,
|
||||
&checkbox_speaker,
|
||||
&checkbox_bloff,
|
||||
&options_bloff,
|
||||
&checkbox_showsplash,
|
||||
&button_ok
|
||||
});
|
||||
|
||||
checkbox_speaker.set_value(persistent_memory::config_speaker());
|
||||
checkbox_showsplash.set_value(persistent_memory::config_splash());
|
||||
//checkbox_login.set_value(persistent_memory::config_login());
|
||||
|
||||
@@ -258,6 +261,15 @@ SetUIView::SetUIView(NavigationView& nav) {
|
||||
options_bloff.set_selected_index(0);
|
||||
}
|
||||
|
||||
checkbox_speaker.on_select = [this](Checkbox&, bool v) {
|
||||
if (v) audio::output::speaker_mute(); //Just mute audio if speaker is disabled
|
||||
|
||||
persistent_memory::set_config_speaker(v); //Store Speaker status
|
||||
|
||||
StatusRefreshMessage message { }; //Refresh status bar with/out speaker
|
||||
EventDispatcher::send_message(message);
|
||||
};
|
||||
|
||||
button_ok.on_select = [&nav, this](Button&) {
|
||||
if (checkbox_bloff.value())
|
||||
persistent_memory::set_config_backlight_timer(options_bloff.selected_index() + 1);
|
||||
@@ -473,14 +485,14 @@ void ModInfoView::focus() {
|
||||
|
||||
SettingsMenuView::SettingsMenuView(NavigationView& nav) {
|
||||
add_items({
|
||||
//{ "..", ui::Color::light_grey(), &bitmap_icon_previous, [&nav](){ nav.pop(); } },
|
||||
{ "Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [&nav](){ nav.push<SetAudioView>(); } },
|
||||
{ "Radio", ui::Color::dark_cyan(), nullptr, [&nav](){ nav.push<SetRadioView>(); } },
|
||||
{ "UI", ui::Color::dark_cyan(), nullptr, [&nav](){ nav.push<SetUIView>(); } },
|
||||
//{ "SD card modules", ui::Color::dark_cyan(), [&nav](){ nav.push<ModInfoView>(); } },
|
||||
{ "Date/Time", ui::Color::dark_cyan(), nullptr, [&nav](){ nav.push<SetDateTimeView>(); } },
|
||||
{ "Touch screen", ui::Color::dark_cyan(), nullptr, [&nav](){ nav.push<TouchCalibrationView>(); } },
|
||||
//{ "Play dead", ui::Color::dark_cyan(), &bitmap_icon_playdead, [&nav](){ nav.push<SetPlayDeadView>(); } }
|
||||
//{ "..", ui::Color::light_grey(), &bitmap_icon_previous, [&nav](){ nav.pop(); } },
|
||||
{ "Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [&nav](){ nav.push<SetAudioView>(); } },
|
||||
{ "Radio", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav](){ nav.push<SetRadioView>(); } },
|
||||
{ "Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [&nav](){ nav.push<SetUIView>(); } },
|
||||
//{ "SD card modules", ui::Color::dark_cyan(), [&nav](){ nav.push<ModInfoView>(); } },
|
||||
{ "Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [&nav](){ nav.push<SetDateTimeView>(); } },
|
||||
{ "Touchscreen", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [&nav](){ nav.push<TouchCalibrationView>(); } },
|
||||
//{ "Play dead", ui::Color::dark_cyan(), &bitmap_icon_playdead, [&nav](){ nav.push<SetPlayDeadView>(); } }
|
||||
});
|
||||
set_max_rows(2); // allow wider buttons
|
||||
}
|
||||
|
||||
@@ -200,6 +200,11 @@ private:
|
||||
"Login with play dead"
|
||||
};*/
|
||||
|
||||
Checkbox checkbox_speaker {
|
||||
{ 3 * 8, 2 * 16 },
|
||||
20,
|
||||
"Hide H1 Speaker option"
|
||||
};
|
||||
Checkbox checkbox_bloff {
|
||||
{ 3 * 8, 5 * 16 },
|
||||
20,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
using portapack::clock_manager;
|
||||
|
||||
#include "portapack_hal.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include "i2s.hpp"
|
||||
using namespace lpc43xx;
|
||||
@@ -153,6 +154,16 @@ void unmute() {
|
||||
audio_codec->headphone_enable();
|
||||
}
|
||||
|
||||
void speaker_mute() {
|
||||
i2s::i2s0::tx_mute();
|
||||
audio_codec->speaker_disable();
|
||||
}
|
||||
|
||||
void speaker_unmute() {
|
||||
i2s::i2s0::tx_unmute();
|
||||
audio_codec->speaker_enable();
|
||||
}
|
||||
|
||||
} /* namespace output */
|
||||
|
||||
namespace input {
|
||||
|
||||
@@ -41,6 +41,9 @@ public:
|
||||
virtual bool reset() = 0;
|
||||
virtual void init() = 0;
|
||||
|
||||
virtual void speaker_enable() = 0;
|
||||
virtual void speaker_disable() = 0;
|
||||
|
||||
virtual void headphone_enable() = 0;
|
||||
virtual void headphone_disable() = 0;
|
||||
virtual volume_range_t headphone_gain_range() const = 0;
|
||||
@@ -62,6 +65,9 @@ void stop();
|
||||
void mute();
|
||||
void unmute();
|
||||
|
||||
void speaker_mute();
|
||||
void speaker_unmute();
|
||||
|
||||
} /* namespace output */
|
||||
|
||||
namespace input {
|
||||
@@ -79,6 +85,14 @@ void set_volume(const volume_t volume);
|
||||
|
||||
} /* namespace headphone */
|
||||
|
||||
namespace speaker {
|
||||
|
||||
volume_range_t volume_range();
|
||||
|
||||
void set_volume(const volume_t volume);
|
||||
|
||||
} /* namespace speaker */
|
||||
|
||||
namespace debug {
|
||||
|
||||
size_t reg_count();
|
||||
|
||||
@@ -93,6 +93,15 @@ bool get_antenna_bias() {
|
||||
return antenna_bias;
|
||||
}
|
||||
|
||||
bool speaker_mode { false };
|
||||
void set_speaker_mode(const bool v) {
|
||||
speaker_mode = v;
|
||||
if (speaker_mode)
|
||||
audio::output::speaker_unmute();
|
||||
else
|
||||
audio::output::speaker_mute();
|
||||
}
|
||||
|
||||
static constexpr uint32_t systick_count(const uint32_t clock_source_f) {
|
||||
return clock_source_f / CH_FREQUENCY;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,9 @@ extern ClockManager clock_manager;
|
||||
extern ReceiverModel receiver_model;
|
||||
extern TransmitterModel transmitter_model;
|
||||
|
||||
extern bool speaker_mode;
|
||||
void set_speaker_mode(const bool v);
|
||||
|
||||
extern uint8_t bl_tick_counter;
|
||||
extern bool antenna_bias;
|
||||
|
||||
|
||||
@@ -247,8 +247,6 @@ public:
|
||||
parent_pos,
|
||||
5,
|
||||
{
|
||||
{ " 1 ", 1 },
|
||||
{ " 10 ", 10 },
|
||||
{ " 100", 100 },
|
||||
{ " 1k ", 1000 },
|
||||
{ " 3k ", 3000 }, /* Approximate SSB bandwidth */
|
||||
|
||||
@@ -106,6 +106,7 @@ SystemStatusView::SystemStatusView(
|
||||
&backdrop,
|
||||
&button_back,
|
||||
&title,
|
||||
&button_speaker,
|
||||
&button_stealth,
|
||||
//&button_textentry,
|
||||
&button_camera,
|
||||
@@ -115,6 +116,11 @@ SystemStatusView::SystemStatusView(
|
||||
&sd_card_status_view,
|
||||
});
|
||||
|
||||
if (portapack::persistent_memory::config_speaker())
|
||||
button_speaker.hidden(false);
|
||||
else
|
||||
button_speaker.hidden(true);
|
||||
|
||||
button_back.id = -1; // Special ID used by FocusManager
|
||||
title.set_style(&style_systemstatus);
|
||||
|
||||
@@ -133,6 +139,10 @@ SystemStatusView::SystemStatusView(
|
||||
this->on_back();
|
||||
};
|
||||
|
||||
button_speaker.on_select = [this](ImageButton&) {
|
||||
this->on_speaker();
|
||||
};
|
||||
|
||||
button_stealth.on_select = [this](ImageButton&) {
|
||||
this->on_stealth();
|
||||
};
|
||||
@@ -156,6 +166,14 @@ SystemStatusView::SystemStatusView(
|
||||
}
|
||||
|
||||
void SystemStatusView::refresh() {
|
||||
if (!portapack::persistent_memory::config_speaker()) {
|
||||
button_speaker.set_foreground(Color::light_grey());
|
||||
button_speaker.set_bitmap(&bitmap_icon_speaker_mute);
|
||||
button_speaker.hidden(false);
|
||||
}
|
||||
else {
|
||||
button_speaker.hidden(true);
|
||||
}
|
||||
if (portapack::get_antenna_bias()) {
|
||||
button_bias_tee.set_bitmap(&bitmap_icon_biast_on);
|
||||
button_bias_tee.set_foreground(ui::Color::yellow());
|
||||
@@ -188,6 +206,23 @@ void SystemStatusView::set_title(const std::string new_value) {
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStatusView::on_speaker() {
|
||||
if (!portapack::speaker_mode)
|
||||
{
|
||||
portapack::set_speaker_mode(true);
|
||||
button_speaker.set_foreground(Color::green());
|
||||
button_speaker.set_bitmap(&bitmap_icon_speaker);
|
||||
}
|
||||
else
|
||||
{
|
||||
portapack::set_speaker_mode(false);
|
||||
button_speaker.set_foreground(Color::light_grey());
|
||||
button_speaker.set_bitmap(&bitmap_icon_speaker_mute);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SystemStatusView::on_stealth() {
|
||||
bool mode = not portapack::persistent_memory::stealth_mode();
|
||||
|
||||
@@ -198,7 +233,7 @@ void SystemStatusView::on_stealth() {
|
||||
|
||||
void SystemStatusView::on_bias_tee() {
|
||||
if (!portapack::antenna_bias) {
|
||||
nav_.display_modal("Bias voltage", "Enable DC voltage on\nantenna connector ?", YESNO, [this](bool v) {
|
||||
nav_.display_modal("Bias voltage", "Enable DC voltage on\nantenna connector?", YESNO, [this](bool v) {
|
||||
if (v) {
|
||||
portapack::set_antenna_bias(true);
|
||||
//radio::set_antenna_bias(true);
|
||||
@@ -402,15 +437,15 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) {
|
||||
UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) {
|
||||
add_items({
|
||||
//{ "Test app", ui::Color::dark_grey(), nullptr, [&nav](){ nav.push<TestView>(); } },
|
||||
//{ "..", ui::Color::light_grey(),&bitmap_icon_previous, [&nav](){ nav.pop(); } },
|
||||
{ "Freq manager", ui::Color::green(), &bitmap_icon_freqman, [&nav](){ nav.push<FrequencyManagerView>(); } },
|
||||
{ "File manager", ui::Color::yellow(), &bitmap_icon_file, [&nav](){ nav.push<FileManagerView>(); } },
|
||||
//{ "Notepad", ui::Color::dark_grey(), &bitmap_icon_notepad, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{ "Signal gen", ui::Color::green(), &bitmap_icon_cwgen, [&nav](){ nav.push<SigGenView>(); } },
|
||||
//{ "Tone search", ui::Color::dark_grey(), nullptr, [&nav](){ nav.push<ToneSearchView>(); } },
|
||||
{ "Wave viewer", ui::Color::blue(), nullptr, [&nav](){ nav.push<ViewWavView>(); } },
|
||||
{ "Antenna length", ui::Color::yellow(), nullptr, [&nav](){ nav.push<WhipCalcView>(); } },
|
||||
{ "Wipe SD card", ui::Color::red(), nullptr, [&nav](){ nav.push<WipeSDView>(); } },
|
||||
//{ "..", ui::Color::light_grey(),&bitmap_icon_previous, [&nav](){ nav.pop(); } },
|
||||
{ "Freq manager", ui::Color::green(), &bitmap_icon_freqman, [&nav](){ nav.push<FrequencyManagerView>(); } },
|
||||
{ "File manager", ui::Color::yellow(), &bitmap_icon_dir, [&nav](){ nav.push<FileManagerView>(); } },
|
||||
//{ "Notepad", ui::Color::dark_grey(), &bitmap_icon_notepad, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{ "Signal gen", ui::Color::green(), &bitmap_icon_cwgen, [&nav](){ nav.push<SigGenView>(); } },
|
||||
//{ "Tone search", ui::Color::dark_grey(), nullptr, [&nav](){ nav.push<ToneSearchView>(); } },
|
||||
{ "Wave viewer", ui::Color::yellow(), &bitmap_icon_soundboard, [&nav](){ nav.push<ViewWavView>(); } },
|
||||
{ "Antenna length", ui::Color::green(), &bitmap_icon_tools_antenna, [&nav](){ nav.push<WhipCalcView>(); } },
|
||||
{ "Wipe SD card", ui::Color::red(), &bitmap_icon_tools_wipesd, [&nav](){ nav.push<WipeSDView>(); } },
|
||||
});
|
||||
set_max_rows(2); // allow wider buttons
|
||||
}
|
||||
@@ -418,7 +453,7 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) {
|
||||
/* SystemMenuView ********************************************************/
|
||||
|
||||
void SystemMenuView::hackrf_mode(NavigationView& nav) {
|
||||
nav.push<ModalMessageView>("HackRF mode", "This mode enables the USB\nfunctionality. Reset the\ndevice to get back.\n\nDo you want to Switch now?", YESNO,
|
||||
nav.push<ModalMessageView>("HackRF mode", " This mode enables HackRF\n functionality. To return,\n press the reset button.\n\n Switch to HackRF mode?", YESNO,
|
||||
[this](bool choice) {
|
||||
if (choice) {
|
||||
EventDispatcher::request_stop();
|
||||
|
||||
@@ -54,8 +54,6 @@ enum modal_t {
|
||||
ABORT
|
||||
};
|
||||
|
||||
//#define VERSION_STRING "v1.0.0"; // TODO: Move somewhere else
|
||||
|
||||
class NavigationView : public View {
|
||||
public:
|
||||
std::function<void(const View&)> on_view_changed { };
|
||||
@@ -111,7 +109,7 @@ public:
|
||||
void set_title(const std::string new_value);
|
||||
|
||||
private:
|
||||
static constexpr auto default_title = "MAYHEM v1.0.0"; // TODO: Move the version somewhere
|
||||
static constexpr auto default_title = "MAYHEM v1.0.3"; // TODO: Move the version somewhere
|
||||
|
||||
NavigationView& nav_;
|
||||
|
||||
@@ -128,9 +126,16 @@ private:
|
||||
};
|
||||
|
||||
Text title {
|
||||
{ 20, 0, 16 * 8, 1 * 16 },
|
||||
{ 20, 0, 14 * 8, 1 * 16 },
|
||||
default_title,
|
||||
};
|
||||
|
||||
ImageButton button_speaker {
|
||||
{ 17 * 8, 0, 2 * 8, 1 * 16 },
|
||||
&bitmap_icon_speaker_mute,
|
||||
Color::light_grey(),
|
||||
Color::dark_grey()
|
||||
};
|
||||
|
||||
ImageButton button_stealth {
|
||||
{ 19 * 8, 0, 2 * 8, 1 * 16 },
|
||||
@@ -178,6 +183,7 @@ private:
|
||||
{ 28 * 8, 0 * 16, 2 * 8, 1 * 16 }
|
||||
};
|
||||
|
||||
void on_speaker();
|
||||
void on_stealth();
|
||||
void on_bias_tee();
|
||||
//void on_textentry();
|
||||
|
||||
@@ -201,6 +201,11 @@ void RecordView::start() {
|
||||
update_status_display();
|
||||
}
|
||||
|
||||
void RecordView::on_hide() {
|
||||
stop(); // Stop current recording
|
||||
View::on_hide();
|
||||
}
|
||||
|
||||
void RecordView::stop() {
|
||||
if( is_active() ) {
|
||||
capture_thread.reset();
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void on_hide() override;
|
||||
|
||||
bool is_active() const;
|
||||
|
||||
|
||||
@@ -58,34 +58,18 @@ void ReplayProcessor::execute(const buffer_c8_t& buffer) {
|
||||
}
|
||||
|
||||
// Fill and "stretch"
|
||||
for (size_t i = 0; i < buffer.count; i++) {
|
||||
/*if (i & 3) {
|
||||
buffer.p[i] = buffer.p[i - 1];
|
||||
} else {
|
||||
auto re_out = iq_buffer.p[i >> 3].real() ;
|
||||
auto im_out = iq_buffer.p[i >> 3].imag() ;
|
||||
buffer.p[i] = { (int8_t)re_out, (int8_t)im_out };
|
||||
}*/
|
||||
/*
|
||||
if (i % 8 != 0) {
|
||||
buffer.p[i] = buffer.p[i - 1];
|
||||
} else {
|
||||
auto re_out = iq_buffer.p[i/8].real() ;
|
||||
auto im_out = iq_buffer.p[i/8].imag() ;
|
||||
buffer.p[i] = { (int8_t)re_out, (int8_t)im_out };
|
||||
}*/
|
||||
|
||||
auto re_out = iq_buffer.p[i].real() ;
|
||||
auto im_out = iq_buffer.p[i].imag() ;
|
||||
for (size_t i = 0; i < buffer.count; i++) {
|
||||
auto re_out = iq_buffer.p[i].real() ;
|
||||
auto im_out = iq_buffer.p[i].imag() ;
|
||||
buffer.p[i] = { (int8_t)re_out, (int8_t)im_out };
|
||||
}
|
||||
|
||||
spectrum_samples += buffer.count;
|
||||
if( spectrum_samples >= spectrum_interval_samples ) {
|
||||
spectrum_samples -= spectrum_interval_samples;
|
||||
//channel_spectrum.feed(iq_buffer, channel_filter_pass_f, channel_filter_stop_f);
|
||||
|
||||
txprogress_message.progress = bytes_read; // Inform UI about progress
|
||||
|
||||
txprogress_message.progress = bytes_read / 1024; // Inform UI about progress
|
||||
|
||||
txprogress_message.done = false;
|
||||
shared_memory.application_queue.push(txprogress_message);
|
||||
}
|
||||
|
||||
@@ -218,10 +218,17 @@ void set_playdead_sequence(const uint32_t new_value) {
|
||||
data->playdead_magic = playdead_magic;
|
||||
}
|
||||
|
||||
bool config_speaker() {
|
||||
return (data->ui_config & 0x10000000UL) ? false : true; // Default true
|
||||
}
|
||||
bool stealth_mode() {
|
||||
return (data->ui_config & 0x20000000UL) ? true : false;
|
||||
}
|
||||
|
||||
void set_config_speaker(bool new_value) {
|
||||
data->ui_config = (data->ui_config & ~0x10000000UL) | (!new_value << 28);
|
||||
}
|
||||
|
||||
void set_stealth_mode(const bool v) {
|
||||
data->ui_config = (data->ui_config & ~0x20000000UL) | (v << 29);
|
||||
}
|
||||
|
||||
@@ -76,10 +76,12 @@ void set_stealth_mode(const bool v);
|
||||
|
||||
bool config_splash();
|
||||
bool config_login();
|
||||
bool config_speaker();
|
||||
uint32_t config_backlight_timer();
|
||||
|
||||
void set_config_splash(bool v);
|
||||
void set_config_login(bool v);
|
||||
void set_config_speaker(bool new_value);
|
||||
void set_config_backlight_timer(uint32_t i);
|
||||
|
||||
//uint8_t ui_config_textentry();
|
||||
|
||||
@@ -341,6 +341,10 @@ public:
|
||||
headphone_mute();
|
||||
}
|
||||
|
||||
void speaker_enable() {};
|
||||
void speaker_disable() {};
|
||||
|
||||
|
||||
void microphone_enable() override {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
BIN
firmware/graphics/icon_back.png
Normal file
|
After Width: | Height: | Size: 168 B |
BIN
firmware/graphics/icon_controls.png
Normal file
|
After Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 175 B After Width: | Height: | Size: 171 B |
BIN
firmware/graphics/icon_delete.png
Normal file
|
After Width: | Height: | Size: 153 B |
|
Before Width: | Height: | Size: 117 B After Width: | Height: | Size: 156 B |
|
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 168 B |
|
Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 156 B |
BIN
firmware/graphics/icon_file_wav.png
Normal file
|
After Width: | Height: | Size: 168 B |
|
Before Width: | Height: | Size: 103 B After Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 168 B After Width: | Height: | Size: 177 B |
BIN
firmware/graphics/icon_load.png
Normal file
|
After Width: | Height: | Size: 174 B |
BIN
firmware/graphics/icon_memory.png
Normal file
|
After Width: | Height: | Size: 168 B |
|
Before Width: | Height: | Size: 117 B After Width: | Height: | Size: 159 B |
BIN
firmware/graphics/icon_new_category.png
Normal file
|
After Width: | Height: | Size: 186 B |
BIN
firmware/graphics/icon_options_datetime.png
Normal file
|
After Width: | Height: | Size: 186 B |
BIN
firmware/graphics/icon_options_radio.png
Normal file
|
After Width: | Height: | Size: 183 B |
BIN
firmware/graphics/icon_options_touch.png
Normal file
|
After Width: | Height: | Size: 207 B |
BIN
firmware/graphics/icon_options_ui.png
Normal file
|
After Width: | Height: | Size: 168 B |
BIN
firmware/graphics/icon_peripherals.png
Normal file
|
After Width: | Height: | Size: 198 B |
BIN
firmware/graphics/icon_peripherals_details.png
Normal file
|
After Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 141 B After Width: | Height: | Size: 147 B |
BIN
firmware/graphics/icon_rename.png
Normal file
|
After Width: | Height: | Size: 171 B |
BIN
firmware/graphics/icon_rename_numeric.png
Normal file
|
After Width: | Height: | Size: 171 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 116 B |
BIN
firmware/graphics/icon_save.png
Normal file
|
After Width: | Height: | Size: 171 B |
|
Before Width: | Height: | Size: 151 B After Width: | Height: | Size: 153 B |
BIN
firmware/graphics/icon_sdcard.png
Normal file
|
After Width: | Height: | Size: 132 B |
|
Before Width: | Height: | Size: 121 B After Width: | Height: | Size: 150 B |
|
Before Width: | Height: | Size: 115 B After Width: | Height: | Size: 183 B |
|
Before Width: | Height: | Size: 121 B After Width: | Height: | Size: 165 B |
BIN
firmware/graphics/icon_speaker_mute.png
Normal file
|
After Width: | Height: | Size: 162 B |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 150 B |
BIN
firmware/graphics/icon_temperature.png
Normal file
|
After Width: | Height: | Size: 189 B |
BIN
firmware/graphics/icon_tools_antenna.png
Normal file
|
After Width: | Height: | Size: 153 B |
BIN
firmware/graphics/icon_tools_wipesd.png
Normal file
|
After Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 93 B After Width: | Height: | Size: 102 B |
|
Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 178 B |
|
Before Width: | Height: | Size: 87 B After Width: | Height: | Size: 146 B |
@@ -112,4 +112,4 @@ f.write("\n")
|
||||
f.write("} /* namespace ui */\n\n")
|
||||
f.write("#endif/*__BITMAP_HPP__*/\n")
|
||||
|
||||
print "Converted " + str(count) + " files"
|
||||
print("Converted " + str(count) + " files")
|
||||
|
||||
2
sdcard/ADSB/About the new world_map.bin.url
Normal file
@@ -0,0 +1,2 @@
|
||||
[InternetShortcut]
|
||||
URL=https://github.com/furrtek/portapack-havoc/issues/326
|
||||
2
sdcard/GPS/How to generate files for the GPS Sim.url
Normal file
@@ -0,0 +1,2 @@
|
||||
[InternetShortcut]
|
||||
URL=https://github.com/eried/portapack-havoc/wiki/GPS-Sim
|
||||
@@ -1,10 +0,0 @@
|
||||
# How to generate world_map.bin
|
||||
|
||||
World_map.bin is required if you want to use the world map view in some apps. It's a huge (~450MB) raw image file in a format that can be easily rendered by the PortaPack.
|
||||
|
||||
Since Github doesn't allow uploading such large files, you must generate it yourself from the provided jpg file.
|
||||
|
||||
1. Make sure that `world_map.jpg` is in `/sdcard/ADSB`.
|
||||
1. Go in `/firmware/tools`.
|
||||
1. Run 'python adsb_map.py'. Give it some time.
|
||||
1. `world_map.bin` should appear ! Leave it in the ADSB directory.
|
||||
2
sdcard/WAV/How to generate WAV files.url
Normal file
@@ -0,0 +1,2 @@
|
||||
[InternetShortcut]
|
||||
URL=https://twitter.com/caj380/status/1264586260187959296
|
||||
BIN
sdcard/WAV/do not give up.wav
Normal file
BIN
sdcard/WAV/epic sax.wav
Normal file
BIN
sdcard/WAV/final countdown.wav
Normal file
BIN
sdcard/WAV/mission impossible.wav
Normal file
BIN
sdcard/WAV/sexy.wav
Normal file
BIN
sdcard/WAV/thug life.wav
Normal file
BIN
sdcard/WAV/trololol.wav
Normal file
|
Before Width: | Height: | Size: 28 MiB |