#pragma once #include "tiring.h" extern const char gpio_shift_table[]; void gpio_tristate_set_dynamic(bool value); template class Tristate { private: void set_dynamic(bool value) const { if (value) T_PIN_SET(OUT_, pin_n); else T_PIN_CLEAR(OUT_, pin_n); } public: void output() { T_PIN_SET(DIR_, pin_n); } void input() { T_PIN_CLEAR(DIR_, pin_n); } void pull_up() { T_PIN_SET(REN_, pin_n); T_PIN_SET(OUT_, pin_n); } void pull_down() { T_PIN_SET(REN_, pin_n); T_PIN_CLEAR(OUT_, pin_n); } void pull_none() { T_PIN_CLEAR(REN_, pin_n); } void operator=(bool value) const __attribute__((always_inline)) { if (__builtin_constant_p(value)) { if (value) T_PIN_SET(OUT_, pin_n); else T_PIN_CLEAR(OUT_, pin_n); } else { set_dynamic(value); } } operator bool() const { return (*T_PIN_REG(IN_, pin_n) & T_PIN_BIT(pin_n)) != 0; } }; template class Output : protected Tristate { public: Output() { Tristate::output(); } Tristate::operator=; }; template class Input : protected Tristate { public: Tristate::operator bool; Tristate::pull_up; Tristate::pull_down; Tristate::pull_none; };