Merge pull request #273 from SSYYL/master

Added new programs 2.7inch V2 e-Paper routine.
This commit is contained in:
Wilson 2022-11-01 10:48:07 +08:00 committed by GitHub
commit 0e47b883bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 23009 additions and 987 deletions

View file

@ -0,0 +1,585 @@
/**
* @filename : epd2in7_V2.cpp
* @brief : Implements for e-paper library
* @author : Waveshare
*
* Copyright (C) Waveshare September 20 2022
*
* 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 "epd2in7_V2.h"
static const unsigned char LUT_DATA_4Gray[159] =
{
0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x8, 0x48, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x2, 0x48, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x20, 0x48, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xA, 0x19, 0x0, 0x3, 0x8, 0x0, 0x0,
0x14, 0x1, 0x0, 0x14, 0x1, 0x0, 0x3,
0xA, 0x3, 0x0, 0x8, 0x19, 0x0, 0x0,
0x1, 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,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
0x22, 0x17, 0x41, 0x0, 0x32, 0x1C
};
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;
};
int Epd::Init(void) {
/* this calls the peripheral hardware interface, see epdif */
if (IfInit() != 0) {
return -1;
}
Reset();
ReadBusy();
SendCommand(0x12); //SWRESET
ReadBusy();
SendCommand(0x45); //set Ram-Y address start/end position
SendData(0x00);
SendData(0x00);
SendData(0x07); //0x0107-->(263+1)=264
SendData(0x01);
SendCommand(0x4F); // set RAM y address count to 0;
SendData(0x00);
SendData(0x00);
SendCommand(0x11); // data entry mode
SendData(0x03);
return 0;
}
int Epd::Init_Fast(void) {
/* this calls the peripheral hardware interface, see epdif */
if (IfInit() != 0) {
return -1;
}
Reset();
ReadBusy();
SendCommand(0x12); //SWRESET
ReadBusy();
SendCommand(0x18); //Read built-in temperature sensor
SendData(0x80);
SendCommand(0x22); // Load temperature value
SendData(0xB1);
SendCommand(0x20);
ReadBusy();
SendCommand(0x1A); // Write to temperature register
SendData(0x64);
SendData(0x00);
SendCommand(0x45); //set Ram-Y address start/end position
SendData(0x00);
SendData(0x00);
SendData(0x07); //0x0107-->(263+1)=264
SendData(0x01);
SendCommand(0x4F); // set RAM y address count to 0;
SendData(0x00);
SendData(0x00);
SendCommand(0x11); // data entry mode
SendData(0x03);
SendCommand(0x22); // Load temperature value
SendData(0x91);
SendCommand(0x20);
ReadBusy();
return 0;
}
void Epd::Init_4Gray(void)
{
Reset();
ReadBusy();
SendCommand(0x12); // soft reset
ReadBusy();
SendCommand(0x74); //set analog block control
SendData(0x54);
SendCommand(0x7E); //set digital block control
SendData(0x3B);
SendCommand(0x01); //Driver output control
SendData(0x07);
SendData(0x01);
SendData(0x00);
SendCommand(0x11); //data entry mode
SendData(0x03);
SendCommand(0x44); //set Ram-X address start/end position
SendData(0x00);
SendData(0x15); //0x15-->(21+1)*8=176
SendCommand(0x45); //set Ram-Y address start/end position
SendData(0x00);
SendData(0x00);
SendData(0x07);//0x0107-->(263+1)=264
SendData(0x01);
SendCommand(0x3C); //BorderWavefrom
SendData(0x00);
SendCommand(0x2C); //VCOM Voltage
SendData(LUT_DATA_4Gray[158]); //0x1C
SendCommand(0x3F); //EOPQ
SendData(LUT_DATA_4Gray[153]);
SendCommand(0x03); //VGH
SendData(LUT_DATA_4Gray[154]);
SendCommand(0x04); //
SendData(LUT_DATA_4Gray[155]); //VSH1
SendData(LUT_DATA_4Gray[156]); //VSH2
SendData(LUT_DATA_4Gray[157]); //VSL
Lut(); //LUT
SendCommand(0x4E); // set RAM x address count to 0;
SendData(0x00);
SendCommand(0x4F); // set RAM y address count to 0X199;
SendData(0x00);
SendData(0x00);
ReadBusy();
}
/**
* @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::ReadBusy(void) {
Serial.print("e-Paper busy\r\n");
while(DigitalRead(busy_pin) == 1) { //1: busy, 0: idle
DelayMs(100);
}
Serial.print("e-Paper busy release\r\n");
}
/**
* @brief: module reset.
* often used to awaken the module in deep sleep,
* see Epd::Sleep();
*/
void Epd::Reset(void) {
DigitalWrite(reset_pin, HIGH);
DelayMs(200);
DigitalWrite(reset_pin, LOW);
DelayMs(2);
DigitalWrite(reset_pin, HIGH);
DelayMs(200);
}
/**
* @brief: set the look-up tables
*/
void Epd::Lut(void) {
unsigned int count;
SendCommand(0x32); //vcom
for(count = 0; count < 153; count++) {
SendData(LUT_DATA_4Gray[count]);
}
}
/******************************************************************************
function : Turn on display
parameter:
******************************************************************************/
void Epd::TurnOnDisplay(void)
{
SendCommand(0x22); //Display Update Control
SendData(0xF7);
SendCommand(0x20); //Activate Display Update Sequence
ReadBusy();
}
void Epd::TurnOnDisplay_Fast(void)
{
SendCommand(0x22); //Display Update Control
SendData(0xC7);
SendCommand(0x20); //Activate Display Update Sequence
ReadBusy();
}
void Epd::TurnOnDisplay_Partial(void)
{
SendCommand(0x22);
SendData(0xFF);
SendCommand(0x20);
ReadBusy();
}
void Epd::TurnOnDisplay_4GRAY(void)
{
SendCommand(0x22);
SendData(0xC7);
SendCommand(0x20);
ReadBusy();
}
/******************************************************************************
function : Clear screen
parameter:
******************************************************************************/
void Epd::Clear(void)
{
unsigned int Width, Height;
Width = (WIDTH % 8 == 0)? (WIDTH / 8 ): (WIDTH / 8 + 1);
Height = HEIGHT;
SendCommand(0x24);
for (unsigned int j = 0; j < Height; j++) {
for (unsigned int i = 0; i < Width; i++) {
SendData(0XFF);
}
}
TurnOnDisplay();
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void Epd::Display(const unsigned char* Image)
{
unsigned int Width, Height;
Width = (WIDTH % 8 == 0)? (WIDTH / 8 ): (WIDTH / 8 + 1);
Height = HEIGHT;
SendCommand(0x24);
for (unsigned int j = 0; j < Height; j++) {
for (unsigned int i = 0; i < Width; i++) {
SendData(pgm_read_byte(&Image[i + j * Width]));
}
}
TurnOnDisplay();
}
void Epd::Display_Fast(const unsigned char* Image)
{
unsigned int Width, Height;
Width = (WIDTH % 8 == 0)? (WIDTH / 8 ): (WIDTH / 8 + 1);
Height = HEIGHT;
SendCommand(0x24);
for (unsigned int j = 0; j < Height; j++) {
for (unsigned int i = 0; i < Width; i++) {
SendData(pgm_read_byte(&Image[i + j * Width]));
}
}
TurnOnDisplay_Fast();
}
void Epd::Display_Base(const unsigned char* Image)
{
unsigned int Width, Height;
Width = (WIDTH % 8 == 0)? (WIDTH / 8 ): (WIDTH / 8 + 1);
Height = HEIGHT;
SendCommand(0x24); //Write Black and White image to RAM
for (unsigned int j = 0; j < Height; j++) {
for (unsigned int i = 0; i < Width; i++) {
SendData(pgm_read_byte(&Image[i + j * Width]));
}
}
SendCommand(0x26); //Write Black and White image to RAM
for (unsigned int j = 0; j < Height; j++) {
for (unsigned int i = 0; i < Width; i++) {
SendData(pgm_read_byte(&Image[i + j * Width]));
}
}
TurnOnDisplay();
}
void Epd::Display_Base_color(unsigned char color)
{
unsigned int Width, Height;
Width = (WIDTH % 8 == 0)? (WIDTH / 8 ): (WIDTH / 8 + 1);
Height = HEIGHT;
SendCommand(0x24); //Write Black and White image to RAM
for (unsigned int j = 0; j < Height; j++) {
for (unsigned int i = 0; i < Width; i++) {
SendData(color);
}
}
SendCommand(0x26); //Write Black and White image to RAM
for (unsigned int j = 0; j < Height; j++) {
for (unsigned int i = 0; i < Width; i++) {
SendData(color);
}
}
// TurnOnDisplay();
}
void Epd::Display_Partial(unsigned char* Image, unsigned int Xstart, unsigned int Ystart, unsigned int Xend, unsigned int Yend)
{
unsigned int i, Width;
unsigned int IMAGE_COUNTER;
if((Xstart % 8 + Xend % 8 == 8 && Xstart % 8 > Xend % 8) || Xstart % 8 + Xend % 8 == 0 || (Xend - Xstart)%8 == 0)
{
Xstart = Xstart / 8 ;
Xend = Xend / 8;
}
else
{
Xstart = Xstart / 8 ;
Xend = Xend % 8 == 0 ? Xend / 8 : Xend / 8 + 1;
}
Width = Xend - Xstart;
IMAGE_COUNTER = Width * (Yend-Ystart);
Serial.println(IMAGE_COUNTER);
Xend -= 1;
Yend -= 1;
//Reset
Reset();
SendCommand(0x3C); //BorderWavefrom
SendData(0x80);
//
SendCommand(0x44); // set RAM x address start/end, in page 35
SendData(Xstart & 0xff); // RAM x address start at 00h;
SendData(Xend & 0xff); // RAM x address end at 0fh(15+1)*8->128
SendCommand(0x45); // set RAM y address start/end, in page 35
SendData(Ystart & 0xff); // RAM y address start at 0127h;
SendData((Ystart>>8) & 0x01); // RAM y address start at 0127h;
SendData(Yend & 0xff); // RAM y address end at 00h;
SendData((Yend>>8) & 0x01);
SendCommand(0x4E); // set RAM x address count to 0;
SendData(Xstart & 0xff);
SendCommand(0x4F); // set RAM y address count to 0X127;
SendData(Ystart & 0xff);
SendData((Ystart>>8) & 0x01);
SendCommand(0x24); //Write Black and White image to RAM
for (i = 0; i < IMAGE_COUNTER; i++) {
SendData(Image[i]);
}
TurnOnDisplay_Partial();
}
void Epd::Display_Partial_Not_refresh(unsigned char* Image, unsigned int Xstart, unsigned int Ystart, unsigned int Xend, unsigned int Yend)
{
unsigned int i, Width;
unsigned int IMAGE_COUNTER;
if((Xstart % 8 + Xend % 8 == 8 && Xstart % 8 > Xend % 8) || Xstart % 8 + Xend % 8 == 0 || (Xend - Xstart)%8 == 0)
{
Xstart = Xstart / 8 ;
Xend = Xend / 8;
}
else
{
Xstart = Xstart / 8 ;
Xend = Xend % 8 == 0 ? Xend / 8 : Xend / 8 + 1;
}
Width = Xend - Xstart;
IMAGE_COUNTER = Width * (Yend-Ystart);
Serial.println(IMAGE_COUNTER);
Xend -= 1;
Yend -= 1;
//Reset
Reset();
SendCommand(0x3C); //BorderWavefrom
SendData(0x80);
//
SendCommand(0x44); // set RAM x address start/end, in page 35
SendData(Xstart & 0xff); // RAM x address start at 00h;
SendData(Xend & 0xff); // RAM x address end at 0fh(15+1)*8->128
SendCommand(0x45); // set RAM y address start/end, in page 35
SendData(Ystart & 0xff); // RAM y address start at 0127h;
SendData((Ystart>>8) & 0x01); // RAM y address start at 0127h;
SendData(Yend & 0xff); // RAM y address end at 00h;
SendData((Yend>>8) & 0x01);
SendCommand(0x4E); // set RAM x address count to 0;
SendData(Xstart & 0xff);
SendCommand(0x4F); // set RAM y address count to 0X127;
SendData(Ystart & 0xff);
SendData((Ystart>>8) & 0x01);
SendCommand(0x24); //Write Black and White image to RAM
for (i = 0; i < IMAGE_COUNTER; i++) {
SendData(Image[i]);
}
// TurnOnDisplay_Partial();
}
void Epd::Display4Gray(const unsigned char *Image)
{
int i,j,k;
unsigned char temp1,temp2,temp3;
SendCommand(0x24);
for(i=0;i<5808;i++) //5808*4 46464
{
temp3=0;
for(j=0;j<2;j++)
{
temp1 = pgm_read_byte(&Image[i*2+j]);
for(k=0;k<2;k++)
{
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x00;//white
else if(temp2 == 0x00)
temp3 |= 0x01; //black
else if(temp2 == 0x80)
temp3 |= 0x01; //gray1
else //0x40
temp3 |= 0x00; //gray2
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0) //white
temp3 |= 0x00;
else if(temp2 == 0x00) //black
temp3 |= 0x01;
else if(temp2 == 0x80)
temp3 |= 0x01; //gray1
else //0x40
temp3 |= 0x00; //gray2
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
SendData(temp3);
}
// new data
SendCommand(0x26);
for(i=0;i<5808;i++) //5808*4 46464
{
temp3=0;
for(j=0;j<2;j++)
{
temp1 = pgm_read_byte(&Image[i*2+j]);
for(k=0;k<2;k++)
{
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x00;//white
else if(temp2 == 0x00)
temp3 |= 0x01; //black
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1
else //0x40
temp3 |= 0x01; //gray2
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0) //white
temp3 |= 0x00;
else if(temp2 == 0x00) //black
temp3 |= 0x01;
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1
else //0x40
temp3 |= 0x01; //gray2
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
SendData(temp3);
}
TurnOnDisplay_4GRAY();
}
/**
* @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(0X10);
SendData(0x01);
}

View file

@ -0,0 +1,75 @@
/**
* @filename : epd2in7_V2.h
* @brief : Header file for e-paper library epd2in7_V2.cpp
* @author : Waveshare
*
* Copyright (C) Waveshare September 20 2022
*
* 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.
*/
#ifndef EPD2IN7_V2_H
#define EPD2IN7_V2_H
#include "epdif.h"
// Display resolution
#define EPD_WIDTH 176
#define EPD_HEIGHT 264
class Epd : EpdIf {
public:
unsigned int WIDTH;
unsigned int HEIGHT;
Epd();
~Epd();
int Init(void);
int Init_Fast(void);
void Init_4Gray(void);
void SendCommand(unsigned char command);
void SendData(unsigned char data);
void ReadBusy(void);
void Reset(void);
void Lut(void);
void TurnOnDisplay(void);
void TurnOnDisplay_Fast(void);
void TurnOnDisplay_Partial(void);
void TurnOnDisplay_4GRAY(void);
void Clear(void);
void Display(const unsigned char* Image);
void Display_Fast(const unsigned char* Image);
void Display_Base(const unsigned char* Image);
void Display_Base_color(unsigned char color);
void Display_Partial(unsigned char* Image, unsigned int Xstart, unsigned int Ystart, unsigned int Xend, unsigned int Yend);
void Display_Partial_Not_refresh(unsigned char* Image, unsigned int Xstart, unsigned int Ystart, unsigned int Xend, unsigned int Yend);
void Display4Gray(const unsigned char *Image);
void Sleep(void);
private:
unsigned int reset_pin;
unsigned int dc_pin;
unsigned int cs_pin;
unsigned int busy_pin;
};
#endif /* EPD2IN7_H */
/* END OF FILE */

View file

@ -0,0 +1,114 @@
/**
@filename : epd2in7_V2-demo.ino
@brief : 2.7inch e-paper display demo
@author : Waveshare
Copyright (C) Waveshare September 20 2022
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 <SPI.h>
#include "epd2in7_V2.h"
#include "imagedata.h"
#include "epdpaint.h"
#define COLORED 0
#define UNCOLORED 1
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Epd epd;
Serial.print("e-Paper init\r\n");
if (epd.Init() != 0) {
Serial.print("e-Paper init failed\r\n");
return;
}
/* This clears the SRAM of the e-paper display */
epd.Clear();
/**
Due to RAM not enough in Arduino UNO, a frame buffer is not allowed.
In this case, a smaller image buffer is allocated and you have to
update a partial display several times.
1 byte = 8 pixels, therefore you have to set 8*N pixels at a time.
*/
#if 1
epd.Display_Base_color(0xff);
unsigned char image[1024];
Paint paint(image, 176, 24); //width should be the multiple of 8
paint.Clear(UNCOLORED);
paint.DrawStringAt(20, 5, "e-Paper Demo", &Font16, COLORED);
epd.Display_Partial_Not_refresh(paint.GetImage(), 0, 32, 0+paint.GetWidth(), 32+paint.GetHeight());
paint.Clear(COLORED);
paint.DrawStringAt(20, 5, "Hello world!", &Font16, UNCOLORED);
epd.Display_Partial_Not_refresh(paint.GetImage(), 0, 64, 0+paint.GetWidth(), 64+paint.GetHeight());
paint.SetWidth(64);
paint.SetHeight(64);
paint.Clear(UNCOLORED);
paint.DrawRectangle(0, 0, 40, 50, COLORED);
paint.DrawLine(0, 0, 40, 50, COLORED);
paint.DrawLine(40, 0, 0, 50, COLORED);
epd.Display_Partial_Not_refresh(paint.GetImage(), 10, 130, 10+paint.GetWidth(), 130+paint.GetHeight());
paint.Clear(UNCOLORED);
paint.DrawCircle(32, 32, 30, COLORED);
epd.Display_Partial_Not_refresh(paint.GetImage(), 90, 120, 90+paint.GetWidth(), 120+paint.GetHeight());
paint.Clear(UNCOLORED);
paint.DrawFilledRectangle(0, 0, 40, 50, COLORED);
epd.Display_Partial_Not_refresh(paint.GetImage(), 10, 200, 10+paint.GetWidth(), 200+paint.GetHeight());
paint.Clear(UNCOLORED);
paint.DrawFilledCircle(32, 32, 30, COLORED);
epd.Display_Partial(paint.GetImage(), 90, 190, 90+paint.GetWidth(), 190+paint.GetHeight());
delay(1000);
#endif
#if 1
/* This displays an image */
epd.Init();
Serial.print("show 2-gray image\r\n");
epd.Display(IMAGE_DATA);
delay(1000);
#endif
#if 1
Serial.print("show 4-gray image\r\n");
epd.Init_4Gray();
epd.Display4Gray(IMAGE_DATA_4Gray);
#endif
/* Deep sleep */
Serial.print("sleep...");
epd.Sleep();
}
void loop() {
// put your main code here, to run repeatedly:
}

View file

@ -0,0 +1,64 @@
/**
* @filename : epdif.cpp
* @brief : Implements EPD interface functions
* Users have to implement all the functions in epdif.cpp
* @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.
*/
#include "epdif.h"
#include <SPI.h>
EpdIf::EpdIf() {
};
EpdIf::~EpdIf() {
};
void EpdIf::DigitalWrite(int pin, int value) {
digitalWrite(pin, value);
}
int EpdIf::DigitalRead(int pin) {
return digitalRead(pin);
}
void EpdIf::DelayMs(unsigned int delaytime) {
delay(delaytime);
}
void EpdIf::SpiTransfer(unsigned char data) {
digitalWrite(CS_PIN, LOW);
SPI.transfer(data);
digitalWrite(CS_PIN, HIGH);
}
int EpdIf::IfInit(void) {
pinMode(CS_PIN, OUTPUT);
pinMode(RST_PIN, OUTPUT);
pinMode(DC_PIN, OUTPUT);
pinMode(BUSY_PIN, INPUT);
SPI.begin();
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
return 0;
}

View file

@ -0,0 +1,51 @@
/**
* @filename : epdif.h
* @brief : Header file of epdif.cpp providing EPD interface functions
* Users have to implement all the functions in epdif.cpp
* @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.
*/
#ifndef EPDIF_H
#define EPDIF_H
#include <Arduino.h>
// Pin definition
#define RST_PIN 8
#define DC_PIN 9
#define CS_PIN 10
#define BUSY_PIN 7
class EpdIf {
public:
EpdIf(void);
~EpdIf(void);
static int IfInit(void);
static void DigitalWrite(int pin, int value);
static int DigitalRead(int pin);
static void DelayMs(unsigned int delaytime);
static void SpiTransfer(unsigned char data);
};
#endif

View file

@ -0,0 +1,342 @@
/**
* @filename : epdpaint.cpp
* @brief : Paint tools
* @author : Yehui from Waveshare
*
* Copyright (C) Waveshare September 9 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.
*/
#include <avr/pgmspace.h>
#include "epdpaint.h"
Paint::Paint(unsigned char* image, int width, int height) {
this->rotate = ROTATE_0;
this->image = image;
/* 1 byte = 8 pixels, so the width should be the multiple of 8 */
this->width = width % 8 ? width + 8 - (width % 8) : width;
this->height = height;
}
Paint::~Paint() {
}
/**
* @brief: clear the image
*/
void Paint::Clear(int colored) {
for (int x = 0; x < this->width; x++) {
for (int y = 0; y < this->height; y++) {
DrawAbsolutePixel(x, y, colored);
}
}
}
/**
* @brief: this draws a pixel by absolute coordinates.
* this function won't be affected by the rotate parameter.
*/
void Paint::DrawAbsolutePixel(int x, int y, int colored) {
if (x < 0 || x >= this->width || y < 0 || y >= this->height) {
return;
}
if (IF_INVERT_COLOR) {
if (colored) {
image[(x + y * this->width) / 8] |= 0x80 >> (x % 8);
} else {
image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8));
}
} else {
if (colored) {
image[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8));
} else {
image[(x + y * this->width) / 8] |= 0x80 >> (x % 8);
}
}
}
/**
* @brief: Getters and Setters
*/
unsigned char* Paint::GetImage(void) {
return this->image;
}
int Paint::GetWidth(void) {
return this->width;
}
void Paint::SetWidth(int width) {
this->width = width % 8 ? width + 8 - (width % 8) : width;
}
int Paint::GetHeight(void) {
return this->height;
}
void Paint::SetHeight(int height) {
this->height = height;
}
int Paint::GetRotate(void) {
return this->rotate;
}
void Paint::SetRotate(int rotate){
this->rotate = rotate;
}
/**
* @brief: this draws a pixel by the coordinates
*/
void Paint::DrawPixel(int x, int y, int colored) {
int point_temp;
if (this->rotate == ROTATE_0) {
if(x < 0 || x >= this->width || y < 0 || y >= this->height) {
return;
}
DrawAbsolutePixel(x, y, colored);
} else if (this->rotate == ROTATE_90) {
if(x < 0 || x >= this->height || y < 0 || y >= this->width) {
return;
}
point_temp = x;
x = this->width - y;
y = point_temp;
DrawAbsolutePixel(x, y, colored);
} else if (this->rotate == ROTATE_180) {
if(x < 0 || x >= this->width || y < 0 || y >= this->height) {
return;
}
x = this->width - x;
y = this->height - y;
DrawAbsolutePixel(x, y, colored);
} else if (this->rotate == ROTATE_270) {
if(x < 0 || x >= this->height || y < 0 || y >= this->width) {
return;
}
point_temp = x;
x = y;
y = this->height - point_temp;
DrawAbsolutePixel(x, y, colored);
}
}
/**
* @brief: this draws a charactor on the frame buffer but not refresh
*/
void Paint::DrawCharAt(int x, int y, char ascii_char, sFONT* font, int colored) {
int i, j;
unsigned int char_offset = (ascii_char - ' ') * font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0));
const unsigned char* ptr = &font->table[char_offset];
for (j = 0; j < font->Height; j++) {
for (i = 0; i < font->Width; i++) {
if (pgm_read_byte(ptr) & (0x80 >> (i % 8))) {
DrawPixel(x + i, y + j, colored);
}
if (i % 8 == 7) {
ptr++;
}
}
if (font->Width % 8 != 0) {
ptr++;
}
}
}
/**
* @brief: this displays a string on the frame buffer but not refresh
*/
void Paint::DrawStringAt(int x, int y, const char* text, sFONT* font, int colored) {
const char* p_text = text;
unsigned int counter = 0;
int refcolumn = x;
/* Send the string character by character on EPD */
while (*p_text != 0) {
/* Display one character on EPD */
DrawCharAt(refcolumn, y, *p_text, font, colored);
/* Decrement the column position by 16 */
refcolumn += font->Width;
/* Point on the next character */
p_text++;
counter++;
}
}
/**
* @brief: this draws a line on the frame buffer
*/
void Paint::DrawLine(int x0, int y0, int x1, int y1, int colored) {
/* Bresenham algorithm */
int dx = x1 - x0 >= 0 ? x1 - x0 : x0 - x1;
int sx = x0 < x1 ? 1 : -1;
int dy = y1 - y0 <= 0 ? y1 - y0 : y0 - y1;
int sy = y0 < y1 ? 1 : -1;
int err = dx + dy;
while((x0 != x1) && (y0 != y1)) {
DrawPixel(x0, y0 , colored);
if (2 * err >= dy) {
err += dy;
x0 += sx;
}
if (2 * err <= dx) {
err += dx;
y0 += sy;
}
}
}
/**
* @brief: this draws a horizontal line on the frame buffer
*/
void Paint::DrawHorizontalLine(int x, int y, int line_width, int colored) {
int i;
for (i = x; i < x + line_width; i++) {
DrawPixel(i, y, colored);
}
}
/**
* @brief: this draws a vertical line on the frame buffer
*/
void Paint::DrawVerticalLine(int x, int y, int line_height, int colored) {
int i;
for (i = y; i < y + line_height; i++) {
DrawPixel(x, i, colored);
}
}
/**
* @brief: this draws a rectangle
*/
void Paint::DrawRectangle(int x0, int y0, int x1, int y1, int colored) {
int min_x, min_y, max_x, max_y;
min_x = x1 > x0 ? x0 : x1;
max_x = x1 > x0 ? x1 : x0;
min_y = y1 > y0 ? y0 : y1;
max_y = y1 > y0 ? y1 : y0;
DrawHorizontalLine(min_x, min_y, max_x - min_x + 1, colored);
DrawHorizontalLine(min_x, max_y, max_x - min_x + 1, colored);
DrawVerticalLine(min_x, min_y, max_y - min_y + 1, colored);
DrawVerticalLine(max_x, min_y, max_y - min_y + 1, colored);
}
/**
* @brief: this draws a filled rectangle
*/
void Paint::DrawFilledRectangle(int x0, int y0, int x1, int y1, int colored) {
int min_x, min_y, max_x, max_y;
int i;
min_x = x1 > x0 ? x0 : x1;
max_x = x1 > x0 ? x1 : x0;
min_y = y1 > y0 ? y0 : y1;
max_y = y1 > y0 ? y1 : y0;
for (i = min_x; i <= max_x; i++) {
DrawVerticalLine(i, min_y, max_y - min_y + 1, colored);
}
}
/**
* @brief: this draws a circle
*/
void Paint::DrawCircle(int x, int y, int radius, int colored) {
/* Bresenham algorithm */
int x_pos = -radius;
int y_pos = 0;
int err = 2 - 2 * radius;
int e2;
do {
DrawPixel(x - x_pos, y + y_pos, colored);
DrawPixel(x + x_pos, y + y_pos, colored);
DrawPixel(x + x_pos, y - y_pos, colored);
DrawPixel(x - x_pos, y - y_pos, colored);
e2 = err;
if (e2 <= y_pos) {
err += ++y_pos * 2 + 1;
if(-x_pos == y_pos && e2 <= x_pos) {
e2 = 0;
}
}
if (e2 > x_pos) {
err += ++x_pos * 2 + 1;
}
} while (x_pos <= 0);
}
/**
* @brief: this draws a filled circle
*/
void Paint::DrawFilledCircle(int x, int y, int radius, int colored) {
/* Bresenham algorithm */
int x_pos = -radius;
int y_pos = 0;
int err = 2 - 2 * radius;
int e2;
do {
DrawPixel(x - x_pos, y + y_pos, colored);
DrawPixel(x + x_pos, y + y_pos, colored);
DrawPixel(x + x_pos, y - y_pos, colored);
DrawPixel(x - x_pos, y - y_pos, colored);
DrawHorizontalLine(x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored);
DrawHorizontalLine(x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored);
e2 = err;
if (e2 <= y_pos) {
err += ++y_pos * 2 + 1;
if(-x_pos == y_pos && e2 <= x_pos) {
e2 = 0;
}
}
if(e2 > x_pos) {
err += ++x_pos * 2 + 1;
}
} while(x_pos <= 0);
}
/* END OF FILE */

View file

@ -0,0 +1,75 @@
/**
* @filename : epdpaint.h
* @brief : Header file for epdpaint.cpp
* @author : Yehui from Waveshare
*
* Copyright (C) Waveshare July 28 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.
*/
#ifndef EPDPAINT_H
#define EPDPAINT_H
// Display orientation
#define ROTATE_0 0
#define ROTATE_90 1
#define ROTATE_180 2
#define ROTATE_270 3
// Color inverse. 1 or 0 = set or reset a bit if set a colored pixel
#define IF_INVERT_COLOR 1
#include "fonts.h"
class Paint {
public:
Paint(unsigned char* image, int width, int height);
~Paint();
void Clear(int colored);
int GetWidth(void);
void SetWidth(int width);
int GetHeight(void);
void SetHeight(int height);
int GetRotate(void);
void SetRotate(int rotate);
unsigned char* GetImage(void);
void DrawAbsolutePixel(int x, int y, int colored);
void DrawPixel(int x, int y, int colored);
void DrawCharAt(int x, int y, char ascii_char, sFONT* font, int colored);
void DrawStringAt(int x, int y, const char* text, sFONT* font, int colored);
void DrawLine(int x0, int y0, int x1, int y1, int colored);
void DrawHorizontalLine(int x, int y, int width, int colored);
void DrawVerticalLine(int x, int y, int height, int colored);
void DrawRectangle(int x0, int y0, int x1, int y1, int colored);
void DrawFilledRectangle(int x0, int y0, int x1, int y1, int colored);
void DrawCircle(int x, int y, int radius, int colored);
void DrawFilledCircle(int x, int y, int radius, int colored);
private:
unsigned char* image;
int width;
int height;
int rotate;
};
#endif
/* END OF FILE */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1005
Arduino/epd2in7_V2/font8.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,65 @@
/**
******************************************************************************
* @file fonts.h
* @author MCD Application Team
* @version V1.0.0
* @date 18-February-2014
* @brief Header for fonts.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FONTS_H
#define __FONTS_H
/* Max size of bitmap will based on a font24 (17x24) */
#define MAX_HEIGHT_FONT 24
#define MAX_WIDTH_FONT 17
#define OFFSET_BITMAP 54
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
struct sFONT {
const uint8_t *table;
uint16_t Width;
uint16_t Height;
};
extern sFONT Font24;
extern sFONT Font20;
extern sFONT Font16;
extern sFONT Font12;
extern sFONT Font8;
#endif /* __FONTS_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,32 @@
/**
* @filename : imagedata.h
* @brief : head file for imagedata.cpp
*
* Copyright (C) Waveshare August 18 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.
*/
extern const unsigned char IMAGE_DATA[];
extern const unsigned char IMAGE_DATA_4Gray[];
/* END OF FILE*/

View file

@ -5,7 +5,7 @@
* | Info :
*----------------
* | This version: V1.0
* | Date : 2021-04-22
* | Date : 2022-08-18
* | Info :
* -----------------------------------------------------------------------------
#
@ -60,7 +60,6 @@ int EPD_2in7_V2_test(void)
Paint_Clear(WHITE);
#if 1 // show bmp
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
printf("show window BMP-----------------\r\n");
Paint_SelectImage(BlackImage);
GUI_ReadBmp("./pic/100x100.bmp", 10, 10);
@ -72,17 +71,7 @@ int EPD_2in7_V2_test(void)
GUI_ReadBmp("./pic/2in7.bmp", 0, 0);
EPD_2IN7_V2_Display(BlackImage);
DEV_Delay_ms(3000);
#endif
#if 1 //show image for array
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
printf("show image for array\r\n");
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
Paint_DrawBitMap(gImage_2in7);
EPD_2IN7_V2_Display(BlackImage);
DEV_Delay_ms(3000);
#endif
#if 1 // Drawing on the image
@ -116,23 +105,93 @@ int EPD_2in7_V2_test(void)
Paint_DrawNum(10, 33, 123456789, &Font12, BLACK, WHITE);
Paint_DrawNum(10, 50, 987654321, &Font16, WHITE, BLACK);
Paint_DrawString_CN(130, 0,"你好abc", &Font12CN, BLACK, WHITE);
Paint_DrawString_CN(130, 20, "微雪电子", &Font24CN, WHITE, BLACK);
Paint_DrawString_CN(130, 0,"ÄãºÃabc", &Font12CN, BLACK, WHITE);
Paint_DrawString_CN(130, 20, "΢ѩµç×Ó", &Font24CN, WHITE, BLACK);
EPD_2IN7_V2_Display_Base(BlackImage);
DEV_Delay_ms(3000);
#endif
#if 1 //Partial refresh, example shows time
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
#if 1 // Fast Drawing on the image
// Fast refresh
printf("This is followed by a quick refresh demo\r\n");
printf("First, clear the screen\r\n");
EPD_2IN7_V2_Init();
EPD_2IN7_V2_Clear();
printf("e-Paper Init Fast\r\n");
EPD_2IN7_V2_Init_Fast();
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
printf("Drawing\r\n");
//1.Select Image
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
printf("show window BMP-----------------\r\n");
Paint_SelectImage(BlackImage);
GUI_ReadBmp("./pic/100x100.bmp", 10, 10);
EPD_2IN7_V2_Display_Fast(BlackImage);
DEV_Delay_ms(3000);
printf("show bmp------------------------\r\n");
Paint_SelectImage(BlackImage);
GUI_ReadBmp("./pic/2in7.bmp", 0, 0);
EPD_2IN7_V2_Display_Fast(BlackImage);
DEV_Delay_ms(3000);
// 2.Drawing on the image
Paint_Clear(WHITE);
printf("Drawing:BlackImage\r\n");
Paint_DrawPoint(10, 80, BLACK, DOT_PIXEL_1X1, DOT_STYLE_DFT);
Paint_DrawPoint(10, 90, BLACK, DOT_PIXEL_2X2, DOT_STYLE_DFT);
Paint_DrawPoint(10, 100, BLACK, DOT_PIXEL_3X3, DOT_STYLE_DFT);
Paint_DrawLine(20, 70, 70, 120, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawLine(70, 70, 20, 120, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawRectangle(20, 70, 70, 120, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawRectangle(80, 70, 130, 120, BLACK, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawCircle(45, 95, 20, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawCircle(105, 95, 20, WHITE, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawLine(85, 95, 125, 95, BLACK, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawLine(105, 75, 105, 115, BLACK, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawString_EN(10, 0, "waveshare", &Font16, BLACK, WHITE);
Paint_DrawString_EN(10, 20, "hello world", &Font12, WHITE, BLACK);
Paint_DrawNum(10, 33, 123456789, &Font12, BLACK, WHITE);
Paint_DrawNum(10, 50, 987654321, &Font16, WHITE, BLACK);
Paint_DrawString_CN(130, 0,"ÄãºÃabc", &Font12CN, BLACK, WHITE);
Paint_DrawString_CN(130, 20, "΢ѩµç×Ó", &Font24CN, WHITE, BLACK);
EPD_2IN7_V2_Display_Fast(BlackImage);
DEV_Delay_ms(3000);
#endif
#if 1 //Partial refresh, example shows time
// If you didn't use the EPD_2IN7_V2_Display_Base() function to refresh the image before,
// use the EPD_2IN7_V2_Display_Base_color() function to refresh the background color,
// otherwise the background color will be garbled
EPD_2IN7_V2_Init();
// EPD_2IN7_V2_Display_Base_color(WHITE);
Paint_NewImage(BlackImage, 50, 120, 90, WHITE);
printf("Partial refresh\r\n");
Paint_SelectImage(BlackImage);
Paint_SetScale(2);
Paint_Clear(WHITE);
PAINT_TIME sPaint_time;
sPaint_time.Hour = 12;
sPaint_time.Min = 34;
sPaint_time.Sec = 56;
UBYTE num = 10;
UBYTE num = 15;
for (;;) {
sPaint_time.Sec = sPaint_time.Sec + 1;
if (sPaint_time.Sec == 60) {
@ -148,18 +207,67 @@ int EPD_2in7_V2_test(void)
}
}
}
Paint_ClearWindows(150, 80, 150 + Font20.Width * 7, 80 + Font20.Height, WHITE);
Paint_DrawTime(150, 80, &sPaint_time, &Font20, WHITE, BLACK);
Paint_Clear(WHITE);
Paint_DrawRectangle(1, 1, 120, 50, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawTime(10, 15, &sPaint_time, &Font20, WHITE, BLACK);
num = num - 1;
if(num == 0) {
break;
}
EPD_2IN7_V2_Display_Partial(BlackImage);
DEV_Delay_ms(500);//Analog clock 1s
printf("Part refresh...\r\n");
EPD_2IN7_V2_Display_Partial(BlackImage, 60, 134, 110, 254); // Xstart must be a multiple of 8
DEV_Delay_ms(500);
}
#endif
#if 1 // show image for array
free(BlackImage);
printf("show Gray------------------------\r\n");
Imagesize = ((EPD_2IN7_V2_WIDTH % 4 == 0)? (EPD_2IN7_V2_WIDTH / 4 ): (EPD_2IN7_V2_WIDTH / 4 + 1)) * EPD_2IN7_V2_HEIGHT;
if((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) {
printf("Failed to apply for black memory...\r\n");
return -1;
}
EPD_2IN7_V2_Init_4GRAY();
printf("4 grayscale display\r\n");
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
Paint_SetScale(4);
Paint_Clear(0xff);
Paint_DrawPoint(10, 80, GRAY4, DOT_PIXEL_1X1, DOT_STYLE_DFT);
Paint_DrawPoint(10, 90, GRAY4, DOT_PIXEL_2X2, DOT_STYLE_DFT);
Paint_DrawPoint(10, 100, GRAY4, DOT_PIXEL_3X3, DOT_STYLE_DFT);
Paint_DrawLine(20, 70, 70, 120, GRAY4, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawLine(70, 70, 20, 120, GRAY4, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawRectangle(20, 70, 70, 120, GRAY4, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawRectangle(80, 70, 130, 120, GRAY4, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawCircle(45, 95, 20, GRAY4, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawCircle(105, 95, 20, GRAY2, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawLine(85, 95, 125, 95, GRAY4, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawLine(105, 75, 105, 115, GRAY4, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawString_EN(10, 0, "waveshare", &Font16, GRAY4, GRAY1);
Paint_DrawString_EN(10, 20, "hello world", &Font12, GRAY3, GRAY1);
Paint_DrawNum(10, 33, 123456789, &Font12, GRAY4, GRAY2);
Paint_DrawNum(10, 50, 987654321, &Font16, GRAY1, GRAY4);
Paint_DrawString_CN(150, 0,"ÄãºÃabc", &Font12CN, GRAY4, GRAY1);
Paint_DrawString_CN(150, 20,"ÄãºÃabc", &Font12CN, GRAY3, GRAY2);
Paint_DrawString_CN(150, 40,"ÄãºÃabc", &Font12CN, GRAY2, GRAY3);
Paint_DrawString_CN(150, 60,"ÄãºÃabc", &Font12CN, GRAY1, GRAY4);
Paint_DrawString_CN(10, 130, "΢ѩµç×Ó", &Font24CN, GRAY1, GRAY4);
EPD_2IN7_V2_4GrayDisplay(BlackImage);
DEV_Delay_ms(3000);
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 0, WHITE);
Paint_SetScale(4);
Paint_Clear(WHITE);
GUI_ReadBmp_4Gray("./pic/2in7_Scale.bmp", 0, 0);
EPD_2IN7_V2_4GrayDisplay(BlackImage);
DEV_Delay_ms(3000);
#endif
printf("Clear...\r\n");
EPD_2IN7_V2_Init();
EPD_2IN7_V2_Clear();

View file

@ -5,7 +5,7 @@
* | Info :
*----------------
* | This version: V1.0
* | Date : 2021-04-22
* | Date : 2022-08-18
* | Info :
* -----------------------------------------------------------------------------
#
@ -31,27 +31,27 @@
#include "EPD_2in7_V2.h"
#include "Debug.h"
UBYTE WF_PARTIAL_2in7_V2[159] =
UBYTE LUT_DATA_4Gray[159] =
{
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,
0xF,0x0,0x0,0x0,0x0,0x0,0x1,
0x1,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,0x0,0x0,0x0,0x0,0x0,0x0,
0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
0x22,0x17,0x41,0xB0,0x32,0x32,
0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x8, 0x48, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x2, 0x48, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x20, 0x48, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xA, 0x19, 0x0, 0x3, 0x8, 0x0, 0x0,
0x14, 0x1, 0x0, 0x14, 0x1, 0x0, 0x3,
0xA, 0x3, 0x0, 0x8, 0x19, 0x0, 0x0,
0x1, 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,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
0x22, 0x17, 0x41, 0x0, 0x32, 0x1C
};
/******************************************************************************
@ -115,61 +115,48 @@ parameter:
******************************************************************************/
static void EPD_2IN7_V2_TurnOnDisplay(void)
{
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_SendCommand(0x22); //Display Update Control
EPD_2IN7_V2_SendData(0xF7);
EPD_2IN7_V2_SendCommand(0x20); //Activate Display Update Sequence
EPD_2IN7_V2_ReadBusy();
}
static void EPD_2IN7_V2_TurnOnDisplay_Fast(void)
{
EPD_2IN7_V2_SendCommand(0x22); //Display Update Control
EPD_2IN7_V2_SendData(0xC7);
EPD_2IN7_V2_SendCommand(0x20); //Activate Display Update Sequence
EPD_2IN7_V2_ReadBusy();
}
static void EPD_2IN7_V2_TurnOnDisplay_Partial(void)
{
EPD_2IN7_V2_SendCommand(0x22);
EPD_2IN7_V2_SendData(0x0f);
EPD_2IN7_V2_SendData(0xFF);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
}
static void EPD_2IN7_V2_TurnOnDisplay_4GRAY(void)
{
EPD_2IN7_V2_SendCommand(0x22);
EPD_2IN7_V2_SendData(0xC7);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
}
/******************************************************************************
function : set the look-up tables
parameter:
******************************************************************************/
static void EPD_2IN7_V2_SetLut(void)
static void EPD_2IN7_V2_Lut(void)
{
unsigned int count;
EPD_2IN7_V2_SendCommand(0x32); //vcom
for(count = 0; count < 153; count++) {
EPD_2IN7_V2_SendData(WF_PARTIAL_2in7_V2[count]);
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[count]);
}
}
/******************************************************************************
function : Setting the display window
parameter:
******************************************************************************/
static void EPD_2IN7_V2_SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
{
EPD_2IN7_V2_SendCommand(0x44); // SET_RAM_X_ADDRESS_START_END_POSITION
EPD_2IN7_V2_SendData((Xstart>>3) & 0xFF);
EPD_2IN7_V2_SendData((Xend>>3) & 0xFF);
EPD_2IN7_V2_SendCommand(0x45); // SET_RAM_Y_ADDRESS_START_END_POSITION
EPD_2IN7_V2_SendData(Ystart & 0xFF);
EPD_2IN7_V2_SendData((Ystart >> 8) & 0xFF);
EPD_2IN7_V2_SendData(Yend & 0xFF);
EPD_2IN7_V2_SendData((Yend >> 8) & 0xFF);
}
/******************************************************************************
function : Set Cursor
parameter:
******************************************************************************/
static void EPD_2IN7_V2_SetCursor(UWORD Xstart, UWORD Ystart)
{
EPD_2IN7_V2_SendCommand(0x4E); // SET_RAM_X_ADDRESS_COUNTER
EPD_2IN7_V2_SendData(Xstart & 0xFF);
EPD_2IN7_V2_SendCommand(0x4F); // SET_RAM_Y_ADDRESS_COUNTER
EPD_2IN7_V2_SendData(Ystart & 0xFF);
EPD_2IN7_V2_SendData((Ystart >> 8) & 0xFF);
}
/******************************************************************************
function : Initialize the e-Paper register
@ -180,19 +167,121 @@ void EPD_2IN7_V2_Init(void)
EPD_2IN7_V2_Reset();
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x12);
EPD_2IN7_V2_SendCommand(0x12); //SWRESET
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x45); //set Ram-Y address start/end position
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x07); //0x0107-->(263+1)=264
EPD_2IN7_V2_SendData(0x01);
EPD_2IN7_V2_SendCommand(0x4F); // set RAM y address count to 0;
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x11); // data entry mode
EPD_2IN7_V2_SendData(0x03);
}
void EPD_2IN7_V2_Init_Fast(void)
{
EPD_2IN7_V2_Reset();
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x12); //SWRESET
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x18); //Read built-in temperature sensor
EPD_2IN7_V2_SendData(0x80);
EPD_2IN7_V2_SendCommand(0x22); // Load temperature value
EPD_2IN7_V2_SendData(0xB1);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x1A); // Write to temperature register
EPD_2IN7_V2_SendData(0x64);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x45); //set Ram-Y address start/end position
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x07); //0x0107-->(263+1)=264
EPD_2IN7_V2_SendData(0x01);
EPD_2IN7_V2_SendCommand(0x4F); // set RAM y address count to 0;
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x11); // data entry mode
EPD_2IN7_V2_SendData(0x03);
EPD_2IN7_V2_SendCommand(0x22); // Load temperature value
EPD_2IN7_V2_SendData(0x91);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
}
void EPD_2IN7_V2_Init_4GRAY(void)
{
EPD_2IN7_V2_Reset();
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x12); // soft reset
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x74); //set analog block control
EPD_2IN7_V2_SendData(0x54);
EPD_2IN7_V2_SendCommand(0x7E); //set digital block control
EPD_2IN7_V2_SendData(0x3B);
EPD_2IN7_V2_SendCommand(0x01); //Driver output control
EPD_2IN7_V2_SendData(0x27);
EPD_2IN7_V2_SendData(0x07);
EPD_2IN7_V2_SendData(0x01);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x11); //data entry mode
EPD_2IN7_V2_SendData(0x03);
EPD_2IN7_V2_SendCommand(0x44); //set Ram-X address start/end position
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x15); //0x15-->(21+1)*8=176
EPD_2IN7_V2_SendCommand(0x45); //set Ram-Y address start/end position
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x07);//0x0107-->(263+1)=264
EPD_2IN7_V2_SendData(0x01);
EPD_2IN7_V2_SendCommand(0x3C); //BorderWavefrom
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x2C); //VCOM Voltage
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[158]); //0x1C
EPD_2IN7_V2_SendCommand(0x3F); //EOPQ
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[153]);
EPD_2IN7_V2_SetWindows(0, 0, EPD_2IN7_V2_WIDTH-1, EPD_2IN7_V2_HEIGHT-1);
EPD_2IN7_V2_SetCursor(0, 0);
EPD_2IN7_V2_SendCommand(0x03); //VGH
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[154]);
EPD_2IN7_V2_SendCommand(0x04); //
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[155]); //VSH1
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[156]); //VSH2
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[157]); //VSL
EPD_2IN7_V2_Lut(); //LUT
EPD_2IN7_V2_SendCommand(0x4E); // set RAM x address count to 0;
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x4F); // set RAM y address count to 0X199;
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_ReadBusy();
}
/******************************************************************************
@ -212,12 +301,6 @@ void EPD_2IN7_V2_Clear(void)
}
}
EPD_2IN7_V2_SendCommand(0x26);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(0X00);
}
}
EPD_2IN7_V2_TurnOnDisplay();
}
@ -241,6 +324,21 @@ void EPD_2IN7_V2_Display(UBYTE *Image)
EPD_2IN7_V2_TurnOnDisplay();
}
void EPD_2IN7_V2_Display_Fast(UBYTE *Image)
{
UWORD Width, Height;
Width = (EPD_2IN7_V2_WIDTH % 8 == 0)? (EPD_2IN7_V2_WIDTH / 8 ): (EPD_2IN7_V2_WIDTH / 8 + 1);
Height = EPD_2IN7_V2_HEIGHT;
EPD_2IN7_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(Image[i + j * Width]);
}
}
EPD_2IN7_V2_TurnOnDisplay_Fast();
}
void EPD_2IN7_V2_Display_Base(UBYTE *Image)
{
UWORD Width, Height;
@ -262,48 +360,161 @@ void EPD_2IN7_V2_Display_Base(UBYTE *Image)
EPD_2IN7_V2_TurnOnDisplay();
}
void EPD_2IN7_V2_Display_Partial(UBYTE *Image)
void EPD_2IN7_V2_Display_Base_color(UBYTE color)
{
UWORD Width, Height;
Width = (EPD_2IN7_V2_WIDTH % 8 == 0)? (EPD_2IN7_V2_WIDTH / 8 ): (EPD_2IN7_V2_WIDTH / 8 + 1);
Height = EPD_2IN7_V2_HEIGHT;
DEV_Digital_Write(EPD_RST_PIN, 0);
DEV_Delay_ms(1);
DEV_Digital_Write(EPD_RST_PIN, 1);
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SetLut();
EPD_2IN7_V2_SendCommand(0x37);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x40);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x3c);
EPD_2IN7_V2_SendData(0x80);
EPD_2IN7_V2_SendCommand(0x22);
EPD_2IN7_V2_SendData(0xc0);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x24);
EPD_2IN7_V2_SendCommand(0x24); //Write Black and White image to RAM
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(Image[i + j * Width]);
EPD_2IN7_V2_SendData(color);
}
}
EPD_2IN7_V2_SendCommand(0x26); //Write Black and White image to RAM
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(color);
}
}
// EPD_2IN7_V2_TurnOnDisplay();
}
void EPD_2IN7_V2_Display_Partial(const UBYTE *Image, UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
{
if((Xstart % 8 + Xend % 8 == 8 && Xstart % 8 > Xend % 8) || Xstart % 8 + Xend % 8 == 0 || (Xend - Xstart)%8 == 0)
{
Xstart = Xstart / 8 ;
Xend = Xend / 8;
}
else
{
Xstart = Xstart / 8 ;
Xend = Xend % 8 == 0 ? Xend / 8 : Xend / 8 + 1;
}
UWORD i, Width;
Width = Xend - Xstart;
UWORD IMAGE_COUNTER = Width * (Yend-Ystart);
Xend -= 1;
Yend -= 1;
//Reset
EPD_2IN7_V2_Reset();
EPD_2IN7_V2_SendCommand(0x3C); //BorderWavefrom
EPD_2IN7_V2_SendData(0x80);
//
EPD_2IN7_V2_SendCommand(0x44); // set RAM x address start/end, in page 35
EPD_2IN7_V2_SendData(Xstart & 0xff); // RAM x address start at 00h;
EPD_2IN7_V2_SendData(Xend & 0xff); // RAM x address end at 0fh(15+1)*8->128
EPD_2IN7_V2_SendCommand(0x45); // set RAM y address start/end, in page 35
EPD_2IN7_V2_SendData(Ystart & 0xff); // RAM y address start at 0127h;
EPD_2IN7_V2_SendData((Ystart>>8) & 0x01); // RAM y address start at 0127h;
EPD_2IN7_V2_SendData(Yend & 0xff); // RAM y address end at 00h;
EPD_2IN7_V2_SendData((Yend>>8) & 0x01);
EPD_2IN7_V2_SendCommand(0x4E); // set RAM x address count to 0;
EPD_2IN7_V2_SendData(Xstart & 0xff);
EPD_2IN7_V2_SendCommand(0x4F); // set RAM y address count to 0X127;
EPD_2IN7_V2_SendData(Ystart & 0xff);
EPD_2IN7_V2_SendData((Ystart>>8) & 0x01);
EPD_2IN7_V2_SendCommand(0x24); //Write Black and White image to RAM
for (i = 0; i < IMAGE_COUNTER; i++) {
EPD_2IN7_V2_SendData(Image[i]);
}
EPD_2IN7_V2_TurnOnDisplay_Partial();
}
void EPD_2IN7_V2_4GrayDisplay(UBYTE *Image)
{
UDOUBLE i,j,k;
UBYTE temp1,temp2,temp3;
// old data
EPD_2IN7_V2_SendCommand(0x24);
for(i=0; i<5808; i++) { //5808*4 46464
temp3=0;
for(j=0; j<2; j++) {
temp1 = Image[i*2+j];
for(k=0; k<2; k++) {
temp2 = temp1&0xC0;
if(temp2 == 0xC0)
temp3 |= 0x00;
else if(temp2 == 0x00)
temp3 |= 0x01;
else if(temp2 == 0x80)
temp3 |= 0x01;
else //0x40
temp3 |= 0x00;
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x00;
else if(temp2 == 0x00)
temp3 |= 0x01;
else if(temp2 == 0x80)
temp3 |= 0x01;
else //0x40
temp3 |= 0x00;
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
EPD_2IN7_V2_SendData(temp3);
// printf("%x",temp3);
}
EPD_2IN7_V2_SendCommand(0x26); //write RAM for black(0)/white (1)
for(i=0; i<5808; i++) { //5808*4 46464
temp3=0;
for(j=0; j<2; j++) {
temp1 = Image[i*2+j];
for(k=0; k<2; k++) {
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x00;//white
else if(temp2 == 0x00)
temp3 |= 0x01; //black
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1
else //0x40
temp3 |= 0x01; //gray2
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0) //white
temp3 |= 0x00;
else if(temp2 == 0x00) //black
temp3 |= 0x01;
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1
else //0x40
temp3 |= 0x01; //gray2
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
EPD_2IN7_V2_SendData(temp3);
// printf("%x",temp3);
}
EPD_2IN7_V2_TurnOnDisplay_4GRAY();
}
/******************************************************************************
function : Enter sleep mode
parameter:

View file

@ -5,7 +5,7 @@
* | Info :
*----------------
* | This version: V1.0
* | Date : 2021-04-22
* | Date : 2022-08-18
* | Info :
* -----------------------------------------------------------------------------
#
@ -38,11 +38,15 @@
#define EPD_2IN7_V2_HEIGHT 264
void EPD_2IN7_V2_Init(void);
void EPD_2IN7_V2_Init_Fast(void);
void EPD_2IN7_V2_Init_4GRAY(void);
void EPD_2IN7_V2_Clear(void);
void EPD_2IN7_V2_Display(UBYTE *Image);
void EPD_2IN7_V2_Display_Fast(UBYTE *Image);
void EPD_2IN7_V2_Display_Base(UBYTE *Image);
void EPD_2IN7_V2_Display_Base_color(UBYTE color);
void EPD_2IN7_V2_Display_Partial(const UBYTE *Image, UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yende);
void EPD_2IN7_V2_4GrayDisplay(UBYTE *Image);
void EPD_2IN7_V2_Sleep(void);
void EPD_2IN7_V2_Display_Base(UBYTE *Image);
void EPD_2IN7_V2_Display_Partial(UBYTE *Image);
#endif

View file

@ -0,0 +1,158 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic')
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib')
if os.path.exists(libdir):
sys.path.append(libdir)
import logging
from waveshare_epd import epd2in7_V2
import time
from PIL import Image,ImageDraw,ImageFont
import traceback
logging.basicConfig(level=logging.DEBUG)
try:
logging.info("epd2in7 Demo")
epd = epd2in7_V2.EPD()
'''2Gray(Black and white) display'''
logging.info("init and Clear")
epd.init()
epd.clear()
font24 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 24)
font18 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 18)
font35 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 35)
# Quick refresh
logging.info("Quick refresh demo")
epd.init_Fast()
# Drawing on the Vertical image
logging.info("1.Drawing on the Vertical image...")
Limage = Image.new('1', (epd.width, epd.height), 255) # 255: clear the frame
draw = ImageDraw.Draw(Limage)
draw.text((2, 0), 'hello world', font = font18, fill = 0)
draw.text((20, 50), u'微雪电子', font = font18, fill = 0)
draw.line((10, 90, 60, 140), fill = 0)
draw.line((60, 90, 10, 140), fill = 0)
draw.rectangle((10, 90, 60, 140), outline = 0)
draw.line((95, 90, 95, 140), fill = 0)
draw.line((70, 115, 120, 115), fill = 0)
draw.arc((70, 90, 120, 140), 0, 360, fill = 0)
draw.rectangle((10, 150, 60, 200), fill = 0)
draw.chord((70, 150, 120, 200), 0, 360, fill = 0)
epd.display_Fast(epd.getbuffer(Limage))
time.sleep(2)
logging.info("2.read bmp file")
Himage = Image.open(os.path.join(picdir, '2in7.bmp'))
epd.display_Fast(epd.getbuffer(Himage))
time.sleep(2)
# Normal refresh
logging.info("Normal refresh demo")
epd.init()
logging.info("3.read bmp file on window")
Himage2 = Image.new('1', (epd.height, epd.width), 255) # 255: clear the frame
bmp = Image.open(os.path.join(picdir, '100x100.bmp'))
Himage2.paste(bmp, (50,10))
epd.display(epd.getbuffer(Himage2))
time.sleep(2)
# Drawing on the Horizontal image
logging.info("4.Drawing on the Horizontal image...")
Himage = Image.new('1', (epd.height, epd.width), 255) # 255: clear the frame
draw = ImageDraw.Draw(Himage)
draw.text((10, 0), 'hello world', font = font24, fill = 0)
draw.text((150, 0), u'微雪电子', font = font24, fill = 0)
draw.line((20, 50, 70, 100), fill = 0)
draw.line((70, 50, 20, 100), fill = 0)
draw.rectangle((20, 50, 70, 100), outline = 0)
draw.line((165, 50, 165, 100), fill = 0)
draw.line((140, 75, 190, 75), fill = 0)
draw.arc((140, 50, 190, 100), 0, 360, fill = 0)
draw.rectangle((80, 50, 130, 100), fill = 0)
draw.chord((200, 50, 250, 100), 0, 360, fill = 0)
epd.display_Base(epd.getbuffer(Himage))
time.sleep(2)
# partial update
logging.info("5.show time")
epd.init()
'''
# If you didn't use the EPD_2IN7_V2_Display_Base() function to refresh the image before,
# use the EPD_2IN7_V2_Display_Base_color() function to refresh the background color,
# otherwise the background color will be garbled
'''
# epd.display_Base_color(0xff)
# Himage = Image.new('1', (epd.height ,epd.width), 0xff)
# draw = ImageDraw.Draw(time_image)
num = 0
while (True):
draw.rectangle((10, 110, 120, 150), fill = 255)
draw.text((10, 110), time.strftime('%H:%M:%S'), font = font24, fill = 0)
newimage = Himage.crop([10, 110, 120, 150])
Himage.paste(newimage, (10,110))
epd.display_Partial(epd.getbuffer(Himage),110, epd.height - 120, 150, epd.height - 10)
num = num + 1
if(num == 10):
break
# epd.init()
# epd.clear()
# epd.display_Base_color(0xff)
# Himage = Image.new('1', (epd.width ,epd.height), 0xff)
# draw = ImageDraw.Draw(Himage)
# num = 0
# while (True):
# draw.rectangle((10, 10, 120, 50), fill = 255)
# draw.text((10, 10), time.strftime('%H:%M:%S'), font = font24, fill = 0)
# newimage = Himage.crop([10, 10, 120, 50])
# Himage.paste(newimage, (10,10))
# epd.display_Partial(epd.getbuffer(Himage),10, 10, 120, 50)
# num = num + 1
# if(num == 10):
# break
'''4Gray display'''
logging.info("4Gray display--------------------------------")
epd.Init_4Gray()
Limage = Image.new('L', (epd.width, epd.height), 0) # 255: clear the frame
draw = ImageDraw.Draw(Limage)
draw.text((20, 0), u'微雪电子', font = font35, fill = epd.GRAY1)
draw.text((20, 35), u'微雪电子', font = font35, fill = epd.GRAY2)
draw.text((20, 70), u'微雪电子', font = font35, fill = epd.GRAY3)
draw.text((40, 110), 'hello world', font = font18, fill = epd.GRAY1)
draw.line((10, 140, 60, 190), fill = epd.GRAY1)
draw.line((60, 140, 10, 190), fill = epd.GRAY1)
draw.rectangle((10, 140, 60, 190), outline = epd.GRAY1)
draw.line((95, 140, 95, 190), fill = epd.GRAY1)
draw.line((70, 165, 120, 165), fill = epd.GRAY1)
draw.arc((70, 140, 120, 190), 0, 360, fill = epd.GRAY1)
draw.rectangle((10, 200, 60, 250), fill = epd.GRAY1)
draw.chord((70, 200, 120, 250), 0, 360, fill = epd.GRAY1)
epd.display_4Gray(epd.getbuffer_4Gray(Limage))
time.sleep(2)
#display 4Gra bmp
Himage = Image.open(os.path.join(picdir, '2in7_Scale.bmp'))
epd.display_4Gray(epd.getbuffer_4Gray(Himage))
time.sleep(2)
logging.info("Clear...")
epd.clear()
logging.info("Goto Sleep...")
epd.sleep()
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info("ctrl + c:")
epd2in7.epdconfig.module_exit()
exit()

View file

@ -0,0 +1,519 @@
# *****************************************************************************
# * | File : epd2in7_V2.py
# * | Author : Waveshare team
# * | Function : Electronic paper driver
# * | Info :
# *----------------
# * | This version: V1.0
# * | Date : 2022-09-17
# # | Info : python demo
# -----------------------------------------------------------------------------
# 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.
#
import logging
from . import epdconfig
# Display resolution
EPD_WIDTH = 176
EPD_HEIGHT = 264
GRAY1 = 0xff #white
GRAY2 = 0xC0
GRAY3 = 0x80 #gray
GRAY4 = 0x00 #Blackest
logger = logging.getLogger(__name__)
class EPD:
def __init__(self):
self.reset_pin = epdconfig.RST_PIN
self.dc_pin = epdconfig.DC_PIN
self.busy_pin = epdconfig.BUSY_PIN
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
self.GRAY1 = GRAY1 #white
self.GRAY2 = GRAY2
self.GRAY3 = GRAY3 #gray
self.GRAY4 = GRAY4 #Blackest
LUT_DATA_4Gray = [
0x40,0x48,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x8,0x48,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x2,0x48,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x20,0x48,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xA,0x19,0x0,0x3,0x8,0x0,0x0,
0x14,0x1,0x0,0x14,0x1,0x0,0x3,
0xA,0x3,0x0,0x8,0x19,0x0,0x0,
0x1,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,
0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
0x22,0x17,0x41,0x0,0x32,0x1C,
]
# Hardware reset
def reset(self):
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(200)
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(2)
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(200)
def send_command(self, command):
epdconfig.digital_write(self.dc_pin, 0)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([command])
epdconfig.digital_write(self.cs_pin, 1)
def send_data(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self):
logger.debug("e-Paper busy")
while(epdconfig.digital_read(self.busy_pin) == 1): # 1: idle, 0: busy
epdconfig.delay_ms(20)
logger.debug("e-Paper busy release")
def TurnOnDisplay(self):
self.send_command(0x22) #Display Update Control
self.send_data(0xF7)
self.send_command(0x20) #Activate Display Update Sequence
self.ReadBusy()
def TurnOnDisplay_Fast(self):
self.send_command(0x22) #Display Update Control
self.send_data(0xC7)
self.send_command(0x20) #Activate Display Update Sequence
self.ReadBusy()
def TurnOnDisplay_Partial(self):
self.send_command(0x22) #Display Update Control
self.send_data(0xFF)
self.send_command(0x20) #Activate Display Update Sequence
self.ReadBusy()
def TurnOnDisplay_4GRAY(self):
self.send_command(0x22) #Display Update Control
self.send_data(0xC7)
self.send_command(0x20) #Activate Display Update Sequence
self.ReadBusy()
def Lut(self):
self.send_command(0x32)
for i in range(159):
self.send_data(self.LUT_DATA_4Gray[i])
def init(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
self.ReadBusy()
self.send_command(0x12) #SWRESET
self.ReadBusy()
self.send_command(0x45) #set Ram-Y address start/end position
self.send_data(0x00)
self.send_data(0x00)
self.send_data(0x07) #0x0107-->(263+1)=264
self.send_data(0x01)
self.send_command(0x4F) # set RAM y address count to 0;
self.send_data(0x00)
self.send_data(0x00)
self.send_command(0x11) # data entry mode
self.send_data(0x03)
return 0
def init_Fast(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
self.ReadBusy()
self.send_command(0x12) #SWRESET
self.ReadBusy()
self.send_command(0x12) #SWRESET
self.ReadBusy()
self.send_command(0x18) #Read built-in temperature sensor
self.send_data(0x80)
self.send_command(0x22) # Load temperature value
self.send_data(0xB1)
self.send_command(0x20)
self.ReadBusy()
self.send_command(0x1A) # Write to temperature register
self.send_data(0x64)
self.send_data(0x00)
self.send_command(0x45) #set Ram-Y address start/end position
self.send_data(0x00)
self.send_data(0x00)
self.send_data(0x07) #0x0107-->(263+1)=264
self.send_data(0x01)
self.send_command(0x4F) # set RAM y address count to 0;
self.send_data(0x00)
self.send_data(0x00)
self.send_command(0x11) # data entry mode
self.send_data(0x03)
self.send_command(0x22) # Load temperature value
self.send_data(0x91)
self.send_command(0x20)
self.ReadBusy()
return 0
def Init_4Gray(self):
if (epdconfig.module_init() != 0):
return -1
self.reset()
self.send_command(0x12) # soft reset
self.ReadBusy();
self.send_command(0x74) #set analog block control
self.send_data(0x54)
self.send_command(0x7E) #set digital block control
self.send_data(0x3B)
self.send_command(0x01) #Driver output control
self.send_data(0x07)
self.send_data(0x01)
self.send_data(0x00)
self.send_command(0x11) #data entry mode
self.send_data(0x03)
self.send_command(0x44) #set Ram-X address start/end position
self.send_data(0x00)
self.send_data(0x15) #0x15-->(21+1)*8=176
self.send_command(0x45) #set Ram-Y address start/end position
self.send_data(0x00)
self.send_data(0x00)
self.send_data(0x07) #0x0107-->(263+1)=264
self.send_data(0x01)
self.send_command(0x3C) #BorderWavefrom
self.send_data(0x00)
self.send_command(0x2C) #VCOM Voltage
self.send_data(self.LUT_DATA_4Gray[158]) #0x1C
self.send_command(0x3F) #EOPQ
self.send_data(self.LUT_DATA_4Gray[153])
self.send_command(0x03) #VGH
self.send_data(self.LUT_DATA_4Gray[154])
self.send_command(0x04) #
self.send_data(self.LUT_DATA_4Gray[155]) #VSH1
self.send_data(self.LUT_DATA_4Gray[156]) #VSH2
self.send_data(self.LUT_DATA_4Gray[157]) #VSL
self.Lut() #LUT
self.send_command(0x4E) # set RAM x address count to 0;
self.send_data(0x00)
self.send_command(0x4F) # set RAM y address count to 0X199;
self.send_data(0x00)
self.send_data(0x00)
self.ReadBusy()
return 0
def getbuffer(self, image):
# logger.debug("bufsiz = ",int(self.width/8) * self.height)
buf = [0xFF] * (int(self.width/8) * self.height)
image_monocolor = image.convert('1')
imwidth, imheight = image_monocolor.size
pixels = image_monocolor.load()
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
if(imwidth == self.width and imheight == self.height):
logger.debug("Vertical")
for y in range(imheight):
for x in range(imwidth):
# Set the bits for the column of pixels at the current position.
if pixels[x, y] == 0:
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
elif(imwidth == self.height and imheight == self.width):
logger.debug("Horizontal")
for y in range(imheight):
for x in range(imwidth):
newx = y
newy = self.height - x - 1
if pixels[x, y] == 0:
buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
return buf
def getbuffer_4Gray(self, image):
# logger.debug("bufsiz = ",int(self.width/8) * self.height)
buf = [0xFF] * (int(self.width / 4) * self.height)
image_monocolor = image.convert('L')
imwidth, imheight = image_monocolor.size
pixels = image_monocolor.load()
i=0
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
if(imwidth == self.width and imheight == self.height):
logger.debug("Vertical")
for y in range(imheight):
for x in range(imwidth):
# Set the bits for the column of pixels at the current position.
if(pixels[x, y] == 0xC0):
pixels[x, y] = 0x80
elif (pixels[x, y] == 0x80):
pixels[x, y] = 0x40
i= i+1
if(i%4 == 0):
buf[int((x + (y * self.width))/4)] = ((pixels[x-3, y]&0xc0) | (pixels[x-2, y]&0xc0)>>2 | (pixels[x-1, y]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
elif(imwidth == self.height and imheight == self.width):
logger.debug("Horizontal")
for x in range(imwidth):
for y in range(imheight):
newx = y
newy = self.height - x - 1
if(pixels[x, y] == 0xC0):
pixels[x, y] = 0x80
elif (pixels[x, y] == 0x80):
pixels[x, y] = 0x40
i= i+1
if(i%4 == 0):
buf[int((newx + (newy * self.width))/4)] = ((pixels[x, y-3]&0xc0) | (pixels[x, y-2]&0xc0)>>2 | (pixels[x, y-1]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
return buf
def clear(self):
if(self.width % 8 == 0):
Width = self.width // 8
else:
Width = self.width // 8 +1
Height = self.height
self.send_command(0x24)
for j in range(Height):
for i in range(Width):
self.send_data(0XFF)
self.TurnOnDisplay()
def display(self, image):
if(self.width % 8 == 0):
Width = self.width // 8
else:
Width = self.width // 8 +1
Height = self.height
self.send_command(0x24)
for j in range(Height):
for i in range(Width):
self.send_data(image[i + j * Width])
self.TurnOnDisplay()
def display_Fast(self, image):
if(self.width % 8 == 0):
Width = self.width // 8
else:
Width = self.width // 8 +1
Height = self.height
self.send_command(0x24)
for j in range(Height):
for i in range(Width):
self.send_data(image[i + j * Width])
self.TurnOnDisplay_Fast()
def display_Base(self, image):
if(self.width % 8 == 0):
Width = self.width // 8
else:
Width = self.width // 8 +1
Height = self.height
self.send_command(0x24) #Write Black and White image to RAM
for j in range(Height):
for i in range(Width):
self.send_data(image[i + j * Width])
self.send_command(0x26) #Write Black and White image to RAM
for j in range(Height):
for i in range(Width):
self.send_data(image[i + j * Width])
self.TurnOnDisplay()
def display_Base_color(self, color):
if(self.width % 8 == 0):
Width = self.width // 8
else:
Width = self.width // 8 +1
Height = self.height
self.send_command(0x24) #Write Black and White image to RAM
for j in range(Height):
for i in range(Width):
self.send_data(color)
self.send_command(0x26) #Write Black and White image to RAM
for j in range(Height):
for i in range(Width):
self.send_data(color)
# self.TurnOnDisplay()
def display_Partial(self, Image, Xstart, Ystart, Xend, Yend):
if((Xstart % 8 + Xend % 8 == 8 & Xstart % 8 > Xend % 8) | Xstart % 8 + Xend % 8 == 0 | (Xend - Xstart)%8 == 0):
Xstart = Xstart // 8
Xend = Xend // 8
else:
Xstart = Xstart // 8
if Xend % 8 == 0:
Xend = Xend // 8
else:
Xend = Xend // 8 + 1
if(self.width % 8 == 0):
Width = self.width // 8
else:
Width = self.width // 8 +1
Height = self.height
Xend -= 1
Yend -= 1
# Reset
self.reset()
self.send_command(0x3C) #BorderWavefrom
self.send_data(0x80)
self.send_command(0x44) # set RAM x address start/end, in page 35
self.send_data(Xstart & 0xff) # RAM x address start at 00h;
self.send_data(Xend & 0xff) # RAM x address end at 0fh(15+1)*8->128
self.send_command(0x45) # set RAM y address start/end, in page 35
self.send_data(Ystart & 0xff) # RAM y address start at 0127h;
self.send_data((Ystart>>8) & 0x01) # RAM y address start at 0127h;
self.send_data(Yend & 0xff) # RAM y address end at 00h;
self.send_data((Yend>>8) & 0x01)
self.send_command(0x4E) # set RAM x address count to 0;
self.send_data(Xstart & 0xff)
self.send_command(0x4F) # set RAM y address count to 0X127;
self.send_data(Ystart & 0xff)
self.send_data((Ystart>>8) & 0x01)
self.send_command(0x24) #Write Black and White image to RAM
for j in range(Height):
for i in range(Width):
if((j > Ystart-1) & (j < (Yend + 1)) & (i > Xstart-1) & (i < (Xend + 1))):
self.send_data(Image[i + j * Width])
self.TurnOnDisplay_Partial()
def display_4Gray(self, image):
self.send_command(0x24)
for i in range(0, 5808): #5808*4 46464
temp3=0
for j in range(0, 2):
temp1 = image[i*2+j]
for k in range(0, 2):
temp2 = temp1&0xC0
if(temp2 == 0xC0):
temp3 |= 0x00
elif(temp2 == 0x00):
temp3 |= 0x01
elif(temp2 == 0x80):
temp3 |= 0x01
else: #0x40
temp3 |= 0x00
temp3 <<= 1
temp1 <<= 2
temp2 = temp1&0xC0
if(temp2 == 0xC0):
temp3 |= 0x00
elif(temp2 == 0x00):
temp3 |= 0x01
elif(temp2 == 0x80):
temp3 |= 0x01
else : #0x40
temp3 |= 0x00
if(j!=1 or k!=1):
temp3 <<= 1
temp1 <<= 2
self.send_data(temp3)
self.send_command(0x26)
for i in range(0, 5808): #5808*4 46464
temp3=0
for j in range(0, 2):
temp1 = image[i*2+j]
for k in range(0, 2):
temp2 = temp1&0xC0
if(temp2 == 0xC0):
temp3 |= 0x00
elif(temp2 == 0x00):
temp3 |= 0x01
elif(temp2 == 0x80):
temp3 |= 0x00
else: #0x40
temp3 |= 0x01
temp3 <<= 1
temp1 <<= 2
temp2 = temp1&0xC0
if(temp2 == 0xC0):
temp3 |= 0x00
elif(temp2 == 0x00):
temp3 |= 0x01
elif(temp2 == 0x80):
temp3 |= 0x00
else: #0x40
temp3 |= 0x01
if(j!=1 or k!=1):
temp3 <<= 1
temp1 <<= 2
self.send_data(temp3)
self.TurnOnDisplay_4GRAY()
def sleep(self):
self.send_command(0X10)
self.send_data(0x01)
epdconfig.delay_ms(2000)
epdconfig.module_exit()
### END OF FILE ###

View file

@ -0,0 +1,97 @@
// <<< Use Configuration Wizard in Context Menu >>>
// <h> Debug MCU Configuration
// <o0.0> DBG_SLEEP
// <i> Debug Sleep Mode
// <i> 0: (FCLK=On, HCLK=Off) FCLK is clocked by the system clock as previously configured by the software while HCLK is disabled
// <i> 1: (FCLK=On, HCLK=On) HCLK is fed by the same clock that is provided to FCLK
// <o0.1> DBG_STOP
// <i> Debug Stop Mode
// <i> 0: (FCLK=Off, HCLK=Off) Clock controller disables all clocks
// <i> 1: (FCLK=On, HCLK=On) FCLK and HCLK are provided by the internal RC oscillator which remains active
// <o0.2> DBG_STANDBY
// <i> Debug Standby Mode
// <i> 0: (FCLK=Off, HCLK=Off) The whole digital part is unpowered.
// <i> 1: (FCLK=On, HCLK=On) Digital part is powered and FCLK and HCLK are provided by the internal RC oscillator which remains active
// <o0.8> DBG_IWDG_STOP
// <i> Debug independent watchdog stopped when core is halted
// <i> 0: The watchdog counter clock continues even if the core is halted
// <i> 1: The watchdog counter clock is stopped when the core is halted
// <o0.9> DBG_WWDG_STOP
// <i> Debug window watchdog stopped when core is halted
// <i> 0: The window watchdog counter clock continues even if the core is halted
// <i> 1: The window watchdog counter clock is stopped when the core is halted
// <o0.10> DBG_TIM1_STOP
// <i> Timer 1 counter stopped when core is halted
// <i> 0: The clock of the involved Timer Counter is fed even if the core is halted
// <i> 1: The clock of the involved Timer counter is stopped when the core is halted
// <o0.11> DBG_TIM2_STOP
// <i> Timer 2 counter stopped when core is halted
// <i> 0: The clock of the involved Timer Counter is fed even if the core is halted
// <i> 1: The clock of the involved Timer counter is stopped when the core is halted
// <o0.12> DBG_TIM3_STOP
// <i> Timer 3 counter stopped when core is halted
// <i> 0: The clock of the involved Timer Counter is fed even if the core is halted
// <i> 1: The clock of the involved Timer counter is stopped when the core is halted
// <o0.13> DBG_TIM4_STOP
// <i> Timer 4 counter stopped when core is halted
// <i> 0: The clock of the involved Timer Counter is fed even if the core is halted
// <i> 1: The clock of the involved Timer counter is stopped when the core is halted
// <o0.14> DBG_CAN1_STOP
// <i> Debug CAN1 stopped when Core is halted
// <i> 0: Same behavior as in normal mode
// <i> 1: CAN1 receive registers are frozen
// <o0.15> DBG_I2C1_SMBUS_TIMEOUT
// <i> I2C1 SMBUS timeout mode stopped when Core is halted
// <i> 0: Same behavior as in normal mode
// <i> 1: The SMBUS timeout is frozen
// <o0.16> DBG_I2C2_SMBUS_TIMEOUT
// <i> I2C2 SMBUS timeout mode stopped when Core is halted
// <i> 0: Same behavior as in normal mode
// <i> 1: The SMBUS timeout is frozen
// <o0.17> DBG_TIM8_STOP
// <i> Timer 8 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.18> DBG_TIM5_STOP
// <i> Timer 5 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.19> DBG_TIM6_STOP
// <i> Timer 6 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.20> DBG_TIM7_STOP
// <i> Timer 7 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.21> DBG_CAN2_STOP
// <i> Debug CAN2 stopped when Core is halted
// <i> 0: Same behavior as in normal mode
// <i> 1: CAN2 receive registers are frozen
// <o0.25> DBG_TIM12_STOP
// <i> Timer 12 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.26> DBG_TIM13_STOP
// <i> Timer 13 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.27> DBG_TIM14_STOP
// <i> Timer 14 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.28> DBG_TIM9_STOP
// <i> Timer 9 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.29> DBG_TIM10_STOP
// <i> Timer 10 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// <o0.30> DBG_TIM11_STOP
// <i> Timer 11 counter stopped when core is halted
// <i> 0: The clock of the involved timer counter is fed even if the core is halted, and the outputs behave normally.
// <i> 1: The clock of the involved timer counter is stopped when the core is halted, and the outputs are disabled (as if there were an emergency stop in response to a break event).
// </h>
DbgMCU_CR = 0x00000007;
// <<< end of configuration section >>>

View file

@ -0,0 +1,20 @@
/*
* Auto generated Run-Time-Environment Component Configuration File
* *** Do not modify ! ***
*
* Project: 'epd-demo'
* Target: 'EPD_2in7_V2_test'
*/
#ifndef RTE_COMPONENTS_H
#define RTE_COMPONENTS_H
/*
* Define the Device Header File:
*/
#define CMSIS_device_header "stm32f10x.h"
#endif /* RTE_COMPONENTS_H */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -3,92 +3,92 @@
<pre>
<h1>µVision Build Log</h1>
<h2>Tool Versions:</h2>
IDE-Version: ¦ÌVision V5.25.2.0
IDE-Version: ¦ÌVision V5.26.2.0
Copyright (C) 2018 ARM Ltd and ARM Germany GmbH. All rights reserved.
License Information: ass ass, ass, LIC=JL2UH-W872P-CJR6Z-JYZTW-ESB48-R6YF4
License Information: , , LIC=RC93N-YLJYL-JJH6S-LI3Z1-D1AV2-99PL8
Tool Versions:
Toolchain: MDK-ARM Plus Version: 5.25.2.0
Toolchain Path: D:\Program Files\keil5\ARM\ARMCC\Bin
Toolchain: MDK-ARM Plus Version: 5.26.2.0
Toolchain Path: D:\KEIL\azwz\ARM\ARMCC\Bin
C Compiler: Armcc.exe V5.06 update 6 (build 750)
Assembler: Armasm.exe V5.06 update 6 (build 750)
Linker/Locator: ArmLink.exe V5.06 update 6 (build 750)
Library Manager: ArmAr.exe V5.06 update 6 (build 750)
Hex Converter: FromElf.exe V5.06 update 6 (build 750)
CPU DLL: SARMCM3.DLL V5.25.2.0
Dialog DLL: DCM.DLL V1.17.1.0
Target DLL: STLink\ST-LINKIII-KEIL_SWO.dll V3.0.1.0
Dialog DLL: TCM.DLL V1.35.1.0
CPU DLL: SARMCM3.DLL V5.26.2.0
Dialog DLL: DCM.DLL V1.17.2.0
Target DLL: STLink\ST-LINKIII-KEIL_SWO.dll V3.0.5.0
Dialog DLL: TCM.DLL V1.36.1.0
<h2>Project:</h2>
E:\github\E-Paper_code\STM32\STM32-F103ZET6\MDK-ARM\epd-demo.uvprojx
Project File Date: 10/20/2022
E:\ÏîÄ¿\e-Paper\Code\E-Paper_code\STM32\STM32-F103ZET6\MDK-ARM\epd-demo.uvprojx
Project File Date: 10/27/2022
<h2>Output:</h2>
*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'D:\Program Files\keil5\ARM\ARMCC\Bin'
Build target 'epd-demo'
*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'D:\KEIL\azwz\ARM\ARMCC\Bin'
Build target 'EPD_2in7_V2_test'
assembling startup_stm32f103xe.s...
compiling spi.c...
compiling usart.c...
compiling gpio.c...
compiling stm32f1xx_hal_msp.c...
compiling DEV_Config.c...
compiling usart.c...
compiling stm32f1xx_it.c...
compiling main.c...
compiling spi.c...
compiling ImageData.c...
compiling DEV_Config.c...
compiling stm32f1xx_hal_msp.c...
compiling font8.c...
compiling EPD_2in7_V2.c...
compiling font12.c...
compiling EPD_2in7_V2_test.c...
compiling font12CN.c...
compiling font16.c...
compiling font24CN.c...
compiling font20.c...
compiling GUI_Paint.c...
compiling font24.c...
compiling system_stm32f1xx.c...
compiling stm32f1xx_hal_gpio.c...
compiling font24CN.c...
compiling GUI_Paint.c...
compiling stm32f1xx_hal_gpio_ex.c...
compiling stm32f1xx_hal.c...
compiling system_stm32f1xx.c...
compiling stm32f1xx_hal_spi.c...
compiling stm32f1xx_hal_rcc_ex.c...
compiling stm32f1xx_hal_dma.c...
compiling stm32f1xx_hal.c...
compiling stm32f1xx_hal_rcc.c...
compiling stm32f1xx_hal_flash.c...
compiling stm32f1xx_hal_tim.c...
compiling stm32f1xx_hal_exti.c...
compiling stm32f1xx_hal_tim_ex.c...
compiling stm32f1xx_hal_pwr.c...
compiling stm32f1xx_hal_cortex.c...
compiling stm32f1xx_hal_rcc_ex.c...
compiling stm32f1xx_hal_dma.c...
compiling stm32f1xx_hal_gpio.c...
compiling stm32f1xx_hal_tim.c...
compiling stm32f1xx_hal_tim_ex.c...
compiling stm32f1xx_hal_exti.c...
compiling stm32f1xx_hal_flash_ex.c...
compiling stm32f1xx_hal_flash.c...
compiling stm32f1xx_hal_uart.c...
linking...
epd-demo\epd-demo.axf: Error: L6218E: Undefined symbol EPD_test (referred from main.o).
Not enough information to list image symbols.
Not enough information to list load addresses in the image map.
Finished: 2 information, 0 warning and 1 error messages.
"epd-demo\epd-demo.axf" - 1 Error(s), 0 Warning(s).
Program Size: Code=27652 RO-data=31976 RW-data=236 ZI-data=53428
FromELF: creating hex file...
"epd-demo\epd-demo.axf" - 0 Error(s), 0 Warning(s).
<h2>Software Packages used:</h2>
Package Vendor: ARM
http://www.keil.com/pack/ARM.CMSIS.5.7.0.pack
ARM.CMSIS.5.7.0
CMSIS (Cortex Microcontroller Software Interface Standard)
* Component: CORE Version: 5.4.0
http://www.keil.com/pack/ARM.CMSIS.5.9.0.pack
ARM.CMSIS.5.9.0
CMSIS (Common Microcontroller Software Interface Standard)
* Component: CORE Version: 5.6.0
Package Vendor: Keil
http://www.keil.com/pack/Keil.STM32F1xx_DFP.2.3.0.pack
Keil.STM32F1xx_DFP.2.3.0
http://www.keil.com/pack/Keil.STM32F1xx_DFP.2.1.0.pack
Keil.STM32F1xx_DFP.2.1.0
STMicroelectronics STM32F1 Series Device Support, Drivers and Examples
<h2>Collection of Component include folders:</h2>
.\RTE\_epd-demo
D:\Program Files\keil5\ARM\PACK\ARM\CMSIS\5.7.0\CMSIS\Core\Include
D:\Program Files\keil5\ARM\PACK\Keil\STM32F1xx_DFP\2.3.0\Device\Include
.\RTE\_EPD_2in7_V2_test
D:\KEIL\azwz\ARM\PACK\ARM\CMSIS\5.9.0\CMSIS\Core\Include
D:\KEIL\azwz\ARM\PACK\Keil\STM32F1xx_DFP\2.1.0\Device\Include
<h2>Collection of Component Files used:</h2>
* Component: ARM::CMSIS:CORE:5.4.0
Target not created.
Build Time Elapsed: 00:00:15
* Component: ARM::CMSIS:CORE:5.6.0
Build Time Elapsed: 00:00:13
</pre>
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -580,17 +580,17 @@ ARM Macro Assembler Page 9
00000000
Command Line: --debug --xref --diag_suppress=9931 --cpu=Cortex-M3 --apcs=interw
ork --depend=epd-demo\startup_stm32f103xe.d -oepd-demo\startup_stm32f103xe.o -I
.\RTE\_epd-demo -I"D:\Program Files\keil5\ARM\PACK\ARM\CMSIS\5.7.0\CMSIS\Core\I
nclude" -I"D:\Program Files\keil5\ARM\PACK\Keil\STM32F1xx_DFP\2.3.0\Device\Incl
ude" --predefine="__MICROLIB SETA 1" --predefine="__UVISION_VERSION SETA 525" -
.\RTE\_EPD_2in7_V2_test -ID:\KEIL\azwz\ARM\PACK\ARM\CMSIS\5.9.0\CMSIS\Core\Incl
ude -ID:\KEIL\azwz\ARM\PACK\Keil\STM32F1xx_DFP\2.1.0\Device\Include --predefine
="__MICROLIB SETA 1" --predefine="__UVISION_VERSION SETA 526" --predefine="_RTE
ARM Macro Assembler Page 10
-predefine="_RTE_ SETA 1" --predefine="STM32F10X_HD SETA 1" --list=startup_stm3
2f103xe.lst startup_stm32f103xe.s
_ SETA 1" --predefine="STM32F10X_HD SETA 1" --list=startup_stm32f103xe.lst star
tup_stm32f103xe.s

View file

@ -0,0 +1,265 @@
/*****************************************************************************
* | File : EPD_2in7_V2.c
* | Author : Waveshare team
* | Function : 2.7inch V2 e-paper
* | Info :
*----------------
* | This version: V1.0
* | Date : 2022-09-17
* | 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 "EPD_Test.h"
#include "EPD_2in7_V2.h"
#include <time.h>
int EPD_test(void)
{
printf("EPD_2IN7_V2_test Demo\r\n");
if(DEV_Module_Init()!=0){
return -1;
}
printf("e-Paper Init and Clear...\r\n");
EPD_2IN7_V2_Init();
EPD_2IN7_V2_Clear();
//Create a new image cache
UBYTE *BlackImage;
UWORD Imagesize = ((EPD_2IN7_V2_WIDTH % 8 == 0)? (EPD_2IN7_V2_WIDTH / 8 ): (EPD_2IN7_V2_WIDTH / 8 + 1)) * EPD_2IN7_V2_HEIGHT;
if((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) {
printf("Failed to apply for black memory...\r\n");
return -1;
}
printf("Paint_NewImage\r\n");
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
Paint_Clear(WHITE);
#if 1 // Fast Drawing on the image
// Fast refresh
printf("This is followed by a quick refresh demo\r\n");
printf("First, clear the screen\r\n");
EPD_2IN7_V2_Init();
EPD_2IN7_V2_Clear();
printf("e-Paper Init Fast\r\n");
EPD_2IN7_V2_Init_Fast();
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
printf("Drawing\r\n");
//1.Select Image
Paint_SelectImage(BlackImage);
// 2.Drawing on the image
Paint_Clear(WHITE);
printf("Drawing:BlackImage\r\n");
Paint_DrawPoint(10, 80, BLACK, DOT_PIXEL_1X1, DOT_STYLE_DFT);
Paint_DrawPoint(10, 90, BLACK, DOT_PIXEL_2X2, DOT_STYLE_DFT);
Paint_DrawPoint(10, 100, BLACK, DOT_PIXEL_3X3, DOT_STYLE_DFT);
Paint_DrawLine(20, 70, 70, 120, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawLine(70, 70, 20, 120, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawRectangle(20, 70, 70, 120, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawRectangle(80, 70, 130, 120, BLACK, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawCircle(45, 95, 20, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawCircle(105, 95, 20, WHITE, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawLine(85, 95, 125, 95, BLACK, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawLine(105, 75, 105, 115, BLACK, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawString_EN(10, 0, "waveshare", &Font16, BLACK, WHITE);
Paint_DrawString_EN(10, 20, "hello world", &Font12, WHITE, BLACK);
Paint_DrawNum(10, 33, 123456789, &Font12, BLACK, WHITE);
Paint_DrawNum(10, 50, 987654321, &Font16, WHITE, BLACK);
Paint_DrawString_CN(130, 0,"ÄãºÃabc", &Font12CN, BLACK, WHITE);
Paint_DrawString_CN(130, 20, "΢ѩµç×Ó", &Font24CN, WHITE, BLACK);
EPD_2IN7_V2_Display_Fast(BlackImage);
DEV_Delay_ms(3000);
#endif
#if 1 // show bmp
printf("show window BMP-----------------\r\n");
EPD_2IN7_V2_Init();
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
Paint_DrawBitMap(gImage_2in7);
EPD_2IN7_V2_Display(BlackImage);
DEV_Delay_ms(3000);
#endif
#if 1 // Drawing on the image
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
printf("Drawing\r\n");
//1.Select Image
EPD_2IN7_V2_Init();
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
// 2.Drawing on the image
printf("Drawing:BlackImage\r\n");
Paint_DrawPoint(10, 80, BLACK, DOT_PIXEL_1X1, DOT_STYLE_DFT);
Paint_DrawPoint(10, 90, BLACK, DOT_PIXEL_2X2, DOT_STYLE_DFT);
Paint_DrawPoint(10, 100, BLACK, DOT_PIXEL_3X3, DOT_STYLE_DFT);
Paint_DrawLine(20, 70, 70, 120, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawLine(70, 70, 20, 120, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawRectangle(20, 70, 70, 120, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawRectangle(80, 70, 130, 120, BLACK, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawCircle(45, 95, 20, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawCircle(105, 95, 20, WHITE, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawLine(85, 95, 125, 95, BLACK, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawLine(105, 75, 105, 115, BLACK, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawString_EN(10, 0, "waveshare", &Font16, BLACK, WHITE);
Paint_DrawString_EN(10, 20, "hello world", &Font12, WHITE, BLACK);
Paint_DrawNum(10, 33, 123456789, &Font12, BLACK, WHITE);
Paint_DrawNum(10, 50, 987654321, &Font16, WHITE, BLACK);
Paint_DrawString_CN(130, 0,"ÄãºÃabc", &Font12CN, BLACK, WHITE);
Paint_DrawString_CN(130, 20, "΢ѩµç×Ó", &Font24CN, WHITE, BLACK);
EPD_2IN7_V2_Display_Base(BlackImage);
DEV_Delay_ms(3000);
#endif
#if 1 //Partial refresh, example shows time
// If you didn't use the EPD_2IN7_V2_Display_Base() function to refresh the image before,
// use the EPD_2IN7_V2_Display_Base_color() function to refresh the background color,
// otherwise the background color will be garbled
EPD_2IN7_V2_Init();
// EPD_2IN7_V2_Display_Base_color(WHITE);
Paint_NewImage(BlackImage, 50, 120, 90, WHITE);
printf("Partial refresh\r\n");
Paint_SelectImage(BlackImage);
Paint_SetScale(2);
Paint_Clear(WHITE);
PAINT_TIME sPaint_time;
sPaint_time.Hour = 12;
sPaint_time.Min = 34;
sPaint_time.Sec = 56;
UBYTE num = 15;
for (;;) {
sPaint_time.Sec = sPaint_time.Sec + 1;
if (sPaint_time.Sec == 60) {
sPaint_time.Min = sPaint_time.Min + 1;
sPaint_time.Sec = 0;
if (sPaint_time.Min == 60) {
sPaint_time.Hour = sPaint_time.Hour + 1;
sPaint_time.Min = 0;
if (sPaint_time.Hour == 24) {
sPaint_time.Hour = 0;
sPaint_time.Min = 0;
sPaint_time.Sec = 0;
}
}
}
Paint_Clear(WHITE);
Paint_DrawRectangle(1, 1, 120, 50, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawTime(10, 15, &sPaint_time, &Font20, WHITE, BLACK);
num = num - 1;
if(num == 0) {
break;
}
printf("Part refresh...\r\n");
EPD_2IN7_V2_Display_Partial(BlackImage, 60, 134, 110, 254); // Xstart must be a multiple of 8
DEV_Delay_ms(500);
}
#endif
#if 1 // show image for array
free(BlackImage);
printf("show Gray------------------------\r\n");
Imagesize = ((EPD_2IN7_V2_WIDTH % 4 == 0)? (EPD_2IN7_V2_WIDTH / 4 ): (EPD_2IN7_V2_WIDTH / 4 + 1)) * EPD_2IN7_V2_HEIGHT;
if((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) {
printf("Failed to apply for black memory...\r\n");
return -1;
}
EPD_2IN7_V2_Init_4GRAY();
printf("4 grayscale display\r\n");
Paint_NewImage(BlackImage, EPD_2IN7_V2_WIDTH, EPD_2IN7_V2_HEIGHT, 90, WHITE);
Paint_SetScale(4);
Paint_Clear(0xff);
Paint_DrawPoint(10, 80, GRAY4, DOT_PIXEL_1X1, DOT_STYLE_DFT);
Paint_DrawPoint(10, 90, GRAY4, DOT_PIXEL_2X2, DOT_STYLE_DFT);
Paint_DrawPoint(10, 100, GRAY4, DOT_PIXEL_3X3, DOT_STYLE_DFT);
Paint_DrawLine(20, 70, 70, 120, GRAY4, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawLine(70, 70, 20, 120, GRAY4, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
Paint_DrawRectangle(20, 70, 70, 120, GRAY4, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawRectangle(80, 70, 130, 120, GRAY4, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawCircle(45, 95, 20, GRAY4, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
Paint_DrawCircle(105, 95, 20, GRAY2, DOT_PIXEL_1X1, DRAW_FILL_FULL);
Paint_DrawLine(85, 95, 125, 95, GRAY4, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawLine(105, 75, 105, 115, GRAY4, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
Paint_DrawString_EN(10, 0, "waveshare", &Font16, GRAY4, GRAY1);
Paint_DrawString_EN(10, 20, "hello world", &Font12, GRAY3, GRAY1);
Paint_DrawNum(10, 33, 123456789, &Font12, GRAY4, GRAY2);
Paint_DrawNum(10, 50, 987654321, &Font16, GRAY1, GRAY4);
Paint_DrawString_CN(150, 0,"ÄãºÃabc", &Font12CN, GRAY4, GRAY1);
Paint_DrawString_CN(150, 20,"ÄãºÃabc", &Font12CN, GRAY3, GRAY2);
Paint_DrawString_CN(150, 40,"ÄãºÃabc", &Font12CN, GRAY2, GRAY3);
Paint_DrawString_CN(150, 60,"ÄãºÃabc", &Font12CN, GRAY1, GRAY4);
Paint_DrawString_CN(10, 130, "΢ѩµç×Ó", &Font24CN, GRAY1, GRAY4);
EPD_2IN7_V2_4GrayDisplay(BlackImage);
DEV_Delay_ms(3000);
Paint_SelectImage(BlackImage);
Paint_Clear(WHITE);
Paint_DrawBitMap(gImage_2in7_4Gray);
EPD_2IN7_V2_4GrayDisplay(BlackImage);
DEV_Delay_ms(3000);
#endif
printf("Clear...\r\n");
EPD_2IN7_V2_Init();
EPD_2IN7_V2_Clear();
printf("Goto Sleep...\r\n");
EPD_2IN7_V2_Sleep();
free(BlackImage);
BlackImage = NULL;
DEV_Delay_ms(2000);//important, at least 2s
// close 5V
printf("close 5V, Module enters 0 power consumption ...\r\n");
DEV_Module_Exit();
return 0;
}

View file

@ -0,0 +1,526 @@
/*****************************************************************************
* | File : EPD_2in7_V2.c
* | Author : Waveshare team
* | Function : 2.7inch V2 e-paper
* | Info :
*----------------
* | This version: V1.0
* | Date : 2022-08-18
* | 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 "EPD_2in7_V2.h"
#include "Debug.h"
UBYTE LUT_DATA_4Gray[159] =
{
0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x8, 0x48, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x2, 0x48, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x20, 0x48, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xA, 0x19, 0x0, 0x3, 0x8, 0x0, 0x0,
0x14, 0x1, 0x0, 0x14, 0x1, 0x0, 0x3,
0xA, 0x3, 0x0, 0x8, 0x19, 0x0, 0x0,
0x1, 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,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
0x22, 0x17, 0x41, 0x0, 0x32, 0x1C
};
/******************************************************************************
function : Software reset
parameter:
******************************************************************************/
static void EPD_2IN7_V2_Reset(void)
{
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(20);
DEV_Digital_Write(EPD_RST_PIN, 0);
DEV_Delay_ms(2);
DEV_Digital_Write(EPD_RST_PIN, 1);
DEV_Delay_ms(20);
}
/******************************************************************************
function : send command
parameter:
Reg : Command register
******************************************************************************/
static void EPD_2IN7_V2_SendCommand(UBYTE Reg)
{
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Reg);
DEV_Digital_Write(EPD_CS_PIN, 1);
}
/******************************************************************************
function : send data
parameter:
Data : Write data
******************************************************************************/
static void EPD_2IN7_V2_SendData(UBYTE Data)
{
DEV_Digital_Write(EPD_DC_PIN, 1);
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Data);
DEV_Digital_Write(EPD_CS_PIN, 1);
}
/******************************************************************************
function : Wait until the busy_pin goes LOW
parameter:
******************************************************************************/
static void EPD_2IN7_V2_ReadBusy(void)
{
Debug("e-Paper busy\r\n");
do {
if(DEV_Digital_Read(EPD_BUSY_PIN) == 0)
break;
} while(1);
DEV_Delay_ms(20);
Debug("e-Paper busy release\r\n");
}
/******************************************************************************
function : Turn on display
parameter:
******************************************************************************/
static void EPD_2IN7_V2_TurnOnDisplay(void)
{
EPD_2IN7_V2_SendCommand(0x22); //Display Update Control
EPD_2IN7_V2_SendData(0xF7);
EPD_2IN7_V2_SendCommand(0x20); //Activate Display Update Sequence
EPD_2IN7_V2_ReadBusy();
}
static void EPD_2IN7_V2_TurnOnDisplay_Fast(void)
{
EPD_2IN7_V2_SendCommand(0x22); //Display Update Control
EPD_2IN7_V2_SendData(0xC7);
EPD_2IN7_V2_SendCommand(0x20); //Activate Display Update Sequence
EPD_2IN7_V2_ReadBusy();
}
static void EPD_2IN7_V2_TurnOnDisplay_Partial(void)
{
EPD_2IN7_V2_SendCommand(0x22);
EPD_2IN7_V2_SendData(0xFF);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
}
static void EPD_2IN7_V2_TurnOnDisplay_4GRAY(void)
{
EPD_2IN7_V2_SendCommand(0x22);
EPD_2IN7_V2_SendData(0xC7);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
}
/******************************************************************************
function : set the look-up tables
parameter:
******************************************************************************/
static void EPD_2IN7_V2_Lut(void)
{
unsigned int count;
EPD_2IN7_V2_SendCommand(0x32); //vcom
for(count = 0; count < 153; count++) {
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[count]);
}
}
/******************************************************************************
function : Initialize the e-Paper register
parameter:
******************************************************************************/
void EPD_2IN7_V2_Init(void)
{
EPD_2IN7_V2_Reset();
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x12); //SWRESET
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x45); //set Ram-Y address start/end position
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x07); //0x0107-->(263+1)=264
EPD_2IN7_V2_SendData(0x01);
EPD_2IN7_V2_SendCommand(0x4F); // set RAM y address count to 0;
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x11); // data entry mode
EPD_2IN7_V2_SendData(0x03);
}
void EPD_2IN7_V2_Init_Fast(void)
{
EPD_2IN7_V2_Reset();
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x12); //SWRESET
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x18); //Read built-in temperature sensor
EPD_2IN7_V2_SendData(0x80);
EPD_2IN7_V2_SendCommand(0x22); // Load temperature value
EPD_2IN7_V2_SendData(0xB1);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x1A); // Write to temperature register
EPD_2IN7_V2_SendData(0x64);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x45); //set Ram-Y address start/end position
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x07); //0x0107-->(263+1)=264
EPD_2IN7_V2_SendData(0x01);
EPD_2IN7_V2_SendCommand(0x4F); // set RAM y address count to 0;
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x11); // data entry mode
EPD_2IN7_V2_SendData(0x03);
EPD_2IN7_V2_SendCommand(0x22); // Load temperature value
EPD_2IN7_V2_SendData(0x91);
EPD_2IN7_V2_SendCommand(0x20);
EPD_2IN7_V2_ReadBusy();
}
void EPD_2IN7_V2_Init_4GRAY(void)
{
EPD_2IN7_V2_Reset();
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x12); // soft reset
EPD_2IN7_V2_ReadBusy();
EPD_2IN7_V2_SendCommand(0x74); //set analog block control
EPD_2IN7_V2_SendData(0x54);
EPD_2IN7_V2_SendCommand(0x7E); //set digital block control
EPD_2IN7_V2_SendData(0x3B);
EPD_2IN7_V2_SendCommand(0x01); //Driver output control
EPD_2IN7_V2_SendData(0x07);
EPD_2IN7_V2_SendData(0x01);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x11); //data entry mode
EPD_2IN7_V2_SendData(0x03);
EPD_2IN7_V2_SendCommand(0x44); //set Ram-X address start/end position
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x15); //0x15-->(21+1)*8=176
EPD_2IN7_V2_SendCommand(0x45); //set Ram-Y address start/end position
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x07);//0x0107-->(263+1)=264
EPD_2IN7_V2_SendData(0x01);
EPD_2IN7_V2_SendCommand(0x3C); //BorderWavefrom
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x2C); //VCOM Voltage
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[158]); //0x1C
EPD_2IN7_V2_SendCommand(0x3F); //EOPQ
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[153]);
EPD_2IN7_V2_SendCommand(0x03); //VGH
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[154]);
EPD_2IN7_V2_SendCommand(0x04); //
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[155]); //VSH1
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[156]); //VSH2
EPD_2IN7_V2_SendData(LUT_DATA_4Gray[157]); //VSL
EPD_2IN7_V2_Lut(); //LUT
EPD_2IN7_V2_SendCommand(0x4E); // set RAM x address count to 0;
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendCommand(0x4F); // set RAM y address count to 0X199;
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_SendData(0x00);
EPD_2IN7_V2_ReadBusy();
}
/******************************************************************************
function : Clear screen
parameter:
******************************************************************************/
void EPD_2IN7_V2_Clear(void)
{
UWORD Width, Height;
Width = (EPD_2IN7_V2_WIDTH % 8 == 0)? (EPD_2IN7_V2_WIDTH / 8 ): (EPD_2IN7_V2_WIDTH / 8 + 1);
Height = EPD_2IN7_V2_HEIGHT;
EPD_2IN7_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(0XFF);
}
}
EPD_2IN7_V2_TurnOnDisplay();
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_2IN7_V2_Display(UBYTE *Image)
{
UWORD Width, Height;
Width = (EPD_2IN7_V2_WIDTH % 8 == 0)? (EPD_2IN7_V2_WIDTH / 8 ): (EPD_2IN7_V2_WIDTH / 8 + 1);
Height = EPD_2IN7_V2_HEIGHT;
EPD_2IN7_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(Image[i + j * Width]);
}
}
EPD_2IN7_V2_TurnOnDisplay();
}
void EPD_2IN7_V2_Display_Fast(UBYTE *Image)
{
UWORD Width, Height;
Width = (EPD_2IN7_V2_WIDTH % 8 == 0)? (EPD_2IN7_V2_WIDTH / 8 ): (EPD_2IN7_V2_WIDTH / 8 + 1);
Height = EPD_2IN7_V2_HEIGHT;
EPD_2IN7_V2_SendCommand(0x24);
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(Image[i + j * Width]);
}
}
EPD_2IN7_V2_TurnOnDisplay_Fast();
}
void EPD_2IN7_V2_Display_Base(UBYTE *Image)
{
UWORD Width, Height;
Width = (EPD_2IN7_V2_WIDTH % 8 == 0)? (EPD_2IN7_V2_WIDTH / 8 ): (EPD_2IN7_V2_WIDTH / 8 + 1);
Height = EPD_2IN7_V2_HEIGHT;
EPD_2IN7_V2_SendCommand(0x24); //Write Black and White image to RAM
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(Image[i + j * Width]);
}
}
EPD_2IN7_V2_SendCommand(0x26); //Write Black and White image to RAM
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(Image[i + j * Width]);
}
}
EPD_2IN7_V2_TurnOnDisplay();
}
void EPD_2IN7_V2_Display_Base_color(UBYTE color)
{
UWORD Width, Height;
Width = (EPD_2IN7_V2_WIDTH % 8 == 0)? (EPD_2IN7_V2_WIDTH / 8 ): (EPD_2IN7_V2_WIDTH / 8 + 1);
Height = EPD_2IN7_V2_HEIGHT;
EPD_2IN7_V2_SendCommand(0x24); //Write Black and White image to RAM
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(color);
}
}
EPD_2IN7_V2_SendCommand(0x26); //Write Black and White image to RAM
for (UWORD j = 0; j < Height; j++) {
for (UWORD i = 0; i < Width; i++) {
EPD_2IN7_V2_SendData(color);
}
}
// EPD_2IN7_V2_TurnOnDisplay();
}
void EPD_2IN7_V2_Display_Partial(const UBYTE *Image, UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
{
if((Xstart % 8 + Xend % 8 == 8 && Xstart % 8 > Xend % 8) || Xstart % 8 + Xend % 8 == 0 || (Xend - Xstart)%8 == 0)
{
Xstart = Xstart / 8 ;
Xend = Xend / 8;
}
else
{
Xstart = Xstart / 8 ;
Xend = Xend % 8 == 0 ? Xend / 8 : Xend / 8 + 1;
}
UWORD i, Width;
Width = Xend - Xstart;
UWORD IMAGE_COUNTER = Width * (Yend-Ystart);
Xend -= 1;
Yend -= 1;
//Reset
EPD_2IN7_V2_Reset();
EPD_2IN7_V2_SendCommand(0x3C); //BorderWavefrom
EPD_2IN7_V2_SendData(0x80);
//
EPD_2IN7_V2_SendCommand(0x44); // set RAM x address start/end, in page 35
EPD_2IN7_V2_SendData(Xstart & 0xff); // RAM x address start at 00h;
EPD_2IN7_V2_SendData(Xend & 0xff); // RAM x address end at 0fh(15+1)*8->128
EPD_2IN7_V2_SendCommand(0x45); // set RAM y address start/end, in page 35
EPD_2IN7_V2_SendData(Ystart & 0xff); // RAM y address start at 0127h;
EPD_2IN7_V2_SendData((Ystart>>8) & 0x01); // RAM y address start at 0127h;
EPD_2IN7_V2_SendData(Yend & 0xff); // RAM y address end at 00h;
EPD_2IN7_V2_SendData((Yend>>8) & 0x01);
EPD_2IN7_V2_SendCommand(0x4E); // set RAM x address count to 0;
EPD_2IN7_V2_SendData(Xstart & 0xff);
EPD_2IN7_V2_SendCommand(0x4F); // set RAM y address count to 0X127;
EPD_2IN7_V2_SendData(Ystart & 0xff);
EPD_2IN7_V2_SendData((Ystart>>8) & 0x01);
EPD_2IN7_V2_SendCommand(0x24); //Write Black and White image to RAM
for (i = 0; i < IMAGE_COUNTER; i++) {
EPD_2IN7_V2_SendData(Image[i]);
}
EPD_2IN7_V2_TurnOnDisplay_Partial();
}
void EPD_2IN7_V2_4GrayDisplay(UBYTE *Image)
{
UDOUBLE i,j,k;
UBYTE temp1,temp2,temp3;
// old data
EPD_2IN7_V2_SendCommand(0x24);
for(i=0; i<5808; i++) { //5808*4 46464
temp3=0;
for(j=0; j<2; j++) {
temp1 = Image[i*2+j];
for(k=0; k<2; k++) {
temp2 = temp1&0xC0;
if(temp2 == 0xC0)
temp3 |= 0x00;
else if(temp2 == 0x00)
temp3 |= 0x01;
else if(temp2 == 0x80)
temp3 |= 0x01;
else //0x40
temp3 |= 0x00;
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x00;
else if(temp2 == 0x00)
temp3 |= 0x01;
else if(temp2 == 0x80)
temp3 |= 0x01;
else //0x40
temp3 |= 0x00;
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
EPD_2IN7_V2_SendData(temp3);
// printf("%x",temp3);
}
EPD_2IN7_V2_SendCommand(0x26); //write RAM for black(0)/white (1)
for(i=0; i<5808; i++) { //5808*4 46464
temp3=0;
for(j=0; j<2; j++) {
temp1 = Image[i*2+j];
for(k=0; k<2; k++) {
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0)
temp3 |= 0x00;//white
else if(temp2 == 0x00)
temp3 |= 0x01; //black
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1
else //0x40
temp3 |= 0x01; //gray2
temp3 <<= 1;
temp1 <<= 2;
temp2 = temp1&0xC0 ;
if(temp2 == 0xC0) //white
temp3 |= 0x00;
else if(temp2 == 0x00) //black
temp3 |= 0x01;
else if(temp2 == 0x80)
temp3 |= 0x00; //gray1
else //0x40
temp3 |= 0x01; //gray2
if(j!=1 || k!=1)
temp3 <<= 1;
temp1 <<= 2;
}
}
EPD_2IN7_V2_SendData(temp3);
// printf("%x",temp3);
}
EPD_2IN7_V2_TurnOnDisplay_4GRAY();
}
/******************************************************************************
function : Enter sleep mode
parameter:
******************************************************************************/
void EPD_2IN7_V2_Sleep(void)
{
EPD_2IN7_V2_SendCommand(0X10);
EPD_2IN7_V2_SendData(0x01);
}

View file

@ -0,0 +1,52 @@
/*****************************************************************************
* | File : EPD_2in7_V2.h
* | Author : Waveshare team
* | Function : 2.7inch V2 e-paper
* | Info :
*----------------
* | This version: V1.0
* | Date : 2022-08-18
* | 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.
#
******************************************************************************/
#ifndef __EPD_2IN7_V2_H_
#define __EPD_2IN7_V2_H_
#include "DEV_Config.h"
// Display resolution
#define EPD_2IN7_V2_WIDTH 176
#define EPD_2IN7_V2_HEIGHT 264
void EPD_2IN7_V2_Init(void);
void EPD_2IN7_V2_Init_Fast(void);
void EPD_2IN7_V2_Init_4GRAY(void);
void EPD_2IN7_V2_Clear(void);
void EPD_2IN7_V2_Display(UBYTE *Image);
void EPD_2IN7_V2_Display_Fast(UBYTE *Image);
void EPD_2IN7_V2_Display_Base(UBYTE *Image);
void EPD_2IN7_V2_Display_Base_color(UBYTE color);
void EPD_2IN7_V2_Display_Partial(const UBYTE *Image, UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yende);
void EPD_2IN7_V2_4GrayDisplay(UBYTE *Image);
void EPD_2IN7_V2_Sleep(void);
#endif

View file

@ -33,4 +33,5 @@
2022-07-22添加新程序3.52inch e-Paper例程。
2022-08-16添加新程序4.37inch e-Paper (G)例程。
2022-08-17添加新程序2.36inch e-Paper (G)例程。
2022-10-22添加新程序7.3inch e-Paper (F)例程。
2022-10-22添加新程序7.3inch e-Paper (F)例程。
2022-10-27添加新程序2.7inch V2 e-Paper 例程。

View file

@ -32,4 +32,5 @@
2022-07-22: Added new programs 3.52inch e-Paper routine.
2022-08-16: Added new programs 4.37inch e-Paper (G) routine.
2022-08-17: Added new programs 2.36inch e-Paper (G) routine.
2022-10-22: Added new programs 7.3inch e-Paper (F) routine.
2022-10-22: Added new programs 7.3inch e-Paper (F) routine.
2022-10-27: Added new programs 2.7inch V2 e-Paper routine.