### Create ESP32 DCC Project from Example Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Creates a new ESP32 project from a specific DCC library example using the IDF Frontend tool. Ensure the correct path and version are specified. ```sh idf.py create-project-from-example "zimo-elektronik/dcc^0.0.46.5:esp32" ``` -------------------------------- ### Build DCC REPL Example Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Builds the DCC REPL example using CMake. This example allows sending commands from a simulated command station to a simulated decoder. ```sh cmake -Bbuild cmake --build build --target DCCRepl ``` -------------------------------- ### Install DCC with FetchContent Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Use CMake's FetchContent module to download and include the DCC library. ```cmake FetchContent_Declare( DCC GIT_REPOSITORY "https://github.com/ZIMO-Elektronik/DCC" GIT_TAG v0.0.46.5) target_link_libraries(YourTarget PRIVATE DCC::DCC) ``` -------------------------------- ### ESP32 DCC Project CMake Configuration Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/esp32/CMakeLists.txt This snippet configures the CMake build system for an ESP32 project. It sets the minimum required CMake version, includes the ESP-IDF project setup script, and defines the project name and supported languages (ASM, C, CXX). ```cmake cmake_minimum_required(VERSION 3.25) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(DCCEsp32Rmt LANGUAGES ASM C CXX) ``` -------------------------------- ### DCC REPL Set Speed and Direction Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Example commands to set the speed to level 10 in reverse direction and then read CV byte 22. Note the different ways to set speed and direction. ```sh dcc> direction_speed 0 10 dcc> Read CV byte 28==2 dcc> Address 3: set direction backward dcc> Address 3: set speed 18 ``` -------------------------------- ### Install DCC with CPM Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Include the DCC library using the CPM package manager in your CMake project. ```cmake cpmaddpackage("gh:ZIMO-Elektronik/DCC@0.0.46.5") ``` -------------------------------- ### DCCypher JavaScript Module Configuration Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/index.html Configures the Emscripten JavaScript module, including pre- and post-run hooks, print/printErr functions, canvas element selection, status monitoring, and run dependency management. This setup is essential for initializing and interacting with the DCCypher application in a web browser. ```javascript var Module = { preRun: [], postRun: [], print: (function () { return function (text) { text = Array.prototype.slice.call(arguments).join(' '); console.log(text); }; })(), printErr: function (text) { text = Array.prototype.slice.call(arguments).join(' '); console.error(text); }, canvas: (function () { var canvas = document.getElementById('canvas'); //canvas.addEventListener("webglcontextlost", function(e) { alert('FIXME: WebGL context lost, please reload the page'); e.preventDefault(); }, false); return canvas; })(), setStatus: function (text) { console.log("status: " + text); }, monitorRunDependencies: function (left) { // no run dependencies to log } }; window.onerror = function () { console.log("onerror: " + event); }; {{{ SCRIPT }}} ``` -------------------------------- ### Initialize Command Station with Track Signal Configuration Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Configure the track signal by calling the init method with parameters for preamble bits, bit durations, and BiDi cutout. An optional packet can be provided for when the deque is empty. ```cpp // Initializing the command station is mandatory command_station.init({.num_preamble = 17u, .bit1_duration = 58u, .bit0_duration = 100u, .flags = {.bidi = true}}); // Optionally, you can also specify the packet that should be sent as soon as the internal deque is empty (e.g. reset for service mode) command_station.init({.num_preamble = 17u, .bit1_duration = 58u, .bit0_duration = 100u, .flags = {.bidi = false}}, dcc::make_reset_packet()); ``` -------------------------------- ### Download and Configure Code Formatting Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Downloads the .clang-format configuration file from a GitHub raw URL and adds a target to format source files using clang-format. ```cmake if(PROJECT_IS_TOP_LEVEL) include(CTest) add_subdirectory(examples) file( DOWNLOAD "https://github.com/ZIMO-Elektronik/.github/raw/master/data/.clang-format" ${CMAKE_CURRENT_LIST_DIR}/.clang-format) file(GLOB_RECURSE SRC examples/*.[ch]pp include/*.[ch]pp src/*.[ch]pp tests/*.[ch]pp) add_clang_format_target(DCCFormat OPTIONS -i FILES ${SRC}) add_include_what_you_must_target(DCCIncludeWhatYouMust TARGET DCC EXCLUDE_HEADERS "rmt_dcc_encoder.h") endif() ``` -------------------------------- ### DCC REPL Help Command Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Lists available commands in the DCC REPL. Use 'help' to see all possible operations. ```sh ./build/examples/repl/DCCRepl dcc> help ``` -------------------------------- ### Build ImGui Library Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/CMakeLists.txt Compiles ImGui as a static library, including its source files and backend implementations for OpenGL and SDL2. ```cmake file(GLOB SRC ${imgui_SOURCE_DIR}/*.cpp) add_library( imgui STATIC ${SRC} ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp ${imgui_SOURCE_DIR}/backends/imgui_impl_sdl2.cpp) target_include_directories( imgui SYSTEM PUBLIC ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends ${imgui_SOURCE_DIR}/examples/libs) ``` -------------------------------- ### Build ImPlot Library Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/CMakeLists.txt Compiles ImPlot as a static library, including its source files and setting up include directories and linking against ImGui. ```cmake file(GLOB SRC ${implot_SOURCE_DIR}/*.cpp) add_library(implot STATIC ${SRC}) target_include_directories(implot SYSTEM PUBLIC ${implot_SOURCE_DIR}) target_link_libraries(implot PUBLIC imgui) ``` -------------------------------- ### Configure SDL2 and OpenGL for Host System Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/CMakeLists.txt For the host system, this block adds the SDL2 dependency and finds the OpenGL package. ```cmake if(CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME) # On host, build SDL2 and find OpenGL cpmaddpackage( NAME SDL VERSION 2.32.8 GIT_TAG release-2.32.8 GITHUB_REPOSITORY "libsdl-org/SDL" SYSTEM YES) find_package(OpenGL REQUIRED) elseif(CMAKE_SYSTEM_NAME STREQUAL Emscripten) # ... neither of those things are necessary for Emscripten set_target_properties(DCCypher PROPERTIES SUFFIX .html OUTPUT_NAME index) target_compile_definitions( imgui PUBLIC IMGUI_IMPL_OPENGL_ES2 # Default definition ain't compatible with Emscripten ImTextureID=unsigned int) target_compile_options(imgui PUBLIC "-sUSE_SDL=2") target_link_options( imgui PUBLIC "--shell-file=${CMAKE_CURRENT_LIST_DIR}/index.html" "-sALLOW_MEMORY_GROWTH=1" "-sFULL_ES3=1" "-sUSE_SDL=2" "-sUSE_WEBGL2=1") endif() ``` -------------------------------- ### Build STM32 DCC Decoder and Command Station Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Builds both the DCC decoder and command station firmwares for STM32 platforms using CMake. Requires specific architecture and toolchain configurations. ```sh cmake -Bbuild -GNinja -DARCH="-mcpu=cortex-m7 -mfloat-abi=hard" -DCMAKE_TOOLCHAIN_FILE=CMakeModules/cmake/toolchain-arm-none-eabi-gcc.cmake cmake --build build --target DCCStm32Decoder DCCStm32CommandStation ``` -------------------------------- ### DCC REPL Available Commands Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Displays the list of commands available in the DCC REPL, including their syntax and purpose. ```sh Commands available: - help This help message - exit Quit the session - address
Set address all commands are sent to - direction_speed Set direction and speed - f4-f0 Functions F4-F0 - f8-f5 Functions F8-F5 - read_cv_byte Read CV byte - write_cv_byte Write CV byte - read_cv_bit Read CV bit - write_cv_bit Write CV bit ``` -------------------------------- ### Find Source Files and Define Executable Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/repl/CMakeLists.txt Uses GLOB_RECURSE to find all .cpp files in the src directory and adds them to the DCCRepl executable target. ```cmake file(GLOB_RECURSE SRC src/*.cpp) add_executable(DCCRepl ${SRC}) ``` -------------------------------- ### Optional Asynchronous CV Operations and BiDi Control Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Implement optional asynchronous CV read/write methods with callbacks for non-blocking operations. Control high-current BiDi and set east-west direction if needed. ```cpp // Read CV asynchronously void readCv(uint32_t cv_addr, uint8_t byte, std::function cb); ``` ```cpp // Write CV asynchronously void writeCv(uint32_t cv_addr, uint8_t byte, std::function cb); ``` ```cpp // High-current BiDi void highCurrentBiDi(bool high_current); ``` ```cpp // Set east-west direction void eastWestDirection(uint32_t addr, std::optional dir); ``` -------------------------------- ### Link Libraries for ImGui Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/CMakeLists.txt Links the necessary libraries for ImGui, conditionally including OpenGL for the host system. ```cmake target_link_libraries( imgui PUBLIC SDL2 "<$:OpenGL::OpenGL>" ``` -------------------------------- ### Project Definition and Versioning Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Defines the main project 'DCC' with its version obtained from Git. It specifies the programming languages used in the project. ```cmake version_from_git() project( DCC VERSION ${VERSION_FROM_GIT} LANGUAGES ASM C CXX) ``` -------------------------------- ### Add ImGui Dependency using CPM Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/CMakeLists.txt Adds the ImGui library as a dependency using the CPM (CMake Package Manager) method, specifying the GitHub repository, version, and tag. ```cmake # imgui still doesn't come with a CMakeLists.txt *sigh* cpmaddpackage( NAME imgui GITHUB_REPOSITORY "ocornut/imgui" VERSION 1.91.9b GIT_TAG v1.91.9b-docking DOWNLOAD_ONLY TRUE) ``` -------------------------------- ### Define Executable and Compile Definitions Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/CMakeLists.txt Defines the main executable for DCCypher and sets necessary compile definitions, including version information and ImGui operator definitions. ```cmake file(GLOB_RECURSE SRC src/*.cpp) add_executable(DCCypher ${SRC}) target_compile_definitions( DCCypher PRIVATE DCC_CYPHER_VERSION="${PROJECT_VERSION}" IMGUI_DEFINE_MATH_OPERATORS) ``` -------------------------------- ### Initialize ESP32 RMT DCC Encoder Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Configure and create a new instance of the RMT DCC encoder. Ensure the ESP-IDF framework is set up. The `dcc_encoder_config_t` struct allows fine-tuning of DCC signal timing parameters. ```c #include dcc_encoder_config_t encoder_config{.num_preamble = 17u, .bidibit_duration = 60u, .bit1_duration = 58u, .bit0_duration = 100u, .endbit_duration = 58u - 24u, .flags{.level0 = false, .zimo0 = true}}; rmt_encoder_handle_t* encoder; ESP_ERROR_CHECK(rmt_new_dcc_encoder(&encoder_config, &encoder)); ``` -------------------------------- ### Configure DCC Target Include Directories and Warnings Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Sets include directories and common warnings/errors for the DCC target. It differentiates between top-level project inclusion and system inclusion. ```cmake if(PROJECT_IS_TOP_LEVEL AND NOT ESP_PLATFORM) target_include_directories(DCC INTERFACE include) target_common_warnings(DCC INTERFACE) target_common_errors(DCC INTERFACE -Wfatal-errors) else() target_include_directories(DCC SYSTEM INTERFACE include) endif() ``` -------------------------------- ### Initialize DCC Decoder Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Mandatory initialization step after instantiating the decoder class. This triggers CV reads to determine configuration like address and speed steps. ```cpp // Initializing the decoder is mandatory decoder.init(); ``` -------------------------------- ### Add STM32CubeH7 Package Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/stm32/CMakeLists.txt Adds the STM32CubeH7 HAL driver package from a GitHub repository. This is typically the first step in setting up the STM32 environment. ```cmake cpmaddpackage("gh:STMicroelectronics/STM32CubeH7@1.12.1") ``` -------------------------------- ### Link Libraries to Executable Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/repl/CMakeLists.txt Links the 'cli::cli' and 'DCC::DCC' libraries to the DCCRepl executable. ```cmake target_link_libraries(DCCRepl PRIVATE cli::cli DCC::DCC) ``` -------------------------------- ### Define Command Station Structure Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Derive from dcc::tx::CrtpBase to implement a DCC command station. Implementations for track outputs, packet end, and BiDi callbacks are optional. ```cpp #include struct CommandStation : dcc::tx::CrtpBase { friend dcc::tx::CrtpBase; private: // Write track outputs void trackOutputs(bool N, bool P); // Packet end void packetEnd(); // BiDi start void biDiStart(); // BiDi channel 1 void biDiChannel1(); // BiDi channel 2 void biDiChannel2(); // BiDi end void biDiEnd(); }; ``` -------------------------------- ### Manage 'cli' Dependency with CPM Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/repl/CMakeLists.txt Ensures the 'cli' library is available by adding it as a package using CPM if it's not already a target. Fetches version 2.2.0 from GitHub. ```cmake if(NOT TARGET cli::cli) cpmaddpackage("gh:daniele77/cli@2.2.0") endif() ``` -------------------------------- ### DCC Configuration Options Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Sets various configuration options for the DCC component, including standard compliance, manufacturer ID, packet sizes, and timing parameters for both receiver and transmitter. These options can be customized via CMake cache. ```cmake option(DCC_STANDARD_COMPLIANCE "Standard compliance" OFF) set(DCC_MANUFACTURER_ID 145u CACHE STRING "Manufacturer ID") set(DCC_MAX_PACKET_SIZE 18u CACHE STRING "Maximum size of a packet in bytes") set(DCC_RX_LOGON_DID_CV_ADDRESS 249u CACHE STRING "First CV address of decoder ID") set(DCC_RX_LOGON_CID_CV_ADDRESS 65296u CACHE STRING "First CV address of last CID") set(DCC_RX_LOGON_SID_CV_ADDRESS 65298u CACHE STRING "First CV address of last SID") set(DCC_RX_LOGON_ADDRESS_CV_ADDRESS 65299u CACHE STRING "First CV address of last logon address") set(DCC_RX_MIN_PREAMBLE_BITS 10u CACHE STRING "Minimum number of preamble bits of decoder") set(DCC_RX_MIN_BIT_1_TIMING 52u CACHE STRING "Minimum duration of a 1 bit of decoder") set(DCC_RX_MAX_BIT_1_TIMING 64u CACHE STRING "Maximum duration of a 1 bit of decoder") set(DCC_RX_MIN_BIT_0_TIMING 90u CACHE STRING "Minimum duration of a 0 bit of decoder") set(DCC_RX_MAX_BIT_0_TIMING 119u CACHE STRING "Maximum duration of a 0 bit of decoder") set(DCC_RX_DEQUE_SIZE 31u CACHE STRING "Size of the receiver deque of decoder") set(DCC_RX_BIDI_DEQUE_SIZE 7u CACHE STRING "Size of the sender deque of decoder") set(DCC_TX_MIN_PREAMBLE_BITS 17u CACHE STRING "Minimum number of preamble bits of command station") set(DCC_TX_MAX_PREAMBLE_BITS 30u CACHE STRING "Maximum number of preamble bits of command station") set(DCC_TX_MIN_BIT_1_TIMING 56u CACHE STRING "Minimum duration of a 1 bit of command station") set(DCC_TX_MAX_BIT_1_TIMING 60u CACHE STRING "Maximum duration of a 1 bit of command station") set(DCC_TX_MIN_BIT_0_TIMING 97u CACHE STRING "Minimum duration of a 0 bit of command station") set(DCC_TX_MAX_BIT_0_TIMING 114u CACHE STRING "Maximum duration of a 0 bit of command station") set(DCC_TX_MIN_BIDI_BIT_TIMING 57u CACHE STRING "Minimum duration of a BiDi bit of command station") set(DCC_TX_MAX_BIDI_BIT_TIMING 61u CACHE STRING "Maximum duration of a BiDi bit of command station") set(DCC_TX_DEQUE_SIZE 3u CACHE STRING "Size of the transmitter deque of command station") ``` -------------------------------- ### Link Final Libraries to DCCypher Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/CMakeLists.txt Links the ImGui and ImPlot libraries, along with the DCC library, to the main DCCypher executable. ```cmake target_link_libraries(DCCypher PRIVATE DCC::DCC imgui implot) ``` -------------------------------- ### Add ZTL Package via CPM Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Adds the ZTL package using CPM from a GitHub repository. This is a shorthand for adding a package directly from a GitHub URL. ```cmake if(NOT TARGET ZTL::ZTL) cpmaddpackage("gh:ZIMO-Elektronik/ZTL@0.25.0") endif() ``` -------------------------------- ### Add STM32 Targets Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/stm32/CMakeLists.txt Calls the defined `add_stm32_target` function to create specific build targets for the decoder and command station. ```cmake add_stm32_target(DCCStm32Decoder) ``` ```cmake add_stm32_target(DCCStm32CommandStation) ``` -------------------------------- ### External CMake Modules Fetching Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Fetches the 'CMakeModules' from a Git repository to manage external build configurations. This ensures consistent build settings across different projects. ```cmake FetchContent_Declare( CMakeModules GIT_REPOSITORY "https://github.com/ZIMO-Elektronik/CMakeModules" GIT_TAG v0.12.3 SOURCE_DIR ${CMAKE_BINARY_DIR}/CMakeModules) FetchContent_MakeAvailable(CMakeModules) ``` -------------------------------- ### Add ImPlot Dependency using CPM Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/CMakeLists.txt Adds the ImPlot library as a dependency using CPM, specifying the GitHub repository and version. Note: This only supports ImGui versions prior to 1.92.0. ```cmake # Only supports imgui < 1.92.0 cpmaddpackage( NAME implot GITHUB_REPOSITORY "epezent/implot" VERSION 0.16 DOWNLOAD_ONLY TRUE) ``` -------------------------------- ### Add static_math Package via CPM Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Adds the static_math package using CPM. It specifies the GitHub repository, tag, and build options to disable tests and set a minimum CMake policy. ```cmake if(NOT TARGET static_math) cpmaddpackage( NAME static_math GITHUB_REPOSITORY "Morwenn/static_math" GIT_TAG master SYSTEM YES OPTIONS "STATIC_MATH_BUILD_TESTS OFF" "CMAKE_POLICY_VERSION_MINIMUM 3.5") endif() ``` -------------------------------- ### Apply Common Compiler Warnings and Errors Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/repl/CMakeLists.txt Applies standard warning and error flags to the DCCRepl target for improved code quality. ```cmake target_common_warnings(DCCRepl PRIVATE) target_common_errors(DCCRepl PRIVATE) ``` -------------------------------- ### DCC Compile Definitions Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Sets compile definitions for the DCC component, passing configured options and parameters directly into the C++ preprocessor. This allows for compile-time customization of DCC behavior. ```cmake target_compile_definitions( DCC INTERFACE DCC_STANDARD_COMPLIANCE=$ DCC_MANUFACTURER_ID=${DCC_MANUFACTURER_ID} DCC_MAX_PACKET_SIZE=${DCC_MAX_PACKET_SIZE} DCC_RX_LOGON_DID_CV_ADDRESS=${DCC_RX_LOGON_DID_CV_ADDRESS} DCC_RX_LOGON_CID_CV_ADDRESS=${DCC_RX_LOGON_CID_CV_ADDRESS} DCC_RX_LOGON_SID_CV_ADDRESS=${DCC_RX_LOGON_SID_CV_ADDRESS} DCC_RX_LOGON_ADDRESS_CV_ADDRESS=${DCC_RX_LOGON_ADDRESS_CV_ADDRESS} DCC_RX_MIN_PREAMBLE_BITS=${DCC_RX_MIN_PREAMBLE_BITS} DCC_RX_MIN_BIT_1_TIMING=${DCC_RX_MIN_BIT_1_TIMING} DCC_RX_MAX_BIT_1_TIMING=${DCC_RX_MAX_BIT_1_TIMING} DCC_RX_MIN_BIT_0_TIMING=${DCC_RX_MIN_BIT_0_TIMING} DCC_RX_MAX_BIT_0_TIMING=${DCC_RX_MAX_BIT_0_TIMING} DCC_RX_DEQUE_SIZE=${DCC_RX_DEQUE_SIZE} DCC_RX_BIDI_DEQUE_SIZE=${DCC_RX_BIDI_DEQUE_SIZE} DCC_TX_MIN_PREAMBLE_BITS=${DCC_TX_MIN_PREAMBLE_BITS} DCC_TX_MAX_PREAMBLE_BITS=${DCC_TX_MAX_PREAMBLE_BITS} DCC_TX_MIN_BIT_1_TIMING=${DCC_TX_MIN_BIT_1_TIMING} DCC_TX_MAX_BIT_1_TIMING=${DCC_TX_MAX_BIT_1_TIMING} DCC_TX_MIN_BIT_0_TIMING=${DCC_TX_MIN_BIT_0_TIMING} DCC_TX_MAX_BIT_0_TIMING=${DCC_TX_MAX_BIT_0_TIMING} DCC_TX_MIN_BIDI_BIT_TIMING=${DCC_TX_MIN_BIDI_BIT_TIMING} DCC_TX_MAX_BIDI_BIT_TIMING=${DCC_TX_MAX_BIDI_BIT_TIMING} DCC_TX_DEQUE_SIZE=${DCC_TX_DEQUE_SIZE}) ``` -------------------------------- ### Add DCC as an ESP-IDF Component Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Add the DCC library as a dependency in your ESP-IDF project's idf_component.yml file. ```yaml dependencies: zimo-elektronik/dcc: version: "0.0.46.5" ``` -------------------------------- ### Configure DCC Receiver Deque Size Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Set the DCC_RX_DEQUE_SIZE option in CMake to configure the receiver deque length. This can be adjusted based on RAM availability and command processing speed. ```cmake set(DCC_RX_DEQUE_SIZE 8u CACHE STRING "" FORCE) ``` -------------------------------- ### Link Libraries to DCC Target Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Links the static_math and ZTL::ZTL libraries to the DCC target. This makes the functionality of these libraries available to the DCC target. ```cmake target_link_libraries(DCC INTERFACE static_math ZTL::ZTL) ``` -------------------------------- ### BiDi Dissector for RailCom Feedback Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Use the dcc::bidi::Dissector class to iterate over BiDi datagrams received from RailCom. The dissector can be initialized with received datagrams and the last sent packet. Dereferencing the iterator returns a std::variant of possible datagram types. ```cpp // Last sent packet dcc::Packet packet{0x03u, 0xA0u, 0xA3u}; // Received datagram dcc::bidi::Datagram<> datagram{0x99u, 0xA5u, 0x59u, 0x2Eu, 0xD2u, 0x00u, 0x00u, 0x00u}; // Create dissector Dissector dissector{datagram, packet}; // Iterate for (auto const& dg : dissector) if (auto ack{get_if(&dg)}) { // Use Ack here } if (auto adr_low{get_if(&dg)}) { // Use app:adr_low data here } else if (auto dyn{get_if(&dg)}) { // Use app:dyn data here } // else if... ``` -------------------------------- ### Add Test Subdirectory Conditionally Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Adds the 'tests' subdirectory to the build if testing is enabled, the project is the top-level project, and the build system is native. ```cmake if(BUILD_TESTING AND PROJECT_IS_TOP_LEVEL AND CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME) add_subdirectory(tests) endif() ``` -------------------------------- ### ESP Platform Component Registration Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Registers the DCC encoder component for ESP platforms, specifying source files, include directories, and required components. It also handles potential conflicts with the RMT driver version. ```cmake cmake_minimum_required(VERSION 3.25 FATAL_ERROR) include(FetchContent) if(ESP_PLATFORM) # >5.3.0 requires esp_driver_rmt if(IDF_VERSION_MAJOR GREATER 5 OR (IDF_VERSION_MAJOR EQUAL 5 AND IDF_VERSION_MINOR GREATER_EQUAL 3)) set(ESP_DRIVER_RMT_COMPONENT esp_driver_rmt) endif() idf_component_register( SRCS src/rmt_dcc_encoder.c INCLUDE_DIRS include REQUIRES driver ${ESP_DRIVER_RMT_COMPONENT}) # Change OUTPUT_NAME from DCC to lib__idf_DCC to avoid conflicts set_target_properties(${COMPONENT_LIB} PROPERTIES PREFIX "") set_target_properties( ${COMPONENT_LIB} PROPERTIES OUTPUT_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}${COMPONENT_LIB}) target_link_libraries(${COMPONENT_LIB} PUBLIC DCC) endif() ``` -------------------------------- ### DCCypher Emscripten Styling Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/cypher/index.html Provides CSS for Emscripten canvas elements to ensure proper display and performance in a web environment. This styling is crucial for the DCCypher application running in the browser. ```css DCCypher body { margin: 0; background-color: black } /* FIXME: with our GLFW example this block seems to break resizing and io.DisplaySize gets stuck */ .emscripten { position: absolute; top: 0px; left: 0px; margin: 0px; border: 0; width: 100%; height: 100%; overflow: hidden; display: block; image-rendering: optimizeSpeed; image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; image-rendering: optimize-contrast; image-rendering: crisp-edges; image-rendering: pixelated; -ms-interpolation-mode: nearest-neighbor; } ``` -------------------------------- ### Conditional Subdirectory Inclusion in CMake Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/CMakeLists.txt This snippet demonstrates conditional logic in CMake to include subdirectories based on the system name or platform. It's used to manage different build configurations for various target environments. ```cmake if(ESP_PLATFORM) # ESP32 example gets automatically included by component manager # https://docs.espressif.com/projects/idf-component-manager/en/latest/reference/manifest_file.html#examples elseif(CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL Emscripten) add_subdirectory(cypher) add_subdirectory(repl) else() add_subdirectory(stm32) endif() ``` -------------------------------- ### DCC Decoder Interface Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Define the interface for a DCC decoder by deriving from dcc::rx::CrtpBase and implementing the required methods. Friend declarations are necessary if base class methods are not public. ```cpp #include struct Decoder : dcc::rx::CrtpBase { friend dcc::rx::CrtpBase; private: // Set direction (1 forward, 0 backward) void direction(uint16_t addr, bool dir); // Set speed [-1, 255] (regardless of CV settings) void speed(uint16_t addr, int32_t speed); // Set function inputs void function(uint16_t addr, uint32_t mask, uint32_t state); // Enter or exit service mode void serviceModeHook(bool service_mode); // Generate current pulse as service ACK void serviceAck(); // Transmit BiDi void transmitBiDi(std::span bytes); // Read CV uint8_t readCv(uint32_t cv_addr, uint8_t byte = 0u); // Write CV uint8_t writeCv(uint32_t cv_addr, uint8_t byte); // Read CV bit bool readCv(uint32_t cv_addr, bool bit, uint32_t pos); // Write CV bit bool writeCv(uint32_t cv_addr, bool bit, uint32_t pos); }; ``` -------------------------------- ### DCC Library Definition and Aliasing Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Defines the DCC library as an interface library and creates an alias 'DCC::DCC' for it. This simplifies linking the DCC component in other CMake projects. ```cmake add_library(DCC INTERFACE) add_library(DCC::DCC ALIAS DCC) ``` -------------------------------- ### Implement Timer Interrupt Handler for DCC Signal Generation Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md The transmit method returns the next timer period. Reload the hardware timer with this value in the interrupt handler to maintain DCC signal timings. Assign a high priority to this interrupt. ```cpp // Timer interrupt handler void isr() { auto const arr{command_station.transmit()}; // Get next timer period TIM->ARR = arr; // Set timer period register } ``` -------------------------------- ### C++ Standard Feature Requirement Source: https://github.com/zimo-elektronik/dcc/blob/master/CMakeLists.txt Specifies that the DCC component requires C++23 standard features for compilation. This ensures that the code utilizes modern C++ capabilities. ```cmake target_compile_features(DCC INTERFACE cxx_std_23) ``` -------------------------------- ### Define STM32 Target Function Source: https://github.com/zimo-elektronik/dcc/blob/master/examples/stm32/CMakeLists.txt A CMake function to define a new STM32 target. It handles source file globbing, conditional source inclusion, compiler definitions, include directories, and linking libraries. ```cmake function(add_stm32_target TARGET) file(GLOB_RECURSE SRC ${STM32CubeH7_SOURCE_DIR}/Drivers/STM32H7xx_HAL_Driver/*.c src/startup_stm32h743zitx.s src/bsp.c) # Filter unwanted .template files list(FILTER SRC EXCLUDE REGEX ".*template") add_executable(${TARGET} ${SRC}) # Include either decoder.cpp or command_station.cpp, but not both target_sources( ${TARGET} PRIVATE "$,src/decoder.cpp,src/command_station.cpp>" ) target_compile_definitions(${TARGET} PUBLIC USE_FULL_LL_DRIVER USE_HAL_DRIVER STM32H743xx) target_include_directories( ${TARGET} PUBLIC ${STM32CubeH7_SOURCE_DIR}/Drivers/CMSIS/Core/Include ${STM32CubeH7_SOURCE_DIR}/Drivers/CMSIS/Device/ST/STM32H7xx/Include ${STM32CubeH7_SOURCE_DIR}/Drivers/CMSIS/Include ${STM32CubeH7_SOURCE_DIR}/Drivers/STM32H7xx_HAL_Driver/Inc) # Use some other projects stm32h7xx_hal_conf.h and system_stm32h7xx.c files target_include_directories( ${TARGET} PUBLIC ${STM32CubeH7_SOURCE_DIR}/Projects/NUCLEO-H743ZI/Applications/FreeRTOS/FreeRTOS_MPU/Inc ) target_sources( ${TARGET} PRIVATE ${STM32CubeH7_SOURCE_DIR}/Projects/NUCLEO-H743ZI/Applications/FreeRTOS/FreeRTOS_MPU/Src/system_stm32h7xx.c ) target_common_warnings(${TARGET} PRIVATE) target_common_errors(${TARGET} PRIVATE) target_link_libraries(${TARGET} PRIVATE DCC::DCC) target_link_libraries( ${TARGET} PRIVATE --specs=nano.specs -Wl,--gc-sections,-Map=${TARGET}.map -T${CMAKE_CURRENT_SOURCE_DIR}/STM32H743ZITX_FLASH.ld) # Create .hex files post build add_custom_command( TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -O ihex ${TARGET} ${TARGET}.hex COMMAND ${CMAKE_OBJDUMP} --source --all-headers --demangle --line-numbers --wide ${TARGET} > ${TARGET}.lst COMMAND ${CMAKE_SIZE} --format=berkeley ${TARGET}) endfunction() ``` -------------------------------- ### Periodic Packet Execution Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Call the execute method periodically to process received DCC packets. This can be done in a super-loop or an RTOS task to avoid blocking the interrupt context. ```cpp // RTOS task void task(void*) { for (;;) { decoder.execute(); vTaskDelay(pdMS_TO_TICKS(5u)); } } ``` -------------------------------- ### DCC Signal Reception Source: https://github.com/zimo-elektronik/dcc/blob/master/README.md Pass the captured timer value (in microseconds) to the decoder's receive method within a timer interrupt handler. This is crucial for decoding the DCC signal. ```cpp // Timer interrupt handler void isr() { auto const ccr{TIM->CCR}; // Read capture/compare register decoder.receive(ccr); // Pass captured value in µs } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.