### 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.