31#ifndef ETL_MANCHESTER_INCLUDED
32#define ETL_MANCHESTER_INCLUDED
36#include "static_assert.h"
44 namespace private_manchester
50 template <
typename TChunk>
53 static const bool value =
54#if ETL_USING_8BIT_TYPES
55 etl::is_same<TChunk, uint8_t>::value ||
57 etl::is_same<TChunk, uint16_t>::value
58#if ETL_USING_64BIT_TYPES
59 || etl::is_same<TChunk, uint32_t>::value
68 template <
typename TChunk>
71 static const bool value =
72#if ETL_USING_8BIT_TYPES
73 etl::is_same<TChunk, uint16_t>::value ||
75 etl::is_same<TChunk, uint32_t>::value
76#if ETL_USING_64BIT_TYPES
77 || etl::is_same<TChunk, uint64_t>::value
91 ETL_STATIC_ASSERT(
sizeof(T) == 0,
"Manchester encoding type should be one of [uint8_t, uint16_t, uint32_t]");
94#if ETL_USING_8BIT_TYPES
98 typedef uint16_t
type;
105 typedef uint32_t type;
108#if ETL_USING_64BIT_TYPES
112 typedef uint64_t type;
122 template <
typename T>
125 ETL_STATIC_ASSERT(
sizeof(T) == 0,
"Manchester decoding type should be one of [uint16_t, uint32_t, uint64_t]");
128#if ETL_USING_64BIT_TYPES
132 typedef uint8_t type;
139 typedef uint16_t type;
142#if ETL_USING_64BIT_TYPES
146 typedef uint32_t type;
155#if ETL_USING_64BIT_TYPES
156 static const uint64_t inversion_mask = 0x0000000000000000ULL;
158 static const uint32_t inversion_mask = 0x00000000UL;
167#if ETL_USING_64BIT_TYPES
168 static const uint64_t inversion_mask = 0xFFFFFFFFFFFFFFFFULL;
170 static const uint32_t inversion_mask = 0xFFFFFFFFUL;
181 template <
typename T>
185 for (
size_t j = 0; j <
sizeof(T); ++j)
187 value |=
static_cast<T
>(bytes[index + j]) << (j * CHAR_BIT);
199 template <
typename T>
202 for (
size_t j = 0; j <
sizeof(T); ++j)
204 bytes[index + j] =
static_cast<uint_least8_t
>(value >> (j * CHAR_BIT));
216 manchester_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
217 :
exception(reason_, file_name_, line_number_)
229 manchester_invalid_size(string_type file_name_, numeric_type line_number_)
240 template <
typename TManchesterType>
243 ETL_STATIC_ASSERT((etl::is_same<TManchesterType, private_manchester::manchester_type_normal>::value
244 || etl::is_same<TManchesterType, private_manchester::manchester_type_inverted>::value),
245 "TManchesterType must be manchester_type_normal or manchester_type_inverted");
248 "Manchester requires uint_least8_t to have the same number of bits as CHAR (CHAR_BITS)");
254#if ETL_USING_8BIT_TYPES
260 template <
typename TDecoded>
267 TEncoded encoded = decoded;
269 encoded =
static_cast<TEncoded
>((
static_cast<unsigned int>(encoded) | (
static_cast<unsigned int>(encoded) << 4U)) & 0x0F0FU);
270 encoded =
static_cast<TEncoded
>((
static_cast<unsigned int>(encoded) | (
static_cast<unsigned int>(encoded) << 2U)) & 0x3333U);
271 encoded =
static_cast<TEncoded
>((
static_cast<unsigned int>(encoded) | (
static_cast<unsigned int>(encoded) << 1U)) & 0x5555U);
272 encoded =
static_cast<TEncoded
>((
static_cast<unsigned int>(encoded) | (
static_cast<unsigned int>(encoded) << 1U))
273 ^ (0xAAAAU ^
static_cast<unsigned int>(TManchesterType::inversion_mask)));
283 template <
typename TDecoded>
290 TEncoded encoded = decoded;
292 encoded = (encoded | (encoded << 8U)) & 0x00FF00FFUL;
293 encoded = (encoded | (encoded << 4U)) & 0x0F0F0F0FUL;
294 encoded = (encoded | (encoded << 2U)) & 0x33333333UL;
295 encoded = (encoded | (encoded << 1U)) & 0x55555555UL;
296 encoded = (encoded | (encoded << 1U)) ^ (0xAAAAAAAAUL ^ static_cast<TEncoded>(TManchesterType::inversion_mask));
300#if ETL_USING_64BIT_TYPES
306 template <
typename TDecoded>
313 TEncoded encoded = decoded;
315 encoded = (encoded | (encoded << 16U)) & 0x0000FFFF0000FFFFULL;
316 encoded = (encoded | (encoded << 8U)) & 0x00FF00FF00FF00FFULL;
317 encoded = (encoded | (encoded << 4U)) & 0x0F0F0F0F0F0F0F0FULL;
318 encoded = (encoded | (encoded << 2U)) & 0x3333333333333333ULL;
319 encoded = (encoded | (encoded << 1U)) & 0x5555555555555555ULL;
320 encoded = (encoded | (encoded << 1U)) ^ (0xAAAAAAAAAAAAAAAAULL ^ TManchesterType::inversion_mask);
331 template <
typename TChunk = u
int_least8_t>
334 typedef TChunk TDecoded;
340 size_t dest_index = 0;
341 size_t source_index = 0;
342 for (
size_t i = 0; i < decoded.
size() /
sizeof(TDecoded); ++i)
344 const TDecoded decoded_value = private_manchester::read_little_endian<TDecoded>(decoded, source_index);
345 const TEncoded encoded_value =
encode(decoded_value);
346 private_manchester::write_little_endian<TEncoded>(encoded, dest_index, encoded_value);
348 source_index +=
sizeof(TDecoded);
349 dest_index +=
sizeof(TEncoded);
357#if ETL_USING_8BIT_TYPES
363 template <
typename TEncoded>
370 encoded =
static_cast<TEncoded
>((
static_cast<unsigned int>(encoded) ^ (0xAAAAU ^
static_cast<unsigned int>(TManchesterType::inversion_mask)))
372 encoded =
static_cast<TEncoded
>((
static_cast<unsigned int>(encoded) | (
static_cast<unsigned int>(encoded) >> 1)) & 0x3333U);
373 encoded =
static_cast<TEncoded
>((
static_cast<unsigned int>(encoded) | (
static_cast<unsigned int>(encoded) >> 2)) & 0x0F0FU);
374 return static_cast<TDecoded
>(
static_cast<unsigned int>(encoded) | (
static_cast<unsigned int>(encoded) >> 4U));
383 template <
typename TEncoded>
385 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_same<TEncoded, uint32_t>::value,
typename private_manchester::decoded<TEncoded>::type>
::type
390 encoded = (encoded ^ (0xAAAAAAAAUL ^
static_cast<TEncoded
>(TManchesterType::inversion_mask))) & 0x55555555UL;
391 encoded = (encoded | (encoded >> 1)) & 0x33333333UL;
392 encoded = (encoded | (encoded >> 2)) & 0x0F0F0F0FUL;
393 encoded = (encoded | (encoded >> 4)) & 0x00FF00FFUL;
394 return static_cast<TDecoded
>(encoded | (encoded >> 8U));
397#if ETL_USING_64BIT_TYPES
403 template <
typename TEncoded>
410 encoded = (encoded ^ (0xAAAAAAAAAAAAAAAAULL ^ TManchesterType::inversion_mask)) & 0x5555555555555555ULL;
411 encoded = (encoded | (encoded >> 1)) & 0x3333333333333333ULL;
412 encoded = (encoded | (encoded >> 2)) & 0x0F0F0F0F0F0F0F0FULL;
413 encoded = (encoded | (encoded >> 4)) & 0x00FF00FF00FF00FFULL;
414 encoded = (encoded | (encoded >> 8)) & 0x0000FFFF0000FFFFULL;
415 return static_cast<TDecoded
>(encoded | (encoded >> 16U));
425 template <typename TChunk = typename private_manchester::encoded<uint_least8_t>::type>
429 typedef TChunk TEncoded;
434 size_t dest_index = 0;
435 size_t source_index = 0;
436 for (
size_t i = 0; i < encoded.
size() /
sizeof(TEncoded); ++i)
438 const TEncoded encoded_value = private_manchester::read_little_endian<TEncoded>(encoded, source_index);
439 const TDecoded decoded_value =
decode(encoded_value);
440 private_manchester::write_little_endian<TDecoded>(decoded, dest_index, decoded_value);
442 source_index +=
sizeof(TEncoded);
443 dest_index +=
sizeof(TDecoded);
456 template <
typename TChunk>
458 static ETL_CONSTEXPR14
typename etl::enable_if<private_manchester::is_decodable<TChunk>::value,
bool>
::type is_valid(TChunk encoded)
460 const TChunk mask =
static_cast<TChunk
>(0x5555555555555555ULL);
461 return (((encoded ^ (encoded >> 1)) & mask) == mask);
474 for (
size_t i = 0; i < encoded.
size(); i +=
sizeof(uint16_t))
476 const uint16_t chunk = private_manchester::read_little_endian<uint16_t>(encoded, i);
Exception for Manchester.
Definition manchester.h:213
Invalid size exception for Manchester.
Definition manchester.h:226
Span - Fixed Extent.
Definition span.h:208
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the span.
Definition span.h:564
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition exception.h:59
static ETL_CONSTEXPR14 etl::enable_if< etl::is_same< TDecoded, uint32_t >::value, typenameprivate_manchester::encoded< TDecoded >::type >::type encode(TDecoded decoded)
Definition manchester.h:309
static ETL_CONSTEXPR14 etl::enable_if< etl::is_same< TEncoded, uint64_t >::value, typenameprivate_manchester::decoded< TEncoded >::type >::type decode(TEncoded encoded)
Definition manchester.h:406
static ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if< private_manchester::is_decodable< TChunk >::value, bool >::type is_valid(TChunk encoded)
Definition manchester.h:458
static ETL_CONSTEXPR14 void encode(etl::span< const uint_least8_t > decoded, etl::span< uint_least8_t > encoded)
Definition manchester.h:332
static ETL_CONSTEXPR14 etl::enable_if< etl::is_same< TEncoded, uint32_t >::value, typenameprivate_manchester::decoded< TEncoded >::type >::type decode(TEncoded encoded)
Definition manchester.h:386
static ETL_NODISCARD ETL_CONSTEXPR14 bool is_valid(etl::span< const uint_least8_t > encoded)
Definition manchester.h:470
static ETL_CONSTEXPR14 etl::enable_if< etl::is_same< TDecoded, uint16_t >::value, typenameprivate_manchester::encoded< TDecoded >::type >::type encode(TDecoded decoded)
Definition manchester.h:286
static ETL_CONSTEXPR14 void decode(etl::span< const uint_least8_t > encoded, etl::span< uint_least8_t > decoded)
Definition manchester.h:426
manchester_base< private_manchester::manchester_type_normal > manchester
Definition manchester.h:492
manchester_base< private_manchester::manchester_type_inverted > manchester_inverted
Definition manchester.h:498
Definition manchester.h:242
bitset_ext
Definition absolute.h:40
Definition manchester.h:124
Definition manchester.h:90
Definition manchester.h:70
Definition manchester.h:52
Inverted Manchester encoding type.
Definition manchester.h:166
Normal Manchester encoding type (no inversion).
Definition manchester.h:154