#pragma once #include #include #include "../clock.hpp" #include "../io/io.hpp" template class Epd { static constexpr auto width = uint16_t{200}; static constexpr auto height = uint16_t{200}; io::Pin m_rst; io::Pin m_dc; io::Pin m_bsy; public: Epd() = default; ~Epd() = default; int Init() { m_rst.dir(io::Dir::OUT); m_dc.dir(io::Dir::OUT); m_bsy.dir(io::Dir::IN); Spi::init(); /* EPD hardware init start */ Reset(); WaitUntilIdle(); SendCommand(0x12); // SWRESET WaitUntilIdle(); SendCommand(0x01); // Driver output control SendData(0xC7); SendData(0x00); SendData(0x01); SendCommand(0x11); // data entry mode SendData(0x01); SendCommand(0x44); // set Ram-X address start/end position SendData(0x00); SendData(0x18); // 0x18-->(24+1)*8=200 SendCommand(0x45); // set Ram-Y address start/end position SendData(0xC7); // 0xC7-->(199+1)=200 SendData(0x00); SendData(0x00); SendData(0x00); SendCommand(0x3C); // BorderWavefrom SendData(0x05); SendCommand(0x18); // Read built-in temperature sensor SendData(0x80); SendCommand(0x4E); // set RAM x address count to 0; SendData(0x00); SendCommand(0x4F); // set RAM y address count to 0X199; SendData(0xC7); SendData(0x00); WaitUntilIdle(); /* EPD hardware init end */ return 0; } void SendCommand(unsigned char command) { m_dc = false; SpiTransfer(command); } void SendData(unsigned char data) { m_dc = true; SpiTransfer(data); } void WaitUntilIdle() { while (m_bsy) { _delay_ms(100); } } void Reset() { m_rst = true; _delay_ms(200); m_rst = false; // module reset _delay_ms(10); m_rst = true; _delay_ms(200); } void DisplayFrame(const unsigned char *frame_buffer_black, const unsigned char *frame_buffer_red) { SendCommand(0x24); for (auto i = uint16_t{0}; i < width * height / 8; i++) { SendData(pgm_read_byte(&frame_buffer_black[i])); } SendCommand(0x26); for (auto i = uint16_t{0}; i < width * height / 8; i++) { SendData(~pgm_read_byte(&frame_buffer_red[i])); } SendCommand(0x22); SendData(0xF7); SendCommand(0x20); WaitUntilIdle(); } void DisplayClear() { SendCommand(0x24); for (auto i = uint16_t{0}; i < width * height / 8; i++) { SendData(0xff); } SendCommand(0x26); for (auto i = uint16_t{0}; i < width * height / 8; i++) { SendData(0x00); } SendCommand(0x22); SendData(0xF7); SendCommand(0x20); WaitUntilIdle(); } void Sleep() { SendCommand(0x10); // power setting SendData(0x01); // gate switch to external _delay_ms(100); } void SpiTransfer(unsigned char data) { Spi::select(true); Spi::transfer(data); Spi::select(false); } };