fix memory bug

This commit is contained in:
fsender
2023-11-07 21:26:51 +08:00
parent 85a785eabd
commit d24639a962
4 changed files with 22 additions and 17 deletions

View File

@@ -61,16 +61,16 @@ uint8_t readguyImage::drawImgHandler(int r, LGFX_Sprite *spr){
//_x=y-r/stage*_h; yd=0; //_x=y-r/stage*_h; yd=0;
//_y=x;//(widthDiv8<<3)-x-1; //_y=x;//(widthDiv8<<3)-x-1;
_x=x-r/stage*_h; _x=x-r/stage*_h;
_y=y; yd=0; _y=y+w-guy->drvWidth(); yd=0;
if(_x<0){ xd=-_x; _x=0; } if(_x<0){ xd=-_x; _x=0; }
break; break;
case 2: case 2:
_x=x; xd=0; _x=x+w-guy->drvWidth(); xd=0;
_y=y-(GUY_STAGES-r/stage-1)*_h; _y=y+(r/stage+1)*_h-h;
if(_y<0){ yd=-_y; _y=0; } if(_y<0){ yd=-_y; _y=0; }
break; break;
case 3: case 3:
_x=x-(GUY_STAGES-r/stage-1)*_h; _x=x+(r/stage+1)*_h-h;
_y=y; yd=0; _y=y; yd=0;
if(_x<0){ xd=-_x; _x=0; } if(_x<0){ xd=-_x; _x=0; }
break; break;
@@ -234,7 +234,7 @@ void readguyImage::drawImageFile(bool use16grey){
_pool=exPool; _pool=exPool;
} }
if(_pool==nullptr) { if(_pool==nullptr) {
_h=(h+7)>>3; //设置缓存区的高度. 更多内存将可以更快显示 _h=h>>3; //设置缓存区的高度. 更多内存将可以更快显示
_pool=(uint8_t *)guy->getBuffer(); _pool=(uint8_t *)guy->getBuffer();
} }
//(guy->guyMemoryHeight()+7)>>3 返回高度,并补齐后右移三位 (等效于除以2³, 分成8份) //(guy->guyMemoryHeight()+7)>>3 返回高度,并补齐后右移三位 (等效于除以2³, 分成8份)
@@ -275,7 +275,7 @@ void readguyImage::drawImageFile(bool use16grey){
} }
else{ else{
// ************* 提示: 编写此示例时的最新版本LovyanGFX库不提供此函数. 请看ex06_Image.ino文件开头的解决方法! // ************* 提示: 编写此示例时的最新版本LovyanGFX库不提供此函数. 请看ex06_Image.ino文件开头的解决方法!
guy->display(std::bind(&readguyImage::drawImgHandler,this,std::placeholders::_1,&bmpspr)); guy->display(std::bind(&readguyImage::drawImgHandler,this,std::placeholders::_1,&bmpspr),READGUY_FAST);
// 此函数过不了编译 需要改库. // 此函数过不了编译 需要改库.
} }

View File

@@ -148,10 +148,10 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷
lastRefresh=millis(); lastRefresh=millis();
} }
if(m&2){//stage 2 if(m&2){//stage 2
lastRefresh=0;
uint32_t ms=millis()-lastRefresh; uint32_t ms=millis()-lastRefresh;
uint32_t u=epdFull?1600:310; uint32_t u=epdFull?1600:310;
if(ms<u) guy_epdBusy(u-ms); if(ms<u) guy_epdBusy(u-ms);
lastRefresh=0;
} }
//guy_epdBusy(epdFull?1600:310); //guy_epdBusy(epdFull?1600:310);
} }

View File

@@ -49,7 +49,7 @@ ReadguyDriver::ReadguyDriver(){
READGUY_sd_ok = 0; //初始默认SD卡未成功初始化 READGUY_sd_ok = 0; //初始默认SD卡未成功初始化
READGUY_buttons = 0; //初始情况下没有按钮 READGUY_buttons = 0; //初始情况下没有按钮
} //WiFiSet: 是否保持AP服务器一直处于打开状态 } //WiFiSet: 是否保持AP服务器一直处于打开状态
uint8_t ReadguyDriver::init(uint8_t WiFiSet,bool initepd/* ,int g_width,int g_height */){ uint8_t ReadguyDriver::init(uint8_t WiFiSet, bool initepd){
if(READGUY_cali==127) //已经初始化过了一次了, 为了防止里面一些volatile的东西出现问题....还是退出吧 if(READGUY_cali==127) //已经初始化过了一次了, 为了防止里面一些volatile的东西出现问题....还是退出吧
return 0; return 0;
#ifdef DYNAMIC_PIN_SETTINGS #ifdef DYNAMIC_PIN_SETTINGS
@@ -187,7 +187,7 @@ void ReadguyDriver::setEpdDriver(bool initepd/* ,int g_width,int g_height */){
//创建画布. 根据LovyanGFX的特性, 如果以前有画布会自动重新生成新画布 //创建画布. 根据LovyanGFX的特性, 如果以前有画布会自动重新生成新画布
//此外, 即使画布宽度不是8的倍数(如2.13寸单色),也支持自动补全8的倍数 ( 250x122 => 250x128 ) //此外, 即使画布宽度不是8的倍数(如2.13寸单色),也支持自动补全8的倍数 ( 250x122 => 250x128 )
//为了保证图片显示功能的正常使用, 高度也必须是8的倍数. //为了保证图片显示功能的正常使用, 高度也必须是8的倍数.
createSprite(guy_dev->drv_width(),(guy_dev->drv_height()+7)&0x7ffffff8); createSprite(guy_dev->drv_width(),guy_dev->drv_height());
//这里发现如果用自定义的内存分配方式会更好一些. 不会导致返回的height不对. 但是因为LovyanGFX库未更新 暂时不能这么用. //这里发现如果用自定义的内存分配方式会更好一些. 不会导致返回的height不对. 但是因为LovyanGFX库未更新 暂时不能这么用.
//setRotation(1); //旋转之后操作更方便 //setRotation(1); //旋转之后操作更方便
setRotation(0); setRotation(0);
@@ -380,7 +380,7 @@ void ReadguyDriver::display(uint8_t part){
//in_release(); //恢复 //in_release(); //恢复
} }
} }
void ReadguyDriver::display(const uint8_t *buf, uint8_t part){ void ReadguyDriver::displayBuffer(const uint8_t *buf, uint8_t part){
if(READGUY_cali==127){ if(READGUY_cali==127){
//in_press(); //暂停, 然后读取按键状态 spibz //in_press(); //暂停, 然后读取按键状态 spibz
guy_dev->drv_fullpart(part&1); guy_dev->drv_fullpart(part&1);

View File

@@ -154,9 +154,10 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
/** @brief 初始化readguy /** @brief 初始化readguy
* @param WiFiSet 是否保持AP模式关闭. 0:配网完成自动关WiFi, 1:需要手动调用 WiFi.mode(WIFI_OFF) 关闭WiFi. * @param WiFiSet 是否保持AP模式关闭. 0:配网完成自动关WiFi, 1:需要手动调用 WiFi.mode(WIFI_OFF) 关闭WiFi.
* 2:自动连接到已存的WiFi, 但不等待连接成功 * 2:自动连接到已存的WiFi, 但不等待连接成功
* @param initepd 是否初始化墨水屏. 初始化后的首次刷屏必为慢刷. 如果是不断电复位, 可以不初始化墨水屏直接刷屏
* @return SD卡是否就绪 * @return SD卡是否就绪
*/ */
uint8_t init(uint8_t WiFiSet = 0,bool initepd = 1/* ,int g_width = 0,int g_height = 0 */); uint8_t init(uint8_t WiFiSet = 0, bool initepd = 1);
/// @brief 设置显示亮度 /// @brief 设置显示亮度
void setBright(int d); void setBright(int d);
/// @brief 返回显示亮度 /// @brief 返回显示亮度
@@ -164,7 +165,7 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
/// @brief 刷新显示到屏幕上 /// @brief 刷新显示到屏幕上
void display(uint8_t part = READGUY_FAST); void display(uint8_t part = READGUY_FAST);
/// @brief 刷新显示到屏幕上 /// @brief 刷新显示到屏幕上
void display(const uint8_t *buf, uint8_t part = READGUY_FAST); void displayBuffer(const uint8_t *buf, uint8_t part);
/** @brief 刷新显示到屏幕上, 可以自定义读取指定位置像素的函数 /** @brief 刷新显示到屏幕上, 可以自定义读取指定位置像素的函数
* @param f 自定义的函数. 此函数将在读取像素并输出到墨水屏时被调用. * @param f 自定义的函数. 此函数将在读取像素并输出到墨水屏时被调用.
* 每次调用需要返回 "参数对应位置" 的8个像素的颜色信息(凑成一字节). 其中左侧应在高位,右侧应在低位. * 每次调用需要返回 "参数对应位置" 的8个像素的颜色信息(凑成一字节). 其中左侧应在高位,右侧应在低位.
@@ -179,7 +180,7 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
* @endcode * @endcode
* 该函数会将参数从0开始,每次逐渐增加1的顺序来被调用. 即先调用f(0),再f(1),f(2),f(3)... 以此类推. * 该函数会将参数从0开始,每次逐渐增加1的顺序来被调用. 即先调用f(0),再f(1),f(2),f(3)... 以此类推.
*/ */
void display(std::function<uint8_t(int)> f, uint8_t part = READGUY_FAST); void display(std::function<uint8_t(int)> f, uint8_t part);
/// @brief 显示图片, 使用抖动算法. 可以用省内存的方法显示, 可以缩放到指定的宽度和高度 /// @brief 显示图片, 使用抖动算法. 可以用省内存的方法显示, 可以缩放到指定的宽度和高度
void drawImage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint16_t zoomw=0, uint16_t zoomh=0){ 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); if(READGUY_cali==127) drawImage(*this,spr,x,y,zoomw,zoomh);
@@ -337,14 +338,18 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
static uint8_t rd_btn_f(uint8_t btn); static uint8_t rd_btn_f(uint8_t btn);
uint8_t getBtn_impl(); //按钮不可用, 返回0. uint8_t getBtn_impl(); //按钮不可用, 返回0.
static void in_press(){ //SPI开始传输屏幕数据 static void in_press(){ //SPI开始传输屏幕数据
#ifndef ESP8266 #ifdef ESP8266
if(!spibz) SPI.beginTransaction(SPISettings(ESP8266_SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
#else
if(!spibz) epd_spi->beginTransaction(SPISettings(ESP32_DISP_FREQUENCY, MSBFIRST, SPI_MODE0)); if(!spibz) epd_spi->beginTransaction(SPISettings(ESP32_DISP_FREQUENCY, MSBFIRST, SPI_MODE0));
#endif #endif
spibz ++; spibz ++;
} }
static void in_release(){//SPI结束传输屏幕数据 static void in_release(){//SPI结束传输屏幕数据
spibz --; spibz --;
#ifndef ESP8266 #ifdef ESP8266
if(!spibz) SPI.endTransaction();
#else
if(!spibz) epd_spi->endTransaction(); if(!spibz) epd_spi->endTransaction();
#endif #endif
} }
@@ -377,8 +382,8 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
//constexpr int memHeight () const { return guy_height ; } //返回显存高度(不是画幅高度),不会随着画布旋转改变 //constexpr int memHeight () const { return guy_height ; } //返回显存高度(不是画幅高度),不会随着画布旋转改变
int drvWidth () const { return READGUY_cali==127?guy_dev->drv_width():0; } //返回显示屏硬件宽度(不是画幅宽度) 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 drvHeight() const { return READGUY_cali==127?guy_dev->drv_height():0; } //返回显示屏硬件高度(不是画幅高度)
int width () const { return (getRotation()&1)?drvHeight():drvWidth(); } //int width () const { return (getRotation()&1)?drvHeight():drvWidth(); }
int height() const { return (getRotation()&1)?drvWidth():drvHeight(); } //int height() const { return (getRotation()&1)?drvWidth():drvHeight(); }
// private: // private:
void implBeginTransfer() { guy_dev->BeginTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!! void implBeginTransfer() { guy_dev->BeginTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
void implEndTransfer() { guy_dev->EndTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!! void implEndTransfer() { guy_dev->EndTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!