mirror of
https://github.com/fsender/readguy.git
synced 2025-12-15 14:18:13 +08:00
update to 1.3.1 ver
This commit is contained in:
@@ -110,7 +110,9 @@ void drvBase::drv_fullpart(bool part){ //切换慢刷/快刷功能
|
||||
if(!part) iLut=15; //恢复默认的灰度模式
|
||||
Init(part?lut_fast:lut_slow);
|
||||
}*/
|
||||
void drvBase::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新等功能
|
||||
void drvBase::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新等功能
|
||||
if(m&1){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
if(sleeping) Init(lut_slow);
|
||||
BeginTransfer();
|
||||
SetMemory(); // bit set = white, bit reset = black
|
||||
@@ -123,14 +125,22 @@ void drvBase::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新等
|
||||
guy_epdCmd(0x20);
|
||||
guy_epdCmd(0xff);
|
||||
EndTransfer();
|
||||
guy_epdBusy((this->lut == (const uint8_t*)lut_fast)?idleFastRf:idleSlowRf);
|
||||
BeginTransfer();
|
||||
SetMemory(); // bit set = white, bit reset = black
|
||||
guy_epdBusy(90);
|
||||
guy_epdCmd(0x26); /* will send the color data */
|
||||
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
|
||||
SpiTransfer(f(i));
|
||||
EndTransfer();
|
||||
lastRefresh=millis();
|
||||
}
|
||||
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
uint32_t u=(this->lut == (const uint8_t*)lut_fast)?idleFastRf:idleSlowRf;
|
||||
if(ms<u) guy_epdBusy(u-ms);
|
||||
lastRefresh=0;
|
||||
BeginTransfer();
|
||||
SetMemory(); // bit set = white, bit reset = black
|
||||
guy_epdBusy(90);
|
||||
guy_epdCmd(0x26); /* will send the color data */
|
||||
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
|
||||
SpiTransfer(f(i));
|
||||
EndTransfer();
|
||||
}
|
||||
}
|
||||
void drvBase::drv_sleep() { //开始屏幕睡眠
|
||||
if(RST_PIN>=0) { //未定义RST_PIN时无法唤醒
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
virtual int drv_ID() const=0;
|
||||
void drv_init(); //初始化屏幕
|
||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||
void drv_sleep() ; //开始屏幕睡眠
|
||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||
|
||||
@@ -148,7 +148,9 @@ void drvSSD168x::drv_fullpart(bool part){ //切换慢刷/快刷功能
|
||||
if(!part) { iLut=15; greyScaling=0; }
|
||||
_part=part;
|
||||
}
|
||||
void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||
if(m&1){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
BeginTransfer();
|
||||
if(_part){
|
||||
//Reset();
|
||||
@@ -196,7 +198,15 @@ void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
guy_epdParam(_part?0x0f:0xc7);
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
guy_epdBusy(_part?600:2300);
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
uint32_t u=_part?600:2300;
|
||||
if(ms<u) guy_epdBusy(u-ms);
|
||||
lastRefresh=0;
|
||||
}
|
||||
//guy_epdBusy(_part?600:2300);
|
||||
}
|
||||
void drvSSD168x::drv_sleep() { //开始屏幕睡眠
|
||||
if(RST_PIN>=0){ //无法唤醒
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
virtual int drv_ID() const =0;
|
||||
void drv_init(); //初始化屏幕
|
||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||
void drv_sleep() ; //开始屏幕睡眠
|
||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||
|
||||
@@ -119,7 +119,9 @@ void drv::drv_fullpart(bool part){ //初始化慢刷功能
|
||||
epdFull = !part;
|
||||
//epd_Init();
|
||||
}
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||
if(m&1){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
BeginTransfer();
|
||||
if(epdFull) { //当刷新模式从快刷切换为慢刷时, 需要发送一次init
|
||||
epdFull=0;
|
||||
@@ -143,7 +145,15 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
guy_epdParam(epdFull?0xc4:0x04);
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
guy_epdBusy(epdFull?1600:310);
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
lastRefresh=0;
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
uint32_t u=epdFull?1600:310;
|
||||
if(ms<u) guy_epdBusy(u-ms);
|
||||
}
|
||||
//guy_epdBusy(epdFull?1600:310);
|
||||
}
|
||||
void drv::drv_sleep() { //开始屏幕睡眠
|
||||
if(RST_PIN>=0){ //RST_PIN<0 无法唤醒
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
int drv_ID() const { return READGUY_DEV_213A; }
|
||||
void drv_init(); //初始化屏幕
|
||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||
void drv_sleep() ; //开始屏幕睡眠
|
||||
int drv_width() const { return EPD_REAL_WIDTH; }; //返回显示区域宽度
|
||||
//int drv_panelwidth() const { return GUY_D_WIDTH; }; //返回缓存的数据宽度
|
||||
|
||||
@@ -152,7 +152,9 @@ void drv_base::drv_setDepth(uint8_t i){
|
||||
SendLuts(1);
|
||||
EndTransfer();
|
||||
}
|
||||
void drv_base::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
void drv_base::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||
if(m&1){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
BeginTransfer();
|
||||
epd_init();
|
||||
SendLuts(part_mode);
|
||||
@@ -169,17 +171,29 @@ void drv_base::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
send_zoneInfo();
|
||||
guy_epdCmd(0x12);
|
||||
EndTransfer();
|
||||
guy_epdBusy(-200);
|
||||
}
|
||||
else{
|
||||
guy_epdCmd(0x12);
|
||||
EndTransfer();
|
||||
guy_epdBusy(-2000);
|
||||
BeginTransfer();
|
||||
epd_init();
|
||||
SendLuts(1);
|
||||
guy_epdCmd(0x92);
|
||||
EndTransfer();
|
||||
}
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
if(part_mode){
|
||||
if(ms<200) guy_epdBusy(ms-200);
|
||||
//guy_epdBusy(-200);
|
||||
}
|
||||
else{
|
||||
if(ms<2000) guy_epdBusy(ms-2000);
|
||||
//guy_epdBusy(-2000);
|
||||
BeginTransfer();
|
||||
epd_init();
|
||||
SendLuts(1);
|
||||
guy_epdCmd(0x92);
|
||||
EndTransfer();
|
||||
}
|
||||
lastRefresh=0;
|
||||
}
|
||||
}
|
||||
void drv_base::drv_sleep() { //开始屏幕睡眠
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
virtual int drv_ID() const=0;
|
||||
void drv_init(); //初始化屏幕
|
||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||
void drv_sleep() ; //开始屏幕睡眠
|
||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||
|
||||
@@ -120,7 +120,9 @@ void drv::drv_fullpart(bool part){ //切换慢刷/快刷功能
|
||||
}
|
||||
part_mode=part;
|
||||
}
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||
if(m&1){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
if(sleeping) Init();
|
||||
BeginTransfer();
|
||||
guy_epdCmd(0x4E); guy_epdParam(0x00); guy_epdParam(0x00);
|
||||
@@ -138,7 +140,15 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
Load_LUT(!part_mode);
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
guy_epdBusy(part_mode?500:1300);
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
uint32_t u=part_mode?500:1300;
|
||||
if(ms<u) guy_epdBusy(u-ms);
|
||||
lastRefresh=0;
|
||||
}
|
||||
//guy_epdBusy(part_mode?500:1300);
|
||||
}
|
||||
void drv::drv_sleep() { //开始屏幕睡眠
|
||||
if(RST_PIN>=0){
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
int drv_ID() const { return READGUY_DEV_370A; }
|
||||
void drv_init(); //初始化屏幕
|
||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||
void drv_sleep() ; //开始屏幕睡眠
|
||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
||||
|
||||
@@ -185,7 +185,9 @@ void drv::drv_fullpart(bool part){ //初始化慢刷功能
|
||||
if(epdFull<=1) epdFull = !part; //epdFull==2代表睡眠中, 不能快刷
|
||||
if(epdFull) GreyScaling=0;
|
||||
}
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||
if(m&1){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
BeginTransfer();
|
||||
epd_Init();
|
||||
SetMemory();
|
||||
@@ -211,9 +213,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
SetLut(lut_213_B72_Full);
|
||||
guy_epdCmd(0x22);
|
||||
guy_epdParam(0xc4);
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
guy_epdBusy(1600); //等待刷完
|
||||
//guy_epdBusy(1600); //等待刷完
|
||||
}
|
||||
else{ //快刷
|
||||
guy_epdCmd(0x2c); //may a mistake? 此处不需要设置vcom
|
||||
@@ -221,17 +221,24 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
SetLut(GreyScalingHighQuality?lut_213_B72_16grey:lut_213_B72);
|
||||
guy_epdCmd(0x22);
|
||||
guy_epdParam(0x04);
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
guy_epdBusy(260); //等待屏幕刷新完成
|
||||
}
|
||||
BeginTransfer(); //write again
|
||||
SetMemory();
|
||||
guy_epdCmd(0x26);
|
||||
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
|
||||
SpiTransfer(f(i)); //按照给定的RAM写入数据
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
if(epdFull) power_down();
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
uint32_t u=epdFull?1600:260;
|
||||
if(ms<u) guy_epdBusy(u-ms); //等待屏幕刷新完成
|
||||
lastRefresh=0;
|
||||
BeginTransfer(); //write again
|
||||
SetMemory();
|
||||
guy_epdCmd(0x26);
|
||||
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
|
||||
SpiTransfer(f(i)); //按照给定的RAM写入数据
|
||||
EndTransfer();
|
||||
if(epdFull) power_down();
|
||||
}
|
||||
}
|
||||
void drv::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
|
||||
if(_quality&1) return readguyEpdBase::drv_draw16grey_step(f,step);
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
int drv_ID() const { return READGUY_DEV_420A; }
|
||||
void drv_init(); //初始化屏幕
|
||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||
void drv_sleep() ; //开始屏幕睡眠
|
||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
||||
|
||||
@@ -147,7 +147,9 @@ 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::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||
if(m&1){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
BeginTransfer();
|
||||
Init(part_mode);
|
||||
if(part_mode){
|
||||
@@ -181,7 +183,13 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
}
|
||||
guy_epdCmd(0x12);
|
||||
EndTransfer();
|
||||
guy_epdBusy(part_mode?-800:-3600);
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
uint32_t u=part_mode?800:3600;
|
||||
if(ms<u) guy_epdBusy(ms-u);
|
||||
lastRefresh=0;
|
||||
BeginTransfer();
|
||||
if(part_mode){
|
||||
sendArea();
|
||||
@@ -189,7 +197,6 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
|
||||
SpiTransfer(f(i));
|
||||
guy_epdCmd(0x92);
|
||||
EndTransfer();
|
||||
}
|
||||
else{
|
||||
Init(2);
|
||||
@@ -199,6 +206,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
SpiTransfer(f(i));
|
||||
guy_epdCmd(0x92);
|
||||
guy_epdCmd(0x02);
|
||||
}
|
||||
EndTransfer();
|
||||
guy_epdBusy(-20);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
void drv_init(); //初始化屏幕
|
||||
//void drv_draw16grey(uint8_t *d16bit);
|
||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||
void drv_sleep() ; //开始屏幕睡眠
|
||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
||||
|
||||
@@ -77,6 +77,7 @@ int readguyEpdBase::IfInit(SPIClass &c,int8_t cs,int8_t dc,int8_t rst,int8_t bus
|
||||
DigitalWrite(DC_PIN,HIGH);
|
||||
if(BUSY_PIN>=0) pinMode(BUSY_PIN, INPUT);
|
||||
_spi = &c;
|
||||
lastRefresh=0;
|
||||
|
||||
//_spi->begin();
|
||||
//_spi->beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
|
||||
@@ -161,8 +162,7 @@ void readguyEpdBase::Reset(uint32_t minTime)
|
||||
|
||||
void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,int o,
|
||||
uint16_t fw, uint16_t fh){
|
||||
#ifndef FLOYD_STEINBERG_DITHERING
|
||||
static const uint8_t bayer_tab [64]={
|
||||
static const PROGMEM uint8_t bayer_tab [64]={
|
||||
0, 32, 8, 40, 2, 34, 10, 42,
|
||||
48, 16, 56, 24, 50, 18, 58, 26,
|
||||
12, 44, 4, 36, 14, 46, 6, 38,
|
||||
@@ -172,24 +172,21 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
|
||||
15, 47, 7, 39, 13, 45, 5, 37,
|
||||
63, 31, 55, 23, 61, 29, 53, 21
|
||||
};
|
||||
#endif
|
||||
if(!fw) fw=spr.width();
|
||||
if(!fh) fh=spr.height();
|
||||
if((!fw) || (!fh)) return;
|
||||
if(o==0 || o==1){
|
||||
readBuff = new uint16_t[spr.width()];
|
||||
#ifdef FLOYD_STEINBERG_DITHERING
|
||||
floyd_tab[0] = new int16_t [fw];
|
||||
floyd_tab[1] = new int16_t [fw];
|
||||
for(int j=0;j<fw;j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
||||
#endif
|
||||
writeBuff = new uint8_t[(fw+7)>>3];
|
||||
}
|
||||
sprbase.fillRect(x,y,fw,fh,1);
|
||||
for(int32_t i=y;i<(int32_t)fh+y;i++){
|
||||
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
||||
#ifdef FLOYD_STEINBERG_DITHERING
|
||||
uint_fast8_t buff8bit=0;
|
||||
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
||||
if(_quality&2){
|
||||
for(int32_t j=0;j<fw;j++){
|
||||
int gv=greysc(readBuff[j*spr.width()/fw]);
|
||||
int32_t flodelta = floyd_tab[i&1][j]+(int32_t)((gv<<8)|gv);
|
||||
@@ -218,24 +215,24 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
|
||||
{ floyd_tab[!(i&1)][j+1] += (flodelta )>>4; }
|
||||
}
|
||||
for(int floi=0;floi<fw;floi++) floyd_tab[i&1][floi]=0;
|
||||
#else
|
||||
for(int32_t j=0;j<w;j++){
|
||||
uint_fast8_t buff8bit=0;
|
||||
for(uint_fast8_t b=0;b<8;b++)
|
||||
buff8bit |= (bayer_tab[(b<<3)|(i&7)]<(greysc(readBuff[j*spr.width()/fw])>>2))<<(7-b);
|
||||
writeBuff[j]=buff8bit;
|
||||
}
|
||||
#endif
|
||||
else{
|
||||
for(int32_t j=0;j<((fw+7)>>3);j++){
|
||||
buff8bit=0;
|
||||
for(uint_fast8_t b=0;b<8;b++)
|
||||
buff8bit |= ((pgm_read_byte(bayer_tab+((b<<3)|(i&7)))<<2)+2
|
||||
<greysc(readBuff[((j<<3)+b)*spr.width()/fw]))<<(7-b);
|
||||
writeBuff[j]=buff8bit;
|
||||
}
|
||||
}
|
||||
sprbase.drawBitmap(x,i,writeBuff,fw,1,1,0);
|
||||
}
|
||||
//_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] ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//不支持的话使用单色抖动刷屏
|
||||
@@ -247,10 +244,8 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
||||
if((!fw) || (!fh)) return;
|
||||
readBuff = new uint16_t[spr.width()];
|
||||
if(_quality&2){
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
floyd_tab[0] = new int16_t [fw];
|
||||
floyd_tab[1] = new int16_t [fw];
|
||||
#endif
|
||||
}
|
||||
writeBuff = new uint8_t[(fw+7)>>3];
|
||||
sprbase.fillRect(x,y,fw,fh,1);
|
||||
@@ -260,15 +255,12 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
||||
drv_dispWriter(FILL_WHITE);
|
||||
drv_fullpart(1);
|
||||
for(uint_fast8_t k=1;k<16;k++){ //亮度为15的不用绘制,因为本来就是白色
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
if(_quality&2) for(int j=0;j<fw;j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
||||
#endif
|
||||
for(int i=y;i<(int32_t)fh+y;i++){
|
||||
uint_fast8_t buff8bit=0;
|
||||
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
||||
for(int32_t j=0;j<fw;j++){
|
||||
//for(uint_fast8_t b=0;b<8;b++){
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
uint_fast8_t cg=0;
|
||||
if(_quality&2){
|
||||
int gv=greysc(readBuff[j*spr.width()/fw]);
|
||||
@@ -284,9 +276,7 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
||||
if(j!=fw-1) { floyd_tab[!(i&1)][j+1] += (fd )>>4; }
|
||||
}
|
||||
else{ cg=greysc(readBuff[j*spr.width()/fw])>>4; }
|
||||
#else
|
||||
uint_fast8_t cg=greysc(readBuff[j*spr.width()/fw])>>4;
|
||||
#endif
|
||||
//uint_fast8_t cg=greysc(readBuff[j*spr.width()/fw])>>4;
|
||||
if(negativeOrder)
|
||||
buff8bit |= (cg<k)<<((~j)&7);
|
||||
else{
|
||||
@@ -300,9 +290,7 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
||||
//}
|
||||
//sprbase.drawPixel(x+j,i,(greysc(readBuff[j*spr.width()/fw])/16)==(15-k));
|
||||
}
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
if(_quality&2) for(int floi=0;floi<fw;floi++) floyd_tab[i&1][floi]=0;
|
||||
#endif
|
||||
sprbase.drawBitmap(x,i,writeBuff,fw,1,1,0);
|
||||
}
|
||||
drv_draw16grey_step((const uint8_t*)sprbase.getBuffer(),k); //使用灰度显示函数
|
||||
@@ -310,10 +298,8 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
||||
delete []readBuff;
|
||||
delete []writeBuff;
|
||||
if(_quality&2){
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
delete [] floyd_tab[0] ;
|
||||
delete [] floyd_tab[1] ;
|
||||
#endif
|
||||
}
|
||||
} /* END OF FILE. ReadGuy project.
|
||||
Copyright (C) 2023 FriendshipEnder. */
|
||||
@@ -55,9 +55,8 @@ protected:
|
||||
#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
|
||||
uint32_t lastRefresh;
|
||||
|
||||
public:
|
||||
readguyEpdBase(void);
|
||||
@@ -82,9 +81,9 @@ public:
|
||||
virtual int drv_ID() const =0; //返回驱动代号
|
||||
virtual void drv_init()=0; //初始化屏幕
|
||||
virtual void drv_fullpart(bool part)=0; //初始化慢刷功能
|
||||
void _display(const uint8_t *d){ drv_dispWriter([&](int n)->uint8_t{return d[n];}); }
|
||||
virtual void drv_dispWriter(std::function<uint8_t(int)>)=0; //按照显示函数刷新
|
||||
void drv_color(uint8_t c){ drv_dispWriter([=](int)->uint8_t{return c;}); } //单色刷新
|
||||
void _display(const uint8_t *d,uint8_t m=3){ drv_dispWriter([&](int n)->uint8_t{return d[n];},m); }
|
||||
virtual void drv_dispWriter(std::function<uint8_t(int)>,uint8_t m=3)=0; //按照显示函数刷新
|
||||
void drv_color(uint8_t c,uint8_t m=3){ drv_dispWriter([=](int)->uint8_t{return c;},m); } //单色刷新
|
||||
virtual void drv_sleep() =0; //开始屏幕睡眠
|
||||
virtual int drv_width() const=0; //返回显示区域宽度, 即使旋转了也不能影响此函数输出
|
||||
virtual int drv_height()const=0; //返回显示区域高度, 即使旋转了也不能影响此函数输出
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
//#define _DEFINA_SD_CS_PIN 0
|
||||
|
||||
// * for NodeMcu ctg stack LCF board
|
||||
#define WHITE_GAP 8
|
||||
#define WHITE_GAP 2
|
||||
|
||||
#ifdef ESP8266
|
||||
#define DISPLAY_TYPE_ST7789_240320 //2.0寸的ST7789 IPS TFT模块
|
||||
|
||||
@@ -40,7 +40,9 @@ void drv::drv_init(){
|
||||
void drv::drv_fullpart(bool part){
|
||||
partMode=part;
|
||||
}
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||
if(m&1){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
uint16_t dat[8];
|
||||
unsigned short xbits=(drv_width()+7)/8;
|
||||
if(partMode==0){
|
||||
@@ -79,7 +81,13 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
}
|
||||
}
|
||||
}
|
||||
yield();
|
||||
}
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
if(ms<150) DelayMs(150-ms);
|
||||
lastRefresh=0;
|
||||
}
|
||||
}
|
||||
void drv::drv_sleep() {}
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
int drv_ID() const { return MEPD_DEBUG_DISPLAY; }
|
||||
void drv_init(); //初始化屏幕
|
||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f); //单色刷新
|
||||
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //单色刷新
|
||||
void drv_sleep() ; //开始屏幕睡眠
|
||||
int drv_width() const { return ips.width()-2*WHITE_GAP; } //返回显示区域宽度
|
||||
int drv_height() const{ return ips.height()-2*WHITE_GAP; } //返回显示区域高度
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
//另外, 在提交新版本之前, 不要忘记在github上创建release, 否则Arduino IDE会读不到
|
||||
#define READGUY_V_MAJOR 1
|
||||
#define READGUY_V_MINOR 3
|
||||
#define READGUY_V_PATCH 0
|
||||
#define READGUY_V_PATCH 1
|
||||
#define READGUY_VERSION_VAL (READGUY_V_MAJOR*1000+READGUY_V_MINOR*100+READGUY_V_PATCH*10)
|
||||
#define READGUY_VERSION "1.3.0"
|
||||
#define READGUY_VERSION "1.3.1"
|
||||
|
||||
#ifdef ESP8266
|
||||
#define _READGUY_PLATFORM "ESP8266"
|
||||
|
||||
@@ -191,7 +191,7 @@ bool ReadguyDriver::server_loop(){ //此时等待网页操作完成响应...
|
||||
}
|
||||
if(refFlag!=127) {
|
||||
Serial.printf("randch: %d %c\n",randomch[refFlag],(char)(randomch[refFlag]));
|
||||
drawChar((width()>>1)-46+refFlag*24,(height()>>1)-14,randomch[refFlag],true,false,4);
|
||||
drawChar((guy_dev->drv_width()>>1)-46+refFlag*24,(guy_dev->drv_height()>>1)-14,randomch[refFlag],true,false,4);
|
||||
guy_dev->drv_fullpart(1);
|
||||
guy_dev->_display((const uint8_t*)getBuffer());
|
||||
}
|
||||
@@ -311,13 +311,14 @@ void ReadguyDriver::handleInitPost(){
|
||||
setEpdDriver(); //尝试初始化屏幕
|
||||
Serial.println(F("[Guy] Init details..."));
|
||||
setTextSize(1);
|
||||
drawCenterString(setSDcardDriver()?"SD Init OK!":"SD Init failed!",width()>>1,(height()>>1)+20);
|
||||
drawCenterString(setSDcardDriver()?"SD Init OK!":"SD Init failed!",
|
||||
guy_dev->drv_width()>>1,(guy_dev->drv_height()>>1)+20);
|
||||
setButtonDriver(); //初始化按钮..
|
||||
//} //尝试初始化按键, 调用后, 若SD卡初始化成功, READGUY_sd_ok的值会变成1
|
||||
drawRect((width()>>1)-46 ,(height()>>1)-14,20,28,0);
|
||||
drawRect((width()>>1)-46+24,(height()>>1)-14,20,28,0);
|
||||
drawRect((width()>>1)-46+48,(height()>>1)-14,20,28,0);
|
||||
drawRect((width()>>1)-46+72,(height()>>1)-14,20,28,0);
|
||||
drawRect((guy_dev->drv_width()>>1)-46 ,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||
drawRect((guy_dev->drv_width()>>1)-46+24,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||
drawRect((guy_dev->drv_width()>>1)-46+48,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||
drawRect((guy_dev->drv_width()>>1)-46+72,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||
spibz++;
|
||||
guy_dev->drv_fullpart(1);
|
||||
guy_dev->_display((const uint8_t*)getBuffer());
|
||||
|
||||
@@ -180,11 +180,10 @@ void ReadguyDriver::setEpdDriver(bool initepd/* ,int g_width,int g_height */){
|
||||
//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("[Guy EPD] EPD init OK"));
|
||||
//以下依赖于你的图形驱动
|
||||
setColorDepth(1); //单色模式
|
||||
createPalette(); //初始化颜色系统
|
||||
Serial.printf_P(PSTR("[Guy EPD] mono set: w: %d, h: %d\n"),guy_dev->drv_width(),guy_dev->drv_height());
|
||||
Serial.printf_P(PSTR("[Guy EPD] EPD init OK: w: %d, h: %d\n"),guy_dev->drv_width(),guy_dev->drv_height());
|
||||
//创建画布. 根据LovyanGFX的特性, 如果以前有画布会自动重新生成新画布
|
||||
//此外, 即使画布宽度不是8的倍数(如2.13寸单色),也支持自动补全8的倍数 ( 250x122 => 250x128 )
|
||||
//为了保证图片显示功能的正常使用, 高度也必须是8的倍数.
|
||||
@@ -370,32 +369,41 @@ void ReadguyDriver::setBright(int d){
|
||||
digitalWrite(READGUY_bl_pin,d?HIGH:LOW);
|
||||
}
|
||||
}
|
||||
void ReadguyDriver::display(bool part){
|
||||
void ReadguyDriver::display(uint8_t part){
|
||||
//真的是我c++的盲区了啊....搜索了半天才找到可以这么玩的
|
||||
//......可惜'dynamic_cast' not permitted with -fno-rtti
|
||||
// static bool _part = 0; 记忆上次到底是full还是part, 注意启动时默认为full
|
||||
if(READGUY_cali==127){
|
||||
//in_press(); //暂停, 然后读取按键状态 spibz
|
||||
guy_dev->drv_fullpart(part);
|
||||
guy_dev->_display((const uint8_t*)getBuffer());
|
||||
guy_dev->drv_fullpart(part&1);
|
||||
guy_dev->_display((const uint8_t*)getBuffer(),((part>>1)?part>>1:3));
|
||||
//in_release(); //恢复
|
||||
}
|
||||
}
|
||||
void ReadguyDriver::display(std::function<uint8_t(int)> f, bool part){
|
||||
void ReadguyDriver::display(const uint8_t *buf, uint8_t part){
|
||||
if(READGUY_cali==127){
|
||||
//in_press(); //暂停, 然后读取按键状态 spibz
|
||||
guy_dev->drv_fullpart(part);
|
||||
guy_dev->drv_dispWriter(f);
|
||||
guy_dev->drv_fullpart(part&1);
|
||||
guy_dev->_display(buf,((part>>1)?part>>1:3));
|
||||
//in_release(); //恢复
|
||||
}
|
||||
}
|
||||
void ReadguyDriver::display(std::function<uint8_t(int)> f, uint8_t part){
|
||||
if(READGUY_cali==127){
|
||||
//in_press(); //暂停, 然后读取按键状态 spibz
|
||||
guy_dev->drv_fullpart(part&1);
|
||||
guy_dev->drv_dispWriter(f,((part>>1)?part>>1:3));
|
||||
//in_release(); //恢复
|
||||
}
|
||||
}
|
||||
void ReadguyDriver::drawImage(LGFX_Sprite &base, LGFX_Sprite &spr,uint16_t x,uint16_t y,uint16_t zoomw, uint16_t zoomh) {
|
||||
if(READGUY_cali==127) guy_dev->drv_drawImage(base, spr, x, y, 0, zoomw, zoomh);
|
||||
}
|
||||
void ReadguyDriver::drawImageStage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint8_t stage,
|
||||
void ReadguyDriver::drawImageStage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,uint8_t stage,
|
||||
uint8_t totalstage,uint16_t zoomw,uint16_t zoomh) {
|
||||
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)),zoomw,zoomh);
|
||||
//Serial.printf("stage: %d/%d\n",stage+1,totalstage);
|
||||
guy_dev->drv_drawImage(sprbase, spr, x, y, (totalstage<=1)?0:(stage==0?1:(stage==(totalstage-1)?3:2)),zoomw,zoomh);
|
||||
}
|
||||
void ReadguyDriver::setDepth(uint8_t d){
|
||||
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling()) guy_dev->drv_setDepth(d);
|
||||
|
||||
@@ -132,6 +132,13 @@
|
||||
#define READGUY_buttons (config_data[21]) //按钮个数, 0-3都有可能
|
||||
#endif
|
||||
|
||||
#define READGUY_SLOW 0
|
||||
#define READGUY_FAST 1
|
||||
#define READGUY_SLOW_START 2
|
||||
#define READGUY_FAST_START 3
|
||||
#define READGUY_SLOW_END 4
|
||||
#define READGUY_FAST_END 5
|
||||
|
||||
class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||
public:
|
||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
||||
@@ -155,7 +162,9 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||
/// @brief 返回显示亮度
|
||||
int getBright() const { return currentBright; }
|
||||
/// @brief 刷新显示到屏幕上
|
||||
void display(bool part = true);
|
||||
void display(uint8_t part = READGUY_FAST);
|
||||
/// @brief 刷新显示到屏幕上
|
||||
void display(const uint8_t *buf, uint8_t part = READGUY_FAST);
|
||||
/** @brief 刷新显示到屏幕上, 可以自定义读取指定位置像素的函数
|
||||
* @param f 自定义的函数. 此函数将在读取像素并输出到墨水屏时被调用.
|
||||
* 每次调用需要返回 "参数对应位置" 的8个像素的颜色信息(凑成一字节). 其中左侧应在高位,右侧应在低位.
|
||||
@@ -170,7 +179,7 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||
* @endcode
|
||||
* 该函数会将参数从0开始,每次逐渐增加1的顺序来被调用. 即先调用f(0),再f(1),f(2),f(3)... 以此类推.
|
||||
*/
|
||||
void display(std::function<uint8_t(int)> f, bool part = true);
|
||||
void display(std::function<uint8_t(int)> f, uint8_t part = READGUY_FAST);
|
||||
/// @brief 显示图片, 使用抖动算法. 可以用省内存的方法显示, 可以缩放到指定的宽度和高度
|
||||
void drawImage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint16_t zoomw=0, uint16_t zoomh=0){
|
||||
if(READGUY_cali==127) drawImage(*this,spr,x,y,zoomw,zoomh);
|
||||
@@ -368,14 +377,16 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||
//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; } //返回显示屏硬件高度(不是画幅高度)
|
||||
int width () const { return READGUY_cali==127?((getRotation()&1)?drvHeight():drvWidth()):0; }
|
||||
int height() const { return READGUY_cali==127?((getRotation()&1)?drvWidth():drvHeight()):0; }
|
||||
int width () const { return (getRotation()&1)?drvHeight():drvWidth(); }
|
||||
int height() const { return (getRotation()&1)?drvWidth():drvHeight(); }
|
||||
// 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,
|
||||
uint16_t zoomw=0,uint16_t zoomh=0);
|
||||
uint16_t zoomw=0,uint16_t zoomh=0){ drawImageStage(*this,spr,x,y,stage,totalstage,zoomw,zoomh); }
|
||||
void drawImageStage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,
|
||||
uint8_t stage,uint8_t totalstage,uint16_t zoomw=0,uint16_t zoomh=0);
|
||||
};
|
||||
#endif /* END OF FILE. ReadGuy project.
|
||||
Copyright (C) 2023 FriendshipEnder. */
|
||||
Reference in New Issue
Block a user