Created
August 11, 2021 22:29
-
-
Save kammce/f05692e9b50240744525b64c53b1a7c8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cinttypes> | |
#include <cstdio> | |
#include <functional> | |
namespace embed { | |
/// An empty settings structure used to indicate that a module or interface does | |
/// not have generic settings. | |
struct empty_settings {}; | |
/// The basis class for all peripheral, device and system drivers in SJSU-Dev2. | |
template <class Settings = empty_settings> class module { | |
public: | |
void initialize() { module_initialize(); } | |
Settings &settings() { return m_settings; } | |
protected: | |
virtual void module_initialize() = 0; | |
Settings m_settings; | |
}; | |
struct pin_settings { | |
enum class resistor { | |
none, | |
pull_down, | |
pull_up, | |
}; | |
enum class trigger { | |
none = 0, | |
falling = 0, | |
rising = 1, | |
both = 2, | |
}; | |
constexpr pin_settings &pull_up() { | |
resistor = resistor::pull_up; | |
return *this; | |
} | |
constexpr pin_settings &pull_Down() { | |
resistor = resistor::pull_down; | |
return *this; | |
} | |
constexpr pin_settings &floating() { | |
resistor = resistor::none; | |
return *this; | |
} | |
int function = -1; | |
bool open_drain = false; | |
resistor resistor = resistor::pull_up; | |
}; | |
class gpio : public module<pin_settings> { | |
public: | |
enum class pin_direction { | |
input, | |
output, | |
}; | |
enum class state { | |
low = 0, | |
high = 1, | |
}; | |
enum class trigger { | |
falling = 0, | |
rising = 1, | |
both = 2, | |
}; | |
virtual void direction(pin_direction p_direction) = 0; | |
virtual pin_direction direction() = 0; | |
virtual void level(state p_level) = 0; | |
virtual state level() = 0; | |
virtual void attach_interrupt(std::function<void(void)> p_callback, | |
trigger p_trigger) = 0; | |
virtual void detach_interrupt() = 0; | |
void high() { level(state::high); } | |
void low() { level(state::low); } | |
bool is_high() { return state::high == level(); } | |
bool is_low() { return state::low == level(); } | |
void output() { direction(pin_direction::output); } | |
void input() { direction(pin_direction::input); } | |
bool is_output() { return pin_direction::output == direction(); } | |
bool is_input() { return pin_direction::input == direction(); } | |
void on_falling_edge(std::function<void(void)> p_callback) { | |
attach_interrupt(p_callback, trigger::falling); | |
} | |
void on_rising_edge(std::function<void(void)> p_callback) { | |
attach_interrupt(p_callback, trigger::rising); | |
} | |
void on_both_edges(std::function<void(void)> p_callback) { | |
attach_interrupt(p_callback, trigger::both); | |
} | |
}; | |
namespace lpc40xx { | |
class gpio : public embed::gpio { | |
public: | |
void module_initialize() override { printf("MODULE INITIALIZE!\n"); } | |
void direction(pin_direction p_direction) override { | |
m_direction = p_direction; | |
} | |
pin_direction direction() override { return m_direction; } | |
void level(state p_level) override { m_level = p_level; } | |
state level() override { return m_level; } | |
void attach_interrupt(std::function<void(void)> p_callback, | |
trigger p_trigger) { | |
m_callback = p_callback; | |
printf("ATTACHING INTERRUPT with %d!\n", static_cast<int>(p_trigger)); | |
} | |
void detach_interrupt() { printf("DETACHING INTERRUPT!\n"); } | |
void manual_trigger() { m_callback(); } | |
private: | |
pin_direction m_direction = pin_direction::output; | |
state m_level = state::high; | |
std::function<void(void)> m_callback; | |
}; | |
} // namespace lpc40xx | |
} // namespace embed | |
int main() { | |
embed::lpc40xx::gpio gpio; | |
gpio.settings().pull_up(); | |
gpio.initialize(); | |
gpio.output(); | |
gpio.high(); | |
printf("level = %d\n", static_cast<int>(gpio.level())); | |
gpio.low(); | |
printf("level = %d\n", static_cast<int>(gpio.level())); | |
gpio.on_falling_edge([]() { puts("I'm a callback!\n"); }); | |
gpio.manual_trigger(); | |
printf("sizeof(std::function<void(void)>) == %zu\n", | |
sizeof(std::function<void(void)>)); | |
printf("sizeof(gpio) == %zu\n", sizeof(gpio)); | |
printf("sizeof(pin_settings) == %zu\n", sizeof(embed::pin_settings)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment