From 9bcc6a799cfcffd321c8c8592c6d3bb6fdf5b0f8 Mon Sep 17 00:00:00 2001 From: "R. van Twisk" Date: Tue, 26 May 2026 07:52:11 +0200 Subject: [PATCH 1/2] Strict Compilation --- .github/copilot-instructions.md | 178 ++++++++++++++++-- src/lib/adsbdecoder/ace/adsbdatacollector.hpp | 6 +- src/lib/adsbdecoder/ace/cpr.hpp | 2 +- src/lib/adsbdecoder/ace/src/adsbdecoder.cpp | 4 +- src/lib/adsbdecoder/ace/src/cpr.cpp | 14 +- .../aircrafttracker_tests/CMakeLists.txt | 2 +- src/lib/bluetooth/ace/src/bluetooth.cpp | 14 +- src/lib/bmp280/ace/bmp280.hpp | 2 +- src/lib/bmp280/ace/src/bmp280.cpp | 8 +- src/lib/config/ace/config.hpp | 4 +- src/lib/config/ace/src/config.cpp | 6 +- src/lib/core/ace/antennaRadiationPattern.hpp | 6 +- src/lib/core/ace/binarymessages.hpp | 6 +- src/lib/core/ace/constants.hpp | 16 +- src/lib/core/ace/coreutils.hpp | 61 +++--- src/lib/core/ace/datasourcetimestatstable.hpp | 4 +- src/lib/core/ace/models.hpp | 12 +- src/lib/core/ace/spinlockguard.hpp | 2 +- src/lib/core/ace/src/basemodule.cpp | 6 +- src/lib/core/ace/src/coreutils.cpp | 10 +- src/lib/fanetace/ace/fanetace.hpp | 8 +- src/lib/fanetace/ace/src/fanetace.cpp | 2 +- src/lib/flarmgatas/ace/flarm2024.hpp | 2 +- src/lib/flarmgatas/ace/src/flarm2024.cpp | 2 +- src/lib/gatas_module.cmake | 2 +- .../gatasconnect/ace/src/gatasconnectudp.cpp | 6 +- src/lib/gdl90service/ace/src/gdl90service.cpp | 6 +- src/lib/gdloverudp/ace/gdloverudp.hpp | 2 +- src/lib/gdloverudp/ace/src/gdloverudp.cpp | 12 +- src/lib/gps/ace/AbstractGnss.hpp | 2 +- src/lib/gpsdecoder/ace/gpsdecoder.hpp | 2 +- src/lib/gpsdecoder/ace/src/gpsdecoder.cpp | 14 +- src/lib/idle/ace/idle.hpp | 2 +- src/lib/idle/ace/src/idle.cpp | 18 +- src/lib/mocks/pico/sync.h | 4 +- src/lib/ogn/ace/ogn1.hpp | 2 +- src/lib/ogn/ace/ognpacket.hpp | 38 ++-- src/lib/ogn/ace/src/ogn1.cpp | 34 ++-- src/lib/pioserial/ace/pioserial.hpp | 10 +- src/lib/pioserial/ace/src/pioserial.cpp | 32 ++-- src/lib/pioserial/ace/uart_rx_f.h | 2 +- src/lib/pioserial/ace/uart_tx.pio | 2 +- .../radiotuner/ace/countryregulations_v2.hpp | 2 +- .../radiotuner/ace/src/radiotunerrx_v2.cpp | 4 +- .../radiotuner/ace/src/radiotunertx_v2.cpp | 2 +- src/lib/sx1262/ace/src/rxdataframequeue.cpp | 4 +- src/lib/sx1262/ace/src/sx1262.cpp | 18 +- src/lib/sx1262/ace/sx1262.hpp | 2 +- src/lib/utils/ace/bitutils.hpp | 10 +- src/lib/utils/ace/ldpc.hpp | 4 +- src/lib/utils/ace/ognconv.hpp | 40 ++-- src/lib/utils/ace/src/cobs.cpp | 2 +- src/lib/utils/ace/src/moreutils.cpp | 2 +- src/lib/utils/ace/src/ognconv.cpp | 73 ++++--- src/lib/utils/ace/src/picopio.cpp | 6 +- src/lib/utils/ace/tcpclient.hpp | 7 +- src/lib/webserver/ace/src/webserver.cpp | 2 +- src/lib/wifiservice/ace/src/wifiservice.cpp | 5 +- 58 files changed, 449 insertions(+), 301 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index f382c11b..ca46cd62 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,15 +1,29 @@ -You are an embedded C++ assistant. +# GATAS Copilot Instructions -Target platform: +You are an embedded C++ assistant for the GATAS conspicuity device project. + +## Project Overview + +GATAS is an aviation conspicuity device supporting multiple radio protocols (OGN, FLARM, FANET, ADS-L, PAW) on a Raspberry Pi Pico. The firmware enables simultaneous multi-protocol transmission/reception through time-sharing technology and serves traffic data to EFBs via GDL90 or NMEA protocols. + +**Repository structure:** +- `src/pico/` – Firmware (RP2040/RP2350 main application) +- `src/lib/` – Core libraries (units organized by domain: core, adsbdecoder, flarmgatas, ogn, fanetace, etc.) +- `src/SystemGUI/` – Web UI (Vue.js) for aircraft configuration +- `src/vendor/` – Third-party dependencies (Catch2, ETL, gdl90, libcrc, libmodes, ArduinoJson, minmea, etc.) + +### Target Platform * Raspberry Pi Pico (RP2040/RP2350, dual-core Cortex-M0+) -* Bare-metal or Pico SDK -* No operating system unless explicitly stated +* Pico SDK 2.1.0+ (required) +* FreeRTOS Kernel V11.2.0 with custom patches +* Bare-metal with FreeRTOS, no higher-level OS -Language and standard: +### Language and Standard -* C++17 only -* No GNU extensions unless explicitly used by the Pico SDK +* **C++17 only** (C++20 for test build but limited in firmware) +* No GNU extensions unless required by Pico SDK +* CMake-based build system with Ninja for both firmware and unit tests ### Core Constraints (Hard Rules) @@ -34,7 +48,7 @@ Language and standard: ### Coding Style -* Always use braces `{}` for all conditionals and loops, even single-line bodies, a opning brace starts at a new line, closing brace ends at a new line +* Always use braces `{}` for all conditionals and loops, even single-line bodies; opening brace starts on a new line, closing brace ends on a new line * Prefer `constexpr`, `const`, and `static` where applicable * Prefer ETL enum utilities for strongly typed enums * Prefer POD types and simple structs @@ -75,13 +89,13 @@ Language and standard: * Mark shared data as `volatile` where appropriate * Use Pico SDK synchronization primitives when needed * Avoid race conditions; prefer lock-free designs -* Prevere FreeRTOS tasks, but use queue_spsc_atomic queues -* Prevere to use mutex, but use for copy of shared memory, for example: auto ownship = SpinlockGuard::copyWithLock(CoreUtils::sharedSpinLock(), ); +* Prefer FreeRTOS tasks, but use queue_spsc_atomic queues for inter-task communication +* Prefer SpinlockGuard for thread-safe shared memory access: `auto data = SpinlockGuard::copyWithLock(CoreUtils::sharedSpinLock(), );` ### Timing -* Prevere to use CoreUtils::timeUs32Raw() for microsecond timings not aligned to seconds -* Prevere to use CoreUtils::timeUs32() for microsecond timings aligned to seconds +* Prefer `CoreUtils::timeUs32Raw()` for microsecond timings not aligned to seconds (free-running counter) +* Prefer `CoreUtils::timeUs32()` for microsecond timings aligned to seconds (PPS-aligned) * Avoid busy-wait loops unless interacting with hardware ### Documentation @@ -104,6 +118,128 @@ If a requested feature violates these rules, explain why and propose a safe embe --- +## Build, Test, and Development Workflow + +### Building Unit Tests (Host-Based) + +**Full test suite:** +```bash +cd src +./runtests.sh +# or manually: +cmake -B build_test -G Ninja && ninja -C build_test +``` + +**Single test (e.g., adsbdecoder):** +```bash +cmake -B build_test -G Ninja && ninja -C build_test adsbdecoder_tests +./build_test/lib/adsbdecoder/adsbdecoder_tests/adsbdecoder_tests +``` + +**Key points:** +- Tests run on **host (x86)**, not on the Pico +- Compilation uses Clang 18 in CI; GCC 14 or Clang 18 supported locally +- Tests use Catch2 framework with no Pico SDK dependencies +- Each test module has its own CMakeLists.txt in `lib/*/lib_*_tests/` + +### Building Firmware + +**Environment setup:** +```bash +export PICO_SDK_PATH=/pico-sdk/ +export FREERTOS_KERNEL_PATH=/FreeRTOS-Kernel +``` + +**Build firmware (RP2040 – Pico W):** +```bash +cd src/pico +cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DPICO_PLATFORM=rp2040 -DPICO_BOARD=pico_w +ninja -C build +# Output: build/GATAS_rp2040.uf2 +``` + +**Build firmware (RP2350 – Pico 2 W):** +```bash +cd src/pico +cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DPICO_PLATFORM=rp2350 -DPICO_BOARD=pico2_w +ninja -C build +# Output: build/GATAS_rp2350-arm-s.uf2 +``` + +**Debug build (USB UART enabled by default):** +```bash +cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DGATAS_UART_OVER_USB=1 -DPICO_PLATFORM=rp2040 +``` + +### Configuration + +- **Firmware defaults:** Configured in `src/pico/gatas_default_config.json` (processed by `external/optimizejson.py` into `generated/default_config.hpp`) +- **Build-time headers:** `src/pico/generated/config.hpp` and `build_time.hpp` auto-generated by CMake +- **UART over USB:** Controlled by `-DGATAS_UART_OVER_USB=1` flag (Release builds default to USB, Debug defaults to physical UART) + +### CI/CD + +- GitHub Actions workflows in `.github/workflows/ci.yml` and `release.yml` +- CI runs unit tests on every push, builds both firmware targets and Docker image +- Release builds create GitHub releases with UF2 files and changelog +- Custom GitHub Actions in `.github/actions/` for setup and build orchestration + +--- + +## Architecture and Key Conventions + +### Module Organization + +**`src/lib/`** – Unit-testable pure-logic libraries: +- `core/` – Fundamental utilities (CoreUtils, poolallocator, timing, synchronization guards) +- `adsbdecoder/` – ADS-B frame decoding and CPR math +- `aircrafttracker/` – Aircraft state tracking and path prediction +- `config/` – Configuration storage (flash or in-memory) +- `radiotuner/` – Radio frequency tuning (rx/tx, country regulations) +- `gdl90service/` – GDL90 protocol formatting +- `utils/` – Bit/packet manipulation, COBS encoding, Manchester encoding, DDB database utils +- `sx1262/` – SX1262 transceiver driver (hardware-specific but testable via mocks) +- `flarmgatas/` – FLARM 2024 protocol implementation +- `fanetace/` – FANET protocol implementation +- `ogn/` – OGN protocol implementation +- `adslace/` – ADS-L protocol implementation +- `gatasconnect/` – GATASConnect UDP/TCP protocol +- `wifiservice/`, `bluetooth/`, `webserver/` – Connectivity and UI services +- `dataport/` – NMEA/GDL90 output over UART/serial + +**`src/pico/`** – Firmware entry point: +- `main.cpp` – System initialization, module composition, FreeRTOS task creation +- `main.h` – Configuration and hardware setup +- `IdleMemory.c` – Memory optimization for idle time +- `CMakeLists.txt` – Firmware build configuration + +**`src/SystemGUI/`** – Vue.js web UI for aircraft configuration (separate from firmware) + +### Naming and File Organization + +- **Header files:** `.hpp` for C++ libraries, `.h` for pure-C or hardware definitions +- **Test files:** `*_test.cpp` in `*_tests/` directories +- **ACE suffix:** Embedded implementations in `ace/` subdirectories (e.g., `lib/sx1262/ace/sx1262.hpp` vs. external driver in `lib/sx1262/driver/`) +- **Mock files:** `src/lib/mocks/` contains Pico SDK and FreeRTOS stubs for host-based testing + +### Message Routing and Concurrency + +- **MessageRouter:** Central pub/sub system for inter-module communication (see `core/messagerouter.hpp`) +- **Synchronization:** + - Use `SpinlockGuard::copyWithLock()` for thread-safe shared memory access + - Use `SemaphoreGuard` for critical sections + - Prefer queue_spsc_atomic for lock-free inter-task queues +- **FreeRTOS tasks:** Avoid creating new tasks; use message router and existing task infrastructure +- **Timing:** Use `CoreUtils::timeUs32()` (aligned to PPS) or `CoreUtils::timeUs32Raw()` (free-running) for microsecond timings + +### Protocol Handling + +- **Multi-protocol time-sharing:** Transceiver alternates between protocols based on active traffic and priority +- **Adaptive prioritization:** Protocols with recent RX activity get more airtime +- **Ground station mode (ADS-L):** Relays traffic back into the network; max 10 aircraft uplinked + +--- + ## Unit Testing (Catch2 – Embedded Safe) ### General Rules @@ -112,6 +248,8 @@ If a requested feature violates these rules, explain why and propose a safe embe * Tests are **host-based by default** (x86/CI), not running on the RP2040 * Tests must compile **without Pico SDK dependencies** * Hardware access must be abstracted or mocked +* Test file pattern: `lib//_tests/_test.cpp` +* Each test module auto-builds and links mocks from `src/lib/mocks/` ### Allowed in Tests @@ -137,22 +275,26 @@ If a requested feature violates these rules, explain why and propose a safe embe * Hardware abstraction layer (HAL) * Use dependency injection via references or interfaces (non-virtual preferred) * Prefer compile-time configuration over runtime setup -* when using REQUIRE follow REQUIRE( == ); SO always set expected value first +* **Assertion format:** Always `REQUIRE( == )` – put expected value first +* Tests may include `#include "pico/rand.h"`, `"pico/time.h"` etc., which are mocked ### Mocking Strategy * Do NOT use mocking frameworks * Use: - * Simple fake structs - * Manual stubs with deterministic behavior + * Simple fake structs with deterministic behavior + * Manual stubs in `src/lib/mocks/` (pico.h, FreeRTOS.h, task.h, geomock.hpp, etc.) * Compile-time substitution (`#ifdef UNIT_TEST` only if unavoidable) +* Mock headers shadow Pico/FreeRTOS APIs; globals like `time_us_Value`, `mockConfig`, `geomock_*` are used by tests +* Example: `coreutils_test.cpp` sets `time_us_Value` to simulate time, calls `CoreUtils::msSinceEpoch()`, verifies result Example pattern: -* `Driver` depends on `Interface&` -* Tests provide a `FakeInterface` -* Production provides a hardware-backed implementation +* Interface: `class GnsDriver { virtual void read() = 0; }` +* Production: `class L76B : public GnsDriver { /*Pico SDK calls*/ }` +* Test fake: `struct FakeGnss { void read() { /*deterministic data*/ } }` +* Test code: `void testParsing(GnsDriver& driver)` – inject FakeGnss ### Assertions diff --git a/src/lib/adsbdecoder/ace/adsbdatacollector.hpp b/src/lib/adsbdecoder/ace/adsbdatacollector.hpp index d8182158..4e52528b 100644 --- a/src/lib/adsbdecoder/ace/adsbdatacollector.hpp +++ b/src/lib/adsbdecoder/ace/adsbdatacollector.hpp @@ -209,7 +209,7 @@ class AdsbDataCollector } } - void updateRawOdd(uint32_t raw_latitude, uint32_t raw_longitude) + void updateRawOdd(int32_t raw_latitude, int32_t raw_longitude) { currentDataStatus->messageStatus |= HAS_POSITION_ODD; currentDataStatus->raw_odd_latitude = raw_latitude; @@ -217,7 +217,7 @@ class AdsbDataCollector decodePCR(true); } - void updateRawEven(uint32_t raw_latitude, uint32_t raw_longitude) + void updateRawEven(int32_t raw_latitude, int32_t raw_longitude) { currentDataStatus->messageStatus |= HAS_POSITION_EVEN; currentDataStatus->raw_even_latitude = raw_latitude; @@ -249,7 +249,7 @@ class AdsbDataCollector { if ((currentDataStatus->messageStatus & VALID_MASK) == VALID_MASK) { - currentDataStatus->messageStatus &= ~HAS_POSITION_UPDATED; + currentDataStatus->messageStatus &= static_cast(~HAS_POSITION_UPDATED); return true; } diff --git a/src/lib/adsbdecoder/ace/cpr.hpp b/src/lib/adsbdecoder/ace/cpr.hpp index 07b1877c..e7046071 100644 --- a/src/lib/adsbdecoder/ace/cpr.hpp +++ b/src/lib/adsbdecoder/ace/cpr.hpp @@ -3,4 +3,4 @@ #include -void decodeCPR(bool fflag, uint32_t even_cprlat, uint32_t even_cprlon, uint32_t odd_cprlat, uint32_t odd_cprlon, float *pfLat, float *pfLon); +void decodeCPR(bool fflag, int32_t even_cprlat, int32_t even_cprlon, int32_t odd_cprlat, int32_t odd_cprlon, float *pfLat, float *pfLon); diff --git a/src/lib/adsbdecoder/ace/src/adsbdecoder.cpp b/src/lib/adsbdecoder/ace/src/adsbdecoder.cpp index 44dfd0f0..bdfa7e7c 100644 --- a/src/lib/adsbdecoder/ace/src/adsbdecoder.cpp +++ b/src/lib/adsbdecoder/ace/src/adsbdecoder.cpp @@ -109,7 +109,7 @@ void ADSBDecoder::processAdsbData(const uint8_t *data, uint8_t length) // THis might temporary create a incorrect offset, but should be corrected pretty quickly die to how ADSB sends different information in different packages // In addition this is also not the true altitude - int32_t altitude = (mm.unit == MODE_S_UNIT_METERS ? mm.altitude : mm.altitude * FT_TO_M); + int32_t altitude = mm.unit == MODE_S_UNIT_METERS ? mm.altitude : static_cast(static_cast(mm.altitude) * FT_TO_M); if (mm.metype >= 20 && mm.metype <= 22) // GPS Altitude so far never seen this { @@ -126,7 +126,7 @@ void ADSBDecoder::processAdsbData(const uint8_t *data, uint8_t length) if (mm.mesub == 1 || mm.mesub == 2) { // printf("%06lX Ellipsoid:%ldm\n", mm.aa, baro_gnss_diff); - adsbDataCollector.updateVelocityHeadingBaroDiff(mm.velocity, mm.vert_rate_sign ? -mm.vert_rate : mm.vert_rate, mm.heading, mm.head * FT_TO_M); // mm.head is always in feet + adsbDataCollector.updateVelocityHeadingBaroDiff(mm.velocity, mm.vert_rate_sign ? -mm.vert_rate : mm.vert_rate, mm.heading, static_cast(static_cast(mm.head) * FT_TO_M)); // mm.head is always in feet } else if (mm.mesub == 3 || mm.mesub == 4) { diff --git a/src/lib/adsbdecoder/ace/src/cpr.cpp b/src/lib/adsbdecoder/ace/src/cpr.cpp index d164e66b..899cde5a 100644 --- a/src/lib/adsbdecoder/ace/src/cpr.cpp +++ b/src/lib/adsbdecoder/ace/src/cpr.cpp @@ -45,7 +45,7 @@ int16_t cprModint (int16_t a, int16_t b) /* Always positive MOD operation, used for CPR decoding. */ float cprModDouble(float a, float b) { - float res = fmod(a, b); + float res = fmodf(a, b); if (res < 0) res += b; return res; } @@ -119,7 +119,7 @@ int16_t cprNLFunction(float lat) int16_t cprNFunction(float lat, bool fflag) { - int16_t nl = cprNLFunction(lat) - (fflag ? 1 : 0); + int16_t nl = static_cast(cprNLFunction(lat) - (fflag ? 1 : 0)); if (nl < 1) nl = 1; return nl; } @@ -140,7 +140,7 @@ float cprDlonFunction(float lat, bool fflag, bool surface=false) * simplicity. This may provide a position that is less fresh of a few * seconds. */ -void decodeCPR(bool fflag, uint32_t even_cprlat, uint32_t even_cprlon, uint32_t odd_cprlat, uint32_t odd_cprlon, float *pfLat, float *pfLon) +void decodeCPR(bool fflag, int32_t even_cprlat, int32_t even_cprlon, int32_t odd_cprlat, int32_t odd_cprlon, float *pfLat, float *pfLon) { constexpr float AirDlat0 = 360.0f / 60; constexpr float AirDlat1 = 360.0f / 59; @@ -153,7 +153,7 @@ void decodeCPR(bool fflag, uint32_t even_cprlat, uint32_t even_cprlon, uint32_t float rlat, rlon; /* Compute the Latitude Index "j" */ - int16_t j = static_cast(floor(((59*lat0 - 60.0f*lat1) / 131072) + 0.5)); + int16_t j = static_cast(floorf(((59*lat0 - 60.0f*lat1) / 131072) + 0.5f)); float rlat0 = AirDlat0 * (cprModint (j,60) + lat0 / 131072.0f); float rlat1 = AirDlat1 * (cprModint (j,59) + lat1 / 131072.0f); @@ -175,7 +175,7 @@ void decodeCPR(bool fflag, uint32_t even_cprlat, uint32_t even_cprlon, uint32_t { /* Use odd packet. */ int16_t ni = cprNFunction(rlat1,true); - int16_t m = static_cast(floor((((lon0 * (cprLat1-1)) - (lon1 * cprLat1)) / 131072.0f) + 0.5f)); + int16_t m = static_cast(floorf((((lon0 * (cprLat1-1)) - (lon1 * cprLat1)) / 131072.0f) + 0.5f)); rlon = cprDlonFunction(rlat1,true) * (cprModint (m,ni)+lon1/131072); rlat = rlat1; @@ -184,11 +184,11 @@ void decodeCPR(bool fflag, uint32_t even_cprlat, uint32_t even_cprlon, uint32_t { /* Use even packet. */ int16_t ni = cprNFunction(rlat0,false); - int16_t m = static_cast(floor((((lon0 * (cprLat0-1)) - (lon1 * cprLat0)) / 131072.0f) + 0.5f)); + int16_t m = static_cast(floorf((((lon0 * (cprLat0-1)) - (lon1 * cprLat0)) / 131072.0f) + 0.5f)); rlon = cprDlonFunction(rlat0,false) * (cprModint (m,ni)+lon0/131072); rlat = rlat0; } - rlon -= floor( (rlon + 180.0f) / 360.0f ) * 360.0f; + rlon -= floorf( (rlon + 180.0f) / 360.0f ) * 360.0f; *pfLat = rlat; *pfLon = rlon; diff --git a/src/lib/aircrafttracker/aircrafttracker_tests/CMakeLists.txt b/src/lib/aircrafttracker/aircrafttracker_tests/CMakeLists.txt index c1fd9798..38dd0c07 100644 --- a/src/lib/aircrafttracker/aircrafttracker_tests/CMakeLists.txt +++ b/src/lib/aircrafttracker/aircrafttracker_tests/CMakeLists.txt @@ -32,7 +32,7 @@ endif() # These examples use the standard separate compilation set(SOURCES_IDIOMATIC_EXAMPLES - trackerdata_test.cpp + trackerdata_test.cpp ) string(REPLACE ".cpp" "" BASENAMES_IDIOMATIC_EXAMPLES diff --git a/src/lib/bluetooth/ace/src/bluetooth.cpp b/src/lib/bluetooth/ace/src/bluetooth.cpp index 777f1271..a829d2a3 100644 --- a/src/lib/bluetooth/ace/src/bluetooth.cpp +++ b/src/lib/bluetooth/ace/src/bluetooth.cpp @@ -52,7 +52,7 @@ void Bluetooth::start() bd_addr_t null_addr; memset(null_addr, 0, 6); gap_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00); - gap_advertisements_set_data(advertiseData.size(), advertiseData.data()); + gap_advertisements_set_data(static_cast(advertiseData.size()), advertiseData.data()); gap_advertisements_enable(1); gap_set_local_name(localName.c_str()); @@ -141,7 +141,7 @@ void Bluetooth::createAdvData() // bit 4 Previously Used advertiseData.push_back(0x06); - uint8_t maxSize = etl::min((size_t)8, localName.size()); + uint8_t maxSize = static_cast(etl::min(static_cast(8), localName.size())); advertiseData.push_back(static_cast(1 + maxSize)); // length = type + name length advertiseData.push_back(BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME); advertiseData.insert(advertiseData.end(), localName.begin(), localName.begin() + maxSize); @@ -241,7 +241,7 @@ void Bluetooth::attContextCallback(void *context) uint8_t sendStatus = !ERROR_CODE_SUCCESS; if (btContext->hciHandle && (btContext->readyState & ATT_READYSTATE) == ATT_READYSTATE) { - sendStatus = att_server_notify(btContext->hciHandle, btContext->attrHandle, data.data(), data.size()); + sendStatus = att_server_notify(btContext->hciHandle, btContext->attrHandle, data.data(), static_cast(data.size())); } size_t used=0; @@ -281,8 +281,8 @@ void Bluetooth::attPacketHandler(uint8_t packet_type, uint16_t channel, uint8_t case ATT_EVENT_CONNECTED: { auto handle = att_event_connected_get_handle(packet); - auto mtu = att_server_get_mtu(handle) - 4; - if (createConnection(handle, mtu, 0b010)) + auto mtu = static_cast(att_server_get_mtu(handle) - 4); + if (createConnection(handle, mtu, static_cast(0b010))) { printf("ATT_EVENT_CONNECTED Handle:%d MTU:%d\n", handle, mtu); // Only re-advertise when it's possible to accept new connections @@ -375,7 +375,7 @@ int Bluetooth::attWriteCallback(hci_con_handle_t con_handle, uint16_t att_handle Bluetooth::withHandle(con_handle, etl::delegate::create([buffer](BtContext &ctx) { - ctx.readyState |= little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION ? Bluetooth::CONN_READY : 0b000; + ctx.readyState |= static_cast(little_endian_read_16(buffer, 0) == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION ? Bluetooth::CONN_READY : 0b000); ctx.attrHandle = ATT_CHARACTERISTIC_0000ffe1_0000_1000_8000_00805f9b34fb_01_VALUE_HANDLE; } )); @@ -401,7 +401,7 @@ uint16_t Bluetooth::attReadCallback(hci_con_handle_t connection_handle, uint16_t UNUSED(connection_handle); if (att_handle == ATT_CHARACTERISTIC_GAP_DEVICE_NAME_01_VALUE_HANDLE) { - return att_read_callback_handle_blob((const uint8_t *)Bluetooth::instance->localName.c_str(), Bluetooth::instance->localName.size(), offset, buffer, buffer_size); + return att_read_callback_handle_blob((const uint8_t *)Bluetooth::instance->localName.c_str(), static_cast(Bluetooth::instance->localName.size()), offset, buffer, buffer_size); } return 0; } diff --git a/src/lib/bmp280/ace/bmp280.hpp b/src/lib/bmp280/ace/bmp280.hpp index 79be31f5..37a55f7f 100644 --- a/src/lib/bmp280/ace/bmp280.hpp +++ b/src/lib/bmp280/ace/bmp280.hpp @@ -55,7 +55,7 @@ class Bmp280 : public BaseModule, public etl::message_router(config.valueByPath(0, NAME, "compensation")); } virtual ~Bmp280() = default; diff --git a/src/lib/bmp280/ace/src/bmp280.cpp b/src/lib/bmp280/ace/src/bmp280.cpp index a70fb7b6..88306c8a 100644 --- a/src/lib/bmp280/ace/src/bmp280.cpp +++ b/src/lib/bmp280/ace/src/bmp280.cpp @@ -11,7 +11,7 @@ void Bmp280::on_receive(const GATAS::ConfigUpdatedMsg &msg) { if (msg.moduleName == Bmp280::NAME) { - compensation = msg.config.valueByPath(0, Bmp280::NAME, "compensation"); + compensation = static_cast(msg.config.valueByPath(0, Bmp280::NAME, "compensation")); } } @@ -52,7 +52,7 @@ uint32_t Bmp280::compensate_pressure(int32_t adc_P) if (var1 == 0) return 0; - p = (((uint32_t)(((int32_t)1048576) - adc_P) - (var2 >> 12))) * 3125; + p = static_cast((((int32_t)1048576) - adc_P) - (var2 >> 12)) * 3125U; if (p < 0x80000000) p = (p << 1) / ((uint32_t)var1); else @@ -143,9 +143,9 @@ void Bmp280::on_receive(const GATAS::Every30SecMsg &msg) int32_t temperature = ((uint32_t)buffer[3] << 12) | ((uint32_t)buffer[4] << 4) | (buffer[5] >> 4); temperature = compensate_temp(temperature); - pressure = compensate_pressure(pressure); + pressure = static_cast(compensate_pressure(pressure)); - statistics.lastPressurehPa = (pressure + compensation) / 100.0f; + statistics.lastPressurehPa = static_cast(pressure + compensation) / 100.0f; getBus().receive(GATAS::BarometricPressureMsg( GATAS::BarometricPressure( statistics.lastPressurehPa, CoreUtils::timeUs32Raw()))); diff --git a/src/lib/config/ace/config.hpp b/src/lib/config/ace/config.hpp index 211a4311..4428c51f 100644 --- a/src/lib/config/ace/config.hpp +++ b/src/lib/config/ace/config.hpp @@ -54,10 +54,10 @@ class Config : public Configuration, public etl::message_router { auto const &key = pathParsed[depth]; // TODO: Check if we can do without the PATH index check - auto index = etl::to_arithmetic(key); + auto index = etl::to_arithmetic(key); if (index.has_value()) { - variant = variant[(int)index.value()]; + variant = variant[index.value()]; } else { diff --git a/src/lib/config/ace/src/config.cpp b/src/lib/config/ace/src/config.cpp index b96d2b41..f14f0d77 100644 --- a/src/lib/config/ace/src/config.cpp +++ b/src/lib/config/ace/src/config.cpp @@ -74,7 +74,7 @@ GATAS::PostConstruct Config::postConstruct() else { statistics.location = PERSISTENT; - statistics.persistentStoreSize = strlen((const char *)permanentStore.data()) + 1; + statistics.persistentStoreSize = static_cast(strlen((const char *)permanentStore.data()) + 1); serializeToVolatile(); } } @@ -252,7 +252,7 @@ void Config::serializeToPersistent() permanentStore.rewind(); permanentStore.write(volatileStore.data(), strlen((const char *)volatileStore.data()) + 1); - statistics.persistentStoreSize = strlen((char *)permanentStore.data()) + 1; + statistics.persistentStoreSize = static_cast(strlen((char *)permanentStore.data()) + 1); } bool Config::deleteData(const etl::string_view fullPath) @@ -266,7 +266,7 @@ bool Config::deleteData(const etl::string_view fullPath) auto array = src.as(); if (array) { - src.remove(idx.value()); + src.remove(static_cast(idx.value())); dataMutated = true; } } diff --git a/src/lib/core/ace/antennaRadiationPattern.hpp b/src/lib/core/ace/antennaRadiationPattern.hpp index ab71da4c..bab7648c 100644 --- a/src/lib/core/ace/antennaRadiationPattern.hpp +++ b/src/lib/core/ace/antennaRadiationPattern.hpp @@ -41,9 +41,9 @@ namespace GATAS void put(const GATAS::IngressAircraftPositionMsg &msg) { auto &position = msg.position; - const float bearingFromOwn = CoreUtils::bearingFromInDegShort(position.relEastFromOwn, position.relNorthFromOwn); + const float bearingFromOwn = CoreUtils::bearingFromInDegShort(static_cast(position.relEastFromOwn), static_cast(position.relNorthFromOwn)); const float relativeBearing = CoreUtils::toBearing(bearingFromOwn - static_cast(position.track)); - uint8_t positionInRadial = CoreUtils::getRadialSection(relativeBearing); + uint8_t positionInRadial = static_cast(CoreUtils::getRadialSection(static_cast(relativeBearing))); Measurement &measurement = radiationPattern[positionInRadial]; if (position.distanceFromOwn > measurement.maxDistance) @@ -52,7 +52,7 @@ namespace GATAS measurement.maxRssiDbm = msg.rssidBm; } measurement.avgDistance = (measurement.avgDistance + position.distanceFromOwn) / 2; - measurement.avgRssiDbm = (measurement.avgRssiDbm + msg.rssidBm) / 2; + measurement.avgRssiDbm = static_cast((measurement.avgRssiDbm + msg.rssidBm) / 2); } const etl::array& _radiationPattern() const diff --git a/src/lib/core/ace/binarymessages.hpp b/src/lib/core/ace/binarymessages.hpp index 7acdfd1c..80449ba6 100644 --- a/src/lib/core/ace/binarymessages.hpp +++ b/src/lib/core/ace/binarymessages.hpp @@ -64,8 +64,8 @@ class BinaryMessages uint32_t addressRaw = reader.read_unchecked(24U); uint8_t addressTypeIdx = reader.read_unchecked(8U); uint8_t dataSourceIdx = reader.read_unchecked(8U); - float lat = static_cast(reader.read_unchecked(32U)) / 1E7; - float lon = static_cast(reader.read_unchecked(32U)) / 1E7; + float lat = static_cast(reader.read_unchecked(32U)) / 1E7f; + float lon = static_cast(reader.read_unchecked(32U)) / 1E7f; int16_t heightHAE = reader.read_unchecked(16U) - 100; // Aircraft message needs to be in ellipsoid float track = static_cast(reader.read_unchecked(8U)) * (360.f / 255.f); float turnRate = static_cast(reader.read_unchecked(8U)) / 5.0f; @@ -96,7 +96,7 @@ class BinaryMessages heightHAE, verticalRate, groundSpeed, - track, + static_cast(track), turnRate, rel.distance, rel.relNorth, diff --git a/src/lib/core/ace/constants.hpp b/src/lib/core/ace/constants.hpp index 8bb10c56..4967f60d 100644 --- a/src/lib/core/ace/constants.hpp +++ b/src/lib/core/ace/constants.hpp @@ -7,6 +7,8 @@ #include "etl/string_stream.h" #include "poolallocator.hpp" +constexpr float M_PIF = (float)M_PI; +constexpr float M_TWOPIF = 2.0f * M_PIF; // 2 x PI constexpr float KN_TO_MS = 0.514444444f; // knots to meter/sec constexpr float MS_TO_KN = 1.0f / KN_TO_MS; // meter/sec to knots constexpr float MS_TO_FTPMIN = 196.850394f; // meter/sec to feet/min @@ -18,13 +20,9 @@ constexpr float MS_TO_DMPS = 10.f; // meter/sec to decmeter/sec constexpr float DPMS_TO_MS = 1.f / MS_TO_DMPS; // decmeter/sec to meter/sec constexpr float FT_TO_M = 0.3048f; // feet to meter constexpr float M_TO_FT = 1.0f / FT_TO_M; // feet to meter -constexpr float DEG_TO_RADS = M_PI / 180.f; // degrees to radians -constexpr float RADS_TO_DEG = 180.f / M_PI; // degrees to radians -constexpr float DIAMETER_EARTH_M = 6371640; // Radius of the earth in km - -#if !defined(M_TWOPI) -constexpr float M_TWOPI = 2.0f * M_PI; // 2 x PI -#endif +constexpr float DEG_TO_RADS = M_PIF / 180.f; // degrees to radians +constexpr float RADS_TO_DEG = 180.f / M_PIF; // degrees to radians +constexpr float DIAMETER_EARTH_M = 6371640.f; // Radius of the earth in km namespace GATAS { @@ -54,11 +52,11 @@ namespace GATAS // 32 Byte is a decoded manchester frame // 64 is an manchester frame // 216 byte are LORA ADSL-H Frames - // Maximum size should be 0xC8 (200 bytes) which is ADSL TrafficUplink + 4 byte because we shift a byte + // Maximum size should be 0xC8 (200 bytes) which is ADSL TrafficUplink + 4 byte because we shift a byte using GlobalPoolConfiguration = MultiPoolAllocator, PoolSpec<64, 4>, PoolSpec<0xD0 + 4, 4>>; enum class PinType : uint8_t; - using PinTypeMap = etl::flat_map; + using PinTypeMap = etl::flat_map; constexpr etl::format_spec ICAO_HEX_FORMAT = etl::format_spec{}.hex().width(6).upper_case(true); constexpr etl::format_spec RESET_FORMAT = etl::format_spec{}; diff --git a/src/lib/core/ace/coreutils.hpp b/src/lib/core/ace/coreutils.hpp index 33b3e68f..54573171 100644 --- a/src/lib/core/ace/coreutils.hpp +++ b/src/lib/core/ace/coreutils.hpp @@ -7,6 +7,7 @@ #include "pico/time.h" +#include "constants.hpp" #include "messages.hpp" #include "spinlockguard.hpp" @@ -26,21 +27,11 @@ class CoreUtils spinLock = SpinlockGuard::claim(); } - __force_inline static spin_lock_t * sharedSpinLock() + __force_inline static spin_lock_t *sharedSpinLock() { return spinLock; } - /** - * Convert and timestamp to an uint32_t which is synced with GPS time such that at PPS the ms should reppresents (somewhere close) to a ms - * eg: 45'453'010 = represents 10ms after PPS - * \deprecated - */ - static uint32_t timeToPositionTs(int8_t hours, int8_t minutes, int8_t seconds, int16_t microseconds) - { - return hours * 3600 + minutes * 60 + seconds + microseconds; - } - /** * Get a timestamp in us aligned on PPS so that for example45000 is at the exact pps * This timestamp monotonically increases from power up @@ -71,7 +62,7 @@ class CoreUtils */ static uint32_t timeMs32() { - return timeUs64() / 1'000; + return static_cast(timeUs64() / (uint64_t)1'000); } /** * Get a timestamp in seconds @@ -79,7 +70,7 @@ class CoreUtils */ static uint32_t timeS32() { - return timeUs64() / 1'000'000; + return static_cast(timeUs64() / (uint32_t)1'000'000); } /** @@ -144,7 +135,7 @@ class CoreUtils */ static void __time_critical_func(setPPS)(int32_t offsetUs) { - CoreUtils_timeUs32PpsOffset = time_us_32() % 1'000'000 - offsetUs; + CoreUtils_timeUs32PpsOffset = static_cast(static_cast(time_us_32() % 1'000'000) - static_cast(offsetUs)); } /** @@ -153,12 +144,12 @@ class CoreUtils */ static uint16_t msInSecond() { - return (timeUs32() / 1'000) % 1'000; + return static_cast(static_cast((timeUs32() / 1'000)) % static_cast(1'000)); } static uint16_t usInSecond() { - return (timeUs64()) % 1'000'000; + return static_cast(timeUs64() % static_cast(1'000'000)); } /** @@ -178,7 +169,7 @@ class CoreUtils } else { - return 1'000 - ms + refMsInSecond; + return static_cast(1'000 - ms + refMsInSecond); } } @@ -208,7 +199,7 @@ class CoreUtils */ static uint32_t secondsSinceEpoch() { - return msSinceEpoch() / 1000; + return static_cast(msSinceEpoch() / static_cast(1000)); } /** @@ -222,7 +213,7 @@ class CoreUtils static uint32_t msSinceMidnight() { - return msSinceEpoch() % 86'400'000; + return static_cast(msSinceEpoch() % static_cast(86'400'000)); } static tm localTime() @@ -232,7 +223,7 @@ class CoreUtils static tm localTime(uint64_t msSinceEpoch) { - time_t secondsSinceEpoch = msSinceEpoch / 1000; + time_t secondsSinceEpoch = static_cast(msSinceEpoch / static_cast(1000)); struct tm timeinfo = {}; localtime_r(&secondsSinceEpoch, &timeinfo); return timeinfo; @@ -338,7 +329,7 @@ class CoreUtils float dLon = toLon - fromLon; float cosToLat = cosf(toLat); float bearingDegrees = atan2f(sinf(dLon) * cosToLat, (cosf(fromLat) * sinf(toLat)) - (sinf(fromLat) * cosToLat * cosf(dLon))); - return fmodf((bearingDegrees + M_TWOPI), M_TWOPI); + return fmodf((bearingDegrees + M_TWOPIF), M_TWOPIF); } /** @@ -356,8 +347,9 @@ class CoreUtils static float __time_critical_func(bearingFromInDegShort)(float east, float north) { float theta = atan2f(east, north); - float deg = theta * 180.f / M_PI; - if (deg < 0.f) { + float deg = theta * 180.f / (float)M_PI; + if (deg < 0.f) + { deg += 360.f; } return deg; @@ -379,12 +371,13 @@ class CoreUtils int32_t relEast; uint16_t bearing() { - auto bearing = bearingFromInDegShort(relEast, relNorth); - if (bearing >= 360) + float bearing = bearingFromInDegShort(static_cast(relEast), static_cast(relNorth)); + uint16_t rounded = static_cast(bearing + 0.5f); + if (rounded >= 360) { - bearing = 0; + rounded = 0; } - return bearing; + return rounded; } }; @@ -472,13 +465,13 @@ class CoreUtils degree = CoreUtils::toBearing(degree); // Calculate the section - return static_cast(fmodf((degree + (sectionSize >> 1)) / sectionSize, SECTIONS)); + return static_cast(fmodf(static_cast(degree + (sectionSize >> 1)) / static_cast(sectionSize), static_cast(SECTIONS))); } template static int getRadialSectionRad(float rad) { - return getRadialSection(rad * RADS_TO_DEG); + return getRadialSection(static_cast(rad * RADS_TO_DEG)); } /* @@ -608,7 +601,7 @@ class CoreUtils // For lowercase a-f letters: // return val - (val < 58 ? 48 : 87); // Or the two combined, but a bit slower: - return val - (val < 58 ? 48 : (val < 97 ? 55 : 87)); + return static_cast(val - (val < 58 ? 48 : (val < 97 ? 55 : 87))); } /** @@ -622,10 +615,14 @@ class CoreUtils } } + /** + * Convert a HEX string to a byte array to a maximum length of 254 characters/ + */ static void hexStrToByteArray(const char *hex, uint8_t byteArray[]) { auto hexLength = strlen(hex); - hexStrToByteArray(hex, hexLength, byteArray); + if (hexLength > 254) return; + hexStrToByteArray(hex, static_cast(hexLength), byteArray); } /** @@ -645,7 +642,7 @@ class CoreUtils /** * Returns the pin number from the pin map, when not found returns -1 to indicate that */ - static int8_t pinValue(const GATAS::PinTypeMap &pm, const GATAS::PinType &pinName, int8_t defaultValue = -1) + static uint8_t pinValue(const GATAS::PinTypeMap &pm, const GATAS::PinType &pinName, uint8_t defaultValue = UINT8_MAX) { auto it = pm.find(pinName); if (it != pm.end()) diff --git a/src/lib/core/ace/datasourcetimestatstable.hpp b/src/lib/core/ace/datasourcetimestatstable.hpp index 2d801a01..7f54d008 100644 --- a/src/lib/core/ace/datasourcetimestatstable.hpp +++ b/src/lib/core/ace/datasourcetimestatstable.hpp @@ -33,7 +33,7 @@ namespace GATAS { if (stat.frequency == frequency) { - stat.timeTenthMs.set(tenthMsIndex); + stat.timeTenthMs.set(static_cast(tenthMsIndex)); return; } } @@ -43,7 +43,7 @@ namespace GATAS auto &stat = storage_[size_++]; stat = DataSourceTimeStats{}; stat.frequency = frequency; - stat.timeTenthMs.set(tenthMsIndex); + stat.timeTenthMs.set(static_cast(tenthMsIndex)); } } diff --git a/src/lib/core/ace/models.hpp b/src/lib/core/ace/models.hpp index d4d044ab..be845e09 100644 --- a/src/lib/core/ace/models.hpp +++ b/src/lib/core/ace/models.hpp @@ -266,7 +266,7 @@ namespace GATAS bool airborne; // Is the aircraft airborne float lat; float lon; - int16_t ellipseHeight; // Altitude above the GeoId (MSL) in meters. For aircraft where altitude is based from BARO, this is an estimate + int32_t ellipseHeight; // Altitude above the GeoId (MSL) in meters. For aircraft where altitude is based from BARO, this is an estimate float verticalSpeed; // in m/s float groundSpeed; // in m/s int16_t track; // 0..359 @@ -284,7 +284,7 @@ namespace GATAS { } // Default constructor - AircraftPositionInfo() : timestamp(0), callSign(""), address(0), addressType(AddressType::RANDOM), dataSource(DataSource::NONE), aircraftType(AircraftCategory::UNKNOWN), stealth(false), noTrack(false), airborne(false), lat(0), lon(0), ellipseHeight(0), verticalSpeed(0), groundSpeed(0), track(0), hTurnRate(0), distanceFromOwn(INT32_MIN), relNorthFromOwn(INT32_MIN), relEastFromOwn(INT32_MIN) // , bearingFromOwn(INT16_MIN) + AircraftPositionInfo() : timestamp(0), callSign(""), address(0), addressType(AddressType::RANDOM), dataSource(DataSource::NONE), aircraftType(AircraftCategory::UNKNOWN), stealth(false), noTrack(false), airborne(false), lat(0), lon(0), ellipseHeight(0), verticalSpeed(0), groundSpeed(0), track(0), hTurnRate(0), distanceFromOwn(UINT32_MAX), relNorthFromOwn(INT32_MIN), relEastFromOwn(INT32_MIN) // , bearingFromOwn(INT16_MIN) { } @@ -377,7 +377,7 @@ namespace GATAS AircraftAddress icaoAddress = 0; float lat = 0; float lon = 0; - int16_t ellipseHeight = 0; + int32_t ellipseHeight = 0; }; struct OwnshipPositionInfo @@ -385,7 +385,7 @@ namespace GATAS uint32_t timestamp; // Timestamp when the position was received float lat; float lon; - int16_t ellipseHeight; // Height above the Ellipsoid (WGS84) in meters. For aircraft where altitude is based from BARO, this is an estimate + int32_t ellipseHeight; // Height above the Ellipsoid (WGS84) in meters. For aircraft where altitude is based from BARO, this is an estimate float verticalSpeed; // in m/s float groundSpeed; // in m/s float track; // 0..359 @@ -395,9 +395,9 @@ namespace GATAS int16_t geoidSeparation; // The distance from the surface of an ellipsoid to the surface of the geoid. bool airborne; // Is the aircraft airborne, can this be taken from GS? It can be rare under normal situations that GS is low, even though we are flying (large headwind??) Config::Conspicuity conspicuity; // Configuration for this aircraft, used to send out the correct data - int16_t heightMsl() const + int32_t heightMsl() const { - return ellipseHeight - geoidSeparation; + return ellipseHeight - static_cast(geoidSeparation); } const OwnshipMinimalPositionInfo assignTo() const diff --git a/src/lib/core/ace/spinlockguard.hpp b/src/lib/core/ace/spinlockguard.hpp index be11fc43..ffdd56cb 100644 --- a/src/lib/core/ace/spinlockguard.hpp +++ b/src/lib/core/ace/spinlockguard.hpp @@ -29,7 +29,7 @@ class SpinlockGuard */ static spin_lock_t *claim(bool required = true) { - return spin_lock_instance(spin_lock_claim_unused(required)); + return spin_lock_instance((uint)spin_lock_claim_unused(required)); } SpinlockGuard(const SpinlockGuard &) = delete; diff --git a/src/lib/core/ace/src/basemodule.cpp b/src/lib/core/ace/src/basemodule.cpp index 70df20ad..049b366a 100644 --- a/src/lib/core/ace/src/basemodule.cpp +++ b/src/lib/core/ace/src/basemodule.cpp @@ -92,12 +92,14 @@ BaseModule *BaseModule::moduleByName(const BaseModule &that, const etl::string_v void __isr __time_critical_func(BaseModule::gpioInterrupt)(uint pin, uint32_t event) { + const uint8_t pinKey = static_cast(pin); + // Handle the interrupt and call back over callback or task notification // Cannot wrap this in a baseMutex since when there is an interrupt we get an assert on suspend // This is in reality only an issue when modules are added/removed which is not expected during normal operation - if (pinInterruptHandlers.contains(pin) && pinInterruptHandlers[pin].enabled) + if (pinInterruptHandlers.contains(pinKey) && pinInterruptHandlers[pinKey].enabled) { - pinInterruptHandler &iHandler = pinInterruptHandlers[pin]; + pinInterruptHandler &iHandler = pinInterruptHandlers[pinKey]; if ((iHandler.event & event) == iHandler.event) { if (iHandler.callback.is_valid()) diff --git a/src/lib/core/ace/src/coreutils.cpp b/src/lib/core/ace/src/coreutils.cpp index d526498b..4d437fbc 100644 --- a/src/lib/core/ace/src/coreutils.cpp +++ b/src/lib/core/ace/src/coreutils.cpp @@ -40,7 +40,7 @@ uint32_t CoreUtils::getTotalHeap(void) return 0; #else extern char __StackLimit, __bss_end__; - return &__StackLimit - &__bss_end__; + return static_cast(&__StackLimit - &__bss_end__); #endif } @@ -61,14 +61,14 @@ int8_t CoreUtils::egmGeoidOffset(float lat, float lon) // Convert directly to index space constexpr float invRes = 1.0f / egm2008_resolution_deg; - const int lat_idx = static_cast((egm2008_max_lat - lat) * invRes + 0.5f); - const int lon_idx = static_cast((lon - egm2008_min_lon) * invRes + 0.5f); + const int32_t lat_idx = static_cast((egm2008_max_lat - lat) * invRes + 0.5f); + const int32_t lon_idx = static_cast((lon - egm2008_min_lon) * invRes + 0.5f); // Single bounds check (fast path) - if ((unsigned)lat_idx >= egm2008_lat_steps || (unsigned)lon_idx >= egm2008_lon_steps) + if ((uint32_t)lat_idx >= egm2008_lat_steps || (uint32_t)lon_idx >= egm2008_lon_steps) { return 0; } - return egm2008s_dem[lon_idx][lat_idx]; + return egm2008s_dem[static_cast(lon_idx)][static_cast(lat_idx)]; } diff --git a/src/lib/fanetace/ace/fanetace.hpp b/src/lib/fanetace/ace/fanetace.hpp index 95a1a8fc..65a8cbd7 100644 --- a/src/lib/fanetace/ace/fanetace.hpp +++ b/src/lib/fanetace/ace/fanetace.hpp @@ -19,8 +19,8 @@ class FanetAce : public BaseModule, public FANET::Connector, public etl::message private: friend class message_router; - static constexpr int DEFAULT_IGNORE_DISTANCE = 25000; - static constexpr int MAX_IGNORE_DISTANCE = 100000; + static constexpr uint32_t DEFAULT_IGNORE_DISTANCE = 25000; + static constexpr uint32_t MAX_IGNORE_DISTANCE = 100000; enum TaskState : uint32_t { @@ -71,8 +71,8 @@ class FanetAce : public BaseModule, public FANET::Connector, public etl::message FanetAce(etl::imessage_bus &bus, const Configuration &config) : BaseModule(bus, NAME), protocol(this), distanceIgnore(DEFAULT_IGNORE_DISTANCE), ownshipPosition{}, gaTasConfiguration(config.gaTasConfig()) { protocol.ownAddress(FANET::Address{gaTasConfiguration.conspicuity.icaoAddress}); - auto di = config.valueByPath(DEFAULT_IGNORE_DISTANCE, "Fanet", "distanceIgnore"); - distanceIgnore = etl::max(0, etl::min(di, MAX_IGNORE_DISTANCE)); + auto di = static_cast(config.valueByPath(DEFAULT_IGNORE_DISTANCE, "Fanet", "distanceIgnore")); + distanceIgnore = etl::max(static_cast(0), etl::min(di, MAX_IGNORE_DISTANCE)); } virtual ~FanetAce() = default; diff --git a/src/lib/fanetace/ace/src/fanetace.cpp b/src/lib/fanetace/ace/src/fanetace.cpp index f63a0638..deb4e382 100644 --- a/src/lib/fanetace/ace/src/fanetace.cpp +++ b/src/lib/fanetace/ace/src/fanetace.cpp @@ -78,7 +78,7 @@ void FanetAce::on_receive(const GATAS::RadioTxPositionRequestMsg &msg) FANET::TrackingPayload payload; payload.latitude(ownship.lat) .longitude(ownship.lon) - .altitude(ownship.heightMsl()) + .altitude(static_cast(ownship.heightMsl())) .speed(ownship.groundSpeed * MS_TO_KPH) .groundTrack(ownship.track) .climbRate(ownship.verticalSpeed) diff --git a/src/lib/flarmgatas/ace/flarm2024.hpp b/src/lib/flarmgatas/ace/flarm2024.hpp index e20dd6c2..8e7df461 100644 --- a/src/lib/flarmgatas/ace/flarm2024.hpp +++ b/src/lib/flarmgatas/ace/flarm2024.hpp @@ -48,7 +48,7 @@ class Flarm2024 : public BaseModule, public etl::message_router(etl::max(0, etl::min(di, MAX_IGNORE_DISTANCE))); gaTasConfiguration = config.gaTasConfig(); } diff --git a/src/lib/flarmgatas/ace/src/flarm2024.cpp b/src/lib/flarmgatas/ace/src/flarm2024.cpp index 1cc247c9..bba504a6 100644 --- a/src/lib/flarmgatas/ace/src/flarm2024.cpp +++ b/src/lib/flarmgatas/ace/src/flarm2024.cpp @@ -123,7 +123,7 @@ void Flarm2024::on_receive(const GATAS::RadioTxPositionRequestMsg &msg) packet.noTrack(ownship.conspicuity.noTrack); packet.epochSeconds(epochSeconds); packet.aircraftType(fromAircraftCategory(ownship.conspicuity.category)); - packet.altitude(ownship.ellipseHeight); + packet.altitude(static_cast(ownship.ellipseHeight)); packet.setPosition(ownship.lat, ownship.lon); packet.turnRate(ownship.hTurnRate); packet.groundSpeed(ownship.groundSpeed); diff --git a/src/lib/gatas_module.cmake b/src/lib/gatas_module.cmake index 5edae5d4..0a597cc1 100644 --- a/src/lib/gatas_module.cmake +++ b/src/lib/gatas_module.cmake @@ -45,7 +45,7 @@ function(gatas_add_module) if(MODULE_CXX_SOURCES) set_source_files_properties(${MODULE_CXX_SOURCES} PROPERTIES - COMPILE_FLAGS "-Wall -Wextra -Werror -Wvexing-parse" + COMPILE_FLAGS "-Wall -Wextra -Werror -Wvexing-parse -Wconversion -Wsign-conversion -Werror=conversion -Werror=sign-conversion" ) endif() diff --git a/src/lib/gatasconnect/ace/src/gatasconnectudp.cpp b/src/lib/gatasconnect/ace/src/gatasconnectudp.cpp index e2a8beb4..f00e47c7 100644 --- a/src/lib/gatasconnect/ace/src/gatasconnectudp.cpp +++ b/src/lib/gatasconnect/ace/src/gatasconnectudp.cpp @@ -269,7 +269,7 @@ void GatasConnect::requestTimerCallback(TimerHandle_t xTimer) // --- Aircraft configuration (always send) writer.restart(); // > 25 Byte - BinaryMessages::serializeAircraftConfigurationV2(writer, gatasIdSnap, icaoAddressSnap, allIcaoAddressesSnap, gatasIpSnap, pinCodeSnap); + BinaryMessages::serializeAircraftConfigurationV2(writer, static_cast(gatasIdSnap), icaoAddressSnap, allIcaoAddressesSnap, gatasIpSnap, pinCodeSnap); auto size = encodeCOBS(perCobsBuffer.data(), configSize, cobsPayload.data() + position, cobsPayload.size() - position, true); position += size; @@ -292,13 +292,13 @@ void GatasConnect::requestTimerCallback(TimerHandle_t xTimer) } } - struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, position, PBUF_POOL); + struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, static_cast(position), PBUF_POOL); if (!pbuf) { statistics.bufferAllocErr++; return; } - if (pbuf_take(pbuf, cobsPayload.begin(), position) != ERR_OK) + if (pbuf_take(pbuf, cobsPayload.begin(), static_cast(position)) != ERR_OK) { pbuf_free(pbuf); return; diff --git a/src/lib/gdl90service/ace/src/gdl90service.cpp b/src/lib/gdl90service/ace/src/gdl90service.cpp index 03e09e2c..1939928a 100644 --- a/src/lib/gdl90service/ace/src/gdl90service.cpp +++ b/src/lib/gdl90service/ace/src/gdl90service.cpp @@ -183,7 +183,7 @@ void Gdl90Service::on_receive(const GATAS::OwnshipPositionMsg &msg) gdl90.latlon_encode(latitude, pos.lat); gdl90.latlon_encode(longitude, pos.lon); - gdl90.altitude_encode(altitude, pos.heightMsl() * M_TO_FT); + gdl90.altitude_encode(altitude, static_cast(pos.heightMsl()) * M_TO_FT); gdl90.horizontal_velocity_encode(horiz_velocity, pos.groundSpeed * MS_TO_KN); gdl90.vertical_velocity_encode(vert_velocity, pos.verticalSpeed * MS_TO_FTPMIN); gdl90.track_hdg_encode(track_hdg, pos.track); @@ -240,7 +240,7 @@ void Gdl90Service::on_receive(const GATAS::OwnshipPositionMsg &msg) constexpr float vertical_figure_of_merit_f = 10.f * M_TO_FT; uint32_t vertical_figure_of_merit; uint32_t geo_altitude; - bool ok = gdl90.geo_altitude_encode(geo_altitude, pos.ellipseHeight * M_TO_FT); + bool ok = gdl90.geo_altitude_encode(geo_altitude, static_cast(pos.ellipseHeight) * M_TO_FT); ok |= gdl90.vertical_figure_of_merit_encode(vertical_figure_of_merit, vertical_figure_of_merit_f); if (ok && gdl90.ownership_geometric_altitude_encode(unpacked, geo_altitude, vertical_warning, vertical_figure_of_merit)) { @@ -336,7 +336,7 @@ void Gdl90Service::on_receive(const GATAS::EgressAircraftPositionMsg &msg) gdl90.latlon_encode(latitude, pos.lat); gdl90.latlon_encode(longitude, pos.lon); - gdl90.altitude_encode(altitude, (pos.ellipseHeight - ownshipGeoidSeparation) * M_TO_FT); + gdl90.altitude_encode(altitude, static_cast(pos.ellipseHeight - ownshipGeoidSeparation) * M_TO_FT); gdl90.horizontal_velocity_encode(horiz_velocity, pos.groundSpeed * MS_TO_KN); gdl90.vertical_velocity_encode(vert_velocity, pos.verticalSpeed * MS_TO_FTPMIN); gdl90.track_hdg_encode(track_hdg, pos.track); diff --git a/src/lib/gdloverudp/ace/gdloverudp.hpp b/src/lib/gdloverudp/ace/gdloverudp.hpp index 911917d6..b793528b 100644 --- a/src/lib/gdloverudp/ace/gdloverudp.hpp +++ b/src/lib/gdloverudp/ace/gdloverudp.hpp @@ -65,7 +65,7 @@ class GDLoverUDP : public BaseModule, public etl::message_router data); + void sendTo(uint32_t ip, uint16_t port, etl::span data); public: static constexpr const etl::string_view NAME = "GDLoverUDP"; diff --git a/src/lib/gdloverudp/ace/src/gdloverudp.cpp b/src/lib/gdloverudp/ace/src/gdloverudp.cpp index e0af8dcb..9a4d025e 100644 --- a/src/lib/gdloverudp/ace/src/gdloverudp.cpp +++ b/src/lib/gdloverudp/ace/src/gdloverudp.cpp @@ -39,7 +39,7 @@ void GDLoverUDP::getConfigurationNoMutex(const Configuration &config) etl::string_stream stream(path); stream << etl::make_string("defaultPorts/") << i; int32_t p = config.valueByPath(GDL90OVERUDP_DEFAULT_PORT, NAME, path); - udpPorts.insert(p); + udpPorts.insert(static_cast(p)); } } @@ -234,7 +234,7 @@ void GDLoverUDP::transmitBuffer() // Calculate how many pbufs auto [lconnectedClients, ludpPorts] = SpinlockGuard::copyWithLock(CoreUtils::sharedSpinLock(), connectedClients, udpPorts); - uint8_t totalpBufs = lconnectedClients.size() * ludpPorts.size() + gateWayClient ? ludpPorts.size() : 0; + uint8_t totalpBufs = static_cast(static_cast(lconnectedClients.size() * ludpPorts.size()) + static_cast(gateWayClient ? ludpPorts.size() : 0)); for (const auto &client : customClients) { if ((client.ip & 0xFFFFFF) == networkAddress) @@ -291,23 +291,23 @@ void GDLoverUDP::transmitBuffer() } } -void GDLoverUDP::sendTo(uint32_t ip, int16_t port, etl::span data) +void GDLoverUDP::sendTo(uint32_t ip, uint16_t port, etl::span data) { ip_addr_t addr; ip4_addr_set_u32(&addr, ip); - struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, data.size(), PBUF_POOL); + struct pbuf *pbuf = pbuf_alloc(PBUF_TRANSPORT, static_cast(data.size()), PBUF_POOL); if (!pbuf) { return; } - if (pbuf_take(pbuf, data.begin(), data.size()) != ERR_OK) + if (pbuf_take(pbuf, data.begin(), static_cast(data.size())) != ERR_OK) { pbuf_free(pbuf); return; } - err_t err = udp_sendto(sendPcb, pbuf, &addr, port); + err_t err = udp_sendto(sendPcb, pbuf, &addr, static_cast(port)); pbuf_free(pbuf); if (err == ERR_OK) diff --git a/src/lib/gps/ace/AbstractGnss.hpp b/src/lib/gps/ace/AbstractGnss.hpp index 85c408fe..1ac333f5 100644 --- a/src/lib/gps/ace/AbstractGnss.hpp +++ b/src/lib/gps/ace/AbstractGnss.hpp @@ -43,7 +43,7 @@ class AbstractGnss : public BaseModule static void receiveTask(void *arg); PioSerial pioSerial; - const int8_t ppsPin; + const uint8_t ppsPin; bool softwarebasedPPS; int32_t softPPSlagUs; uint32_t measureSoftPPSlag = 0; diff --git a/src/lib/gpsdecoder/ace/gpsdecoder.hpp b/src/lib/gpsdecoder/ace/gpsdecoder.hpp index ac1a31cd..777069b5 100644 --- a/src/lib/gpsdecoder/ace/gpsdecoder.hpp +++ b/src/lib/gpsdecoder/ace/gpsdecoder.hpp @@ -88,7 +88,7 @@ class GpsDecoder : public BaseModule, public etl::message_router((static_cast(statistics.receivedRMC) / static_cast(CoreUtils::timeS32() - taskStartTime)) + 0.5f); } float getFloat(const minmea_float &f, float defaultValue) diff --git a/src/lib/gpsdecoder/ace/src/gpsdecoder.cpp b/src/lib/gpsdecoder/ace/src/gpsdecoder.cpp index c5cab040..28ba98fd 100644 --- a/src/lib/gpsdecoder/ace/src/gpsdecoder.cpp +++ b/src/lib/gpsdecoder/ace/src/gpsdecoder.cpp @@ -96,16 +96,16 @@ void GpsDecoder::on_receive(const GATAS::GPSSentenceMsg &msg) switch (type) { case 'P': - satViewStats.gps = frame.total_sats; + satViewStats.gps = static_cast(frame.total_sats); break; case 'L': - satViewStats.glo = frame.total_sats; + satViewStats.glo = static_cast(frame.total_sats); break; case 'A': - satViewStats.gal = frame.total_sats; + satViewStats.gal = static_cast(frame.total_sats); break; case 'B': - satViewStats.bds = frame.total_sats; + satViewStats.bds = static_cast(frame.total_sats); break; } } @@ -117,7 +117,7 @@ void GpsDecoder::on_receive(const GATAS::GPSSentenceMsg &msg) struct minmea_sentence_rmc frame; if (minmea_parse_rmc(&frame, msg.sentence.c_str())) { - uint16_t millis = frame.time.microseconds / 1000; + uint16_t millis = static_cast(frame.time.microseconds / 1000); #if GATAS_DEBUG == 1 // Print the time difference between the RMC and the local time @@ -205,8 +205,8 @@ void GpsDecoder::on_receive(const GATAS::GPSSentenceMsg &msg) geoidSeparation = convertToMeters(frame.height, frame.height_units, geoidSeparation); // Field 11 (Undulation) altitudeGeoid(geoidAltitude); - satsUsedForFix = frame.satellites_tracked; - fixQuality = frame.fix_quality; + satsUsedForFix = static_cast(frame.satellites_tracked); + fixQuality = static_cast(frame.fix_quality); lastGGATimestamp = frame.time; sendMessageWhenGGAisRMC(); diff --git a/src/lib/idle/ace/idle.hpp b/src/lib/idle/ace/idle.hpp index 46a59cd9..d0c92b1e 100644 --- a/src/lib/idle/ace/idle.hpp +++ b/src/lib/idle/ace/idle.hpp @@ -55,7 +55,7 @@ class Idle : public BaseModule, public etl::message_router(config.valueByPath(26, "port5", "O0")); (void)config; } diff --git a/src/lib/idle/ace/src/idle.cpp b/src/lib/idle/ace/src/idle.cpp index 1b73795f..a74d6491 100644 --- a/src/lib/idle/ace/src/idle.cpp +++ b/src/lib/idle/ace/src/idle.cpp @@ -37,7 +37,11 @@ void Idle::calculatePattern() wifiModePattern = WIFI_NC_PATTERN; } - blinkPattern = hasGpsFix ? wifiModePattern << 16 | wifiModePattern << 8 | wifiModePattern : wifiModePattern; + blinkPattern = hasGpsFix + ? (static_cast(static_cast(wifiModePattern) << 16U) | + static_cast(static_cast(wifiModePattern) << 8U) | + static_cast(wifiModePattern)) + : static_cast(wifiModePattern); } void Idle::on_receive_unknown(const etl::imessage &msg) @@ -66,7 +70,7 @@ bool Idle::blinkCb(repeating_timer_t *t) idle->patternStep = Idle::PATTERN_STEPS; } idle->patternStep--; - gpio_put(idle->ledStatusIndicatorPin, idle->runningPattern & 0b1); + gpio_put(static_cast(idle->ledStatusIndicatorPin), idle->runningPattern & 0b1U); idle->runningPattern >>= 1; return true; @@ -126,12 +130,12 @@ void Idle::idleTask(void *arg) if (msgFlags & DO_300S) { at->getBus().receive(GATAS::Every300SecMsg()); - msgFlags &= ~DO_300S; + msgFlags &= static_cast(~DO_300S); } else if (msgFlags & DO_30S) { at->getBus().receive(GATAS::Every30SecMsg()); - msgFlags &= ~DO_30S; + msgFlags &= static_cast(~DO_30S); } else if (msgFlags & DO_15S) { @@ -154,12 +158,12 @@ void Idle::idleTask(void *arg) } #endif at->getBus().receive(GATAS::Every15SecMsg()); - msgFlags &= ~DO_15S; + msgFlags &= static_cast(~DO_15S); } else if (msgFlags & DO_5S) { at->getBus().receive(GATAS::Every5SecMsg()); - msgFlags &= ~DO_5S; + msgFlags &= static_cast(~DO_5S); } else { @@ -168,4 +172,4 @@ void Idle::idleTask(void *arg) vTaskDelay(TASK_DELAY_MS(CoreUtils::msDelayToReference(0))); } -} \ No newline at end of file +} diff --git a/src/lib/mocks/pico/sync.h b/src/lib/mocks/pico/sync.h index 334f1f9c..2ff5e125 100644 --- a/src/lib/mocks/pico/sync.h +++ b/src/lib/mocks/pico/sync.h @@ -1,5 +1,7 @@ #pragma once +#include "../pico.h" + struct spin_lock_t { }; @@ -21,4 +23,4 @@ inline int spin_lock_blocking(spin_lock_t* spinlock) { inline void spin_unlock(spin_lock_t* spinlock, int num) { (void)spinlock; (void)num; -} \ No newline at end of file +} diff --git a/src/lib/ogn/ace/ogn1.hpp b/src/lib/ogn/ace/ogn1.hpp index 053b8e82..d74f3fc6 100644 --- a/src/lib/ogn/ace/ogn1.hpp +++ b/src/lib/ogn/ace/ogn1.hpp @@ -108,7 +108,7 @@ class Ogn1 : public BaseModule, public etl::message_router(etl::max(0, etl::min(di, MAX_IGNORE_DISTANCE))); } virtual ~Ogn1() = default; diff --git a/src/lib/ogn/ace/ognpacket.hpp b/src/lib/ogn/ace/ognpacket.hpp index c1943a05..119a59a6 100644 --- a/src/lib/ogn/ace/ognpacket.hpp +++ b/src/lib/ogn/ace/ognpacket.hpp @@ -212,7 +212,7 @@ class OGN1_Packet // Packet structure for the OGN tracker // Centripetal acceleration static int16_t calcCPaccel(int16_t Speed, int16_t TurnRate) { - return ((int32_t)TurnRate*Speed*229+0x10000)>>17; // [0.1m/s^2] + return static_cast(((static_cast(TurnRate) * Speed * 229) + 0x10000) >> 17); // [0.1m/s^2] } int16_t calcCPaccel(void) { @@ -227,7 +227,7 @@ class OGN1_Packet // Packet structure for the OGN tracker Radius /= TurnRate; Radius = (Radius+128)>>8; if (etl::absolute(Radius)>MaxRadius) return 0; - return Radius; + return static_cast(Radius); } int16_t calcTurnRadius(int16_t MaxRadius=0x7FFF) { @@ -264,7 +264,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeLatitude(int32_t Latitude) // encode Latitude: units are 0.0001/60 degrees { - Position.Latitude = Latitude>>3; + Data[0] = (Data[0] & 0xFF000000U) | (static_cast(Latitude >> 3) & 0x00FFFFFFU); } int32_t DecodeLatitude(void) const @@ -277,7 +277,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeLongitude(int32_t Longitude) // encode Longitude: units are 0.0001/60 degrees { - Position.Longitude = Longitude>>=4; + Data[1] = (Data[1] & 0xFF000000U) | (static_cast(Longitude >> 4) & 0x00FFFFFFU); } int32_t DecodeLongitude(void) const @@ -299,7 +299,7 @@ class OGN1_Packet // Packet structure for the OGN tracker int16_t getBaroAltDiff(void) const { int16_t AltDiff=Position.BaroAltDiff; - if (Position.BaroMSB==0) AltDiff|=0xFF00; + if (Position.BaroMSB==0) AltDiff |= static_cast(0xFF00); return AltDiff; } void setBaroAltDiff(int32_t AltDiff) @@ -325,7 +325,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeAltitude(int32_t Altitude) // encode altitude in meters { if (Altitude<0) Altitude=0; - Position.Altitude = UnsVRencode((uint16_t)Altitude); + Position.Altitude = static_cast(UnsVRencode(static_cast(Altitude)) & 0x3FFFU); } // Position.Altitude = EncodeUR2V12((uint16_t)Altitude); } @@ -337,43 +337,43 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeDOP(uint8_t DOP) { - Position.DOP = UnsVRencode(DOP); + Position.DOP = static_cast(UnsVRencode(DOP) & 0x3FU); } // { Position.DOP = EncodeUR2V4(DOP); } uint8_t DecodeDOP(void) const { - return UnsVRdecode(Position.DOP); + return static_cast(UnsVRdecode(Position.DOP)); } // { return DecodeUR2V4(Position.DOP); } void EncodeSpeed(int16_t Speed) // speed in 0.2 knots (or 0.1m/s) { if (Speed<0) Speed=0; - else Speed = UnsVRencode(Speed); // EncodeUR2V8(Speed); - Position.Speed = Speed; + else Speed = static_cast(UnsVRencode(static_cast(Speed))); // EncodeUR2V8(Speed); + Position.Speed = static_cast(static_cast(Speed) & 0x03FFU); } int16_t DecodeSpeed(void) const // return speed in 0.2 knots or 0.1m/s units { - return UnsVRdecode(Position.Speed); + return static_cast(UnsVRdecode(Position.Speed)); } // { return DecodeUR2V8(Position.Speed); } // => max. speed: 3832*0.2 = 766 knots int16_t DecodeHeading(void) const // return Heading in 0.1 degree units 0..359.9 deg { int32_t Heading = Position.Heading; - return (Heading*3600+512)>>10; + return static_cast((Heading * 3600 + 512) >> 10); } void EncodeHeading(int16_t Heading) { - Position.Heading = (((int32_t)Heading<<10)+180)/3600; + Position.Heading = static_cast(static_cast(((static_cast(Heading) << 10) + 180) / 3600) & 0x03FFU); } void setHeadingAngle(uint16_t HeadingAngle) { - Position.Heading = (((HeadingAngle+32)>>6)); + Position.Heading = static_cast(static_cast((HeadingAngle + 32) >> 6) & 0x03FFU); } uint16_t getHeadingAngle(void) const @@ -411,7 +411,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeClimbRate(int16_t Climb) { - Position.ClimbRate = EncodeSR2V6(Climb); + Position.ClimbRate = static_cast(EncodeSR2V6(Climb) & 0x01FFU); } int16_t DecodeClimbRate(void) const @@ -441,7 +441,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeVoltage(uint16_t Voltage) { - Status.Voltage=EncodeUR2V6(Voltage); // [1/64V] + Status.Voltage = static_cast(EncodeUR2V6(Voltage)); // [1/64V] } uint16_t DecodeVoltage(void) const { @@ -462,7 +462,7 @@ class OGN1_Packet // Packet structure for the OGN tracker } uint16_t DecodeHumidity(void) const { - return 520+DecodeSR2V5(Status.Humidity); + return static_cast(520 + DecodeSR2V5(Status.Humidity)); } // -------------------------------------------------------------------------------------------------------------- @@ -490,7 +490,7 @@ class OGN1_Packet // Packet structure for the OGN tracker uint8_t Msk1 = 0xFF; Msk1<<=Ofs; uint8_t Msk2 = 0x01; - Msk2 = (Msk2<((Msk2 << Len2) - 1); Info.Data[Idx ] = (Info.Data[Idx ]&(~Msk1)) | (Char<>Len1); } @@ -528,7 +528,7 @@ class OGN1_Packet // Packet structure for the OGN tracker Len += 1; } setInfoChar(InfoType, Idx); // terminating character - Info.DataChars=Idx; // update number of characters + Info.DataChars = static_cast(Idx & 0x0FU); // update number of characters return Len+1; } // return number of added Value characters diff --git a/src/lib/ogn/ace/src/ogn1.cpp b/src/lib/ogn/ace/src/ogn1.cpp index ea71bb6d..261305b5 100644 --- a/src/lib/ogn/ace/src/ogn1.cpp +++ b/src/lib/ogn/ace/src/ogn1.cpp @@ -80,7 +80,7 @@ uint8_t Ogn1::errorCorrect(uint8_t *output, uint8_t *data, uint8_t *err, uint8_t Ogn1::decoder.Input(data, err); // put data into the FEC decoder do // more loops is more chance to recover the packet { - check = decoder.ProcessChecks(); // do an iteration + check = static_cast(decoder.ProcessChecks()); // do an iteration } while ((iter--) && check); // if FEC all fine: break Ogn1::decoder.Output(output); // get corrected bytes into the OGN packet errCount += ErrCount(output, data, err, OGN_PACKET_LENGTH); @@ -133,8 +133,8 @@ int8_t Ogn1::parseFrame(OGN1_Packet &packet, int16_t rssiDbm) } statistics.relay[packet.Header.Relay % 4] += 1; - float fLatitude = POSITION_DECODE * packet.DecodeLatitude(); - float fLongitude = POSITION_DECODE * packet.DecodeLongitude(); + float fLatitude = POSITION_DECODE * static_cast(packet.DecodeLatitude()); + float fLongitude = POSITION_DECODE * static_cast(packet.DecodeLongitude()); auto ownship = SpinlockGuard::copyWithLock(CoreUtils::sharedSpinLock(), ownshipPosition); @@ -189,8 +189,8 @@ void Ogn1::on_receive(const GATAS::RadioTxPositionRequestMsg &msg) OGN1_Packet packet; packet.Header = { - .Address = ownship.conspicuity.icaoAddress, // Address - .AddrType = addressTypeToOgn(ownship.conspicuity.addressType), + .Address = static_cast(ownship.conspicuity.icaoAddress) & 0x00FFFFFFU, // Address + .AddrType = static_cast(addressTypeToOgn(ownship.conspicuity.addressType)) & 0x03U, .NonPos = 0, // 0 = position packet, 1 = other information like status .Parity = 0, // parity takes into account bits 0..27 thus only the 28 lowest bits .Relay = 0, // 0 = direct packet, 1 = relayed once, 2 = relayed twice, ... @@ -200,14 +200,14 @@ void Ogn1::on_receive(const GATAS::RadioTxPositionRequestMsg &msg) packet.calcAddrParity(); - packet.EncodeLatitude(ownship.lat * POSITION_ENDECODE); - packet.EncodeLongitude(ownship.lon * POSITION_ENDECODE); - packet.EncodeSpeed(ownship.groundSpeed * 10.f); - packet.EncodeHeading(ownship.track * 10.f); - packet.EncodeClimbRate(ownship.verticalSpeed * 10.f); - packet.EncodeTurnRate(ownship.hTurnRate * 10.f); + packet.EncodeLatitude(static_cast(ownship.lat * POSITION_ENDECODE)); + packet.EncodeLongitude(static_cast(ownship.lon * POSITION_ENDECODE)); + packet.EncodeSpeed(static_cast(ownship.groundSpeed * 10.f)); + packet.EncodeHeading(static_cast(ownship.track * 10.f)); + packet.EncodeClimbRate(static_cast(ownship.verticalSpeed * 10.f)); + packet.EncodeTurnRate(static_cast(ownship.hTurnRate * 10.f)); packet.EncodeAltitude(ownship.heightMsl()); - packet.EncodeDOP(gpsStats.pDop + 0.5f); + packet.EncodeDOP(static_cast(gpsStats.pDop + 0.5f)); // TODO: Understand how baro Altitude really works in OGN packet.clrBaro(); @@ -222,7 +222,7 @@ void Ogn1::on_receive(const GATAS::RadioTxPositionRequestMsg &msg) auto msSinceEpoch = CoreUtils::msSinceEpoch(); tm time = CoreUtils::localTime(msSinceEpoch); - uint8_t secondTime = time.tm_sec; + uint8_t secondTime = static_cast(time.tm_sec); // Round time to nearest full second if (CoreUtils::msInSecond() >= 500) { @@ -253,10 +253,10 @@ void Ogn1::on_receive(const GATAS::RadioTxPositionRequestMsg &msg) break; } - packet.Position.Time = secondTime; - packet.Position.FixQuality = fixQuality; - packet.Position.FixMode = fixMode; - packet.Position.AcftType = gatasToOgn(ownship.conspicuity.category); + packet.Position.Time = static_cast(secondTime & 0x3FU); + packet.Position.FixQuality = static_cast(fixQuality & 0x03U); + packet.Position.FixMode = static_cast(fixMode & 0x01U); + packet.Position.AcftType = static_cast(gatasToOgn(ownship.conspicuity.category)) & 0x0FU; packet.Whiten(); LDPC_Encode(packet.Word()); diff --git a/src/lib/pioserial/ace/pioserial.hpp b/src/lib/pioserial/ace/pioserial.hpp index d6fca4ee..a9a608e9 100644 --- a/src/lib/pioserial/ace/pioserial.hpp +++ b/src/lib/pioserial/ace/pioserial.hpp @@ -26,7 +26,7 @@ class PioSerial using CallBackFunction = etl::delegate&)>; private: - static constexpr etl::array commonBaudrates{ 115200, 9600, 19200, 38400, 57600 }; + static constexpr etl::array commonBaudrates{ 115200U, 9600U, 19200U, 38400U, 57600U }; static void pio0_irq0_func_handler() @@ -55,8 +55,8 @@ class PioSerial uint8_t handlerIdx=0; - const int8_t rxPin; - const int8_t txPin; + const uint8_t rxPin; + const uint8_t txPin; const uint32_t baudrate; PIO rxPio; @@ -80,11 +80,11 @@ class PioSerial txPin(CoreUtils::pinValue(pins, GATAS::PinType::TX)), baudrate(baudrate_), rxPio(nullptr), - rxSmIndx(-1), + rxSmIndx(0), rxOffset(0), charIndex(0), txPio(nullptr), - txSmIndx(-1), + txSmIndx(0), txOffset(0), handler(nullptr), callback(callback_) diff --git a/src/lib/pioserial/ace/src/pioserial.cpp b/src/lib/pioserial/ace/src/pioserial.cpp index fde24fc0..551f2d56 100644 --- a/src/lib/pioserial/ace/src/pioserial.cpp +++ b/src/lib/pioserial/ace/src/pioserial.cpp @@ -11,7 +11,7 @@ etl::array PioSerial::interruptHandlers; GATAS::PostConstruct PioSerial::postConstruct() { - if (rxPin == -1 || txPin == -1) + if (rxPin == UINT8_MAX || txPin == UINT8_MAX) { return GATAS::PostConstruct::HARDWARE_NOT_CONFIGURED; } @@ -76,7 +76,7 @@ void PioSerial::start() { // Enable interrupt uint8_t pio_irq = (rxPio == pio0) ? PIO0_IRQ_0 : PIO1_IRQ_0; // pio_irq will become 7,8,9,10 - uint8_t irq_index = pio_irq - ((rxPio == pio0) ? PIO0_IRQ_0 : PIO1_IRQ_0); + uint8_t irq_index = static_cast(pio_irq - ((rxPio == pio0) ? PIO0_IRQ_0 : PIO1_IRQ_0)); irq_add_shared_handler(pio_irq, handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY); // Add a shared IRQ handler irq_set_enabled(pio_irq, true); // Enable the IRQ pio_set_irqn_source_enabled(rxPio, irq_index, static_cast(pis_sm0_rx_fifo_not_empty + rxSmIndx), true); // Set pio to tell us when the FIFO is NOT empty @@ -92,7 +92,7 @@ bool PioSerial::enableRx() { return false; } - uart_rx_program_init(rxPio, rxSmIndx, rxOffset, rxPin, baudrate); + uart_rx_program_init(rxPio, static_cast(rxSmIndx), rxOffset, rxPin, baudrate); } return true; } @@ -103,9 +103,9 @@ void PioSerial::disableRx() if (rxPio != nullptr) { // Cleanup Pio - pio_sm_set_enabled(rxPio, rxSmIndx, false); + pio_sm_set_enabled(rxPio, static_cast(rxSmIndx), false); pio_remove_program(rxPio, &uart_rx_program, rxOffset); - pio_sm_unclaim(rxPio, rxSmIndx); + pio_sm_unclaim(rxPio, static_cast(rxSmIndx)); // Remove the handler rxSmIndx = -1; @@ -133,9 +133,9 @@ void __isr __time_critical_func(PioSerial::pio_irq_func)(uint8_t irqHandlerIndex return; } - while (!pio_sm_is_rx_fifo_empty(pioSerial->rxPio, pioSerial->rxSmIndx)) + while (!pio_sm_is_rx_fifo_empty(pioSerial->rxPio, static_cast(pioSerial->rxSmIndx))) { - uint32_t data = pio_sm_get(pioSerial->rxPio, pioSerial->rxSmIndx); + uint32_t data = pio_sm_get(pioSerial->rxPio, static_cast(pioSerial->rxSmIndx)); char *bytePtr = (char *)&data; for (int i = 0; i < 4; i++) { @@ -167,12 +167,12 @@ void __isr __time_critical_func(PioSerial::pio_irq_func)(uint8_t irqHandlerIndex void PioSerial::sendBlocking(const uint8_t *data, uint16_t length) { - uart_tx_program_put(txPio, txSmIndx, data, length); + uart_tx_program_put(txPio, static_cast(txSmIndx), data, length); } void PioSerial::sendBlocking(const etl::string_view &data) { - uart_tx_program_put(txPio, txSmIndx, (uint8_t *)data.cbegin(), data.size()); + uart_tx_program_put(txPio, static_cast(txSmIndx), (uint8_t *)data.cbegin(), data.size()); } bool PioSerial::enableTx(uint32_t givenBaudRate) @@ -185,7 +185,7 @@ bool PioSerial::enableTx(uint32_t givenBaudRate) return false; } } - uart_tx_program_init(txPio, txSmIndx, txOffset, txPin, givenBaudRate); + uart_tx_program_init(txPio, static_cast(txSmIndx), txOffset, txPin, givenBaudRate); return true; } @@ -193,9 +193,9 @@ void PioSerial::disableTx() { if (txPio != nullptr) { - pio_sm_set_enabled(txPio, txSmIndx, false); + pio_sm_set_enabled(txPio, static_cast(txSmIndx), false); pio_remove_program(txPio, &uart_tx_program, txOffset); - pio_sm_unclaim(txPio, txSmIndx); + pio_sm_unclaim(txPio, static_cast(txSmIndx)); txPio = nullptr; txOffset = 0; @@ -207,8 +207,8 @@ bool PioSerial::setBaudRate(uint32_t baudRate) { if (rxPio != nullptr) { - pio_sm_set_enabled(rxPio, rxSmIndx, false); - uart_rx_program_init(rxPio, rxSmIndx, rxOffset, rxPin, baudRate); + pio_sm_set_enabled(rxPio, static_cast(rxSmIndx), false); + uart_rx_program_init(rxPio, static_cast(rxSmIndx), rxOffset, rxPin, baudRate); return true; } return false; @@ -223,7 +223,7 @@ bool PioSerial::testUartAtBaudrate(uint32_t testBaudRate, uint32_t maximumScanTi { setBaudRate(testBaudRate); // printf("Baud: tx:%d rx:%d %ld ", txPin, rxPin, testBaudRate); - uint8_t status = uart_rx_program_test(rxPio, rxSmIndx, 0x0a, 0x80, maximumScanTimeMs, numcharsConsideringValid); + uint8_t status = uart_rx_program_test(rxPio, static_cast(rxSmIndx), 0x0a, 0x80, maximumScanTimeMs, numcharsConsideringValid); // printf(" uart: %d\n", status); setBaudRate(baudrate); return status == 0; @@ -249,5 +249,5 @@ uint32_t PioSerial::findBaudRate(uint32_t maxTimeOutMs) void PioSerial::rxFlush() { - uart_rx_flush(rxPio, rxSmIndx); + uart_rx_flush(rxPio, static_cast(rxSmIndx)); } diff --git a/src/lib/pioserial/ace/uart_rx_f.h b/src/lib/pioserial/ace/uart_rx_f.h index fd877732..61413fbd 100644 --- a/src/lib/pioserial/ace/uart_rx_f.h +++ b/src/lib/pioserial/ace/uart_rx_f.h @@ -17,7 +17,7 @@ static inline void uart_rx_program_init(PIO pio, uint sm, uint offset, uint pin, // Deeper FIFO as we're not doing any TX sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); // SM transmits 1 bit per 8 execution cycles. - float div = (float)clock_get_hz(clk_sys) / (8 * baudRate); + float div = (float)clock_get_hz(clk_sys) / (float)(8 * baudRate); sm_config_set_clkdiv(&c, div); pio_sm_init(pio, sm, offset, &c); diff --git a/src/lib/pioserial/ace/uart_tx.pio b/src/lib/pioserial/ace/uart_tx.pio index 1ffbd673..a589c79c 100644 --- a/src/lib/pioserial/ace/uart_tx.pio +++ b/src/lib/pioserial/ace/uart_tx.pio @@ -44,7 +44,7 @@ static inline void uart_tx_program_init(PIO pio, uint sm, uint offset, uint pin_ sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); // SM transmits 1 bit per 8 execution cycles. - float div = (float)clock_get_hz(clk_sys) / (8 * baud); + float div = (float)clock_get_hz(clk_sys) / static_cast(8U * baud); sm_config_set_clkdiv(&c, div); pio_sm_init(pio, sm, offset, &c); diff --git a/src/lib/radiotuner/ace/countryregulations_v2.hpp b/src/lib/radiotuner/ace/countryregulations_v2.hpp index 7e30c1b0..5d1a00e4 100644 --- a/src/lib/radiotuner/ace/countryregulations_v2.hpp +++ b/src/lib/radiotuner/ace/countryregulations_v2.hpp @@ -352,7 +352,7 @@ class CountryRegulations // ms is in range 0..999 ms = ms % 1000; uint32_t start = t.start % 1000; - uint32_t end = (t.end - ChannelTiming::REDUCE_ENDTIME_MS) % 1000; + uint32_t end = static_cast((t.end - ChannelTiming::REDUCE_ENDTIME_MS) % 1000); if (start < end) { diff --git a/src/lib/radiotuner/ace/src/radiotunerrx_v2.cpp b/src/lib/radiotuner/ace/src/radiotunerrx_v2.cpp index ecf80a08..0d02b57c 100644 --- a/src/lib/radiotuner/ace/src/radiotunerrx_v2.cpp +++ b/src/lib/radiotuner/ace/src/radiotunerrx_v2.cpp @@ -100,7 +100,7 @@ void RadioTunerRx::radioTuneTask(void *arg) } // Position within the repeating cycle - const int32_t cycleMs = loopStartMs % ref.maxTimeMs; + const int32_t cycleMs = static_cast(loopStartMs % ref.maxTimeMs); // Find which entry covers this time size_t foundIdx = 0; @@ -325,7 +325,7 @@ void RadioTunerRx::spreadSecondIndex(RadioProtocolCtx &ctx) } } - const uint16_t N = unique.size(); + const uint16_t N = static_cast(unique.size()); if (N <= 2) { return; // nothing to improve diff --git a/src/lib/radiotuner/ace/src/radiotunertx_v2.cpp b/src/lib/radiotuner/ace/src/radiotunertx_v2.cpp index 393f5902..d2a55243 100644 --- a/src/lib/radiotuner/ace/src/radiotunertx_v2.cpp +++ b/src/lib/radiotuner/ace/src/radiotunertx_v2.cpp @@ -89,7 +89,7 @@ void RadioTunerTx::radioTuneTask() while (true) { uint32_t notifyValue = 0; - xTaskNotifyWait(pdFALSE, ULONG_MAX, ¬ifyValue, TASK_DELAY_MS(nextDelayMs)); + xTaskNotifyWait(pdFALSE, ULONG_MAX, ¬ifyValue, TASK_DELAY_MS(static_cast(nextDelayMs))); if (notifyValue & TaskState::UNBLOCK) { diff --git a/src/lib/sx1262/ace/src/rxdataframequeue.cpp b/src/lib/sx1262/ace/src/rxdataframequeue.cpp index 3c87dafd..850db672 100644 --- a/src/lib/sx1262/ace/src/rxdataframequeue.cpp +++ b/src/lib/sx1262/ace/src/rxdataframequeue.cpp @@ -82,7 +82,7 @@ void RxDataFrameQueue::radioQueueTask(void *arg) rxFrame.config->dataSource(), rxFrame.rssidBm}; - manchesterDecodeInline(msg.frame.get(), msg.error.get(), rxFrame.length); + manchesterDecodeInline(msg.frame.get(), msg.error.get(), static_cast(rxFrame.length)); // Handle multi protocol situations // auto ds = decideDataSource(rxFrame.config->dataSource(), msg.frame32(), rxFrame.length ); @@ -246,7 +246,7 @@ uint8_t RxDataFrameQueue::FindCRCsyndrome(uint32_t Syndr) // quick search for a uint32_t MidSyndr = 0; for (;;) { - uint16_t Mid = (Bot + Top) >> 1; + uint16_t Mid = static_cast((Bot + Top) >> 1); MidSyndr = Syndrome[Mid] >> 8; if (Syndr == MidSyndr) { diff --git a/src/lib/sx1262/ace/src/sx1262.cpp b/src/lib/sx1262/ace/src/sx1262.cpp index 1b7a665a..1a2abb3b 100644 --- a/src/lib/sx1262/ace/src/sx1262.cpp +++ b/src/lib/sx1262/ace/src/sx1262.cpp @@ -138,7 +138,7 @@ void Sx1262::on_receive(const GATAS::ConfigUpdatedMsg &msg) if (msg.moduleName == Sx1262::NAMES[radioNo]) { txEnabled = msg.config.valueByPath(true, Sx1262::NAMES[radioNo], "txEnabled"); - offsetHz = msg.config.valueByPath(true, Sx1262::NAMES[radioNo], "offset"); + offsetHz = static_cast(msg.config.valueByPath(true, Sx1262::NAMES[radioNo], "offset")); } groundStation = msg.config.gaTasConfig().conspicuity.groundStation; } @@ -279,7 +279,7 @@ void Sx1262::configureSx1262(const GATAS::RadioParameters &newParameters, uint8_ // TX Config syncLengthBits = newParameters.config->syncLength; syncData = newParameters.config->syncWord.data(); - pkt_params_gfsk.pld_len_in_bytes = payloadLength * (newParameters.config->manchester ? 2 : 1); + pkt_params_gfsk.pld_len_in_bytes = static_cast(payloadLength * (newParameters.config->manchester ? 2 : 1)); // Variable payload test (0 is true) if (newParameters.config->packetLength == 0) // When newParameters.config->packetLength == 0, this means variable payload @@ -302,7 +302,7 @@ void Sx1262::configureSx1262(const GATAS::RadioParameters &newParameters, uint8_ } else { - pkt_params_gfsk.pld_len_in_bytes = newParameters.config->packetLength * (newParameters.config->manchester ? 2 : 1); + pkt_params_gfsk.pld_len_in_bytes = static_cast(newParameters.config->packetLength * (newParameters.config->manchester ? 2 : 1)); } } @@ -310,7 +310,7 @@ void Sx1262::configureSx1262(const GATAS::RadioParameters &newParameters, uint8_ pkt_params_gfsk.preamble_len_in_bits = newParameters.config->txPreambleLength; // In addition to this length, there is also 16 bit preamble specific for nRF905 added to the syncword. This will works fine for an SX1262 pkt_params_gfsk.sync_word_len_in_bits = syncLengthBits; sx126x_set_gfsk_pkt_params(this, &pkt_params_gfsk); - sx126x_set_gfsk_sync_word(this, syncData, (syncLengthBits + 7) / 8); + sx126x_set_gfsk_sync_word(this, syncData, static_cast((syncLengthBits + 7) / 8)); } else if (newParameters.frequency->mode == GATAS::Modulation::LORA) { @@ -612,18 +612,18 @@ void Sx1262::sendPacket(const TxPacket &txPacket) return; } uint8_t manchesterFrame[GATAS::RADIO_MAX_TX_GFSK_FRAME_LENGTH * MANCHESTER]; - manchesterEncode(manchesterFrame, txPacket.frame, txPacket.length); - sendGFSKPacket(txPacket.radioParameters, manchesterFrame, txPacket.length * MANCHESTER); + manchesterEncode(manchesterFrame, txPacket.frame, static_cast(txPacket.length)); + sendGFSKPacket(txPacket.radioParameters, manchesterFrame, static_cast(txPacket.length * MANCHESTER)); } else { - sendGFSKPacket(txPacket.radioParameters, txPacket.frame, txPacket.length); + sendGFSKPacket(txPacket.radioParameters, txPacket.frame, static_cast(txPacket.length)); } } else if (txPacket.radioParameters.frequency->mode == GATAS::Modulation::LORA) { GATAS_MEASURE("sendLORAPacket", 100); - sendLORAPacket(txPacket.radioParameters, txPacket.frame, txPacket.length); + sendLORAPacket(txPacket.radioParameters, txPacket.frame, static_cast(txPacket.length)); } } @@ -709,7 +709,7 @@ void Sx1262::sx1262Task(void *arg) GATAS_MEASURE("Send Radio:", 1500, radioNo); // GATAS_INFO("%8ld TX Packet ds:%s", CoreUtils::timeUs32Raw() / 1000, GATAS::toString(txPacket.radioParameters.config->dataSource())); keepTransmittingUntill = CoreUtils::timeUs32Raw() + 55000; // 55ms is longest packet expect (LORA) - configureSx1262(txPacket.radioParameters, txPacket.length); + configureSx1262(txPacket.radioParameters, static_cast(txPacket.length)); sendPacket(txPacket); continue; // Need to wait for TX done } diff --git a/src/lib/sx1262/ace/sx1262.hpp b/src/lib/sx1262/ace/sx1262.hpp index 5d08fe82..a0934c0b 100644 --- a/src/lib/sx1262/ace/sx1262.hpp +++ b/src/lib/sx1262/ace/sx1262.hpp @@ -186,7 +186,7 @@ class Sx1262 : public Radio, public etl::message_router(config.valueByPath(true, NAMES[radioNo_], "offset"))) { } diff --git a/src/lib/utils/ace/bitutils.hpp b/src/lib/utils/ace/bitutils.hpp index bcf8eb0a..a0fa8a45 100644 --- a/src/lib/utils/ace/bitutils.hpp +++ b/src/lib/utils/ace/bitutils.hpp @@ -7,27 +7,27 @@ // http://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer inline uint8_t Count1s(uint8_t Byte) { - return __builtin_popcount(Byte); + return (uint8_t)__builtin_popcount(Byte); } inline uint8_t Count1s(uint16_t Word) { - return __builtin_popcount(Word); + return (uint8_t)__builtin_popcount(Word); } inline uint8_t Count1s(uint32_t LongWord) { - return __builtin_popcountl(LongWord); + return (uint8_t)__builtin_popcountl(LongWord); } inline uint8_t Count1s(int32_t LongWord) { - return __builtin_popcountl(LongWord); + return (uint8_t)__builtin_popcountl((uint32_t)LongWord); } inline uint8_t Count1s(uint64_t LongWord) { - return __builtin_popcountll(LongWord); + return (uint8_t)__builtin_popcountll(LongWord); } inline uint8_t Count1s(int64_t LongWord) diff --git a/src/lib/utils/ace/ldpc.hpp b/src/lib/utils/ace/ldpc.hpp index b4bd22ad..2a91a423 100644 --- a/src/lib/utils/ace/ldpc.hpp +++ b/src/lib/utils/ace/ldpc.hpp @@ -205,7 +205,7 @@ class LDPC_Decoder { OutBit[Bit] = InpBit[Bit] + (ExtBit[Bit]>>1); } - return Count; + return static_cast(Count); } int16_t ProcessCheck(uint8_t Row) @@ -242,7 +242,7 @@ class LDPC_Decoder uint8_t BitIdx=CheckIndex[Bit]; int16_t Ampl = Bit==MinBit ? MinAmpl2 : MinAmpl; if(CheckFails) Ampl=(-Ampl); - ExtBit[BitIdx] += (Word&Mask) ? Ampl:-Ampl; + ExtBit[BitIdx] = static_cast(ExtBit[BitIdx] + ((Word & Mask) ? Ampl : -Ampl)); Mask<<=1; } return CheckFails?-MinAmpl:MinAmpl; diff --git a/src/lib/utils/ace/ognconv.hpp b/src/lib/utils/ace/ognconv.hpp index 3ccfe2f6..71c87ce0 100644 --- a/src/lib/utils/ace/ognconv.hpp +++ b/src/lib/utils/ace/ognconv.hpp @@ -30,47 +30,47 @@ uint8_t DecodeUR2V4(uint8_t DOP); template Type UnsVRdecode(Type Value) { - const Type Thres = 1<>Bits; - Value &= Thres-1; - if(Range==0) return Value; - if(Range==1) return Thres+1+(Value<<1); - if(Range==2) return 3*Thres+2+(Value<<2); - return 7*Thres+4+(Value<<3); + const Type Thres = static_cast(1 << Bits); + uint8_t Range = static_cast(Value >> Bits); + Value &= static_cast(Thres - 1); + if(Range==0) return Value; + if(Range==1) return static_cast(Thres + 1 + (Value << 1)); + if(Range==2) return static_cast(3 * Thres + 2 + (Value << 2)); + return static_cast(7 * Thres + 4 + (Value << 3)); } template Type UnsVRencode(Type Value) { - const Type Thres = 1<>1); - if(Value< 7*Thres) return 2*Thres | ((Value-3*Thres)>>2); - if(Value<15*Thres) return 3*Thres | ((Value-7*Thres)>>3); - return 4*Thres-1; + const Type Thres = static_cast(1 << Bits); + if(Value< Thres) return Value; + if(Value< 3*Thres) return static_cast(Thres | ((Value - Thres) >> 1)); + if(Value< 7*Thres) return static_cast(2 * Thres | ((Value - 3 * Thres) >> 2)); + if(Value<15*Thres) return static_cast(3 * Thres | ((Value - 7 * Thres) >> 3)); + return static_cast(4 * Thres - 1); } template Type SignVRencode(Type Value) { - const Type SignMask = 1<<(Bits+2); + const Type SignMask = static_cast(1 << (Bits + 2)); Type Sign=0; if(Value<0) { - Value=(-Value); + Value = static_cast(-Value); Sign=SignMask; } Value = UnsVRencode(Value); - return Value | Sign; + return static_cast(Value | Sign); } template Type SignVRdecode(Type Value) { - const Type SignMask = 1<<(Bits+2); - Type Sign = Value&SignMask; - Value = UnsVRdecode(Value&(SignMask-1)); - return Sign ? -Value: Value; + const Type SignMask = static_cast(1 << (Bits + 2)); + Type Sign = static_cast(Value & SignMask); + Value = UnsVRdecode(static_cast(Value & static_cast(SignMask - 1))); + return Sign ? static_cast(-Value) : Value; } uint8_t EncodeGray(uint8_t Binary); diff --git a/src/lib/utils/ace/src/cobs.cpp b/src/lib/utils/ace/src/cobs.cpp index b687e608..4fb3aa22 100644 --- a/src/lib/utils/ace/src/cobs.cpp +++ b/src/lib/utils/ace/src/cobs.cpp @@ -229,7 +229,7 @@ size_t decodeCOBS(const uint8_t *inptr, size_t inputlen, uint8_t *outptr, size_t // make sure we do not try to read after specified end of input buffer if (inptr + code > end) { - code = end - inptr; + code = static_cast(end - inptr); } inptr += 1; // copy (code-1) elements from inptr to outptr diff --git a/src/lib/utils/ace/src/moreutils.cpp b/src/lib/utils/ace/src/moreutils.cpp index 5b995519..9ee6ca9c 100644 --- a/src/lib/utils/ace/src/moreutils.cpp +++ b/src/lib/utils/ace/src/moreutils.cpp @@ -8,7 +8,7 @@ uint32_t parseIpv4String(const etl::string_view ipStr, uint32_t defaultValue) Token token; while ((token = etl::get_token(ipStr, ".", token, true))) { - uint32_t value = atoi(token.value().cbegin()); + uint32_t value = static_cast(atoi(token.value().cbegin())); if (value > 255) { return defaultValue; diff --git a/src/lib/utils/ace/src/ognconv.cpp b/src/lib/utils/ace/src/ognconv.cpp index 6a1fd2bc..3ebed1ad 100644 --- a/src/lib/utils/ace/src/ognconv.cpp +++ b/src/lib/utils/ace/src/ognconv.cpp @@ -8,9 +8,9 @@ uint16_t EncodeUR2V8(uint16_t Value) // Encode unsigned 12bit (0..3832) as 10bit { if(Value<0x100) { } - else if(Value<0x300) Value = 0x100 | ((Value-0x100)>>1); - else if(Value<0x700) Value = 0x200 | ((Value-0x300)>>2); - else if(Value<0xF00) Value = 0x300 | ((Value-0x700)>>3); + else if(Value<0x300) Value = 0x100 | (uint16_t)((Value-0x100)>>1); + else if(Value<0x700) Value = 0x200 | (uint16_t)((Value-0x300)>>2); + else if(Value<0xF00) Value = 0x300 | (uint16_t)((Value-0x700)>>3); else Value = 0x3FF; return Value; } @@ -20,20 +20,20 @@ uint16_t DecodeUR2V8(uint16_t Value) // Decode 1 uint16_t Range = Value>>8; Value &= 0x0FF; if(Range==0) return Value; // 000..0FF - if(Range==1) return 0x101+(Value<<1); // 100..2FE - if(Range==2) return 0x302+(Value<<2); // 300..6FC - return 0x704+(Value<<3); + if(Range==1) return 0x101+(uint16_t)(Value<<1); // 100..2FE + if(Range==2) return 0x302+(uint16_t)(Value<<2); // 300..6FC + return 0x704+(uint16_t)(Value<<3); } // 700..EF8 // in 12bit (0..3832) uint8_t EncodeUR2V5(uint16_t Value) // Encode unsigned 9bit (0..472) as 7bit { if(Value<0x020) { } - else if(Value<0x060) Value = 0x020 | ((Value-0x020)>>1); - else if(Value<0x0E0) Value = 0x040 | ((Value-0x060)>>2); - else if(Value<0x1E0) Value = 0x060 | ((Value-0x0E0)>>3); + else if(Value<0x060) Value = 0x020 | (uint16_t)((Value-0x020)>>1); + else if(Value<0x0E0) Value = 0x040 | (uint16_t)((Value-0x060)>>2); + else if(Value<0x1E0) Value = 0x060 | (uint16_t)((Value-0x0E0)>>3); else Value = 0x07F; - return Value; + return (uint8_t)Value; } uint16_t DecodeUR2V5(uint16_t Value) // Decode 7bit as unsigned 9bit (0..472) @@ -43,15 +43,15 @@ uint16_t DecodeUR2V5(uint16_t Value) // Decode 7 if(Range==0) { } // 000..01F else if(Range==1) { - Value = 0x021+(Value<<1); // 020..05E + Value = 0x021+(uint16_t)(Value<<1); // 020..05E } else if(Range==2) { - Value = 0x062+(Value<<2); // 060..0DC + Value = 0x062+(uint16_t)(Value<<2); // 060..0DC } else { - Value = 0x0E4+(Value<<3); // 0E0..1D8 => max. Value = 472 + Value = 0x0E4+(uint16_t)(Value<<3); // 0E0..1D8 => max. Value = 472 } return Value; } @@ -64,23 +64,23 @@ uint8_t EncodeSR2V5(int16_t Value) // Encode si Value=(-Value); Sign=0x80; } - Value = EncodeUR2V5(Value); - return Value | Sign; + Value = EncodeUR2V5((uint16_t)Value); + return (uint8_t)Value | Sign; } int16_t DecodeSR2V5( int16_t Value) // Decode { int16_t Sign = Value&0x80; - Value = DecodeUR2V5(Value&0x7F); + Value = static_cast(DecodeUR2V5(static_cast(Value & 0x7F))); return Sign ? -Value: Value; } uint16_t EncodeUR2V6(uint16_t Value) // Encode unsigned 10bit (0..952) as 8 bit { if(Value<0x040) { } - else if(Value<0x0C0) Value = 0x040 | ((Value-0x040)>>1); - else if(Value<0x1C0) Value = 0x080 | ((Value-0x0C0)>>2); - else if(Value<0x3C0) Value = 0x0C0 | ((Value-0x1C0)>>3); + else if(Value<0x0C0) Value = 0x040 | (uint16_t)((Value-0x040)>>1); + else if(Value<0x1C0) Value = 0x080 | (uint16_t)((Value-0x0C0)>>2); + else if(Value<0x3C0) Value = 0x0C0 | (uint16_t)((Value-0x1C0)>>3); else Value = 0x0FF; return Value; } @@ -92,15 +92,15 @@ uint16_t DecodeUR2V6(uint16_t Value) // Decode 8b if(Range==0) { } // 000..03F else if(Range==1) { - Value = 0x041+(Value<<1); // 040..0BE + Value = 0x041+(uint16_t)(Value<<1); // 040..0BE } else if(Range==2) { - Value = 0x0C2+(Value<<2); // 0C0..1BC + Value = 0x0C2+(uint16_t)(Value<<2); // 0C0..1BC } else { - Value = 0x1C4+(Value<<3); // 1C0..3B8 => max. Value = 952 + Value = 0x1C4+(uint16_t)(Value<<3); // 1C0..3B8 => max. Value = 952 } return Value; } @@ -113,23 +113,22 @@ uint16_t EncodeSR2V6(int16_t Value) // Encode si Value=(-Value); Sign=0x100; } - Value = EncodeUR2V6(Value); - return Value | Sign; + return EncodeUR2V6((uint16_t)Value) | Sign; } int16_t DecodeSR2V6( int16_t Value) // Decode 9bit as signed 11bit (-952..+952) { int16_t Sign = Value&0x100; - Value = DecodeUR2V6(Value&0x00FF); + Value = (int16_t)DecodeUR2V6(Value&0x00FF); return Sign ? -Value: Value; } uint8_t EncodeUR2V4(uint8_t DOP) { if(DOP<0x10) { } - else if(DOP<0x30) DOP = 0x10 | ((DOP-0x10)>>1); - else if(DOP<0x70) DOP = 0x20 | ((DOP-0x30)>>2); - else if(DOP<0xF0) DOP = 0x30 | ((DOP-0x70)>>3); + else if(DOP<0x30) DOP = 0x10 | (uint8_t)((DOP-0x10)>>1); + else if(DOP<0x70) DOP = 0x20 | (uint8_t)((DOP-0x30)>>2); + else if(DOP<0xF0) DOP = 0x30 | (uint8_t)((DOP-0x70)>>3); else DOP = 0x3F; return DOP; } @@ -139,17 +138,17 @@ uint8_t DecodeUR2V4(uint8_t DOP) uint8_t Range = DOP>>4; DOP &= 0x0F; if(Range==0) return DOP; // 00..0F - if(Range==1) return 0x11+(DOP<<1); // 10..2E - if(Range==2) return 0x32+(DOP<<2); // 30..6C - return 0x74+(DOP<<3); + if(Range==1) return 0x11+(uint8_t)(DOP<<1); // 10..2E + if(Range==2) return 0x32+(uint8_t)(DOP<<2); // 30..6C + return 0x74+(uint8_t)(DOP<<3); } // 70..E8 => max. DOP = 232*0.1=23.2 uint16_t EncodeUR2V12(uint16_t Value) // encode unsigned 16-bit (0..61432) as 14-bit { if(Value<0x1000) { } - else if(Value<0x3000) Value = 0x1000 | ((Value-0x1000)>>1); - else if(Value<0x7000) Value = 0x2000 | ((Value-0x3000)>>2); - else if(Value<0xF000) Value = 0x3000 | ((Value-0x7000)>>3); + else if(Value<0x3000) Value = 0x1000 | (uint16_t)((Value-0x1000)>>1); + else if(Value<0x7000) Value = 0x2000 | (uint16_t)((Value-0x3000)>>2); + else if(Value<0xF000) Value = 0x3000 | (uint16_t)((Value-0x7000)>>3); else Value = 0x3FFF; return Value; } @@ -159,9 +158,9 @@ uint16_t DecodeUR2V12(uint16_t Value) uint16_t Range = Value>>12; Value &=0x0FFF; if(Range==0) return Value; // 0000..0FFF - if(Range==1) return 0x1001+(Value<<1); // 1000..2FFE - if(Range==2) return 0x3002+(Value<<2); // 3000..6FFC - return 0x7004+(Value<<3); + if(Range==1) return 0x1001+(uint16_t)(Value<<1); // 1000..2FFE + if(Range==2) return 0x3002+(uint16_t)(Value<<2); // 3000..6FFC + return 0x7004+(uint16_t)(Value<<3); } // 7000..EFF8 => max: 61432 // ============================================================================================== diff --git a/src/lib/utils/ace/src/picopio.cpp b/src/lib/utils/ace/src/picopio.cpp index 4510432d..a0e73fe0 100644 --- a/src/lib/utils/ace/src/picopio.cpp +++ b/src/lib/utils/ace/src/picopio.cpp @@ -13,12 +13,12 @@ bool add_pio_program(const pio_program_t *program, PIO *pio_hw, int *sm, uint *o *pio_hw = pio1; if (!pio_can_add_program(*pio_hw, program)) { - *offset = -1; + *offset = UINT8_MAX; return false; } } - *offset = pio_add_program(*pio_hw, program); - *sm = (int8_t)pio_claim_unused_sm(*pio_hw, false); + *offset = static_cast(pio_add_program(*pio_hw, program)); + *sm = pio_claim_unused_sm(*pio_hw, false); if (*sm < 0) { return false; diff --git a/src/lib/utils/ace/tcpclient.hpp b/src/lib/utils/ace/tcpclient.hpp index cb229dcc..a4218487 100644 --- a/src/lib/utils/ace/tcpclient.hpp +++ b/src/lib/utils/ace/tcpclient.hpp @@ -148,7 +148,8 @@ friend class TcpListener; return false; } - err_t err = tcp_write(pcb, data.data(), data.size(), + const u16_t writeSize = static_cast(data.size()); + err_t err = tcp_write(pcb, data.data(), writeSize, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); if (flush || err != ERR_OK) @@ -307,7 +308,7 @@ friend class TcpListener; cyw43_arch_lwip_check(); - size_t total = 0; + u16_t total = 0; for (pbuf *q = pBuf; q != nullptr; q = q->next) { auto *data = reinterpret_cast(q->payload); @@ -316,7 +317,7 @@ friend class TcpListener; { self->onReceive({data, len}); } - total += len; + total = static_cast(total + q->len); } tcp_recved(tpcb, total); diff --git a/src/lib/webserver/ace/src/webserver.cpp b/src/lib/webserver/ace/src/webserver.cpp index fd15f6cb..b3f566e2 100644 --- a/src/lib/webserver/ace/src/webserver.cpp +++ b/src/lib/webserver/ace/src/webserver.cpp @@ -240,7 +240,7 @@ int fs_open_custom(fs_file *file, const char *name) module->getData(stream, pathString); file->data = (const char *)file->pextension; - file->len = response.size(); + file->len = static_cast(response.size()); file->index = file->len; // We set index to len to indicate that the complete file has been read and the server can send and close the response // file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT; return 1; diff --git a/src/lib/wifiservice/ace/src/wifiservice.cpp b/src/lib/wifiservice/ace/src/wifiservice.cpp index a7555ef5..009bba17 100644 --- a/src/lib/wifiservice/ace/src/wifiservice.cpp +++ b/src/lib/wifiservice/ace/src/wifiservice.cpp @@ -453,7 +453,10 @@ void WifiService::mDnsInit(int itf) void WifiService::mDnsDeinit(int itf) { #if LWIP_MDNS_RESPONDER == 1 - mdns_resp_del_service(&cyw43_state.netif[itf], mdnsSlot); + if (mdnsSlot >= 0) + { + mdns_resp_del_service(&cyw43_state.netif[itf], static_cast(mdnsSlot)); + } mdns_resp_remove_netif(&cyw43_state.netif[itf]); #endif } From 7e6daf351f9d9e6d27315d6a843323d5ac3f187f Mon Sep 17 00:00:00 2001 From: "R. van Twisk" Date: Tue, 26 May 2026 22:24:16 +0200 Subject: [PATCH 2/2] Strict Compilation --- src/SystemGUI/test/README.md | 20 ++++ src/lib/adsbdecoder/ace/adsbdatacollector.hpp | 3 +- .../aircrafttracker/ace/aircrafttracker.hpp | 4 +- .../ace/src/aircrafttracker.cpp | 7 +- src/lib/bluetooth/ace/src/bluetooth.cpp | 2 +- src/lib/bmp280/ace/src/bmp280.cpp | 16 ++-- src/lib/config/ace/config.hpp | 2 +- src/lib/config/ace/src/config.cpp | 5 +- src/lib/core/ace/antennaRadiationPattern.hpp | 11 ++- src/lib/core/ace/coreutils.hpp | 44 +++++---- src/lib/core/ace/spinlockguard.hpp | 6 +- src/lib/core/ace/src/coreutils.cpp | 14 +-- .../antennaRadiationPattern_test.cpp | 33 ++++++- src/lib/core/core_tests/coreutils_test.cpp | 19 +++- src/lib/fanetace/ace/src/fanetace.cpp | 4 +- src/lib/flarmgatas/ace/flarm2024.hpp | 8 +- src/lib/idle/ace/idle.hpp | 6 +- src/lib/idle/ace/src/idle.cpp | 2 +- src/lib/ogn/CMakeLists.txt | 1 - src/lib/ogn/ace/ogn1.hpp | 8 +- src/lib/ogn/ace/ognpacket.cpp | 3 - src/lib/ogn/ace/ognpacket.hpp | 48 ++++++---- src/lib/ogn/ace/src/ogn1.cpp | 6 +- src/lib/pioserial/ace/pioserial.hpp | 2 +- .../radiotuner/ace/src/radiotunerrx_v2.cpp | 8 +- src/lib/utils/ace/ldpc.hpp | 18 +++- src/lib/utils/ace/ognconv.hpp | 51 ++++++---- src/lib/utils/ace/src/ldpc.cpp | 11 +++ src/lib/utils/ace/src/ognconv.cpp | 96 +++++++++++-------- 29 files changed, 302 insertions(+), 156 deletions(-) create mode 100644 src/SystemGUI/test/README.md delete mode 100644 src/lib/ogn/ace/ognpacket.cpp diff --git a/src/SystemGUI/test/README.md b/src/SystemGUI/test/README.md new file mode 100644 index 00000000..e177f3f5 --- /dev/null +++ b/src/SystemGUI/test/README.md @@ -0,0 +1,20 @@ +# Frontend Unit Tests + +This directory is reserved for SystemGUI frontend unit tests. + +## Run tests + +From `src/SystemGUI`: + +```bash +npm test +``` + +## File naming + +Use `*.test.mjs` files so they are picked up by the `npm test` script. + +## Notes + +- The default setup uses Node's built-in test runner. +- For browser/DOM-specific component tests, add a DOM-capable test stack (for example Vitest + jsdom) in a follow-up change. diff --git a/src/lib/adsbdecoder/ace/adsbdatacollector.hpp b/src/lib/adsbdecoder/ace/adsbdatacollector.hpp index 4e52528b..32ecb797 100644 --- a/src/lib/adsbdecoder/ace/adsbdatacollector.hpp +++ b/src/lib/adsbdecoder/ace/adsbdatacollector.hpp @@ -87,6 +87,7 @@ class AdsbDataCollector static constexpr uint8_t HAS_VELOCITY = 1 << 3; static constexpr uint8_t HAS_ALTITUDE = 1 << 4; // static constexpr uint8_t HAS_POSITION_UPDATED = 1 << 5; + static constexpr uint8_t NOT_HAS_POSITION_UPDATED = static_cast(~HAS_POSITION_UPDATED); static constexpr uint8_t CHECK_HAS_CALLSIGN = 1 << 6; static constexpr uint8_t VALID_MASK = HAS_POSITION_ODD | HAS_POSITION_EVEN | HAS_HEADING | HAS_VELOCITY | HAS_ALTITUDE | HAS_POSITION_UPDATED; @@ -249,7 +250,7 @@ class AdsbDataCollector { if ((currentDataStatus->messageStatus & VALID_MASK) == VALID_MASK) { - currentDataStatus->messageStatus &= static_cast(~HAS_POSITION_UPDATED); + currentDataStatus->messageStatus &= NOT_HAS_POSITION_UPDATED; return true; } diff --git a/src/lib/aircrafttracker/ace/aircrafttracker.hpp b/src/lib/aircrafttracker/ace/aircrafttracker.hpp index 0a75cf61..7b4d1fd5 100644 --- a/src/lib/aircrafttracker/ace/aircrafttracker.hpp +++ b/src/lib/aircrafttracker/ace/aircrafttracker.hpp @@ -22,7 +22,7 @@ * Client that can connect to a host and a port and expect to receive line terminated NMEA Messages * Part of this code taken from the example from Raspbery */ -class AircraftTracker : public BaseModule, public etl::message_router +class AircraftTracker : public BaseModule, public etl::message_router { private: mutable SemaphoreHandle_t trackedAircraftMutex = nullptr; @@ -61,6 +61,7 @@ class AircraftTracker : public BaseModule, public etl::message_router trackedAircraft; GATAS::AircraftAddress ownshipAddress; + float ownshipTrack = 0.f; bool groundStation_ = false; // Producer Consumer queue to handle data between this task and the send task @@ -82,6 +83,7 @@ class AircraftTracker : public BaseModule, public etl::message_router(msg.position.dataSource); if (dataSource < antennaRadiationPattern.size()) { - antennaRadiationPattern[dataSource].put(msg); + antennaRadiationPattern[dataSource].put(msg, ownshipTrack); } if (!queue.full()) diff --git a/src/lib/bluetooth/ace/src/bluetooth.cpp b/src/lib/bluetooth/ace/src/bluetooth.cpp index a829d2a3..c125d273 100644 --- a/src/lib/bluetooth/ace/src/bluetooth.cpp +++ b/src/lib/bluetooth/ace/src/bluetooth.cpp @@ -141,7 +141,7 @@ void Bluetooth::createAdvData() // bit 4 Previously Used advertiseData.push_back(0x06); - uint8_t maxSize = static_cast(etl::min(static_cast(8), localName.size())); + uint8_t maxSize = static_cast(etl::min(8U, localName.size())); advertiseData.push_back(static_cast(1 + maxSize)); // length = type + name length advertiseData.push_back(BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME); advertiseData.insert(advertiseData.end(), localName.begin(), localName.begin() + maxSize); diff --git a/src/lib/bmp280/ace/src/bmp280.cpp b/src/lib/bmp280/ace/src/bmp280.cpp index 88306c8a..784114e6 100644 --- a/src/lib/bmp280/ace/src/bmp280.cpp +++ b/src/lib/bmp280/ace/src/bmp280.cpp @@ -43,22 +43,22 @@ uint32_t Bmp280::compensate_pressure(int32_t adc_P) { int32_t var1, var2; uint32_t p; - var1 = (((int32_t)t_fine) >> 1) - (int32_t)64000; - var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((int32_t)dig_P6); - var2 = var2 + ((var1 * ((int32_t)dig_P5)) << 1); - var2 = (var2 >> 2) + (((int32_t)dig_P4) << 16); - var1 = (((dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + ((((int32_t)dig_P2) * var1) >> 1)) >> 18; - var1 = ((((32768 + var1)) * ((int32_t)dig_P1)) >> 15); + var1 = (t_fine >> 1) - 64000; + var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * dig_P6; + var2 = var2 + ((var1 * dig_P5) << 1); + var2 = (var2 >> 2) + (dig_P4 << 16); + var1 = (((dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + ((dig_P2 * var1) >> 1)) >> 18; + var1 = ((((32768 + var1)) * dig_P1) >> 15); if (var1 == 0) return 0; - p = static_cast((((int32_t)1048576) - adc_P) - (var2 >> 12)) * 3125U; + p = static_cast((1048576 - adc_P) - (var2 >> 12)) * 3125U; if (p < 0x80000000) p = (p << 1) / ((uint32_t)var1); else p = (p / (uint32_t)var1) * 2; - var1 = (((int32_t)dig_P9) * ((int32_t)(((p >> 3) * (p >> 3)) >> 13))) >> 12; + var1 = (dig_P9 * ((int32_t)(((p >> 3) * (p >> 3)) >> 13))) >> 12; var2 = (((int32_t)(p >> 2)) * ((int32_t)dig_P8)) >> 13; p = (uint32_t)((int32_t)p + ((var1 + var2 + dig_P7) >> 4)); diff --git a/src/lib/config/ace/config.hpp b/src/lib/config/ace/config.hpp index 4428c51f..439a7414 100644 --- a/src/lib/config/ace/config.hpp +++ b/src/lib/config/ace/config.hpp @@ -33,7 +33,7 @@ class Config : public Configuration, public etl::message_router struct { LoadLocation location = NA; - uint16_t persistentStoreSize = 0; + size_t persistentStoreSize = 0; } statistics; etl::string_view loadLocationToString(LoadLocation location) const; diff --git a/src/lib/config/ace/src/config.cpp b/src/lib/config/ace/src/config.cpp index f14f0d77..949333e0 100644 --- a/src/lib/config/ace/src/config.cpp +++ b/src/lib/config/ace/src/config.cpp @@ -11,6 +11,7 @@ #include "ace/moreutils.hpp" #include "etl/string.h" +#include "etl/algorithm.h" #include "pico/rand.h" @@ -74,7 +75,7 @@ GATAS::PostConstruct Config::postConstruct() else { statistics.location = PERSISTENT; - statistics.persistentStoreSize = static_cast(strlen((const char *)permanentStore.data()) + 1); + statistics.persistentStoreSize = strlen((const char *)permanentStore.data()) + 1; serializeToVolatile(); } } @@ -252,7 +253,7 @@ void Config::serializeToPersistent() permanentStore.rewind(); permanentStore.write(volatileStore.data(), strlen((const char *)volatileStore.data()) + 1); - statistics.persistentStoreSize = static_cast(strlen((char *)permanentStore.data()) + 1); + statistics.persistentStoreSize = strlen((char *)permanentStore.data()) + 1; } bool Config::deleteData(const etl::string_view fullPath) diff --git a/src/lib/core/ace/antennaRadiationPattern.hpp b/src/lib/core/ace/antennaRadiationPattern.hpp index bab7648c..a6c7d8aa 100644 --- a/src/lib/core/ace/antennaRadiationPattern.hpp +++ b/src/lib/core/ace/antennaRadiationPattern.hpp @@ -38,11 +38,16 @@ namespace GATAS public: AntennaRadiationPattern() : radiationPattern() {}; - void put(const GATAS::IngressAircraftPositionMsg &msg) + static float calculateRelativeBearing(int32_t relNorthFromOwn, int32_t relEastFromOwn, float ownTrack) + { + const float bearingFromOwn = CoreUtils::bearingFromInDegShort(static_cast(relEastFromOwn), static_cast(relNorthFromOwn)); + return CoreUtils::toBearing(bearingFromOwn - ownTrack); + } + + void put(const GATAS::IngressAircraftPositionMsg &msg, float ownTrack) { auto &position = msg.position; - const float bearingFromOwn = CoreUtils::bearingFromInDegShort(static_cast(position.relEastFromOwn), static_cast(position.relNorthFromOwn)); - const float relativeBearing = CoreUtils::toBearing(bearingFromOwn - static_cast(position.track)); + const float relativeBearing = calculateRelativeBearing(position.relNorthFromOwn, position.relEastFromOwn, ownTrack); uint8_t positionInRadial = static_cast(CoreUtils::getRadialSection(static_cast(relativeBearing))); Measurement &measurement = radiationPattern[positionInRadial]; diff --git a/src/lib/core/ace/coreutils.hpp b/src/lib/core/ace/coreutils.hpp index 54573171..0d57c8ce 100644 --- a/src/lib/core/ace/coreutils.hpp +++ b/src/lib/core/ace/coreutils.hpp @@ -18,7 +18,7 @@ class CoreUtils { inline static uint64_t CoreUtils_offsetTimeToAbsolute = 0; - inline static uint32_t CoreUtils_timeUs32PpsOffset = 0; + inline static int32_t CoreUtils_timeUs32PpsOffset = 0; inline static spin_lock_t *spinLock; public: @@ -41,7 +41,7 @@ class CoreUtils */ __force_inline static uint32_t timeUs32() { - return time_us_32() - CoreUtils_timeUs32PpsOffset; + return time_us_32() - static_cast(CoreUtils_timeUs32PpsOffset); } __force_inline static uint32_t timeUs32Raw() @@ -52,7 +52,7 @@ class CoreUtils __force_inline static uint64_t timeUs64() { // time_us_64 and time_us_32 use the same hardware time, thus offset is also the same - return time_us_64() - CoreUtils_timeUs32PpsOffset; + return static_cast(static_cast(time_us_64()) - static_cast(CoreUtils_timeUs32PpsOffset)); } /** @@ -129,13 +129,21 @@ class CoreUtils } /** - * Must be called at high priority to set the PPS offset. - * When offset is known, the correct time in us in reference to PPS can be calculated - * @param offsetUs Offset in us to add to the current time_us_32 to align with PPS This can be used for software PPS adjustments + * Must be called from the PPS path with minimal latency. + * + * Aligns CoreUtils time functions to the PPS second boundary. At the moment this + * function is called, timeUs32() and timeUs64() will report offsetUs microseconds + * into the current PPS second. Use offsetUs for known software/interrupt latency + * compensation; pass 0 when called exactly on PPS. + * + * Raw time functions are not affected. + * + * @param offsetUs Desired corrected microsecond offset within the PPS second. */ static void __time_critical_func(setPPS)(int32_t offsetUs) { - CoreUtils_timeUs32PpsOffset = static_cast(static_cast(time_us_32() % 1'000'000) - static_cast(offsetUs)); + const int32_t usIntoSecond = static_cast(time_us_32() % 1'000'000U); + CoreUtils_timeUs32PpsOffset = usIntoSecond - offsetUs; } /** @@ -144,12 +152,12 @@ class CoreUtils */ static uint16_t msInSecond() { - return static_cast(static_cast((timeUs32() / 1'000)) % static_cast(1'000)); + return static_cast(static_cast(timeUs32() / 1'000) % 1'000U); } - static uint16_t usInSecond() + static uint32_t usInSecond() { - return static_cast(timeUs64() % static_cast(1'000'000)); + return static_cast(timeUs64() % 1'000'000U); } /** @@ -199,7 +207,7 @@ class CoreUtils */ static uint32_t secondsSinceEpoch() { - return static_cast(msSinceEpoch() / static_cast(1000)); + return static_cast(msSinceEpoch() / 1000U); } /** @@ -213,7 +221,7 @@ class CoreUtils static uint32_t msSinceMidnight() { - return static_cast(msSinceEpoch() % static_cast(86'400'000)); + return static_cast(msSinceEpoch() % 86'400'000U); } static tm localTime() @@ -223,7 +231,7 @@ class CoreUtils static tm localTime(uint64_t msSinceEpoch) { - time_t secondsSinceEpoch = static_cast(msSinceEpoch / static_cast(1000)); + time_t secondsSinceEpoch = static_cast(msSinceEpoch / 1000U); struct tm timeinfo = {}; localtime_r(&secondsSinceEpoch, &timeinfo); return timeinfo; @@ -347,7 +355,7 @@ class CoreUtils static float __time_critical_func(bearingFromInDegShort)(float east, float north) { float theta = atan2f(east, north); - float deg = theta * 180.f / (float)M_PI; + float deg = theta * 180.f / M_PIF; if (deg < 0.f) { deg += 360.f; @@ -575,8 +583,8 @@ class CoreUtils return nmea; } - static uint32_t getTotalHeap(void); - static uint32_t getFreeHeap(void); + static size_t getTotalHeap(void); + static size_t getFreeHeap(void); /** * Create an textual representation of the aircraftId. FOr the moment it will simply turn the aircraftID as received into a textual HEX representation @@ -621,7 +629,9 @@ class CoreUtils static void hexStrToByteArray(const char *hex, uint8_t byteArray[]) { auto hexLength = strlen(hex); - if (hexLength > 254) return; + if (hexLength > 254) { + return; + } hexStrToByteArray(hex, static_cast(hexLength), byteArray); } diff --git a/src/lib/core/ace/spinlockguard.hpp b/src/lib/core/ace/spinlockguard.hpp index ffdd56cb..247e8fee 100644 --- a/src/lib/core/ace/spinlockguard.hpp +++ b/src/lib/core/ace/spinlockguard.hpp @@ -25,11 +25,11 @@ class SpinlockGuard } /** - * Request a spinlock. When required is set to value, the function won't panic if no spinlock is available. + * Request a spinlock. When required is set to false, the function won't panic if no spinlock is available. */ - static spin_lock_t *claim(bool required = true) + static spin_lock_t *claim() { - return spin_lock_instance((uint)spin_lock_claim_unused(required)); + return spin_lock_instance((uint)spin_lock_claim_unused(true)); } SpinlockGuard(const SpinlockGuard &) = delete; diff --git a/src/lib/core/ace/src/coreutils.cpp b/src/lib/core/ace/src/coreutils.cpp index 4d437fbc..a7a34371 100644 --- a/src/lib/core/ace/src/coreutils.cpp +++ b/src/lib/core/ace/src/coreutils.cpp @@ -34,17 +34,19 @@ const etl::vector CoreUtils::parsePath(const etl::string_v return tokens; } -uint32_t CoreUtils::getTotalHeap(void) +size_t CoreUtils::getTotalHeap(void) { -#if !defined(__arm__) - return 0; -#else +#if defined(PICO_RP2040) || defined(PICO_RP2350) extern char __StackLimit, __bss_end__; - return static_cast(&__StackLimit - &__bss_end__); + return static_cast( + reinterpret_cast(&__StackLimit) - + reinterpret_cast(&__bss_end__)); +#else + return 0; #endif } -uint32_t CoreUtils::getFreeHeap(void) +size_t CoreUtils::getFreeHeap(void) { // We hit this during unit testing, we return 0 because it would // properly be useless diff --git a/src/lib/core/core_tests/antennaRadiationPattern_test.cpp b/src/lib/core/core_tests/antennaRadiationPattern_test.cpp index 4f887815..ea2d8fbf 100644 --- a/src/lib/core/core_tests/antennaRadiationPattern_test.cpp +++ b/src/lib/core/core_tests/antennaRadiationPattern_test.cpp @@ -22,8 +22,8 @@ TEST_CASE("put stores measurements in the expected radial", "[antennaRadiationPa { GATAS::AntennaRadiationPattern<8> pattern; - pattern.put(makeMsg(15620, -10000, -12000, 45, -70)); - pattern.put(makeMsg(200, 100, 0, 90, -60)); + pattern.put(makeMsg(15620, -10000, -12000, 45, -70), 45.f); + pattern.put(makeMsg(200, 100, 0, 90, -60), 90.f); const auto &snapshot = pattern._radiationPattern(); @@ -43,3 +43,32 @@ TEST_CASE("put stores measurements in the expected radial", "[antennaRadiationPa REQUIRE(snapshot[0].avgRssiDbm == -128); REQUIRE(snapshot[0].maxRssiDbm == -128); } + +TEST_CASE("calculateRelativeBearing uses ownship track and target position", "[antennaRadiationPattern]") +{ + using Pattern = GATAS::AntennaRadiationPattern<8>; + + REQUIRE(Pattern::calculateRelativeBearing(0, 100, 270.f) == Catch::Approx(180.f)); + REQUIRE(Pattern::calculateRelativeBearing(0, 100, 90.f) == Catch::Approx(0.f)); + REQUIRE(Pattern::calculateRelativeBearing(100, 0, 90.f) == Catch::Approx(270.f)); + REQUIRE(Pattern::calculateRelativeBearing(-100, 0, 90.f) == Catch::Approx(90.f)); +} + +TEST_CASE("put ignores target track when storing measurements", "[antennaRadiationPattern]") +{ + GATAS::AntennaRadiationPattern<8> pattern; + + pattern.put(makeMsg(200, 0, 100, 0, -60), 270.f); + + const auto &snapshot = pattern._radiationPattern(); + + REQUIRE(snapshot[4].avgDistance == 100); + REQUIRE(snapshot[4].maxDistance == 200); + REQUIRE(snapshot[4].avgRssiDbm == -94); + REQUIRE(snapshot[4].maxRssiDbm == -60); + + REQUIRE(snapshot[0].avgDistance == 0); + REQUIRE(snapshot[0].maxDistance == 0); + REQUIRE(snapshot[0].avgRssiDbm == -128); + REQUIRE(snapshot[0].maxRssiDbm == -128); +} diff --git a/src/lib/core/core_tests/coreutils_test.cpp b/src/lib/core/core_tests/coreutils_test.cpp index 572a0bd8..a377e1d7 100644 --- a/src/lib/core/core_tests/coreutils_test.cpp +++ b/src/lib/core/core_tests/coreutils_test.cpp @@ -25,7 +25,7 @@ TEST_CASE( "msSinceEpoch", "[single-file]" ) TEST_CASE( "msInSecond", "[single-file]" ) { time_us_Value = 23456623; - CoreUtils::setPPS(00); + CoreUtils::setPPS(0); REQUIRE( CoreUtils::msInSecond() == 0 ); time_us_Value = time_us_Value + 1758'000; @@ -40,6 +40,23 @@ TEST_CASE( "timeUs32 must be alliged with PPS", "[single-file]" ) REQUIRE( CoreUtils::timeUs32() == 23216500 ); } +TEST_CASE("setPPS handles signed software offsets", "[single-file]") +{ + time_us_Value = 23'000'100; + CoreUtils::setPPS(250); + REQUIRE(CoreUtils::timeUs32() == 23'000'250); + REQUIRE(CoreUtils::timeUs64() == 23'000'250); + time_us_Value += 150; + REQUIRE(CoreUtils::usInSecond() == 400); + REQUIRE(CoreUtils::timeUs32() == 23'000'400); + + time_us_Value = 23'000'250; + CoreUtils::setPPS(-100); + REQUIRE(CoreUtils::timeUs32() == 22'999'900); + REQUIRE(CoreUtils::timeUs64() == 22'999'900); + REQUIRE(CoreUtils::usInSecond() == 999'900); +} + TEST_CASE( "usToReference must handle wraparounds", "[single-file]" ) { REQUIRE( CoreUtils::usToReference(1000, 750) == 250); diff --git a/src/lib/fanetace/ace/src/fanetace.cpp b/src/lib/fanetace/ace/src/fanetace.cpp index deb4e382..88858663 100644 --- a/src/lib/fanetace/ace/src/fanetace.cpp +++ b/src/lib/fanetace/ace/src/fanetace.cpp @@ -13,6 +13,8 @@ #include "ace/spinlockguard.hpp" #include "ace/poolallocator.hpp" +#include "etl/algorithm.h" + void FanetAce::start() { xTaskCreate(fanetAceTaskTrampoline, FanetAce::NAME.cbegin(), configMINIMAL_STACK_SIZE + 256, this, tskIDLE_PRIORITY + 2, &taskHandle); @@ -78,7 +80,7 @@ void FanetAce::on_receive(const GATAS::RadioTxPositionRequestMsg &msg) FANET::TrackingPayload payload; payload.latitude(ownship.lat) .longitude(ownship.lon) - .altitude(static_cast(ownship.heightMsl())) + .altitude(static_cast(etl::clamp(ownship.heightMsl(), static_cast(-450), static_cast(5900)))) .speed(ownship.groundSpeed * MS_TO_KPH) .groundTrack(ownship.track) .climbRate(ownship.verticalSpeed) diff --git a/src/lib/flarmgatas/ace/flarm2024.hpp b/src/lib/flarmgatas/ace/flarm2024.hpp index 8e7df461..96fc7e11 100644 --- a/src/lib/flarmgatas/ace/flarm2024.hpp +++ b/src/lib/flarmgatas/ace/flarm2024.hpp @@ -23,8 +23,8 @@ class Flarm2024 : public BaseModule, public etl::message_router { friend class message_router; - static constexpr int DEFAULT_IGNORE_DISTANCE = 25000; - static constexpr int MAX_IGNORE_DISTANCE = 100000; + static constexpr uint32_t DEFAULT_IGNORE_DISTANCE = 25000; + static constexpr uint32_t MAX_IGNORE_DISTANCE = 100000; private: struct @@ -47,8 +47,8 @@ class Flarm2024 : public BaseModule, public etl::message_router(etl::max(0, etl::min(di, MAX_IGNORE_DISTANCE))); + auto di = static_cast(config.valueByPath(DEFAULT_IGNORE_DISTANCE, NAME, "distanceIgnore")); + distanceIgnore = etl::clamp(di, static_cast(0), MAX_IGNORE_DISTANCE); gaTasConfiguration = config.gaTasConfig(); } diff --git a/src/lib/idle/ace/idle.hpp b/src/lib/idle/ace/idle.hpp index d0c92b1e..42da2a7f 100644 --- a/src/lib/idle/ace/idle.hpp +++ b/src/lib/idle/ace/idle.hpp @@ -29,7 +29,7 @@ class Idle : public BaseModule, public etl::message_router(config.valueByPath(26, "port5", "O0")); + ledStatusIndicatorPin = static_cast(config.valueByPath(26, "port5", "O0")); (void)config; } diff --git a/src/lib/idle/ace/src/idle.cpp b/src/lib/idle/ace/src/idle.cpp index a74d6491..97dbbbb4 100644 --- a/src/lib/idle/ace/src/idle.cpp +++ b/src/lib/idle/ace/src/idle.cpp @@ -70,7 +70,7 @@ bool Idle::blinkCb(repeating_timer_t *t) idle->patternStep = Idle::PATTERN_STEPS; } idle->patternStep--; - gpio_put(static_cast(idle->ledStatusIndicatorPin), idle->runningPattern & 0b1U); + gpio_put(idle->ledStatusIndicatorPin, idle->runningPattern & 0b1U); idle->runningPattern >>= 1; return true; diff --git a/src/lib/ogn/CMakeLists.txt b/src/lib/ogn/CMakeLists.txt index 92328293..b2601c7c 100644 --- a/src/lib/ogn/CMakeLists.txt +++ b/src/lib/ogn/CMakeLists.txt @@ -5,7 +5,6 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/../gatas_module.cmake) gatas_add_module( SOURCE_FILES - ace/ognpacket.cpp ace/src/ogn1.cpp TARGET_LINK_LIBS utils diff --git a/src/lib/ogn/ace/ogn1.hpp b/src/lib/ogn/ace/ogn1.hpp index d74f3fc6..345ff1b8 100644 --- a/src/lib/ogn/ace/ogn1.hpp +++ b/src/lib/ogn/ace/ogn1.hpp @@ -38,8 +38,8 @@ class Ogn1 : public BaseModule, public etl::message_router(etl::max(0, etl::min(di, MAX_IGNORE_DISTANCE))); + auto di = static_cast(config.valueByPath(DEFAULT_IGNORE_DISTANCE, NAME, "distanceIgnore")); + distanceIgnore = etl::clamp(di, static_cast(0), MAX_IGNORE_DISTANCE); } virtual ~Ogn1() = default; diff --git a/src/lib/ogn/ace/ognpacket.cpp b/src/lib/ogn/ace/ognpacket.cpp deleted file mode 100644 index a0f51417..00000000 --- a/src/lib/ogn/ace/ognpacket.cpp +++ /dev/null @@ -1,3 +0,0 @@ - -#include "ognpacket.hpp" - diff --git a/src/lib/ogn/ace/ognpacket.hpp b/src/lib/ogn/ace/ognpacket.hpp index 119a59a6..62436a45 100644 --- a/src/lib/ogn/ace/ognpacket.hpp +++ b/src/lib/ogn/ace/ognpacket.hpp @@ -20,6 +20,12 @@ // #include "nmea.h" // #include "mavlink.h" +// We would like to have this enabled, but it's hard to fix this correctly since there are not tests available. +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif // the packet description here is how it look on the little-endian CPU before sending it to the RF chip // nRF905, CC1101, SPIRIT1, RFM69 chips actually reverse the bit order within every byte @@ -212,7 +218,7 @@ class OGN1_Packet // Packet structure for the OGN tracker // Centripetal acceleration static int16_t calcCPaccel(int16_t Speed, int16_t TurnRate) { - return static_cast(((static_cast(TurnRate) * Speed * 229) + 0x10000) >> 17); // [0.1m/s^2] + return ((int32_t)TurnRate*Speed*229+0x10000)>>17; // [0.1m/s^2] } int16_t calcCPaccel(void) { @@ -227,7 +233,7 @@ class OGN1_Packet // Packet structure for the OGN tracker Radius /= TurnRate; Radius = (Radius+128)>>8; if (etl::absolute(Radius)>MaxRadius) return 0; - return static_cast(Radius); + return Radius; } int16_t calcTurnRadius(int16_t MaxRadius=0x7FFF) { @@ -264,7 +270,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeLatitude(int32_t Latitude) // encode Latitude: units are 0.0001/60 degrees { - Data[0] = (Data[0] & 0xFF000000U) | (static_cast(Latitude >> 3) & 0x00FFFFFFU); + Position.Latitude = Latitude>>3; } int32_t DecodeLatitude(void) const @@ -277,7 +283,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeLongitude(int32_t Longitude) // encode Longitude: units are 0.0001/60 degrees { - Data[1] = (Data[1] & 0xFF000000U) | (static_cast(Longitude >> 4) & 0x00FFFFFFU); + Position.Longitude = Longitude>>=4; } int32_t DecodeLongitude(void) const @@ -299,7 +305,7 @@ class OGN1_Packet // Packet structure for the OGN tracker int16_t getBaroAltDiff(void) const { int16_t AltDiff=Position.BaroAltDiff; - if (Position.BaroMSB==0) AltDiff |= static_cast(0xFF00); + if (Position.BaroMSB==0) AltDiff|=0xFF00; return AltDiff; } void setBaroAltDiff(int32_t AltDiff) @@ -325,7 +331,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeAltitude(int32_t Altitude) // encode altitude in meters { if (Altitude<0) Altitude=0; - Position.Altitude = static_cast(UnsVRencode(static_cast(Altitude)) & 0x3FFFU); + Position.Altitude = UnsVRencode((uint16_t)Altitude); } // Position.Altitude = EncodeUR2V12((uint16_t)Altitude); } @@ -337,43 +343,43 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeDOP(uint8_t DOP) { - Position.DOP = static_cast(UnsVRencode(DOP) & 0x3FU); + Position.DOP = UnsVRencode(DOP); } // { Position.DOP = EncodeUR2V4(DOP); } uint8_t DecodeDOP(void) const { - return static_cast(UnsVRdecode(Position.DOP)); + return UnsVRdecode(Position.DOP); } // { return DecodeUR2V4(Position.DOP); } void EncodeSpeed(int16_t Speed) // speed in 0.2 knots (or 0.1m/s) { if (Speed<0) Speed=0; - else Speed = static_cast(UnsVRencode(static_cast(Speed))); // EncodeUR2V8(Speed); - Position.Speed = static_cast(static_cast(Speed) & 0x03FFU); + else Speed = UnsVRencode(Speed); // EncodeUR2V8(Speed); + Position.Speed = Speed; } int16_t DecodeSpeed(void) const // return speed in 0.2 knots or 0.1m/s units { - return static_cast(UnsVRdecode(Position.Speed)); + return UnsVRdecode(Position.Speed); } // { return DecodeUR2V8(Position.Speed); } // => max. speed: 3832*0.2 = 766 knots int16_t DecodeHeading(void) const // return Heading in 0.1 degree units 0..359.9 deg { int32_t Heading = Position.Heading; - return static_cast((Heading * 3600 + 512) >> 10); + return (Heading*3600+512)>>10; } void EncodeHeading(int16_t Heading) { - Position.Heading = static_cast(static_cast(((static_cast(Heading) << 10) + 180) / 3600) & 0x03FFU); + Position.Heading = (((int32_t)Heading<<10)+180)/3600; } void setHeadingAngle(uint16_t HeadingAngle) { - Position.Heading = static_cast(static_cast((HeadingAngle + 32) >> 6) & 0x03FFU); + Position.Heading = (((HeadingAngle+32)>>6)); } uint16_t getHeadingAngle(void) const @@ -411,7 +417,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeClimbRate(int16_t Climb) { - Position.ClimbRate = static_cast(EncodeSR2V6(Climb) & 0x01FFU); + Position.ClimbRate = EncodeSR2V6(Climb); } int16_t DecodeClimbRate(void) const @@ -441,7 +447,7 @@ class OGN1_Packet // Packet structure for the OGN tracker void EncodeVoltage(uint16_t Voltage) { - Status.Voltage = static_cast(EncodeUR2V6(Voltage)); // [1/64V] + Status.Voltage=EncodeUR2V6(Voltage); // [1/64V] } uint16_t DecodeVoltage(void) const { @@ -462,7 +468,7 @@ class OGN1_Packet // Packet structure for the OGN tracker } uint16_t DecodeHumidity(void) const { - return static_cast(520 + DecodeSR2V5(Status.Humidity)); + return 520+DecodeSR2V5(Status.Humidity); } // -------------------------------------------------------------------------------------------------------------- @@ -490,7 +496,7 @@ class OGN1_Packet // Packet structure for the OGN tracker uint8_t Msk1 = 0xFF; Msk1<<=Ofs; uint8_t Msk2 = 0x01; - Msk2 = static_cast((Msk2 << Len2) - 1); + Msk2 = (Msk2<>Len1); } @@ -528,7 +534,7 @@ class OGN1_Packet // Packet structure for the OGN tracker Len += 1; } setInfoChar(InfoType, Idx); // terminating character - Info.DataChars = static_cast(Idx & 0x0FU); // update number of characters + Info.DataChars=Idx; // update number of characters return Len+1; } // return number of added Value characters @@ -596,3 +602,7 @@ class OGN1_Packet // Packet structure for the OGN tracker } ; + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif diff --git a/src/lib/ogn/ace/src/ogn1.cpp b/src/lib/ogn/ace/src/ogn1.cpp index 261305b5..109ebb90 100644 --- a/src/lib/ogn/ace/src/ogn1.cpp +++ b/src/lib/ogn/ace/src/ogn1.cpp @@ -80,13 +80,13 @@ uint8_t Ogn1::errorCorrect(uint8_t *output, uint8_t *data, uint8_t *err, uint8_t Ogn1::decoder.Input(data, err); // put data into the FEC decoder do // more loops is more chance to recover the packet { - check = static_cast(decoder.ProcessChecks()); // do an iteration + check = decoder.ProcessChecks(); // do an iteration } while ((iter--) && check); // if FEC all fine: break Ogn1::decoder.Output(output); // get corrected bytes into the OGN packet errCount += ErrCount(output, data, err, OGN_PACKET_LENGTH); - errCount = etl::min(errCount, (uint8_t)15); - check = etl::min(check, (uint8_t)15); + errCount = etl::min(errCount, static_cast(15)); + check = etl::min(check, static_cast(15)); return (check & 0x0F) | (errCount << 4); } diff --git a/src/lib/pioserial/ace/pioserial.hpp b/src/lib/pioserial/ace/pioserial.hpp index a9a608e9..4f5a8a94 100644 --- a/src/lib/pioserial/ace/pioserial.hpp +++ b/src/lib/pioserial/ace/pioserial.hpp @@ -26,7 +26,7 @@ class PioSerial using CallBackFunction = etl::delegate&)>; private: - static constexpr etl::array commonBaudrates{ 115200U, 9600U, 19200U, 38400U, 57600U }; + static constexpr etl::array commonBaudrates{ 115200U, 9600U, 19200U, 38400U, 57600U }; static void pio0_irq0_func_handler() diff --git a/src/lib/radiotuner/ace/src/radiotunerrx_v2.cpp b/src/lib/radiotuner/ace/src/radiotunerrx_v2.cpp index 0d02b57c..40117b96 100644 --- a/src/lib/radiotuner/ace/src/radiotunerrx_v2.cpp +++ b/src/lib/radiotuner/ace/src/radiotunerrx_v2.cpp @@ -100,7 +100,7 @@ void RadioTunerRx::radioTuneTask(void *arg) } // Position within the repeating cycle - const int32_t cycleMs = static_cast(loopStartMs % ref.maxTimeMs); + const auto cycleMs = loopStartMs % ref.maxTimeMs; // Find which entry covers this time size_t foundIdx = 0; @@ -325,7 +325,7 @@ void RadioTunerRx::spreadSecondIndex(RadioProtocolCtx &ctx) } } - const uint16_t N = static_cast(unique.size()); + const auto N = unique.size(); if (N <= 2) { return; // nothing to improve @@ -334,12 +334,12 @@ void RadioTunerRx::spreadSecondIndex(RadioProtocolCtx &ctx) // 2. Build new order: even indices first, then odd IndexVector order; - for (uint16_t i = 0; i < N; i += 2) + for (size_t i = 0; i < N; i += 2) { order.push_back(unique[i]); } - for (uint16_t i = 1; i < N; i += 2) + for (size_t i = 1; i < N; i += 2) { order.push_back(unique[i]); } diff --git a/src/lib/utils/ace/ldpc.hpp b/src/lib/utils/ace/ldpc.hpp index 2a91a423..7204d0e8 100644 --- a/src/lib/utils/ace/ldpc.hpp +++ b/src/lib/utils/ace/ldpc.hpp @@ -6,6 +6,7 @@ #ifndef __LDPC_H__ #define __LDPC_H__ + #include #include #include "pico/stdlib.h" @@ -15,7 +16,12 @@ #include "bitutils.hpp" - +// We would like to have this enabled, but it's hard to fix this correctly since there are not tests available. +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif // extern const uint32_t LDPC_ParityGen_n208k160[48][5]; // extern const uint32_t LDPC_ParityCheck_n208k160[48][7]; @@ -205,7 +211,7 @@ class LDPC_Decoder { OutBit[Bit] = InpBit[Bit] + (ExtBit[Bit]>>1); } - return static_cast(Count); + return Count; } int16_t ProcessCheck(uint8_t Row) @@ -242,7 +248,7 @@ class LDPC_Decoder uint8_t BitIdx=CheckIndex[Bit]; int16_t Ampl = Bit==MinBit ? MinAmpl2 : MinAmpl; if(CheckFails) Ampl=(-Ampl); - ExtBit[BitIdx] = static_cast(ExtBit[BitIdx] + ((Word & Mask) ? Ampl : -Ampl)); + ExtBit[BitIdx] += (Word&Mask) ? Ampl:-Ampl; Mask<<=1; } return CheckFails?-MinAmpl:MinAmpl; @@ -630,4 +636,10 @@ class OGN_PPM_Decoder #endif // __AVR__ + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + #endif // of __LDPC_H__ + diff --git a/src/lib/utils/ace/ognconv.hpp b/src/lib/utils/ace/ognconv.hpp index 71c87ce0..7ea36318 100644 --- a/src/lib/utils/ace/ognconv.hpp +++ b/src/lib/utils/ace/ognconv.hpp @@ -6,6 +6,13 @@ #include +// We would like to have this enabled, but it's hard to fix this correctly since there are not tests available. +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + uint16_t EncodeUR2V8(uint16_t Value); // Encode unsigned 12bit (0..3832) as 10bit uint16_t DecodeUR2V8(uint16_t Value); // Decode 10bit 0..0x3FF @@ -30,47 +37,47 @@ uint8_t DecodeUR2V4(uint8_t DOP); template Type UnsVRdecode(Type Value) { - const Type Thres = static_cast(1 << Bits); - uint8_t Range = static_cast(Value >> Bits); - Value &= static_cast(Thres - 1); - if(Range==0) return Value; - if(Range==1) return static_cast(Thres + 1 + (Value << 1)); - if(Range==2) return static_cast(3 * Thres + 2 + (Value << 2)); - return static_cast(7 * Thres + 4 + (Value << 3)); + const Type Thres = 1<>Bits; + Value &= Thres-1; + if(Range==0) return Value; + if(Range==1) return Thres+1+(Value<<1); + if(Range==2) return 3*Thres+2+(Value<<2); + return 7*Thres+4+(Value<<3); } template Type UnsVRencode(Type Value) { - const Type Thres = static_cast(1 << Bits); - if(Value< Thres) return Value; - if(Value< 3*Thres) return static_cast(Thres | ((Value - Thres) >> 1)); - if(Value< 7*Thres) return static_cast(2 * Thres | ((Value - 3 * Thres) >> 2)); - if(Value<15*Thres) return static_cast(3 * Thres | ((Value - 7 * Thres) >> 3)); - return static_cast(4 * Thres - 1); + const Type Thres = 1<>1); + if(Value< 7*Thres) return 2*Thres | ((Value-3*Thres)>>2); + if(Value<15*Thres) return 3*Thres | ((Value-7*Thres)>>3); + return 4*Thres-1; } template Type SignVRencode(Type Value) { - const Type SignMask = static_cast(1 << (Bits + 2)); + const Type SignMask = 1<<(Bits+2); Type Sign=0; if(Value<0) { - Value = static_cast(-Value); + Value=(-Value); Sign=SignMask; } Value = UnsVRencode(Value); - return static_cast(Value | Sign); + return Value | Sign; } template Type SignVRdecode(Type Value) { - const Type SignMask = static_cast(1 << (Bits + 2)); - Type Sign = static_cast(Value & SignMask); - Value = UnsVRdecode(static_cast(Value & static_cast(SignMask - 1))); - return Sign ? static_cast(-Value) : Value; + const Type SignMask = 1<<(Bits+2); + Type Sign = Value&SignMask; + Value = UnsVRdecode(Value&(SignMask-1)); + return Sign ? -Value: Value; } uint8_t EncodeGray(uint8_t Binary); @@ -82,3 +89,7 @@ uint32_t DecodeGray(uint32_t Gray); uint8_t EncodeAscii85( char *Ascii, uint32_t Word ); // Encode 32-bit Word into 5-char Ascii-85 string uint8_t DecodeAscii85(uint32_t &Word, const char *Ascii); // Decode 5-char Ascii-85 to 32-bit Word + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif diff --git a/src/lib/utils/ace/src/ldpc.cpp b/src/lib/utils/ace/src/ldpc.cpp index fcf54562..9565cc16 100644 --- a/src/lib/utils/ace/src/ldpc.cpp +++ b/src/lib/utils/ace/src/ldpc.cpp @@ -3,6 +3,14 @@ #include "../ldpc.hpp" +// We would like to have this enabled, but it's hard to fix this correctly since there are not tests available. +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + + #ifndef __AVR__ #include #endif @@ -861,3 +869,6 @@ uint8_t LDPC_Check_n354k160(const uint32_t *Data) #endif // __AVR__ +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif diff --git a/src/lib/utils/ace/src/ognconv.cpp b/src/lib/utils/ace/src/ognconv.cpp index 3ebed1ad..89115fc8 100644 --- a/src/lib/utils/ace/src/ognconv.cpp +++ b/src/lib/utils/ace/src/ognconv.cpp @@ -3,14 +3,21 @@ #include "../ognconv.hpp" +// We would like to have this enabled, but it's hard to fix this correctly since there are not tests available. +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + // ============================================================================================== uint16_t EncodeUR2V8(uint16_t Value) // Encode unsigned 12bit (0..3832) as 10bit { if(Value<0x100) { } - else if(Value<0x300) Value = 0x100 | (uint16_t)((Value-0x100)>>1); - else if(Value<0x700) Value = 0x200 | (uint16_t)((Value-0x300)>>2); - else if(Value<0xF00) Value = 0x300 | (uint16_t)((Value-0x700)>>3); + else if(Value<0x300) Value = 0x100 | ((Value-0x100)>>1); + else if(Value<0x700) Value = 0x200 | ((Value-0x300)>>2); + else if(Value<0xF00) Value = 0x300 | ((Value-0x700)>>3); else Value = 0x3FF; return Value; } @@ -20,20 +27,20 @@ uint16_t DecodeUR2V8(uint16_t Value) // Decode 1 uint16_t Range = Value>>8; Value &= 0x0FF; if(Range==0) return Value; // 000..0FF - if(Range==1) return 0x101+(uint16_t)(Value<<1); // 100..2FE - if(Range==2) return 0x302+(uint16_t)(Value<<2); // 300..6FC - return 0x704+(uint16_t)(Value<<3); + if(Range==1) return 0x101+(Value<<1); // 100..2FE + if(Range==2) return 0x302+(Value<<2); // 300..6FC + return 0x704+(Value<<3); } // 700..EF8 // in 12bit (0..3832) uint8_t EncodeUR2V5(uint16_t Value) // Encode unsigned 9bit (0..472) as 7bit { if(Value<0x020) { } - else if(Value<0x060) Value = 0x020 | (uint16_t)((Value-0x020)>>1); - else if(Value<0x0E0) Value = 0x040 | (uint16_t)((Value-0x060)>>2); - else if(Value<0x1E0) Value = 0x060 | (uint16_t)((Value-0x0E0)>>3); + else if(Value<0x060) Value = 0x020 | ((Value-0x020)>>1); + else if(Value<0x0E0) Value = 0x040 | ((Value-0x060)>>2); + else if(Value<0x1E0) Value = 0x060 | ((Value-0x0E0)>>3); else Value = 0x07F; - return (uint8_t)Value; + return Value; } uint16_t DecodeUR2V5(uint16_t Value) // Decode 7bit as unsigned 9bit (0..472) @@ -43,15 +50,15 @@ uint16_t DecodeUR2V5(uint16_t Value) // Decode 7 if(Range==0) { } // 000..01F else if(Range==1) { - Value = 0x021+(uint16_t)(Value<<1); // 020..05E + Value = 0x021+(Value<<1); // 020..05E } else if(Range==2) { - Value = 0x062+(uint16_t)(Value<<2); // 060..0DC + Value = 0x062+(Value<<2); // 060..0DC } else { - Value = 0x0E4+(uint16_t)(Value<<3); // 0E0..1D8 => max. Value = 472 + Value = 0x0E4+(Value<<3); // 0E0..1D8 => max. Value = 472 } return Value; } @@ -64,23 +71,23 @@ uint8_t EncodeSR2V5(int16_t Value) // Encode si Value=(-Value); Sign=0x80; } - Value = EncodeUR2V5((uint16_t)Value); - return (uint8_t)Value | Sign; + Value = EncodeUR2V5(Value); + return Value | Sign; } int16_t DecodeSR2V5( int16_t Value) // Decode { int16_t Sign = Value&0x80; - Value = static_cast(DecodeUR2V5(static_cast(Value & 0x7F))); + Value = DecodeUR2V5(Value&0x7F); return Sign ? -Value: Value; } uint16_t EncodeUR2V6(uint16_t Value) // Encode unsigned 10bit (0..952) as 8 bit { if(Value<0x040) { } - else if(Value<0x0C0) Value = 0x040 | (uint16_t)((Value-0x040)>>1); - else if(Value<0x1C0) Value = 0x080 | (uint16_t)((Value-0x0C0)>>2); - else if(Value<0x3C0) Value = 0x0C0 | (uint16_t)((Value-0x1C0)>>3); + else if(Value<0x0C0) Value = 0x040 | ((Value-0x040)>>1); + else if(Value<0x1C0) Value = 0x080 | ((Value-0x0C0)>>2); + else if(Value<0x3C0) Value = 0x0C0 | ((Value-0x1C0)>>3); else Value = 0x0FF; return Value; } @@ -92,15 +99,15 @@ uint16_t DecodeUR2V6(uint16_t Value) // Decode 8b if(Range==0) { } // 000..03F else if(Range==1) { - Value = 0x041+(uint16_t)(Value<<1); // 040..0BE + Value = 0x041+(Value<<1); // 040..0BE } else if(Range==2) { - Value = 0x0C2+(uint16_t)(Value<<2); // 0C0..1BC + Value = 0x0C2+(Value<<2); // 0C0..1BC } else { - Value = 0x1C4+(uint16_t)(Value<<3); // 1C0..3B8 => max. Value = 952 + Value = 0x1C4+(Value<<3); // 1C0..3B8 => max. Value = 952 } return Value; } @@ -113,22 +120,23 @@ uint16_t EncodeSR2V6(int16_t Value) // Encode si Value=(-Value); Sign=0x100; } - return EncodeUR2V6((uint16_t)Value) | Sign; + Value = EncodeUR2V6(Value); + return Value | Sign; } int16_t DecodeSR2V6( int16_t Value) // Decode 9bit as signed 11bit (-952..+952) { int16_t Sign = Value&0x100; - Value = (int16_t)DecodeUR2V6(Value&0x00FF); + Value = DecodeUR2V6(Value&0x00FF); return Sign ? -Value: Value; } uint8_t EncodeUR2V4(uint8_t DOP) { if(DOP<0x10) { } - else if(DOP<0x30) DOP = 0x10 | (uint8_t)((DOP-0x10)>>1); - else if(DOP<0x70) DOP = 0x20 | (uint8_t)((DOP-0x30)>>2); - else if(DOP<0xF0) DOP = 0x30 | (uint8_t)((DOP-0x70)>>3); + else if(DOP<0x30) DOP = 0x10 | ((DOP-0x10)>>1); + else if(DOP<0x70) DOP = 0x20 | ((DOP-0x30)>>2); + else if(DOP<0xF0) DOP = 0x30 | ((DOP-0x70)>>3); else DOP = 0x3F; return DOP; } @@ -138,17 +146,17 @@ uint8_t DecodeUR2V4(uint8_t DOP) uint8_t Range = DOP>>4; DOP &= 0x0F; if(Range==0) return DOP; // 00..0F - if(Range==1) return 0x11+(uint8_t)(DOP<<1); // 10..2E - if(Range==2) return 0x32+(uint8_t)(DOP<<2); // 30..6C - return 0x74+(uint8_t)(DOP<<3); + if(Range==1) return 0x11+(DOP<<1); // 10..2E + if(Range==2) return 0x32+(DOP<<2); // 30..6C + return 0x74+(DOP<<3); } // 70..E8 => max. DOP = 232*0.1=23.2 uint16_t EncodeUR2V12(uint16_t Value) // encode unsigned 16-bit (0..61432) as 14-bit { if(Value<0x1000) { } - else if(Value<0x3000) Value = 0x1000 | (uint16_t)((Value-0x1000)>>1); - else if(Value<0x7000) Value = 0x2000 | (uint16_t)((Value-0x3000)>>2); - else if(Value<0xF000) Value = 0x3000 | (uint16_t)((Value-0x7000)>>3); + else if(Value<0x3000) Value = 0x1000 | ((Value-0x1000)>>1); + else if(Value<0x7000) Value = 0x2000 | ((Value-0x3000)>>2); + else if(Value<0xF000) Value = 0x3000 | ((Value-0x7000)>>3); else Value = 0x3FFF; return Value; } @@ -158,9 +166,9 @@ uint16_t DecodeUR2V12(uint16_t Value) uint16_t Range = Value>>12; Value &=0x0FFF; if(Range==0) return Value; // 0000..0FFF - if(Range==1) return 0x1001+(uint16_t)(Value<<1); // 1000..2FFE - if(Range==2) return 0x3002+(uint16_t)(Value<<2); // 3000..6FFC - return 0x7004+(uint16_t)(Value<<3); + if(Range==1) return 0x1001+(Value<<1); // 1000..2FFE + if(Range==2) return 0x3002+(Value<<2); // 3000..6FFC + return 0x7004+(Value<<3); } // 7000..EFF8 => max: 61432 // ============================================================================================== @@ -213,12 +221,12 @@ uint32_t DecodeGray(uint32_t Gray) static const unsigned char MapAscii85[86] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~"; static const uint8_t UnmapAscii85[128] = -{ - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 62, 85, 63, 64, 65, 66, 85, 67, 68, 69, 70, 85, 71, 85, 85, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 85, 72, 73, 74, 75, 76, - 77, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 85, 85, 85, 78, 79, - 80, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 81, 82, 83, 84, 85 -}; + { + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 62, 85, 63, 64, 65, 66, 85, 67, 68, 69, 70, 85, 71, 85, 85, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 85, 72, 73, 74, 75, 76, + 77, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 85, 85, 85, 78, 79, + 80, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 81, 82, 83, 84, 85 + }; uint8_t EncodeAscii85(char *Ascii, uint32_t Word) { @@ -246,3 +254,7 @@ uint8_t DecodeAscii85(uint32_t &Word, const char *Ascii) } return 5; } + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif