Compare commits
No commits in common. "d89322bdaae6c08bedc65209373e0a1fc5c9af05" and "80de36ee7ee3e6b0842d5eaee81d54062cb496b2" have entirely different histories.
d89322bdaa
...
80de36ee7e
90
io.hpp
90
io.hpp
@ -45,6 +45,8 @@
|
|||||||
#define PIN_C7_AVAILABLE
|
#define PIN_C7_AVAILABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define FORCE_INLINE __attribute__((always_inline))
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Library implementation
|
// Library implementation
|
||||||
|
|
||||||
@ -102,8 +104,6 @@ enum class P {
|
|||||||
D6 = 0x36,
|
D6 = 0x36,
|
||||||
D7 = 0x37,
|
D7 = 0x37,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NONE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Bus {
|
enum class Bus {
|
||||||
@ -119,8 +119,6 @@ enum class Bus {
|
|||||||
#ifdef PORT_D_AVAILABLE
|
#ifdef PORT_D_AVAILABLE
|
||||||
D = 0x03,
|
D = 0x03,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NONE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -252,7 +250,7 @@ static inline reg_ptr_t getRegPtr()
|
|||||||
template <template <P, uint8_t> typename Func, P pin, P... pins>
|
template <template <P, uint8_t> typename Func, P pin, P... pins>
|
||||||
struct CallHelper {
|
struct CallHelper {
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
[[gnu::always_inline]] static inline void call(Args... args)
|
FORCE_INLINE static inline void call(Args... args)
|
||||||
{
|
{
|
||||||
Func<pin, sizeof...(pins)>::call(args...);
|
Func<pin, sizeof...(pins)>::call(args...);
|
||||||
CallHelper<Func, pins...>::call(args...);
|
CallHelper<Func, pins...>::call(args...);
|
||||||
@ -262,7 +260,7 @@ struct CallHelper {
|
|||||||
template <template <P, uint8_t> typename Func, P pin>
|
template <template <P, uint8_t> typename Func, P pin>
|
||||||
struct CallHelper<Func, pin> {
|
struct CallHelper<Func, pin> {
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
[[gnu::always_inline]] static inline void call(Args... args)
|
FORCE_INLINE static inline void call(Args... args)
|
||||||
{
|
{
|
||||||
Func<pin, 0>::call(args...);
|
Func<pin, 0>::call(args...);
|
||||||
}
|
}
|
||||||
@ -270,7 +268,7 @@ struct CallHelper<Func, pin> {
|
|||||||
|
|
||||||
template <template <P> typename Func, P pin, P... pins>
|
template <template <P> typename Func, P pin, P... pins>
|
||||||
struct ReadCallHelper {
|
struct ReadCallHelper {
|
||||||
[[gnu::always_inline]] static inline uint8_t call()
|
static inline uint8_t call() FORCE_INLINE
|
||||||
{
|
{
|
||||||
return Func<pin>::call() << sizeof...(pins) | ReadCallHelper<Func, pins...>::call();
|
return Func<pin>::call() << sizeof...(pins) | ReadCallHelper<Func, pins...>::call();
|
||||||
}
|
}
|
||||||
@ -278,7 +276,7 @@ struct ReadCallHelper {
|
|||||||
|
|
||||||
template <template <P> typename Func, P pin>
|
template <template <P> typename Func, P pin>
|
||||||
struct ReadCallHelper<Func, pin> {
|
struct ReadCallHelper<Func, pin> {
|
||||||
[[gnu::always_inline]] static inline uint8_t call()
|
static inline uint8_t call() FORCE_INLINE
|
||||||
{
|
{
|
||||||
return Func<pin>::call();
|
return Func<pin>::call();
|
||||||
}
|
}
|
||||||
@ -301,9 +299,8 @@ class Pin {
|
|||||||
// The only valid way to create a Pin object is with the default constructor
|
// The only valid way to create a Pin object is with the default constructor
|
||||||
Pin() = default;
|
Pin() = default;
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void dir(const Dir dir)
|
static inline void dir(const Dir dir) FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (pin != P::NONE) {
|
|
||||||
constexpr auto bus = detail::getBus(pin);
|
constexpr auto bus = detail::getBus(pin);
|
||||||
constexpr auto pinBit = detail::getPinBit(pin);
|
constexpr auto pinBit = detail::getPinBit(pin);
|
||||||
|
|
||||||
@ -314,11 +311,9 @@ class Pin {
|
|||||||
else if (dir == Dir::OUT)
|
else if (dir == Dir::OUT)
|
||||||
*dirRegPtr |= (1 << pinBit);
|
*dirRegPtr |= (1 << pinBit);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void pullup(const bool enable)
|
static inline void pullup(const bool enable) FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (pin != P::NONE) {
|
|
||||||
constexpr auto bus = detail::getBus(pin);
|
constexpr auto bus = detail::getBus(pin);
|
||||||
constexpr auto pinBit = detail::getPinBit(pin);
|
constexpr auto pinBit = detail::getPinBit(pin);
|
||||||
|
|
||||||
@ -329,11 +324,9 @@ class Pin {
|
|||||||
else
|
else
|
||||||
*portRegPtr &= ~(1 << pinBit);
|
*portRegPtr &= ~(1 << pinBit);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void write(const bool value)
|
static inline void write(const bool value) FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (pin != P::NONE) {
|
|
||||||
constexpr auto bus = detail::getBus(pin);
|
constexpr auto bus = detail::getBus(pin);
|
||||||
constexpr auto pinBit = detail::getPinBit(pin);
|
constexpr auto pinBit = detail::getPinBit(pin);
|
||||||
|
|
||||||
@ -344,11 +337,9 @@ class Pin {
|
|||||||
else
|
else
|
||||||
*portRegPtr &= ~(1 << pinBit);
|
*portRegPtr &= ~(1 << pinBit);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void toggle()
|
static inline void toggle() FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (pin != P::NONE) {
|
|
||||||
constexpr auto bus = detail::getBus(pin);
|
constexpr auto bus = detail::getBus(pin);
|
||||||
constexpr auto pinBit = detail::getPinBit(pin);
|
constexpr auto pinBit = detail::getPinBit(pin);
|
||||||
|
|
||||||
@ -360,11 +351,9 @@ class Pin {
|
|||||||
*portRegPtr ^= (1 << pinBit);
|
*portRegPtr ^= (1 << pinBit);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline bool read()
|
static inline bool read() FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (pin != P::NONE) {
|
|
||||||
constexpr auto bus = detail::getBus(pin);
|
constexpr auto bus = detail::getBus(pin);
|
||||||
constexpr auto pinBit = detail::getPinBit(pin);
|
constexpr auto pinBit = detail::getPinBit(pin);
|
||||||
|
|
||||||
@ -372,17 +361,17 @@ class Pin {
|
|||||||
|
|
||||||
if (*pinRegPtr >> pinBit & 1)
|
if (*pinRegPtr >> pinBit & 1)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] Pin &operator=(const bool value)
|
Pin &operator=(const bool value) FORCE_INLINE
|
||||||
{
|
{
|
||||||
write(value);
|
write(value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] operator bool() const
|
operator bool() const FORCE_INLINE
|
||||||
{
|
{
|
||||||
return read();
|
return read();
|
||||||
}
|
}
|
||||||
@ -403,9 +392,8 @@ class Port {
|
|||||||
// The only valid way to create a Port object is with the default constructor
|
// The only valid way to create a Port object is with the default constructor
|
||||||
Port() = default;
|
Port() = default;
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void dir(const Dir dir)
|
static inline void dir(const Dir dir) FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (port != Bus::NONE) {
|
|
||||||
detail::reg_ptr_t dirRegPtr = detail::getRegPtr<detail::getDDR(port)>();
|
detail::reg_ptr_t dirRegPtr = detail::getRegPtr<detail::getDDR(port)>();
|
||||||
|
|
||||||
if (dir == Dir::IN)
|
if (dir == Dir::IN)
|
||||||
@ -413,11 +401,9 @@ class Port {
|
|||||||
else if (dir == Dir::OUT)
|
else if (dir == Dir::OUT)
|
||||||
*dirRegPtr = 0xFF;
|
*dirRegPtr = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void pullup(const bool enable)
|
static inline void pullup(const bool enable) FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (port != Bus::NONE) {
|
|
||||||
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(port)>();
|
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(port)>();
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
@ -425,19 +411,15 @@ class Port {
|
|||||||
else
|
else
|
||||||
*portRegPtr = 0x00;
|
*portRegPtr = 0x00;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void write([[maybe_unused]] const uint8_t value)
|
static inline void write(const uint8_t value) FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (port != Bus::NONE) {
|
|
||||||
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(port)>();
|
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(port)>();
|
||||||
*portRegPtr = value;
|
*portRegPtr = value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void invert()
|
static inline void invert() FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (port != Bus::NONE) {
|
|
||||||
#ifdef HARDWARE_TOGGLE
|
#ifdef HARDWARE_TOGGLE
|
||||||
detail::reg_ptr_t pinRegPtr = detail::getRegPtr<detail::getPIN(port)>();
|
detail::reg_ptr_t pinRegPtr = detail::getRegPtr<detail::getPIN(port)>();
|
||||||
*pinRegPtr = 0xFF;
|
*pinRegPtr = 0xFF;
|
||||||
@ -446,25 +428,21 @@ class Port {
|
|||||||
*portRegPtr = ~(*portRegPtr);
|
*portRegPtr = ~(*portRegPtr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline uint8_t read()
|
static inline uint8_t read() FORCE_INLINE
|
||||||
{
|
{
|
||||||
if constexpr (port != Bus::NONE) {
|
|
||||||
detail::reg_ptr_t pinRegPtr = detail::getRegPtr<detail::getPIN(port)>();
|
detail::reg_ptr_t pinRegPtr = detail::getRegPtr<detail::getPIN(port)>();
|
||||||
|
|
||||||
return *pinRegPtr;
|
return *pinRegPtr;
|
||||||
}
|
}
|
||||||
return 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::always_inline]] inline Port &operator=(const uint8_t value)
|
inline Port &operator=(const uint8_t value) FORCE_INLINE
|
||||||
{
|
{
|
||||||
write(value);
|
write(value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] inline operator uint8_t() const
|
inline operator uint8_t() const FORCE_INLINE
|
||||||
{
|
{
|
||||||
return read();
|
return read();
|
||||||
}
|
}
|
||||||
@ -477,22 +455,22 @@ namespace detail {
|
|||||||
|
|
||||||
template <P pin, uint8_t offset>
|
template <P pin, uint8_t offset>
|
||||||
struct Callers {
|
struct Callers {
|
||||||
[[gnu::always_inline]] static void call(const Dir dir)
|
static void call(const Dir dir) FORCE_INLINE
|
||||||
{
|
{
|
||||||
Pin<pin>::dir(dir);
|
Pin<pin>::dir(dir);
|
||||||
};
|
};
|
||||||
|
|
||||||
[[gnu::always_inline]] static void call(const bool enable)
|
static void call(const bool enable) FORCE_INLINE
|
||||||
{
|
{
|
||||||
Pin<pin>::pullup(enable);
|
Pin<pin>::pullup(enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
[[gnu::always_inline]] static void call(const uint8_t value)
|
static void call(const uint8_t value) FORCE_INLINE
|
||||||
{
|
{
|
||||||
Pin<pin>::write(value >> offset & 1);
|
Pin<pin>::write(value >> offset & 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
[[gnu::always_inline]] static void call()
|
static void call() FORCE_INLINE
|
||||||
{
|
{
|
||||||
Pin<pin>::toggle();
|
Pin<pin>::toggle();
|
||||||
};
|
};
|
||||||
@ -500,7 +478,7 @@ struct Callers {
|
|||||||
|
|
||||||
template <P pin>
|
template <P pin>
|
||||||
struct readCaller {
|
struct readCaller {
|
||||||
[[gnu::always_inline]] static bool call()
|
static bool call() FORCE_INLINE
|
||||||
{
|
{
|
||||||
return Pin<pin>::read();
|
return Pin<pin>::read();
|
||||||
};
|
};
|
||||||
@ -522,38 +500,38 @@ class VirtPort {
|
|||||||
// The only valid way to create a VirtPort object is with the default constructor
|
// The only valid way to create a VirtPort object is with the default constructor
|
||||||
VirtPort() = default;
|
VirtPort() = default;
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void dir(const Dir dir)
|
static inline void dir(const Dir dir) FORCE_INLINE
|
||||||
{
|
{
|
||||||
detail::CallHelper<detail::Callers, pins...>::call(dir);
|
detail::CallHelper<detail::Callers, pins...>::call(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void pullup(const bool enable)
|
static inline void pullup(const bool enable) FORCE_INLINE
|
||||||
{
|
{
|
||||||
detail::CallHelper<detail::Callers, pins...>::call(enable);
|
detail::CallHelper<detail::Callers, pins...>::call(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void write(const uint8_t value)
|
static inline void write(const uint8_t value) FORCE_INLINE
|
||||||
{
|
{
|
||||||
detail::CallHelper<detail::Callers, pins...>::call(value);
|
detail::CallHelper<detail::Callers, pins...>::call(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline void invert()
|
static inline void invert() FORCE_INLINE
|
||||||
{
|
{
|
||||||
detail::CallHelper<detail::Callers, pins...>::call();
|
detail::CallHelper<detail::Callers, pins...>::call();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] static inline uint8_t read()
|
static inline uint8_t read() FORCE_INLINE
|
||||||
{
|
{
|
||||||
return detail::ReadCallHelper<detail::readCaller, pins...>::call();
|
return detail::ReadCallHelper<detail::readCaller, pins...>::call();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] inline VirtPort &operator=(const uint8_t value)
|
inline VirtPort &operator=(const uint8_t value) FORCE_INLINE
|
||||||
{
|
{
|
||||||
write(value);
|
write(value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::always_inline]] inline operator uint8_t() const
|
inline operator uint8_t() const FORCE_INLINE
|
||||||
{
|
{
|
||||||
return read();
|
return read();
|
||||||
}
|
}
|
||||||
@ -575,3 +553,5 @@ class VirtPort {
|
|||||||
#undef PIN_B6_AVAILABLE
|
#undef PIN_B6_AVAILABLE
|
||||||
#undef PIN_B7_AVAILABLE
|
#undef PIN_B7_AVAILABLE
|
||||||
#undef PIN_C7_AVAILABLE
|
#undef PIN_C7_AVAILABLE
|
||||||
|
|
||||||
|
#undef FORCE_INLINE
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user