Compare commits
4 Commits
8153696309
...
87e6936051
| Author | SHA1 | Date | |
|---|---|---|---|
| 87e6936051 | |||
| 1d633c538e | |||
| 231fc0de48 | |||
| 6438aa81c1 |
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../clock.h"
|
#include "../clock.hpp"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <avr/interrupt.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
@@ -131,6 +132,7 @@ class Hardware0<mode, cfg, Driven::INTERRUPT> {
|
|||||||
detail::fnDataReg0EmptyIntHandler = dataRegEmptyIntHandler;
|
detail::fnDataReg0EmptyIntHandler = dataRegEmptyIntHandler;
|
||||||
|
|
||||||
HardwareImpl::init();
|
HardwareImpl::init();
|
||||||
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void txByte(const data_t &byte) FORCE_INLINE
|
static void txByte(const data_t &byte) FORCE_INLINE
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <avr/interrupt.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
@@ -135,6 +136,7 @@ class Hardware1<mode, cfg, Driven::INTERRUPT> {
|
|||||||
detail::fnDataReg1EmptyIntHandler = dataRegEmptyIntHandler;
|
detail::fnDataReg1EmptyIntHandler = dataRegEmptyIntHandler;
|
||||||
|
|
||||||
HardwareImpl::init();
|
HardwareImpl::init();
|
||||||
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void txByte(const data_t &byte) FORCE_INLINE
|
static void txByte(const data_t &byte) FORCE_INLINE
|
||||||
|
|||||||
41
uart.hpp
41
uart.hpp
@@ -22,11 +22,6 @@ static constexpr size_t cntDigits()
|
|||||||
T num = limit;
|
T num = limit;
|
||||||
size_t cnt = 0;
|
size_t cnt = 0;
|
||||||
|
|
||||||
if (num < 0) {
|
|
||||||
num = -num;
|
|
||||||
++cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
num /= Base;
|
num /= Base;
|
||||||
++cnt;
|
++cnt;
|
||||||
@@ -38,8 +33,23 @@ static constexpr size_t cntDigits()
|
|||||||
template <typename T, size_t Base>
|
template <typename T, size_t Base>
|
||||||
static constexpr size_t maxNumDigits()
|
static constexpr size_t maxNumDigits()
|
||||||
{
|
{
|
||||||
T minDigits = cntDigits<T, util::NumericLimits<T>::min(), Base>();
|
constexpr T minVal = util::NumericLimits<T>::min();
|
||||||
T maxDigits = cntDigits<T, util::NumericLimits<T>::max(), Base>();
|
constexpr T maxVal = util::NumericLimits<T>::max();
|
||||||
|
|
||||||
|
T minDigits = cntDigits<T, minVal, Base>() + ((minVal < 0) ? 1 : 0);
|
||||||
|
T maxDigits = cntDigits<T, maxVal, Base>() + ((maxVal < 0) ? 1 : 0);
|
||||||
|
|
||||||
|
return (minDigits < maxDigits) ? maxDigits : minDigits;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, size_t Base>
|
||||||
|
static constexpr size_t maxPadding()
|
||||||
|
{
|
||||||
|
constexpr T minVal = util::NumericLimits<T>::min();
|
||||||
|
constexpr T maxVal = util::NumericLimits<T>::max();
|
||||||
|
|
||||||
|
T minDigits = cntDigits<T, minVal, Base>();
|
||||||
|
T maxDigits = cntDigits<T, maxVal, Base>();
|
||||||
|
|
||||||
return (minDigits < maxDigits) ? maxDigits : minDigits;
|
return (minDigits < maxDigits) ? maxDigits : minDigits;
|
||||||
}
|
}
|
||||||
@@ -111,14 +121,17 @@ class Uart {
|
|||||||
txByte(ch);
|
txByte(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t Base = 10>
|
template <typename T, size_t Base = 10, size_t Padding = 0, char PadChar = '0', bool LowerCase = true>
|
||||||
static void txNumber(const T &val)
|
static void txNumber(const T &val)
|
||||||
{
|
{
|
||||||
static_assert(util::is_integral_v<T>, "Only supported on integral types");
|
static_assert(util::is_integral_v<T>, "Only supported on integral types");
|
||||||
static_assert(Base >= 2, "Numbers with bases less than 2 make no sense");
|
static_assert(Base >= 2, "Numbers with bases less than 2 make no sense");
|
||||||
static_assert(Base <= 16, "Numbers with bases higher than 16 are not supported");
|
static_assert(Base <= 16, "Numbers with bases higher than 16 are not supported");
|
||||||
|
static_assert(Padding <= detail::maxPadding<T, Base>(), "Cannot pad more than maximum length of number");
|
||||||
|
|
||||||
|
constexpr char alphaChar = (LowerCase) ? 'a' : 'A';
|
||||||
constexpr size_t numDigits = detail::maxNumDigits<T, Base>();
|
constexpr size_t numDigits = detail::maxNumDigits<T, Base>();
|
||||||
|
|
||||||
data_t buffer[numDigits];
|
data_t buffer[numDigits];
|
||||||
data_t *bufEnd = buffer + numDigits - 1;
|
data_t *bufEnd = buffer + numDigits - 1;
|
||||||
|
|
||||||
@@ -131,10 +144,20 @@ class Uart {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
data_t lastDigit = digits % Base;
|
data_t lastDigit = digits % Base;
|
||||||
*bufEnd-- = (lastDigit < 10) ? ('0' + lastDigit) : ('a' + lastDigit - 10);
|
*bufEnd-- = (lastDigit < 10) ? ('0' + lastDigit) : (alphaChar + lastDigit - 10);
|
||||||
digits /= Base;
|
digits /= Base;
|
||||||
} while (digits > 0);
|
} while (digits > 0);
|
||||||
|
|
||||||
|
if (Padding > 0) {
|
||||||
|
size_t strLen = buffer + numDigits - (bufEnd + 1);
|
||||||
|
|
||||||
|
if (Padding > strLen) {
|
||||||
|
for (size_t i = Padding; i > strLen && bufEnd >= buffer; --i) {
|
||||||
|
*bufEnd-- = PadChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (data_t *buf = bufEnd + 1; buf < buffer + numDigits; ++buf)
|
for (data_t *buf = bufEnd + 1; buf < buffer + numDigits; ++buf)
|
||||||
txByte(*buf);
|
txByte(*buf);
|
||||||
}
|
}
|
||||||
|
|||||||
13
utils.hpp
13
utils.hpp
@@ -5,6 +5,7 @@
|
|||||||
#define __STDC_VERSION__ 201112L
|
#define __STDC_VERSION__ 201112L
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
namespace uart {
|
namespace uart {
|
||||||
@@ -121,20 +122,20 @@ struct NumericLimits<unsigned long long int> {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct NumericLimits<float> {
|
struct NumericLimits<float> {
|
||||||
template <typename... Ts> static constexpr float min() { static_assert(always_false_v<Ts...>, "Not implemented"); return 0; }
|
template <typename... Ts> static constexpr float min() { return FLT_MIN; }
|
||||||
template <typename... Ts> static constexpr float max() { static_assert(always_false_v<Ts...>, "Not implemented"); return 0; }
|
template <typename... Ts> static constexpr float max() { return FLT_MAX; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct NumericLimits<double> {
|
struct NumericLimits<double> {
|
||||||
template <typename... Ts> static constexpr double min() { static_assert(always_false_v<Ts...>, "Not implemented"); return 0; }
|
template <typename... Ts> static constexpr double min() { return DBL_MIN; }
|
||||||
template <typename... Ts> static constexpr double max() { static_assert(always_false_v<Ts...>, "Not implemented"); return 0; }
|
template <typename... Ts> static constexpr double max() { return DBL_MAX; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct NumericLimits<long double> {
|
struct NumericLimits<long double> {
|
||||||
template <typename... Ts> static constexpr long double min() { static_assert(always_false_v<Ts...>, "Not implemented"); return 0; }
|
template <typename... Ts> static constexpr long double min() { return LDBL_MIN; }
|
||||||
template <typename... Ts> static constexpr long double max() { static_assert(always_false_v<Ts...>, "Not implemented"); return 0; }
|
template <typename... Ts> static constexpr long double max() { return LDBL_MAX; }
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user