Skip to content

Commit

Permalink
Merge pull request #3 from ZIMO-Elektronik/packet
Browse files Browse the repository at this point in the history
Packet
  • Loading branch information
higaski committed Jul 14, 2023
2 parents ede4078 + 64a1fcc commit da78a22
Show file tree
Hide file tree
Showing 38 changed files with 547 additions and 530 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ jobs:
- uses: actions/checkout@v3
- run: git fetch --unshallow --tags
- run: cmake -Bbuild
env:
CC: gcc-12
CXX: g++-12
- run: cmake --build build
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ jobs:
- uses: actions/checkout@v3
- run: git fetch --unshallow --tags
- run: cmake -Bbuild
env:
CC: gcc-12
CXX: g++-12
- run: cmake --build build --target DCCTests
- run: ctest --test-dir build --schedule-random
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ endif()
FetchContent_Declare(
CMakeModules
GIT_REPOSITORY https://github.com/ZIMO-Elektronik/CMakeModules
GIT_TAG v0.0.7
GIT_TAG v0.1.0
SOURCE_DIR ${CMAKE_BINARY_DIR}/CMakeModules)
FetchContent_MakeAvailable(CMakeModules)

Expand Down Expand Up @@ -62,6 +62,8 @@ else()
target_include_directories(DCC SYSTEM INTERFACE include)
endif()

target_common_warnings(DCC INTERFACE)

if(NOT TARGET static_math)
cpmaddpackage(
NAME
Expand All @@ -77,7 +79,7 @@ if(NOT TARGET static_math)
endif()

if(NOT TARGET ZTL::ZTL)
cpmaddpackage("gh:ZIMO-Elektronik/ZTL@0.16.2")
cpmaddpackage("gh:ZIMO-Elektronik/ZTL@0.17.0")
endif()

target_link_libraries(DCC INTERFACE static_math ZTL::ZTL)
Expand Down
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
- Consist address is never used, although it should be sent in channel 1 in case it's active
- Use std::span instead of raw pointers
- Literal for converting CV number to index? The "- 1u" everything is fucking ugly
- dcc::tx::CrtpBase currently pops it's queue at a bad time. Although the design or circular_array guarantees that it's not UB it looks funky.
- dcc::tx::CrtpBase currently pops it's queue at a bad time. Although the design or inplace_deque guarantees that it's not UB it looks funky.
2 changes: 1 addition & 1 deletion examples/repl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
file(GLOB_RECURSE SRC *.cpp)
add_executable(DCCReplExample ${SRC})

target_common_warnings(DCCReplExample)
target_common_warnings(DCCReplExample PRIVATE)

cpmaddpackage("gh:daniele77/cli@2.0.2")

Expand Down
18 changes: 9 additions & 9 deletions examples/repl/decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
std::cout << std::flush

Decoder::Decoder() {
cvs_[29uz - 1uz] = 0b10u; // Decoder configuration
cvs_[1uz - 1uz] = 3u; // Primary address
cvs_[8uz - 1uz] = 145u; // ZIMO manufacturer ID
_cvs[29uz - 1uz] = 0b10u; // Decoder configuration
_cvs[1uz - 1uz] = 3u; // Primary address
_cvs[8uz - 1uz] = 145u; // ZIMO manufacturer ID
};

void Decoder::direction(uint32_t addr, int32_t dir) {
Expand Down Expand Up @@ -45,27 +45,27 @@ void Decoder::transmitBiDi(std::span<uint8_t const>) {}

uint8_t Decoder::readCv(uint32_t cv_addr, uint8_t byte) {
cli::Cli::cout() << "Read CV byte " << cv_addr
<< "==" << static_cast<uint32_t>(cvs_[cv_addr])
<< "==" << static_cast<uint32_t>(_cvs[cv_addr])
<< PROMPTENDL;
return cvs_[cv_addr];
return _cvs[cv_addr];
}

uint8_t Decoder::writeCv(uint32_t cv_addr, uint8_t byte) {
cli::Cli::cout() << "Write CV byte " << cv_addr << "="
<< static_cast<uint32_t>(byte) << PROMPTENDL;
return cvs_[cv_addr] = byte;
return _cvs[cv_addr] = byte;
}

bool Decoder::readCv(uint32_t cv_addr, bool bit, uint32_t pos) {
auto const red_bit{static_cast<bool>(cvs_[cv_addr] & (1u << pos))};
auto const red_bit{static_cast<bool>(_cvs[cv_addr] & (1u << pos))};
cli::Cli::cout() << "Read CV bit " << cv_addr << ":" << pos << "==" << red_bit
<< PROMPTENDL;
return red_bit;
}

bool Decoder::writeCv(uint32_t cv_addr, bool bit, uint32_t pos) {
cvs_[cv_addr] = (cvs_[cv_addr] & ~(1u << pos)) | (bit << pos);
auto const red_bit{static_cast<bool>(cvs_[cv_addr] & (1u << pos))};
_cvs[cv_addr] = (_cvs[cv_addr] & ~(1u << pos)) | (bit << pos);
auto const red_bit{static_cast<bool>(_cvs[cv_addr] & (1u << pos))};
cli::Cli::cout() << "Write CV bit " << cv_addr << ":" << pos << "=" << red_bit
<< PROMPTENDL;
return red_bit;
Expand Down
2 changes: 1 addition & 1 deletion examples/repl/decoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ struct Decoder : dcc::rx::CrtpBase<Decoder> {
// Write CV bit
bool writeCv(uint32_t cv_addr, bool bit, uint32_t pos);

std::array<uint8_t, 1024uz> cvs_{};
std::array<uint8_t, 1024uz> _cvs{};
};
20 changes: 10 additions & 10 deletions examples/repl/fifo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@
// (Very very) minimalistic FIFO with internal locking
template<typename T>
struct FiFo {
T front() const { return deque_.front(); }
T front() const { return _deque.front(); }

T back() const { return deque_.back(); }
T back() const { return _deque.back(); }

void push_back(T value) {
std::scoped_lock lk{m_};
deque_.push_back(value);
std::scoped_lock lk{_m};
_deque.push_back(value);
}

void pop_front() {
std::scoped_lock lk{m_};
deque_.pop_front();
std::scoped_lock lk{_m};
_deque.pop_front();
}

bool empty() const { return std::empty(deque_); }
bool empty() const { return std::empty(_deque); }

size_t size() const { return std::size(deque_); }
size_t size() const { return std::size(_deque); }

private:
std::mutex m_{};
std::deque<T> deque_;
std::mutex _m{};
std::deque<T> _deque;
};

template<typename T>
Expand Down
4 changes: 2 additions & 2 deletions include/dcc/address.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ struct Address {
: lhs.value == rhs.value && lhs.type == rhs.type;
}

constexpr operator value_type&() & { return value; }
constexpr operator value_type const&() const& { return value; }
constexpr operator value_type&() { return value; }
constexpr operator value_type const&() const { return value; }

value_type value{};

Expand Down
30 changes: 17 additions & 13 deletions include/dcc/bidi/datagram.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <algorithm>
#include <array>
#include <cassert>
#include "bundled_channels.hpp"

namespace dcc::bidi {

Expand Down Expand Up @@ -55,6 +56,9 @@ inline constexpr std::array<uint8_t, 256uz> decode_lut{

} // namespace detail

template<size_t I = bundled_channels_size>
using Datagram = std::array<uint8_t, I>;

enum class Bits { _12 = 12uz, _18 = 18uz, _24 = 24uz, _36 = 36uz, _48 = 48uz };

/// Make datagram with ID
Expand All @@ -75,15 +79,15 @@ enum class Bits { _12 = 12uz, _18 = 18uz, _24 = 24uz, _36 = 36uz, _48 = 48uz };
template<Bits I, std::unsigned_integral T>
constexpr auto make_datagram(uint32_t id, T data) {
constexpr size_t bytes_to_send{(std::to_underlying(I) + 4uz) / 6uz};
std::array<uint8_t, bytes_to_send> retval{};
Datagram<bytes_to_send> datagram{};
// Data must be smaller than the number of bits (-4 for ID)
assert(data < smath::pow<uint64_t>(2u, bytes_to_send * 6uz - 4uz));
for (auto i{size(retval) - 1u}; i > 0u; --i) {
retval[i] = data & 0x3Fu;
for (auto i{size(datagram) - 1u}; i > 0u; --i) {
datagram[i] = data & 0x3Fu;
data >>= 6u;
}
retval.front() = static_cast<uint8_t>(id << 2u | (data & 0x03u));
return retval;
datagram.front() = static_cast<uint8_t>(id << 2u | (data & 0x03u));
return datagram;
}

/// Make datagram without ID
Expand All @@ -95,14 +99,14 @@ constexpr auto make_datagram(uint32_t id, T data) {
template<Bits I, std::unsigned_integral T>
constexpr auto make_datagram(T data) {
constexpr size_t bytes_to_send{(std::to_underlying(I) + 4uz) / 6uz};
std::array<uint8_t, bytes_to_send> retval{};
Datagram<bytes_to_send> datagram{};
// Data must be smaller than the number of bits
assert(data < smath::pow<uint64_t>(2u, bytes_to_send * 6u));
for (auto i{size(retval)}; i-- > 0u;) {
retval[i] = data & 0x3Fu;
for (auto i{size(datagram)}; i-- > 0u;) {
datagram[i] = data & 0x3Fu;
data >>= 6u;
}
return retval;
return datagram;
}

/// Encode datagram
Expand All @@ -111,8 +115,8 @@ constexpr auto make_datagram(T data) {
/// \param datagram Datagram
/// \return Encoded datagram
template<size_t I>
constexpr auto encode_datagram(std::array<uint8_t, I> const& datagram) {
std::array<uint8_t, I> encoded_datagram;
constexpr auto encode_datagram(Datagram<I> const& datagram) {
Datagram<I> encoded_datagram;
std::ranges::transform(datagram, begin(encoded_datagram), [](uint8_t b) {
return detail::encode_lut[b];
});
Expand All @@ -125,8 +129,8 @@ constexpr auto encode_datagram(std::array<uint8_t, I> const& datagram) {
/// \param encoded_datagram Encoded datagram
/// \return Datagram
template<size_t I>
constexpr auto decode_datagram(std::array<uint8_t, I> const& encoded_datagram) {
std::array<uint8_t, I> datagram{};
constexpr auto decode_datagram(Datagram<I> const& encoded_datagram) {
Datagram<I> datagram{};
std::ranges::transform(encoded_datagram, begin(datagram), [](uint8_t b) {
return detail::decode_lut[b];
});
Expand Down
4 changes: 2 additions & 2 deletions include/dcc/bidi/dyn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ namespace dcc::bidi {
struct Dyn {
using value_type = int16_t;

constexpr operator value_type&() & { return d; }
constexpr operator value_type const&() const& { return d; }
constexpr operator value_type&() { return d; }
constexpr operator value_type const&() const { return d; }

value_type d; ///< DV (dynamic CV)
uint8_t x; ///< Subindex
Expand Down
11 changes: 11 additions & 0 deletions include/dcc/crc8.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <cstdint>
#include <numeric>
#include <span>
#include "packet.hpp"

namespace dcc {

Expand Down Expand Up @@ -66,4 +67,14 @@ constexpr uint8_t crc8(std::span<uint8_t const> chunk) {
[](uint8_t a, uint8_t b) { return crc8(static_cast<uint8_t>(a ^ b)); });
}

/// This function calculates CRC8 (Dallas/Maxim). The polynomial representations
/// is 0x31.
///
/// \param chunk Chunk to calculate CRC8 for
/// \return CRC8
constexpr uint8_t crc8(Packet const& packet) {
// Packet checksum is not part of CRC
return crc8({cbegin(packet), size(packet) - 1uz});
}

} // namespace dcc
Loading

0 comments on commit da78a22

Please sign in to comment.