diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index a1ad5db2..166fc2f5 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -14,18 +14,17 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' - name: Install arm-none-eabi run: sudo apt install gcc-arm-none-eabi - - name: make gd32_dmx_usb_pro + - name: version + run: arm-none-eabi-g++ --version + - name: build all run: | - cd gd32_dmx_usb_pro - make -f Makefile.GD32 clean - make -f Makefile.GD32 - cd - - - name: make gd32_rdm_responder - run: | - cd gd32_rdm_responder - make -f Makefile.GD32 clean - make -f Makefile.GD32 - cd - + cd scripts + ./build_all.sh \ No newline at end of file diff --git a/common/include/common/utils/utils_enum.h b/common/include/common/utils/utils_enum.h index c088970f..39218761 100755 --- a/common/include/common/utils/utils_enum.h +++ b/common/include/common/utils/utils_enum.h @@ -28,8 +28,7 @@ #include -namespace common -{ +namespace common { // Converts an enum class value to its underlying integer type. template constexpr auto ToValue(Enum e) noexcept -> std::underlying_type_t { diff --git a/common/include/common/utils/utils_flags.h b/common/include/common/utils/utils_flags.h index 6091f975..e7a009b8 100755 --- a/common/include/common/utils/utils_flags.h +++ b/common/include/common/utils/utils_flags.h @@ -31,80 +31,64 @@ #include "common/utils/utils_enum.h" // Ensure this provides ToValue and FromValue -namespace common -{ - +namespace common { template requires std::is_enum_v -constexpr E operator|(E lhs, E rhs) -{ +constexpr E operator|(E lhs, E rhs) { return static_cast(ToValue(lhs) | ToValue(rhs)); } template requires std::is_enum_v -constexpr E operator&(E lhs, E rhs) -{ +constexpr E operator&(E lhs, E rhs) { return static_cast(ToValue(lhs) & ToValue(rhs)); } template requires std::is_enum_v -constexpr E operator~(E e) -{ +constexpr E operator~(E e) { return static_cast(~ToValue(e)); } template requires std::is_enum_v -constexpr E& operator|=(E& lhs, E rhs) -{ +constexpr E& operator|=(E& lhs, E rhs) { lhs = lhs | rhs; return lhs; } template requires std::is_enum_v -constexpr E& operator&=(E& lhs, E rhs) -{ +constexpr E& operator&=(E& lhs, E rhs) { lhs = lhs & rhs; return lhs; } template requires std::is_enum_v -constexpr void SetFlag(uint32_t& flags, E bit, bool enable) -{ - if (enable) - { +constexpr void SetFlag(uint32_t& flags, E bit, bool enable) { + if (enable) { flags |= ToValue(bit); - } - else - { + } else { flags &= ~ToValue(bit); } } template requires std::is_enum_v -constexpr uint32_t SetFlagValue(uint32_t flags, E bit, bool enable) -{ - if (enable) - { +constexpr uint32_t SetFlagValue(uint32_t flags, E bit, bool enable) { + if (enable) { return flags | ToValue(bit); } - else - { - return flags & ~ToValue(bit); - } + + return flags & ~ToValue(bit); } template -requires std::is_enum_v + requires std::is_enum_v constexpr bool IsFlagSet(uint32_t flags, E bit) { return (flags & ToValue(bit)) != 0; } - } // namespace common -#endif // COMMON_UTILS_UTILS_FLAGS_H_ +#endif // COMMON_UTILS_UTILS_FLAGS_H_ diff --git a/common/include/common/utils/utils_hash.h b/common/include/common/utils/utils_hash.h index 525c669f..806ff3cc 100755 --- a/common/include/common/utils/utils_hash.h +++ b/common/include/common/utils/utils_hash.h @@ -29,11 +29,9 @@ #include // Compile-time FNV-1a 32-bit hash -consteval uint32_t Fnv1a32(const char* str, uint8_t length) -{ +consteval uint32_t Fnv1a32(const char* str, uint8_t length) { uint32_t hash = 0x811c9dc5u; - for (uint8_t i = 0; i < length; ++i) - { + for (uint8_t i = 0; i < length; ++i) { hash ^= static_cast(str[i]); hash *= 0x01000193u; } @@ -41,15 +39,13 @@ consteval uint32_t Fnv1a32(const char* str, uint8_t length) } // Runtime version for raw filenames -inline uint32_t Fnv1a32Runtime(const char* str, uint32_t length) -{ +inline uint32_t Fnv1a32Runtime(const char* str, uint32_t length) { uint32_t hash = 0x811c9dc5u; - for (uint32_t i = 0; i < length; ++i) - { + for (uint32_t i = 0; i < length; ++i) { hash ^= static_cast(str[i]); hash *= 0x01000193u; } return hash; } -#endif // COMMON_UTILS_UTILS_HASH_H_ +#endif // COMMON_UTILS_UTILS_HASH_H_ diff --git a/common/include/common/utils/utils_port.h b/common/include/common/utils/utils_port.h index fe20fcf7..c0e99ec4 100755 --- a/common/include/common/utils/utils_port.h +++ b/common/include/common/utils/utils_port.h @@ -28,18 +28,17 @@ #include -namespace common -{ -template void PortSet(uint32_t port_index, S s, uint16_t& n) -{ +namespace common { +template +void PortSet(uint32_t port_index, S s, uint16_t& n) { uint16_t value = n; // Create a local copy value &= static_cast(~(0x3 << (port_index * 2))); value |= static_cast((static_cast(s) & 0x3) << (port_index * 2)); n = value; // Write back to the original field } -template S PortGet(uint32_t port_index, uint16_t n) -{ +template +S PortGet(uint32_t port_index, uint16_t n) { return static_cast((n >> (port_index * 2)) & 0x3); } } // namespace common diff --git a/common/include/common/utils/utils_string.h b/common/include/common/utils/utils_string.h index 97810481..50a16025 100644 --- a/common/include/common/utils/utils_string.h +++ b/common/include/common/utils/utils_string.h @@ -28,13 +28,10 @@ #include -namespace common -{ -constexpr uint32_t ConstStrLen(const char* s) -{ +namespace common { +constexpr uint32_t ConstStrLen(const char* str) { uint32_t len = 0; - while (s[len] != '\0') - { + while (str[len] != '\0') { ++len; } return len; diff --git a/common/include/firmware/debug/debug_dump.h b/common/include/firmware/debug/debug_dump.h index ef6f4f61..39b45120 100755 --- a/common/include/firmware/debug/debug_dump.h +++ b/common/include/firmware/debug/debug_dump.h @@ -2,7 +2,7 @@ * @file debug_dump.h * */ -/* Copyright (C) 2018-2025 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2018-2026 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,57 +31,48 @@ #include #if defined(H3) -namespace uart0 -{ +namespace uart0 { int Printf(const char* fmt, ...); } #define printf uart0::Printf // NOLINT #endif -namespace debug -{ -namespace dump -{ +namespace debug { +namespace dump { inline constexpr uint32_t kCharsPerLine = 16; } #ifdef NDEBUG -inline void Dump([[maybe_unused]] const void* data, [[maybe_unused]] uint32_t size) {} +static inline void Dump([[maybe_unused]] const void* data, [[maybe_unused]] uint32_t size) {} #else -inline void Dump(const void* data, uint32_t size) -{ +inline void Dump(const void* data, uint32_t size) { uint32_t chars = 0; - const auto* p = reinterpret_cast(data); + const auto* ptr = reinterpret_cast(data); - printf("%p:%d\n", data, size); + printf("%p:%u\n", data, static_cast(size)); - do - { + do { uint32_t chars_this_line = 0; - printf("%04x ", chars); + printf("%04x ", static_cast(chars)); - const auto* q = p; + const auto* q = ptr; - while ((chars_this_line < dump::kCharsPerLine) && (chars < size)) - { - if (chars_this_line % 8 == 0) - { + while ((chars_this_line < dump::kCharsPerLine) && (chars < size)) { + if (chars_this_line % 8 == 0) { printf(" "); } - printf("%02x ", *p); + printf("%02x ", *ptr); chars_this_line++; chars++; - p++; + ptr++; } auto chars_dot_line = chars_this_line; - for (; chars_this_line < dump::kCharsPerLine; chars_this_line++) - { - if (chars_this_line % 8 == 0) - { + for (; chars_this_line < dump::kCharsPerLine; chars_this_line++) { + if (chars_this_line % 8 == 0) { printf(" "); } printf(" "); @@ -89,20 +80,15 @@ inline void Dump(const void* data, uint32_t size) chars_this_line = 0; - while (chars_this_line < chars_dot_line) - { - if (chars_this_line % 8 == 0) - { + while (chars_this_line < chars_dot_line) { + if (chars_this_line % 8 == 0) { printf(" "); } int ch = *q; - if (isprint(ch)) - { + if (isprint(ch)) { printf("%c", ch); - } - else - { + } else { printf("."); } diff --git a/common/include/firmware/debug/debug_i2cdetect.h b/common/include/firmware/debug/debug_i2cdetect.h index 663a1686..8a17ad98 100644 --- a/common/include/firmware/debug/debug_i2cdetect.h +++ b/common/include/firmware/debug/debug_i2cdetect.h @@ -44,7 +44,7 @@ void Detect() { puts("\n 0 1 2 3 4 5 6 7 8 9 a b c d e f"); for (uint32_t i = 0; i < 128; i = (i + 16)) { - printf("%02x: ", i); + printf("%02x: ", static_cast(i)); for (uint32_t j = 0; j < 16; j++) { // Skip unwanted addresses if ((i + j < kFirst) || (i + j > kLast)) { @@ -53,7 +53,7 @@ void Detect() { } if (::i2c::IsConnected(static_cast(i + j))) { - printf("%02x ", i + j); + printf("%02x ", static_cast(i + j)); } else { printf("-- "); } diff --git a/common/include/firmware/debug/debug_stack.h b/common/include/firmware/debug/debug_stack.h index ebce1e72..62051178 100755 --- a/common/include/firmware/debug/debug_stack.h +++ b/common/include/firmware/debug/debug_stack.h @@ -45,18 +45,18 @@ inline void Print() { assert(end > start); const auto kSize = static_cast(end - start); - auto* p = start; + const auto* ptr = start; - while (p < end) { - if (*p != kMagicWord) { + while (ptr < end) { + if (*ptr != kMagicWord) { break; } - p++; + ptr++; } - const auto kUsedBytes = static_cast(4 * (end - p)); - const auto kFreeBytes = static_cast(4 * (p - start)); - const auto kFreePct = (static_cast(p - start) * 100U) / kSize; + const auto kUsedBytes = static_cast(4 * (end - ptr)); + const auto kFreeBytes = static_cast(4 * (ptr - start)); + const auto kFreePct = (static_cast(ptr - start) * 100U) / kSize; if (s_used_bytes_previous != kUsedBytes) { s_used_bytes_previous = kUsedBytes; @@ -70,9 +70,9 @@ inline void Print() { } #ifndef NDEBUG - printf("Stack: Size %uKB, [%p:%p:%p], Used: %u, Free: %u [%u]", kSize / (1024 / 4), start, p, end, kUsedBytes, kFreeBytes, kFreePct); + printf("Stack: Size %uKB, [%p:%p:%p], Used: %u, Free: %u [%u]", static_cast(kSize / (1024 / 4)), reinterpret_cast(start), reinterpret_cast(ptr), reinterpret_cast(end), static_cast(kUsedBytes), static_cast(kFreeBytes), static_cast(kFreePct)); #else - printf("Stack: Size %uKB, Used: %u, Free: %u", kSize / (1024 / 4), kUsedBytes, kFreeBytes); + printf("Stack: Size %uKB, Used: %u, Free: %u", static_cast(kSize / (1024 / 4)), static_cast(kUsedBytes), static_cast(kFreeBytes)); #endif printf("\x1b[39m\n"); } @@ -81,7 +81,7 @@ inline void Print() { inline void Run() { static uint32_t s_millis_previous; const auto kMillis = timing::Millis(); - if (kMillis - s_millis_previous >= 1000) { + if (kMillis - s_millis_previous >= 1000U) { s_millis_previous = kMillis; Print(); } diff --git a/common/include/firmware/pixeldmx/show.h b/common/include/firmware/pixeldmx/show.h index b6276026..444171a2 100755 --- a/common/include/firmware/pixeldmx/show.h +++ b/common/include/firmware/pixeldmx/show.h @@ -35,7 +35,7 @@ namespace common::firmware::pixeldmx { inline void Show(uint32_t line, pixelpatterns::Pattern pattern) { - DEBUG_PRINTF("line=%u, pattern=%u", line, static_cast(pattern)); + DEBUG_PRINTF("line=%u, pattern=%u", static_cast(line), static_cast(pattern)); auto& configuration = PixelDmxConfiguration::Get(); auto* display = Display::Get(); @@ -44,8 +44,8 @@ inline void Show(uint32_t line, pixelpatterns::Pattern pattern) { display->ClearEndOfLine(); display->Printf(line, "%s:%d G%d %s", pixel::GetTypeName(configuration.GetType()), - configuration.GetCount(), - configuration.GetGroupingCount(), + static_cast(configuration.GetCount()), + static_cast(configuration.GetGroupingCount()), pixel::GetMapName(configuration.GetMap()) ); @@ -55,7 +55,7 @@ inline void Show(uint32_t line, pixelpatterns::Pattern pattern) { if (pattern != pixelpatterns::Pattern::kNone) { display->Printf(6, "%s:%u", PixelPatterns::GetName(pattern), - static_cast(pattern) + static_cast(pattern) ); } } diff --git a/common/include/global.h b/common/include/global.h index 3851bae5..c227c84d 100644 --- a/common/include/global.h +++ b/common/include/global.h @@ -16,79 +16,51 @@ #include "utc.h" +namespace global { + /** - * @namespace global - * @brief Contains global variables related to time configuration. + * @brief Gets the current UTC offset in seconds. + * @return UTC offset in seconds. */ -namespace global { -extern int32_t g_utc_offset; +inline int32_t GetUtcOffset() { + return global::g_utc_offset; } /** - * @class Global - * @brief Singleton class for managing and validating UTC offsets. - * - * The Global class provides methods to set and get the UTC offset in seconds. - * It also includes validation logic for standard UTC time zones. + * @brief Gets the current UTC offset as (hours, minutes). + * @param[out] hours Signed hour component. + * @param[out] minutes Unsigned minute component. */ -class Global { - public: - /** - * @brief Get the singleton instance of the Global class. - * @return Reference to the singleton Global object. - */ - static Global& Instance() { - static Global instance; - return instance; - } - - /** - * @brief Gets the current UTC offset in seconds. - * @return UTC offset in seconds. - */ - int32_t GetUtcOffset() const { return global::g_utc_offset; } - - /** - * @brief Gets the current UTC offset as (hours, minutes). - * @param[out] hours Signed hour component. - * @param[out] minutes Unsigned minute component. - */ - inline void GetUtcOffset(int32_t& hours, uint32_t& minutes) { utc::SplitOffset(global::g_utc_offset, hours, minutes); } +inline void GetUtcOffset(int32_t& hours, uint32_t& minutes) { + utc::SplitOffset(global::g_utc_offset, hours, minutes); +} - /** - * @brief Sets the global UTC offset if the value is valid. - * @param utc_offset_seconds Offset in seconds - * @return true if successfully set; false otherwise - */ - inline bool SetUtcOffsetIfValid(int32_t utc_offset_seconds) { - if (utc::IsValidOffset(utc_offset_seconds)) { - ::global::g_utc_offset = utc_offset_seconds; - return true; - } - return false; +/** + * @brief Sets the global UTC offset if the value is valid. + * @param utc_offset_seconds Offset in seconds + * @return true if successfully set; false otherwise + */ +inline bool SetUtcOffsetIfValid(int32_t utc_offset_seconds) { + if (utc::IsValidOffset(utc_offset_seconds)) { + ::global::g_utc_offset = utc_offset_seconds; + return true; } + return false; +} - /** - * @brief Sets the global UTC offset from (hours, minutes) if valid. - * @param hours Signed hour component - * @param minutes Unsigned minute component - * @return true if valid and set; false otherwise - */ - inline bool SetUtcOffsetIfValid(int32_t hours, uint32_t minutes) { - int32_t offset_seconds; - if (utc::ValidateOffset(hours, minutes, offset_seconds)) { - return SetUtcOffsetIfValid(offset_seconds); - } - return false; +/** + * @brief Sets the global UTC offset from (hours, minutes) if valid. + * @param hours Signed hour component + * @param minutes Unsigned minute component + * @return true if valid and set; false otherwise + */ +inline bool SetUtcOffsetIfValid(int32_t hours, uint32_t minutes) { + int32_t offset_seconds; + if (utc::ValidateOffset(hours, minutes, offset_seconds)) { + return SetUtcOffsetIfValid(offset_seconds); } - - private: - Global() = default; - // Delete copy/move constructors and assignment operators - Global(const Global&) = delete; - Global& operator=(const Global&) = delete; - Global(Global&&) = delete; - Global& operator=(Global&&) = delete; -}; + return false; +} +} // namespace global #endif // GLOBAL_H_ diff --git a/common/include/json/json_format_helpers.h b/common/include/json/json_format_helpers.h index 54a1a040..8e5f8b19 100755 --- a/common/include/json/json_format_helpers.h +++ b/common/include/json/json_format_helpers.h @@ -34,11 +34,6 @@ namespace format { constexpr size_t kFloatBufferSize = 8; // For "%.2f", "%.1f" constexpr size_t kOffsetBufferSize = 12; // For timezone offsets e.g. "+01:00" -inline void Append2Digits(char*& p, uint32_t v) { - *p++ = static_cast('0' + (v / 10)); - *p++ = static_cast('0' + (v % 10)); -} - inline const char* Float(float value, char (&buf)[kFloatBufferSize], const char* fmt = "%.2f") { snprintf(buf, sizeof(buf), fmt, value); return buf; @@ -46,21 +41,13 @@ inline const char* Float(float value, char (&buf)[kFloatBufferSize], const char* inline const char* UtcOffset(int32_t hours, uint32_t minutes, char (&buf)[kOffsetBufferSize]) { const auto kNegative = hours < 0; - if (kNegative) hours = -hours; - - auto* p = buf; - - if (hours != 0) { - *p++ = kNegative ? '-' : '+'; + if (kNegative) { + hours = -hours; } - - Append2Digits(p, static_cast(hours)); - *p++ = ':'; - Append2Digits(p, minutes); - *p = '\0'; - - assert(static_cast((p - buf) + 1) <= kOffsetBufferSize); - + snprintf(buf, sizeof(buf), "%c%02d:%02d", + kNegative ? '-' : '+', + static_cast(hours), + static_cast(minutes)); return buf; } } // namespace format diff --git a/common/include/json/json_parser.h b/common/include/json/json_parser.h index b5e59c46..08d057d8 100755 --- a/common/include/json/json_parser.h +++ b/common/include/json/json_parser.h @@ -38,19 +38,27 @@ inline void ParseJsonWithTable(const char* buffer, size_t size, const json::Key* JsonTokenizer tok(buffer, size); tok.SkipWhitespace(); - if (tok.p >= tok.end || *tok.p != '{') return; + if (tok.p >= tok.end || *tok.p != '{') { + return; + } ++tok.p; while (tok.p < tok.end) { const char* json_key; size_t json_key_len; - if (!tok.NextString(json_key, json_key_len)) break; + if (!tok.NextString(json_key, json_key_len)) { + break; + } - if (!tok.Expect(':')) break; + if (!tok.Expect(':')) { + break; + } const char* val; size_t val_len; - if (!tok.NextValue(val, val_len)) break; + if (!tok.NextValue(val, val_len)) { + break; + } uint32_t h = Fnv1a32Runtime(json_key, static_cast(json_key_len)); bool matched = false; diff --git a/common/include/utc.h b/common/include/utc.h index 91141ea6..60910de1 100644 --- a/common/include/utc.h +++ b/common/include/utc.h @@ -73,7 +73,7 @@ inline bool ValidateOffset(int32_t hours, uint32_t minutes, int32_t& utc_offset_ } for (const auto& offset : kValidOffsets) { if (offset.hours == hours && offset.minutes == minutes) { - utc_offset_seconds = (hours >= 0) ? (hours * 3600 + static_cast(minutes) * 60) : (hours * 3600 - static_cast(minutes) * 60); + utc_offset_seconds = (hours >= 0) ? ((hours * 3600) + static_cast(minutes) * 60) : (hours * 3600 - static_cast(minutes) * 60); return true; } } @@ -87,7 +87,9 @@ inline bool ValidateOffset(int32_t hours, uint32_t minutes, int32_t& utc_offset_ * @return true if offset is valid; false otherwise */ inline bool IsValidOffset(int32_t utc_offset_seconds) { - if (utc_offset_seconds == 0) return true; + if (utc_offset_seconds == 0) { + return true; + } int32_t hours = utc_offset_seconds / 3600; uint32_t minutes = (utc_offset_seconds >= 0) ? static_cast(utc_offset_seconds - hours * 3600) / 60 : static_cast((hours * 3600 - utc_offset_seconds)) / 60; @@ -96,8 +98,10 @@ inline bool IsValidOffset(int32_t utc_offset_seconds) { } for (const auto& offset : kValidOffsets) { - int32_t offset_seconds = (offset.hours >= 0) ? offset.hours * 3600 + static_cast(offset.minutes * 60) : offset.hours * 3600 - static_cast(offset.minutes * 60); - if (utc_offset_seconds == offset_seconds) return true; + int32_t offset_seconds = (offset.hours >= 0) ? (offset.hours * 3600) + static_cast(offset.minutes * 60) : offset.hours * 3600 - static_cast(offset.minutes * 60); + if (utc_offset_seconds == offset_seconds) { + return true; + } } return false; } @@ -149,9 +153,13 @@ inline bool ParseOffset(const char* buffer, uint32_t buffer_length, int32_t& hou if (buffer[5] < '0' || buffer[5] > '9') return false; int32_t h = (buffer[1] - '0') * 10 + (buffer[2] - '0'); - if (h > 14) return false; + if (h > 14) { + return false; + } uint32_t m = static_cast((buffer[4] - '0') * 10 + (buffer[5] - '0')); - if (m >= 60) return false; + if (m >= 60) { + return false; + } hours = negative ? -h : h; minutes = m; diff --git a/common/make/CppOps.mk b/common/make/CppOps.mk index ed076fc1..ecaada2c 100755 --- a/common/make/CppOps.mk +++ b/common/make/CppOps.mk @@ -1,7 +1,8 @@ $(info "CppOpts.mk") -CPPOPS=-std=c++20 +CPPOPS=-std=c++23 CPPOPS+=-Wnon-virtual-dtor -Woverloaded-virtual -Wnull-dereference -fno-rtti -fno-exceptions -fno-unwind-tables CPPOPS+=-Wuseless-cast -Wold-style-cast CPPOPS+=-fno-threadsafe-statics -fno-use-cxa-atexit -CPPOPS+=-Wshadow -Wshadow=local \ No newline at end of file +CPPOPS+=-Wshadow -Wshadow=local +CPPOPS+=-Dcplusplus \ No newline at end of file diff --git a/common/make/gd32/Gd32FirmwareOps.mk b/common/make/gd32/Gd32FirmwareOps.mk new file mode 100644 index 00000000..518ddbed --- /dev/null +++ b/common/make/gd32/Gd32FirmwareOps.mk @@ -0,0 +1,11 @@ +$(info "Gd32FirmwareOpts.mk") + +GD32FIRMWAREOPS =-Wno-error=unused-parameter +GD32FIRMWAREOPS+=-Wno-error=unused-but-set-variable +GD32FIRMWAREOPS+=-Wno-error=conversion +GD32FIRMWAREOPS+=-Wno-error=old-style-cast +GD32FIRMWAREOPS+=-Wno-error=unused-function +GD32FIRMWAREOPS+=-Wno-error=unused-variable +GD32FIRMWAREOPS+=-Wno-error=duplicated-cond +GD32FIRMWAREOPS+=-Wno-error=missing-field-initializers +GD32FIRMWAREOPS+=-Wno-error=implicit-function-declaration \ No newline at end of file diff --git a/common/make/gd32/Includes.mk b/common/make/gd32/Includes.mk index 8ead6bd3..a8396c5b 100644 --- a/common/make/gd32/Includes.mk +++ b/common/make/gd32/Includes.mk @@ -1,13 +1,14 @@ $(info "Includes.mk") -INCLUDES:=-I./include -INCLUDES+=-I../common/include -I../include -INCLUDES+=-I../firmware-template-gd32/include -INCLUDES+=-I../CMSIS/Core/Include -INCLUDES+=-I../lib-gd32/${FAMILY}/${FAMILY_UC}_standard_peripheral/Include -INCLUDES+=-I../lib-gd32/${FAMILY}/CMSIS/GD/${FAMILY_UC}/Include -INCLUDES+=-I../lib-gd32/include +INCLUDES:=-I../include +INCLUDES+=-isystem ../CMSIS/Core/Include +INCLUDES+=-isystem ../lib-gd32/${FAMILY}/${FAMILY_UC}_standard_peripheral/Include +INCLUDES+=-isystem ../lib-gd32/${FAMILY}/CMSIS/GD/${FAMILY_UC}/Include +INCLUDES+=-isystem ../lib-gd32/include +INCLUDES+=-isystem ../firmware-template-gd32/include +INCLUDES+=-I../common/include INCLUDES+=-I../lib-hwclock/include +INCLUDES+=-I./include INCLUDES+=$(addprefix -I,$(EXTRA_INCLUDES)) @@ -104,5 +105,5 @@ ifdef USB_HOST_MSC INCLUDES+=-I../lib-fatfs endif -INCLUDES:= $(strip -I../${PROJECT}/include $(sort $(INCLUDES))) +#INCLUDES:= $(strip -I../${PROJECT}/include $(sort $(INCLUDES))) $(info $$INCLUDES [${INCLUDES}]) \ No newline at end of file diff --git a/common/make/lib/Objects.mk b/common/make/lib/Objects.mk index 37dfa4d9..7ff3594a 100755 --- a/common/make/lib/Objects.mk +++ b/common/make/lib/Objects.mk @@ -17,3 +17,4 @@ ifneq ($(EXTRA_CPP_SOURCE_FILES),) endif OBJECTS:=$(strip $(ASM_OBJECTS) $(C_OBJECTS) $(CPP_OBJECTS) $(EXTRA_C_OBJECTS) $(EXTRA_CPP_OBJECTS)) +SRCDIR+=$(EXTRA_C_DIRECTORIES) $(EXTRA_CPP_DIRECTORIES) \ No newline at end of file diff --git a/common/scripts/gd32/flash.py b/common/scripts/gd32/flash.py index 1392cacc..7186deed 100755 --- a/common/scripts/gd32/flash.py +++ b/common/scripts/gd32/flash.py @@ -1,43 +1,107 @@ #!/usr/bin/env python3 -import serial -import time -import sys import argparse -import subprocess -import os +import json +import sys +import time from pathlib import Path +import serial + +def load_gd32_db(filename="gd32.json"): + path = Path(__file__).resolve().parent / filename + + if not path.is_file(): + print(f"Warning: device database '{path}' not found.") + return {} + + try: + with path.open("r", encoding="utf-8") as f: + return json.load(f) + except json.JSONDecodeError as e: + print(f"Error parsing '{path}': {e}") + except OSError as e: + print(f"Error reading '{path}': {e}") + + return {} + +def normalize_chip_id(chip_id): + chip_id = str(chip_id).lower() + if chip_id.startswith("0x"): + chip_id = chip_id[2:] + return chip_id.zfill(4) + + +def db_get_family(db, chip_id): + chip_id = normalize_chip_id(chip_id) + + for key, value in db.items(): + if normalize_chip_id(key) == chip_id: + return value + + return None + +def lookup_device(db, chip_id, flash_size_kb, flasher=None): + family = db_get_family(db, chip_id) + if family is None: + return { + "identifier": "Unknown", + "series": "Unknown", + "part_number": "Unknown", + } + + identifier = None + device = family + + if flasher is not None: + identifier = flasher.get_identifier() + + identifiers = family.get("identifiers", {}) + if identifier is not None and isinstance(identifiers, dict): + device = identifiers.get(identifier, family) + + series = device.get("series", family.get("series", "Unknown")) + flash = device.get("flash", family.get("flash", {})) + part_number = flash.get(str(flash_size_kb), "Unknown") + + return { + "identifier": identifier or "Unknown", + "series": series, + "part_number": part_number, + } + + class GD32Flasher: ACK = 0x79 NACK = 0x1F - + CMD_GET = 0x00 CMD_GET_VERSION = 0x01 CMD_GET_ID = 0x02 + CMD_GET_IDENTIFIER = 0x06 CMD_READ_MEMORY = 0x11 CMD_GO = 0x21 CMD_WRITE_MEMORY = 0x31 CMD_ERASE = 0x43 CMD_EXTENDED_ERASE = 0x44 - + def __init__(self, port, baud=57600, timeout=5): self.port_name = port self.baud = baud self.timeout = timeout self.port = None - + def open(self): self.port = serial.Serial( self.port_name, self.baud, parity=serial.PARITY_EVEN, - timeout=self.timeout + timeout=self.timeout, ) self.port.dtr = False self.port.rts = False time.sleep(0.1) - + def close(self): if self.port: self.port.dtr = False @@ -46,64 +110,236 @@ def close(self): self.port.rts = False self.port.close() print("Done. Reset the MCU manually before the next bootloader session.") - + def enter_bootloader(self): - """Enter ROM bootloader mode using DTR/RTS""" print("Entering bootloader mode...") - + for dtr_state in [True, False]: self.port.dtr = dtr_state time.sleep(0.05) - + self.port.rts = True time.sleep(0.1) self.port.rts = False time.sleep(0.3) - + self.port.reset_input_buffer() - + if self._try_sync(): return True - + print(" FAILED: No bootloader response") return False - + def _try_sync(self, attempts=3): - for i in range(attempts): - self.port.write(bytes([0x7F])) - time.sleep(0.1) - resp = self.port.read(1) - if resp and resp[0] == self.ACK: - return True - return False - + original_timeout = self.port.timeout + + try: + for attempt in range(1, attempts + 1): + self.port.reset_input_buffer() + + print(f" Synchronization attempt {attempt}") + self.port.write(b"\x7F") + self.port.flush() + + deadline = time.monotonic() + 1.0 + + while time.monotonic() < deadline: + self.port.timeout = max( + deadline - time.monotonic(), + 0.01 + ) + + response = self.port.read(1) + if not response: + break + + value = response[0] + print(f" Synchronization RX: 0x{value:02X}") + + if value == self.ACK: + return True + + if value == self.NACK: + break + + if value == 0x7F: + # Possible local echo. + continue + + time.sleep(0.05) + + return False + + finally: + self.port.timeout = original_timeout + def _send_command(self, cmd): - self.port.write(bytes([cmd, cmd ^ 0xFF])) - resp = self.port.read(1) - return resp and resp[0] == self.ACK - + command = bytes([cmd, cmd ^ 0xFF]) + + self.port.write(command) + self.port.flush() + + response = self.port.read(1) + + if not response: + print(f" Command 0x{cmd:02X}: timeout") + return False + + if response[0] == self.ACK: + return True + + if response[0] == self.NACK: + print(f" Command 0x{cmd:02X}: NACK") + else: + print( + f" Command 0x{cmd:02X}: unexpected response" + ) + + return False + def _wait_ack(self): resp = self.port.read(1) return resp and resp[0] == self.ACK - + def get_version(self): if not self._send_command(self.CMD_GET_VERSION): return None - version = self.port.read(1)[0] + + version_data = self.port.read(1) + if len(version_data) != 1: + return None + + version = version_data[0] self.port.read(2) self._wait_ack() return version - + def get_id(self): if not self._send_command(self.CMD_GET_ID): return None - n = self.port.read(1)[0] + + n_data = self.port.read(1) + if len(n_data) != 1: + return None + + n = n_data[0] chip_id = self.port.read(n + 1) + if len(chip_id) != n + 1: + return None + self._wait_ack() return chip_id.hex() + + def get_identifier(self): + """Return the four-character GD32 device identifier. + + Command 0x06 may return more than four payload bytes on newer + devices. The first four bytes contain the printable identifier; + any remaining bytes are vendor-specific extension data. + """ + if not self._send_command(self.CMD_GET_IDENTIFIER): + return None + + length_data = self.port.read(1) + if len(length_data) != 1: + print(" Identifier: timeout while reading payload length") + return None + + length = length_data[0] + if length < 4 or length > 32: + print(f" Identifier: invalid payload length {length}") + return None + + payload = self.port.read(length) + if len(payload) != length: + print( + f" Identifier: expected {length} payload bytes, " + f"received {len(payload)}" + ) + return None + + if not self._wait_ack(): + print(" Identifier: missing final ACK") + return None + + identifier_data = payload[:4] + if not all(0x20 <= value <= 0x7E for value in identifier_data): + print( + " Identifier: first four bytes are not printable ASCII: " + + identifier_data.hex(" ").upper() + ) + return None + + identifier = identifier_data.decode("ascii") + + if length > 4: + extension = payload[4:] + print( + f" Identifier payload: {payload.hex(' ').upper()} " + f"(extension: {extension.hex(' ').upper()})" + ) + + return identifier + + def read_memory(self, address, length): + if not 1 <= length <= 256: + raise ValueError("length must be 1..256") + + if not self._send_command(self.CMD_READ_MEMORY): + return None + + addr_bytes = address.to_bytes(4, "big") + checksum = 0 + for b in addr_bytes: + checksum ^= b + + self.port.write(addr_bytes + bytes([checksum])) + + if not self._wait_ack(): + return None + + n = length - 1 + self.port.write(bytes([n, n ^ 0xFF])) + + if not self._wait_ack(): + return None + + data = self.port.read(length) + if len(data) != length: + return None + + return data + + def get_flash_size_kb(self, family): + if family in (0x0410, 0x0414, 0x0440, 0x0418): + flash_size_addr = 0x1FFFF7E0 + elif family == 0x0419: + flash_size_addr = 0x1FFF7A22 + else: + flash_size_addr = 0x1FFF77DE + + data = self.read_memory(flash_size_addr, 2) + if data is None or len(data) != 2: + return None + + return int.from_bytes(data, "little") + + def get_uid(self, family): + if family == 0x0419: + uid_addr = 0x1FFF7A10 + else: + uid_addr = 0x1FFFF7E8 + + data = self.read_memory(uid_addr, 12) + if data is None or len(data) != 12: + return None + return data.hex().upper() + def erase_all(self): print("Erasing flash...") + if not self._send_command(self.CMD_EXTENDED_ERASE): if not self._send_command(self.CMD_ERASE): print(" Erase command not supported") @@ -111,147 +347,228 @@ def erase_all(self): self.port.write(bytes([0xFF, 0x00])) else: self.port.write(bytes([0xFF, 0xFF, 0x00])) - + self.port.timeout = 30 result = self._wait_ack() self.port.timeout = self.timeout + print(" Erase " + ("OK" if result else "FAILED")) return result - + def write_memory(self, address, data): if not self._send_command(self.CMD_WRITE_MEMORY): return False - - addr_bytes = address.to_bytes(4, 'big') + + addr_bytes = address.to_bytes(4, "big") checksum = 0 for b in addr_bytes: checksum ^= b + self.port.write(addr_bytes + bytes([checksum])) - + if not self._wait_ack(): return False - + n = len(data) - 1 checksum = n for b in data: checksum ^= b + self.port.write(bytes([n]) + data + bytes([checksum])) - + return self._wait_ack() - + + def read_u32(self, address): + data = self.read_memory(address, 4) + if data is None or len(data) != 4: + return None + return int.from_bytes(data, "little") + + + def write_u32(self, address, value): + return self.write_memory(address, value.to_bytes(4, "little")) + + + def probe_register_bit(self, address, bit): + mask = 1 << bit + + original = self.read_u32(address) + if original is None: + return None + + if not self.write_u32(address, original | mask): + return None + + changed = self.read_u32(address) + + # Always restore original register value. + self.write_u32(address, original) + + if changed is None: + return None + + return bool(changed & mask) + def flash_file(self, filename, address, label=""): data = Path(filename).read_bytes() prefix = f"[{label}] " if label else "" + print(f"{prefix}Flashing {len(data)} bytes to 0x{address:08X}...") print(f"{prefix}File: {filename}") - + chunk_size = 256 offset = 0 - + while offset < len(data): chunk = data[offset:offset + chunk_size] current_addr = address + offset - + if not self.write_memory(current_addr, chunk): print(f"\n{prefix} Write failed at 0x{current_addr:08X}") return False - + offset += len(chunk) progress = offset * 100 // len(data) - print(f"\r{prefix} Progress: {progress}% ({offset}/{len(data)} bytes)", end='', flush=True) - + print( + f"\r{prefix} Progress: {progress}% ({offset}/{len(data)} bytes)", + end="", + flush=True, + ) + print(f"\n{prefix} Flash complete!") return True - + def run(self, address): print(f"Starting execution at 0x{address:08X}...") + if not self._send_command(self.CMD_GO): return False - - addr_bytes = address.to_bytes(4, 'big') + + addr_bytes = address.to_bytes(4, "big") checksum = 0 for b in addr_bytes: checksum ^= b + self.port.write(addr_bytes + bytes([checksum])) - + return self._wait_ack() +def print_device_info(flasher, gd32_db): + chip_id = flasher.get_id() + if chip_id is None: + print("Failed to read chip ID") + return False + + family = int(chip_id, 16) + size_kb = flasher.get_flash_size_kb(family) + if size_kb is None: + print("Failed to read flash size") + return False + + device = lookup_device(gd32_db, chip_id, size_kb, flasher) + + print(f"Chip ID : {chip_id}") + print(f"Identifier : {device['identifier']}") + + if device: + print(f"Series : {device['series']}") + print(f"Flash size : {size_kb} KB") + print(f"Part number : {device['part_number']}") + else: + print("Series : Unknown") + print(f"Flash size : {size_kb} KB") + print("Part number : Unknown") + + return True + + def start_monitor(port, baud=115200, reset=True): - """Start a UART monitor on the specified port with auto-reconnect""" + """Start a UART monitor on the specified port with auto-reconnect.""" print(f"\n=== Starting UART Monitor on {port} at {baud} baud ===") print("Press Ctrl+C to exit\n") - + ser = None first_connect = True - + try: while True: - # Try to connect/reconnect if ser is None or not ser.is_open: try: ser = serial.Serial(port, baud, timeout=0.1) - + if first_connect: print("[Connected]") else: print("\n[Reconnected]") - - # Set normal boot mode - ser.dtr = True # BOOT0 = low (normal boot from flash) - + + ser.dtr = True # BOOT0 = low, normal boot from flash + if reset and first_connect: print("[Resetting board...]\n") - ser.rts = True # Assert reset + ser.rts = True time.sleep(0.1) - ser.rts = False # Release reset - board boots + ser.rts = False else: ser.rts = False - + first_connect = False - + except serial.SerialException: - # Port not available, wait briefly and retry time.sleep(0.05) continue - - # Read data + try: data = ser.read(1024) if data: try: - text = data.decode('utf-8', errors='replace') - print(text, end='', flush=True) - except: - print(data.hex(), end=' ', flush=True) + text = data.decode("utf-8", errors="replace") + print(text, end="", flush=True) + except UnicodeError: + print(data.hex(), end=" ", flush=True) except (serial.SerialException, OSError): - # Device disconnected print("\n[Disconnected - waiting for reconnect...]", flush=True) try: ser.close() - except: + except serial.SerialException: pass ser = None - + except KeyboardInterrupt: print("\n\nMonitor stopped.") finally: if ser and ser.is_open: ser.close() + def main(): - parser = argparse.ArgumentParser(description='Flash GD32 board') - parser.add_argument('--port', '-p', default='/dev/ttyUSB0', help='Serial port') - parser.add_argument('--baud', '-b', type=int, default=57600, help='Baud rate for flashing') - parser.add_argument('--monitor', action='store_true', help='Start UART monitor') - parser.add_argument('--get-version', action='store_true', help='Read bootloader version') - parser.add_argument('--get-id', action='store_true', help='Read chip ID') - parser.add_argument('--mass-erase', action='store_true', help='Erase entire flash') - parser.add_argument('--flash', metavar='FILE', help='Flash binary file') - parser.add_argument('--address', '-a', type=lambda x: int(x, 0), - default=0x08000000, - help='Flash start address (default: 0x08000000)') - parser.add_argument('--label', default='', help='Optional label for flash output') + parser = argparse.ArgumentParser(description="Flash GD32 board") + parser.add_argument("--port", "-p", default="/dev/ttyUSB0", help="Serial port") + parser.add_argument("--baud", "-b", type=int, default=57600, help="Baud rate for flashing") + parser.add_argument("--monitor", action="store_true", help="Start UART monitor") + parser.add_argument("--get-version", action="store_true", help="Read bootloader version") + parser.add_argument("--get-id", action="store_true", help="Read chip ID") + parser.add_argument("--get-identifier", action="store_true", help="Read device identifier") + parser.add_argument("--get-uid", action="store_true", help="Read chip UID") + parser.add_argument("--get-size", action="store_true", help="Read flash size, series and part number") + parser.add_argument("--db", default="gd32.json", help="GD32 JSON database file") + parser.add_argument("--mass-erase", action="store_true", help="Erase entire flash") + parser.add_argument("--flash", metavar="FILE", help="Flash binary file") + parser.add_argument( + "--address", + "-a", + type=lambda x: int(x, 0), + default=0x08000000, + help="Flash start address (default: 0x08000000)", + ) + parser.add_argument("--label", default="", help="Optional label for flash output") + parser.add_argument("--go", action="store_true", help="Start execution after flashing") + parser.add_argument( + "--go-address", + type=lambda x: int(x, 0), + default=0x08000000, + help="Execution start address for --go (default: 0x08000000)", + ) args = parser.parse_args() @@ -263,14 +580,20 @@ def main(): needs_bootloader = any([ args.get_version, args.get_id, + args.get_identifier, + args.get_uid, + args.get_size, args.mass_erase, - args.flash + args.flash, + args.go, ]) if not needs_bootloader: parser.print_help() return 0 + gd32_db = load_gd32_db(args.db) + flasher = GD32Flasher(args.port, args.baud) flasher.open() @@ -278,19 +601,43 @@ def main(): if not flasher.enter_bootloader(): return 1 + chip_id_already_printed = False + if args.get_version: version = flasher.get_version() if version is None: print("Failed to read bootloader version") - else: - print(f"Bootloader version: 0x{version:02X}") + return 1 + print(f"Bootloader version: 0x{version:02X}") + + if args.get_id and not args.get_size: + chip_id = flasher.get_id() + if chip_id is None: + print("Failed to read chip ID") + return 1 + print(f"Chip ID: {chip_id}") + chip_id_already_printed = True + + if args.get_identifier and not args.get_size: + identifier = flasher.get_identifier() + if identifier is None: + print("Failed to read device identifier") + return 1 + print(f"Identifier: {identifier}") - if args.get_id: + if args.get_size: + if not print_device_info(flasher, gd32_db): + return 1 + chip_id_already_printed = True + + if args.get_uid: chip_id = flasher.get_id() if chip_id is None: print("Failed to read chip ID") - else: - print(f"Chip ID: {chip_id}") + return False + + chip_uid = flasher.get_uid(int(chip_id, 16)) + print(f"Chip UID : {chip_uid}") if args.mass_erase: if not flasher.erase_all(): @@ -300,10 +647,18 @@ def main(): if not flasher.flash_file(args.flash, args.address, args.label): return 1 + if args.go: + if not flasher.run(args.go_address): + return 1 + + # Keep variable useful for future extension and avoid lint warnings in strict editors. + _ = chip_id_already_printed + finally: flasher.close() return 0 - -if __name__ == '__main__': + + +if __name__ == "__main__": sys.exit(main()) diff --git a/common/scripts/gd32/gd32.json b/common/scripts/gd32/gd32.json new file mode 100644 index 00000000..8bd3b9d4 --- /dev/null +++ b/common/scripts/gd32/gd32.json @@ -0,0 +1,56 @@ +{ + "0414": { + "identifiers": { + "3RCF": { + "series": "GD32F303", + "flash": { + "256": "GD32F303RCXX" + } + }, + "3RCB": { + "series": "GD32F103", + "flash": { + "256": "GD32F103RCXX" + } + } + } + }, + "0418": { + "identifiers": { + "7RCB": { + "series": "GD32F107", + "flash": { + "256": "GD32F107RCXX" + } + }, + "7RGC": { + "series": "GD32F207", + "flash": { + "1024": "GD32F207RGXX" + } + } + } + }, + "0419": { + "identifiers": { + "7REE": { + "series": "GD32F407", + "flash": { + "512": "GD32F407REXX" + } + }, + "9VIE": { + "series": "GD32F450", + "flash": { + "2048": "GD32F450VIXX" + } + }, + "0VGN": { + "series": "GD32F470", + "flash": { + "1024": "GD32F470VGXX" + } + } + } + } +} diff --git a/firmware-template-gd32/lib/Rules.mk b/firmware-template-gd32/lib/Rules.mk index 0eceb694..2ba46583 100644 --- a/firmware-template-gd32/lib/Rules.mk +++ b/firmware-template-gd32/lib/Rules.mk @@ -39,6 +39,7 @@ COPS+=-Wconversion endif include ../common/make/CppOps.mk +include ../common/make/gd32/Gd32FirmwareOps.mk BUILD=build_gd32/ BUILD_DIRS:=$(addprefix build_gd32/,$(SRCDIR)) @@ -60,7 +61,7 @@ $(info $$TARGET [${TARGET}]) define compile-objects $(info $1) $(BUILD)$1/%.o: $1/%.c - $(CC) -MD -MP $(COPS) -c $$< -o $$@ + $(CC) -MD -MP $(COPS) $(GD32FIRMWAREOPS) -c $$< -o $$@ $(BUILD)$1/%.o: $1/%.cpp $(CPP) -MD -MP $(COPS) $(CPPOPS) -c $$< -o $$@ @@ -84,9 +85,6 @@ clean: rm -rf build_gd32 rm -rf lib_gd32 -$(BUILD)%.o: %.c - $(CC) $(COPS) -c $< -o $@ - $(TARGET): Makefile.GD32 $(OBJECTS) $(AR) -r $(TARGET) $(OBJECTS) $(PREFIX)objdump -d $(TARGET) | $(PREFIX)c++filt > lib_gd32/lib.list diff --git a/gd32_dmx_usb_pro/.cproject b/gd32_dmx_usb_pro/.cproject index c2fee85c..b314d266 100755 --- a/gd32_dmx_usb_pro/.cproject +++ b/gd32_dmx_usb_pro/.cproject @@ -130,7 +130,6 @@ @@ -350,7 +348,6 @@ - diff --git a/lib-pixeldmx/include/pixeldmxconfiguration.h b/lib-pixeldmx/include/pixeldmxconfiguration.h index 14a3d373..5f07837f 100755 --- a/lib-pixeldmx/include/pixeldmxconfiguration.h +++ b/lib-pixeldmx/include/pixeldmxconfiguration.h @@ -41,10 +41,8 @@ #include "pixelconfiguration.h" #include "pixeltype.h" -namespace pixeldmxconfiguration -{ -struct PortInfo -{ +namespace pixeldmxconfiguration { +struct PortInfo { uint16_t begin_index_port[4]; uint16_t protocol_port_index_last; }; @@ -52,8 +50,7 @@ struct PortInfo class PixelDmxConfiguration : public PixelConfiguration { public: - PixelDmxConfiguration() - { + PixelDmxConfiguration() { DEBUG_ENTRY(); assert(s_this == nullptr); @@ -79,10 +76,8 @@ class PixelDmxConfiguration : public PixelConfiguration { pixeldmxconfiguration::PortInfo& GetPortInfo() { return port_info_; } - void SetDmxStartAddress(uint16_t dmx_start_address) - { - if ((dmx_start_address > 0) && (dmx_start_address <= dmxnode::kUniverseSize)) - { + void SetDmxStartAddress(uint16_t dmx_start_address) { + if ((dmx_start_address > 0) && (dmx_start_address <= dmxnode::kUniverseSize)) { dmx_start_address_ = dmx_start_address; return; } @@ -92,17 +87,13 @@ class PixelDmxConfiguration : public PixelConfiguration { uint16_t GetDmxFootprint() const { return dmx_footprint_; } - void Validate(uint32_t ports_max) - { + void Validate(uint32_t ports_max) { DEBUG_ENTRY(); PixelConfiguration::Validate(); - if (!PixelConfiguration::IsRTZProtocol()) - { - if (!((PixelConfiguration::GetType() == pixel::LedType::kWS2801) || (PixelConfiguration::GetType() == pixel::LedType::kAPA102) || - (PixelConfiguration::GetType() == pixel::LedType::kSK9822))) - { + if (!PixelConfiguration::IsRTZProtocol()) { + if ((PixelConfiguration::GetType() != pixel::LedType::kWS2801) && (PixelConfiguration::GetType() != pixel::LedType::kAPA102) && (PixelConfiguration::GetType() != pixel::LedType::kSK9822)) { PixelConfiguration::SetType(pixel::LedType::kWS2801); } @@ -111,21 +102,17 @@ class PixelDmxConfiguration : public PixelConfiguration { port_info_.begin_index_port[0] = 0; - if (PixelConfiguration::GetType() == pixel::LedType::kSK6812W) - { + if (PixelConfiguration::GetType() == pixel::LedType::kSK6812W) { port_info_.begin_index_port[1] = 128; port_info_.begin_index_port[2] = 256; port_info_.begin_index_port[3] = 384; - } - else - { + } else { port_info_.begin_index_port[1] = 170; port_info_.begin_index_port[2] = 340; port_info_.begin_index_port[3] = 510; } - if ((grouping_count_ == 0) || (grouping_count_ > PixelConfiguration::GetCount())) - { + if ((grouping_count_ == 0) || (grouping_count_ > PixelConfiguration::GetCount())) { grouping_count_ = PixelConfiguration::GetCount(); } @@ -133,14 +120,14 @@ class PixelDmxConfiguration : public PixelConfiguration { output_ports_ = std::min(ports_max, output_ports_); universes_ = (1U + (groups_ / (1U + port_info_.begin_index_port[1]))); dmx_footprint_ = static_cast(PixelConfiguration::GetLedsPerPixel() * groups_); - if (dmx_start_address_ == 0) dmx_start_address_ = dmxnode::kStartAddressDefault; + + if (dmx_start_address_ == 0) { + dmx_start_address_ = dmxnode::kStartAddressDefault; + } - if (ports_max == 1) - { + if (ports_max == 1) { port_info_.protocol_port_index_last = static_cast(groups_ / (1U + port_info_.begin_index_port[1])); - } - else - { + } else { #if defined(NODE_DDP_DISPLAY) port_info_.protocol_port_index_last = static_cast(((output_ports_ - 1U) * 4U) + universes_ - 1U); #else @@ -151,23 +138,26 @@ class PixelDmxConfiguration : public PixelConfiguration { DEBUG_EXIT(); } - void Print() - { + void Print() { PixelConfiguration::Print(); puts("Pixel DMX configuration"); - printf(" Outputs : %u\n", output_ports_); - printf(" Grouping count : %u [Groups : %u]\n", grouping_count_, groups_); - printf(" Universes : %u\n", universes_); - printf(" DmxFootprint : %u\n", dmx_footprint_); + printf(" Outputs : %u\n", static_cast(output_ports_)); + printf(" Grouping count : %u [Groups : %u]\n", static_cast(grouping_count_), static_cast(groups_)); + printf(" Universes : %u\n", static_cast(universes_)); + printf(" DmxFootprint : %u\n", static_cast(dmx_footprint_)); #ifndef NDEBUG const auto& begin_index_port = port_info_.begin_index_port; - printf(" %u:%u:%u:%u -> %u\n", begin_index_port[0], begin_index_port[1], begin_index_port[2], begin_index_port[3], port_info_.protocol_port_index_last); + printf(" %u:%u:%u:%u -> %u\n", + static_cast(begin_index_port[0]), + static_cast(begin_index_port[1]), + static_cast(begin_index_port[2]), + static_cast(begin_index_port[3]), + static_cast(port_info_.protocol_port_index_last)); #endif } - static PixelDmxConfiguration& Get() - { + static PixelDmxConfiguration& Get() { assert(s_this != nullptr); return *s_this; } @@ -184,4 +174,4 @@ class PixelDmxConfiguration : public PixelConfiguration { static inline PixelDmxConfiguration* s_this; }; -#endif // PIXELDMXCONFIGURATION_H_ +#endif // PIXELDMXCONFIGURATION_H_ diff --git a/lib-pixeldmx/src/json/json_status_pixeldmx.cpp b/lib-pixeldmx/src/json/json_status_pixeldmx.cpp index 86890169..870106cf 100755 --- a/lib-pixeldmx/src/json/json_status_pixeldmx.cpp +++ b/lib-pixeldmx/src/json/json_status_pixeldmx.cpp @@ -28,26 +28,24 @@ #include "dmxnode.h" -namespace json::status -{ -uint32_t PixelDmx(char* out_buffer, uint32_t out_buffer_size) -{ +namespace json::status { +uint32_t PixelDmx(char* out_buffer, uint32_t out_buffer_size) { const auto kBufferSize = out_buffer_size - 2U; out_buffer[0] = '{'; uint32_t length = 1; - static_assert(dmxnode::kMaxPorts != 0); + static_assert(dmxnode::kMaxPorts != 0); - for (uint32_t i = 0; i < dmxnode::kMaxPorts; i++) - { + for (uint32_t i = 0; i < dmxnode::kMaxPorts; i++) { length += static_cast(snprintf(&out_buffer[length], kBufferSize - length, - "\"Dmx Output %u\":\"%s\",", - i + 1, - DmxNode::Instance().GetPortName(i))); + "\"Dmx Output %u\":\"%s\",", + static_cast(i + 1), + DmxNode::Instance().GetPortName(i)) + ); } out_buffer[length - 1] = '}'; - + return length; } } // namespace json::status \ No newline at end of file diff --git a/lib-pixeldmx/src/json/pixeldmxparams.cpp b/lib-pixeldmx/src/json/pixeldmxparams.cpp index 70a2883e..2e3f8529 100755 --- a/lib-pixeldmx/src/json/pixeldmxparams.cpp +++ b/lib-pixeldmx/src/json/pixeldmxparams.cpp @@ -120,10 +120,10 @@ void PixelDmxParams::SetSpiSpeedHz(const char* val, uint32_t len) { } void PixelDmxParams::SetGlobalBrightness(const char* val, uint32_t len) { - uint8_t v; + uint8_t value; - if (ParseInRange(val, len, 0U, 255U, &v)) { - store_dmxled.global_brightness = v; + if (ParseInRange(val, len, 0U, 255U, &value)) { + store_dmxled.global_brightness = value; } } @@ -135,8 +135,7 @@ void PixelDmxParams::SetStartUniPort(const char* key, uint32_t key_len, const ch index += 10; } - auto v = ParseValue(val, val_len); - store_dmxled.start_universe[index] = v; + store_dmxled.start_universe[index] = ParseValue(val, val_len); } #if defined(RDM_RESPONDER) @@ -216,7 +215,11 @@ void PixelDmxParams::Set() { DmxNodeNodeType::Get()->SetDirection(protocol_port_index, dmxnode::Direction::kOutput); char label[dmxnode::kPortNameLength]; - snprintf(label, dmxnode::kPortNameLength - 1, "Pixel %c -> %u:%u", static_cast('A' + pixel_port_index), protocol_port_index, kStartUniverse + universe); + snprintf(label, dmxnode::kPortNameLength - 1, "Pixel %c -> %u:%u", + static_cast('A' + pixel_port_index), + static_cast(protocol_port_index), + static_cast(kStartUniverse + universe) + ); DmxNode::Instance().SetShortName(protocol_port_index, label); } protocol_port_index++; @@ -266,19 +269,19 @@ void PixelDmxParams::Dump() { printf(" %s=%.2f [0x%X]\n", DmxLedParamsConst::kT0H.name, pixel::ConvertTxH(store_dmxled.low_code), store_dmxled.low_code); printf(" %s=%.2f [0x%X]\n", DmxLedParamsConst::kT1H.name, pixel::ConvertTxH(store_dmxled.high_code), store_dmxled.high_code); printf(" %s=%s\n", DmxLedParamsConst::kMap.name, pixel::GetMapName(common::FromValue(store_dmxled.map))); - printf(" %s=%u\n", DmxLedParamsConst::kCount.name, store_dmxled.count); - printf(" %s=%u\n", DmxLedParamsConst::kGroupingCount.name, store_dmxled.grouping_count); + printf(" %s=%u\n", DmxLedParamsConst::kCount.name, static_cast(store_dmxled.count)); + printf(" %s=%u\n", DmxLedParamsConst::kGroupingCount.name, static_cast(store_dmxled.grouping_count)); for (uint32_t i = 0; i < kMaxStartUniverses; i++) { printf(" %s=%d\n", PixelDmxParamsConst::kStartUniPort[i].name, store_dmxled.start_universe[i]); } #if defined(OUTPUT_DMX_PIXEL_MULTI) printf(" %s=%d\n", DmxLedParamsConst::kActiveOutputPorts.name, store_dmxled.active_outputs); #endif - printf(" %s=%d\n", DmxLedParamsConst::kTestPattern.name, store_dmxled.test_pattern); - printf(" %s=%u\n", DmxLedParamsConst::kSpiSpeedHz.name, store_dmxled.spi_speed_hz); - printf(" %s=%d\n", DmxLedParamsConst::kGlobalBrightness.name, store_dmxled.global_brightness); + printf(" %s=%u\n", DmxLedParamsConst::kTestPattern.name, static_cast(store_dmxled.test_pattern)); + printf(" %s=%u\n", DmxLedParamsConst::kSpiSpeedHz.name, static_cast(store_dmxled.spi_speed_hz)); + printf(" %s=%u\n", DmxLedParamsConst::kGlobalBrightness.name, static_cast(store_dmxled.global_brightness)); #if defined(RDM_RESPONDER) - printf(" %s=%d\n", PixelDmxParamsConst::kDmxStartAddress.name, store_dmxled.dmx_start_address); + printf(" %s=%u\n", PixelDmxParamsConst::kDmxStartAddress.name, static_cast(store_dmxled.dmx_start_address)); #endif #if defined(CONFIG_PIXELDMX_ENABLE_GAMMATABLE) printf(" %s=%d\n", DmxLedParamsConst::kGammaCorrection.name, common::IsFlagSet(store_dmxled.flags, Flags::Flag::kEnableGamma)); diff --git a/lib-rdm/.cproject b/lib-rdm/.cproject index f19d254a..c696228c 100644 --- a/lib-rdm/.cproject +++ b/lib-rdm/.cproject @@ -38,13 +38,11 @@