#define NDEBUG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "hc05.h" #include "ds3231.h" #include "ssd1306.h" using namespace std::literals::chrono; using namespace External::Units::literals; template struct Devices; // HWRev 6 template struct Devices<5, MCU> { inline static constexpr megahertz fMcu{F_CPU / 1000000}; inline static constexpr auto fRtc = 1000_Hz; using ccp = AVR::Cpu::Ccp<>; using clock = AVR::Clock<>; using sigrow = AVR::SigRow<>; using systemTimer = AVR::SystemTimer, fRtc>; using usart0Position = AVR::Portmux::Position, AVR::Portmux::Default>; using usart1Position = AVR::Portmux::Position, AVR::Portmux::Alt1>; using usart2Position = AVR::Portmux::Position, AVR::Portmux::Default>; using usart3Position = AVR::Portmux::Position, AVR::Portmux::Default>; using usart4Position = AVR::Portmux::Position, AVR::Portmux::Default>; using la0 = AVR::ActiveHigh, 4>, AVR::Output>; using la1 = AVR::ActiveHigh, 5>, AVR::Output>; using la2 = AVR::ActiveHigh, 6>, AVR::Output>; using la3 = AVR::ActiveHigh, 7>, AVR::Output>; using led1 = AVR::ActiveHigh, 2>, AVR::Output>; using led2 = AVR::ActiveHigh, 3>, AVR::Output>; using blinkLed1 = External::Blinker2; using blinkLed2 = External::Blinker2; using rmc = External::GPS::RMC>; using vtg = External::GPS::VTG>; using gsv = External::GPS::GSV>; using gps_decoder_list = Meta::List; using gps_pa = External::GPS::GpsProtocollAdapter<0, gps_decoder_list>; using gps = AVR::Usart, AVR::ReceiveQueueLength<0>, AVR::SendQueueLength<0>>; using serial2 = AVR::Usart, AVR::UseInterrupts>; using terminal2 = etl::basic_ostream; using portmux = AVR::Portmux::StaticMapper>; static inline void init() { portmux::init(); ccp::unlock([]{ if constexpr(AVR::Concepts::AtDxSeriesAll) { clock::template init(); } else { static_assert(std::false_v); } }); systemTimer::init(); } }; // HWRev 5 template struct Devices<4, MCU> { // ... }; // HWRev 3 template struct Devices<2, MCU> { // ... }; // HWRev 2 template struct Devices<1, MCU> { // ... }; // HWRev 1 template struct Devices<0, MCU> { // ... }; template struct GlobalFsm { using devs = Devices; using terminal2 = devs::terminal2; using la1Scoped = AVR::ScopedPin; enum State {Undefined, Init, On, On2, BT_SetName}; static void init() { devs::init(); // ... devs::gps::template init>(); devs::serial2::template init>(); } static void periodic() { devs::la0::toggle(); // ... devs::gps::periodic(); devs::serial2::periodic(); // fsm } static void ratePeriodic() { la1Scoped measure; devs::blinkLed1::ratePeriodic(); devs::blinkLed2::ratePeriodic(); // fsm switch(mState) { case State::On: etl::outl("Bla"_pgm); break; //... } } private: static inline etl::StringBuffer timeBuffer; static inline State mState{State::Undefined}; static inline External::Tick mStateTicks; }; using devices = Devices<5>; using gfsm = GlobalFsm; int main() { gfsm::init(); while(true) { gfsm::periodic(); devices::systemTimer::periodic([&]{ gfsm::ratePeriodic(); }); } } #ifndef NDEBUG /*[[noreturn]] */inline void assertOutput(const AVR::Pgm::StringView& expr [[maybe_unused]], const AVR::Pgm::StringView& file[[maybe_unused]], const unsigned int line [[maybe_unused]]) noexcept { } template [[noreturn]] inline void assertFunction(const String1& s1, const String2& s2, const unsigned int l) { assertOutput(s1, s2, l); } #endif