mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-12-01 18:42:20 +00:00
Compare commits
13 Commits
nightly-ta
...
nightly-ta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bbe1175c1 | ||
|
|
ecd1a217d7 | ||
|
|
335cace137 | ||
|
|
dbd708a1c7 | ||
|
|
4d842b5fae | ||
|
|
e24f1b131d | ||
|
|
3f2c7351f1 | ||
|
|
afc75f6cda | ||
|
|
69b17faddf | ||
|
|
2c118ae584 | ||
|
|
75c34747cb | ||
|
|
7754c0f37f | ||
|
|
37cc35d3c6 |
@@ -2,6 +2,7 @@ name: Hardware / QC / QA / selling
|
||||
description: Issues that related with hardware, quality control, quality assurance, selling, etc.
|
||||
labels:
|
||||
- question
|
||||
- hardware problem
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -11,9 +12,6 @@ body:
|
||||
We would like to inform you that we can't provide much help regarding hardware/QC/QA/selling issues because we are not controlling various vendors/manufacturers, and also we are not profiting from you buying your device.
|
||||
|
||||
You are still welcome to ask, but please be aware that for this kind of issue, ask the seller would be the best option.
|
||||
|
||||
> [!IMPORTANT]
|
||||
If you are a seller/vendor and your customer has directed you to this page as a reference/evidence of a "broken device" or similar issue, please be aware that we are not providing any "official guarantee of a faulty device." We are only offering suggestions based on what the submitter has stated. We do not guarantee that the device is broken or anything else.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
|
||||
20
.github/workflows/hardware_issue_warning.yml
vendored
Normal file
20
.github/workflows/hardware_issue_warning.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: Hardware Issue Warning
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
add-comment:
|
||||
if: github.event.label.name == 'hardware problem'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Add warning comment
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
> [!IMPORTANT]
|
||||
If you are a seller/vendor and your customer has directed you to this page as a reference/evidence of a "broken device" or similar issue, please be aware that we are not providing any "official guarantee of a faulty device." We are only offering suggestions based on what the submitter has stated. We do not guarantee that the device is broken or anything else.
|
||||
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
https://github.com/portapack-mayhem/mayhem-firmware/issues/new/.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
1
CONTRIBUTING.md
Normal file
1
CONTRIBUTING.md
Normal file
@@ -0,0 +1 @@
|
||||
Please see [How-to-collaborate](https://github.com/portapack-mayhem/mayhem-firmware/wiki/How-to-collaborate)
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
This is a fork of the [Havoc](https://github.com/furrtek/portapack-havoc/) firmware, which itself 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 is a derivate, in this case one that has extra features and fixes when compared to the older versions.
|
||||
|
||||
[<img src="https://github.com/user-attachments/assets/dea337ab-fb64-4a2a-b419-69afd272e815" height="400">](https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions#new-h4m-mayhem-edition) [<img src="https://camo.githubusercontent.com/5c1f1da0688240ac7b2ccca0c8dbfd1d73f2540741ad8b1828ba4d5ea68af248/68747470733a2f2f6769746875622d70726f64756374696f6e2d757365722d61737365742d3632313064662e73332e616d617a6f6e6177732e636f6d2f343339333937392f3239353533323731382d38653562363631632d663934362d346365652d386232642d3061363135663737313566342e706e67" height="400">](https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions#h2m-mayhem-edition)
|
||||
[<img src="https://github.com/user-attachments/assets/dea337ab-fb64-4a2a-b419-69afd272e815" height="310">](https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions#new-h4m-mayhem-edition)
|
||||
[<img src="https://camo.githubusercontent.com/5c1f1da0688240ac7b2ccca0c8dbfd1d73f2540741ad8b1828ba4d5ea68af248/68747470733a2f2f6769746875622d70726f64756374696f6e2d757365722d61737365742d3632313064662e73332e616d617a6f6e6177732e636f6d2f343339333937392f3239353533323731382d38653562363631632d663934362d346365652d386232642d3061363135663737313566342e706e67" height="310">](https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions#h2m-mayhem-edition)
|
||||
[<img src="https://camo.githubusercontent.com/c1f7dd1e7672324f60a513f0de23de76da6a669e63896a9de535d8c8093fc3c7/68747470733a2f2f7261772e6769746875622e636f6d2f7368617265627261696e65642f706f7274617061636b2d6861636b72662f6d61737465722f646f632f696d616765732f68617264776172652f706f7274617061636b5f68315f6f7065726174696e672e6a7067" height="310">]([https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions#h2m-mayhem-edition](https://github.com/portapack-mayhem/mayhem-firmware/wiki/PortaPack-Versions#h1r1r2))
|
||||
|
||||
# What is this?
|
||||
|
||||
|
||||
1
SECURITY.md
Normal file
1
SECURITY.md
Normal file
@@ -0,0 +1 @@
|
||||
Please check [Intended-Use-and-Legality](https://github.com/portapack-mayhem/mayhem-firmware/wiki/)
|
||||
@@ -293,7 +293,6 @@ set(CPPSRC
|
||||
apps/ui_flash_utility.cpp
|
||||
apps/ui_freqman.cpp
|
||||
apps/ui_iq_trim.cpp
|
||||
apps/ui_level.cpp
|
||||
apps/ui_looking_glass_app.cpp
|
||||
apps/ui_mictx.cpp
|
||||
apps/ui_modemsetup.cpp
|
||||
@@ -302,7 +301,6 @@ set(CPPSRC
|
||||
apps/ui_rds.cpp
|
||||
apps/ui_recon_settings.cpp
|
||||
apps/ui_recon.cpp
|
||||
# apps/ui_scanner.cpp
|
||||
apps/ui_sd_over_usb.cpp
|
||||
apps/ui_search.cpp
|
||||
apps/ui_settings.cpp
|
||||
|
||||
@@ -517,11 +517,7 @@ ReconView::ReconView(NavigationView& nav)
|
||||
};
|
||||
set_loop_config(continuous);
|
||||
|
||||
rssi.set_focusable(true);
|
||||
rssi.set_peak(true, 500);
|
||||
rssi.on_select = [this](RSSI&) {
|
||||
nav_.replace<LevelView>();
|
||||
};
|
||||
|
||||
// TODO: *BUG* Both transmitter_model and receiver_model share the same pmem setting for target_frequency.
|
||||
button_mic_app.on_select = [this](Button&) {
|
||||
@@ -1227,16 +1223,6 @@ size_t ReconView::change_mode(freqman_index_t new_mod) {
|
||||
text_ctcss.set(" ");
|
||||
recording_sampling_rate = 48000;
|
||||
break;
|
||||
case AMFM_MODULATION:
|
||||
freqman_set_bandwidth_option(new_mod, field_bw);
|
||||
baseband::run_image(portapack::spi_flash::image_tag_am_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::AMAudioFMApt);
|
||||
receiver_model.set_amfm_configuration(5); // Fix index 5 manually, not from freqman: set to RX AM (USB+FM) mode to demod audio tone, and get Wefax_APT signal.
|
||||
field_bw.on_change = [this](size_t, OptionsField::value_t n) { (void)n; };
|
||||
field_bw.set_by_value(0);
|
||||
text_ctcss.set(" ");
|
||||
recording_sampling_rate = 12000;
|
||||
break;
|
||||
case SPEC_MODULATION:
|
||||
freqman_set_bandwidth_option(new_mod, field_bw);
|
||||
baseband::run_image(portapack::spi_flash::image_tag_capture);
|
||||
@@ -1267,9 +1253,17 @@ size_t ReconView::change_mode(freqman_index_t new_mod) {
|
||||
|
||||
field_mode.set_selected_index(new_mod);
|
||||
field_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
if (v != -1) {
|
||||
change_mode(v);
|
||||
// initialize to a value under SPEC
|
||||
static freqman_index_t last_mode = WFM_MODULATION;
|
||||
if (v > SPEC_MODULATION) {
|
||||
if (last_mode == SPEC_MODULATION)
|
||||
v = AM_MODULATION;
|
||||
else
|
||||
v = SPEC_MODULATION;
|
||||
field_mode.set_selected_index(v);
|
||||
}
|
||||
last_mode = v;
|
||||
change_mode(v);
|
||||
};
|
||||
// for some motive, audio output gets stopped.
|
||||
if (!recon && field_mode.selected_index_value() != SPEC_MODULATION)
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "analog_audio_app.hpp"
|
||||
#include "audio.hpp"
|
||||
#include "ui_mictx.hpp"
|
||||
#include "ui_level.hpp"
|
||||
#include "ui_looking_glass_app.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "baseband_api.hpp"
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
unsigned char modal_warning_bmp[] = {
|
||||
0x42, 0x4d, 0xfa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00,
|
||||
0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8, 0x02,
|
||||
0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xff, 0x00, 0x00, 0x5a,
|
||||
0xff, 0x00, 0x78, 0x78, 0x78, 0x00, 0x00, 0x7c, 0xff, 0x00, 0x00, 0xa9,
|
||||
0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x02, 0x03, 0x24, 0x66, 0x02, 0x30,
|
||||
0x00, 0x00, 0x02, 0x36, 0x24, 0x66, 0x02, 0x63, 0x00, 0x00, 0x02, 0x66,
|
||||
0x02, 0x63, 0x20, 0x00, 0x02, 0x36, 0x02, 0x66, 0x00, 0x00, 0x02, 0x36,
|
||||
0x02, 0x60, 0x20, 0x00, 0x02, 0x06, 0x02, 0x63, 0x00, 0x00, 0x02, 0x06,
|
||||
0x02, 0x60, 0x0c, 0x00, 0x00, 0x08, 0x03, 0x66, 0x66, 0x30, 0x0c, 0x00,
|
||||
0x02, 0x06, 0x02, 0x60, 0x00, 0x00, 0x02, 0x03, 0x02, 0x66, 0x0c, 0x00,
|
||||
0x00, 0x08, 0x06, 0x11, 0x11, 0x60, 0x0c, 0x00, 0x02, 0x66, 0x02, 0x30,
|
||||
0x00, 0x00, 0x02, 0x00, 0x02, 0x66, 0x0c, 0x00, 0x00, 0x08, 0x06, 0x21,
|
||||
0x21, 0x60, 0x0c, 0x00, 0x02, 0x66, 0x02, 0x00, 0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x36, 0x60, 0x00, 0x0a, 0x00, 0x00, 0x08, 0x06, 0x42, 0x42, 0x60,
|
||||
0x0a, 0x00, 0x00, 0x06, 0x06, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x06, 0x60, 0x00, 0x0a, 0x00, 0x00, 0x08, 0x06, 0x54, 0x45, 0x60,
|
||||
0x0a, 0x00, 0x00, 0x06, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x03, 0x66, 0x00, 0x0a, 0x00, 0x00, 0x08, 0x03, 0x66, 0x66, 0x30,
|
||||
0x0a, 0x00, 0x00, 0x06, 0x66, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x66, 0x00, 0x1c, 0x00, 0x00, 0x06, 0x66, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x36, 0x60, 0x18, 0x00, 0x00, 0x08,
|
||||
0x06, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x60,
|
||||
0x0a, 0x00, 0x02, 0x36, 0x02, 0x63, 0x0a, 0x00, 0x00, 0x08, 0x06, 0x60,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x66, 0x08, 0x00,
|
||||
0x00, 0x08, 0x03, 0x61, 0x16, 0x30, 0x08, 0x00, 0x00, 0x08, 0x66, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x66, 0x08, 0x00, 0x00, 0x08,
|
||||
0x06, 0x11, 0x11, 0x60, 0x08, 0x00, 0x02, 0x66, 0x06, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x02, 0x36, 0x02, 0x60, 0x06, 0x00, 0x00, 0x08, 0x06, 0x11,
|
||||
0x11, 0x60, 0x06, 0x00, 0x02, 0x06, 0x02, 0x63, 0x06, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x02, 0x06, 0x02, 0x60, 0x06, 0x00, 0x00, 0x08, 0x06, 0x11,
|
||||
0x11, 0x60, 0x06, 0x00, 0x02, 0x06, 0x02, 0x60, 0x06, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x02, 0x03, 0x02, 0x66, 0x06, 0x00, 0x00, 0x08, 0x06, 0x11,
|
||||
0x11, 0x60, 0x06, 0x00, 0x02, 0x66, 0x02, 0x30, 0x06, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x02, 0x66, 0x06, 0x00, 0x00, 0x08, 0x06, 0x11, 0x11, 0x60,
|
||||
0x06, 0x00, 0x02, 0x66, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18,
|
||||
0x36, 0x60, 0x00, 0x00, 0x06, 0x11, 0x11, 0x60, 0x00, 0x00, 0x06, 0x63,
|
||||
0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x06, 0x60, 0x00, 0x00,
|
||||
0x06, 0x21, 0x21, 0x60, 0x00, 0x00, 0x06, 0x60, 0x08, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x00, 0x18, 0x03, 0x66, 0x00, 0x00, 0x06, 0x12, 0x12, 0x60,
|
||||
0x00, 0x00, 0x66, 0x30, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x14,
|
||||
0x66, 0x00, 0x00, 0x06, 0x21, 0x21, 0x60, 0x00, 0x00, 0x66, 0x0a, 0x00,
|
||||
0x00, 0x00, 0x0a, 0x00, 0x00, 0x14, 0x36, 0x60, 0x00, 0x06, 0x22, 0x22,
|
||||
0x60, 0x00, 0x06, 0x63, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x14,
|
||||
0x06, 0x60, 0x00, 0x06, 0x24, 0x24, 0x60, 0x00, 0x06, 0x60, 0x0a, 0x00,
|
||||
0x00, 0x00, 0x0a, 0x00, 0x00, 0x14, 0x03, 0x66, 0x00, 0x06, 0x42, 0x42,
|
||||
0x60, 0x00, 0x66, 0x30, 0x0a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10,
|
||||
0x66, 0x00, 0x06, 0x54, 0x45, 0x60, 0x00, 0x66, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x0c, 0x00, 0x00, 0x10, 0x36, 0x60, 0x03, 0x66, 0x66, 0x30, 0x06, 0x63,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x06, 0x02, 0x60, 0x08, 0x00,
|
||||
0x02, 0x06, 0x02, 0x60, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x03,
|
||||
0x02, 0x66, 0x08, 0x00, 0x02, 0x66, 0x02, 0x30, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x0e, 0x00, 0x02, 0x66, 0x08, 0x00, 0x02, 0x66, 0x0e, 0x00, 0x00, 0x00,
|
||||
0x0e, 0x00, 0x00, 0x0c, 0x36, 0x60, 0x00, 0x00, 0x06, 0x63, 0x0e, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x00, 0x00, 0x0c, 0x06, 0x60, 0x00, 0x00, 0x06, 0x60,
|
||||
0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0c, 0x03, 0x66, 0x00, 0x00,
|
||||
0x66, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x66, 0x00,
|
||||
0x00, 0x66, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x36, 0x60,
|
||||
0x06, 0x63, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x06, 0x60,
|
||||
0x06, 0x60, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x03, 0x66,
|
||||
0x66, 0x30, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x66, 0x02, 0x66,
|
||||
0x12, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x36, 0x02, 0x63, 0x12, 0x00,
|
||||
0x00, 0x01};
|
||||
unsigned int modal_warning_bmp_len = 830;
|
||||
@@ -1,327 +0,0 @@
|
||||
// converted by bmp_to_hex_cpp_arr.py at the firmware/tools dir
|
||||
// fake transparent px should be the exact color rgb dec(41,24,22), then use true for the last arg when drawing bmp with the draw func
|
||||
|
||||
const unsigned char splash_bmp[] = {
|
||||
0x42, 0x4d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00,
|
||||
0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x32, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x9c, 0x0e,
|
||||
0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x0f, 0x00,
|
||||
0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x19, 0xf6, 0x00, 0x00, 0x14,
|
||||
0xc9, 0x00, 0x00, 0x0c, 0x78, 0x00, 0x16, 0x18, 0x29, 0x00, 0xfd, 0xfd,
|
||||
0xfd, 0x00, 0xf0, 0xf0, 0xf0, 0x00, 0xe7, 0xe7, 0xe7, 0x00, 0xda, 0xda,
|
||||
0xda, 0x00, 0xcd, 0xcd, 0xcd, 0x00, 0xc7, 0xc7, 0xc7, 0x00, 0xba, 0xba,
|
||||
0xba, 0x00, 0xad, 0xad, 0xad, 0x00, 0x96, 0x96, 0x96, 0x00, 0x5c, 0x5c,
|
||||
0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x33, 0x00, 0x00, 0xe6, 0x33,
|
||||
0x00, 0x00, 0xe6, 0x33, 0x00, 0x00, 0xe6, 0x33, 0x00, 0x00, 0x00, 0x08,
|
||||
0x33, 0x44, 0x44, 0x47, 0x0a, 0x33, 0x00, 0x06, 0xd5, 0x44, 0x7d, 0x00,
|
||||
0x0a, 0x33, 0x00, 0x0a, 0x44, 0x44, 0x48, 0x33, 0x3a, 0x00, 0x06, 0x44,
|
||||
0x02, 0xd3, 0x12, 0x33, 0x00, 0x08, 0xa4, 0x44, 0x45, 0x9d, 0x08, 0x33,
|
||||
0x00, 0x08, 0xc4, 0x44, 0x45, 0xc3, 0x10, 0x33, 0x00, 0x08, 0x34, 0x44,
|
||||
0x44, 0x6d, 0x16, 0x33, 0x00, 0x08, 0x34, 0x44, 0x44, 0x6d, 0x08, 0x33,
|
||||
0x02, 0xd5, 0x1a, 0x44, 0x00, 0x0c, 0x45, 0xc3, 0x33, 0x44, 0x44, 0x47,
|
||||
0x0a, 0x33, 0x00, 0x06, 0xd5, 0x44, 0x7d, 0x00, 0x0a, 0x33, 0x00, 0x08,
|
||||
0x44, 0x44, 0x48, 0x33, 0x00, 0x00, 0x00, 0x0a, 0x33, 0x49, 0x99, 0x95,
|
||||
0xd3, 0x00, 0x06, 0x33, 0x00, 0x0a, 0xd4, 0x46, 0x89, 0x98, 0xb3, 0x00,
|
||||
0x08, 0x33, 0x00, 0x12, 0x49, 0x99, 0x94, 0x33, 0x3d, 0x79, 0x99, 0x99,
|
||||
0x73, 0x00, 0x10, 0x33, 0x00, 0x0a, 0x3d, 0x47, 0x99, 0x95, 0xa3, 0x00,
|
||||
0x08, 0x33, 0x00, 0x08, 0xc7, 0x99, 0x97, 0xa3, 0x10, 0x33, 0x00, 0x08,
|
||||
0x34, 0x99, 0x99, 0x7c, 0x16, 0x33, 0x00, 0x08, 0x34, 0x99, 0x99, 0x7c,
|
||||
0x06, 0x33, 0x00, 0x06, 0xb4, 0x56, 0x89, 0x00, 0x18, 0x99, 0x00, 0x0e,
|
||||
0x97, 0xa3, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x00, 0x06, 0x33, 0x00, 0x0a,
|
||||
0xd4, 0x46, 0x89, 0x98, 0xb3, 0x00, 0x08, 0x33, 0x00, 0x08, 0x49, 0x99,
|
||||
0x94, 0x33, 0x00, 0x00, 0x00, 0x0a, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x00,
|
||||
0x06, 0x33, 0x02, 0x55, 0x06, 0x99, 0x02, 0x9b, 0x08, 0x33, 0x00, 0x12,
|
||||
0x49, 0x99, 0x94, 0x33, 0x33, 0xb9, 0x99, 0x99, 0x8d, 0x00, 0x10, 0x33,
|
||||
0x00, 0x0a, 0x37, 0x69, 0x99, 0x74, 0xd3, 0x00, 0x08, 0x33, 0x00, 0x08,
|
||||
0xc7, 0x99, 0x97, 0xa3, 0x10, 0x33, 0x00, 0x08, 0x34, 0x99, 0x99, 0x7c,
|
||||
0x16, 0x33, 0x00, 0x10, 0x34, 0x99, 0x99, 0x7c, 0x33, 0x33, 0x3a, 0x47,
|
||||
0x1c, 0x99, 0x00, 0x0e, 0x97, 0xa3, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x00,
|
||||
0x06, 0x33, 0x02, 0x55, 0x06, 0x99, 0x02, 0x9b, 0x08, 0x33, 0x00, 0x08,
|
||||
0x49, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00, 0x12, 0x33, 0x49, 0x99, 0x95,
|
||||
0xd3, 0x33, 0x33, 0x3a, 0x48, 0x00, 0x06, 0x99, 0x02, 0x98, 0x02, 0xd3,
|
||||
0x06, 0x33, 0x00, 0x12, 0x49, 0x99, 0x94, 0x33, 0x33, 0xd7, 0x99, 0x99,
|
||||
0x98, 0x00, 0x10, 0x33, 0x00, 0x08, 0xd4, 0x89, 0x99, 0x5a, 0x0a, 0x33,
|
||||
0x00, 0x08, 0xc7, 0x99, 0x97, 0xa3, 0x10, 0x33, 0x00, 0x08, 0x34, 0x99,
|
||||
0x99, 0x7c, 0x16, 0x33, 0x00, 0x10, 0x34, 0x99, 0x99, 0x7c, 0x33, 0x33,
|
||||
0xb4, 0x79, 0x1c, 0x99, 0x00, 0x16, 0x97, 0xa3, 0x33, 0x49, 0x99, 0x95,
|
||||
0xd3, 0x33, 0x33, 0x3a, 0x48, 0x00, 0x06, 0x99, 0x02, 0x98, 0x02, 0xd3,
|
||||
0x06, 0x33, 0x00, 0x08, 0x49, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00, 0x12,
|
||||
0x33, 0x49, 0x99, 0x95, 0xd3, 0x33, 0x33, 0xd4, 0x79, 0x00, 0x08, 0x99,
|
||||
0x02, 0x73, 0x06, 0x33, 0x00, 0x0c, 0x49, 0x99, 0x94, 0x33, 0x33, 0x3b,
|
||||
0x06, 0x99, 0x02, 0xc3, 0x0e, 0x33, 0x00, 0x08, 0x56, 0x99, 0x97, 0x4d,
|
||||
0x0a, 0x33, 0x00, 0x08, 0xc7, 0x99, 0x97, 0xa3, 0x10, 0x33, 0x00, 0x08,
|
||||
0x34, 0x99, 0x99, 0x7c, 0x16, 0x33, 0x00, 0x0e, 0x34, 0x99, 0x99, 0x7c,
|
||||
0x33, 0x3d, 0x47, 0x00, 0x1e, 0x99, 0x00, 0x16, 0x97, 0xa3, 0x33, 0x49,
|
||||
0x99, 0x95, 0xd3, 0x33, 0x33, 0xd4, 0x79, 0x00, 0x08, 0x99, 0x02, 0x73,
|
||||
0x06, 0x33, 0x00, 0x08, 0x49, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00, 0x10,
|
||||
0x33, 0x49, 0x99, 0x95, 0xd3, 0x33, 0x33, 0xa5, 0x0a, 0x99, 0x02, 0x8d,
|
||||
0x06, 0x33, 0x00, 0x14, 0x49, 0x99, 0x94, 0x33, 0x33, 0x3d, 0x79, 0x99,
|
||||
0x99, 0x73, 0x0c, 0x33, 0x00, 0x0a, 0x3c, 0x48, 0x99, 0x95, 0xa3, 0x00,
|
||||
0x0a, 0x33, 0x00, 0x08, 0xc7, 0x99, 0x97, 0xa3, 0x10, 0x33, 0x00, 0x08,
|
||||
0x34, 0x99, 0x99, 0x7c, 0x16, 0x33, 0x00, 0x0e, 0x34, 0x99, 0x99, 0x7c,
|
||||
0x33, 0x37, 0x69, 0x00, 0x1e, 0x99, 0x00, 0x14, 0x97, 0xa3, 0x33, 0x49,
|
||||
0x99, 0x95, 0xd3, 0x33, 0x33, 0xa5, 0x0a, 0x99, 0x02, 0x8d, 0x06, 0x33,
|
||||
0x00, 0x08, 0x49, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00, 0x1c, 0x33, 0x49,
|
||||
0x99, 0x95, 0xd3, 0x33, 0x3d, 0x47, 0x99, 0x97, 0x89, 0x99, 0x99, 0x97,
|
||||
0x06, 0x33, 0x00, 0x06, 0x49, 0x99, 0x94, 0x00, 0x06, 0x33, 0x00, 0x08,
|
||||
0xb9, 0x99, 0x99, 0x9d, 0x0c, 0x33, 0x00, 0x0a, 0x34, 0x69, 0x99, 0x74,
|
||||
0xd3, 0x00, 0x0a, 0x33, 0x00, 0x08, 0xc7, 0x99, 0x98, 0xa3, 0x10, 0x33,
|
||||
0x00, 0x08, 0x34, 0x99, 0x99, 0x7c, 0x16, 0x33, 0x00, 0x12, 0x34, 0x99,
|
||||
0x99, 0x7c, 0x33, 0x34, 0x89, 0x99, 0x64, 0x00, 0x1c, 0x44, 0x00, 0x1e,
|
||||
0xa3, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x33, 0x3d, 0x47, 0x99, 0x97, 0x89,
|
||||
0x99, 0x99, 0x97, 0x00, 0x06, 0x33, 0x00, 0x08, 0x49, 0x99, 0x94, 0x33,
|
||||
0x00, 0x00, 0x00, 0x28, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x33, 0x3c, 0x59,
|
||||
0x99, 0x95, 0xbc, 0x99, 0x99, 0x98, 0xd3, 0x33, 0x33, 0x49, 0x99, 0x94,
|
||||
0x06, 0x33, 0x02, 0xd7, 0x06, 0x99, 0x02, 0x74, 0x0c, 0x44, 0x00, 0x06,
|
||||
0x99, 0x99, 0x4b, 0x00, 0x0c, 0x33, 0x00, 0x08, 0xb7, 0x99, 0x99, 0xa3,
|
||||
0x10, 0x33, 0x00, 0x08, 0x34, 0x99, 0x99, 0x7c, 0x16, 0x33, 0x00, 0x12,
|
||||
0x34, 0x99, 0x99, 0x7c, 0x33, 0xd5, 0x99, 0x99, 0x6d, 0x00, 0x20, 0x33,
|
||||
0x00, 0x28, 0x49, 0x99, 0x95, 0xd3, 0x33, 0x3c, 0x59, 0x99, 0x95, 0xbc,
|
||||
0x99, 0x99, 0x98, 0xd3, 0x33, 0x33, 0x49, 0x99, 0x94, 0x33, 0x00, 0x00,
|
||||
0x00, 0x28, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x33, 0x34, 0x79, 0x99, 0x84,
|
||||
0xdd, 0x89, 0x99, 0x99, 0x83, 0x33, 0x33, 0x49, 0x99, 0x94, 0x06, 0x33,
|
||||
0x02, 0x3b, 0x16, 0x99, 0x02, 0x97, 0x02, 0x43, 0x0a, 0x33, 0x00, 0x0a,
|
||||
0x3d, 0x47, 0x99, 0x99, 0x9d, 0x00, 0x10, 0x33, 0x00, 0x08, 0x34, 0x99,
|
||||
0x99, 0x9d, 0x16, 0x33, 0x00, 0x12, 0x34, 0x99, 0x99, 0x7c, 0x33, 0xd6,
|
||||
0x99, 0x99, 0x6d, 0x00, 0x20, 0x33, 0x00, 0x28, 0x49, 0x99, 0x95, 0xd3,
|
||||
0x33, 0x34, 0x79, 0x99, 0x84, 0xdd, 0x89, 0x99, 0x99, 0x83, 0x33, 0x33,
|
||||
0x49, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00, 0x28, 0x33, 0x49, 0x99, 0x95,
|
||||
0xd3, 0x33, 0xc4, 0x99, 0x99, 0x67, 0x33, 0x79, 0x99, 0x99, 0x8d, 0x33,
|
||||
0x33, 0x49, 0x99, 0x94, 0x06, 0x33, 0x02, 0x3d, 0x02, 0x79, 0x14, 0x99,
|
||||
0x02, 0x94, 0x02, 0xc3, 0x0a, 0x33, 0x00, 0x0a, 0x35, 0x59, 0x99, 0x99,
|
||||
0x98, 0x00, 0x10, 0x33, 0x02, 0x34, 0x06, 0x99, 0x02, 0x74, 0x16, 0x44,
|
||||
0x00, 0x10, 0x99, 0x99, 0x7c, 0x33, 0xd6, 0x99, 0x99, 0x9d, 0x20, 0x33,
|
||||
0x00, 0x28, 0x49, 0x99, 0x95, 0xd3, 0x33, 0xc4, 0x99, 0x99, 0x67, 0x33,
|
||||
0x79, 0x99, 0x99, 0x8d, 0x33, 0x33, 0x49, 0x99, 0x94, 0x33, 0x00, 0x00,
|
||||
0x00, 0x28, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x33, 0x57, 0x99, 0x99, 0x4d,
|
||||
0x33, 0xd8, 0x99, 0x99, 0x98, 0x33, 0x33, 0x49, 0x99, 0x94, 0x08, 0x33,
|
||||
0x02, 0xc9, 0x14, 0x99, 0x02, 0x74, 0x0c, 0x33, 0x02, 0x84, 0x02, 0x89,
|
||||
0x06, 0x99, 0x02, 0xa3, 0x0e, 0x33, 0x02, 0x34, 0x22, 0x99, 0x00, 0x06,
|
||||
0x7c, 0x33, 0xd6, 0x00, 0x06, 0x99, 0x02, 0x64, 0x18, 0x44, 0x00, 0x2e,
|
||||
0x45, 0xc3, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x33, 0x57, 0x99, 0x99, 0x4d,
|
||||
0x33, 0xd8, 0x99, 0x99, 0x98, 0x33, 0x33, 0x49, 0x99, 0x94, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x28, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x3d, 0x48, 0x99,
|
||||
0x97, 0x43, 0x33, 0x37, 0x99, 0x99, 0x97, 0xd3, 0x33, 0x49, 0x99, 0x94,
|
||||
0x08, 0x33, 0x02, 0x37, 0x14, 0x99, 0x02, 0x4c, 0x0a, 0x33, 0x02, 0x3b,
|
||||
0x02, 0x48, 0x08, 0x99, 0x02, 0x9b, 0x0e, 0x33, 0x02, 0x34, 0x22, 0x99,
|
||||
0x00, 0x06, 0x7c, 0x33, 0xd6, 0x00, 0x20, 0x99, 0x00, 0x2e, 0x97, 0xa3,
|
||||
0x33, 0x49, 0x99, 0x95, 0xd3, 0x3d, 0x48, 0x99, 0x97, 0x43, 0x33, 0x37,
|
||||
0x99, 0x99, 0x97, 0xd3, 0x33, 0x49, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00,
|
||||
0x00, 0x28, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x35, 0x69, 0x99, 0x95, 0xc3,
|
||||
0x33, 0x3c, 0x89, 0x99, 0x99, 0xb3, 0x33, 0x49, 0x99, 0x94, 0x08, 0x33,
|
||||
0x02, 0x3c, 0x12, 0x99, 0x02, 0x97, 0x02, 0x43, 0x0a, 0x33, 0x02, 0xd4,
|
||||
0x02, 0x79, 0x0a, 0x99, 0x02, 0xd3, 0x0c, 0x33, 0x02, 0x34, 0x22, 0x99,
|
||||
0x00, 0x06, 0x7c, 0x33, 0xd6, 0x00, 0x20, 0x99, 0x00, 0x2e, 0x97, 0xa3,
|
||||
0x33, 0x49, 0x99, 0x95, 0xd3, 0x35, 0x69, 0x99, 0x95, 0xc3, 0x33, 0x3c,
|
||||
0x89, 0x99, 0x99, 0xb3, 0x33, 0x49, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00,
|
||||
0x00, 0x12, 0x33, 0x49, 0x99, 0x95, 0xd3, 0xd4, 0x89, 0x99, 0x74, 0x00,
|
||||
0x06, 0x33, 0x00, 0x10, 0x79, 0x99, 0x99, 0x7d, 0x33, 0x49, 0x99, 0x94,
|
||||
0x0a, 0x33, 0x00, 0x16, 0x79, 0x99, 0x99, 0x64, 0x44, 0x44, 0x89, 0x99,
|
||||
0x99, 0x94, 0xc3, 0x00, 0x08, 0x33, 0x00, 0x0a, 0x3d, 0x46, 0x99, 0x98,
|
||||
0x59, 0x00, 0x06, 0x99, 0x02, 0x8d, 0x0c, 0x33, 0x02, 0x34, 0x22, 0x99,
|
||||
0x00, 0x06, 0x7c, 0x33, 0xd6, 0x00, 0x20, 0x99, 0x00, 0x16, 0x97, 0xa3,
|
||||
0x33, 0x49, 0x99, 0x95, 0xd3, 0xd4, 0x89, 0x99, 0x74, 0x00, 0x06, 0x33,
|
||||
0x00, 0x12, 0x79, 0x99, 0x99, 0x7d, 0x33, 0x49, 0x99, 0x94, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x12, 0x33, 0x49, 0x99, 0x95, 0xd3, 0x76, 0x99, 0x99,
|
||||
0x6a, 0x00, 0x06, 0x33, 0x00, 0x10, 0xa9, 0x99, 0x99, 0x9b, 0x33, 0x49,
|
||||
0x99, 0x94, 0x0a, 0x33, 0x00, 0x14, 0xc9, 0x99, 0x99, 0x9c, 0x33, 0x33,
|
||||
0x3b, 0x99, 0x99, 0x74, 0x0a, 0x33, 0x00, 0x0a, 0x35, 0x59, 0x99, 0x95,
|
||||
0x7d, 0x00, 0x06, 0x99, 0x02, 0x9a, 0x0c, 0x33, 0x02, 0x34, 0x22, 0x99,
|
||||
0x00, 0x06, 0x7c, 0x33, 0xd6, 0x00, 0x20, 0x99, 0x00, 0x16, 0x97, 0xa3,
|
||||
0x33, 0x49, 0x99, 0x95, 0xd3, 0x76, 0x99, 0x99, 0x6a, 0x00, 0x06, 0x33,
|
||||
0x00, 0x12, 0xa9, 0x99, 0x99, 0x9b, 0x33, 0x49, 0x99, 0x94, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x12, 0x33, 0x49, 0x99, 0x95, 0x3d, 0x48, 0x99, 0x98,
|
||||
0x4d, 0x00, 0x06, 0x33, 0x00, 0x10, 0xd7, 0x99, 0x99, 0x97, 0xd3, 0x49,
|
||||
0x99, 0x94, 0x0a, 0x33, 0x00, 0x14, 0x37, 0x99, 0x99, 0x97, 0x33, 0x33,
|
||||
0xc4, 0x89, 0x99, 0x4c, 0x0a, 0x33, 0x00, 0x0c, 0x84, 0x89, 0x99, 0x64,
|
||||
0x33, 0xd9, 0x06, 0x99, 0x02, 0xa3, 0x0a, 0x33, 0x00, 0x08, 0x34, 0x99,
|
||||
0x99, 0x64, 0x16, 0x44, 0x06, 0x99, 0x00, 0x06, 0x7c, 0x33, 0xd6, 0x00,
|
||||
0x20, 0x99, 0x00, 0x16, 0x97, 0xa3, 0x33, 0x49, 0x99, 0x95, 0x3d, 0x48,
|
||||
0x99, 0x98, 0x4d, 0x00, 0x06, 0x33, 0x00, 0x12, 0xd7, 0x99, 0x99, 0x97,
|
||||
0xd3, 0x49, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00, 0x00, 0x12, 0x33, 0x49,
|
||||
0x99, 0x96, 0x3b, 0x69, 0x99, 0x96, 0x53, 0x00, 0x06, 0x33, 0x02, 0x38,
|
||||
0x06, 0x99, 0x00, 0x08, 0xc3, 0x49, 0x99, 0x94, 0x0a, 0x33, 0x02, 0x3c,
|
||||
0x06, 0x99, 0x00, 0x0c, 0xb3, 0x33, 0x46, 0x99, 0x96, 0x43, 0x08, 0x33,
|
||||
0x00, 0x0e, 0x3b, 0x48, 0x99, 0x97, 0x4d, 0x33, 0x3d, 0x00, 0x06, 0x99,
|
||||
0x02, 0x9c, 0x0a, 0x33, 0x00, 0x08, 0x34, 0x99, 0x99, 0x6d, 0x16, 0x33,
|
||||
0x00, 0x12, 0x39, 0x99, 0x99, 0x7c, 0x33, 0xd6, 0x99, 0x99, 0x54, 0x00,
|
||||
0x1c, 0x44, 0x00, 0x14, 0xa3, 0x33, 0x49, 0x99, 0x96, 0x3b, 0x69, 0x99,
|
||||
0x96, 0x53, 0x06, 0x33, 0x02, 0x38, 0x06, 0x99, 0x00, 0x0a, 0xc3, 0x49,
|
||||
0x99, 0x94, 0x33, 0x00, 0x00, 0x00, 0x00, 0x12, 0x33, 0x49, 0x99, 0x98,
|
||||
0xd5, 0x79, 0x99, 0x94, 0xd3, 0x00, 0x06, 0x33, 0x00, 0x10, 0x3d, 0x89,
|
||||
0x99, 0x99, 0x73, 0x49, 0x99, 0x94, 0x0c, 0x33, 0x00, 0x12, 0x79, 0x99,
|
||||
0x99, 0x8d, 0x3a, 0x59, 0x99, 0x84, 0xd3, 0x00, 0x08, 0x33, 0x00, 0x10,
|
||||
0xd4, 0x79, 0x99, 0x84, 0xb3, 0x33, 0x33, 0xb9, 0x06, 0x99, 0x02, 0xd3,
|
||||
0x08, 0x33, 0x00, 0x08, 0x34, 0x99, 0x99, 0x6d, 0x16, 0x33, 0x00, 0x12,
|
||||
0x34, 0x99, 0x99, 0x7c, 0x33, 0xd6, 0x99, 0x99, 0x5d, 0x00, 0x20, 0x33,
|
||||
0x00, 0x10, 0x49, 0x99, 0x98, 0xd5, 0x79, 0x99, 0x94, 0xd3, 0x06, 0x33,
|
||||
0x00, 0x12, 0x3d, 0x89, 0x99, 0x99, 0x73, 0x49, 0x99, 0x94, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x33, 0x49, 0x99, 0x99, 0xa6, 0x99, 0x99, 0x74,
|
||||
0x0a, 0x33, 0x00, 0x0e, 0x79, 0x99, 0x99, 0x9c, 0x59, 0x99, 0x94, 0x00,
|
||||
0x0c, 0x33, 0x00, 0x10, 0xc9, 0x99, 0x99, 0x9a, 0xd4, 0x79, 0x99, 0x65,
|
||||
0x08, 0x33, 0x00, 0x0a, 0x3d, 0x46, 0x99, 0x98, 0x48, 0x00, 0x06, 0x33,
|
||||
0x02, 0x3a, 0x06, 0x99, 0x02, 0x83, 0x08, 0x33, 0x00, 0x08, 0x34, 0x99,
|
||||
0x99, 0x6d, 0x16, 0x33, 0x00, 0x12, 0x34, 0x99, 0x99, 0x7c, 0x33, 0xd6,
|
||||
0x99, 0x99, 0x93, 0x00, 0x20, 0x33, 0x00, 0x0e, 0x49, 0x99, 0x99, 0xa6,
|
||||
0x99, 0x99, 0x74, 0x00, 0x0a, 0x33, 0x00, 0x10, 0x79, 0x99, 0x99, 0x9c,
|
||||
0x59, 0x99, 0x94, 0x33, 0x00, 0x00, 0x00, 0x10, 0x33, 0x49, 0x99, 0x99,
|
||||
0x98, 0x99, 0x99, 0x5c, 0x0a, 0x33, 0x02, 0xd8, 0x06, 0x99, 0x00, 0x06,
|
||||
0x79, 0x99, 0x84, 0x00, 0x0c, 0x33, 0x02, 0x37, 0x06, 0x99, 0x00, 0x08,
|
||||
0x86, 0x99, 0x98, 0x4d, 0x08, 0x33, 0x00, 0x0a, 0x35, 0x59, 0x99, 0x95,
|
||||
0x53, 0x00, 0x08, 0x33, 0x00, 0x08, 0x89, 0x99, 0x99, 0x9a, 0x08, 0x33,
|
||||
0x00, 0x08, 0x34, 0x99, 0x99, 0x6d, 0x16, 0x33, 0x00, 0x0c, 0x34, 0x99,
|
||||
0x99, 0x7c, 0x33, 0x36, 0x06, 0x99, 0x02, 0x54, 0x18, 0x44, 0x00, 0x14,
|
||||
0x45, 0xc3, 0x33, 0x49, 0x99, 0x99, 0x98, 0x99, 0x99, 0x5c, 0x0a, 0x33,
|
||||
0x02, 0xd8, 0x06, 0x99, 0x00, 0x08, 0x79, 0x99, 0x84, 0x33, 0x00, 0x00,
|
||||
0x02, 0x33, 0x02, 0x59, 0x08, 0x99, 0x02, 0x97, 0x02, 0x4d, 0x0a, 0x33,
|
||||
0x02, 0x36, 0x0a, 0x99, 0x02, 0x75, 0x0c, 0x33, 0x02, 0x3c, 0x0a, 0x99,
|
||||
0x02, 0x96, 0x02, 0x53, 0x08, 0x33, 0x00, 0x0a, 0x84, 0x89, 0x99, 0x64,
|
||||
0xd3, 0x00, 0x08, 0x33, 0x02, 0xd9, 0x06, 0x99, 0x02, 0xb3, 0x06, 0x33,
|
||||
0x00, 0x08, 0x34, 0x99, 0x99, 0x6d, 0x16, 0x33, 0x00, 0x0c, 0x34, 0x99,
|
||||
0x99, 0x7c, 0x33, 0x36, 0x20, 0x99, 0x00, 0x08, 0x97, 0xa3, 0x33, 0x59,
|
||||
0x08, 0x99, 0x02, 0x97, 0x02, 0x4d, 0x0a, 0x33, 0x02, 0x36, 0x0a, 0x99,
|
||||
0x02, 0x75, 0x02, 0x33, 0x00, 0x00, 0x02, 0x33, 0x02, 0xa8, 0x08, 0x99,
|
||||
0x02, 0x95, 0x02, 0xa3, 0x0a, 0x33, 0x02, 0x3c, 0x0a, 0x99, 0x02, 0x5b,
|
||||
0x0e, 0x33, 0x02, 0x89, 0x08, 0x99, 0x02, 0x84, 0x02, 0xd3, 0x06, 0x33,
|
||||
0x00, 0x0a, 0x3b, 0x48, 0x99, 0x97, 0x4c, 0x00, 0x0a, 0x33, 0x02, 0x3d,
|
||||
0x06, 0x99, 0x02, 0x9d, 0x06, 0x33, 0x00, 0x08, 0x34, 0x99, 0x99, 0x6d,
|
||||
0x16, 0x33, 0x00, 0x0e, 0x34, 0x99, 0x99, 0x7c, 0x33, 0x3d, 0x89, 0x00,
|
||||
0x1e, 0x99, 0x00, 0x08, 0x97, 0xa3, 0x33, 0xa8, 0x08, 0x99, 0x02, 0x95,
|
||||
0x02, 0xa3, 0x0a, 0x33, 0x02, 0x3c, 0x0a, 0x99, 0x02, 0x5b, 0x02, 0x33,
|
||||
0x00, 0x00, 0x02, 0x33, 0x02, 0xd7, 0x08, 0x99, 0x02, 0x64, 0x0e, 0x33,
|
||||
0x02, 0x79, 0x06, 0x99, 0x02, 0x96, 0x02, 0x4d, 0x0e, 0x33, 0x02, 0xd8,
|
||||
0x06, 0x99, 0x02, 0x98, 0x02, 0x48, 0x08, 0x33, 0x00, 0x0a, 0xd4, 0x79,
|
||||
0x99, 0x84, 0xb3, 0x00, 0x0c, 0x33, 0x00, 0x16, 0xb9, 0x99, 0x99, 0x98,
|
||||
0xd3, 0x33, 0x33, 0x34, 0x99, 0x99, 0x6d, 0x00, 0x16, 0x33, 0x00, 0x0c,
|
||||
0x34, 0x99, 0x99, 0x7c, 0x33, 0x33, 0x20, 0x99, 0x00, 0x08, 0x97, 0xa3,
|
||||
0x33, 0xd7, 0x08, 0x99, 0x02, 0x64, 0x0e, 0x33, 0x02, 0x79, 0x06, 0x99,
|
||||
0x00, 0x06, 0x96, 0x4d, 0x33, 0x00, 0x00, 0x00, 0x02, 0x33, 0x02, 0x3c,
|
||||
0x06, 0x99, 0x02, 0x96, 0x02, 0x4d, 0x0e, 0x33, 0x02, 0xd9, 0x06, 0x99,
|
||||
0x02, 0x74, 0x02, 0xc3, 0x0e, 0x33, 0x02, 0x3d, 0x06, 0x99, 0x02, 0x85,
|
||||
0x02, 0x53, 0x06, 0x33, 0x00, 0x0a, 0x3d, 0x46, 0x99, 0x99, 0x57, 0x00,
|
||||
0x0e, 0x33, 0x02, 0x39, 0x06, 0x99, 0x00, 0x0e, 0xa3, 0x33, 0x33, 0x34,
|
||||
0x99, 0x99, 0x6d, 0x00, 0x16, 0x33, 0x00, 0x0e, 0x34, 0x99, 0x99, 0x7c,
|
||||
0x33, 0x33, 0x3a, 0x00, 0x1e, 0x99, 0x00, 0x08, 0x97, 0xa3, 0x33, 0x3c,
|
||||
0x06, 0x99, 0x02, 0x96, 0x02, 0x4d, 0x0e, 0x33, 0x02, 0xd9, 0x06, 0x99,
|
||||
0x00, 0x06, 0x74, 0xc3, 0x33, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x33, 0x33,
|
||||
0xc8, 0x99, 0x96, 0x44, 0xd3, 0x00, 0x0e, 0x33, 0x00, 0x0a, 0x3d, 0x79,
|
||||
0x99, 0x76, 0x4b, 0x00, 0x12, 0x33, 0x00, 0x0a, 0xc7, 0x99, 0x96, 0x45,
|
||||
0xd3, 0x00, 0x06, 0x33, 0x00, 0x0a, 0x35, 0x59, 0x99, 0x96, 0x43, 0x00,
|
||||
0x10, 0x33, 0x00, 0x14, 0x89, 0x99, 0x99, 0x9a, 0x33, 0x33, 0x34, 0x99,
|
||||
0x99, 0x6d, 0x16, 0x33, 0x00, 0x08, 0x34, 0x99, 0x99, 0x7c, 0x06, 0x33,
|
||||
0x02, 0xa6, 0x1c, 0x99, 0x00, 0x12, 0x97, 0xa3, 0x33, 0x33, 0xc8, 0x99,
|
||||
0x96, 0x44, 0xd3, 0x00, 0x0e, 0x33, 0x00, 0x0e, 0x3d, 0x79, 0x99, 0x76,
|
||||
0x4b, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x33, 0x33, 0x3d, 0x84,
|
||||
0x44, 0xc3, 0x12, 0x33, 0x00, 0x08, 0xdc, 0x44, 0x4a, 0xd3, 0x12, 0x33,
|
||||
0x00, 0x08, 0x3d, 0xa4, 0x44, 0xd3, 0x08, 0x33, 0x02, 0xc8, 0x06, 0x44,
|
||||
0x02, 0xd3, 0x10, 0x33, 0x02, 0xd4, 0x06, 0x44, 0x00, 0x0c, 0xa3, 0x33,
|
||||
0x38, 0x44, 0x44, 0x4d, 0x16, 0x33, 0x00, 0x08, 0x38, 0x44, 0x44, 0x4c,
|
||||
0x06, 0x33, 0x02, 0x3d, 0x02, 0xc4, 0x1c, 0x44, 0x00, 0x0e, 0xa3, 0x33,
|
||||
0x33, 0x3d, 0x84, 0x44, 0xc3, 0x00, 0x12, 0x33, 0x00, 0x0c, 0xdc, 0x44,
|
||||
0x4a, 0xd3, 0x33, 0x33, 0x00, 0x00, 0xe6, 0x33, 0x00, 0x00, 0xe6, 0x33,
|
||||
0x00, 0x00, 0xe6, 0x33, 0x00, 0x00, 0xe6, 0x33, 0x00, 0x00, 0xe6, 0x33,
|
||||
0x00, 0x00, 0x00, 0x1e, 0x33, 0x20, 0x00, 0x23, 0x30, 0x00, 0x13, 0x31,
|
||||
0x00, 0x02, 0x33, 0x00, 0x01, 0x33, 0x32, 0x00, 0x08, 0x00, 0x00, 0x26,
|
||||
0x13, 0x31, 0x00, 0x02, 0x33, 0x00, 0x01, 0x33, 0x00, 0x00, 0x13, 0x33,
|
||||
0x00, 0x00, 0x13, 0x32, 0x00, 0x00, 0x23, 0x00, 0x24, 0x33, 0x00, 0x06,
|
||||
0x32, 0x00, 0x02, 0x00, 0x08, 0x33, 0x02, 0x32, 0x06, 0x00, 0x00, 0x30,
|
||||
0x01, 0x33, 0x31, 0x00, 0x02, 0x33, 0x00, 0x01, 0x33, 0x33, 0x32, 0x00,
|
||||
0x02, 0x33, 0x33, 0x30, 0x00, 0x13, 0x32, 0x00, 0x02, 0x33, 0x00, 0x01,
|
||||
0x08, 0x33, 0x00, 0x10, 0x30, 0x00, 0x13, 0x31, 0x00, 0x02, 0x33, 0x30,
|
||||
0x08, 0x00, 0x00, 0x10, 0x23, 0x30, 0x00, 0x13, 0x31, 0x00, 0x02, 0x33,
|
||||
0x00, 0x00, 0x00, 0x20, 0x33, 0x20, 0x11, 0x13, 0x30, 0x11, 0x03, 0x31,
|
||||
0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x10, 0x10, 0x06, 0x00, 0x00, 0x26,
|
||||
0x03, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x01, 0x11, 0x03, 0x33,
|
||||
0x01, 0x11, 0x13, 0x32, 0x01, 0x11, 0x23, 0x00, 0x24, 0x33, 0x00, 0x06,
|
||||
0x32, 0x01, 0x11, 0x00, 0x08, 0x33, 0x00, 0x38, 0x10, 0x10, 0x00, 0x11,
|
||||
0x11, 0x03, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x33, 0x32, 0x01,
|
||||
0x11, 0x33, 0x33, 0x30, 0x11, 0x03, 0x32, 0x01, 0x11, 0x33, 0x01, 0x10,
|
||||
0x08, 0x33, 0x00, 0x12, 0x30, 0x11, 0x03, 0x31, 0x11, 0x02, 0x33, 0x00,
|
||||
0x10, 0x00, 0x06, 0x00, 0x00, 0x10, 0x23, 0x30, 0x11, 0x03, 0x31, 0x11,
|
||||
0x02, 0x33, 0x00, 0x00, 0x00, 0x22, 0x33, 0x20, 0x11, 0x13, 0x30, 0x11,
|
||||
0x03, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x11, 0x10, 0x23, 0x00,
|
||||
0x06, 0x33, 0x00, 0x24, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x01,
|
||||
0x11, 0x13, 0x33, 0x01, 0x10, 0x13, 0x32, 0x01, 0x11, 0x23, 0x24, 0x33,
|
||||
0x00, 0x06, 0x32, 0x01, 0x11, 0x00, 0x08, 0x33, 0x00, 0x38, 0x11, 0x10,
|
||||
0x23, 0x31, 0x11, 0x03, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x33,
|
||||
0x32, 0x01, 0x11, 0x33, 0x33, 0x30, 0x11, 0x03, 0x32, 0x01, 0x11, 0x33,
|
||||
0x01, 0x10, 0x08, 0x33, 0x00, 0x12, 0x30, 0x11, 0x03, 0x31, 0x11, 0x02,
|
||||
0x33, 0x01, 0x10, 0x00, 0x08, 0x33, 0x00, 0x0e, 0x30, 0x11, 0x03, 0x31,
|
||||
0x11, 0x02, 0x33, 0x00, 0x00, 0x00, 0x00, 0x22, 0x33, 0x20, 0x11, 0x23,
|
||||
0x30, 0x11, 0x03, 0x31, 0x11, 0x12, 0x33, 0x01, 0x10, 0x33, 0x11, 0x10,
|
||||
0x23, 0x00, 0x06, 0x33, 0x00, 0x28, 0x31, 0x11, 0x12, 0x33, 0x01, 0x00,
|
||||
0x33, 0x01, 0x11, 0x11, 0x00, 0x01, 0x12, 0x33, 0x32, 0x01, 0x11, 0x11,
|
||||
0x00, 0x23, 0x20, 0x33, 0x00, 0x06, 0x32, 0x01, 0x12, 0x00, 0x08, 0x33,
|
||||
0x00, 0x38, 0x11, 0x10, 0x23, 0x30, 0x11, 0x03, 0x31, 0x11, 0x12, 0x33,
|
||||
0x01, 0x00, 0x33, 0x33, 0x32, 0x01, 0x11, 0x33, 0x33, 0x30, 0x11, 0x13,
|
||||
0x32, 0x01, 0x11, 0x33, 0x01, 0x11, 0x08, 0x33, 0x00, 0x12, 0x30, 0x11,
|
||||
0x03, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x00, 0x08, 0x33, 0x00, 0x0e,
|
||||
0x30, 0x11, 0x03, 0x31, 0x11, 0x02, 0x33, 0x00, 0x00, 0x00, 0x00, 0x22,
|
||||
0x33, 0x20, 0x11, 0x11, 0x00, 0x11, 0x03, 0x31, 0x11, 0x11, 0x00, 0x01,
|
||||
0x10, 0x33, 0x11, 0x10, 0x23, 0x00, 0x06, 0x33, 0x00, 0x10, 0x31, 0x11,
|
||||
0x11, 0x00, 0x01, 0x13, 0x33, 0x01, 0x08, 0x11, 0x00, 0x10, 0x12, 0x33,
|
||||
0x32, 0x01, 0x11, 0x11, 0x10, 0x23, 0x20, 0x33, 0x00, 0x60, 0x32, 0x01,
|
||||
0x11, 0x10, 0x00, 0x03, 0x33, 0x11, 0x10, 0x23, 0x30, 0x11, 0x03, 0x31,
|
||||
0x11, 0x12, 0x22, 0x01, 0x02, 0x33, 0x33, 0x32, 0x01, 0x11, 0x33, 0x33,
|
||||
0x30, 0x11, 0x12, 0x21, 0x01, 0x11, 0x33, 0x01, 0x11, 0x22, 0x22, 0x23,
|
||||
0x33, 0x30, 0x11, 0x12, 0x21, 0x11, 0x02, 0x33, 0x01, 0x10, 0x08, 0x33,
|
||||
0x00, 0x0e, 0x30, 0x11, 0x12, 0x21, 0x10, 0x13, 0x33, 0x00, 0x00, 0x00,
|
||||
0x00, 0x22, 0x33, 0x20, 0x11, 0x00, 0x11, 0x11, 0x03, 0x31, 0x11, 0x00,
|
||||
0x01, 0x11, 0x10, 0x33, 0x11, 0x10, 0x23, 0x00, 0x06, 0x33, 0x00, 0x28,
|
||||
0x31, 0x11, 0x00, 0x01, 0x11, 0x13, 0x33, 0x01, 0x11, 0x00, 0x01, 0x11,
|
||||
0x12, 0x33, 0x32, 0x01, 0x11, 0x00, 0x00, 0x23, 0x20, 0x33, 0x00, 0x60,
|
||||
0x32, 0x01, 0x10, 0x01, 0x11, 0x12, 0x33, 0x11, 0x10, 0x23, 0x30, 0x11,
|
||||
0x03, 0x31, 0x11, 0x10, 0x10, 0x11, 0x13, 0x33, 0x33, 0x32, 0x01, 0x11,
|
||||
0x33, 0x33, 0x30, 0x11, 0x10, 0x10, 0x11, 0x11, 0x33, 0x01, 0x11, 0x01,
|
||||
0x00, 0x01, 0x23, 0x30, 0x11, 0x00, 0x10, 0x11, 0x02, 0x33, 0x01, 0x10,
|
||||
0x08, 0x33, 0x00, 0x0e, 0x30, 0x11, 0x00, 0x10, 0x11, 0x23, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x22, 0x33, 0x20, 0x11, 0x13, 0x31, 0x11, 0x03, 0x31,
|
||||
0x11, 0x02, 0x33, 0x11, 0x10, 0x33, 0x11, 0x10, 0x23, 0x00, 0x06, 0x33,
|
||||
0x00, 0x24, 0x31, 0x11, 0x02, 0x33, 0x11, 0x10, 0x33, 0x01, 0x11, 0x03,
|
||||
0x33, 0x11, 0x11, 0x13, 0x32, 0x01, 0x11, 0x23, 0x24, 0x33, 0x00, 0x60,
|
||||
0x32, 0x01, 0x11, 0x33, 0x11, 0x10, 0x33, 0x11, 0x10, 0x23, 0x30, 0x11,
|
||||
0x03, 0x31, 0x11, 0x01, 0x22, 0x11, 0x12, 0x33, 0x33, 0x32, 0x01, 0x11,
|
||||
0x33, 0x33, 0x30, 0x11, 0x02, 0x22, 0x11, 0x11, 0x33, 0x01, 0x10, 0x22,
|
||||
0x21, 0x11, 0x13, 0x30, 0x11, 0x02, 0x21, 0x11, 0x02, 0x33, 0x01, 0x10,
|
||||
0x08, 0x33, 0x00, 0x0e, 0x30, 0x11, 0x02, 0x21, 0x11, 0x23, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x22, 0x33, 0x20, 0x11, 0x13, 0x30, 0x11, 0x03, 0x31,
|
||||
0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x11, 0x10, 0x23, 0x00, 0x06, 0x33,
|
||||
0x00, 0x24, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x01, 0x11, 0x13,
|
||||
0x33, 0x01, 0x11, 0x13, 0x32, 0x01, 0x11, 0x23, 0x24, 0x33, 0x00, 0x60,
|
||||
0x32, 0x01, 0x11, 0x33, 0x01, 0x10, 0x33, 0x11, 0x11, 0x23, 0x30, 0x11,
|
||||
0x03, 0x31, 0x11, 0x12, 0x33, 0x11, 0x10, 0x33, 0x33, 0x32, 0x01, 0x11,
|
||||
0x33, 0x33, 0x30, 0x11, 0x13, 0x32, 0x11, 0x11, 0x33, 0x01, 0x11, 0x33,
|
||||
0x21, 0x11, 0x13, 0x30, 0x11, 0x03, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10,
|
||||
0x08, 0x33, 0x00, 0x0e, 0x30, 0x11, 0x03, 0x31, 0x11, 0x02, 0x33, 0x00,
|
||||
0x00, 0x00, 0x00, 0x22, 0x33, 0x20, 0x11, 0x13, 0x30, 0x11, 0x03, 0x31,
|
||||
0x11, 0x12, 0x33, 0x01, 0x00, 0x33, 0x11, 0x11, 0x23, 0x00, 0x06, 0x33,
|
||||
0x00, 0x2c, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x01, 0x11, 0x11,
|
||||
0x00, 0x01, 0x10, 0x13, 0x32, 0x01, 0x11, 0x11, 0x00, 0x00, 0x01, 0x23,
|
||||
0x1c, 0x33, 0x00, 0x60, 0x32, 0x01, 0x12, 0x33, 0x01, 0x00, 0x33, 0x11,
|
||||
0x11, 0x22, 0x20, 0x11, 0x03, 0x31, 0x11, 0x12, 0x22, 0x01, 0x10, 0x33,
|
||||
0x33, 0x32, 0x01, 0x12, 0x33, 0x33, 0x30, 0x11, 0x12, 0x21, 0x01, 0x11,
|
||||
0x33, 0x01, 0x11, 0x22, 0x10, 0x11, 0x13, 0x30, 0x11, 0x12, 0x21, 0x11,
|
||||
0x02, 0x33, 0x01, 0x11, 0x08, 0x33, 0x00, 0x0e, 0x30, 0x11, 0x03, 0x31,
|
||||
0x11, 0x02, 0x33, 0x00, 0x00, 0x00, 0x00, 0x38, 0x33, 0x20, 0x11, 0x13,
|
||||
0x30, 0x11, 0x03, 0x32, 0x11, 0x11, 0x00, 0x01, 0x02, 0x33, 0x21, 0x11,
|
||||
0x10, 0x00, 0x00, 0x13, 0x31, 0x11, 0x02, 0x33, 0x01, 0x10, 0x33, 0x01,
|
||||
0x08, 0x11, 0x00, 0x08, 0x12, 0x33, 0x33, 0x21, 0x08, 0x11, 0x02, 0x10,
|
||||
0x02, 0x23, 0x1c, 0x33, 0x00, 0x0e, 0x32, 0x01, 0x11, 0x10, 0x01, 0x02,
|
||||
0x33, 0x00, 0x06, 0x11, 0x00, 0x62, 0x01, 0x10, 0x03, 0x31, 0x11, 0x11,
|
||||
0x10, 0x11, 0x00, 0x33, 0x10, 0x00, 0x01, 0x11, 0x10, 0x13, 0x30, 0x11,
|
||||
0x11, 0x10, 0x11, 0x01, 0x33, 0x01, 0x11, 0x11, 0x01, 0x10, 0x13, 0x30,
|
||||
0x11, 0x11, 0x00, 0x10, 0x02, 0x33, 0x01, 0x11, 0x10, 0x00, 0x00, 0x23,
|
||||
0x30, 0x11, 0x03, 0x31, 0x11, 0x02, 0x33, 0x00, 0x00, 0x00, 0x00, 0x12,
|
||||
0x33, 0x20, 0x00, 0x13, 0x31, 0x00, 0x03, 0x33, 0x20, 0x00, 0x06, 0x00,
|
||||
0x00, 0x06, 0x13, 0x33, 0x32, 0x00, 0x08, 0x00, 0x00, 0x12, 0x03, 0x32,
|
||||
0x00, 0x02, 0x33, 0x10, 0x00, 0x33, 0x10, 0x00, 0x08, 0x00, 0x00, 0x08,
|
||||
0x02, 0x33, 0x33, 0x30, 0x0a, 0x00, 0x02, 0x23, 0x1c, 0x33, 0x02, 0x32,
|
||||
0x08, 0x00, 0x00, 0x06, 0x03, 0x33, 0x32, 0x00, 0x06, 0x00, 0x00, 0x06,
|
||||
0x01, 0x33, 0x32, 0x00, 0x08, 0x00, 0x00, 0x06, 0x13, 0x33, 0x20, 0x00,
|
||||
0x08, 0x00, 0x00, 0x06, 0x03, 0x33, 0x10, 0x00, 0x06, 0x00, 0x00, 0x06,
|
||||
0x23, 0x33, 0x10, 0x00, 0x06, 0x00, 0x00, 0x06, 0x02, 0x33, 0x33, 0x00,
|
||||
0x08, 0x00, 0x00, 0x06, 0x23, 0x33, 0x30, 0x00, 0x08, 0x00, 0x00, 0x10,
|
||||
0x23, 0x31, 0x00, 0x03, 0x32, 0x00, 0x02, 0x33, 0x00, 0x00, 0xe6, 0x33,
|
||||
0x00, 0x00, 0xe6, 0x33, 0x00, 0x00, 0xe6, 0x33, 0x00, 0x00, 0xe6, 0x33,
|
||||
0x00, 0x01};
|
||||
unsigned int splash_new__new_t_len = 3854;
|
||||
@@ -81,8 +81,6 @@ void CVSSpamView::start_tx(const uint32_t id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t sample_rate = 250000;
|
||||
|
||||
current_file = cvsfiles_dir / file_list[id].filename();
|
||||
|
||||
File capture_file;
|
||||
@@ -99,20 +97,13 @@ void CVSSpamView::start_tx(const uint32_t id) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto metadata_path = get_metadata_path(current_file);
|
||||
auto metadata = read_metadata_file(metadata_path);
|
||||
if (!metadata) {
|
||||
metadata = capture_metadata{transmitter_model.target_frequency(), sample_rate};
|
||||
}
|
||||
|
||||
auto file_size = capture_file.size();
|
||||
capture_file.close();
|
||||
|
||||
replay_thread.reset();
|
||||
transmitter_model.disable();
|
||||
ready_signal = false;
|
||||
|
||||
baseband::set_sample_rate(metadata->sample_rate, get_oversample_rate(metadata->sample_rate));
|
||||
baseband::set_sample_rate(SAMPLE_RATE, get_oversample_rate(SAMPLE_RATE));
|
||||
|
||||
auto reader = std::make_unique<FileConvertReader>();
|
||||
if (auto error = reader->open(current_file)) {
|
||||
@@ -120,10 +111,7 @@ void CVSSpamView::start_tx(const uint32_t id) {
|
||||
"Cannot read C16 data.\n"
|
||||
"Check file format/perms.\n"
|
||||
"Rate: " +
|
||||
to_string_dec_uint(metadata->sample_rate) +
|
||||
"\n"
|
||||
"Size: " +
|
||||
to_string_dec_uint(file_size) +
|
||||
to_string_dec_uint(SAMPLE_RATE) +
|
||||
"\n"
|
||||
"Error: " +
|
||||
std::to_string(static_cast<uint32_t>(error)));
|
||||
@@ -132,9 +120,9 @@ void CVSSpamView::start_tx(const uint32_t id) {
|
||||
|
||||
progressbar.set_value(0);
|
||||
|
||||
transmitter_model.set_sampling_rate(get_actual_sample_rate(metadata->sample_rate));
|
||||
transmitter_model.set_baseband_bandwidth(metadata->sample_rate <= 500000 ? 1750000 : 2500000);
|
||||
transmitter_model.set_target_frequency(metadata->center_frequency);
|
||||
transmitter_model.set_sampling_rate(get_actual_sample_rate(SAMPLE_RATE));
|
||||
transmitter_model.set_baseband_bandwidth(SAMPLE_RATE <= 500000 ? 1750000 : 2500000);
|
||||
transmitter_model.set_target_frequency(TARGET_FREQUENCY);
|
||||
transmitter_model.enable();
|
||||
|
||||
chThdSleepMilliseconds(100);
|
||||
@@ -164,7 +152,6 @@ void CVSSpamView::start_random_tx() {
|
||||
lfsr_v = lfsr_iterate(lfsr_v);
|
||||
size_t random_index = lfsr_v % file_list.size();
|
||||
|
||||
const uint32_t sample_rate = 250000;
|
||||
current_file = cvsfiles_dir / file_list[random_index].filename();
|
||||
|
||||
File capture_file;
|
||||
@@ -174,19 +161,13 @@ void CVSSpamView::start_random_tx() {
|
||||
return;
|
||||
}
|
||||
|
||||
auto metadata_path = get_metadata_path(current_file);
|
||||
auto metadata = read_metadata_file(metadata_path);
|
||||
if (!metadata) {
|
||||
metadata = capture_metadata{transmitter_model.target_frequency(), sample_rate};
|
||||
}
|
||||
|
||||
capture_file.close();
|
||||
|
||||
replay_thread.reset();
|
||||
transmitter_model.disable();
|
||||
ready_signal = false;
|
||||
|
||||
baseband::set_sample_rate(metadata->sample_rate, get_oversample_rate(metadata->sample_rate));
|
||||
baseband::set_sample_rate(SAMPLE_RATE, get_oversample_rate(SAMPLE_RATE));
|
||||
|
||||
auto reader = std::make_unique<FileConvertReader>();
|
||||
if (auto error = reader->open(current_file)) {
|
||||
@@ -196,9 +177,9 @@ void CVSSpamView::start_random_tx() {
|
||||
|
||||
progressbar.set_value(0);
|
||||
|
||||
transmitter_model.set_sampling_rate(get_actual_sample_rate(metadata->sample_rate));
|
||||
transmitter_model.set_baseband_bandwidth(metadata->sample_rate <= 500000 ? 1750000 : 2500000);
|
||||
transmitter_model.set_target_frequency(metadata->center_frequency);
|
||||
transmitter_model.set_sampling_rate(get_actual_sample_rate(SAMPLE_RATE));
|
||||
transmitter_model.set_baseband_bandwidth(SAMPLE_RATE <= 500000 ? 1750000 : 2500000);
|
||||
transmitter_model.set_target_frequency(TARGET_FREQUENCY);
|
||||
transmitter_model.enable();
|
||||
|
||||
chThdSleepMilliseconds(100);
|
||||
|
||||
@@ -16,6 +16,9 @@ using namespace portapack;
|
||||
|
||||
namespace ui::external_app::cvs_spam {
|
||||
|
||||
constexpr uint32_t SAMPLE_RATE = 250000;
|
||||
constexpr uint64_t TARGET_FREQUENCY = 433920000;
|
||||
|
||||
class CVSSpamView : public View {
|
||||
public:
|
||||
explicit CVSSpamView(NavigationView& nav);
|
||||
|
||||
11
firmware/application/external/external.cmake
vendored
11
firmware/application/external/external.cmake
vendored
@@ -196,6 +196,13 @@ set(EXTCPPSRC
|
||||
external/debug_pmem/main.cpp
|
||||
external/debug_pmem/ui_debug_pmem.cpp
|
||||
|
||||
#scanner
|
||||
external/scanner/main.cpp
|
||||
external/scanner/ui_scanner.cpp
|
||||
|
||||
#level
|
||||
external/level/main.cpp
|
||||
external/level/ui_level.cpp
|
||||
)
|
||||
|
||||
set(EXTAPPLIST
|
||||
@@ -245,5 +252,7 @@ set(EXTAPPLIST
|
||||
stopwatch
|
||||
breakout
|
||||
doom
|
||||
debug_pmem
|
||||
debug_pmem
|
||||
scanner
|
||||
level
|
||||
)
|
||||
|
||||
14
firmware/application/external/external.ld
vendored
14
firmware/application/external/external.ld
vendored
@@ -70,6 +70,8 @@ MEMORY
|
||||
ram_external_app_breakout (rwx) : org = 0xADDD0000, len = 32k
|
||||
ram_external_app_doom (rwx) : org = 0xADDE0000, len = 32k
|
||||
ram_external_app_debug_pmem (rwx) : org = 0xADDF0000, len = 32k
|
||||
ram_external_app_scanner (rwx) : org = 0xADE00000, len = 32k
|
||||
ram_external_app_level (rwx) : org = 0xADE10000, len = 32k
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
@@ -354,4 +356,16 @@ SECTIONS
|
||||
KEEP(*(.external_app.app_debug_pmem.application_information));
|
||||
*(*ui*external_app*debug_pmem*);
|
||||
} > ram_external_app_debug_pmem
|
||||
|
||||
.external_app_scanner : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.external_app.app_scanner.application_information));
|
||||
*(*ui*external_app*scanner*);
|
||||
} > ram_external_app_scanner
|
||||
|
||||
.external_app_level : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.external_app.app_level.application_information));
|
||||
*(*ui*external_app*level*);
|
||||
} > ram_external_app_level
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ void DebugFontsView::paint(Painter& painter) {
|
||||
|
||||
line_pos = display_font(painter, 32, Theme::getInstance()->bg_darkest, "Fixed 8x16", true);
|
||||
display_font(painter, line_pos + 16, Theme::getInstance()->bg_darkest_small, "Fixed 5x8", false);
|
||||
paint_zoomed_text(painter);
|
||||
}
|
||||
|
||||
void DebugFontsView::update_address_text() {
|
||||
@@ -74,16 +75,29 @@ void DebugFontsView::update_address_text() {
|
||||
text_address.set("0x" + to_string_hex(ascii_value, 2));
|
||||
}
|
||||
|
||||
void DebugFontsView::paint_zoomed_text(Painter& painter) {
|
||||
if (field_zoom_level.value() == 0) return;
|
||||
uint8_t cursor_pos = field_cursor.value();
|
||||
painter.draw_char({screen_width / 2, screen_height / 2},
|
||||
*Theme::getInstance()->bg_darkest,
|
||||
(char)(cursor_pos + 0x20), field_zoom_level.value());
|
||||
}
|
||||
|
||||
DebugFontsView::DebugFontsView(NavigationView& nav)
|
||||
: nav_{nav} {
|
||||
add_children({&field_cursor,
|
||||
&text_address});
|
||||
&text_address,
|
||||
&field_zoom_level});
|
||||
set_focusable(true);
|
||||
|
||||
field_cursor.on_change = [&](int32_t) {
|
||||
update_address_text();
|
||||
set_dirty();
|
||||
};
|
||||
|
||||
field_zoom_level.on_change = [&](int32_t) {
|
||||
set_dirty();
|
||||
};
|
||||
}
|
||||
|
||||
void DebugFontsView::focus() {
|
||||
|
||||
@@ -46,10 +46,17 @@ class DebugFontsView : public View {
|
||||
private:
|
||||
uint16_t display_font(Painter& painter, uint16_t y_offset, const Style* font_style, std::string_view font_name, bool is_big_font);
|
||||
void update_address_text();
|
||||
void paint_zoomed_text(Painter& painter);
|
||||
|
||||
NumberField field_cursor{
|
||||
{0 * 8, 0 * 8},
|
||||
4,
|
||||
{0, 1000},
|
||||
1,
|
||||
' '};
|
||||
NumberField field_zoom_level{
|
||||
{6 * 8, 0 * 8},
|
||||
4,
|
||||
{0, 1000},
|
||||
1,
|
||||
' '};
|
||||
|
||||
84
firmware/application/external/level/main.cpp
vendored
Normal file
84
firmware/application/external/level/main.cpp
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* 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_level.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "external_app.hpp"
|
||||
|
||||
namespace ui::external_app::level {
|
||||
void initialize_app(ui::NavigationView& nav) {
|
||||
nav.push<LevelView>();
|
||||
}
|
||||
} // namespace ui::external_app::level
|
||||
|
||||
extern "C" {
|
||||
|
||||
__attribute__((section(".external_app.app_level.application_information"), used)) application_information_t _application_information_level = {
|
||||
/*.memory_location = */ (uint8_t*)0x00000000,
|
||||
/*.externalAppEntry = */ ui::external_app::level::initialize_app,
|
||||
/*.header_version = */ CURRENT_HEADER_VERSION,
|
||||
/*.app_version = */ VERSION_MD5,
|
||||
|
||||
/*.app_name = */ "Level",
|
||||
/*.bitmap_data = */
|
||||
{
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x04,
|
||||
0x20,
|
||||
0x12,
|
||||
0x48,
|
||||
0x8A,
|
||||
0x51,
|
||||
0xCA,
|
||||
0x53,
|
||||
0xCA,
|
||||
0x53,
|
||||
0x8A,
|
||||
0x51,
|
||||
0x12,
|
||||
0x48,
|
||||
0x84,
|
||||
0x21,
|
||||
0xC0,
|
||||
0x03,
|
||||
0x40,
|
||||
0x02,
|
||||
0x60,
|
||||
0x06,
|
||||
0x20,
|
||||
0x04,
|
||||
0x30,
|
||||
0x0C,
|
||||
0xF0,
|
||||
0x0F},
|
||||
/*.icon_color = */ ui::Color::green().v,
|
||||
/*.menu_location = */ app_location_t::RX,
|
||||
/*.desired_menu_position = */ -1,
|
||||
|
||||
// this has to be the biggest baseband used by the app. Level is using AM,WFM,NFM,AMFM,SPEC and NFM is the biggest
|
||||
/*.m4_app_tag = portapack::spi_flash::image_tag_nfm */ {'P', 'N', 'F', 'M'},
|
||||
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
|
||||
};
|
||||
}
|
||||
@@ -33,7 +33,7 @@ using namespace portapack;
|
||||
using namespace tonekey;
|
||||
using portapack::memory::map::backup_ram;
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::level {
|
||||
|
||||
// Function to map the value from one range to another
|
||||
int32_t LevelView::map(int32_t value, int32_t fromLow, int32_t fromHigh, int32_t toLow, int32_t toHigh) {
|
||||
@@ -130,9 +130,16 @@ LevelView::LevelView(NavigationView& nav)
|
||||
|
||||
freqman_set_modulation_option(field_mode);
|
||||
field_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
if (v != -1) {
|
||||
change_mode(v);
|
||||
static freqman_index_t last_mode = WFM_MODULATION;
|
||||
if (v > SPEC_MODULATION) {
|
||||
if (last_mode == SPEC_MODULATION)
|
||||
v = AM_MODULATION;
|
||||
else
|
||||
v = SPEC_MODULATION;
|
||||
field_mode.set_selected_index(v);
|
||||
}
|
||||
last_mode = v;
|
||||
change_mode(v);
|
||||
};
|
||||
field_mode.set_by_value(radio_mode); // Reflect the mode into the manual selector
|
||||
field_bw.set_selected_index(radio_bw);
|
||||
@@ -277,15 +284,6 @@ size_t LevelView::change_mode(freqman_index_t new_mod) {
|
||||
field_bw.set_by_value(0);
|
||||
field_bw.on_change = [this](size_t index, OptionsField::value_t n) { radio_bw = index ; receiver_model.set_wfm_configuration(n); };
|
||||
break;
|
||||
case AMFM_MODULATION:
|
||||
audio_sampling_rate = audio::Rate::Hz_12000;
|
||||
freqman_set_bandwidth_option(new_mod, field_bw);
|
||||
baseband::run_image(portapack::spi_flash::image_tag_am_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::AMAudioFMApt);
|
||||
receiver_model.set_amfm_configuration(5); // Fix index 5 manually, not from freqman: set to RX AM (USB+FM) mode to demod audio tone, and get Wefax_APT signal.
|
||||
field_bw.set_by_value(0);
|
||||
field_bw.on_change = [this](size_t, OptionsField::value_t n) { (void)n; };
|
||||
break;
|
||||
case SPEC_MODULATION:
|
||||
audio_sampling_rate = audio::Rate::Hz_24000;
|
||||
freqman_set_bandwidth_option(new_mod, field_bw);
|
||||
@@ -338,4 +336,4 @@ void LevelView::on_freqchg(int64_t freq) {
|
||||
button_frequency.set_text("<" + to_string_short_freq(freq) + " MHz>");
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
} // namespace ui::external_app::level
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "ui_receiver.hpp"
|
||||
#include "ui_spectrum.hpp"
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::level {
|
||||
|
||||
class LevelView : public View {
|
||||
public:
|
||||
@@ -211,6 +211,6 @@ class LevelView : public View {
|
||||
}};
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
} // namespace ui::external_app::level
|
||||
|
||||
#endif
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "baseband_api.hpp"
|
||||
#include "audio.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "ui_textentry.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
|
||||
@@ -42,6 +43,7 @@ MetronomeView::MetronomeView(NavigationView& nav)
|
||||
&field_unaccent_beep_tune,
|
||||
&field_beep_flash_duration,
|
||||
&field_bpm,
|
||||
&button_enter_tap_tempo,
|
||||
&progressbar,
|
||||
});
|
||||
|
||||
@@ -59,6 +61,14 @@ MetronomeView::MetronomeView(NavigationView& nav)
|
||||
}
|
||||
};
|
||||
|
||||
button_enter_tap_tempo.on_select = [this](Button&) {
|
||||
auto tap_tempo_view = nav_.push<MetronomeTapTempoView>(field_bpm.value());
|
||||
|
||||
tap_tempo_view->on_apply = [this](uint16_t bpm) {
|
||||
field_bpm.set_value(bpm);
|
||||
};
|
||||
};
|
||||
|
||||
field_volume.set_value(0); // seems that a change is required to force update, so setting to 0 first
|
||||
field_volume.set_value(99);
|
||||
|
||||
@@ -174,4 +184,115 @@ void MetronomeView::run() {
|
||||
}
|
||||
}
|
||||
|
||||
MetronomeTapTempoView::MetronomeTapTempoView(NavigationView& nav, uint16_t bpm)
|
||||
: nav_{nav},
|
||||
bpm_{bpm} {
|
||||
add_children({
|
||||
&button_input,
|
||||
&button_tap,
|
||||
&button_cancel,
|
||||
&button_apply,
|
||||
});
|
||||
|
||||
bpm_when_entered_ = bpm; // save for if user cancel
|
||||
|
||||
// im aware that we have duplicated painter which means in this app, weo have two painter instances
|
||||
// here is the reason why this is necessary:
|
||||
// We need to draw the bpm big font once when enter, which would be at bad timing in constructor,
|
||||
// cuz it happened before the view is pushed to nav, which casued it actually didn't draw
|
||||
// which leads me have to override the paint func from father and draw inside of it.
|
||||
//
|
||||
// BUT I can't completely package the draw logic inside of the paint func,
|
||||
// cuz set_dirty has flaw and cause screen flicker during the char changes, if i just package there and use set_dirty()
|
||||
Painter painter_instance_2;
|
||||
|
||||
button_input.on_select = [this](Button&) {
|
||||
input_buffer = to_string_dec_uint(bpm_);
|
||||
text_prompt(
|
||||
nav_,
|
||||
input_buffer,
|
||||
3,
|
||||
[this](std::string& buffer) {
|
||||
if (buffer.empty()) {
|
||||
return;
|
||||
}
|
||||
bpm_ = atoi(buffer.c_str());
|
||||
|
||||
if (on_apply) {
|
||||
on_apply(bpm_);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
button_tap.on_select = [&](Button&) {
|
||||
on_tap(painter_instance_2);
|
||||
};
|
||||
|
||||
button_apply.on_select = [this](Button&) {
|
||||
// it's dynamically applied in tap handler
|
||||
// the design allow user to hear changes before apply
|
||||
nav_.pop();
|
||||
};
|
||||
|
||||
button_cancel.on_select = [this](Button&) {
|
||||
bpm_ = bpm_when_entered_;
|
||||
if (on_apply) {
|
||||
on_apply(bpm_);
|
||||
}
|
||||
nav_.pop();
|
||||
};
|
||||
}
|
||||
|
||||
void MetronomeTapTempoView::focus() {
|
||||
button_tap.focus();
|
||||
}
|
||||
|
||||
void MetronomeTapTempoView::paint(Painter& painter) {
|
||||
View::paint(painter);
|
||||
painter.draw_char({(0 * 16) * 4 + 2 * 16, 3 * 16}, *Theme::getInstance()->fg_light, '0' + bpm_ / 100, 4);
|
||||
painter.draw_char({(1 * 16) * 4 + 2 * 16, 3 * 16}, *Theme::getInstance()->fg_light, '0' + (bpm_ / 10) % 10, 4);
|
||||
painter.draw_char({(2 * 16) * 4 + 2 * 16, 3 * 16}, *Theme::getInstance()->fg_light, '0' + bpm_ % 10, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
NB: i don't really know if the cpu clock is 1000Hz AKA 1ms per tick for chTimeNow()
|
||||
but it should be, refering to the stop watch app.
|
||||
and also i compared with my real metronome and it's very close
|
||||
so I assume it's 1ms per tick
|
||||
*/
|
||||
void MetronomeTapTempoView::on_tap(Painter& painter) {
|
||||
/* ^ NB: this painter accepted from painter_instance_2*/
|
||||
systime_t current_time = chTimeNow();
|
||||
if (last_tap_time > 0) {
|
||||
uint32_t interval_ms = current_time - last_tap_time;
|
||||
|
||||
if (interval_ms > 100) {
|
||||
uint16_t this_time_bpm = 60000 / interval_ms;
|
||||
|
||||
if (this_time_bpm > 0 && this_time_bpm < 400) {
|
||||
bpms_deque.push_back(this_time_bpm);
|
||||
if (bpms_deque.size() > 4) { // one bar length cuz most music tempo is quarter note as 1 beat
|
||||
bpms_deque.pop_front();
|
||||
}
|
||||
|
||||
// avg
|
||||
uint32_t sum = 0;
|
||||
for (auto& bpm : bpms_deque) {
|
||||
sum += bpm;
|
||||
}
|
||||
bpm_ = sum / bpms_deque.size();
|
||||
|
||||
if (on_apply) {
|
||||
on_apply(bpm_);
|
||||
}
|
||||
|
||||
painter.draw_char({(0 * 16) * 4 + 2 * 16, 3 * 16}, *Theme::getInstance()->fg_light, '0' + bpm_ / 100, 4);
|
||||
painter.draw_char({(1 * 16) * 4 + 2 * 16, 3 * 16}, *Theme::getInstance()->fg_light, '0' + (bpm_ / 10) % 10, 4);
|
||||
painter.draw_char({(2 * 16) * 4 + 2 * 16, 3 * 16}, *Theme::getInstance()->fg_light, '0' + bpm_ % 10, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
last_tap_time = current_time;
|
||||
}
|
||||
|
||||
} // namespace ui::external_app::metronome
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "audio.hpp"
|
||||
#include "ch.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
namespace ui::external_app::metronome {
|
||||
|
||||
class MetronomeView : public View {
|
||||
@@ -73,6 +75,11 @@ class MetronomeView : public View {
|
||||
1,
|
||||
' '};
|
||||
|
||||
Button button_enter_tap_tempo{
|
||||
{(sizeof("BPM:") + 6) * 8, 1 * 16, (sizeof("Tap Tempo") + 3) * 8, 16},
|
||||
"Tap Tempo",
|
||||
};
|
||||
|
||||
NumberField field_rythm_unaccent_time{// e.g. 3 in 3/4 beat
|
||||
{(sizeof("Rhythm:") + 1) * 8, 4 * 16},
|
||||
2,
|
||||
@@ -121,6 +128,45 @@ class MetronomeView : public View {
|
||||
{0 * 16, 8 * 16, screen_width, screen_height - 14 * 16}};
|
||||
};
|
||||
|
||||
class MetronomeTapTempoView : public View {
|
||||
public:
|
||||
std::function<void(uint16_t)> on_apply{};
|
||||
|
||||
MetronomeTapTempoView(NavigationView& nav, uint16_t bpm);
|
||||
|
||||
std::string title() const override { return "Tap.T"; };
|
||||
void focus() override;
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
private:
|
||||
void on_tap(Painter& painter);
|
||||
|
||||
NavigationView& nav_;
|
||||
|
||||
uint16_t bpm_{0};
|
||||
uint16_t bpm_when_entered_{0}; // this pass from MetronomeView and need to restore if user cancel
|
||||
std::deque<uint16_t> bpms_deque = {0}; // take average for recent taps to debounce
|
||||
uint32_t last_tap_time{0};
|
||||
|
||||
std::string input_buffer{""}; // needed by text_prompt
|
||||
|
||||
Button button_input{
|
||||
{0, 0, screen_width, 2 * 16},
|
||||
"Input BPM"};
|
||||
|
||||
Button button_tap{
|
||||
{0, 8 * 16, screen_width, 7 * 16},
|
||||
"Tap BPM"};
|
||||
|
||||
Button button_cancel{
|
||||
{1, 17 * 16, screen_width / 2 - 4, 2 * 16},
|
||||
"Cancel"};
|
||||
|
||||
Button button_apply{
|
||||
{1 + screen_width / 2 + 1, 17 * 16, screen_width / 2 - 4, 2 * 16},
|
||||
"Apply"};
|
||||
};
|
||||
|
||||
} // namespace ui::external_app::metronome
|
||||
|
||||
#endif /*__UI_METRONOME_H__*/
|
||||
51
firmware/application/external/scanner/main.cpp
vendored
Normal file
51
firmware/application/external/scanner/main.cpp
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* 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_scanner.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "external_app.hpp"
|
||||
|
||||
namespace ui::external_app::scanner {
|
||||
void initialize_app(ui::NavigationView& nav) {
|
||||
nav.push<ScannerView>();
|
||||
}
|
||||
} // namespace ui::external_app::scanner
|
||||
|
||||
extern "C" {
|
||||
|
||||
__attribute__((section(".external_app.app_scanner.application_information"), used)) application_information_t _application_information_scanner = {
|
||||
/*.memory_location = */ (uint8_t*)0x00000000,
|
||||
/*.externalAppEntry = */ ui::external_app::scanner::initialize_app,
|
||||
/*.header_version = */ CURRENT_HEADER_VERSION,
|
||||
/*.app_version = */ VERSION_MD5,
|
||||
|
||||
/*.app_name = */ "Scanner",
|
||||
/*.bitmap_data = */ {0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x01, 0x80, 0x01, 0xC3, 0x00, 0xE0, 0xFF, 0xEF, 0xFF, 0xC0, 0x00, 0x83, 0x01, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00},
|
||||
/*.icon_color = */ ui::Color::green().v,
|
||||
/*.menu_location = */ app_location_t::RX,
|
||||
/*.desired_menu_position = */ -1,
|
||||
|
||||
// this has to be the biggest baseband used by the app. Scanner is using AM,WFM,NFM and NFM is the biggest
|
||||
/*.m4_app_tag = portapack::spi_flash::image_tag_scanner */ {'P', 'N', 'F', 'M'},
|
||||
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
|
||||
};
|
||||
}
|
||||
@@ -28,10 +28,11 @@
|
||||
#include "ui_freqman.hpp"
|
||||
#include "file_path.hpp"
|
||||
|
||||
using namespace ui;
|
||||
using namespace portapack;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::scanner {
|
||||
|
||||
ScannerThread::ScannerThread(std::vector<rf::Frequency> frequency_list)
|
||||
: frequency_list_{std::move(frequency_list)} {
|
||||
@@ -451,13 +452,14 @@ ScannerView::ScannerView(
|
||||
|
||||
// Mode field was changed (AM/NFM/WFM)
|
||||
field_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
static freqman_index_t last_mode = AM_MODULATION;
|
||||
// initialize to a value under SPEC
|
||||
static freqman_index_t last_mode = WFM_MODULATION;
|
||||
// unsupported SPEC mode fix
|
||||
if (v == SPEC_MODULATION) {
|
||||
if (last_mode == AM_MODULATION)
|
||||
v = WFM_MODULATION;
|
||||
else
|
||||
if (v >= SPEC_MODULATION) {
|
||||
if (last_mode == WFM_MODULATION)
|
||||
v = AM_MODULATION;
|
||||
else
|
||||
v = WFM_MODULATION;
|
||||
field_mode.set_selected_index(v);
|
||||
}
|
||||
last_mode = v;
|
||||
@@ -725,14 +727,6 @@ void ScannerView::change_mode(freqman_index_t new_mod) {
|
||||
field_bw.set_by_value(receiver_model.wfm_configuration());
|
||||
field_bw.on_change = [this](size_t, OptionsField::value_t n) { receiver_model.set_wfm_configuration(n); };
|
||||
break;
|
||||
case AMFM_MODULATION:
|
||||
freqman_set_bandwidth_option(new_mod, field_bw);
|
||||
baseband::run_image(portapack::spi_flash::image_tag_am_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::AMAudioFMApt);
|
||||
receiver_model.set_amfm_configuration(5);
|
||||
field_bw.set_by_value(0);
|
||||
field_bw.on_change = [this](size_t, OptionsField::value_t n) { (void)n; };
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -773,5 +767,4 @@ void ScannerView::restart_scan() {
|
||||
|
||||
start_scan_thread(); // RESTART SCANNER THREAD in selected mode
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
} // namespace ui::external_app::scanner
|
||||
@@ -35,12 +35,14 @@
|
||||
#include "ui_mictx.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
|
||||
using namespace ui;
|
||||
|
||||
namespace ui::external_app::scanner {
|
||||
|
||||
#define SCANNER_SLEEP_MS 50 // ms that Scanner Thread sleeps per loop
|
||||
#define STATISTICS_UPDATES_PER_SEC 10
|
||||
#define MAX_FREQ_LOCK 10 // # of 50ms cycles scanner locks into freq when signal detected, to verify signal is not spurious
|
||||
|
||||
namespace ui {
|
||||
|
||||
// TODO: There is too much duplicated data in these classes.
|
||||
// ScannerThread should just use more from the View.
|
||||
// Or perhaps ScannerThread should just be in the View.
|
||||
@@ -314,5 +316,4 @@ class ScannerView : public View {
|
||||
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
|
||||
}};
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
} // namespace ui::external_app::scanner
|
||||
@@ -1,6 +1,8 @@
|
||||
// CVS Spam app by RocketGod (@rocketgod-git) https://betaskynet.com
|
||||
// Original .cu8 files by @jimilinuxguy https://github.com/jimilinuxguy/customer-assistance-buttons-sdr
|
||||
// If you can read this, you're a nerd. :P
|
||||
// Come join us at https://discord.gg/thepiratesreborn
|
||||
|
||||
// RocketGod's Shopping Cart Lock app
|
||||
// https://betaskynet.com
|
||||
#include "ui.hpp"
|
||||
#include "shoppingcart_lock.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
@@ -57,10 +59,10 @@ __attribute__((section(".external_app.app_shoppingcart_lock.application_informat
|
||||
0x00,
|
||||
},
|
||||
/*.icon_color = */ ui::Color::red().v,
|
||||
/*.menu_location = */ app_location_t::TX,
|
||||
/*.menu_location = */ app_location_t::UTILITIES,
|
||||
/*.desired_menu_position = */ -1,
|
||||
|
||||
/*.m4_app_tag = portapack::spi_flash::image_tag_afsk_rx */ {'P', 'A', 'T', 'X'},
|
||||
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
|
||||
/*.m4_app_tag = portapack::spi_flash::image_tag_audio_tx */ {'P', 'A', 'T', 'X'},
|
||||
/*.m4_app_offset = */ 0x00000000,
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
// RocketGod's Shopping Cart Lock app
|
||||
// https://betaskynet.com
|
||||
// CVS Spam app by RocketGod (@rocketgod-git) https://betaskynet.com
|
||||
// Original .cu8 files by @jimilinuxguy https://github.com/jimilinuxguy/customer-assistance-buttons-sdr
|
||||
// If you can read this, you're a nerd. :P
|
||||
// Come join us at https://discord.gg/thepiratesreborn
|
||||
|
||||
#include "shoppingcart_lock.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
@@ -48,7 +51,6 @@ void ShoppingCartLock::stop() {
|
||||
audio::output::stop();
|
||||
|
||||
log_event("... Resetting State Variables");
|
||||
transmitter_model.disable();
|
||||
ready_signal = false;
|
||||
thread_sync_complete = false;
|
||||
looping = false;
|
||||
@@ -110,18 +112,24 @@ std::string ShoppingCartLock::list_wav_files() {
|
||||
}
|
||||
|
||||
void ShoppingCartLock::wait_for_thread() {
|
||||
uint32_t timeout = 100;
|
||||
uint32_t timeout = 1000;
|
||||
while (!ready_signal && timeout > 0) {
|
||||
chThdYield();
|
||||
timeout--;
|
||||
}
|
||||
if (!ready_signal) {
|
||||
log_event("!!! Timeout waiting for ReplayThread");
|
||||
}
|
||||
}
|
||||
|
||||
void ShoppingCartLock::restart_playback() {
|
||||
auto reader = std::make_unique<WAVFileReader>();
|
||||
std::string file_path = (wav_dir / current_file).string();
|
||||
|
||||
if (!reader->open(file_path)) return;
|
||||
if (!reader->open(file_path)) {
|
||||
log_event("!!! Failed to reopen " + current_file + " for restart");
|
||||
return;
|
||||
}
|
||||
|
||||
replay_thread = std::make_unique<ReplayThread>(
|
||||
std::move(reader),
|
||||
@@ -133,9 +141,8 @@ void ShoppingCartLock::restart_playback() {
|
||||
EventDispatcher::send_message(message);
|
||||
});
|
||||
|
||||
log_event(">> SENDING <<");
|
||||
log_event(">> RESTARTING AUDIO <<");
|
||||
audio::output::start();
|
||||
transmitter_model.enable();
|
||||
}
|
||||
|
||||
void ShoppingCartLock::play_audio(const std::string& filename, bool loop) {
|
||||
@@ -166,33 +173,24 @@ void ShoppingCartLock::play_audio(const std::string& filename, bool loop) {
|
||||
|
||||
wait_for_thread();
|
||||
|
||||
log_event("... Configuring Baseband");
|
||||
|
||||
const uint32_t bb_sample_rate = 1536000;
|
||||
const uint32_t decimation = bb_sample_rate / wav_sample_rate;
|
||||
|
||||
baseband::set_sample_rate(wav_sample_rate);
|
||||
audio::set_rate(wav_sample_rate <= 12000 ? audio::Rate::Hz_12000 : wav_sample_rate <= 24000 ? audio::Rate::Hz_24000
|
||||
: audio::Rate::Hz_48000);
|
||||
baseband::set_audiotx_config(
|
||||
bb_sample_rate / decimation,
|
||||
wav_sample_rate,
|
||||
0.0f,
|
||||
0.0f,
|
||||
5.0f,
|
||||
wav_bits_per_sample,
|
||||
wav_bits_per_sample,
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false);
|
||||
|
||||
baseband::set_sample_rate(wav_sample_rate);
|
||||
|
||||
log_event("... Starting Audio Output");
|
||||
audio::output::start();
|
||||
log_event("... Setting Max Volume");
|
||||
audio::headphone::set_volume(audio::headphone::volume_range().max);
|
||||
|
||||
transmitter_model.enable();
|
||||
|
||||
log_event(">>> Playback Started <<<");
|
||||
volume_t max_volume = audio::headphone::volume_range().max;
|
||||
audio::headphone::set_volume(max_volume);
|
||||
}
|
||||
|
||||
ShoppingCartLock::ShoppingCartLock(NavigationView& nav)
|
||||
@@ -225,9 +223,6 @@ ShoppingCartLock::ShoppingCartLock(NavigationView& nav)
|
||||
log_event("[+] INITIALIZATION COMPLETE");
|
||||
log_event("[+] PORTAPACK ARMED");
|
||||
log_event("[*] STATUS: READY");
|
||||
log_event("This app use speaker to");
|
||||
log_event("produce LF signal, but");
|
||||
log_event("also trigger radio TX");
|
||||
}
|
||||
|
||||
ShoppingCartLock::~ShoppingCartLock() {
|
||||
@@ -235,4 +230,4 @@ ShoppingCartLock::~ShoppingCartLock() {
|
||||
baseband::shutdown();
|
||||
}
|
||||
|
||||
} // namespace ui::external_app::shoppingcart_lock
|
||||
} // namespace ui::external_app::shoppingcart_lock
|
||||
@@ -1,5 +1,8 @@
|
||||
// RocketGod's Shopping Cart Lock app
|
||||
// https://betaskynet.com
|
||||
// CVS Spam app by RocketGod (@rocketgod-git) https://betaskynet.com
|
||||
// Original .cu8 files by @jimilinuxguy https://github.com/jimilinuxguy/customer-assistance-buttons-sdr
|
||||
// If you can read this, you're a nerd. :P
|
||||
// Come join us at https://discord.gg/thepiratesreborn
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui_widget.hpp"
|
||||
@@ -27,8 +30,8 @@ class ShoppingCartLock : public View {
|
||||
void focus() override;
|
||||
|
||||
private:
|
||||
static constexpr size_t BUFFER_SIZE = 8192;
|
||||
static constexpr size_t NUM_BUFFERS = 8;
|
||||
static constexpr size_t BUFFER_SIZE = 512;
|
||||
static constexpr size_t NUM_BUFFERS = 2;
|
||||
const std::string shoppingcart_lock_file{"shopping_cart_lock.wav"};
|
||||
const std::string shoppingcart_unlock_file{"shopping_cart_unlock.wav"};
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include "ui_navigation.hpp"
|
||||
|
||||
#include "bmp_modal_warning.hpp"
|
||||
#include "bmp_splash.hpp"
|
||||
#include "event_m0.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
@@ -44,7 +42,6 @@
|
||||
#include "ui_font_fixed_8x16.hpp"
|
||||
#include "ui_freqman.hpp"
|
||||
#include "ui_iq_trim.hpp"
|
||||
#include "ui_level.hpp"
|
||||
#include "ui_looking_glass_app.hpp"
|
||||
#include "ui_mictx.hpp"
|
||||
|
||||
@@ -52,7 +49,7 @@
|
||||
#include "ui_pocsag_tx.hpp"
|
||||
#include "ui_rds.hpp"
|
||||
#include "ui_recon.hpp"
|
||||
//#include "ui_scanner.hpp"
|
||||
// #include "ui_scanner.hpp"
|
||||
#include "ui_sd_over_usb.hpp"
|
||||
#include "ui_search.hpp"
|
||||
#include "ui_settings.hpp"
|
||||
@@ -133,22 +130,13 @@ const NavigationView::AppList NavigationView::appList = {
|
||||
{"ais", "AIS Boats", RX, Color::green(), &bitmap_icon_ais, new ViewFactory<AISAppView>()},
|
||||
{"aprsrx", "APRS", RX, Color::green(), &bitmap_icon_aprs, new ViewFactory<APRSRXView>()},
|
||||
{"audio", "Audio", RX, Color::green(), &bitmap_icon_speaker, new ViewFactory<AnalogAudioView>()},
|
||||
//{"blecomm", "BLE Comm", RX, ui::Color::orange(), &bitmap_icon_btle, new ViewFactory<BLECommView>()},
|
||||
{"blerx", "BLE Rx", RX, Color::green(), &bitmap_icon_btle, new ViewFactory<BLERxView>()},
|
||||
{"ert", "ERT Meter", RX, Color::green(), &bitmap_icon_ert, new ViewFactory<ERTAppView>()},
|
||||
{"level", "Level", RX, Color::green(), &bitmap_icon_options_radio, new ViewFactory<LevelView>()},
|
||||
{"pocsag", "POCSAG", RX, Color::green(), &bitmap_icon_pocsag, new ViewFactory<POCSAGAppView>()},
|
||||
{"radiosonde", "Radiosnde", RX, Color::green(), &bitmap_icon_sonde, new ViewFactory<SondeView>()},
|
||||
// {"scanner", "Scanner", RX, Color::green(), &bitmap_icon_scanner, new ViewFactory<ScannerView>()},
|
||||
{"search", "Search", RX, Color::yellow(), &bitmap_icon_search, new ViewFactory<SearchView>()},
|
||||
{"subghzd", "SubGhzD", RX, Color::yellow(), &bitmap_icon_remote, new ViewFactory<SubGhzDView>()},
|
||||
{"weather", "Weather", RX, Color::green(), &bitmap_icon_thermometer, new ViewFactory<WeatherView>()},
|
||||
//{"fskrx", "FSK RX", RX, Color::yellow(), &bitmap_icon_remote, new ViewFactory<FskxRxMainView>()}, //for JT
|
||||
//{"dmr", "DMR", RX, Color::dark_grey(), &bitmap_icon_dmr, new ViewFactory<NotImplementedView>()},
|
||||
//{"sigfox", "SIGFOX", RX, Color::dark_grey(), &bitmap_icon_fox, new ViewFactory<NotImplementedView>()},
|
||||
//{"lora", "LoRa", RX, Color::dark_grey(), &bitmap_icon_lora, new ViewFactory<NotImplementedView>()},
|
||||
//{"sstv", "SSTV", RX, Color::dark_grey(), &bitmap_icon_sstv, new ViewFactory<NotImplementedView>()},
|
||||
//{"tetra", "TETRA", RX, Color::dark_grey(), &bitmap_icon_tetra, new ViewFactory<NotImplementedView>()},
|
||||
/* TX ********************************************************************/
|
||||
{"aprstx", "APRS TX", TX, ui::Color::green(), &bitmap_icon_aprs, new ViewFactory<APRSTXView>()},
|
||||
{"bht", "BHT Xy/EP", TX, ui::Color::green(), &bitmap_icon_bht, new ViewFactory<BHTView>()},
|
||||
@@ -1049,7 +1037,12 @@ SplashScreenView::SplashScreenView(NavigationView& nav)
|
||||
void SplashScreenView::paint(Painter&) {
|
||||
if (!portapack::display.draw_bmp_from_sdcard_file({0, 0}, splash_dot_bmp))
|
||||
// ^ try draw bmp file from sdcard at (0,0), and the (0,0) already bypassed the status bar, so actual pos is (0, STATUS_BAR_HEIGHT)
|
||||
portapack::display.draw_bmp_from_bmp_hex_arr({(240 - 230) / 2, (320 - 50) / 2 - 10}, splash_bmp, (const uint8_t[]){0x29, 0x18, 0x16});
|
||||
portapack::display.draw_bitmap({screen_width / 2 - 120,
|
||||
screen_height / 2},
|
||||
bitmap_titlebar_image.size,
|
||||
bitmap_titlebar_image.data,
|
||||
Theme::getInstance()->bg_darkest->foreground,
|
||||
Theme::getInstance()->bg_darkest->background, 3);
|
||||
// ^ draw BMP HEX arr in firmware, note that the BMP HEX arr only cover the image part (instead of fill the screen with background, this position is located it in the center)
|
||||
}
|
||||
|
||||
@@ -1144,7 +1137,12 @@ ModalMessageView::ModalMessageView(
|
||||
}
|
||||
|
||||
void ModalMessageView::paint(Painter& painter) {
|
||||
if (!compact) portapack::display.draw_bmp_from_bmp_hex_arr({100, 48}, modal_warning_bmp, (const uint8_t[]){0, 0, 0});
|
||||
if (!compact) portapack::display.draw_bitmap({screen_width / 2 - 3 * 16 / 2,
|
||||
screen_height / 2 - 3 * 16 / 2 - 100},
|
||||
bitmap_icon_utilities.size,
|
||||
bitmap_icon_utilities.data,
|
||||
Theme::getInstance()->bg_darkest->foreground,
|
||||
Theme::getInstance()->bg_darkest->background, 3);
|
||||
|
||||
// Break lines.
|
||||
auto lines = split_string(message_, '\n');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
* copyleft 2025 Whiterose of the Dark Army
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
@@ -646,31 +647,58 @@ void ILI9341::draw_bitmap(
|
||||
const ui::Size size,
|
||||
const uint8_t* const pixels,
|
||||
const ui::Color foreground,
|
||||
const ui::Color background) {
|
||||
// Not a transparent background
|
||||
if (ui::Color::magenta().v != background.v) {
|
||||
lcd_start_ram_write(p, size);
|
||||
const ui::Color background,
|
||||
uint8_t zoom_level) {
|
||||
if (zoom_level <= 1) {
|
||||
// Not a transparent background
|
||||
if (ui::Color::magenta().v != background.v) {
|
||||
lcd_start_ram_write(p, size);
|
||||
|
||||
const size_t count = size.width() * size.height();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const auto pixel = pixels[i >> 3] & (1U << (i & 0x7));
|
||||
io.lcd_write_pixel(pixel ? foreground : background);
|
||||
}
|
||||
} else {
|
||||
int x = p.x();
|
||||
int y = p.y();
|
||||
int maxX = x + size.width();
|
||||
const size_t count = size.width() * size.height();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const auto pixel = pixels[i >> 3] & (1U << (i & 0x7));
|
||||
if (pixel) {
|
||||
draw_pixel(ui::Point(x, y), foreground);
|
||||
const size_t count = size.width() * size.height();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const auto pixel = pixels[i >> 3] & (1U << (i & 0x7));
|
||||
io.lcd_write_pixel(pixel ? foreground : background);
|
||||
}
|
||||
// Move to the next pixel
|
||||
x++;
|
||||
if (x >= maxX) {
|
||||
x = p.x();
|
||||
y++;
|
||||
} else {
|
||||
// transparent bg
|
||||
int x = p.x();
|
||||
int y = p.y();
|
||||
int maxX = x + size.width();
|
||||
const size_t count = size.width() * size.height();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const auto pixel = pixels[i >> 3] & (1U << (i & 0x7));
|
||||
if (pixel) {
|
||||
draw_pixel(ui::Point(x, y), foreground);
|
||||
}
|
||||
// move to next px
|
||||
x++;
|
||||
if (x >= maxX) {
|
||||
x = p.x();
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // zoom
|
||||
|
||||
// dot to square
|
||||
for (int y = 0; y < size.height(); y++) {
|
||||
for (int x = 0; x < size.width(); x++) {
|
||||
// pos
|
||||
size_t bit_index = y * size.width() + x;
|
||||
int byte_index = bit_index >> 3;
|
||||
int bit_pos = bit_index & 0x7;
|
||||
|
||||
// val
|
||||
const auto pixel = pixels[byte_index] & (1U << bit_pos);
|
||||
/* ^ the byte_index-th bit AKA current bit
|
||||
^ current px in current byte*/
|
||||
|
||||
if (pixel || background.v != ui::Color::magenta().v) {
|
||||
fill_rectangle(
|
||||
{p.x() + x * zoom_level, p.y() + y * zoom_level,
|
||||
zoom_level, zoom_level},
|
||||
pixel ? foreground : background);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -680,8 +708,9 @@ void ILI9341::draw_glyph(
|
||||
const ui::Point p,
|
||||
const ui::Glyph& glyph,
|
||||
const ui::Color foreground,
|
||||
const ui::Color background) {
|
||||
draw_bitmap(p, glyph.size(), glyph.pixels(), foreground, background);
|
||||
const ui::Color background,
|
||||
uint8_t zoom_level) {
|
||||
draw_bitmap(p, glyph.size(), glyph.pixels(), foreground, background, zoom_level);
|
||||
}
|
||||
|
||||
void ILI9341::scroll_set_area(
|
||||
|
||||
@@ -86,13 +86,15 @@ class ILI9341 {
|
||||
const ui::Size size,
|
||||
const uint8_t* const data,
|
||||
const ui::Color foreground,
|
||||
const ui::Color background);
|
||||
const ui::Color background,
|
||||
uint8_t zoom_level = 1);
|
||||
|
||||
void draw_glyph(
|
||||
const ui::Point p,
|
||||
const ui::Glyph& glyph,
|
||||
const ui::Color foreground,
|
||||
const ui::Color background);
|
||||
const ui::Color background,
|
||||
uint8_t zoom_level = 1);
|
||||
|
||||
/*** Scrolling ***
|
||||
* Scrolling support is implemented in the ILI9341 driver. Basically a region
|
||||
|
||||
@@ -36,34 +36,12 @@ Style Style::invert() const {
|
||||
.foreground = background};
|
||||
}
|
||||
|
||||
int Painter::draw_char(Point p, const Style& style, char c, uint8_t zoom_factor) {
|
||||
int Painter::draw_char(Point p, const Style& style, char c, uint8_t zoom_level) {
|
||||
const auto glyph = style.font.glyph(c);
|
||||
|
||||
if (zoom_factor <= 1) {
|
||||
display.draw_glyph(p, glyph, style.foreground, style.background);
|
||||
} else {
|
||||
// dot to square
|
||||
const uint8_t* pixels = glyph.pixels();
|
||||
for (int y = 0; y < glyph.h(); y++) { // each line
|
||||
for (int x = 0; x < glyph.w(); x++) { // each clum
|
||||
// pos
|
||||
int byte_index = (y * glyph.w() + x) / 8;
|
||||
int bit_pos = (y * glyph.w() + x) % 8;
|
||||
display.draw_glyph(p, glyph, style.foreground, style.background, zoom_level);
|
||||
|
||||
// fill
|
||||
Color pixel_color = ((pixels[byte_index] & (1 << bit_pos)) != 0) ? style.foreground : style.background;
|
||||
/* ^ true: fg, false: bg
|
||||
^ the byte_index-th bit AKA current bit
|
||||
^ current px in current byte */
|
||||
display.fill_rectangle(
|
||||
{p.x() + x * zoom_factor, p.y() + y * zoom_factor,
|
||||
zoom_factor, zoom_factor},
|
||||
pixel_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return glyph.advance().x() * zoom_factor;
|
||||
return glyph.advance().x() * zoom_level;
|
||||
}
|
||||
|
||||
int Painter::draw_string(Point p, const Style& style, std::string_view text) {
|
||||
|
||||
1
firmware/tools/bitmap_tools/.gitignore
vendored
Normal file
1
firmware/tools/bitmap_tools/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
bitmap.hpp
|
||||
127
firmware/tools/bitmap_tools/make_bitmap2.py
Normal file
127
firmware/tools/bitmap_tools/make_bitmap2.py
Normal file
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2016 Furrtek
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
import sys
|
||||
import struct
|
||||
from PIL import Image
|
||||
from os import listdir
|
||||
from os import path
|
||||
from os import makedirs
|
||||
|
||||
usage_message = f"""
|
||||
1BPP PortaPack bitmap.hpp generator
|
||||
|
||||
Usage: {sys.argv[0]} <directory>
|
||||
"""
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(usage_message)
|
||||
sys.exit(-1)
|
||||
|
||||
graphics_path = path.join(sys.argv[1], '')
|
||||
hex_output_dir = path.join(graphics_path, 'hex_files')
|
||||
|
||||
# Create hex output directory if it doesn't exist
|
||||
if not path.exists(hex_output_dir):
|
||||
makedirs(hex_output_dir)
|
||||
|
||||
def convert_png(file):
|
||||
c = 0
|
||||
data = 0
|
||||
|
||||
rgb_im = Image.open(file).convert('RGBA')
|
||||
|
||||
if rgb_im.size[0] % 8 or rgb_im.size[1] % 8:
|
||||
print((file + ": Size is not a multiple of 8. Image is not included in bitmap.hpp."))
|
||||
sys.exit(-1)
|
||||
|
||||
name = path.basename(file).split(".")[0].lower();
|
||||
|
||||
# Prepare data for both hpp and hex file
|
||||
hpp_lines = []
|
||||
hex_data = bytearray()
|
||||
|
||||
for i in range(rgb_im.size[1]):
|
||||
for j in range(rgb_im.size[0]):
|
||||
r, g, b, a = rgb_im.getpixel((j, i))
|
||||
|
||||
data >>= 1
|
||||
|
||||
if r > 127 and g > 127 and b > 127 and a > 127:
|
||||
data += 128
|
||||
|
||||
if j % 8 == 7:
|
||||
hpp_lines.append(" 0x%0.2X,\n" % data)
|
||||
hex_data.append(data)
|
||||
data = 0
|
||||
|
||||
# Write to hpp file
|
||||
f.write("static constexpr uint8_t bitmap_" + name + "_data[] = {\n")
|
||||
f.writelines(hpp_lines)
|
||||
f.write("};\n")
|
||||
f.write("static constexpr Bitmap bitmap_" + name + " {\n")
|
||||
f.write(" {" + str(rgb_im.size[0]) + ", " + str(rgb_im.size[1]) + "},\n bitmap_" + name + "_data};\n\n")
|
||||
|
||||
# Write to hex file
|
||||
hex_filename = path.join(hex_output_dir, name + ".hex")
|
||||
with open(hex_filename, 'wb') as hex_file:
|
||||
hex_file.write(hex_data)
|
||||
|
||||
return
|
||||
|
||||
count = 0
|
||||
|
||||
f = open('bitmap.hpp', 'w')
|
||||
f.write("/*\n"
|
||||
" * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.\n"
|
||||
" * Copyright (C) 2016 Furrtek\n"
|
||||
" *\n"
|
||||
" * This file is part of PortaPack.\n"
|
||||
" *\n"
|
||||
" * This program is free software; you can redistribute it and/or modify\n"
|
||||
" * it under the terms of the GNU General Public License as published by\n"
|
||||
" * the Free Software Foundation; either version 2, or (at your option)\n"
|
||||
" * any later version.\n"
|
||||
" *\n"
|
||||
" * This program is distributed in the hope that it will be useful,\n"
|
||||
" * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
" * GNU General Public License for more details.\n"
|
||||
" *\n"
|
||||
" * You should have received a copy of the GNU General Public License\n"
|
||||
" * along with this program; see the file COPYING. If not, write to\n"
|
||||
" * the Free Software Foundation, Inc., 51 Franklin Street,\n"
|
||||
" * Boston, MA 02110-1301, USA.\n"
|
||||
" */\n\n"
|
||||
"// This file was generated by make_bitmap.py\n\n"
|
||||
"#ifndef __BITMAP_HPP__\n"
|
||||
"#define __BITMAP_HPP__\n\n"
|
||||
"#include \"ui.hpp\"\n\n"
|
||||
"namespace ui {\n\n")
|
||||
|
||||
for file in listdir(graphics_path):
|
||||
if file.endswith(".png") and path.isfile(graphics_path + file):
|
||||
convert_png(graphics_path + file)
|
||||
count += 1
|
||||
|
||||
f.write("} /* namespace ui */\n\n")
|
||||
f.write("#endif/*__BITMAP_HPP__*/\n")
|
||||
|
||||
print(("Converted " + str(count) + " files"))
|
||||
@@ -137,7 +137,12 @@ def get_pp_device_linux():
|
||||
parts = clean_line.split()
|
||||
|
||||
if len(parts) >= 2 and SDCARD_LABEL in parts[1]: # checker
|
||||
print("found pp sd:")
|
||||
device_path = parts[0]
|
||||
#remove `- in it
|
||||
device_path = device_path.replace('-', '')
|
||||
device_path = device_path.replace('`', '')
|
||||
print(device_path)
|
||||
# if path valid
|
||||
if not os.path.exists(device_path):
|
||||
continue
|
||||
|
||||
5
pull_request_template.md
Normal file
5
pull_request_template.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## Brief description what you did
|
||||
|
||||
## Checklist
|
||||
- [ ] Kept changes minimal and limited to necessary files
|
||||
- [ ] Verified functionality remains intact and code compiles
|
||||
@@ -1,25 +0,0 @@
|
||||
# Description: WEather FAX list
|
||||
# Author: gullradriel
|
||||
|
||||
# Deutscher Wetterdienst (DWD) - Offenbach, Germany
|
||||
# Surface analysis: 04:30,10:50,16:36,22:00 UTC
|
||||
f=3855000,m=AMFM,bw=USB+FM,d=DWD DDH3 Analysis
|
||||
# Surface analysis, forecasts, warnings (continuous)
|
||||
f=7880000,m=AMFM,bw=USB+FM,d=DWD DDK3 Forecasts
|
||||
# Surface analysis & wave height (continuous)
|
||||
f=13882500,m=AMFM,bw=USB+FM,d=DWD DDK6 Waves
|
||||
|
||||
# Royal Navy (Northwood) - United Kingdom
|
||||
# Surface/Wave charts every 6 hrs
|
||||
f=2618500,m=AMFM,bw=USB+FM,d=Northwood 2.6MHz WX
|
||||
f=4610000,m=AMFM,bw=USB+FM,d=Northwood 4.6MHz WX
|
||||
f=8040000,m=AMFM,bw=USB+FM,d=Northwood 8.0MHz WX
|
||||
f=11086500,m=AMFM,bw=USB+FM,d=Northwood 11MHz WX
|
||||
|
||||
# United States Coast Guard (USCG) - Boston/NMF
|
||||
# Atlantic Analysis: 03:00,09:00,15:00,21:00 UTC
|
||||
f=6340500,m=AMFM,bw=USB+FM,d=USCG 6.3MHz Atlantic
|
||||
# Forecasts & Hurricane Warnings (continuous updates)
|
||||
f=9110000,m=AMFM,bw=USB+FM,d=USCG 9.1MHz WX Warn
|
||||
# Extended Marine Forecasts (continuous updates)
|
||||
f=12750000,m=AMFM,bw=USB+FM,d=USCG 12.7MHz Marine
|
||||
51
sdcard/FREQMAN/WEFAX_1.TXT
Normal file
51
sdcard/FREQMAN/WEFAX_1.TXT
Normal file
@@ -0,0 +1,51 @@
|
||||
# Description: WEather FAX list, part 1
|
||||
# See https://weatherfax.com/stations
|
||||
|
||||
# Australia
|
||||
f=2628000,m=AMFM,bw=USB+FM,d=VMC Charleville
|
||||
f=5100000,m=AMFM,bw=USB+FM,d=VMC Charleville
|
||||
f=11030000,m=AMFM,bw=USB+FM,d=VMC Charleville
|
||||
f=13920000,m=AMFM,bw=USB+FM,d=VMC Charleville
|
||||
f=20469000,m=AMFM,bw=USB+FM,d=VMC Charleville
|
||||
f=5755000,m=AMFM,bw=USB+FM,d=VMW Wiluna
|
||||
f=7535000,m=AMFM,bw=USB+FM,d=VMW Wiluna
|
||||
f=10555000,m=AMFM,bw=USB+FM,d=VMW Wiluna
|
||||
f=15615000,m=AMFM,bw=USB+FM,d=VMW Wiluna
|
||||
f=18060000,m=AMFM,bw=USB+FM,d=VMW Wiluna
|
||||
|
||||
# Canada
|
||||
f=4416000,m=AMFM,bw=USB+FM,d=VCO Sydney NS
|
||||
f=6915100,m=AMFM,bw=USB+FM,d=VCO Sydney NS
|
||||
f=4292000,m=AMFM,bw=USB+FM,d=VFA Inuvik
|
||||
f=8456000,m=AMFM,bw=USB+FM,d=VFA Inuvik
|
||||
f=3253000,m=AMFM,bw=USB+FM,d=VFF Iqaluit/VFR Resolute
|
||||
f=7710000,m=AMFM,bw=USB+FM,d=VFF Iqaluit/VFR Resolute
|
||||
|
||||
# Chile
|
||||
f=4322000,m=AMFM,bw=USB+FM,d=CBM Punta Arenas
|
||||
f=8696000,m=AMFM,bw=USB+FM,d=CBM Punta Arenas
|
||||
f=4228000,m=AMFM,bw=USB+FM,d=CBV Vaparaiso
|
||||
f=8677000,m=AMFM,bw=USB+FM,d=CBV Vaparaiso
|
||||
f=17146400,m=AMFM,bw=USB+FM,d=CBV Vaparaiso
|
||||
|
||||
# China
|
||||
f=4170000,m=AMFM,bw=USB+FM,d=XSG Shanghai
|
||||
f=8302000,m=AMFM,bw=USB+FM,d=XSG Shanghai
|
||||
f=12382000,m=AMFM,bw=USB+FM,d=XSG Shanghai
|
||||
f=16559000,m=AMFM,bw=USB+FM,d=XSG Shanghai
|
||||
f=4199800,m=AMFM,bw=USB+FM,d=XSQ Guangzhou
|
||||
f=8412500,m=AMFM,bw=USB+FM,d=XSQ Guangzhou
|
||||
f=12629300,m=AMFM,bw=USB+FM,d=XSQ Guangzhou
|
||||
f=16826300,m=AMFM,bw=USB+FM,d=XSQ Guangzhou
|
||||
|
||||
# Germany - Deutscher Wetterdienst (DWD) - Offenbach
|
||||
# Surface analysis: 04:30,10:50,16:36,22:00 UTC
|
||||
f=3855000,m=AMFM,bw=USB+FM,d=DWD DDH3 Analysis
|
||||
# Surface analysis, forecasts, warnings (continuous)
|
||||
f=7880000,m=AMFM,bw=USB+FM,d=DWD DDK3 Forecasts
|
||||
# Surface analysis & wave height (continuous)
|
||||
f=13882500,m=AMFM,bw=USB+FM,d=DWD DDK6 Waves
|
||||
|
||||
# Greece
|
||||
f=4482900,m=AMFM,bw=USB+FM,d=SVJ4 Athens
|
||||
f=8106900,m=AMFM,bw=USB+FM,d=SVJ4 Athens
|
||||
58
sdcard/FREQMAN/WEFAX_2.TXT
Normal file
58
sdcard/FREQMAN/WEFAX_2.TXT
Normal file
@@ -0,0 +1,58 @@
|
||||
# Description: WEather FAX list, part 2
|
||||
# See https://weatherfax.com/stations
|
||||
|
||||
# Japan
|
||||
f=3622500,m=AMFM,bw=USB+FM,d=JMH Tokyo
|
||||
f=7795000,m=AMFM,bw=USB+FM,d=JMH Tokyo
|
||||
f=13988500,m=AMFM,bw=USB+FM,d=JMH Tokyo
|
||||
f=16971000,m=AMFM,bw=USB+FM,d=JJC Tokyo
|
||||
f=4274000,m=AMFM,bw=USB+FM,d=JFX Kagoshima
|
||||
f=8658000,m=AMFM,bw=USB+FM,d=JFX Kagoshima
|
||||
f=13074000,m=AMFM,bw=USB+FM,d=JFX Kagoshima
|
||||
f=16907500,m=AMFM,bw=USB+FM,d=JFX Kagoshima
|
||||
f=22559600,m=AMFM,bw=USB+FM,d=JFX Kagoshima
|
||||
|
||||
# Korea
|
||||
f=3585000,m=AMFM,bw=USB+FM,d=HLL2 Seoul
|
||||
f=5857500,m=AMFM,bw=USB+FM,d=HLL2 Seoul
|
||||
f=7433500,m=AMFM,bw=USB+FM,d=HLL2 Seoul
|
||||
f=9165000,m=AMFM,bw=USB+FM,d=HLL2 Seoul
|
||||
f=13570000,m=AMFM,bw=USB+FM,d=HLL2 Seoul
|
||||
|
||||
# Russia
|
||||
f=6328500,m=AMFM,bw=USB+FM,d=UDK2 Murmansk
|
||||
f=8444000,m=AMFM,bw=USB+FM,d=UDK2 Murmansk
|
||||
f=2640000,m=AMFM,bw=USB+FM,d=St Petersburg RU
|
||||
f=4212000,m=AMFM,bw=USB+FM,d=St Petersburg RU
|
||||
f=6456900,m=AMFM,bw=USB+FM,d=Vanino RU
|
||||
|
||||
# Thailand
|
||||
f=7396900,m=AMFM,bw=USB+FM,d=HSW64 Bangkok
|
||||
|
||||
# United Kingdom - Royal Navy
|
||||
# Surface/Wave charts every 6 hrs
|
||||
f=2618500,m=AMFM,bw=USB+FM,d=GYA Northwood
|
||||
f=4610000,m=AMFM,bw=USB+FM,d=GYA Northwood
|
||||
f=8040000,m=AMFM,bw=USB+FM,d=GYA Northwood
|
||||
f=11086500,m=AMFM,bw=USB+FM,d=GYA Northwood
|
||||
|
||||
# United States - Coast Guard (USCG)
|
||||
f=4346000,m=AMFM,bw=USB+FM,d=NMC Point Reyes
|
||||
f=8682000,m=AMFM,bw=USB+FM,d=NMC Point Reyes
|
||||
f=12786000,m=AMFM,bw=USB+FM,d=NMC Point Reyes
|
||||
f=17151200,m=AMFM,bw=USB+FM,d=NMC Point Reyes
|
||||
f=22527000,m=AMFM,bw=USB+FM,d=NMC Point Reyes
|
||||
f=4235000,m=AMFM,bw=USB+FM,d=NMF Boston
|
||||
f=6340500,m=AMFM,bw=USB+FM,d=NMF Boston Atlantic
|
||||
f=9110000,m=AMFM,bw=USB+FM,d=NMF Boston WX Warn
|
||||
f=12750000,m=AMFM,bw=USB+FM,d=NMF Boston Marine
|
||||
f=4317900,m=AMFM,bw=USB+FM,d=NMG New Orleans
|
||||
f=8503900,m=AMFM,bw=USB+FM,d=NMG New Orleans
|
||||
f=12789900,m=AMFM,bw=USB+FM,d=NMG New Orleans
|
||||
f=17146400,m=AMFM,bw=USB+FM,d=NMG New Orleans
|
||||
f=4298000,m=AMFM,bw=USB+FM,d=NOJ Kodiak
|
||||
f=8459000,m=AMFM,bw=USB+FM,d=NOJ Kodiak
|
||||
f=12412500,m=AMFM,bw=USB+FM,d=NOJ Kodiak
|
||||
f=9982500,m=AMFM,bw=USB+FM,d=KVM70 Honolulu
|
||||
f=11090000,m=AMFM,bw=USB+FM,d=KVM70 Honolulu
|
||||
f=16135000,m=AMFM,bw=USB+FM,d=KVM70 Honolulu
|
||||
Reference in New Issue
Block a user