4.2inch e-Paper HAT (C) made by WAVESHARE
Dependents: ePD_4R2inch_test_program_on_nRF52
Diff: epd2in13c.cpp
- Revision:
- 0:825022100d0f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/epd2in13c.cpp Tue Apr 30 02:08:41 2019 +0000 @@ -0,0 +1,309 @@ +/** + * @filename : epd2in9b.cpp + * @brief : Implements for Dual-color e-paper library + * @author : Yehui from Waveshare + * + * Copyright (C) Waveshare August 10 2017 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documnetation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* + * Modified by Kenji Arai / JH1PJL + * + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * Created: April 27th, 2019 + * Revised: April 30th, 2019 + * + * Refrence software + * https://github.com/waveshare/e-Paper + * https://os.mbed.com/users/imachooon/code/epd1in54/ + * + * Technical documents + * https://www.waveshare.com/wiki/2.13inch_e-Paper_HAT_(B) + * + * Product + * http://akizukidenshi.com/catalog/g/gP-13757/ + * https://www.waveshare.com/2.13inch-e-paper-hat-b.htm + * + */ + +#include "epd2in13c.h" + +Epd::Epd(PinName mosi, + PinName miso, + PinName sclk, + PinName cs, + PinName dc, + PinName rst, + PinName busy, + PinName pwr + ):EpdIf(mosi, miso, sclk, cs, dc, rst, busy, pwr) +{ + width = EPD_WIDTH; + height = EPD_HEIGHT; +}; + +int Epd::Init(void) +{ + /* this calls the peripheral hardware interface, see epdif */ + if (IfInit() != 0) { + return -1; + } + /* EPD hardware init start */ + Reset(); + SendCommand(BOOSTER_SOFT_START); + SendData(0x17); + SendData(0x17); + SendData(0x17); + SendCommand(POWER_ON); + WaitUntilIdle(); + SendCommand(PANEL_SETTING); + SendData(0x8F); + SendCommand(VCOM_AND_DATA_INTERVAL_SETTING); + SendData(0x37); + SendCommand(RESOLUTION_SETTING); + SendData(0x68); // width: 104 + SendData(0x00); + SendData(0xD4); // height: 212 + /* EPD hardware init end */ + return 0; +} + +/** + * @brief: basic function for sending commands + */ +void Epd::SendCommand(unsigned char command) +{ + DigitalWrite(m_dc, LOW); + SpiTransfer(command); +} + +/** + * @brief: basic function for sending data + */ +void Epd::SendData(unsigned char data) +{ + DigitalWrite(m_dc, HIGH); + SpiTransfer(data); +} + +/** + * @brief: Wait until the busy_pin goes HIGH + */ +void Epd::WaitUntilIdle(void) +{ + while(DigitalRead(m_busy) == 0) { //0: busy, 1: idle + DelayMs(100); + } +} + +/** + * @brief: module reset. + * often used to awaken the module in deep sleep, + * see Epd::Sleep(); + */ +void Epd::Reset(void) +{ + DigitalWrite(m_rst, LOW); + DelayMs(200); + DigitalWrite(m_rst, HIGH); + DelayMs(200); +} + +/** + * @brief: transmit partial data to the SRAM + */ +void Epd::SetPartialWindow(const unsigned char* buffer_black, const unsigned char* buffer_yellow, int x, int y, int w, int l) +{ + SendCommand(PARTIAL_IN); + SendCommand(PARTIAL_WINDOW); + SendData(x & 0xf8); // x should be the multiple of 8, the last 3 bit will always be ignored + SendData(((x & 0xf8) + w - 1) | 0x07); + SendData(y >> 8); + SendData(y & 0xff); + SendData((y + l - 1) >> 8); + SendData((y + l - 1) & 0xff); + SendData(0x01); // Gates scan both inside and outside of the partial window. (default) + DelayMs(2); + SendCommand(DATA_START_TRANSMISSION_1); + if (buffer_black != NULL) { + for(int i = 0; i < w / 8 * l; i++) { + SendData(buffer_black[i]); + } + } else { + for(int i = 0; i < w / 8 * l; i++) { + SendData(0x00); + } + } + DelayMs(2); + SendCommand(DATA_START_TRANSMISSION_2); + if (buffer_yellow != NULL) { + for(int i = 0; i < w / 8 * l; i++) { + SendData(buffer_yellow[i]); + } + } else { + for(int i = 0; i < w / 8 * l; i++) { + SendData(0x00); + } + } + DelayMs(2); + SendCommand(PARTIAL_OUT); +} + +/** + * @brief: transmit partial data to the black part of SRAM + */ +void Epd::SetPartialWindowBlack(const unsigned char* buffer_black, int x, int y, int w, int l) +{ + SendCommand(PARTIAL_IN); + SendCommand(PARTIAL_WINDOW); + SendData(x & 0xf8); // x should be the multiple of 8, the last 3 bit will always be ignored + SendData(((x & 0xf8) + w - 1) | 0x07); + SendData(y >> 8); + SendData(y & 0xff); + SendData((y + l - 1) >> 8); + SendData((y + l - 1) & 0xff); + SendData(0x01); // Gates scan both inside and outside of the partial window. (default) + DelayMs(2); + SendCommand(DATA_START_TRANSMISSION_1); + if (buffer_black != NULL) { + for(int i = 0; i < w / 8 * l; i++) { + SendData(buffer_black[i]); + } + } else { + for(int i = 0; i < w / 8 * l; i++) { + SendData(0x00); + } + } + DelayMs(2); + SendCommand(PARTIAL_OUT); +} + +/** + * @brief: transmit partial data to the yellow part of SRAM + */ +void Epd::SetPartialWindowYellow(const unsigned char* buffer_yellow, int x, int y, int w, int l) +{ + SendCommand(PARTIAL_IN); + SendCommand(PARTIAL_WINDOW); + SendData(x & 0xf8); // x should be the multiple of 8, the last 3 bit will always be ignored + SendData(((x & 0xf8) + w - 1) | 0x07); + SendData(y >> 8); + SendData(y & 0xff); + SendData((y + l - 1) >> 8); + SendData((y + l - 1) & 0xff); + SendData(0x01); // Gates scan both inside and outside of the partial window. (default) + DelayMs(2); + SendCommand(DATA_START_TRANSMISSION_2); + if (buffer_yellow != NULL) { + for(int i = 0; i < w / 8 * l; i++) { + SendData(buffer_yellow[i]); + } + } else { + for(int i = 0; i < w / 8 * l; i++) { + SendData(0x00); + } + } + DelayMs(2); + SendCommand(PARTIAL_OUT); +} + +/** + * @brief: refresh and displays the frame + */ +void Epd::DisplayFrame(const unsigned char* frame_buffer_black, const unsigned char* frame_buffer_yellow) +{ + if (frame_buffer_black != NULL) { + SendCommand(DATA_START_TRANSMISSION_1); + DelayMs(2); + for (int i = 0; i < this->width * this->height / 8; i++) { + SendData(*(frame_buffer_black + i)); + } + DelayMs(2); + } + if (frame_buffer_yellow != NULL) { + SendCommand(DATA_START_TRANSMISSION_2); + DelayMs(2); + for (int i = 0; i < this->width * this->height / 8; i++) { + SendData(*(frame_buffer_yellow + i)); + } + DelayMs(2); + } + SendCommand(DISPLAY_REFRESH); + WaitUntilIdle(); +} + +/** + * @brief: clear the frame data from the SRAM, this won't refresh the display + */ +void Epd::ClearFrame(void) +{ + SendCommand(DATA_START_TRANSMISSION_1); + DelayMs(2); + for(int i = 0; i < width * height / 8; i++) { + SendData(0xFF); + } + DelayMs(2); + SendCommand(DATA_START_TRANSMISSION_2); + DelayMs(2); + for(int i = 0; i < width * height / 8; i++) { + SendData(0xFF); + } + DelayMs(2); +} + +/** + * @brief: This displays the frame data from SRAM + */ +void Epd::DisplayFrame(void) +{ + SendCommand(DISPLAY_REFRESH); + WaitUntilIdle(); +} + +/** + * @brief: After this command is transmitted, the chip would enter the deep-sleep mode to save power. + * The deep sleep mode would return to standby by hardware reset. The only one parameter is a + * check code, the command would be executed if check code = 0xA5. + * You can use Epd::Reset() to awaken and use Epd::Init() to initialize. + */ +void Epd::Sleep() +{ + SendCommand(POWER_OFF); + WaitUntilIdle(); + SendCommand(DEEP_SLEEP); + SendData(0xA5); // check code +} + +/** + * @brief: e-Paper power control + */ +void Epd::PwrOn() +{ + DigitalWrite(m_pwr, 1); +} + +void Epd::PwrOff() +{ + DigitalWrite(m_pwr, 0); +} + +/* END OF FILE */