#pragma once #include "../io/io.hpp" namespace spi { template class Hardware { public: static void init() { if constexpr (Cfg::SIDE == Side::MASTER) { sm_ss = true; sm_sck.dir(io::Dir::OUT); sm_miso.dir(io::Dir::IN); sm_miso.pullup(Cfg::PULLUP); sm_mosi.dir(io::Dir::OUT); sm_ss.dir(io::Dir::OUT); } else { sm_sck.dir(io::Dir::IN); sm_miso.dir(io::Dir::OUT); sm_mosi.dir(io::Dir::IN); sm_ss.dir(io::Dir::IN); sm_ss.pullup(true); } setClockDiv(); setMode(); setMaster(); setBitOrder(); SPCR |= (1 << SPE); } private: static io::Pin sm_sck; static io::Pin sm_miso; static io::Pin sm_mosi; static io::Pin sm_ss; static void setClockDiv() { uint8_t ui8ClockDiv = static_cast(Cfg::FREQ); if (ui8ClockDiv & 1) { SPCR |= (1 << SPR0); } else { SPCR &= ~(1 << SPR0); } if (ui8ClockDiv & (1 << 1)) { SPCR |= (1 << SPR1); } else { SPCR &= ~(1 << SPR1); } if (ui8ClockDiv & (1 << 2)) { SPSR |= (1 << SPI2X); } else { SPSR &= ~(1 << SPI2X); } } static void setMode() { if (Cfg::MODE == Mode::MODE_0 || Cfg::MODE == Mode::MODE_1) { setCPOL(false); } else { setCPOL(true); } if (Cfg::MODE == Mode::MODE_0 || Cfg::MODE == Mode::MODE_2) { setCPHA(false); } else { setCPHA(true); } } static void setMaster() { if constexpr (Cfg::SIDE == Side::MASTER) { SPCR |= (1 << MSTR); } else { SPCR &= ~(1 << MSTR); } } static void setBitOrder() { if (Cfg::BIT_ORDER == BitOrder::LSB_FIRST) { SPCR |= (1 << DORD); } else { SPCR &= ~(1 << DORD); } } static void setCPOL(bool bCPOL) { if (bCPOL) { SPCR |= (1 << CPOL); } else { SPCR &= ~(1 << CPOL); } } static void setCPHA(bool bCPHA) { if (bCPHA) { SPCR |= (1 << CPHA); } else { SPCR &= ~(1 << CPHA); } } }; } // namespace spi