#pragma once #include #include #include #include #include #include #include namespace interrupt { namespace detail { template struct manager { void init() const { // TODO: log exact interrupt manager configuration // (should be a single compile-time string with no arguments) hal::init(); init_mcu_interrupts(); init_sub_interrupts(); } void init_mcu_interrupts() const { (Impls::init_mcu_interrupts(), ...); } void init_sub_interrupts() const { auto enables = stdx::tuple_cat(Impls::get_interrupt_enables()...); enables.apply([](Enables...) { Dynamic::template enable_by_field(); }); } template inline void run() const { using M = stdx::type_map...>; using irq_t = stdx::value_lookup_t; if constexpr (not std::is_void_v) { irq_t::run(); } } [[nodiscard]] constexpr auto max_irq() const -> irq_num_t { return static_cast( std::max({stdx::to_underlying(Impls::irq_number)...})); } }; template struct build_manager { using dynamic_t = typename Config::template dynamic_controller_t; template using impl = manager; }; } // namespace detail template using manager = typename Config::template build< detail::build_manager::template impl, Nexi...>; } // namespace interrupt