Fix compiler warnings for LOLIN_EPD library

Also mentioned in this (unmerged) PR: https://github.com/wemos/LOLIN_EPD_Library/pull/7/files
This commit is contained in:
Gijs Noorlander
2020-08-30 21:46:12 +02:00
parent 316549ed23
commit ffe27f2ff4
10 changed files with 1556 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
.vscode
.build
+4
View File
@@ -0,0 +1,4 @@
# Arduino library for the LOLIN EPD shield
### Installation
- Clone this repository or download&unzip [zip file](https://github.com/wemos/LOLIN_EPD_Library/archive/master.zip) into Arduino/libraries
@@ -0,0 +1,248 @@
#include <LOLIN_EPD.h>
#include <Adafruit_GFX.h>
float p = 3.1415926;
/*D1 mini*/
#define EPD_CS D0
#define EPD_DC D8
#define EPD_RST -1 // can set to -1 and share with microcontroller Reset!
#define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)
/*D32 Pro*/
// #define EPD_CS 14
// #define EPD_DC 27
// #define EPD_RST 33 // can set to -1 and share with microcontroller Reset!
// #define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)
LOLIN_IL3897 EPD(250, 122, EPD_DC, EPD_RST, EPD_CS, EPD_BUSY); //hardware SPI
// #define EPD_MOSI D7
// #define EPD_CLK D5
// LOLIN_IL3897 EPD(250,122, EPD_MOSI, EPD_CLK, EPD_DC, EPD_RST, EPD_CS, EPD_BUSY); //IO
void setup(void) {
Serial.begin(115200);
Serial.print("Hello! EPD Test");
EPD.begin();
Serial.println("Initialized");
// large block of text
EPD.clearBuffer();
EPD.fillScreen(EPD_WHITE);
testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", EPD_BLACK);
// epd print function!
epdPrintTest();
// a single pixel
EPD.clearBuffer();
EPD.drawPixel(EPD.width()/2, EPD.height()/2, EPD_BLACK);
testtriangles();
// line draw test
testlines(EPD_BLACK);
// optimized lines
testfastlines(EPD_BLACK, EPD_RED);
testdrawrects(EPD_RED);
testfillrects(EPD_BLACK, EPD_RED);
EPD.fillScreen(EPD_WHITE);
testfillcircles(10, EPD_RED);
testdrawcircles(10, EPD_BLACK);
testroundrects();
mediabuttons();
Serial.println("done");
}
void loop() {
delay(500);
}
void testlines(uint16_t color) {
EPD.clearBuffer();
EPD.fillScreen(EPD_WHITE);
for (int16_t x=0; x < EPD.width(); x+=6) {
EPD.drawLine(0, 0, x, EPD.height()-1, color);
}
for (int16_t y=0; y < EPD.height(); y+=6) {
EPD.drawLine(0, 0, EPD.width()-1, y, color);
}
EPD.fillScreen(EPD_WHITE);
for (int16_t x=0; x < EPD.width(); x+=6) {
EPD.drawLine(EPD.width()-1, 0, x, EPD.height()-1, color);
}
for (int16_t y=0; y < EPD.height(); y+=6) {
EPD.drawLine(EPD.width()-1, 0, 0, y, color);
}
EPD.fillScreen(EPD_WHITE);
for (int16_t x=0; x < EPD.width(); x+=6) {
EPD.drawLine(0, EPD.height()-1, x, 0, color);
}
for (int16_t y=0; y < EPD.height(); y+=6) {
EPD.drawLine(0, EPD.height()-1, EPD.width()-1, y, color);
}
EPD.fillScreen(EPD_WHITE);
for (int16_t x=0; x < EPD.width(); x+=6) {
EPD.drawLine(EPD.width()-1, EPD.height()-1, x, 0, color);
}
for (int16_t y=0; y < EPD.height(); y+=6) {
EPD.drawLine(EPD.width()-1, EPD.height()-1, 0, y, color);
}
EPD.display();
}
void testdrawtext(char *text, uint16_t color) {
EPD.clearBuffer();
EPD.setCursor(0, 0);
EPD.setTextColor(color);
EPD.setTextWrap(true);
EPD.print(text);
EPD.display();
}
void testfastlines(uint16_t color1, uint16_t color2) {
EPD.clearBuffer();
EPD.fillScreen(EPD_WHITE);
for (int16_t y=0; y < EPD.height(); y+=5) {
EPD.drawFastHLine(0, y, EPD.width(), color1);
}
for (int16_t x=0; x < EPD.width(); x+=5) {
EPD.drawFastVLine(x, 0, EPD.height(), color2);
}
EPD.display();
}
void testdrawrects(uint16_t color) {
EPD.clearBuffer();
EPD.fillScreen(EPD_WHITE);
for (int16_t x=0; x < EPD.width(); x+=6) {
EPD.drawRect(EPD.width()/2 -x/2, EPD.height()/2 -x/2 , x, x, color);
}
EPD.display();
}
void testfillrects(uint16_t color1, uint16_t color2) {
EPD.clearBuffer();
EPD.fillScreen(EPD_WHITE);
for (int16_t x=EPD.width()-1; x > 6; x-=6) {
EPD.fillRect(EPD.width()/2 -x/2, EPD.height()/2 -x/2 , x, x, color1);
EPD.drawRect(EPD.width()/2 -x/2, EPD.height()/2 -x/2 , x, x, color2);
}
EPD.display();
}
void testfillcircles(uint8_t radius, uint16_t color) {
EPD.clearBuffer();
for (int16_t x=radius; x < EPD.width(); x+=radius*2) {
for (int16_t y=radius; y < EPD.height(); y+=radius*2) {
EPD.fillCircle(x, y, radius, color);
}
}
EPD.display();
}
void testdrawcircles(uint8_t radius, uint16_t color) {
EPD.clearBuffer();
for (int16_t x=0; x < EPD.width()+radius; x+=radius*2) {
for (int16_t y=0; y < EPD.height()+radius; y+=radius*2) {
EPD.drawCircle(x, y, radius, color);
}
}
EPD.display();
}
void testtriangles() {
EPD.clearBuffer();
EPD.fillScreen(EPD_WHITE);
int color = EPD_BLACK;
int t;
int w = EPD.width()/2;
int x = EPD.height()-1;
int y = 0;
int z = EPD.width();
for(t = 0 ; t <= 15; t++) {
EPD.drawTriangle(w, y, y, x, z, x, color);
x-=4;
y+=4;
z-=4;
if(t == 8) color = EPD_RED;
}
EPD.display();
}
void testroundrects() {
EPD.clearBuffer();
EPD.fillScreen(EPD_WHITE);
int color = EPD_BLACK;
int i;
int t;
for(t = 0 ; t <= 4; t+=1) {
int x = 0;
int y = 0;
int w = EPD.width()-2;
int h = EPD.height()-2;
for(i = 0 ; i <= 16; i+=1) {
EPD.drawRoundRect(x, y, w, h, 5, color);
x+=2;
y+=3;
w-=4;
h-=6;
if(i == 7) color = EPD_RED;
}
color = EPD_BLACK;
}
EPD.display();
}
void epdPrintTest() {
EPD.clearBuffer();
EPD.setCursor(2, 0);
EPD.fillScreen(EPD_WHITE);
EPD.setTextColor(EPD_BLACK);
EPD.setTextSize(2);
EPD.println("Hello World!");
EPD.setTextSize(1);
EPD.setTextColor(EPD_RED);
EPD.print(p, 6);
EPD.println(" Want pi?");
EPD.println(" ");
EPD.print(8675309, HEX); // print 8,675,309 out in HEX!
EPD.println(" Print HEX!");
EPD.println(" ");
EPD.setTextColor(EPD_BLACK);
EPD.println("Sketch has been");
EPD.println("running for: ");
EPD.setTextColor(EPD_RED);
EPD.print(millis() / 1000);
EPD.setTextColor(EPD_BLACK);
EPD.print(" seconds.");
EPD.display();
}
void mediabuttons() {
EPD.clearBuffer();
// play
EPD.fillScreen(EPD_WHITE);
EPD.fillRoundRect(25, 10, 78, 60, 8, EPD_BLACK);
EPD.fillTriangle(42, 20, 42, 60, 90, 40, EPD_RED);
// pause
EPD.fillRoundRect(25, 90, 78, 60, 8, EPD_BLACK);
EPD.fillRoundRect(39, 98, 20, 45, 5, EPD_RED);
EPD.fillRoundRect(69, 98, 20, 45, 5, EPD_RED);
EPD.display();
}
@@ -0,0 +1,315 @@
#include <LOLIN_EPD.h>
#include <Adafruit_GFX.h>
const unsigned char gImage_num1[128] PROGMEM = {
/* 0X02,0X01,0X20,0X00,0X20,0X00, */
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xDF,
0xFF,
0xF7,
0xFF,
0xDF,
0xFF,
0xF7,
0xFF,
0xDF,
0xFF,
0xF7,
0xFF,
0xDF,
0xFF,
0xE7,
0xFF,
0x80,
0x00,
0x07,
0xFF,
0x00,
0x00,
0x07,
0xFF,
0x00,
0x00,
0x07,
0xFF,
0xFF,
0xFF,
0xE7,
0xFF,
0xFF,
0xFF,
0xF7,
0xFF,
0xFF,
0xFF,
0xF7,
0xFF,
0xFF,
0xFF,
0xF7,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
};
const unsigned char gImage_num2[128] PROGMEM = {
/* 0X02,0X01,0X20,0X00,0X20,0X00, */
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xE1,
0xFF,
0xC7,
0xFF,
0xC1,
0xFF,
0x87,
0xFF,
0x99,
0xFF,
0x27,
0xFF,
0x3F,
0xFE,
0x67,
0xFF,
0x7F,
0xFC,
0xE7,
0xFF,
0x7F,
0xF9,
0xE7,
0xFF,
0x7F,
0xF3,
0xE7,
0xFF,
0x7F,
0xE7,
0xE7,
0xFF,
0x3F,
0xCF,
0xE7,
0xFF,
0x1F,
0x1F,
0xE7,
0xFF,
0x80,
0x3F,
0xC7,
0xFF,
0x80,
0x7E,
0x07,
0xFF,
0xE0,
0xFE,
0x1F,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
};
/*D1 mini*/
#define EPD_CS D0
#define EPD_DC D8
#define EPD_RST -1 // can set to -1 and share with microcontroller Reset!
#define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)
/*D32 Pro*/
// #define EPD_CS 14
// #define EPD_DC 27
// #define EPD_RST 33 // can set to -1 and share with microcontroller Reset!
// #define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)
LOLIN_IL3897 EPD(250, 122, EPD_DC, EPD_RST, EPD_CS, EPD_BUSY); //hardware SPI
// #define EPD_MOSI D7
// #define EPD_CLK D5
// LOLIN_IL3897 EPD(250,122, EPD_MOSI, EPD_CLK, EPD_DC, EPD_RST, EPD_CS, EPD_BUSY); //IO
void setup()
{
EPD.begin();
EPD.clearBuffer();
EPD.setTextColor(EPD_BLACK);
EPD.println("hello world!");
// EPD.display();
// delay(2000);
EPD.partInit();
delay(100);
}
void loop()
{
// for (uint8_t i = 0; i < 4; i++)
// {
// EPD.setRotation(i);
// EPD.clearBuffer();
// EPD.setCursor(0,0);
// EPD.println("hello world!");
// EPD.println(EPD.getRotation());
// EPD.display();
// delay(2000);
// }
EPD.partDisplay(0, 32, gImage_num1, 32, 32);
EPD.partDisplay(0, 32, gImage_num2, 32, 32);
delay(2000);
}
+31
View File
@@ -0,0 +1,31 @@
#######################################
# Syntax Coloring Map For LOLIN EPD
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
LOLIN_IL3897 KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
clearBuffer KEYWORD2
drawPixel KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
EPD_BLACK LITERAL1
EPD_WHITE LITERAL1
EPD_INVERSE LITERAL1
EPD_RED LITERAL1
EPD_DARK LITERAL1
EPD_LIGHT LITERAL1
+9
View File
@@ -0,0 +1,9 @@
name=LOLIN_EPD
version=1.0.0
author=WEMOS.CC <support@wemos.cc>
maintainer=WEMOS.CC
sentence=Library for the <a href="https://www.wemos.cc">EPD Shield.</a>.
paragraph=LOLIN EPD
category=Device Control
url=https://github.com/wemos/LOLIN_EPD_Library
architectures=*
+264
View File
@@ -0,0 +1,264 @@
#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#else
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) ///< read bytes from program memory
#endif
#if !defined(__ARM_ARCH) && !defined(ENERGIA) && !defined(ESP8266) && !defined(ESP32) && !defined(__arc__)
#include <util/delay.h>
#endif
#include <stdlib.h>
#include <SPI.h>
#include "Adafruit_GFX.h"
#include "LOLIN_EPD.h"
LOLIN_EPD::LOLIN_EPD(int width, int height, int8_t spi_mosi, int8_t spi_clock, int8_t DC, int8_t RST, int8_t CS, int8_t BUSY):Adafruit_GFX(width, height)
{
cs = CS;
rst = RST;
dc = DC;
sclk = spi_clock;
sid = spi_mosi;
busy = BUSY;
hwSPI = false;
singleByteTxns = false;
}
LOLIN_EPD::LOLIN_EPD(int width, int height, int8_t DC, int8_t RST, int8_t CS, int8_t BUSY):Adafruit_GFX(width, height)
{
dc = DC;
rst = RST;
cs = CS;
busy = BUSY;
hwSPI = true;
singleByteTxns = false;
}
/**************************************************************************/
/*!
@brief default destructor
*/
/**************************************************************************/
LOLIN_EPD::~LOLIN_EPD()
{
free(bw_buf);
free(red_buf);
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void LOLIN_EPD::begin(bool reset)
{
blackInverted = true;
redInverted = false;
// set pin directions
pinMode(dc, OUTPUT);
pinMode(cs, OUTPUT);
#ifdef HAVE_PORTREG
csport = portOutputRegister(digitalPinToPort(cs));
cspinmask = digitalPinToBitMask(cs);
dcport = portOutputRegister(digitalPinToPort(dc));
dcpinmask = digitalPinToBitMask(dc);
#endif
csHigh();
if (!hwSPI)
{
// set pins for software-SPI
pinMode(sid, OUTPUT);
pinMode(sclk, OUTPUT);
#ifdef HAVE_PORTREG
clkport = portOutputRegister(digitalPinToPort(sclk));
clkpinmask = digitalPinToBitMask(sclk);
mosiport = portOutputRegister(digitalPinToPort(sid));
mosipinmask = digitalPinToBitMask(sid);
#endif
}
else
{
SPI.begin();
#ifndef SPI_HAS_TRANSACTION
SPI.setClockDivider(4);
#endif
}
if ((reset) && (rst >= 0))
{
// Setup reset pin direction
pinMode(rst, OUTPUT);
// VDD (3.3V) goes high at start, lets just chill for a ms
digitalWrite(rst, HIGH);
delay(1);
// bring reset low
digitalWrite(rst, LOW);
// wait 10ms
delay(10);
// bring out of reset
digitalWrite(rst, HIGH);
}
if (busy >= 0)
{
pinMode(busy, INPUT);
}
}
/**************************************************************************/
/*!
@brief send an EPD command with no data
@param c the command to send
@param end if true the cs pin will be pulled high following the transaction. If false the cs pin will remain low.
@returns the data byte read over the SPI bus
*/
/**************************************************************************/
void LOLIN_EPD::sendCmd(uint8_t c)
{
// SPI
csHigh();
dcLow();
csLow();
fastSPIwrite(c);
csHigh();
}
/**************************************************************************/
/*!
@brief send data to the display
@param buf the data buffer to send
@param len the length of the data buffer
*/
/**************************************************************************/
void LOLIN_EPD::sendData(uint8_t data)
{
// SPI
csHigh();
dcHigh();
csLow();
fastSPIwrite(data);
csHigh();
}
/**************************************************************************/
/*!
@brief transfer a single byte over SPI.
@param d the data to send
@returns the data byte read
*/
/**************************************************************************/
uint8_t LOLIN_EPD::fastSPIwrite(uint8_t d)
{
if (hwSPI)
{
if (singleByteTxns)
{
uint8_t b;
csLow();
b = SPI.transfer(d);
csHigh();
return b;
}
else
return SPI.transfer(d);
}
else
{
//TODO: return read data for software SPI
for (uint8_t bit = 0x80; bit; bit >>= 1)
{
#ifdef HAVE_PORTREG
*clkport &= ~clkpinmask;
if (d & bit)
*mosiport |= mosipinmask;
else
*mosiport &= ~mosipinmask;
*clkport |= clkpinmask;
#else
digitalWrite(sclk, LOW);
if (d & bit)
digitalWrite(sid, HIGH);
else
digitalWrite(sid, LOW);
digitalWrite(sclk, HIGH);
#endif
}
return 0;
}
}
/**************************************************************************/
/*!
@brief set chip select pin high
*/
/**************************************************************************/
void LOLIN_EPD::csHigh()
{
#ifdef SPI_HAS_TRANSACTION
SPI.endTransaction();
#endif
#ifdef HAVE_PORTREG
*csport |= cspinmask;
#else
digitalWrite(cs, HIGH);
#endif
}
/**************************************************************************/
/*!
@brief set chip select pin low
*/
/**************************************************************************/
void LOLIN_EPD::csLow()
{
#ifdef SPI_HAS_TRANSACTION
SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
#endif
#ifdef HAVE_PORTREG
*csport &= ~cspinmask;
#else
digitalWrite(cs, LOW);
#endif
}
/**************************************************************************/
/*!
@brief set data/command pin high
*/
/**************************************************************************/
void LOLIN_EPD::dcHigh()
{
#ifdef HAVE_PORTREG
*dcport |= dcpinmask;
#else
digitalWrite(dc, HIGH);
#endif
}
/**************************************************************************/
/*!
@brief set data/command pin low
*/
/**************************************************************************/
void LOLIN_EPD::dcLow()
{
#ifdef HAVE_PORTREG
*dcport &= ~dcpinmask;
#else
digitalWrite(dc, LOW);
#endif
}
+111
View File
@@ -0,0 +1,111 @@
#ifndef __LOLIN_EPD_H
#define __LOLIN_EPD_H
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#if defined(__SAM3X8E__)
typedef volatile RwReg PortReg; ///< a port register for fast access
typedef uint32_t PortMask; ///< a port register mask for your pin
#define HAVE_PORTREG
#elif defined(ARDUINO_ARCH_SAMD)
// not supported
#elif defined(ESP8266) || defined(ESP32) || defined(ARDUINO_STM32_FEATHER) || defined(__arc__)
typedef volatile uint32_t PortReg; ///< a port register for fast access
typedef uint32_t PortMask; ///< a port register mask for your pin
#elif defined(__AVR__)
typedef volatile uint8_t PortReg; ///< a port register for fast access
typedef uint8_t PortMask; ///< a port register mask for your pin
#define HAVE_PORTREG
#else
// chances are its 32 bit so assume that
typedef volatile uint32_t PortReg; ///< a port register for fast access
typedef uint32_t PortMask; ///< a port register mask for your pin
#endif
#include <SPI.h>
#include <Adafruit_GFX.h>
/**************************************************************************/
/*!
available EPD colors
*/
/**************************************************************************/
enum
{
EPD_BLACK, ///< black color
EPD_WHITE, ///< white color
EPD_INVERSE, ///< invert color
EPD_RED, ///< red color
EPD_DARK, ///< darker color
EPD_LIGHT, ///< lighter color
};
#define EPD_swap(a, b) \
{ \
int16_t t = a; \
a = b; \
b = t; \
} ///< simple swap function
/**************************************************************************/
/*!
Class for interfacing with LOLIN EPD display breakouts.
*/
/**************************************************************************/
class LOLIN_EPD: public Adafruit_GFX
{
public:
LOLIN_EPD(int width, int height, int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS, int8_t BUSY = -1);
LOLIN_EPD(int width, int height, int8_t DC, int8_t RST, int8_t CS, int8_t BUSY = -1);
~LOLIN_EPD();
void begin(bool reset = true);
protected:
int8_t sid, ///< sid pin
sclk, ///< serial clock pin
dc, ///< data/command pin
rst, ///< reset pin
cs, ///< chip select pin
busy; ///< busy pin
bool blackInverted, ///< is black channel inverted
redInverted; ///< is red channel inverted
int bw_bufsize, ///< size of the black and white buffer
red_bufsize; ///< size of the red buffer
bool singleByteTxns; ///< if true CS will go high after every data byte transferred
uint8_t *bw_buf; ///< the pointer to the black and white buffer if using on-chip ram
uint8_t *red_buf; ///< the pointer to the red buffer if using on-chip ram
void sendCmd(uint8_t c);
void sendData(uint8_t data);
uint8_t fastSPIwrite(uint8_t c);
boolean hwSPI; ///< true if using hardware SPI
#ifdef HAVE_PORTREG
PortReg *mosiport, ///< mosi port register
*clkport, ///< serial clock port register
*csport, ///< chip select port register
*dcport; ///< data/command port register
PortMask mosipinmask, ///< mosi pin mask
clkpinmask, ///< serial clock pin mask
cspinmask, ///< chip select pin mask
dcpinmask; ///< data / command pin mask
#endif
void csLow();
void csHigh();
void dcHigh();
void dcLow();
private:
};
#include "LOLIN_IL3897.h"
#endif
+523
View File
@@ -0,0 +1,523 @@
#include "LOLIN_EPD.h"
#include "LOLIN_IL3897.h"
#define ALLSCREEN_GRAGHBYTES 4000
///////////////////////////////////////////////////
/////////////////EPD settings Functions/////////////////////
/////////////////////////////////////LUT//////////////////////////////////////////////
const unsigned char LUT_DATA[] PROGMEM = {
0x80,
0x60,
0x40,
0x00,
0x00,
0x00,
0x00, //LUT0: BB: VS 0 ~7
0x10,
0x60,
0x20,
0x00,
0x00,
0x00,
0x00, //LUT1: BW: VS 0 ~7
0x80,
0x60,
0x40,
0x00,
0x00,
0x00,
0x00, //LUT2: WB: VS 0 ~7
0x10,
0x60,
0x20,
0x00,
0x00,
0x00,
0x00, //LUT3: WW: VS 0 ~7
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, //LUT4: VCOM: VS 0 ~7
0x03,
0x03,
0x00,
0x00,
0x02, // TP0 A~D RP0
0x09,
0x09,
0x00,
0x00,
0x02, // TP1 A~D RP1
0x03,
0x03,
0x00,
0x00,
0x02, // TP2 A~D RP2
0x00,
0x00,
0x00,
0x00,
0x00, // TP3 A~D RP3
0x00,
0x00,
0x00,
0x00,
0x00, // TP4 A~D RP4
0x00,
0x00,
0x00,
0x00,
0x00, // TP5 A~D RP5
0x00,
0x00,
0x00,
0x00,
0x00, // TP6 A~D RP6
0x15,
0x41,
0xA8,
0x32,
0x30,
0x0A,
};
const unsigned char LUT_DATA_part[] PROGMEM = {
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, //LUT0: BB: VS 0 ~7
0x80,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, //LUT1: BW: VS 0 ~7
0x40,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, //LUT2: WB: VS 0 ~7
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, //LUT3: WW: VS 0 ~7
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, //LUT4: VCOM: VS 0 ~7
0x0A,
0x00,
0x00,
0x00,
0x00, // TP0 A~D RP0
0x00,
0x00,
0x00,
0x00,
0x00, // TP1 A~D RP1
0x00,
0x00,
0x00,
0x00,
0x00, // TP2 A~D RP2
0x00,
0x00,
0x00,
0x00,
0x00, // TP3 A~D RP3
0x00,
0x00,
0x00,
0x00,
0x00, // TP4 A~D RP4
0x00,
0x00,
0x00,
0x00,
0x00, // TP5 A~D RP5
0x00,
0x00,
0x00,
0x00,
0x00, // TP6 A~D RP6
0x15,
0x41,
0xA8,
0x32,
0x30,
0x0A,
};
#define BUSY_WAIT 1000
/*!
@brief constructor if using on-chip RAM and software SPI
@param width the width of the display in pixels
@param height the height of the display in pixels
@param SID the SID pin to use
@param SCLK the SCLK pin to use
@param DC the data/command pin to use
@param RST the reset pin to use
@param CS the chip select pin to use
@param BUSY the busy pin to use
*/
/**************************************************************************/
LOLIN_IL3897::LOLIN_IL3897(int width, int height, int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS, int8_t BUSY) : LOLIN_EPD(width, height, SID, SCLK, DC, RST, CS, BUSY)
{
if ((height % 8) > 0)
{
_height_8bit = (height / 8 + 1) * 8;
}
else
{
_height_8bit = height;
}
bw_buf = (uint8_t *)malloc(width * _height_8bit / 8);
red_buf = (uint8_t *)malloc(width * _height_8bit / 8);
bw_bufsize = width * _height_8bit / 8;
red_bufsize = bw_bufsize;
}
LOLIN_IL3897::LOLIN_IL3897(int width, int height, int8_t DC, int8_t RST, int8_t CS, int8_t BUSY) : LOLIN_EPD(width, height, DC, RST, CS, BUSY)
{
if ((height % 8) > 0)
{
_height_8bit = (height / 8 + 1) * 8;
}
else
{
_height_8bit = height;
}
bw_buf = (uint8_t *)malloc(width * _height_8bit / 8);
red_buf = (uint8_t *)malloc(width * _height_8bit / 8);
bw_bufsize = width * _height_8bit / 8;
red_bufsize = bw_bufsize;
}
/**************************************************************************/
/*!
@brief begin communication with and set up the display.
@param reset if true the reset pin will be toggled.
*/
/**************************************************************************/
void LOLIN_IL3897::begin(bool reset)
{
LOLIN_EPD::begin(reset);
readBusy();
sendCmd(0x12); // soft reset
readBusy();
sendCmd(0x74); //set analog block control
sendData(0x54);
sendCmd(0x7E); //set digital block control
sendData(0x3B);
sendCmd(0x01); //Driver output control
sendData(0xF9);
sendData(0x00);
sendData(0x00);
sendCmd(0x11); //data entry mode
sendData(0x01);
sendCmd(0x44); //set Ram-X address start/end position
sendData(0x00);
sendData(0x0F); //0x0C-->(15+1)*8=128
sendCmd(0x45); //set Ram-Y address start/end position
sendData(0xF9); //0xF9-->(249+1)=250
sendData(0x00);
sendData(0x00);
sendData(0x00);
sendCmd(0x3C); //BorderWavefrom
sendData(0x03);
sendCmd(0x2C); //VCOM Voltage
sendData(0x55); //
sendCmd(0x03); //
sendData(LUT_DATA[70]);
sendCmd(0x04); //
sendData(LUT_DATA[71]);
sendData(LUT_DATA[72]);
sendData(LUT_DATA[73]);
sendCmd(0x3A); //Dummy Line
sendData(LUT_DATA[74]);
sendCmd(0x3B); //Gate time
sendData(LUT_DATA[75]);
selectLUT((unsigned char *)LUT_DATA); //LUT
sendCmd(0x4E); // set RAM x address count to 0;
sendData(0x00);
sendCmd(0x4F); // set RAM y address count to 0X127;
sendData(0xF9);
sendData(0x00);
readBusy();
}
void LOLIN_IL3897::display()
{
sendCmd(0x24); //write RAM for black(0)/white (1)
for (uint16_t i = 0; i < bw_bufsize; i++)
{
sendData(bw_buf[i]);
}
update();
}
void LOLIN_IL3897::update()
{
sendCmd(0x22);
sendData(0xC7);
sendCmd(0x20);
readBusy();
}
/**************************************************************************/
/*!
@brief draw a single pixel on the screen
@param x the x axis position
@param y the y axis position
@param color the color of the pixel
*/
/**************************************************************************/
void LOLIN_IL3897::drawPixel(int16_t x, int16_t y, uint16_t color)
{
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
return;
uint8_t *pBuf;
// check rotation, move pixel around if necessary
switch (getRotation())
{
case 1:
EPD_swap(x, y);
x = WIDTH - x - 1;
break;
case 2:
x = WIDTH - x - 1;
y = HEIGHT - y - 1;
break;
case 3:
EPD_swap(x, y);
y = HEIGHT - y - 1;
break;
}
//make our buffer happy
x = (x == 0 ? 1 : x);
// uint16_t addr = (x * height() + y) / 8;
uint16_t addr = (x * _height_8bit + y) / 8;
if (color == EPD_RED)
{
pBuf = red_buf + addr;
}
else
{
pBuf = bw_buf + addr;
}
// x is which column
switch (color)
{
case EPD_WHITE:
*pBuf |= (1 << (7 - y % 8));
break;
case EPD_RED:
case EPD_BLACK:
*pBuf &= ~(1 << (7 - y % 8));
break;
case EPD_INVERSE:
*pBuf ^= (1 << (7 - y % 8));
break;
}
}
/**************************************************************************/
/*!
@brief clear all data buffers
*/
/**************************************************************************/
void LOLIN_IL3897::clearBuffer()
{
memset(bw_buf, 0xFF, bw_bufsize);
}
/**************************************************************************/
/*!
@brief clear the display twice to remove any spooky ghost images
*/
/**************************************************************************/
void LOLIN_IL3897::clearDisplay()
{
clearBuffer();
display();
delay(100);
display();
}
void LOLIN_IL3897::readBusy()
{
if (busy >= 0)
{
while (1)
{
if (digitalRead(busy) == 0)
break;
}
}
else
{
delay(BUSY_WAIT);
}
}
void LOLIN_IL3897::selectLUT(uint8_t *wave_data)
{
uint8_t count;
sendCmd(0x32);
for (count = 0; count < 70; count++)
sendData(pgm_read_byte(&wave_data[count]));
}
void LOLIN_IL3897::deepSleep()
{
sendCmd(0x10); //enter deep sleep
sendData(0x01);
delay(100);
}
void LOLIN_IL3897::partInit()
{
partBaseImg();
sendCmd(0x2C); //VCOM Voltage
sendData(0x26);
readBusy();
selectLUT((unsigned char *)LUT_DATA_part);
sendCmd(0x37);
sendData(0x00);
sendData(0x00);
sendData(0x00);
sendData(0x00);
sendData(0x40);
sendData(0x00);
sendData(0x00);
sendCmd(0x22);
sendData(0xC0);
sendCmd(0x20);
readBusy();
sendCmd(0x3C); //BorderWavefrom
sendData(0x01);
}
void LOLIN_IL3897::partBaseImg()
{
sendCmd(0x24); ////Write Black and White image to RAM
for (uint16_t i = 0; i < bw_bufsize; i++)
{
sendData(bw_buf[i]);
}
sendCmd(0x26); ////Write Black and White image to RAM
for (uint16_t i = 0; i < bw_bufsize; i++)
{
sendData(bw_buf[i]);
}
update();
}
void LOLIN_IL3897::partUpdate()
{
sendCmd(0x22);
sendData(0x0C);
sendCmd(0x20);
readBusy();
}
void LOLIN_IL3897::partDisplay(int16_t x_start, int16_t y_start, const unsigned char *datas, int16_t PART_COLUMN, int16_t PART_LINE)
{
int16_t i;
int16_t x_end, y_start1, y_start2, y_end1, y_end2;
x_start = x_start / 8; //
x_end = x_start + PART_LINE / 8 - 1;
y_start1 = 0;
y_start2 = y_start;
if (y_start >= 256)
{
y_start1 = y_start2 / 256;
y_start2 = y_start2 % 256;
}
y_end1 = 0;
y_end2 = y_start + PART_COLUMN - 1;
if (y_end2 >= 256)
{
y_end1 = y_end2 / 256;
y_end2 = y_end2 % 256;
}
sendCmd(0x44); // set RAM x address start/end, in page 35
sendData(x_start); // RAM x address start at 00h;
sendData(x_end); // RAM x address end at 0fh(15+1)*8->128
sendCmd(0x45); // set RAM y address start/end, in page 35
sendData(y_start2); // RAM y address start at 0127h;
sendData(y_start1); // RAM y address start at 0127h;
sendData(y_end2); // RAM y address end at 00h;
sendData(y_end1); // ????=0
sendCmd(0x4E); // set RAM x address count to 0;
sendData(x_start);
sendCmd(0x4F); // set RAM y address count to 0X127;
sendData(y_start2);
sendData(y_start1);
sendCmd(0x24); //Write Black and White image to RAM
for (i = 0; i < PART_COLUMN * PART_LINE / 8; i++)
{
sendData(pgm_read_byte(&datas[i]));
}
partUpdate();
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef __LOLIN_IL3897_H
#define __LOLIN_IL3897_H
#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#else
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) ///< read bytes from program memory
#endif
#include "LOLIN_EPD.h"
/**************************************************************************/
/*!
@brief Class for interfacing with IL3897 EPD drivers
*/
/**************************************************************************/
class LOLIN_IL3897 : public LOLIN_EPD {
public:
LOLIN_IL3897(int width, int height, int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS, int8_t BUSY = -1);
LOLIN_IL3897(int width, int height, int8_t DC, int8_t RST, int8_t CS, int8_t BUSY = -1);
void begin(bool reset=true);
void drawPixel(int16_t x, int16_t y, uint16_t color);
void display();
void update();
void clearBuffer();
void clearDisplay();
void deepSleep();
void partBaseImg();
void partInit();
void partDisplay(int16_t x_start, int16_t y_start, const unsigned char *datas, int16_t PART_COLUMN, int16_t PART_LINE);
void partUpdate();
protected:
void readBusy();
void selectLUT(uint8_t * wave_data);
int _height_8bit;// height 8-bit alignment
};
#endif