update to 1.2.0 ver

This commit is contained in:
fsender
2023-11-03 18:48:56 +08:00
parent 26a041c3b9
commit 6fef19e3e0
29 changed files with 987 additions and 212 deletions

View File

@@ -75,26 +75,6 @@ void drvBase::SetLut(const unsigned char* lut) {
}
}
void drvBase::SetFrameWriter(std::function<uint8_t(int)> f,uint8_t _extra) {
guy_epdCmd(0x44);
guy_epdParam((0 >> 3) & 0xFF);
guy_epdParam(((epdWidth-1) >> 3) & 0xFF);
guy_epdCmd(0x45);
guy_epdParam(0 & 0xFF);
guy_epdParam((0 >> 8) & 0xFF);
guy_epdParam((epdHeight-1) & 0xFF);
guy_epdParam(((epdHeight-1) >> 8) & 0xFF);
guy_epdCmd(0x4e);
guy_epdParam((0 >> 3) & 0xFF);
guy_epdCmd(0x4f);
guy_epdParam(0 & 0xFF);
guy_epdParam((0 >> 8) & 0xFF);
guy_epdCmd(_extra);
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
guy_epdParam(f(i));
}
const PROGMEM unsigned char lut_slow[] =
{
/* 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22,
@@ -134,7 +114,7 @@ void drvBase::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新等
guy_epdBusy(100);
guy_epdCmd(0x24); /* will send the color data */
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
guy_epdParam(f(i));
SpiTransfer(f(i));
guy_epdCmd(0x22);
guy_epdParam(0xC4);
guy_epdCmd(0x20);
@@ -146,7 +126,7 @@ void drvBase::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新等
guy_epdBusy(90);
guy_epdCmd(0x26); /* will send the color data */
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
guy_epdParam(f(i));
SpiTransfer(f(i));
EndTransfer();
}
void drvBase::drv_sleep() { //开始屏幕睡眠

View File

@@ -55,7 +55,6 @@ protected:
int idleFastRf;
private:
int Init(const unsigned char* lut);
void SetFrameWriter(std::function<uint8_t(int)> f,uint8_t _extra);
const unsigned char* lut;
uint8_t iLut = 15;
uint8_t sleeping=1;

View File

@@ -121,31 +121,6 @@ void drvSSD168x::epd_init() {
SetLut();
}
void drvSSD168x::SetFrameWriter(std::function<uint8_t(int)> f) {
if(_part && epd_PowerOn){
//Reset();
SetLut();
guy_epdCmd(0x37);
for(int i=0;i<10;i++) guy_epdParam(i==5?0x40:0x00);
guy_epdCmd(0x3C); //BorderWavefrom
guy_epdParam(0x80);
guy_epdCmd(0x22);
guy_epdParam(0xC0);
guy_epdCmd(0x20);
guy_epdBusy(140);
}
else epd_init();
SetMemory();
guy_epdCmd(0x24);
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
guy_epdParam(f(i));
if(!_part){
guy_epdCmd(0x26);
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
guy_epdParam(f(i));
}
}
void drvSSD168x::DisplayFrame(void) {
guy_epdCmd(0x22);
guy_epdParam(_part?0x0f:0xc7);
@@ -198,7 +173,29 @@ void drvSSD168x::drv_fullpart(bool part){ //切换慢刷/快刷功能
}
void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
BeginTransfer();
SetFrameWriter(f);
if(_part && epd_PowerOn){
//Reset();
SetLut();
guy_epdCmd(0x37);
for(int i=0;i<10;i++) guy_epdParam(i==5?0x40:0x00);
guy_epdCmd(0x3C); //BorderWavefrom
guy_epdParam(0x80);
guy_epdCmd(0x22);
guy_epdParam(0xC0);
guy_epdCmd(0x20);
guy_epdBusy(140);
}
else epd_init();
SetMemory();
guy_epdCmd(0x24);
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
SpiTransfer(f(i));
if(!_part){
guy_epdCmd(0x26);
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
SpiTransfer(f(i));
}
DisplayFrame();
EndTransfer();
guy_epdBusy(_part?600:2300);
@@ -220,7 +217,7 @@ void drvSSD168x::drv_setDepth(uint8_t i){ //设置显示颜色深度, 不支持
else iLut=15;
}
void drvSSD168x::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
if(_quality) return readguyEpdBase::drv_draw16grey_step(f,step);
if(_quality&1) return readguyEpdBase::drv_draw16grey_step(f,step);
if(step==1){
drv_fullpart(1);
greyScaling=1;

View File

@@ -44,7 +44,7 @@ public:
void drv_sleep() ; //开始屏幕睡眠
int drv_width() const { return epdWidth; }; //返回显示区域宽度
int drv_height() const{ return epdHeight; }; //返回显示区域高度
int drv_supportGreyscaling() const { return _quality?16:-16; }
int drv_supportGreyscaling() const { return (_quality&1)?16:-16; }
void drv_setDepth(uint8_t i); //设置显示颜色深度, 不支持的话什么都不做
void drv_draw16grey_step(std::function<uint8_t(int)> f, int step);
protected:
@@ -61,10 +61,8 @@ private:
static const unsigned char VSH_table[32];
void epd_init();
void SetFrameWriter(std::function<uint8_t(int)> f);
void DisplayFrame(void);
void SetLut();
//void SetLut_by_host(const unsigned char *lut);
};
#ifdef READGUY_DEV_154B

View File

@@ -128,14 +128,14 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
// for (int k = 0; k < GUY_D_WIDTH/8; k++)
// guy_epdParam(f(j*(GUY_D_WIDTH/8)+k)); //按照给定的RAM写入数据
for (int i = 0; i < GUY_D_WIDTH/8*GUY_D_HEIGHT; i++)
guy_epdParam(f(i));
SpiTransfer(f(i));
}
guy_epdCmd(0x24);
//for (int j = GUY_D_HEIGHT-1; j >= 0; j--)
// for (int k = 0; k < GUY_D_WIDTH/8; k++)
// guy_epdParam(f(j*(GUY_D_WIDTH/8)+k)); //按照给定的RAM写入数据
for (int i = 0; i < GUY_D_WIDTH/8*GUY_D_HEIGHT; i++)
guy_epdParam(f(i));
SpiTransfer(f(i));
epd_Init();
guy_epdCmd(0x22);
guy_epdParam(epdFull?0xc4:0x04);

View File

@@ -163,7 +163,7 @@ void drv_base::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
//for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
// guy_epdParam(c);
for (int i = 0; i < epdHeight*epdWidth/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
SpiTransfer(f(i)); //按照给定的RAM写入数据
guy_epdCmd(0x92);
if(part_mode){
@@ -201,7 +201,7 @@ void drv_base::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
//send image data -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
//Total 5624 data written.
for (int i = 0; i < epdHeight*epdWidth/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
SpiTransfer(f(i)); //按照给定的RAM写入数据
guy_epdCmd(0x92);
EndTransfer();
//[EPDrg_BW<>] powerOff fx
@@ -224,7 +224,7 @@ void drv_base::drv_sleep() { //开始屏幕睡眠
}
void drv_base::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
if(_quality) return readguyEpdBase::drv_draw16grey_step(f,step);
if(_quality&1) return readguyEpdBase::drv_draw16grey_step(f,step);
if(step==1){
greyHQ=3;
drv_setDepth(3);

View File

@@ -44,7 +44,7 @@ public:
int drv_width() const { return epdWidth; }; //返回显示区域宽度
int drv_height() const{ return epdHeight; }; //返回显示区域高度
void drv_setDepth(uint8_t i); //设置显示颜色深度
int drv_supportGreyscaling() const { return _quality?16:-16; }
int drv_supportGreyscaling() const { return (_quality&1)?16:-16; }
void drv_draw16grey_step(std::function<uint8_t(int)> f, int step);
protected:
int epdWidth;

View File

@@ -31,7 +31,7 @@
#include "guy_370a.h"
#ifdef READGUY_DEV_370A
namespace guydev_370A{
static const PROGMEM unsigned char lut_1Gray_GC[] ={
static const PROGMEM unsigned char lut_1Grey_GC[] ={
0x2A,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//1
0x05,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//2
0x2A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//3
@@ -39,7 +39,7 @@ static const PROGMEM unsigned char lut_1Gray_GC[] ={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//5
0x00,0x02,0x03,0x0A,0x00,0x02,0x06,0x0A,0x05,0x00
};
static const PROGMEM unsigned char lut_1Gray_A2[] ={
static const PROGMEM unsigned char lut_1Grey_A2[] ={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //1
0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //2
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //3
@@ -88,12 +88,12 @@ void drv::Load_LUT(unsigned char mode) {
guy_epdCmd(0x32);
for (i = 0; i < 60; i++) {
if(mode == 1)
guy_epdParam(pgm_read_byte(lut_1Gray_GC+i));
guy_epdParam(pgm_read_byte(lut_1Grey_GC+i));
else if(mode == 0){
if(20==i && greyScaling<8) guy_epdParam(0x03);
else if(53==i && greyScaling<3) guy_epdParam(greyScaling);
else if(53==i && greyScaling==15) guy_epdParam(5);
else guy_epdParam(pgm_read_byte(lut_1Gray_A2+i));
else guy_epdParam(pgm_read_byte(lut_1Grey_A2+i));
}
}
for (i = 0; i < 45; i++) {
@@ -124,11 +124,11 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
guy_epdCmd(0x24);
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
SpiTransfer(f(i)); //按照给定的RAM写入数据
if(!part_mode) {
guy_epdCmd(0x26);
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
SpiTransfer(f(i)); //按照给定的RAM写入数据
}
Load_LUT(!part_mode);

View File

@@ -100,6 +100,7 @@ const PROGMEM unsigned char drv::lut_213_B72_16grey[]={
void drv::epd_Init(void){
const uint16_t GreyDrvFrameFreq[]={
0x1108, /* 75Hz */
0x1108, /* 75Hz */
0x180c, /* 35Hz */
0x2c0a, /* 50Hz */
@@ -115,7 +116,6 @@ void drv::epd_Init(void){
0x1804, /* 140Hz */
0x0d04, /* 145Hz */
0x0304, /* 150Hz */
//0x0304, /* 150Hz */
};
//_InitDisplay fx
if(epdFull==2) {
@@ -203,11 +203,11 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
if(epdFull){ //慢刷
guy_epdCmd(0x26);
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
SpiTransfer(f(i)); //按照给定的RAM写入数据
}
guy_epdCmd(0x24);
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
SpiTransfer(f(i)); //按照给定的RAM写入数据
if(epdFull){ //慢刷
epd_Init();
SetMemory();
@@ -232,12 +232,12 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
SetMemory();
guy_epdCmd(0x26);
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
SpiTransfer(f(i)); //按照给定的RAM写入数据
EndTransfer();
if(epdFull) power_down();
}
void drv::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
if(_quality) return readguyEpdBase::drv_draw16grey_step(f,step);
if(_quality&1) return readguyEpdBase::drv_draw16grey_step(f,step);
if(step==1) drv_fullpart(1);//初始阶段,完成准备工作 //设置为快刷模式
GreyScalingHighQuality=step; //开启高品质灰度模式
drv_dispWriter(f);

View File

@@ -47,7 +47,7 @@ public:
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
void drv_setDepth(uint8_t i) { epdFull=0; GreyScaling = i>15?15:i; if(!i) GreyScaling=15;}
void drv_draw16grey_step(std::function<uint8_t(int)> f, int step);
int drv_supportGreyscaling() const { return _quality?16:-16; }
int drv_supportGreyscaling() const { return (_quality&1)?16:-16; }
private:
//void Lut(unsigned char* lut);
void epd_Init(void);

View File

@@ -138,15 +138,15 @@ const PROGMEM unsigned char drv::lutFast_w_w[] ={ 0x02,2,0,48,0,1 };
const PROGMEM unsigned char drv::lutFast_b_w[] ={ 0x5a,2,0,63,0,1 };
const PROGMEM unsigned char drv::lutFast_w_b[] ={ 0x84,2,0,48,0,1 };
const PROGMEM unsigned char drv::lutFast_b_b[] ={ 0x01,2,0,48,0,1 };
void drv::epd_display(){
//void drv::epd_display(){
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
BeginTransfer();
Init(part_mode);
if(part_mode){
sendArea();
guy_epdCmd(0x13);
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++){
send(i); //guy_epdParam(d[i]);
}
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
SpiTransfer(f(i));
//data
guy_epdCmd(0x92);
sendAreaRaw();
@@ -155,14 +155,12 @@ void drv::epd_display(){
else{
guy_epdCmd(0x10);
//刷新数据
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++){
send(i); //guy_epdParam(d[i]);
}
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
SpiTransfer(f(i));
guy_epdCmd(0x13);
//刷新数据
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++){
send(i); //guy_epdParam(d[i]);
}
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
SpiTransfer(f(i));
guy_epdCmd(0x92);
//[EPDrg_BW<>] refresh fx
guy_epdCmd(0x00);
@@ -179,9 +177,8 @@ void drv::epd_display(){
if(part_mode){
sendArea();
guy_epdCmd(0x13);
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++){
send(i); //guy_epdParam(d[i]);
}
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
SpiTransfer(f(i));
guy_epdCmd(0x92);
EndTransfer();
}
@@ -189,9 +186,8 @@ void drv::epd_display(){
Init(2);
sendArea();
guy_epdCmd(0x13);
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++){
send(i); //guy_epdParam(d[i]);
}
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
SpiTransfer(f(i));
guy_epdCmd(0x92);
guy_epdCmd(0x02);
EndTransfer();
@@ -212,10 +208,6 @@ void drv::drv_fullpart(bool part){ //切换慢刷/快刷功能
part_mode = part;
//Init(part);
}
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
send = [&](int i){ guy_epdParam(f(i)); };
epd_display();
}
void drv::drv_sleep() { //开始屏幕睡眠
if(RST_PIN>=0){ //未定义RST_PIN时无法唤醒
BeginTransfer();

View File

@@ -79,9 +79,6 @@ private:
void SendLuts(uint8_t lutOption); //0:慢刷, 1:快刷, 2:四阶灰度
uint8_t customLut, customGreyscale; //customLut 是灰度刷新时的自定义lut
void epd_display();
//void (*send)(int);
std::function<void(int)> send; //此处不能用 void (*send)(int); 是因为lambda函数是std的
static const PROGMEM uint8_t greyTable[16];
};
}

View File

@@ -29,27 +29,19 @@
#include "guy_epdbase.h"
#include <spi.h>
#pragma GCC optimize ("O3")
readguyEpdBase::readguyEpdBase() {
};
readguyEpdBase::~readguyEpdBase() {
};
void readguyEpdBase::DigitalWrite(int pin, int value) {
if(pin>=0) digitalWrite(pin, value);
}
int readguyEpdBase::DigitalRead(int pin) {
return (pin>=0)?digitalRead(pin):1;
}
void readguyEpdBase::DelayMs(unsigned int delaytime) {
delay(delaytime);
}
void readguyEpdBase::BeginTransfer(){
if(!in_trans && CS_PIN>=0) {
digitalWrite(CS_PIN, LOW);
DigitalWrite(CS_PIN, LOW);
if(spi_tr_press!=nullptr) spi_tr_press();
}
in_trans++;
@@ -57,11 +49,11 @@ void readguyEpdBase::BeginTransfer(){
void readguyEpdBase::EndTransfer(){
if(in_trans) in_trans--;
if(!in_trans && CS_PIN>=0) {
digitalWrite(CS_PIN, HIGH);
DigitalWrite(CS_PIN, HIGH);
if(spi_tr_release!=nullptr) spi_tr_release();
}
}
void readguyEpdBase::SpiTransfer(unsigned char data) {
/*IRAM_ATTR void readguyEpdBase::SpiTransfer(unsigned char data) {
if(in_trans) {
_spi->transfer(data);
return;
@@ -69,7 +61,7 @@ void readguyEpdBase::SpiTransfer(unsigned char data) {
if(CS_PIN>=0) digitalWrite(CS_PIN, LOW);
_spi->transfer(data);
if(CS_PIN>=0) digitalWrite(CS_PIN, HIGH);
}
}*/
int readguyEpdBase::IfInit(SPIClass &c,int8_t cs,int8_t dc,int8_t rst,int8_t busy) {
//static uint8_t IfHadInit=0;
//if(IfHadInit) return;
@@ -165,7 +157,7 @@ void readguyEpdBase::Reset(uint32_t minTime)
}
//void readguyEpdBase::drv_draw16grey(const uint8_t *d16bit){ //不支持的话什么都不做
void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y){
void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,int o){
#ifndef FLOYD_STEINBERG_DITHERING
static const uint8_t bayer_tab [64]={
0, 32, 8, 40, 2, 34, 10, 42,
@@ -180,20 +172,21 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
#endif
const uint32_t w = (spr.width()+7)>>3;
if((!w) || (!spr.height())) return;
uint16_t *readBuff = new uint16_t[spr.width()];
uint8_t *writeBuff = new uint8_t[w];
if(o==0 || o==1){
readBuff = new uint16_t[spr.width()];
#ifdef FLOYD_STEINBERG_DITHERING
int16_t *floyd_tab[2];
floyd_tab[0] = new int16_t [spr.width()];
floyd_tab[1] = new int16_t [spr.width()];
for(int j=0;j<spr.width();j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
#endif
floyd_tab[0] = new int16_t [spr.width()];
floyd_tab[1] = new int16_t [spr.width()];
for(int j=0;j<spr.width();j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
#endif
writeBuff = new uint8_t[w];
}
sprbase.fillRect(x,y,spr.width(),spr.height(),1);
for(int32_t i=0;i<(int32_t)spr.height();i++){
spr.readRect(0,i,spr.width(),1,readBuff);
for(int32_t i=y;i<(int32_t)spr.height()+y;i++){
spr.readRect(0,i-y,spr.width(),1,readBuff);
#ifdef FLOYD_STEINBERG_DITHERING
uint_fast8_t buff8bit=0;
for(int32_t j=0;j<(int32_t)spr.width();j++){
for(int32_t j=0;j<spr.width();j++){
int32_t flodelta = floyd_tab[i&1][j]+(int32_t)((greysc(readBuff[j])<<8)|greysc(readBuff[j]));
if(flodelta>=0x8000) {
//spr.drawPixel(j,i,1);
@@ -212,11 +205,11 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
}
if(j) { floyd_tab[!(i&1)][j-1] += (flodelta*3)>>4; }
{ floyd_tab[!(i&1)][j ] += (flodelta*5)>>4; }*/
if(j!=(int32_t)spr.width()-1)
if(j!=spr.width()-1)
{ floyd_tab[i&1] [j+1] += (flodelta*7)>>4; }
if(j) { floyd_tab[!(i&1)][j-1] += (flodelta*3)>>4; }
{ floyd_tab[!(i&1)][j ] += (flodelta*5)>>4; }
if(j!=(int32_t)spr.width()-1)
if(j!=spr.width()-1)
{ floyd_tab[!(i&1)][j+1] += (flodelta )>>4; }
}
for(int floi=0;floi<spr.width();floi++) floyd_tab[i&1][floi]=0;
@@ -228,81 +221,94 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
writeBuff[j]=buff8bit;
}
#endif
sprbase.drawBitmap(x,y+i,writeBuff,spr.width(),1,1,0);
sprbase.drawBitmap(x,i,writeBuff,spr.width(),1,1,0);
}
_display((const uint8_t*)sprbase.getBuffer());
delete []readBuff;
delete []writeBuff;
//_display((const uint8_t*)sprbase.getBuffer()); //显示
if(o==0 || o==3){
delete []readBuff;
delete []writeBuff;
#ifdef FLOYD_STEINBERG_DITHERING
delete [] floyd_tab[0] ;
delete [] floyd_tab[1] ;
delete [] floyd_tab[0] ;
delete [] floyd_tab[1] ;
#endif
}
}
//不支持的话使用单色抖动刷屏
void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y){
//Serial.println("drv_draw16grey fx");
const uint32_t w = (spr.width()+7)>>3;
if((!w) || (!spr.height())) return;
uint16_t *readBuff = new uint16_t[spr.width()];
uint8_t *writeBuff = new uint8_t[w];
readBuff = new uint16_t[spr.width()];
if(_quality&2){
#ifdef FLOYD_DITHERING_16GREY
int16_t *floyd_tab[2];
floyd_tab[0] = new int16_t [spr.width()];
floyd_tab[1] = new int16_t [spr.width()];
floyd_tab[0] = new int16_t [spr.width()];
floyd_tab[1] = new int16_t [spr.width()];
#endif
}
writeBuff = new uint8_t[w];
sprbase.fillRect(x,y,spr.width(),spr.height(),1);
bool negativeOrder=(drv_supportGreyscaling()==-16);
drv_fullpart(0);
_display((const uint8_t*)sprbase.getBuffer()); //先对区域慢刷白屏确保颜色正确
//_display((const uint8_t*)sprbase.getBuffer()); //先对区域慢刷白屏确保颜色正确
drv_dispWriter(FILL_WHITE);
drv_fullpart(1);
for(uint_fast8_t k=1;k<16;k++){ //亮度为15的不用绘制,因为本来就是白色
#ifdef FLOYD_DITHERING_16GREY
for(int j=0;j<spr.width();j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
if(_quality&2) for(int j=0;j<spr.width();j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
#endif
for(int i=0;i<spr.height();i++){
spr.readRect(0,i,spr.width(),1,readBuff);
for(uint32_t j=0;j<w;j++){
uint_fast8_t buff8bit=0;
for(uint_fast8_t b=0;b<8;b++){
for(int i=y;i<spr.height()+y;i++){
uint_fast8_t buff8bit=0;
spr.readRect(0,i-y,spr.width(),1,readBuff);
for(int32_t j=0;j<spr.width();j++){
//for(uint_fast8_t b=0;b<8;b++){
#ifdef FLOYD_DITHERING_16GREY
uint_fast8_t cg=0;
int32_t fd = floyd_tab[i&1][(j<<3)+b]+(int32_t)((greysc(readBuff[(j<<3)+b])<<8)|greysc(readBuff[(j<<3)+b]));
uint_fast8_t cg=0;
if(_quality&2){
int gv=greysc(readBuff[j]);
int32_t fd = floyd_tab[i&1][j]+((gv<<8)|gv);
while(fd>=0x800) {
cg++;
if(fd>=0) fd -= 0x1000;
}
if(fd<0) fd++;
if((j<<3)+b!=(uint32_t)spr.width()-1)
{ floyd_tab[i&1] [(j<<3)+b+1] += (fd*7)>>4; }
if((j<<3)+b) { floyd_tab[!(i&1)][(j<<3)+b-1] += (fd*3)>>4; }
{ floyd_tab[!(i&1)][(j<<3)+b ] += (fd*5)>>4; }
if((j<<3)+b!=(uint32_t)spr.width()-1)
{ floyd_tab[!(i&1)][(j<<3)+b+1] += (fd )>>4; }
if(j!=spr.width()-1)
{ floyd_tab[i&1] [j+1] += (fd*7)>>4; }
if(j) { floyd_tab[!(i&1)][j-1] += (fd*3)>>4; }
{ floyd_tab[!(i&1)][j ] += (fd*5)>>4; }
if(j!=spr.width()-1)
{ floyd_tab[!(i&1)][j+1] += (fd )>>4; }
}
else{ cg=greysc(readBuff[j])>>4; }
#else
uint_fast8_t cg=greysc(readBuff[(j<<3)+b])>>4;
uint_fast8_t cg=greysc(readBuff[j])>>4;
#endif
if(negativeOrder)
buff8bit |= (cg<k)<<((~b)&7);
buff8bit |= (cg<k)<<((~j)&7);
else{
if(cg==15) continue; //白色不考虑
buff8bit |= (cg>=((~k)&15))<<((~b)&7);
if(cg<15) //白色不考虑
buff8bit |= (cg>=((~k)&15))<<((~j)&7);
}
}
//sprbase.drawPixel(x+j,y+i,(greysc(readBuff[j])/16)==(15-k));
writeBuff[j]=buff8bit^0xff;
if((j&7)==7 || j==((int32_t)spr.width()-1)){
writeBuff[j>>3]=buff8bit^0xff;
buff8bit=0;
}
//}
//sprbase.drawPixel(x+j,i,(greysc(readBuff[j])/16)==(15-k));
}
#ifdef FLOYD_DITHERING_16GREY
for(int floi=0;floi<spr.width();floi++) floyd_tab[i&1][floi]=0;
if(_quality&2) for(int floi=0;floi<spr.width();floi++) floyd_tab[i&1][floi]=0;
#endif
sprbase.drawBitmap(x,y+i,writeBuff,spr.width(),1,1,0);
sprbase.drawBitmap(x,i,writeBuff,spr.width(),1,1,0);
}
drv_draw16grey_step((const uint8_t*)sprbase.getBuffer(),k); //使用灰度显示函数
}
delete []readBuff;
delete []writeBuff;
if(_quality&2){
#ifdef FLOYD_DITHERING_16GREY
delete [] floyd_tab[0] ;
delete [] floyd_tab[1] ;
delete [] floyd_tab[0] ;
delete [] floyd_tab[1] ;
#endif
}
} /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */

View File

@@ -38,6 +38,8 @@
#include "guy_epaper_config.h"
#define EPD_DRIVERS_NUM_MAX 12 //此选项请不要取消注释掉
#define FILL_WHITE ([](int)->uint8_t{return 0xff;})
#define FILL_BLACK ([](int)->uint8_t{return 0x00;})
class readguyEpdBase {
protected:
SPIClass *_spi;
@@ -47,24 +49,32 @@ protected:
int8_t CS_PIN ;
int8_t BUSY_PIN;
uint8_t in_trans=0;
uint8_t _quality=0; //灰度显示品质 0(默认)-高品质 1-低品质 部分屏幕支持高品质的连续刷灰度.
uint8_t _quality=2; //灰度显示品质 0(默认)-高品质 1-低品质 部分屏幕支持高品质的连续刷灰度.
#ifdef MEPD_DEBUG_WAVE
uint16_t dat_combo = 0; //dc引脚状态 0 command, 1 data
#endif
uint16_t *readBuff;// = new uint16_t[spr.width()];
uint8_t *writeBuff;// = new uint8_t[w];
#if (defined(FLOYD_DITHERING_16GREY) || defined(FLOYD_STEINBERG_DITHERING))
int16_t *floyd_tab[2];
#endif
public:
readguyEpdBase(void);
virtual ~readguyEpdBase(void);
int IfInit(SPIClass &c,int8_t cs,int8_t dc,int8_t rst,int8_t busy);
void DigitalWrite(int pin, int value);
int DigitalRead(int pin);
IRAM_ATTR void DigitalWrite(int pin, int value) { if(pin>=0) digitalWrite(pin, value); }
IRAM_ATTR int DigitalRead(int pin) { return (pin>=0)?digitalRead(pin):1; }
void DelayMs(unsigned int delaytime);
void BeginTransfer();
void EndTransfer();
void SpiTransfer(unsigned char data);
void SpiTransfer(unsigned char data){
if(in_trans)
_spi->transfer(data);
}
//basic I/O operation
void guy_epdCmd(unsigned char command);
void guy_epdParam(unsigned char data);
void guy_epdParam(unsigned char data); //发送数据, 注意此方式速度会比较慢 大量数据发送请直接用SpiTransfer()
void guy_epdBusy(int32_t maxt);
void Reset(uint32_t minTime = 20);
void SetMemory(); //集成了0x44 0x45 0x4e 0x4f指令的函数. 此函数用于设置墨水屏内存写入方式
@@ -86,8 +96,8 @@ public:
* @param gamma_on 是否对灰度值进行gamma校正(速度慢)
* @return uint32_t 颜色的灰度值
*/
static int greysc(int c){return(((c>>3)&0x1F)*79+(((c<<3)+(c>>13))&0x3F)*76+((c>>8)&0x1F)*30)>>5;}
void drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y); //分步完成灰度刷新
IRAM_ATTR static int greysc(int c){return(((c>>3)&0x1F)*79+(((c<<3)+(c>>13))&0x3F)*76+((c>>8)&0x1F)*30)>>5;}
void drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,int o=0); //分步完成灰度刷新
void drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y);//省内存方式
void drv_draw16grey_step(const uint8_t *buf, int step){ //分步完成灰度刷新
drv_draw16grey_step([&](int n)->uint8_t{return buf[n];},step);
@@ -96,9 +106,10 @@ public:
drv_setDepth(step);
drv_dispWriter(f);
}
void setGreyQuality(bool q) { _quality=!q; } //设置灰度的渲染画质. 高画质模式在某些屏幕某些情况下可能表现不好.
void setGreyQuality(uint8_t q){_quality=q^3;} //设置灰度的渲染画质. 高画质模式在某些屏幕某些情况下可能表现不好.
void (*spi_tr_release)(void);
void (*spi_tr_press)(void);
friend class ReadguyDriver;
#ifdef MEPD_DEBUG_DISPLAY
friend class LGFX;
#endif

View File

@@ -73,9 +73,11 @@
//#define _DEFINA_SD_CS_PIN 0
// * for NodeMcu ctg stack LCF board
#define WHITE_GAP 8
#ifdef ESP8266
#define DISPLAY_TYPE_ST7789_240320 //2.0寸的ST7789 IPS TFT模块
#define _DEFINA_IPS_CS_PIN 15
#define _DEFINA_IPS_CS_PIN 15 //lcdDebug是不支持自定义引脚的
#define _DEFINA_IPS_DC_PIN 5
#define _DEFINA_IPS_RST_PIN -1

View File

@@ -54,12 +54,15 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
}
for(int j=0;j<drv_height();j++){
for(int i=0;i<xbits;i++){
if(f(j*xbits+i) == 0xff && i!=xbits-1)
uint_fast8_t readf=f(j*xbits+i);
if(readf == 0xff && i!=xbits-1)
ips.drawFastHLine(WHITE_GAP+i*8,WHITE_GAP+j,8,0xffff);
else {
int lineOK=0;
ips.readRect(WHITE_GAP+i*8,WHITE_GAP+j,8,1,dat); //注意这里 readrect函数已经自动化实现边界处理了
if(f(j*xbits+i) == 0x00 && i!=xbits-1){
if(partMode)//注意这里 readrect函数已经自动化实现边界处理了
ips.readRect(WHITE_GAP+i*8,WHITE_GAP+j,8,1,dat);
else memset(dat,0xff,sizeof(dat));
if(readf == 0x00 && i!=xbits-1){
for(int k=0;k<8;k++)
if((dat[k]&0x1f)==0x1f) lineOK++;
if(lineOK==8) {
@@ -69,7 +72,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
}
for(int k=0;k<8;k++){
if(i==xbits-1 && i*8+k>=drv_width()) break;
if((f(j*xbits+i)&(0x80>>k)))
if((readf&(0x80>>k)))
ips.drawPixel(WHITE_GAP+i*8+k,WHITE_GAP+j,0xffff);
else if((dat[k]&0x1f)==0x1f)
ips.drawPixel(WHITE_GAP+i*8+k,WHITE_GAP+j,0x1082*(15-depth));

View File

@@ -34,7 +34,6 @@
#ifdef MEPD_DEBUG_DISPLAY
#include "ctg_stack_c_defines.h"
#define WHITE_GAP 4
namespace EpdLcdDebug{
class drv : public readguyEpdBase {

View File

@@ -29,6 +29,7 @@
#include "readguy.h"
#ifdef READGUY_ESP_ENABLE_WIFI
static const PROGMEM char NOT_SUPPORTED[] = "(不支持此屏幕)";
static const PROGMEM char TEXT_HTML[] = "text/html";
static const PROGMEM char TEXT_PLAIN [] = "text/plain";
@@ -111,7 +112,6 @@ const char *ReadguyDriver::epd_drivers_list[EPD_DRIVERS_NUM_MAX]={
NAME_guyDev420WF,
NAME_epdLcd
};
#ifdef READGUY_ESP_ENABLE_WIFI
//static const char *index_cn_html;
//static const uint8_t faviconData[1150];

View File

@@ -172,18 +172,23 @@ uint8_t ReadguyDriver::checkEpdDriver(){
Serial.println(F("IfInit OK"));
return READGUY_epd_type;
}
void ReadguyDriver::setEpdDriver(){
void ReadguyDriver::setEpdDriver(int g_width,int g_height){
guy_dev->spi_tr_release = in_release;
guy_dev->spi_tr_press = in_press;
guy_dev->drv_init(); //初始化epd驱动层
if(g_width) guy_width = g_width;
else guy_width = guy_dev->drv_width(); //宽度必须是8的倍数, 但这个可以由GFX自动计算
if(g_height) guy_height = g_height;
else guy_height = guy_dev->drv_height();
Serial.println(F("EPD init OK"));
//以下依赖于你的图形驱动
setColorDepth(1); //单色模式
createPalette(); //初始化颜色系统
Serial.printf_P(PSTR("mono set: w: %d, h: %d\n"),guy_dev->drv_width(),guy_dev->drv_height());
Serial.printf_P(PSTR("mono set: w: %d, h: %d\n"),guy_width,guy_height);
//创建画布. 根据LovyanGFX的特性, 如果以前有画布会自动重新生成新画布
//此外, 即使画布宽度不是8的倍数(如2.13寸单色),也支持自动补全8的倍数 ( 250x122 => 250x128 )
createSprite(guy_dev->drv_width(),guy_dev->drv_height());
//为了保证图片显示功能的正常使用, 高度也必须是8的倍数.
createSprite(guy_width,(guy_height+7)&0x7ffffff8);
//setRotation(1); //旋转之后操作更方便
setRotation(0);
setFont(&fonts::Font0);
@@ -209,7 +214,6 @@ bool ReadguyDriver::setSDcardDriver(){
READGUY_sd_ok = SDFS.begin();
#else
if(sd_spi == nullptr) {
//sd_spi = new SPIClass(HSPI);
#if (defined(CONFIG_IDF_TARGET_ESP32))
sd_spi = new SPIClass(VSPI);
#else
@@ -386,6 +390,10 @@ void ReadguyDriver::display(std::function<uint8_t(int)> f, bool part){
void ReadguyDriver::drawImage(LGFX_Sprite &spr,uint16_t x,uint16_t y) {
if(READGUY_cali==127) guy_dev->drv_drawImage(*this, spr, x, y);
}
void ReadguyDriver::drawImageStage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint8_t stage,uint8_t totalstage) {
if(READGUY_cali!=127 || stage>=totalstage) return;
guy_dev->drv_drawImage(*this, spr, x, y, (totalstage<=1)?0:(stage==0?1:(stage==(totalstage-1)?3:2)));
}
void ReadguyDriver::setDepth(uint8_t d){
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling()) guy_dev->drv_setDepth(d);
}
@@ -396,16 +404,20 @@ void ReadguyDriver::draw16grey(LGFX_Sprite &spr,uint16_t x,uint16_t y){
guy_dev->drv_drawImage(*this, spr, x, y);
}
void ReadguyDriver::draw16greyStep(int step){
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling())
return guy_dev->drv_draw16grey_step((const uint8_t *)this->getBuffer(),step);
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling() && step>0 && step<16 ){
if(step==1) guy_dev->drv_fullpart(1);
guy_dev->drv_draw16grey_step((const uint8_t *)this->getBuffer(),step);
}
}
void ReadguyDriver::draw16greyStep(std::function<uint8_t(int)> f, int step){
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling())
return guy_dev->drv_draw16grey_step(f,step);
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling() && step>0 && step<16 ){
if(step==1) guy_dev->drv_fullpart(1);
guy_dev->drv_draw16grey_step(f,step);
}
}
void ReadguyDriver::invertDisplay(){
if(READGUY_cali==127){
const int pixels=((guy_dev->drv_width()+7)>>3)*guy_dev->drv_height();
const int pixels=((guy_width+7)>>3)*guy_height;
for(int i=0;i<pixels;i++)
((uint8_t*)(getBuffer()))[i]=uint8_t(~(((uint8_t*)(getBuffer()))[i]));
}

View File

@@ -178,12 +178,15 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
/** @brief 返回目标屏幕是否支持16级灰度 返回非0代表支持.
* @note 返回负整数则代表调用draw16greyStep需要从深色到浅色刷新, 而不是从浅色到深色刷新 */
int supportGreyscaling() const{return READGUY_cali==127?guy_dev->drv_supportGreyscaling():0;}
/// @brief 设置灰度的渲染画质. 高画质模式在某些屏幕某些情况下可能表现不好.
void setGreyQuality(bool q) { if(READGUY_cali==127) guy_dev->setGreyQuality(q); }
/** @brief 设置灰度的渲染画质. 高画质模式在某些屏幕某些情况下可能表现不好.
* @param q 0-关闭连续刷屏 开启16阶灰度抖动 1-开启连续刷屏 开启16阶灰度抖动
* 2-关闭连续刷屏 关闭16阶灰度抖动 3-开启连续刷屏 关闭16阶灰度抖动 */
void setGreyQuality(uint8_t q) { if(READGUY_cali==127) guy_dev->setGreyQuality(q); }
/// @brief 显示灰度图片,如果支持,否则就不显示灰度图片了. 可以用省内存的方法显示
void draw16grey(LGFX_Sprite &spr,uint16_t x,uint16_t y);
/** @brief 按照自定义分步显示灰度图片,如果支持,否则就不显示灰度图片了. 可以用省内存的方法显示
* @param step 步骤代号. 从1开始到15,依次调用此函数来自定义的灰度显示显存内容. 没有16.
* @param step 步骤代号. 从1开始到15,依次调用此函数来自定义的灰度显示显存内容. 没有0和16.
* @note 必须按照 "慢刷全屏->绘图->设置参数1->绘图->设置参数2... 调用15次 来完成一次自定义灰度刷屏
* 连续调用多次此函数之间, 可以修改显存内的像素颜色, 但只能从白色改为黑色.
* @attention 需要先调用 supportGreyscaling() 来确定是否支持灰度分步刷新.为负数时需要从深到浅刷新
@@ -219,8 +222,10 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
#endif
/// @brief 检查初始化屏幕硬件, 若检查失败返回0,否则返回硬件代号
uint8_t checkEpdDriver();
/// @brief 初始化屏幕, 设置驱动代号, 引脚排列顺序. 过程会检验引脚可用性.
void setEpdDriver();
/** @brief 初始化屏幕, 设置驱动代号, 引脚排列顺序. 过程会检验引脚可用性.
* @param g_width, g_height 显示区域的宽度和高度. 为0表示直接使用屏幕的宽度和高度
* @note 这两个参数转专为指定分辨率的程序画面设计, 其他分辨率的画面会自动拉伸. [1.2新增] */
void setEpdDriver(int g_width = 0,int g_height = 0);
/** @brief 初始化SD卡, 设置驱动代号, 引脚排列顺序. 过程会检验引脚可用性.
* @return SD卡初始化成功与否 */
bool setSDcardDriver();
@@ -256,6 +261,7 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
#endif
int epd_OK=0; //墨水屏可用
int currentBright = -3; //初始亮度
int16_t guy_width=0,guy_height=0;
//LGFX_Sprite gfx; // 图形引擎类指针, 可以用这个指针去操作屏幕缓冲区
readguyEpdBase *guy_dev = nullptr;
@@ -331,30 +337,39 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
#endif
}
public: //增加了一些返回系统状态变量的函数, 它们是静态的, 而且不会对程序造成任何影响.
constexpr int getReadguyShareSpi() const { return config_data[1]; }
constexpr int getReadguyEpdType () const { return config_data[2]; } // 对应的epd驱动程序代号, -1为未指定
constexpr int getShareSpi() const { return config_data[1]; }
constexpr int getEpdType () const { return config_data[2]; } // 对应的epd驱动程序代号, -1为未指定
//显示驱动部分, 显示默认使用vspi (vspi也是默认SPI库的通道)
constexpr int getReadguyEpdMosi () const { return config_data[3]; } // 目标显示器的 MOSI 引脚
constexpr int getReadguyEpdSclk () const { return config_data[4]; } // 目标显示器的 SCLK 引脚
constexpr int getReadguyEpdCs () const { return config_data[5]; } // 目标显示器的 CS 引脚
constexpr int getReadguyEpdDc () const { return config_data[6]; } // 目标显示器的 DC 引脚
constexpr int getReadguyEpdRst () const { return config_data[7]; } // 目标显示器的 RST 引脚
constexpr int getReadguyEpdBusy () const { return config_data[8]; } // 目标显示器的 BUSY 引脚
constexpr int getEpdMosi () const { return config_data[3]; } // 目标显示器的 MOSI 引脚
constexpr int getEpdSclk () const { return config_data[4]; } // 目标显示器的 SCLK 引脚
constexpr int getEpdCs () const { return config_data[5]; } // 目标显示器的 CS 引脚
constexpr int getEpdDc () const { return config_data[6]; } // 目标显示器的 DC 引脚
constexpr int getEpdRst () const { return config_data[7]; } // 目标显示器的 RST 引脚
constexpr int getEpdBusy () const { return config_data[8]; } // 目标显示器的 BUSY 引脚
//sd卡驱动部分, 默认使用hspi (sd卡建议用hspi)
constexpr int getReadguySdMiso () const { return config_data[9]; } // 目标sd卡的 MISO 引脚, sd_share_spi == 1 时无效
constexpr int getReadguySdMosi () const { return config_data[10]; }// 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
constexpr int getReadguySdSclk () const { return config_data[11]; }// 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
constexpr int getReadguySdCs () const { return config_data[12]; }// 目标sd卡的 CS 引脚.
constexpr int getReadguyI2cSda () const { return config_data[13]; }// 目标i2c总线的SDA引脚, 当且仅当启用i2c总线时才生效
constexpr int getReadguyI2cScl () const { return config_data[14]; }// 目标i2c总线的SCL引脚, 当且仅当启用i2c总线时才生效
constexpr int getSdMiso () const { return config_data[9]; } // 目标sd卡的 MISO 引脚, sd_share_spi == 1 时无效
constexpr int getSdMosi () const { return config_data[10]; }// 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
constexpr int getSdSclk () const { return config_data[11]; }// 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
constexpr int getSdCs () const { return config_data[12]; }// 目标sd卡的 CS 引脚.
constexpr int getI2cSda () const { return config_data[13]; }// 目标i2c总线的SDA引脚, 当且仅当启用i2c总线时才生效
constexpr int getI2cScl () const { return config_data[14]; }// 目标i2c总线的SCL引脚, 当且仅当启用i2c总线时才生效
//按键驱动部分, 为负代表高触发, 否则低触发,
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
constexpr int getReadguyBtn1Pin () const { return config_data[15]; }
constexpr int getReadguyBtn2Pin () const { return config_data[16]; }
constexpr int getReadguyBtn3Pin () const { return config_data[17]; }
constexpr int getReadguyBlPin () const { return config_data[18]; }//前置光接口引脚IO
constexpr int getReadguyRtcType () const { return config_data[19]; }//使用的RTC型号(待定, 还没用上)
constexpr int getButtonsCount () const { return config_data[21]; } //按钮个数, 0-3都有可能
constexpr int getBtn1Pin () const { return config_data[15]; }
constexpr int getBtn2Pin () const { return config_data[16]; }
constexpr int getBtn3Pin () const { return config_data[17]; }
constexpr int getBlPin () const { return config_data[18]; } //前置光接口引脚IO
constexpr int getRtcType () const { return config_data[19]; } //使用的RTC型号(待定, 还没用上)
constexpr int getButtonsCount() const { return config_data[21]; } //按钮个数, 0-3都有可能
constexpr int memWidth () const { return guy_width ; } //返回显存宽度(不是画幅宽度),不会随着画布旋转改变
constexpr int memHeight () const { return guy_height ; } //返回显存高度(不是画幅高度),不会随着画布旋转改变
int drvWidth () const { return READGUY_cali==127?guy_dev->drv_width():0; } //返回显示屏硬件宽度(不是画幅宽度)
int drvHeight() const { return READGUY_cali==127?guy_dev->drv_height():0; } //返回显示屏硬件高度(不是画幅高度)
// private:
void implBeginTransfer() { guy_dev->BeginTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
void implEndTransfer() { guy_dev->EndTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
/// @brief 分阶段显示图片, 使用抖动算法. 更加的省内存.目前函数
void drawImageStage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint8_t stage,uint8_t totalstage);
};
#endif /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */