diff --git a/.github/workflows/changelog.py b/.github/workflows/changelog.py new file mode 100644 index 00000000..53780668 --- /dev/null +++ b/.github/workflows/changelog.py @@ -0,0 +1,28 @@ +import os +import re +import sys + +raw_git = os.popen('git log next --since="24 hours" --pretty=format:"- %h - {USERNAME}*+%al-%an*: %s"').read() + + +def compute_username(line): + stripped = re.search(r'(?<=\*)(.*?)(?=\*)', line).group(0) + + pattern = re.compile("[$@+&?].*[$@+&?]") + if pattern.match(stripped): + stripped = re.sub("[$@+&?].*[$@+&?]", "", stripped) + stripped = re.match(r'.+?(?=-)', stripped).group(0) + else: + stripped = re.sub(r'^.*?-', "", stripped) + return "@" + stripped + + +def compile_line(line): + username = compute_username(line) + line = re.sub(r'[*].*[*]', "", line) + line = line.replace("{USERNAME}", username) + return line + + +for row in raw_git.splitlines(): + print(compile_line(row)) diff --git a/.github/workflows/create_nightly_release.yml b/.github/workflows/create_nightly_release.yml index 004720a7..a4f953ac 100644 --- a/.github/workflows/create_nightly_release.yml +++ b/.github/workflows/create_nightly_release.yml @@ -1,5 +1,3 @@ -# ToDo: only trigger after 24 hours if there are actually changes: https://github.community/t/trigger-action-on-schedule-only-if-there-are-changes-to-the-branch/17887/4 - name: Nightly Release on: @@ -9,15 +7,35 @@ on: workflow_dispatch: jobs: + check_date: + runs-on: ubuntu-latest + name: Check latest commit + outputs: + should_run: ${{ steps.should_run.outputs.should_run }} + steps: + - uses: actions/checkout@v2 + - name: print latest_commit + run: echo ${{ github.sha }} + + - name: check latest commit is less than a day + id: should_run + continue-on-error: true + run: test -z $(git rev-list --after="24 hours" ${{ github.sha }}) && echo "::set-output name=should_run::false" build: + needs: check_date + if: ${{ needs.check_date.outputs.should_run != 'false' }} runs-on: ubuntu-latest steps: - name: Get current date id: date run: echo "::set-output name=date::$(date +'%Y-%m-%d')" + - name: Get version date + id: version_date + run: echo "::set-output name=date::n_$(date +'%y%m%d')" - name: Checkout uses: actions/checkout@master with: + fetch-depth: 0 ref: next submodules: true - name: Git Sumbodule Update @@ -28,13 +46,21 @@ jobs: - name: Make build folder run: mkdir ${{ github.workspace }}/build - name: Run the Docker image - run: docker run -i -v ${{ github.workspace }}:/havoc portapack-dev + run: docker run -e VERSION_STRING=${{ steps.version_date.outputs.date }} -i -v ${{ github.workspace }}:/havoc portapack-dev - name: Create Firmware ZIP run: | - zip --junk-paths firmware build/firmware/portapack-h1_h2-mayhem.bin + zip -j firmware.zip build/firmware/portapack-h1_h2-mayhem.bin && cd flashing && zip -r ../firmware.zip * - name: Create SD Card ZIP run: | zip -r sdcard.zip sdcard + - name: Create changelog + run: | + CHANGELOG=$(python3 .github/workflows/changelog.py) + CHANGELOG="${CHANGELOG//'%'/'%25'}" + CHANGELOG="${CHANGELOG//$'\n'/'%0A'}" + CHANGELOG="${CHANGELOG//$'\r'/'%0D'}" + echo "::set-output name=content::$CHANGELOG" + id: changelog - name: Create Release id: create_release uses: actions/create-release@v1 @@ -42,11 +68,13 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: nightly-tag-${{ steps.date.outputs.date }} - release_name: Nightly-release - ${{ steps.date.outputs.date }} + release_name: Nightly Release - ${{ steps.date.outputs.date }} body: | **Nightly release - ${{ steps.date.outputs.date }}** This build is the latest and greatest, although may not be the most stable as this is a nightly release. - You can find the changes in this commit ${{ github.sha }} + ## Release notes + ### Revision (${{ steps.version_date.outputs.date }}): + ${{ steps.changelog.outputs.content }} draft: false prerelease: true - name: Upload Firmware Asset @@ -57,7 +85,7 @@ jobs: with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ./firmware.zip - asset_name: mayhem_nightly_${{ steps.date.outputs.date }}_FIRMWARE.zip + asset_name: mayhem_nightly_${{ steps.version_date.outputs.date }}_FIRMWARE.zip asset_content_type: application/zip - name: Upload SD Card Assets id: upload-sd-card-asset @@ -67,5 +95,5 @@ jobs: with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ./sdcard.zip - asset_name: mayhem_nightly_${{ steps.date.outputs.date }}_COPY_TO_SDCARD.zip + asset_name: mayhem_nightly_${{ steps.version_date.outputs.date }}_COPY_TO_SDCARD.zip asset_content_type: application/zip diff --git a/.github/workflows/create_stable_release.yml b/.github/workflows/create_stable_release.yml new file mode 100644 index 00000000..53c6e45e --- /dev/null +++ b/.github/workflows/create_stable_release.yml @@ -0,0 +1,93 @@ +name: Stable Release + +on: + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Get current date + id: date + run: echo "::set-output name=date::$(date +'%Y-%m-%d')" + - name: Checkout + uses: actions/checkout@master + with: + fetch-depth: 0 + ref: next + submodules: true + - name: Git Sumbodule Update + run: | + git submodule update --init --recursive + - name: Get version + id: version + run: echo "::set-output name=version::$(cat .github/workflows/version.txt)" + - name: Get past version + id: past_version + run: echo "::set-output name=past_version::$(cat .github/workflows/past_version.txt)" + - name: Build the Docker image + run: docker build -t portapack-dev -f dockerfile-nogit . --tag my-image-name:$(date +%s) + - name: Make build folder + run: mkdir ${{ github.workspace }}/build + - name: Run the Docker image + run: docker run -e VERSION_STRING=${{ steps.version.outputs.version }} -i -v ${{ github.workspace }}:/havoc portapack-dev + - name: Create Firmware ZIP + run: | + zip -j firmware.zip build/firmware/portapack-h1_h2-mayhem.bin && cd flashing && zip -r ../firmware.zip * + - name: Create SD Card ZIP + run: | + zip -r sdcard.zip sdcard + - name: Create changelog + run: | + CHANGELOG=$(python3 .github/workflows/stable_changelog.py ${{ steps.past_version.outputs.past_version }}) + CHANGELOG="${CHANGELOG//'%'/'%25'}" + CHANGELOG="${CHANGELOG//$'\n'/'%0A'}" + CHANGELOG="${CHANGELOG//$'\r'/'%0D'}" + echo "::set-output name=content::$CHANGELOG" + id: changelog + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: v1.5.1 + release_name: Mayhem firmware ${{ steps.version.outputs.version }} + body: | + **Stable release - ${{ steps.version.outputs.version }}** + 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/). Please check the [readme](https://github.com/eried/portapack-mayhem/blob/master/README.md) for details. + ## Release notes + ### Revision (${{ steps.version.outputs.version }}): + ${{ steps.changelog.outputs.content }} + + **Full Changelog**: https://github.com/eried/portapack-mayhem/compare/${{ steps.past_version.outputs.past_version }}...${{ steps.version.outputs.version }} + + ## Installation + Check the [wiki](https://github.com/eried/portapack-havoc/wiki/Update-firmware) for details how to upgrade. + + ### MicroSD card files + + For certain functionality, like the world map, GPS simulator, and others you need to uncompress (using [7-zip](https://www.7-zip.org/download.html)) the files from `mayhem_vX.Y.Z_COPY_TO_SDCARD.zip` to a FAT32 formatted MicroSD card. + draft: true + prerelease: false + - name: Upload Firmware Asset + id: upload-firmware-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./firmware.zip + asset_name: mayhem_${{ steps.version.outputs.version }}_FIRMWARE.zip + asset_content_type: application/zip + - name: Upload SD Card Assets + id: upload-sd-card-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./sdcard.zip + asset_name: mayhem_${{ steps.version.outputs.version }}_COPY_TO_SDCARD.zip + asset_content_type: application/zip + diff --git a/.github/workflows/past_version.txt b/.github/workflows/past_version.txt new file mode 100644 index 00000000..76864c1c --- /dev/null +++ b/.github/workflows/past_version.txt @@ -0,0 +1 @@ +v1.5.0 \ No newline at end of file diff --git a/.github/workflows/stable_changelog.py b/.github/workflows/stable_changelog.py new file mode 100644 index 00000000..cca6cb7a --- /dev/null +++ b/.github/workflows/stable_changelog.py @@ -0,0 +1,30 @@ +import os +import re +import sys + +past_version = sys.argv[1] + +raw_git = os.popen('git log ' + past_version + '..next --pretty=format:"- %h - {USERNAME}*+%al-%an*: %s"').read() + + +def compute_username(line): + stripped = re.search(r'(?<=\*)(.*?)(?=\*)', line).group(0) + + pattern = re.compile("[$@+&?].*[$@+&?]") + if pattern.match(stripped): + stripped = re.sub("[$@+&?].*[$@+&?]", "", stripped) + stripped = re.match(r'.+?(?=-)', stripped).group(0) + else: + stripped = re.sub(r'^.*?-', "", stripped) + return "@" + stripped + + +def compile_line(line): + username = compute_username(line) + line = re.sub(r'[*].*[*]', "", line) + line = line.replace("{USERNAME}", username) + return line + + +for row in raw_git.splitlines(): + print(compile_line(row)) diff --git a/.github/workflows/version.txt b/.github/workflows/version.txt new file mode 100644 index 00000000..c9b3c015 --- /dev/null +++ b/.github/workflows/version.txt @@ -0,0 +1 @@ +v1.5.1 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 97662e15..06d8c0ab 100644 --- a/.gitignore +++ b/.gitignore @@ -39,7 +39,6 @@ *.lib # Executables -*.exe *.out *.app /firmware/baseband/*.bin diff --git a/CMakeLists.txt b/CMakeLists.txt index cf8b5706..9153ded8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,8 @@ set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/firmware/toolchain-arm-cortex project(portapack-h1) -#set(VERSION "") -if (NOT DEFINED VERSION) +set(VERSION "$ENV{VERSION_STRING}") +if ("$ENV{VERSION_STRING}" STREQUAL "") execute_process( COMMAND git log -n 1 --format=%h WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} @@ -38,7 +38,7 @@ if (NOT DEFINED VERSION) if (GIT_VERSION_FOUND) set(VERSION "unknown") else (GIT_VERSION_FOUND) - set(VERSION "local-${GIT_VERSION}") + set(VERSION "${GIT_VERSION}") endif (GIT_VERSION_FOUND) endif() diff --git a/README.md b/README.md index aafed603..d69ee663 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,9 @@ To support the people behind the hardware, please buy a genuine [HackRF](https:/ ## Where is the latest firmware? -The current stable release is on the [![GitHub release (latest by date)](https://img.shields.io/github/v/release/eried/portapack-mayhem?label=Releases&style=social)](https://github.com/eried/portapack-mayhem/releases/latest) page. Follow the instructions you can find in the release description. +The **latest (nightly) release** can be found [here](https://github.com/eried/portapack-mayhem/releases/). + +The current **stable release** is on the [![GitHub release (latest by date)](https://img.shields.io/github/v/release/eried/portapack-mayhem?label=Releases&style=social)](https://github.com/eried/portapack-mayhem/releases/latest) page. Follow the instructions you can find in the release description. ## Is this the newest firmware for my PortaPack? Most probably: **YES**. *If you find new features somewhere else, please [suggest](https://github.com/eried/portapack-mayhem/issues/new/choose) them*. diff --git a/firmware/application/apps/ais_app.cpp b/firmware/application/apps/ais_app.cpp index 06a36a6f..a5c25a55 100644 --- a/firmware/application/apps/ais_app.cpp +++ b/firmware/application/apps/ais_app.cpp @@ -254,8 +254,18 @@ AISRecentEntryDetailView::AISRecentEntryDetailView(NavigationView& nav) { }; - - +} + + +AISRecentEntryDetailView::AISRecentEntryDetailView(const AISRecentEntryDetailView&Entry) : View() +{ + (void)Entry; +} + +AISRecentEntryDetailView & AISRecentEntryDetailView::operator=(const AISRecentEntryDetailView&Entry) +{ + (void)Entry; + return *this; } void AISRecentEntryDetailView::update_position() { diff --git a/firmware/application/apps/ais_app.hpp b/firmware/application/apps/ais_app.hpp index c7f03aca..c6a8a7d5 100644 --- a/firmware/application/apps/ais_app.hpp +++ b/firmware/application/apps/ais_app.hpp @@ -127,6 +127,9 @@ public: void focus() override; void paint(Painter&) override; + AISRecentEntryDetailView(const AISRecentEntryDetailView&Entry); + AISRecentEntryDetailView &operator=(const AISRecentEntryDetailView&Entry); + private: AISRecentEntry entry_ { }; @@ -163,7 +166,7 @@ public: void focus() override; - std::string title() const override { return "AIS"; }; + std::string title() const override { return "AIS Boats RX"; }; private: static constexpr uint32_t initial_target_frequency = 162025000; diff --git a/firmware/application/apps/analog_audio_app.hpp b/firmware/application/apps/analog_audio_app.hpp index 8f62e237..04795e47 100644 --- a/firmware/application/apps/analog_audio_app.hpp +++ b/firmware/application/apps/analog_audio_app.hpp @@ -143,7 +143,7 @@ public: void focus() override; - std::string title() const override { return "Analog audio"; }; + std::string title() const override { return "Audio RX"; }; size_t get_spec_bw_index(); void set_spec_bw(size_t index, uint32_t bw); diff --git a/firmware/application/apps/analog_tv_app.hpp b/firmware/application/apps/analog_tv_app.hpp index 6f90a55c..81ac8ea5 100644 --- a/firmware/application/apps/analog_tv_app.hpp +++ b/firmware/application/apps/analog_tv_app.hpp @@ -53,7 +53,7 @@ public: void focus() override; - std::string title() const override { return "Analog TV"; }; + std::string title() const override { return "Analog TV RX"; }; private: static constexpr ui::Dim header_height = 3 * 16; diff --git a/firmware/application/apps/ert_app.hpp b/firmware/application/apps/ert_app.hpp index 14eb61c0..19cf70d0 100644 --- a/firmware/application/apps/ert_app.hpp +++ b/firmware/application/apps/ert_app.hpp @@ -125,7 +125,7 @@ public: void focus() override; - std::string title() const override { return "ERT"; }; + std::string title() const override { return "ERT Meter RX"; }; private: ERTRecentEntries recent { }; diff --git a/firmware/application/apps/gps_sim_app.hpp b/firmware/application/apps/gps_sim_app.hpp index 34c7bb2d..b027eeec 100644 --- a/firmware/application/apps/gps_sim_app.hpp +++ b/firmware/application/apps/gps_sim_app.hpp @@ -44,7 +44,7 @@ public: void set_parent_rect(const Rect new_parent_rect) override; void focus() override; - std::string title() const override { return "GPS Simulator"; }; + std::string title() const override { return "GPS Sim TX"; }; private: NavigationView& nav_; diff --git a/firmware/application/apps/lge_app.hpp b/firmware/application/apps/lge_app.hpp index 81825800..99c5014d 100644 --- a/firmware/application/apps/lge_app.hpp +++ b/firmware/application/apps/lge_app.hpp @@ -40,7 +40,7 @@ public: void focus() override; - std::string title() const override { return "LGE tool"; }; + std::string title() const override { return "LGE tool TX"; }; private: enum tx_modes { diff --git a/firmware/application/apps/soundboard_app.hpp b/firmware/application/apps/soundboard_app.hpp index 91feaf96..ee9e1b12 100644 --- a/firmware/application/apps/soundboard_app.hpp +++ b/firmware/application/apps/soundboard_app.hpp @@ -45,7 +45,7 @@ public: void focus() override; - std::string title() const override { return "Soundboard"; }; + std::string title() const override { return "Soundboard TX"; }; private: NavigationView& nav_; diff --git a/firmware/application/apps/tpms_app.hpp b/firmware/application/apps/tpms_app.hpp index 7ccef644..2d9b670d 100644 --- a/firmware/application/apps/tpms_app.hpp +++ b/firmware/application/apps/tpms_app.hpp @@ -103,7 +103,7 @@ public: void focus() override; - std::string title() const override { return "TPMS"; }; + std::string title() const override { return "TPMS Cars RX"; }; private: static constexpr uint32_t initial_target_frequency = 315000000; diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index e9ee91cb..879e9d8c 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -184,7 +184,7 @@ private: AircraftRecentEntry entry_copy { 0 }; std::function on_close_ { }; bool send_updates { false }; - std::database db; + std::database db = { }; std::string icao_code = ""; int return_code = 0; @@ -279,7 +279,7 @@ private: GeoMapView* geomap_view { nullptr }; ADSBRxAircraftDetailsView* aircraft_details_view { nullptr }; bool send_updates { false }; - std::database db; + std::database db = { }; std::string airline_code = ""; int return_code = 0; @@ -361,14 +361,14 @@ public: void focus() override; - std::string title() const override { return "ADS-B receive"; }; + std::string title() const override { return "ADS-B RX"; }; void replace_entry(AircraftRecentEntry & entry); AircraftRecentEntry find_or_create_entry(uint32_t ICAO_address); void sort_entries_by_state(); private: - rf::Frequency prevFreq; + rf::Frequency prevFreq = { 0 }; std::unique_ptr logger { }; void on_frame(const ADSBFrameMessage * message); void on_tick_second(); diff --git a/firmware/application/apps/ui_adsb_tx.hpp b/firmware/application/apps/ui_adsb_tx.hpp index f68da241..0cf07f19 100644 --- a/firmware/application/apps/ui_adsb_tx.hpp +++ b/firmware/application/apps/ui_adsb_tx.hpp @@ -152,7 +152,7 @@ public: void focus() override; - std::string title() const override { return "ADS-B transmit"; }; + std::string title() const override { return "ADS-B TX"; }; private: /*enum tx_modes { diff --git a/firmware/application/apps/ui_aprs_rx.hpp b/firmware/application/apps/ui_aprs_rx.hpp index 216e96a3..9ea29559 100644 --- a/firmware/application/apps/ui_aprs_rx.hpp +++ b/firmware/application/apps/ui_aprs_rx.hpp @@ -57,12 +57,12 @@ struct APRSRecentEntry { uint16_t hits { 0 }; uint32_t age { 0 }; - uint64_t source; + uint64_t source { 0 }; std::string source_formatted { " " }; std::string time_string { "" }; std::string info_string { "" }; - aprs::aprs_pos pos; + aprs::aprs_pos pos { 0 , 0 , 0 , 0 }; bool has_position = false; APRSRecentEntry(uint64_t src) { diff --git a/firmware/application/apps/ui_bht_tx.hpp b/firmware/application/apps/ui_bht_tx.hpp index 64cf838d..01e6b48c 100644 --- a/firmware/application/apps/ui_bht_tx.hpp +++ b/firmware/application/apps/ui_bht_tx.hpp @@ -178,7 +178,7 @@ public: void focus() override; - std::string title() const override { return "BHT transmit"; }; + std::string title() const override { return "BHT Xy/EP TX"; }; private: void on_tx_progress(const uint32_t progress, const bool done); diff --git a/firmware/application/apps/ui_coasterp.hpp b/firmware/application/apps/ui_coasterp.hpp index 8d169d86..68963302 100644 --- a/firmware/application/apps/ui_coasterp.hpp +++ b/firmware/application/apps/ui_coasterp.hpp @@ -39,7 +39,7 @@ public: void focus() override; - std::string title() const override { return "Si44xx TX"; }; + std::string title() const override { return "BurgerPgr TX"; }; private: enum tx_modes { diff --git a/firmware/application/apps/ui_debug.cpp b/firmware/application/apps/ui_debug.cpp index 2bec78fa..a1856e25 100644 --- a/firmware/application/apps/ui_debug.cpp +++ b/firmware/application/apps/ui_debug.cpp @@ -352,7 +352,7 @@ DebugMenuView::DebugMenuView(NavigationView& nav) { { "SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [&nav](){ nav.push(); } }, { "Peripherals", ui::Color::dark_cyan(), &bitmap_icon_peripherals, [&nav](){ nav.push(); } }, { "Temperature", ui::Color::dark_cyan(), &bitmap_icon_temperature, [&nav](){ nav.push(); } }, - { "Buttons test", ui::Color::dark_cyan(), &bitmap_icon_controls, [&nav](){ nav.push(); } }, + { "Buttons Test", ui::Color::dark_cyan(), &bitmap_icon_controls, [&nav](){ nav.push(); } }, }); set_max_rows(2); // allow wider buttons } diff --git a/firmware/application/apps/ui_debug.hpp b/firmware/application/apps/ui_debug.hpp index 1e3d6003..19118721 100644 --- a/firmware/application/apps/ui_debug.hpp +++ b/firmware/application/apps/ui_debug.hpp @@ -43,6 +43,8 @@ public: void focus() override; + std::string title() const override { return "Memory"; }; + private: Text text_title { { 96, 96, 48, 16 }, @@ -113,6 +115,8 @@ public: void focus() override; + std::string title() const override { return "Temperature"; }; + private: Text text_title { { 76, 16, 240, 16 }, @@ -252,6 +256,8 @@ public: void focus() override; + std::string title() const override { return "Buttons Test"; }; + private: Text text_title { { 64, 16, 184, 16 }, diff --git a/firmware/application/apps/ui_encoders.hpp b/firmware/application/apps/ui_encoders.hpp index ee311e38..7eef80d5 100644 --- a/firmware/application/apps/ui_encoders.hpp +++ b/firmware/application/apps/ui_encoders.hpp @@ -158,7 +158,7 @@ public: void focus() override; - std::string title() const override { return "OOK transmit"; }; + std::string title() const override { return "OOK TX"; }; private: NavigationView& nav_; diff --git a/firmware/application/apps/ui_jammer.hpp b/firmware/application/apps/ui_jammer.hpp index 8158a6f7..13869262 100644 --- a/firmware/application/apps/ui_jammer.hpp +++ b/firmware/application/apps/ui_jammer.hpp @@ -106,7 +106,7 @@ public: void focus() override; - std::string title() const override { return "Jammer"; }; + std::string title() const override { return "Jammer TX"; }; private: NavigationView& nav_; diff --git a/firmware/application/apps/ui_keyfob.hpp b/firmware/application/apps/ui_keyfob.hpp index 7f28d554..0c723340 100644 --- a/firmware/application/apps/ui_keyfob.hpp +++ b/firmware/application/apps/ui_keyfob.hpp @@ -36,7 +36,7 @@ public: void focus() override; - std::string title() const override { return "Keyfob (BETA)"; }; + std::string title() const override { return "Key fob TX (beta)"; }; private: NavigationView& nav_; diff --git a/firmware/application/apps/ui_lcr.hpp b/firmware/application/apps/ui_lcr.hpp index a9c7548a..096a597a 100644 --- a/firmware/application/apps/ui_lcr.hpp +++ b/firmware/application/apps/ui_lcr.hpp @@ -39,7 +39,7 @@ public: void focus() override; - std::string title() const override { return "LCR transmit"; }; + std::string title() const override { return "TEDI/LCR TX"; }; private: struct scan_list_t { diff --git a/firmware/application/apps/ui_mictx.hpp b/firmware/application/apps/ui_mictx.hpp index aaab059c..9b091e53 100644 --- a/firmware/application/apps/ui_mictx.hpp +++ b/firmware/application/apps/ui_mictx.hpp @@ -58,7 +58,7 @@ public: }; */ - std::string title() const override { return "Mic TX RX"; }; + std::string title() const override { return "Microphone"; }; private: static constexpr uint32_t sampling_rate = 1536000U; diff --git a/firmware/application/apps/ui_rds.hpp b/firmware/application/apps/ui_rds.hpp index 6e6e0797..35d80ba4 100644 --- a/firmware/application/apps/ui_rds.hpp +++ b/firmware/application/apps/ui_rds.hpp @@ -144,7 +144,7 @@ public: void focus() override; - std::string title() const override { return "RDS transmit"; }; + std::string title() const override { return "RDS TX"; }; private: NavigationView& nav_; diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp index 6874280a..3bd350c8 100644 --- a/firmware/application/apps/ui_scanner.cpp +++ b/firmware/application/apps/ui_scanner.cpp @@ -484,6 +484,7 @@ void ScannerView::scan_pause() { scan_thread->set_freq_lock(0); //Reset the scanner lock (because user paused, or MAX_FREQ_LOCK reached) for next freq scan scan_thread->set_scanning(false); // WE STOP SCANNING audio::output::start(); + on_headphone_volume_changed(field_volume.value()); // quick fix to make sure WM8731S chips don't stay silent after pause } } diff --git a/firmware/application/apps/ui_scanner.hpp b/firmware/application/apps/ui_scanner.hpp index 3936904e..caa571f9 100644 --- a/firmware/application/apps/ui_scanner.hpp +++ b/firmware/application/apps/ui_scanner.hpp @@ -111,7 +111,7 @@ public: .foreground = Color::red(), }; - std::string title() const override { return "SCANNER"; }; + std::string title() const override { return "Scanner"; }; std::vector frequency_list{ }; std::vector description_list { }; diff --git a/firmware/application/apps/ui_sd_wipe.hpp b/firmware/application/apps/ui_sd_wipe.hpp index 6d49b6f4..fc593f16 100644 --- a/firmware/application/apps/ui_sd_wipe.hpp +++ b/firmware/application/apps/ui_sd_wipe.hpp @@ -38,7 +38,7 @@ public: ~WipeSDView(); void focus() override; - std::string title() const override { return "Wipe FAT"; }; + std::string title() const override { return "Wipe SD Card"; }; private: NavigationView& nav_; diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index fbda02b7..5b3cc4d3 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -43,7 +43,7 @@ namespace ui { SetDateTimeView::SetDateTimeView( NavigationView& nav ) { - button_done.on_select = [&nav, this](Button&){ + button_save.on_select = [&nav, this](Button&){ const auto model = this->form_collect(); const rtc::RTC new_datetime { model.year, model.month, model.day, @@ -65,7 +65,7 @@ SetDateTimeView::SetDateTimeView( &field_hour, &field_minute, &field_second, - &button_done, + &button_save, &button_cancel, }); @@ -150,7 +150,7 @@ SetRadioView::SetRadioView( &value_freq_step, &labels_bias, &check_bias, - &button_done, + &button_save, &button_cancel }); @@ -200,7 +200,7 @@ SetRadioView::SetRadioView( EventDispatcher::send_message(message); }; - button_done.on_select = [this, &nav](Button&){ + button_save.on_select = [this, &nav](Button&){ const auto model = this->form_collect(); portapack::persistent_memory::set_correction_ppb(model.ppm * 1000); portapack::persistent_memory::set_clkout_freq(model.freq); @@ -210,7 +210,7 @@ SetRadioView::SetRadioView( } void SetRadioView::focus() { - button_done.focus(); + button_save.focus(); } void SetRadioView::form_init(const SetFrequencyCorrectionModel& model) { @@ -224,76 +224,24 @@ SetFrequencyCorrectionModel SetRadioView::form_collect() { }; } -/* -SetPlayDeadView::SetPlayDeadView(NavigationView& nav) { - add_children({ - &text_sequence, - &button_enter, - &button_cancel - }); - - button_enter.on_select = [this, &nav](Button&){ - if (!entermode) { - sequence = 0; - keycount = 0; - memset(sequence_txt, '-', 10); - text_sequence.set(sequence_txt); - entermode = true; - button_cancel.hidden(true); - set_dirty(); - } else { - if (sequence == 0x8D1) // U D L R - nav.display_modal("Warning", "Default sequence entered !", ABORT, nullptr); - else { - persistent_memory::set_playdead_sequence(sequence); - nav.pop(); - } - } - }; - - button_enter.on_dir = [this](Button&, KeyEvent key){ - if ((entermode == true) && (keycount < 10)) { - key_code = static_cast::type>(key); - if (key_code == 0) - sequence_txt[keycount] = 'R'; - else if (key_code == 1) - sequence_txt[keycount] = 'L'; - else if (key_code == 2) - sequence_txt[keycount] = 'D'; - else if (key_code == 3) - sequence_txt[keycount] = 'U'; - text_sequence.set(sequence_txt); - sequence = (sequence << 3) | (key_code + 1); - keycount++; - return true; - } - return false; - }; - - button_cancel.on_select = [&nav](Button&){ nav.pop(); }; -} - -void SetPlayDeadView::focus() { - button_cancel.focus(); -} -*/ SetUIView::SetUIView(NavigationView& nav) { add_children({ - //&checkbox_login, + &checkbox_disable_touchscreen, &checkbox_speaker, &checkbox_bloff, &options_bloff, &checkbox_showsplash, &checkbox_showclock, - &options_clockformat, - &button_ok + &options_clockformat, + &button_save, + &button_cancel }); + checkbox_disable_touchscreen.set_value(persistent_memory::disable_touchscreen()); checkbox_speaker.set_value(persistent_memory::config_speaker()); checkbox_showsplash.set_value(persistent_memory::config_splash()); checkbox_showclock.set_value(!persistent_memory::hide_clock()); - //checkbox_login.set_value(persistent_memory::config_login()); uint32_t backlight_timer = persistent_memory::config_backlight_timer(); if (backlight_timer) { @@ -309,16 +257,14 @@ SetUIView::SetUIView(NavigationView& nav) { options_clockformat.set_selected_index(0); } - checkbox_speaker.on_select = [this](Checkbox&, bool v) { - if (v) audio::output::speaker_mute(); //Just mute audio if speaker is disabled + //checkbox_speaker.on_select = [this](Checkbox&, bool v) { + // if (v) audio::output::speaker_mute(); //Just mute audio if speaker is disabled + // persistent_memory::set_config_speaker(v); //Store Speaker status + // StatusRefreshMessage message { }; //Refresh status bar with/out speaker + // EventDispatcher::send_message(message); + //}; - persistent_memory::set_config_speaker(v); //Store Speaker status - - StatusRefreshMessage message { }; //Refresh status bar with/out speaker - EventDispatcher::send_message(message); - }; - - button_ok.on_select = [&nav, this](Button&) { + button_save.on_select = [&nav, this](Button&) { if (checkbox_bloff.value()) persistent_memory::set_config_backlight_timer(options_bloff.selected_index() + 1); else @@ -329,225 +275,83 @@ SetUIView::SetUIView(NavigationView& nav) { persistent_memory::set_clock_with_date(true); else persistent_memory::set_clock_with_date(false); - } + } + + if (checkbox_speaker.value()) audio::output::speaker_mute(); //Just mute audio if speaker is disabled + persistent_memory::set_config_speaker(checkbox_speaker.value()); //Store Speaker status + StatusRefreshMessage message { }; //Refresh status bar with/out speaker + EventDispatcher::send_message(message); + persistent_memory::set_config_splash(checkbox_showsplash.value()); persistent_memory::set_clock_hidden(!checkbox_showclock.value()); - //persistent_memory::set_config_login(checkbox_login.value()); + persistent_memory::set_disable_touchscreen(checkbox_disable_touchscreen.value()); + nav.pop(); + }; + button_cancel.on_select = [&nav, this](Button&) { nav.pop(); }; } void SetUIView::focus() { - button_ok.focus(); + button_save.focus(); } SetAudioView::SetAudioView(NavigationView& nav) { add_children({ &labels, &field_tone_mix, - &button_ok + &button_save, + &button_cancel }); field_tone_mix.set_value(persistent_memory::tone_mix()); - button_ok.on_select = [&nav, this](Button&) { + button_save.on_select = [&nav, this](Button&) { persistent_memory::set_tone_mix(field_tone_mix.value()); nav.pop(); }; + + button_cancel.on_select = [&nav, this](Button&) { + nav.pop(); + }; } void SetAudioView::focus() { - field_tone_mix.focus(); + button_save.focus(); } -/*void ModInfoView::on_show() { - if (modules_nb) update_infos(0); -} +SetQRCodeView::SetQRCodeView(NavigationView& nav) { + add_children({ + &checkbox_bigger_qr, + &button_save, + &button_cancel + }); -void ModInfoView::update_infos(uint8_t modn) { - char info_str[27]; - char ch; - uint8_t c; - Point pos = { 0, 0 }; - Rect rect = { { 16, 144 }, { 208, 144 } }; + checkbox_bigger_qr.set_value(persistent_memory::show_bigger_qr_code()); - info_str[0] = 0; - strcat(info_str, module_list[modn].name); - text_namestr.set(info_str); - - info_str[0] = 0; - strcat(info_str, to_string_dec_uint(module_list[modn].size).c_str()); - strcat(info_str, " bytes"); - text_sizestr.set(info_str); - - info_str[0] = 0; - for (c = 0; c < 8; c++) - strcat(info_str, to_string_hex(module_list[modn].md5[c], 2).c_str()); - text_md5_a.set(info_str); - - info_str[0] = 0; - for (c = 8; c < 16; c++) - strcat(info_str, to_string_hex(module_list[modn].md5[c], 2).c_str()); - text_md5_b.set(info_str); - - // TODO: Use ui_console - display.fill_rectangle(rect, Color::black()); - - const Font& font = font::fixed_8x16; - const auto line_height = font.line_height(); - c = 0; - while((ch = module_list[modn].description[c++])) { - const auto glyph = font.glyph(ch); - const auto advance = glyph.advance(); - if((pos.x + advance.x) > rect.width()) { - pos.x = 0; - pos.y += line_height; - } - const Point pos_glyph { - static_cast(rect.pos.x + pos.x), - static_cast(rect.pos.y + pos.y) - }; - display.draw_glyph(pos_glyph, glyph, Color::white(), Color::black()); - pos.x += advance.x; - } -} - -ModInfoView::ModInfoView(NavigationView& nav) { - const char magic[4] = {'P', 'P', 'M', ' '}; - UINT bw; - uint8_t i; - char read_buf[16]; - char info_str[25]; - FILINFO modinfo; - FIL modfile; - DIR rootdir; - FRESULT res; - uint8_t c; - - using option_t = std::pair; - using options_t = std::vector; - option_t opt; - options_t opts; - - static constexpr Style style_orange { - .font = font::fixed_8x16, - .background = Color::black(), - .foreground = Color::orange(), - }; - - add_children({{ - &text_modcount, - &text_name, - &text_namestr, - &text_size, - &text_sizestr, - &text_md5, - &text_md5_a, - &text_md5_b, - &button_ok - }}); - - text_name.set_style(&style_orange); - text_size.set_style(&style_orange); - text_md5.set_style(&style_orange); - - // TODO: Find a way to merge this with m4_load_image() in m4_startup.cpp - - // Scan SD card root directory for files starting with the magic bytes - c = 0; - if (f_opendir(&rootdir, "/") == FR_OK) { - for (;;) { - res = f_readdir(&rootdir, &modinfo); - if (res != FR_OK || modinfo.fname[0] == 0) break; // Reached last file, abort - // Only care about files with .bin extension - if ((!(modinfo.fattrib & AM_DIR)) && (modinfo.fname[9] == 'B') && (modinfo.fname[10] == 'I') && (modinfo.fname[11] == 'N')) { - f_open(&modfile, modinfo.fname, FA_OPEN_EXISTING | FA_READ); - // Magic bytes check - f_read(&modfile, &read_buf, 4, &bw); - for (i = 0; i < 4; i++) - if (read_buf[i] != magic[i]) break; - if (i == 4) { - memcpy(&module_list[c].filename, modinfo.fname, 8); - module_list[c].filename[8] = 0; - - f_lseek(&modfile, 4); - f_read(&modfile, &module_list[c].version, 2, &bw); - f_lseek(&modfile, 6); - f_read(&modfile, &module_list[c].size, 4, &bw); - f_lseek(&modfile, 10); - f_read(&modfile, &module_list[c].name, 16, &bw); - f_lseek(&modfile, 26); - f_read(&modfile, &module_list[c].md5, 16, &bw); - f_lseek(&modfile, 42); - f_read(&modfile, &module_list[c].description, 214, &bw); - f_lseek(&modfile, 256); - - // Sanitize - module_list[c].name[15] = 0; - module_list[c].description[213] = 0; - - memcpy(info_str, module_list[c].filename, 16); - strcat(info_str, "(V"); - strcat(info_str, to_string_dec_uint(module_list[c].version, 4, '0').c_str()); - strcat(info_str, ")"); - while(strlen(info_str) < 24) - strcat(info_str, " "); - - opt = std::make_pair(info_str, c); - opts.insert(opts.end(), opt); - - c++; - } - f_close(&modfile); - } - if (c == 8) break; - } - } - f_closedir(&rootdir); - - modules_nb = c; - - if (modules_nb) { - strcpy(info_str, "Found "); - strcat(info_str, to_string_dec_uint(modules_nb, 1).c_str()); - strcat(info_str, " module(s)"); - - text_modcount.set(info_str); - option_modules.set_options(opts); - - add_child(&option_modules); - - option_modules.on_change = [this](size_t n, OptionsField::value_t v) { - (void)n; - update_infos(v); - }; - } else { - strcpy(info_str, "No modules found"); - text_modcount.set(info_str); - } - - button_ok.on_select = [&nav,this](Button&){ + button_save.on_select = [&nav, this](Button&) { + persistent_memory::set_show_bigger_qr_code(checkbox_bigger_qr.value()); nav.pop(); }; + + button_cancel.on_select = [&nav, this](Button&) { + nav.pop(); + }; + } -void ModInfoView::focus() { - if (modules_nb) - option_modules.focus(); - else - button_ok.focus(); -}*/ +void SetQRCodeView::focus() { + button_save.focus(); +} SettingsMenuView::SettingsMenuView(NavigationView& nav) { add_items({ - //{ "..", ui::Color::light_grey(), &bitmap_icon_previous, [&nav](){ nav.pop(); } }, - { "Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [&nav](){ nav.push(); } }, - { "Radio", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav](){ nav.push(); } }, - { "Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [&nav](){ nav.push(); } }, - //{ "SD card modules", ui::Color::dark_cyan(), [&nav](){ nav.push(); } }, - { "Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [&nav](){ nav.push(); } }, - { "Touchscreen", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [&nav](){ nav.push(); } }, - //{ "Play dead", ui::Color::dark_cyan(), &bitmap_icon_playdead, [&nav](){ nav.push(); } } + { "Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [&nav](){ nav.push(); } }, + { "Radio", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav](){ nav.push(); } }, + { "User Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [&nav](){ nav.push(); } }, + { "Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [&nav](){ nav.push(); } }, + { "Calibration", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [&nav](){ nav.push(); } }, + { "QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav](){ nav.push(); } } }); set_max_rows(2); // allow wider buttons } diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index 30acd820..68c1e750 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -47,7 +47,7 @@ public: void focus() override; - std::string title() const override { return "Set Date/Time"; }; + std::string title() const override { return "Date/Time"; }; private: Labels labels { @@ -99,7 +99,7 @@ private: '0', }; - Button button_done { + Button button_save { { 2 * 8, 16 * 16, 12 * 8, 32 }, "Save" }; @@ -197,7 +197,7 @@ private: "Turn on bias voltage" }; - Button button_done { + Button button_save { { 2 * 8, 16 * 16, 12 * 8, 32 }, "Save" }; @@ -219,11 +219,12 @@ public: std::string title() const override { return "UI settings"; }; private: - /*Checkbox checkbox_login { + + Checkbox checkbox_disable_touchscreen { { 3 * 8, 2 * 16 }, 20, - "Login with play dead" - };*/ + "Disable touchscreen" + }; Checkbox checkbox_speaker { { 3 * 8, 4 * 16 }, @@ -271,10 +272,15 @@ private: } }; - Button button_ok { + Button button_save { { 2 * 8, 16 * 16, 12 * 8, 32 }, "Save" }; + + Button button_cancel { + { 16 * 8, 16 * 16, 12 * 8, 32 }, + "Cancel", + }; }; class SetAudioView : public View { @@ -298,111 +304,43 @@ private: '0' }; - Button button_ok { + Button button_save { { 2 * 8, 16 * 16, 12 * 8, 32 }, "Save" }; + + Button button_cancel { + { 16 * 8, 16 * 16, 12 * 8, 32 }, + "Cancel", + }; }; -/* -class SetPlayDeadView : public View { -public: - SetPlayDeadView(NavigationView& nav); - - void focus() override; - - std::string title() const override { return "Playdead settings"; }; - -private: - bool entermode = false; - uint32_t sequence { 0 }; - uint8_t keycount { 0 }, key_code { }; - char sequence_txt[11] = { 0 }; - - Text text_sequence { - { 64, 32, 14 * 8, 16 }, - "Enter sequence", - }; - - Button button_enter { - { 16, 192, 96, 24 }, - "Enter" - }; - Button button_cancel { - { 128, 192, 96, 24 }, - "Cancel" - }; -};*/ -/*class ModInfoView : public View { +class SetQRCodeView : public View { public: - ModInfoView(NavigationView& nav); + SetQRCodeView(NavigationView& nav); + void focus() override; - void on_show() override; + + std::string title() const override { return "QR Code"; }; private: - void update_infos(uint8_t modn); - - typedef struct moduleinfo_t{ - char filename[9]; - uint16_t version; - uint32_t size; - char md5[16]; - char name[16]; - char description[214]; - } moduleinfo_t; - - moduleinfo_t module_list[8]; // 8 max for now - - uint8_t modules_nb; - - Text text_modcount { - { 2 * 8, 1 * 16, 18 * 8, 16 }, - "Searching..." + Checkbox checkbox_bigger_qr { + { 3 * 8, 9 * 16 }, + 20, + "Show large QR code" }; - OptionsField option_modules { - { 2 * 8, 2 * 16 }, - 24, - { - { "-", 0 } - } + Button button_save { + { 2 * 8, 16 * 16, 12 * 8, 32 }, + "Save" }; - Text text_name { - { 2 * 8, 4 * 16, 5 * 8, 16 }, - "Name:" + Button button_cancel { + { 16 * 8, 16 * 16, 12 * 8, 32 }, + "Cancel", }; - Text text_namestr { - { 8 * 8, 4 * 16, 16 * 8, 16 }, - "..." - }; - Text text_size { - { 2 * 8, 5 * 16, 5 * 8, 16 }, - "Size:" - }; - Text text_sizestr { - { 8 * 8, 5 * 16, 16 * 8, 16 }, - "..." - }; - Text text_md5 { - { 2 * 8, 6 * 16, 4 * 8, 16 }, - "MD5:" - }; - Text text_md5_a { - { 7 * 8, 6 * 16, 16 * 8, 16 }, - "..." - }; - Text text_md5_b { - { 7 * 8, 7 * 16, 16 * 8, 16 }, - "..." - }; - - Button button_ok { - { 4 * 8, 272, 64, 24 }, - "Ok" - }; -};*/ +}; class SettingsMenuView : public BtnGridView { public: diff --git a/firmware/application/apps/ui_siggen.hpp b/firmware/application/apps/ui_siggen.hpp index 5abcdd85..f55d19d1 100644 --- a/firmware/application/apps/ui_siggen.hpp +++ b/firmware/application/apps/ui_siggen.hpp @@ -40,7 +40,7 @@ public: void focus() override; - std::string title() const override { return "Generator"; }; + std::string title() const override { return "Signal gen"; }; private: void start_tx(); diff --git a/firmware/application/bitmap.hpp b/firmware/application/bitmap.hpp index 8cb98a43..57c9f5fe 100644 --- a/firmware/application/bitmap.hpp +++ b/firmware/application/bitmap.hpp @@ -1285,6 +1285,28 @@ static constexpr Bitmap bitmap_icon_previous { { 16, 16 }, bitmap_icon_previous_data }; +static constexpr uint8_t bitmap_icon_qr_code_data[] = { + 0x00, 0x00, + 0xFE, 0x7E, + 0xC6, 0x62, + 0xFA, 0x5A, + 0xFA, 0x5A, + 0xDA, 0x5A, + 0xFE, 0x7E, + 0x7E, 0x7E, + 0x00, 0x00, + 0xFE, 0x46, + 0xC2, 0x06, + 0xFA, 0x18, + 0xFA, 0x18, + 0xC6, 0x60, + 0xFE, 0x62, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_qr_code { + { 16, 16 }, bitmap_icon_qr_code_data +}; + static constexpr uint8_t bitmap_icon_rds_data[] = { 0x00, 0x00, 0x00, 0x00, diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 59ef942c..2e471b9f 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -167,14 +167,15 @@ int main(void) { if( portapack::init() ) { portapack::display.init(); - sdcStart(&SDCD1, nullptr); + // sdcStart(&SDCD1, nullptr); // Commented out as now happens in portapack.cpp - controls_init(); + // controls_init(); // Commented out as now happens in portapack.cpp lcd_frame_sync_configure(); rtc_interrupt_enable(); event_loop(); + sdcDisconnect(&SDCD1); sdcStop(&SDCD1); diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index c4f03855..0157cd4f 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -29,6 +29,7 @@ #include "hackrf_gpio.hpp" using namespace hackrf::one; + #include "clock_manager.hpp" #include "event_m0.hpp" @@ -45,6 +46,11 @@ using asahi_kasei::ak4951::AK4951; #include "cpld_update.hpp" #include "optional.hpp" +#include "irq_controls.hpp" + +#include "file.hpp" +#include "sd_card.hpp" +#include "string_format.hpp" namespace portapack { @@ -175,22 +181,93 @@ enum class PortaPackModel { R2_20170522, }; +static bool save_config(int8_t value){ + persistent_memory::set_config_cpld(value); + if(sd_card::status() == sd_card::Status::Mounted){ + make_new_directory("/hardware"); + File file; + auto sucess = file.create("/hardware/settings.txt"); + if(!sucess.is_valid()) { + file.write_line(to_string_dec_uint(value)); + } + } + return true; +} + +int read_file(std::string name) { + std::string return_string = ""; + File file; + auto success = file.open(name); + + if(!success.is_valid()) { + char one_char[1]; + for(size_t pointer = 0; pointer < file.size() ; pointer++) { + file.seek(pointer); + file.read(one_char, 1); + return_string += one_char[0]; + } + return std::stoi(return_string); + } + return -1; +} + +static int load_config(){ + static Optional config_value; + if(!config_value.is_valid()){ + int8_t value = portapack::persistent_memory::config_cpld(); + if((value <= 0 || value >= 4) && sd_card::status() == sd_card::Status::Mounted){ + int data = read_file("/hardware/settings.txt"); + if(data != -1) { + config_value = data; + } + } else { + config_value = value; + } + } + return config_value.value(); +} + + static PortaPackModel portapack_model() { static Optional model; if( !model.is_valid() ) { - /*For the time being, it is impossible to distinguish the hardware of R1 and R2 from the software level*/ - /*At this point, I2c is not ready.*/ - //if( audio_codec_wm8731.detected() ) { - // model = PortaPackModel::R1_20150901; - //} else { + const auto switches_state = get_switches_state(); + if (switches_state[(size_t)ui::KeyEvent::Up]){ + save_config(1); model = PortaPackModel::R2_20170522; - //} + } + else if (switches_state[(size_t)ui::KeyEvent::Down]){ + save_config(2); + model = PortaPackModel::R1_20150901; + } + else if (switches_state[(size_t)ui::KeyEvent::Left]){ + save_config(3); + } + else if (switches_state[(size_t)ui::KeyEvent::Select]){ + save_config(0); + } + + + if (load_config() == 1) { + model = PortaPackModel::R2_20170522; + } else if (load_config() == 2) { + model = PortaPackModel::R1_20150901; + } else { + if( audio_codec_wm8731.detected() ) { + model = PortaPackModel::R1_20150901; // H1R1 + } else { + model = PortaPackModel::R2_20170522; // H1R2, H2, H2+ + } + } } return model.value(); } +//audio_codec_wm8731 = H1R1 & H2+ +//audio_codec_ak4951 = H1R2 + static audio::Codec* portapack_audio_codec() { /* I2C ready OK, Automatic recognition of audio chip */ return (audio_codec_wm8731.detected()) @@ -201,15 +278,14 @@ static audio::Codec* portapack_audio_codec() { static const portapack::cpld::Config& portapack_cpld_config() { return (portapack_model() == PortaPackModel::R2_20170522) - ? portapack::cpld::rev_20170522::config - : portapack::cpld::rev_20150901::config - ; + ? portapack::cpld::rev_20170522::config + : portapack::cpld::rev_20150901::config; } Backlight* backlight() { return (portapack_model() == PortaPackModel::R2_20170522) - ? static_cast(&backlight_cat4004) - : static_cast(&backlight_on_off); + ? static_cast(&backlight_cat4004) // R2_20170522 + : static_cast(&backlight_on_off); // R1_20150901 } #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) @@ -318,14 +394,15 @@ bool init() { i2c0.start(i2c_config_boot_clock); - if( !portapack::cpld::update_if_necessary(portapack_cpld_config()) ) { - shutdown_base(); - return false; - } + // Keeping this here for now incase we need to revert + // if( !portapack::cpld::update_if_necessary(portapack_cpld_config()) ) { + // shutdown_base(); + // return false; + // } - if( !hackrf::cpld::load_sram() ) { - chSysHalt(); - } + // if( !hackrf::cpld::load_sram() ) { + // chSysHalt(); + // } configure_pins_portapack(); @@ -336,7 +413,6 @@ bool init() { i2c0.stop(); set_clock_config(clock_config_irc); - cgu::pll1::disable(); /* Incantation from LPC43xx UM10503 section 12.2.1.1, to bring the M4 @@ -377,20 +453,41 @@ bool init() { i2c0.start(i2c_config_fast_clock); - clock_manager.set_reference_ppb(persistent_memory::correction_ppb()); + touch::adc::init(); + controls_init(); - audio::init(portapack_audio_codec()); - + clock_manager.set_reference_ppb(persistent_memory::correction_ppb()); clock_manager.enable_first_if_clock(); clock_manager.enable_second_if_clock(); clock_manager.enable_codec_clocks(); radio::init(); - touch::adc::init(); + sdcStart(&SDCD1, nullptr); + sd_card::poll_inserted(); + + chThdSleepMilliseconds(1); + + if( !portapack::cpld::update_if_necessary(portapack_cpld_config()) ) { + chThdSleepMilliseconds(1); + // If using a "2021/12 QFP100", press and hold the left button while booting. Should only need to do once. + if (load_config() != 3){ + shutdown_base(); + return false; + } + } + + if( !hackrf::cpld::load_sram() ) { + chSysHalt(); + } + + chThdSleepMilliseconds(1); // This delay seems to solve white noise audio issues LPC_CREG->DMAMUX = portapack::gpdma_mux; gpdma::controller.enable(); + audio::init(portapack_audio_codec()); + + return true; } diff --git a/firmware/application/qrcodegen.cpp b/firmware/application/qrcodegen.cpp index 9e1e293a..2dcdbee5 100644 --- a/firmware/application/qrcodegen.cpp +++ b/firmware/application/qrcodegen.cpp @@ -38,7 +38,7 @@ #include #include -#pragma mark - Error Correction Lookup tables +/* #pragma mark - Error Correction Lookup tables */ #if LOCK_VERSION == 0 @@ -101,7 +101,7 @@ static int abs(int value) { */ -#pragma mark - Mode testing and conversion +/* #pragma mark - Mode testing and conversion */ static int8_t getAlphanumeric(char c) { @@ -140,7 +140,7 @@ static bool isNumeric(const char *text, uint16_t length) { } -#pragma mark - Counting +/* #pragma mark - Counting */ // We store the following tightly packed (less 8) in modeInfo // <=9 <=26 <= 40 @@ -167,7 +167,7 @@ static char getModeBits(uint8_t version, uint8_t mode) { } -#pragma mark - BitBucket +/* #pragma mark - BitBucket */ typedef struct BitBucket { uint32_t bitOffsetOrWidth; @@ -251,7 +251,7 @@ static bool bb_getBit(BitBucket *bitGrid, uint8_t x, uint8_t y) { } -#pragma mark - Drawing Patterns +/* #pragma mark - Drawing Patterns */ // XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical // properties, calling applyMask(m) twice with the same value is equivalent to no change at all. @@ -474,7 +474,7 @@ static void drawCodewords(BitBucket *modules, BitBucket *isFunction, BitBucket * -#pragma mark - Penalty Calculation +/* #pragma mark - Penalty Calculation */ #define PENALTY_N1 3 #define PENALTY_N2 3 @@ -574,7 +574,7 @@ static uint32_t getPenaltyScore(BitBucket *modules) { } -#pragma mark - Reed-Solomon Generator +/* #pragma mark - Reed-Solomon Generator */ static uint8_t rs_multiply(uint8_t x, uint8_t y) { // Russian peasant multiplication @@ -628,7 +628,7 @@ static void rs_getRemainder(uint8_t degree, uint8_t *coeff, uint8_t *data, uint8 -#pragma mark - QrCode +/* #pragma mark - QrCode */ static int8_t encodeDataCodewords(BitBucket *dataCodewords, const uint8_t *text, uint16_t length, uint8_t version) { int8_t mode = MODE_BYTE; @@ -769,7 +769,7 @@ static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data static const uint8_t ECC_FORMAT_BITS = (0x02 << 6) | (0x03 << 4) | (0x00 << 2) | (0x01 << 0); -#pragma mark - Public QRCode functions +/* #pragma mark - Public QRCode functions */ uint16_t qrcode_getBufferSize(uint8_t version) { return bb_getGridSizeBytes(4 * version + 17); @@ -857,7 +857,7 @@ int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_ } bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y) { - if (x < 0 || x >= qrcode->size || y < 0 || y >= qrcode->size) { + if ( x >= qrcode->size || y >= qrcode->size) { return false; } @@ -873,4 +873,4 @@ uint8_t qrcode_getHexLength(QRCode *qrcode) { void qrcode_getHex(QRCode *qrcode, char *result) { } -*/ \ No newline at end of file +*/ diff --git a/firmware/application/touch.cpp b/firmware/application/touch.cpp index d3fc6c92..63c7bb47 100644 --- a/firmware/application/touch.cpp +++ b/firmware/application/touch.cpp @@ -109,7 +109,7 @@ void Manager::feed(const Frame& frame) { switch(state) { case State::NoTouch: - if( touch_stable && touch_pressure ) { + if( touch_stable && touch_pressure && !persistent_memory::disable_touchscreen()) { if( point_stable() ) { state = State::TouchDetected; touch_started(); diff --git a/firmware/application/ui/ui_qrcode.cpp b/firmware/application/ui/ui_qrcode.cpp index fd18d990..736ef441 100644 --- a/firmware/application/ui/ui_qrcode.cpp +++ b/firmware/application/ui/ui_qrcode.cpp @@ -23,6 +23,7 @@ #include "ui_qrcode.hpp" #include "qrcodegen.hpp" #include "portapack.hpp" +#include "portapack_persistent_memory.hpp" #include #include @@ -42,26 +43,74 @@ QRCodeImage::QRCodeImage( } +QRCodeImage::~QRCodeImage( ) +{ + +} + +QRCodeImage::QRCodeImage(const QRCodeImage&Image) : Widget { } +{ + (void)Image; +} + +QRCodeImage & QRCodeImage::operator=(const QRCodeImage&Image) +{ + (void)Image; + return *this; +} + void QRCodeImage::paint(Painter& painter) { + + (void)painter ; + // The structure to manage the QR code QRCode qrcode; - int qr_version = 10; // bigger versions aren't handled very well - - // Allocate a chunk of memory to store the QR code - uint8_t qrcodeBytes[qrcode_getBufferSize(qr_version)]; - - qrcode_initText(&qrcode, qrcodeBytes, qr_version, ECC_HIGH, qr_text_); - display.fill_rectangle(Rect(92, 97, 63, 63), Color::white()); + //Either small or large QR code can be shown.. - for (uint8_t y = 0; y < qrcode.size; y++) { - for (uint8_t x = 0; x < qrcode.size; x++) { - if (qrcode_getModule(&qrcode, x, y)) { - display.draw_pixel(Point(95+x,100+y), Color::black()); + if(portapack::persistent_memory::show_bigger_qr_code()) { // show large QR code + int qr_version = 2; + + // Allocate a chunk of memory to store the QR code + uint8_t qrcodeBytes[qrcode_getBufferSize(qr_version)]; + + qrcode_initText(&qrcode, qrcodeBytes, qr_version, ECC_HIGH, qr_text_); + + + display.fill_rectangle(Rect(10, 30, 220, 220), Color::white()); + + for (uint8_t y = 0; y < qrcode.size; y++) { + for (uint8_t x = 0; x < qrcode.size; x++) { + if (qrcode_getModule(&qrcode, x, y)) { + display.fill_rectangle(Rect(20+(x*8), 40+(y*8), 8, 8), Color::black()); + + } + } + } + + } + + else { // show small QR code + int qr_version = 10; + + // Allocate a chunk of memory to store the QR code + uint8_t qrcodeBytes[qrcode_getBufferSize(qr_version)]; + + qrcode_initText(&qrcode, qrcodeBytes, qr_version, ECC_HIGH, qr_text_); + + + display.fill_rectangle(Rect(92, 97, 63, 63), Color::white()); + + for (uint8_t y = 0; y < qrcode.size; y++) { + for (uint8_t x = 0; x < qrcode.size; x++) { + if (qrcode_getModule(&qrcode, x, y)) { + display.draw_pixel(Point(95+x,100+y), Color::black()); + + } + } + } - } - } } } @@ -84,10 +133,9 @@ QRCodeView::QRCodeView( add_children({ - &text_qr, &qr_code, &button_close}); - text_qr.set(qr_text); + //text_qr.set(qr_text); qr_code.set_text(qr_text); button_close.on_select = [&nav](Button&){ diff --git a/firmware/application/ui/ui_qrcode.hpp b/firmware/application/ui/ui_qrcode.hpp index 43dab2d8..d30b7715 100644 --- a/firmware/application/ui/ui_qrcode.hpp +++ b/firmware/application/ui/ui_qrcode.hpp @@ -40,10 +40,13 @@ public: qr_text_ = qr_text; } void paint(Painter& painter) override; - + // for -weffc++ to be killed + ~QRCodeImage(); // destructor + QRCodeImage(const QRCodeImage&Image); + QRCodeImage & operator=(const QRCodeImage &Image); // assignment private: - const char * qr_text_ ; + const char * qr_text_ = NULL ; }; class QRCodeView : public View { @@ -74,13 +77,13 @@ private: { 50, 100, 100, 100 } }; - Text text_qr { - { 0 * 8, 10 * 16, 32 * 8, 1 * 8 }, - "-" - }; + //Text text_qr { + // { 0 * 8, 10 * 16, 32 * 8, 1 * 8 }, + // "-" + //}; Button button_close { - { 9 * 8, 15 * 16, 12 * 8, 3 * 16 }, + { 9 * 8, 31 * 8, 12 * 8, 3 * 16 }, "Back" }; }; diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index f6299f84..d7e35633 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -525,7 +525,7 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) { add_items({ //{ "Test app", ui::Color::dark_grey(), nullptr, [&nav](){ nav.push(); } }, //{ "..", ui::Color::light_grey(),&bitmap_icon_previous, [&nav](){ nav.pop(); } }, - { "Freq manager", ui::Color::green(), &bitmap_icon_freqman, [&nav](){ nav.push(); } }, + { "Freq. manager", ui::Color::green(), &bitmap_icon_freqman, [&nav](){ nav.push(); } }, { "File manager", ui::Color::yellow(), &bitmap_icon_dir, [&nav](){ nav.push(); } }, //{ "Notepad", ui::Color::dark_grey(), &bitmap_icon_notepad, [&nav](){ nav.push(); } }, { "Signal gen", ui::Color::green(), &bitmap_icon_cwgen, [&nav](){ nav.push(); } }, @@ -533,7 +533,6 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) { { "Wav viewer", ui::Color::yellow(), &bitmap_icon_soundboard, [&nav](){ nav.push(); } }, { "Antenna length", ui::Color::green(), &bitmap_icon_tools_antenna, [&nav](){ nav.push(); } }, { "Wipe SD Card", ui::Color::red(), &bitmap_icon_tools_wipesd, [&nav](){ nav.push(); } }, - }); set_max_rows(2); // allow wider buttons } @@ -557,12 +556,12 @@ SystemMenuView::SystemMenuView(NavigationView& nav) { { "Transmit", ui::Color::cyan(), &bitmap_icon_transmit, [&nav](){ nav.push(); } }, { "Capture", ui::Color::red(), &bitmap_icon_capture, [&nav](){ nav.push(); } }, { "Replay", ui::Color::green(), &bitmap_icon_replay, [&nav](){ nav.push(); } }, - { "Calls", ui::Color::yellow(), &bitmap_icon_search, [&nav](){ nav.push(); } }, + { "Search", ui::Color::yellow(), &bitmap_icon_search, [&nav](){ nav.push(); } }, { "Scanner", ui::Color::yellow(), &bitmap_icon_scanner, [&nav](){ nav.push(); } }, { "Microphone", ui::Color::yellow(), &bitmap_icon_microphone,[&nav](){ nav.push(); } }, { "Looking Glass", ui::Color::yellow(), &bitmap_icon_looking, [&nav](){ nav.push(); } }, - { "Tools", ui::Color::cyan(), &bitmap_icon_utilities, [&nav](){ nav.push(); } }, - { "Options", ui::Color::cyan(), &bitmap_icon_setup, [&nav](){ nav.push(); } }, + { "Utilities", ui::Color::cyan(), &bitmap_icon_utilities, [&nav](){ nav.push(); } }, + { "Settings", ui::Color::cyan(), &bitmap_icon_setup, [&nav](){ nav.push(); } }, { "Debug", ui::Color::light_grey(), &bitmap_icon_debug, [&nav](){ nav.push(); } }, { "HackRF", ui::Color::cyan(), &bitmap_icon_hackrf, [this, &nav](){ hackrf_mode(nav); } }, //{ "About", ui::Color::cyan(), nullptr, [&nav](){ nav.push(); } } diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index 9cc5fa87..d0e3b03f 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -190,7 +190,7 @@ namespace ui void on_speaker(); void on_stealth(); void on_bias_tee(); - //void on_textentry(); + // void on_textentry(); void on_camera(); void on_title(); void refresh(); @@ -212,7 +212,7 @@ namespace ui void refresh(); private: - static constexpr auto version_string = "v1.4.4"; + // static constexpr auto version_string = "v1.4.4"; // This is commented out as we are now setting the version via ENV (VERSION_STRING=v1.0.0) NavigationView &nav_; Rectangle backdrop{ @@ -221,7 +221,7 @@ namespace ui Text version{ {2, 0, 11 * 8, 16}, - version_string}; + VERSION_STRING}; LiveDateTime ltime{ {86, 0, 19 * 8, 16}}; @@ -248,14 +248,14 @@ namespace ui { public: ReceiversMenuView(NavigationView &nav); - std::string title() const override { return "Receivers"; }; + std::string title() const override { return "Receive"; }; }; class TransmittersMenuView : public BtnGridView { public: TransmittersMenuView(NavigationView &nav); - std::string title() const override { return "Transmitters"; }; + std::string title() const override { return "Transmit"; }; }; class UtilitiesMenuView : public BtnGridView diff --git a/firmware/application/ui_sd_card_debug.hpp b/firmware/application/ui_sd_card_debug.hpp index 170c2a68..56253c53 100644 --- a/firmware/application/ui_sd_card_debug.hpp +++ b/firmware/application/ui_sd_card_debug.hpp @@ -38,6 +38,8 @@ public: void focus() override; + std::string title() const override { return "SD Card"; }; + private: SignalToken sd_card_status_signal_token { }; diff --git a/firmware/baseband/dsp_hilbert.hpp b/firmware/baseband/dsp_hilbert.hpp index a4b56cd5..7687ccb3 100644 --- a/firmware/baseband/dsp_hilbert.hpp +++ b/firmware/baseband/dsp_hilbert.hpp @@ -35,8 +35,8 @@ public: private: uint8_t n = 0; - SOSFilter<5> sos_i; - SOSFilter<5> sos_q; + SOSFilter<5> sos_i = {}; + SOSFilter<5> sos_q = {}; }; } /* namespace dsp */ diff --git a/firmware/baseband/proc_adsbrx.cpp b/firmware/baseband/proc_adsbrx.cpp index faef978f..4520f1c9 100644 --- a/firmware/baseband/proc_adsbrx.cpp +++ b/firmware/baseband/proc_adsbrx.cpp @@ -120,7 +120,7 @@ void ADSBRXProcessor::execute(const buffer_c8_t& buffer) { // the high levels as signals can be out of phase so part of the // energy can be in the near samples int32_t thisAmp = (shifter[1] + shifter[3] + shifter[8] + shifter[10]); - int32_t high = thisAmp / 9; + uint32_t high = thisAmp / 9; if ( shifter[5] < high && shifter[6] < high && diff --git a/firmware/baseband/proc_aprsrx.hpp b/firmware/baseband/proc_aprsrx.hpp index 2d3c4568..9bcc4828 100644 --- a/firmware/baseband/proc_aprsrx.hpp +++ b/firmware/baseband/proc_aprsrx.hpp @@ -125,18 +125,18 @@ private: uint32_t sample_bits { 0 }; uint32_t phase { }, phase_inc { }; int32_t sample_mixed { }, prev_mixed { }, sample_filtered { }, prev_filtered { }; - uint8_t last_bit; - uint8_t ones_count = 0; + uint8_t last_bit = 0; + uint8_t ones_count = 0 ; uint8_t current_byte = 0; uint8_t byte_index = 0; uint8_t packet_buffer[256]; size_t packet_buffer_size = 0; bool configured { false }; - bool wait_start { }; - bool bit_value { }; + bool wait_start { 0 }; + bool bit_value { 0 }; - aprs::APRSPacket aprs_packet; + aprs::APRSPacket aprs_packet { }; void configure(const APRSRxConfigureMessage& message); void capture_config(const CaptureConfigMessage& message); diff --git a/firmware/baseband/proc_mictx.hpp b/firmware/baseband/proc_mictx.hpp index 6220835c..b26cae38 100644 --- a/firmware/baseband/proc_mictx.hpp +++ b/firmware/baseband/proc_mictx.hpp @@ -51,7 +51,7 @@ private: AudioInput audio_input { }; ToneGen tone_gen { }; ToneGen beep_gen { }; - dsp::modulate::Modulator *modulator; + dsp::modulate::Modulator *modulator = NULL ; bool am_enabled { false }; bool fm_enabled { true }; diff --git a/firmware/baseband/proc_pocsag.hpp b/firmware/baseband/proc_pocsag.hpp index f5f7ec14..f848e40e 100644 --- a/firmware/baseband/proc_pocsag.hpp +++ b/firmware/baseband/proc_pocsag.hpp @@ -68,6 +68,16 @@ public: delete[] m_lastVals; } + SmoothVals(const SmoothVals&) + { + + } + + SmoothVals & operator=(const SmoothVals&) + { + return *this ; + } + // -------------------------------------------------- // Set size of smoothing // -------------------------------------------------- @@ -154,7 +164,7 @@ private: dsp::decimate::FIRC16xR16x32Decim8 decim_1 { }; dsp::decimate::FIRAndDecimateComplex channel_filter { }; dsp::demodulate::FM demod { }; - SmoothVals smooth; + SmoothVals smooth = { }; AudioOutput audio_output { }; diff --git a/firmware/common/acars_packet.cpp b/firmware/common/acars_packet.cpp index 2cf0366e..4a0e46bd 100644 --- a/firmware/common/acars_packet.cpp +++ b/firmware/common/acars_packet.cpp @@ -84,7 +84,7 @@ bool Packet::crc_ok() const { acars_fcs.process_byte(field_crc.read(i, 8)); } - return (acars_fcs.checksum() == field_crc.read(data_length(), fcs_length)); + return (acars_fcs.checksum() == (unsigned)field_crc.read(data_length(), fcs_length)); } size_t Packet::data_and_fcs_length() const { diff --git a/firmware/common/ais_packet.cpp b/firmware/common/ais_packet.cpp index 61fabd89..c6e7561f 100644 --- a/firmware/common/ais_packet.cpp +++ b/firmware/common/ais_packet.cpp @@ -191,7 +191,7 @@ bool Packet::crc_ok() const { ais_fcs.process_byte(field_crc.read(i, 8)); } - return (ais_fcs.checksum() == field_crc.read(data_length(), fcs_length)); + return (ais_fcs.checksum() == (unsigned)field_crc.read(data_length(), fcs_length)); } size_t Packet::data_and_fcs_length() const { diff --git a/firmware/common/ak4951.cpp b/firmware/common/ak4951.cpp index d94bbb0b..1f88a3d6 100644 --- a/firmware/common/ak4951.cpp +++ b/firmware/common/ak4951.cpp @@ -115,6 +115,10 @@ void AK4951::init() { // update(Register::DigitalFilterMode); } +bool AK4951::detected() { + return reset(); +} + bool AK4951::reset() { io.audio_reset_state(true); diff --git a/firmware/common/ak4951.hpp b/firmware/common/ak4951.hpp index ea394966..3b1f9e1a 100644 --- a/firmware/common/ak4951.hpp +++ b/firmware/common/ak4951.hpp @@ -823,6 +823,8 @@ public: std::string name() const override { return "AK4951"; } + + bool detected(); void init() override; bool reset() override; diff --git a/firmware/common/aprs_packet.hpp b/firmware/common/aprs_packet.hpp index e521a955..c7e7c1db 100644 --- a/firmware/common/aprs_packet.hpp +++ b/firmware/common/aprs_packet.hpp @@ -259,7 +259,7 @@ private: bool valid_checksum = false; uint8_t payload[256]; char address_buffer[15]; - uint8_t payload_size; + uint8_t payload_size = 0 ; Timestamp timestamp_ { }; float parse_lat_str_cmp(const std::string& lat_str){ diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 2bee6470..1b577336 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -82,7 +82,7 @@ struct data_t { int32_t afsk_space_freq; int32_t modem_baudrate; int32_t modem_repeat; - + // Play dead unlock uint32_t playdead_magic; uint32_t playing_dead; @@ -95,6 +95,9 @@ struct data_t { uint32_t pocsag_ignore_address; int32_t tone_mix; + + // Hardware + uint32_t hardware_config; }; static_assert(sizeof(data_t) <= backup_ram.size(), "Persistent memory structure too large for VBAT-maintained region"); @@ -224,9 +227,17 @@ void set_playdead_sequence(const uint32_t new_value) { // ui_config is an uint32_t var storing information bitwise // bits 0,1,2 store the backlight timer -// bits 31, 30,29,28,27, 26, 25 stores the different single bit configs depicted below +// bits 31, 30,29,28,27, 26, 25, 24 stores the different single bit configs depicted below // bits on position 4 to 19 (16 bits) store the clkout frequency +bool disable_touchscreen() { // Option to disable touch screen + return data->ui_config & (1 << 24); +} + +bool show_bigger_qr_code() { // show bigger QR code + return data->ui_config & (1 << 23); +} + bool hide_clock() { // clock hidden from main menu return data->ui_config & (1 << 25); } @@ -254,11 +265,23 @@ bool config_splash() { return data->ui_config & (1 << 31); } +uint8_t config_cpld() { + return data->hardware_config; +} + uint32_t config_backlight_timer() { const uint32_t timer_seconds[8] = { 0, 5, 15, 30, 60, 180, 300, 600 }; return timer_seconds[data->ui_config & 7]; //first three bits, 8 possible values } +void set_disable_touchscreen(bool v) { + data->ui_config = (data->ui_config & ~(1 << 24)) | (v << 24); +} + +void set_show_bigger_qr_code(bool v) { + data->ui_config = (data->ui_config & ~(1 << 23)) | (v << 23); +} + void set_clock_hidden(bool v) { data->ui_config = (data->ui_config & ~(1 << 25)) | (v << 25); } @@ -287,6 +310,10 @@ void set_config_splash(bool v) { data->ui_config = (data->ui_config & ~(1 << 31)) | (v << 31); } +void set_config_cpld(uint8_t i) { + data->hardware_config = i; +} + void set_config_backlight_timer(uint32_t i) { data->ui_config = (data->ui_config & ~7) | (i & 7); } diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 11643bab..bdfc1fef 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -74,19 +74,26 @@ void set_playdead_sequence(const uint32_t new_value); bool stealth_mode(); void set_stealth_mode(const bool v); +uint8_t config_cpld(); +void set_config_cpld(uint8_t i); + bool config_splash(); +bool show_bigger_qr_code(); bool hide_clock(); bool clock_with_date(); bool config_login(); bool config_speaker(); uint32_t config_backlight_timer(); +bool disable_touchscreen(); void set_config_splash(bool v); +void set_show_bigger_qr_code(bool v); void set_clock_hidden(bool v); void set_clock_with_date(bool v); void set_config_login(bool v); void set_config_speaker(bool v); void set_config_backlight_timer(uint32_t i); +void set_disable_touchscreen(bool v); //uint8_t ui_config_textentry(); //void set_config_textentry(uint8_t new_value); diff --git a/firmware/common/tpms_packet.cpp b/firmware/common/tpms_packet.cpp index a2abaada..f81ef35a 100644 --- a/firmware/common/tpms_packet.cpp +++ b/firmware/common/tpms_packet.cpp @@ -40,7 +40,7 @@ Optional Packet::reading_fsk_19k2_schrader() const { case 64: return Reading { Reading::Type::FLM_64, - reader_.read(0, 32), + (uint32_t)reader_.read(0, 32), Pressure { static_cast(reader_.read(32, 8)) * 4 / 3 }, Temperature { static_cast(reader_.read(40, 8) & 0x7f) - 56 } }; @@ -48,7 +48,7 @@ Optional Packet::reading_fsk_19k2_schrader() const { case 72: return Reading { Reading::Type::FLM_72, - reader_.read(0, 32), + (uint32_t)reader_.read(0, 32), Pressure { static_cast(reader_.read(40, 8)) * 4 / 3 }, Temperature { static_cast(reader_.read(48, 8)) - 56 } }; @@ -56,7 +56,7 @@ Optional Packet::reading_fsk_19k2_schrader() const { case 80: return Reading { Reading::Type::FLM_80, - reader_.read(8, 32), + (uint32_t)reader_.read(8, 32), Pressure { static_cast(reader_.read(48, 8)) * 4 / 3 }, Temperature { static_cast(reader_.read(56, 8)) - 56 } }; @@ -85,7 +85,7 @@ Optional Packet::reading_ook_8k192_schrader() const { if( (checksum_calculated & 3) == 3 ) { return Reading { Reading::Type::Schrader, - reader_.read(3, 24), + (uint32_t)reader_.read(3, 24), Pressure { static_cast(reader_.read(27, 8)) * 4 / 3 }, { }, Flags { static_cast((flags << 4) | checksum) } @@ -122,7 +122,7 @@ Optional Packet::reading_ook_8k4_schrader() const { if( checksum_calculated == checksum ) { return Reading { Reading::Type::GMC_96, - id, + (uint32_t)id, Pressure { static_cast(value_1) * 4 / 3 }, Temperature { static_cast(value_0) - 56 } }; diff --git a/firmware/common/tpms_packet.hpp b/firmware/common/tpms_packet.hpp index 5ee3e02a..75ad0077 100644 --- a/firmware/common/tpms_packet.hpp +++ b/firmware/common/tpms_packet.hpp @@ -39,7 +39,7 @@ namespace tpms { using Flags = uint8_t; -enum SignalType : uint32_t { +enum SignalType { FSK_19k2_Schrader = 1, OOK_8k192_Schrader = 2, OOK_8k4_Schrader = 3, diff --git a/firmware/graphics/icon_qr_code.png b/firmware/graphics/icon_qr_code.png new file mode 100755 index 00000000..c19e9bdb Binary files /dev/null and b/firmware/graphics/icon_qr_code.png differ diff --git a/firmware/tools/convert_C16_to_complex.grc b/firmware/tools/convert_C16_to_complex.grc new file mode 100644 index 00000000..a46b15f2 --- /dev/null +++ b/firmware/tools/convert_C16_to_complex.grc @@ -0,0 +1,117 @@ +options: + parameters: + author: '' + category: Custom + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: no_gui + hier_block_src_path: '.:' + id: top_block + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: run + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: blocks_file_sink_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /tmp/foo.cfile + type: complex + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [632, 140.0] + rotation: 0 + state: enabled +- name: blocks_file_source_0 + id: blocks_file_source + parameters: + affinity: '' + alias: '' + begin_tag: pmt.PMT_NIL + comment: '' + file: Porpack_Capture.C16 + length: '0' + maxoutbuf: '0' + minoutbuf: '0' + offset: '0' + repeat: 'False' + type: short + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [64, 124.0] + rotation: 0 + state: enabled +- name: blocks_interleaved_short_to_complex_0 + id: blocks_interleaved_short_to_complex + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + swap: 'False' + vector_input: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [272, 156.0] + rotation: 0 + state: enabled +- name: blocks_multiply_const_vxx_0 + id: blocks_multiply_const_vxx + parameters: + affinity: '' + alias: '' + comment: '' + const: ' 1.0 / 32768.0' + maxoutbuf: '0' + minoutbuf: '0' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [448, 156.0] + rotation: 0 + state: true + +connections: +- [blocks_file_source_0, '0', blocks_interleaved_short_to_complex_0, '0'] +- [blocks_interleaved_short_to_complex_0, '0', blocks_multiply_const_vxx_0, '0'] +- [blocks_multiply_const_vxx_0, '0', blocks_file_sink_0, '0'] + +metadata: + file_format: 1 diff --git a/flashing/Check for firmware updates.url b/flashing/Check for firmware updates.url new file mode 100644 index 00000000..bb321246 --- /dev/null +++ b/flashing/Check for firmware updates.url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=https://github.com/eried/portapack-mayhem/releases diff --git a/flashing/How to update the firmware.url b/flashing/How to update the firmware.url new file mode 100644 index 00000000..99cd950b --- /dev/null +++ b/flashing/How to update the firmware.url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=https://github.com/eried/portapack-mayhem/wiki/Update-firmware diff --git a/flashing/README.txt b/flashing/README.txt new file mode 100644 index 00000000..f22ea845 --- /dev/null +++ b/flashing/README.txt @@ -0,0 +1 @@ +Plug HackRF+Portapack, set it in HackRF mode, launch flash_portapack_mayhem.bat \ No newline at end of file diff --git a/flashing/dfu-util-static.exe b/flashing/dfu-util-static.exe new file mode 100644 index 00000000..fe7f8753 Binary files /dev/null and b/flashing/dfu-util-static.exe differ diff --git a/flashing/dfu_hackrf_one.bat b/flashing/dfu_hackrf_one.bat new file mode 100644 index 00000000..a6bf293b --- /dev/null +++ b/flashing/dfu_hackrf_one.bat @@ -0,0 +1,19 @@ +@echo off + +echo *** Run HackRF firmware in RAM via LPC DFU *** +echo. +echo This is used to "unbrick" your HackRF, if you are no longer able to use +echo HackRF tools to flash or operate your HackRF. +echo. +echo Connect your HackRF One to a USB port on your computer. +echo. +echo Hold down both the DFU and RESET buttons on the HackRF. +echo Then release the RESET button (closest to the edge). +echo Then release the DFU button. +echo. +pause + +echo. +dfu-util-static.exe --device 1fc9:000c --download hackrf_one_usb.dfu --reset +echo. +pause diff --git a/flashing/driver/dpinst.exe b/flashing/driver/dpinst.exe new file mode 100644 index 00000000..3efffc16 Binary files /dev/null and b/flashing/driver/dpinst.exe differ diff --git a/flashing/driver/dpinst.xml b/flashing/driver/dpinst.xml new file mode 100644 index 00000000..2e7747a7 --- /dev/null +++ b/flashing/driver/dpinst.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/flashing/driver/hackrf_one.inf b/flashing/driver/hackrf_one.inf new file mode 100644 index 00000000..cb45479f Binary files /dev/null and b/flashing/driver/hackrf_one.inf differ diff --git a/flashing/driver/hackrf_one_amd64.cat b/flashing/driver/hackrf_one_amd64.cat new file mode 100644 index 00000000..e736e11c Binary files /dev/null and b/flashing/driver/hackrf_one_amd64.cat differ diff --git a/flashing/driver/lpc_dfu.inf b/flashing/driver/lpc_dfu.inf new file mode 100644 index 00000000..d95f77c7 Binary files /dev/null and b/flashing/driver/lpc_dfu.inf differ diff --git a/flashing/driver/lpc_dfu_amd64.cat b/flashing/driver/lpc_dfu_amd64.cat new file mode 100644 index 00000000..31234fe0 Binary files /dev/null and b/flashing/driver/lpc_dfu_amd64.cat differ diff --git a/flashing/flash_hackrf_one.bat b/flashing/flash_hackrf_one.bat new file mode 100644 index 00000000..b18bafff --- /dev/null +++ b/flashing/flash_hackrf_one.bat @@ -0,0 +1,15 @@ +@echo off + +echo *** Re-flash the HackRF with HackRF firmware *** +echo. +echo Connect your HackRF One to a USB port on your computer. +echo. +echo If using a PortaPack, put the PortaPack in HackRF mode by selecting +echo the "HackRF" option from the main menu. +echo. +pause + +echo. +hackrf_update.exe hackrf_one_usb.bin +echo. +pause diff --git a/flashing/flash_portapack_mayhem.bat b/flashing/flash_portapack_mayhem.bat new file mode 100644 index 00000000..e7a68199 --- /dev/null +++ b/flashing/flash_portapack_mayhem.bat @@ -0,0 +1,15 @@ +@echo off + +echo *** Re-flash the HackRF with PortaPack firmware *** +echo. +echo Connect your HackRF One to a USB port on your computer. +echo. +echo If using a PortaPack, put the PortaPack in HackRF mode by selecting +echo the "HackRF" option from the main menu. +echo. +pause + +echo. +hackrf_update.exe portapack-h1_h2-mayhem.bin +echo. +pause diff --git a/flashing/hackrf_one_usb.bin b/flashing/hackrf_one_usb.bin new file mode 100644 index 00000000..6e7935ec Binary files /dev/null and b/flashing/hackrf_one_usb.bin differ diff --git a/flashing/hackrf_one_usb.dfu b/flashing/hackrf_one_usb.dfu new file mode 100644 index 00000000..be690312 Binary files /dev/null and b/flashing/hackrf_one_usb.dfu differ diff --git a/flashing/hackrf_update.exe b/flashing/hackrf_update.exe new file mode 100644 index 00000000..529e45f8 Binary files /dev/null and b/flashing/hackrf_update.exe differ