add 2in13_V3 example code (Arduino)
This commit is contained in:
parent
9c097b5cc3
commit
9896ad819c
16 changed files with 10268 additions and 38 deletions
381
Arduino/epd2in13_V3/epd2in13_V3.cpp
Normal file
381
Arduino/epd2in13_V3/epd2in13_V3.cpp
Normal file
|
|
@ -0,0 +1,381 @@
|
|||
/*****************************************************************************
|
||||
* | File : epd2in13_V3.cpp
|
||||
* | Author : Waveshare team
|
||||
* | Function : 2.13inch e-paper V3
|
||||
* | Info :
|
||||
*----------------
|
||||
* | This version: V1.0
|
||||
* | Date : 2021-11-01
|
||||
* | Info :
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include "epd2in13_V3.h"
|
||||
|
||||
const unsigned char lut_full_update[]= {
|
||||
0x80, 0x4A, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x40, 0x4A, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x80, 0x4A, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x40, 0x4A, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0xF, 0x0, 0x0, 0xF, 0x0, 0x0, 0x2,
|
||||
0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
|
||||
0x22, 0x17, 0x41, 0x0, 0x32, 0x36
|
||||
};
|
||||
|
||||
const unsigned char lut_partial_update[]= {
|
||||
0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x14,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x1,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x1,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
||||
0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
|
||||
0x22,0x17,0x41,0x00,0x32,0x36,
|
||||
};
|
||||
|
||||
Epd::~Epd()
|
||||
{
|
||||
};
|
||||
|
||||
Epd::Epd()
|
||||
{
|
||||
reset_pin = RST_PIN;
|
||||
dc_pin = DC_PIN;
|
||||
cs_pin = CS_PIN;
|
||||
busy_pin = BUSY_PIN;
|
||||
width = EPD_WIDTH;
|
||||
height = EPD_HEIGHT;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief: basic function for sending commands
|
||||
*/
|
||||
void Epd::SendCommand(unsigned char command)
|
||||
{
|
||||
DigitalWrite(dc_pin, LOW);
|
||||
SpiTransfer(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: basic function for sending data
|
||||
*/
|
||||
void Epd::SendData(unsigned char data)
|
||||
{
|
||||
DigitalWrite(dc_pin, HIGH);
|
||||
SpiTransfer(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: Wait until the busy_pin goes HIGH
|
||||
*/
|
||||
void Epd::WaitUntilIdle(void)
|
||||
{
|
||||
while(1) { //LOW: idle, HIGH: busy
|
||||
if(DigitalRead(busy_pin) == 0)
|
||||
break;
|
||||
DelayMs(10);
|
||||
}
|
||||
}
|
||||
|
||||
void Epd::SetWindows(unsigned char Xstart, unsigned char Ystart, unsigned char Xend, unsigned char Yend)
|
||||
{
|
||||
SendCommand(0x44); // SET_RAM_X_ADDRESS_START_END_POSITION
|
||||
SendData((Xstart>>3) & 0xFF);
|
||||
SendData((Xend>>3) & 0xFF);
|
||||
|
||||
SendCommand(0x45); // SET_RAM_Y_ADDRESS_START_END_POSITION
|
||||
SendData(Ystart & 0xFF);
|
||||
SendData((Ystart >> 8) & 0xFF);
|
||||
SendData(Yend & 0xFF);
|
||||
SendData((Yend >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
void Epd::SetCursor(unsigned char Xstart, unsigned char Ystart)
|
||||
{
|
||||
SendCommand(0x4E); // SET_RAM_X_ADDRESS_COUNTER
|
||||
SendData(Xstart & 0xFF);
|
||||
|
||||
SendCommand(0x4F); // SET_RAM_Y_ADDRESS_COUNTER
|
||||
SendData(Ystart & 0xFF);
|
||||
SendData((Ystart >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
void Epd::Lut(unsigned char *lut)
|
||||
{
|
||||
unsigned char count;
|
||||
SendCommand(0x32);
|
||||
for(count = 0; count < 153; count++) {
|
||||
SendData(lut[count]);
|
||||
}
|
||||
|
||||
SendCommand(0x3f);
|
||||
SendData(*(lut+153));
|
||||
SendCommand(0x03); // gate voltage
|
||||
SendData(*(lut+154));
|
||||
SendCommand(0x04); // source voltage
|
||||
SendData(*(lut+155)); // VSH
|
||||
SendData(*(lut+156)); // VSH2
|
||||
SendData(*(lut+157)); // VSL
|
||||
SendCommand(0x2c); // VCOM
|
||||
SendData(*(lut+158));
|
||||
}
|
||||
|
||||
int Epd::Init(char Mode)
|
||||
{
|
||||
/* this calls the peripheral hardware interface, see epdif */
|
||||
if (IfInit() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reset();
|
||||
|
||||
int count;
|
||||
if(Mode == FULL) {
|
||||
WaitUntilIdle();
|
||||
SendCommand(0x12); // soft reset
|
||||
WaitUntilIdle();
|
||||
|
||||
SendCommand(0x01); //Driver output control
|
||||
SendData(0xF9);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
|
||||
SendCommand(0x11); //data entry mode
|
||||
SendData(0x03);
|
||||
|
||||
SetWindows(0, 0, EPD_WIDTH-1, EPD_HEIGHT-1);
|
||||
SetCursor(0, 0);
|
||||
|
||||
SendCommand(0x3C); //BorderWavefrom
|
||||
SendData(0x05);
|
||||
|
||||
SendCommand(0x21); // Display update control
|
||||
SendData(0x00);
|
||||
SendData(0x80);
|
||||
|
||||
SendCommand(0x18); //Read built-in temperature sensor
|
||||
SendData(0x80);
|
||||
|
||||
WaitUntilIdle();
|
||||
Lut(lut_full_update);
|
||||
} else if(Mode == PART) {
|
||||
|
||||
DigitalWrite(reset_pin, LOW); //module reset
|
||||
DelayMs(1);
|
||||
DigitalWrite(reset_pin, HIGH);
|
||||
|
||||
Lut(lut_partial_update);
|
||||
|
||||
SendCommand(0x37);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x40);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
|
||||
SendCommand(0x3C); //BorderWavefrom
|
||||
SendData(0x80);
|
||||
|
||||
SendCommand(0x22); //Display Update Sequence Option
|
||||
SendData(0xC0); // Enable clock and Enable analog
|
||||
SendCommand(0x20); //Activate Display Update Sequence
|
||||
WaitUntilIdle();
|
||||
|
||||
SetWindows(0, 0, EPD_WIDTH-1, EPD_HEIGHT-1);
|
||||
SetCursor(0, 0);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: module reset.
|
||||
* often used to awaken the module in deep sleep,
|
||||
* see Epd::Sleep();
|
||||
*/
|
||||
void Epd::Reset(void)
|
||||
{
|
||||
DigitalWrite(reset_pin, HIGH);
|
||||
DelayMs(20);
|
||||
DigitalWrite(reset_pin, LOW); //module reset
|
||||
DelayMs(2);
|
||||
DigitalWrite(reset_pin, HIGH);
|
||||
DelayMs(20);
|
||||
}
|
||||
|
||||
void Epd::Clear(void)
|
||||
{
|
||||
int w, h;
|
||||
w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
|
||||
h = EPD_HEIGHT;
|
||||
SendCommand(0x24);
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
SendData(0xff);
|
||||
}
|
||||
}
|
||||
|
||||
//DISPLAY REFRESH
|
||||
SendCommand(0x22);
|
||||
SendData(0xC7);
|
||||
SendCommand(0x20);
|
||||
WaitUntilIdle();
|
||||
}
|
||||
|
||||
void Epd::Display(const unsigned char* frame_buffer)
|
||||
{
|
||||
int w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
|
||||
int h = EPD_HEIGHT;
|
||||
|
||||
if (frame_buffer != NULL) {
|
||||
SendCommand(0x24);
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
SendData(pgm_read_byte(&frame_buffer[i + j * w]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//DISPLAY REFRESH
|
||||
SendCommand(0x22);
|
||||
SendData(0xC7);
|
||||
SendCommand(0x20);
|
||||
WaitUntilIdle();
|
||||
}
|
||||
|
||||
void Epd::DisplayPartBaseImage(const unsigned char* frame_buffer)
|
||||
{
|
||||
int w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
|
||||
int h = EPD_HEIGHT;
|
||||
|
||||
if (frame_buffer != NULL) {
|
||||
SendCommand(0x24);
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
SendData(pgm_read_byte(&frame_buffer[i + j * w]));
|
||||
}
|
||||
}
|
||||
|
||||
SendCommand(0x26);
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
SendData(pgm_read_byte(&frame_buffer[i + j * w]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//DISPLAY REFRESH
|
||||
SendCommand(0x22);
|
||||
SendData(0xC7);
|
||||
SendCommand(0x20);
|
||||
WaitUntilIdle();
|
||||
}
|
||||
|
||||
void Epd::DisplayPart(const unsigned char* frame_buffer)
|
||||
{
|
||||
int w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
|
||||
int h = EPD_HEIGHT;
|
||||
|
||||
if (frame_buffer != NULL) {
|
||||
SendCommand(0x24);
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
SendData(pgm_read_byte(&frame_buffer[i + j * w]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//DISPLAY REFRESH
|
||||
SendCommand(0x22);
|
||||
SendData(0x0f);
|
||||
SendCommand(0x20);
|
||||
WaitUntilIdle();
|
||||
}
|
||||
|
||||
void Epd::ClearPart(void)
|
||||
{
|
||||
int w, h;
|
||||
w = (EPD_WIDTH % 8 == 0)? (EPD_WIDTH / 8 ): (EPD_WIDTH / 8 + 1);
|
||||
h = EPD_HEIGHT;
|
||||
SendCommand(0x24);
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
SendData(0xff);
|
||||
}
|
||||
}
|
||||
|
||||
//DISPLAY REFRESH
|
||||
SendCommand(0x22);
|
||||
SendData(0x0f);
|
||||
SendCommand(0x20);
|
||||
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::Init() to awaken
|
||||
*/
|
||||
void Epd::Sleep()
|
||||
{
|
||||
SendCommand(0x10); //enter deep sleep
|
||||
SendData(0x01);
|
||||
DelayMs(200);
|
||||
|
||||
DigitalWrite(reset_pin, LOW);
|
||||
}
|
||||
|
||||
/* END OF FILE */
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue