7 Commits
1.4.0 ... 1.5.0

Author SHA1 Message Date
fsender
f1a61272a9 1.5.0 rewrite several (Pre 2.0 update) 2025-04-07 16:46:04 +08:00
fsender
b8b74b2b8d fix configuring 154B bugs 2025-03-23 14:01:06 +08:00
fsender
25b9e62f5f feat: initialize epd with custom slow-refresh 2025-03-13 08:36:29 +08:00
fsender
86e1022ffa feat: new device pre-support 2025-03-13 00:04:09 +08:00
fsender
20ba78ea52 1.4.2: fix build for arduino-esp32 3.x 2025-03-11 18:36:59 +08:00
fsender
247e5e0b94 update api for arduino-esp32 3.x 2025-03-08 05:14:09 +08:00
fsender
02174694d2 fix: can't run when disable DYNAMIC_PIN_SETTINGS 2024-12-02 22:00:54 +08:00
31 changed files with 767 additions and 254 deletions

View File

@@ -1,3 +1,29 @@
# 1.5.0
## Release 1.5.0 - 2025/4/7
1. 重构较多代码, 为2.0做准备. 现在可以通过包含文件来自定义配置了
2. 修复bug
## Release 1.4.3 - 2025/4/3
1. 加入了更多可选配置项, 如 AP 配网地址等
2. 为ESP32S3优先选择调用 SDIO_1Bit 来驱动SD卡
4. 修复bug
## Release 1.4.2 - 2025/3/11
1. 现在程序可以在Arduino-ESP32的版本高于3.0.0的Arduino集成环境和ESP-IDF (仍需依赖Arduino component, 但不依赖PlatformIO) 中编译成功
2. 示例程序中添加了更多的说明文本
## Release 1.4.1 - 2024/12/2
1. 紧急修复了在禁用 `DYNAMIC_PIN_SETTINGS` 之后点不亮屏幕的bug
## Release 1.4.0 - 2024/12/1
### 新增内容

46
CMakeLists.txt Normal file
View File

@@ -0,0 +1,46 @@
# Esp-idf component requires this file.
# Even Arduino IDE will ignore it.
file(GLOB READGUY_SRCS
src/*.cpp
src/guy_epaper/*.cpp
src/guy_epaper/guy_154a_290a/*.cpp
src/guy_epaper/guy_154b_270b_290b/*.cpp
src/guy_epaper/guy_154C/*.cpp
src/guy_epaper/guy_213a/*.cpp
src/guy_epaper/guy_213b_266a/*.cpp
src/guy_epaper/guy_370a/*.cpp
src/guy_epaper/guy_370B/*.cpp
src/guy_epaper/guy_420a/*.cpp
src/guy_epaper/guy_420b/*.cpp
src/guy_epaper/guy_426A/*.cpp
src/guy_epaper/guy_583A/*.cpp
src/guy_epaper/guy_583B/*.cpp
src/guy_epaper/guy_750A/*.cpp
src/guy_epaper/guy_1020A/*.cpp
src/guy_epaper/lcdDebug/*.cpp
)
set(READGUY_DIRS
src
src/guy_epaper
src/guy_epaper/guy_154a_290a
src/guy_epaper/guy_154b_270b_290b
src/guy_epaper/guy_154C
src/guy_epaper/guy_213a
src/guy_epaper/guy_213b_266a
src/guy_epaper/guy_370a
src/guy_epaper/guy_370B
src/guy_epaper/guy_420a
src/guy_epaper/guy_420b
src/guy_epaper/guy_426A
src/guy_epaper/guy_583A
src/guy_epaper/guy_583B
src/guy_epaper/guy_750A
src/guy_epaper/guy_1020A
src/guy_epaper/lcdDebug
../arduino-esp32/libraries/HTTPUpdateServer/src
)
idf_component_register(SRCS ${READGUY_SRCS}
INCLUDE_DIRS "." ${READGUY_DIRS}
REQUIRES arduino-esp32 LovyanGFX spi_flash
)
#spi flash for read chip

View File

@@ -2,27 +2,48 @@
[![arduino-library-badge](https://www.ardu-badge.com/badge/readguy.svg?)](https://www.ardu-badge.com/readguy)
<img src="extra/artset/readguy_theme3.png" width="30%" height="auto">
## ReadGuy 2.0 预告
**版本1.4,0正式发布欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
1. 内置驱动,无其他 不跨平台 多平台
2. 自定义脚本驱动 不跨平台 多平台
3. 内置 不自定义 带脚本 跨平台 数据存eeprom或者nvs. 支持从文件系统加载
4. 文件系统接口优化
5. 灰度显示优化
6. 按键逻辑优化: 双按键:按键1点按下一个 长按上一个 长按过程中点按2则功能5 按键2点按确定 长按取消
三按键 左键点按松开时候结算: 上一个, 左键长按也是上一个 右键点按长按都是下一个 按住左键按中间功能5 中键点按确定 长按取消
7. 支持pre_init post_init 等设备限定的脚本,在初始化设备时和设备休眠时都可以执行类似功能. 此外readguy2.0的二进制是兼容1.x的
8. 摒弃默认刷屏方式使用dispWriter函数 速度太慢, 改为使用两种示例, 正常读取显示和函数读取显示都支持调用
敬请期待
<img src="https://github.com/fsender/readguy/blob/1.4.2/extra/artset/readguy_theme3.png?raw=true" width="30%" height="auto">
**版本1.5.0正式发布欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
**即将发布7个全新的屏幕驱动: 欢迎支持! (详见后面的驱动表格)**
欢迎克隆, 项目交流QQ群: 926824162 (萌新可以进来问问题的哟), 项目的 Bilibili 主页: [BV1f94y187wz](https://www.bilibili.com/video/BV1f94y187wz/) 记得三连+关注我这个宝藏up主哦~
注意, 有问题一定要先加群问, 先不要提issue, 提了小影 *(也就是作者FriendshipEnder)* 也不会看的.
注意, 有问题一定要先加群问, 先不要提issue, 提了作者 FriendshipEnder 也不会看的.
**依赖的库: [LovyanGFX](https://github.com/lovyan03/LovyanGFX)**
*依赖的环境: Arduino-ESP8266 或者 Arduino-ESP32.*
*依赖的环境: Arduino-ESP8266 或者 Arduino-ESP32. 现已支持使用最新版本的Arduino-ESP32库(2.x和3.x)编译!*
## 在**所有**受支持屏幕上都显示**16级灰度**内容!
### 一次编译即可使程序兼容多种屏幕!
<img src="extra/artset/readguy_girl.png" width="25%" height="auto">
<img src="https://github.com/fsender/readguy/blob/1.4.2/extra/artset/readguy_girl.png?raw=true" width="25%" height="auto">
<img src="extra/artset/view.jpg" width="auto" height="auto">
<img src="https://github.com/fsender/readguy/blob/1.4.2/extra/artset/view.jpg?raw=true" width="auto" height="auto">
#### 目前支持ESP芯片平台、多种屏幕型号、13个按钮操控、SD卡、前置光亮度控制
@@ -111,6 +132,24 @@ Light-brightness-control is optional.
8. sd卡固件更新/切换
---
## 配置方法-使用网页配网配置引脚
1. 首次烧录完成后, 按下板子的复位按键.
2. 打开手机或者电脑的WiFi, 然后找到名称为 `readguy` 的网络, 连接. 密码为12345678.
3. 连接完成后, 打开该手机的浏览器, 访问192.168.4.1 如果手机提示该网络无法访问因特网, 则选择保持连接.
4. 加载完成之后, 根据你的硬件配置引脚. 网页会提供输入各个引脚的输入框, 根据自己的硬件情况输入引脚即可. 如果你正在使用甘草和半糖的开发板, 点击最上方的自定义线序, 可以快捷设置引脚.
5. 点击下方的OK!来确定配置, 直到屏幕闪烁并显示〝口口口口〞后, 即可进入下一步
6. 根据网页的按键说明提示, 依次按下按键, 直到屏幕刷新出4位数字验证码后, 将验证码填写到网页上, 最后点击确定!即可完成配置.
7. 如果刚才的引脚配置有误 (如按下按键无响应, 或者屏幕不显示), 则需要从该步骤的第一步重新开始.
## 使用方法-按钮操控方式:
1. 烧录成功后即刻出现一个wifi热点“readguy”wifi密码为12345678
@@ -131,23 +170,23 @@ Light-brightness-control is optional.
5. 双按键操作说明:
按键1单击向右移动
- 按键1单击向右移动
按键1长按向左移动
- 按键1长按向左移动
按键2单击确定
- 按键2单击确定
按键2长按半秒界面内返回键盘输入状态下可以快速切换英文大小写
- 按键2长按半秒界面内返回键盘输入状态下可以快速切换英文大小写
6. 三按键操作说明:(只不过, GUI功能还在研发编写中...)
按键1向左/向上,
- 按键1向左/向上,
按键2单击确定
- 按键2单击确定
按键3向右/向下。
- 按键3向右/向下。
按键2长按半秒界面内返回键盘输入状态下可以快速切换英文大小写
- 按键2长按半秒界面内返回键盘输入状态下可以快速切换英文大小写
7. 关于菜单控件: 在菜单模式下若处于最后一个菜单选项,再按 向右/向下 功能键则会进入滑动条(选择菜单选项).
@@ -209,7 +248,7 @@ firmware.bin 0x10000
5. 编译目标是`ESP32`且使用`ESP-IDF arduino component`时, 需要单独安装[`LittleFS`](https://github.com/joltwallet/esp_littlefs)库来实现相关功能. 在项目内新建文件夹`components`, 在`components`文件夹内放入刚刚克隆的`LittleFS`库. *详见下图**上**方红框*. (使用纯arduino时跳过此步骤)
<img src="extra/artset/build_dir_structure.png" width="20%" height="auto">
<img src="https://github.com/fsender/readguy/blob/1.4.2/extra/artset/build_dir_structure.png?raw=true" width="20%" height="auto">
6.`readguy``extra`文件夹内的`platformio`文件夹内所有文件都放在当前目录. 这些文件包含推荐的ESP32 sdkconfig, flash分区表等文件. 使用`pio run -t menuconfig`可以更改项目的menuconfig数据. (使用纯arduino时跳过此步骤)

View File

@@ -199,7 +199,7 @@ void setup(){
//使用guy.guyFS()函数返回可用的文件系统. 默认为SD卡. 当SD卡不可用时, 自动切换到内置的LittleFS.
//显示打开的图片信息(宽度和高度), 和剩余内存
Serial.printf("[%lu] sp.w: %d, h: %d, res: %d.\n",millis(),sp.width(),sp.height(),guy.getFreeMem());
Serial.printf("[%lu] sp.w: %d, h: %d, res: %d.\n",millis(),(int)sp.width(),(int)sp.height(),guy.getFreeMem());
guy.drawImage(sp,10,10); //使用抖动像素的方式显示图片(不是灰度, 只有黑点和白点的那种显示效果)

View File

@@ -39,7 +39,7 @@
#ifdef __cplusplus
extern "C" {
#endif
const PROGMEM uint8_t ctg_u8g2_wqy12_chinese1[14241]=
const PROGMEM uint8_t ctg_u8g2_wqy12_chinese1[14241]= {
"\233\0\4\2\5\5\3\5\6\22\22\376\374\13\375\14\374\1\351\3\364\5\310 \6\0\60\242\0!\10\301"
"\375\241\360 \42\42\11\304\270\242\20\361I\0#\34\210\21\242\23\11EB\221\310`\20)\212\204\42\241"
"Hd\60\210\24EB\221\14\0$\32\247\361\241\23\32(\42\21ID\22J\244V\211PD\22\221T"
@@ -485,9 +485,10 @@ const PROGMEM uint8_t ctg_u8g2_wqy12_chinese1[14241]=
"\61\17\322\301\23\317\14\6\212\262Tb\23Kd\6\203H\42\223J\14\6\222\302HQ&\322\242I\213"
"&-\272I\204\62\211\134\246H\223J\210r\1\237 \60\15\332\301\223\34\15\42\311\310 \63\210$#"
"\311\310\340@\17HD\22\221\26\221D$T\222\210$\42-\42\211\204\250B\21Id\6\31U\0\0"
"";
""
};
const PROGMEM uint8_t ctg_u8g2_wqy12_gb2312[208522]=
const PROGMEM uint8_t ctg_u8g2_wqy12_gb2312[208522]= {
"s\0\3\2\4\4\5\5\5\15\15\0\376\10\376\12\377\1m\2\347\5\23 \5\0\60Z!\7\221\22"
"Z\234\2\42\10\64\361ZD\246\0#\17\226\20\336D-\303\22\365\62,Q\13\0$\17\245\360Ye"
"KE\311D-Q*[\4%\21\226\360\331DI\27-\11\323$J\272h\11\0&\16\205\20Ze"
@@ -7004,8 +7005,10 @@ const PROGMEM uint8_t ctg_u8g2_wqy12_gb2312[208522]=
"\13\377\134\10\261\366q<\10\377]\15\303\362qdQ[\22u\211\0\377^\14<p\362\355\200f\7"
"\26\0\377\340\23\227\22\362fCT\321\242Z\224%Y\42U$\0\377\341\26\252\21\362\352@\24\347P"
"\16\245\303\220\3\361*M\221&\1\377\343\7\34Ps|\377\345\26\251\21rlK\232\325\206!L\302"
"aHs$Gr`\3\0";
const PROGMEM uint8_t ctg_u8g2_wqy12[626234]=
"aHs$Gr`\3\0"
};
const PROGMEM uint8_t ctg_u8g2_wqy12[626234]= {
"\324\0\3\3\4\4\5\5\5\15\15\0\376\10\376\12\377\1w\2\370\5$ \5\0\60Z!\7\221\22"
"Z\230\2\42\10\64\361Z\204\224\2#\16\226\20\336\204\262XBy\261\204\262\0$\21\245\360Y\305&"
")\222\230P\26\221\244\314B\0%\22\226\360\331\204\42\271\310\42\301h$\24\311E\26\1&\20\205\20"
@@ -26575,7 +26578,9 @@ const PROGMEM uint8_t ctg_u8g2_wqy12[626234]=
"\377[\15\303\367qEBYb\241\334\2\377\134\10\261\366q\34\10\377]\16\303\362q\304B\331\42\241"
"\134B\0\377^\15<p\362\315\1\62u\300\4\0\377\340\24\227\22\362\306H)\262PZ(\26\211E"
"D)\42\0\377\341\27\252\21\362\312\1\241p\34\24\7E\357\200\360T\64\12\311D\0\377\343\10\34P"
"s\34\12\377\345\25\251\21r\314&\321X\332\61\22\274\306!qH\34\60\3\0";
"s\34\12\377\345\25\251\21r\314&\321X\332\61\22\274\306!qH\34\60\3\0"
};
#ifdef __cplusplus
}
#endif /* END OF FILE. ReadGuy project.

View File

@@ -55,9 +55,9 @@
ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动.
extern const uint8_t ctg_u8g2_wqy12_chinese1[]; //声明中文字体文件
extern const uint8_t ctg_u8g2_wqy12_gb2312[]; //声明中文字体文件
const lgfx::U8g2font cn_font(ctg_u8g2_wqy12_chinese1); //U8G2格式中文字体转化为LGFX格式字体
const lgfx::U8g2font cn_font(ctg_u8g2_wqy12_gb2312); //U8G2格式中文字体转化为LGFX格式字体
void setup(){
@@ -69,7 +69,7 @@ void setup(){
guy.setCursor(10,10);
guy.print("中文");
guy.print("你好, 中文");
guy.display();
}

View File

@@ -39,7 +39,7 @@
#ifdef __cplusplus
extern "C" {
#endif
const PROGMEM uint8_t ctg_u8g2_wqy12_chinese1[14241]=
const PROGMEM uint8_t ctg_u8g2_wqy12_chinese1[14241]= {
"\233\0\4\2\5\5\3\5\6\22\22\376\374\13\375\14\374\1\351\3\364\5\310 \6\0\60\242\0!\10\301"
"\375\241\360 \42\42\11\304\270\242\20\361I\0#\34\210\21\242\23\11EB\221\310`\20)\212\204\42\241"
"Hd\60\210\24EB\221\14\0$\32\247\361\241\23\32(\42\21ID\22J\244V\211PD\22\221T"
@@ -485,9 +485,10 @@ const PROGMEM uint8_t ctg_u8g2_wqy12_chinese1[14241]=
"\61\17\322\301\23\317\14\6\212\262Tb\23Kd\6\203H\42\223J\14\6\222\302HQ&\322\242I\213"
"&-\272I\204\62\211\134\246H\223J\210r\1\237 \60\15\332\301\223\34\15\42\311\310 \63\210$#"
"\311\310\340@\17HD\22\221\26\221D$T\222\210$\42-\42\211\204\250B\21Id\6\31U\0\0"
"";
""
};
const PROGMEM uint8_t ctg_u8g2_wqy12_gb2312[208522]=
const PROGMEM uint8_t ctg_u8g2_wqy12_gb2312[208522]= {
"s\0\3\2\4\4\5\5\5\15\15\0\376\10\376\12\377\1m\2\347\5\23 \5\0\60Z!\7\221\22"
"Z\234\2\42\10\64\361ZD\246\0#\17\226\20\336D-\303\22\365\62,Q\13\0$\17\245\360Ye"
"KE\311D-Q*[\4%\21\226\360\331DI\27-\11\323$J\272h\11\0&\16\205\20Ze"
@@ -7004,8 +7005,10 @@ const PROGMEM uint8_t ctg_u8g2_wqy12_gb2312[208522]=
"\13\377\134\10\261\366q<\10\377]\15\303\362qdQ[\22u\211\0\377^\14<p\362\355\200f\7"
"\26\0\377\340\23\227\22\362fCT\321\242Z\224%Y\42U$\0\377\341\26\252\21\362\352@\24\347P"
"\16\245\303\220\3\361*M\221&\1\377\343\7\34Ps|\377\345\26\251\21rlK\232\325\206!L\302"
"aHs$Gr`\3\0";
const PROGMEM uint8_t ctg_u8g2_wqy12[626234]=
"aHs$Gr`\3\0"
};
const PROGMEM uint8_t ctg_u8g2_wqy12[626234]= {
"\324\0\3\3\4\4\5\5\5\15\15\0\376\10\376\12\377\1w\2\370\5$ \5\0\60Z!\7\221\22"
"Z\230\2\42\10\64\361Z\204\224\2#\16\226\20\336\204\262XBy\261\204\262\0$\21\245\360Y\305&"
")\222\230P\26\221\244\314B\0%\22\226\360\331\204\42\271\310\42\301h$\24\311E\26\1&\20\205\20"
@@ -26575,7 +26578,9 @@ const PROGMEM uint8_t ctg_u8g2_wqy12[626234]=
"\377[\15\303\367qEBYb\241\334\2\377\134\10\261\366q\34\10\377]\16\303\362q\304B\331\42\241"
"\134B\0\377^\15<p\362\315\1\62u\300\4\0\377\340\24\227\22\362\306H)\262PZ(\26\211E"
"D)\42\0\377\341\27\252\21\362\312\1\241p\34\24\7E\357\200\360T\64\12\311D\0\377\343\10\34P"
"s\34\12\377\345\25\251\21r\314&\321X\332\61\22\274\306!qH\34\60\3\0";
"s\34\12\377\345\25\251\21r\314&\321X\332\61\22\274\306!qH\34\60\3\0"
};
#ifdef __cplusplus
}
#endif /* END OF FILE. ReadGuy project.

View File

@@ -8,9 +8,43 @@
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @version 1.0
* @date create: 2023-11-01
* last modify: 2023-11-06
* @brief ReadGuy 图片显示功能演示.
* last modify: 2024-12-04
*
* @note 重要消息: 这是一个实验性功能. 可能你所使用的LGFX库版本较旧而无法通过编译.
*
* (ESPxxxx系列可无视此行) 对于不支持fs::FS的设备 (如PC) 来说, 请前往 guy_image.h 文件并更改第34行的注释
*
* 如果你的项目中无法成功编译源码中的setBuffer, 请更改LovyanGFX库的函数!
* 位于文件 LovyanGFX/src/lgfx/v1/LGFX_Sprite.hpp
* 第155行 void setBuffer 函数:
* 添加为如下内容并保存 (不建议修改库里原有的函数, 保证库的兼容性)
*
``` C++
void setBuffer(void* buffer, int32_t w, int32_t h, color_depth_t bpp)
{
deleteSprite();
if (bpp != 0) {
_write_conv.setColorDepth(bpp);
_read_conv = _write_conv;
_panel_sprite.setColorDepth(bpp);
}
_panel_sprite.setBuffer(buffer, w, h, &_write_conv);
_img = _panel_sprite.getBuffer();
_sw = w;
_clip_r = w - 1;
_xpivot = w >> 1;
_sh = h;
_clip_b = h - 1;
_ypivot = h >> 1;
}
```
* 完成后请再次尝试编译
* [已经向lovyan03/LovyanGFX发布issue, 等待解决]
*
* @brief ReadGuy 图片显示功能演示.
* - 演示如何将比较大的图片通过多种方法显示到屏幕上.
* - 运行的会很缓慢, 因为示例的图片文件比较大.
* 1. 在运行过ex01或者ex02的开发板上 编译烧录本程序.
@@ -106,37 +140,6 @@
* 为了简化程序调用过程并提高调用速度, 此处的像素坐标位置参数为一个整数(而不是两个)
* 至于该怎么调用这个函数, 并不是你需要了解的事情.
*
* @note 重要消息: 这是一个实验性功能. 可能你所使用的LGFX库版本较旧而无法通过编译.
* 如果你的项目中无法成功编译源码中的setBuffer, 请更改LovyanGFX库的函数!
* 位于文件 LovyanGFX/src/lgfx/v1/LGFX_Sprite.hpp
* 第155行 void setBuffer 函数:
* 修改为如下内容并保存
*
``` C++
void setBuffer(void* buffer, int32_t w, int32_t h, color_depth_t bpp = rgb565_2Byte)
{
deleteSprite();
if (bpp != 0) {
_write_conv.setColorDepth(bpp);
_read_conv = _write_conv;
_panel_sprite.setColorDepth(bpp);
}
_panel_sprite.setBuffer(buffer, w, h, &_write_conv);
_img = _panel_sprite.getBuffer();
_sw = w;
_clip_r = w - 1;
_xpivot = w >> 1;
_sh = h;
_clip_b = h - 1;
_ypivot = h >> 1;
}
```
* 完成后请再次尝试编译
* [已经向lovyan03/LovyanGFX发布issue, 等待解决]
*
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
@@ -263,7 +266,9 @@ void setup(){
readguyImage im(guy); //定义一个绘制器, 此类中的函数用于绘制图片.
//所有的绘制图片的参数均需要放入此结构内
//直接更改im内的数据即可设置绘制参数. (就像结构体一样用它)
#ifdef FS_POINTER //对于不支持fs::FS的设备来说, 请前往 guy_image.h 文件并更改第34行的注释
im.baseFs=&guy.guyFS(); //在此处就是设置文件系统.
#endif
im.filename=BMP_FILE; //在此直接设置文件路径和文件名.

View File

@@ -9,6 +9,40 @@
* @version 1.0
* @date 2023-11-01
* @note 重要消息: 这是一个实验性功能. 可能你所使用的LGFX库版本较旧而无法通过编译.
*
* (ESPxxxx系列可无视此行) 对于不支持fs::FS的设备 (如PC) 来说, 请前往 guy_image.h 文件并更改第34行的注释
*
* 如果你的项目中无法成功编译源码中的setBuffer, 请更改LovyanGFX库的函数!
* 位于文件 LovyanGFX/src/lgfx/v1/LGFX_Sprite.hpp
* 第155行 void setBuffer 函数:
* 添加为如下内容并保存 (不建议修改库里原有的函数, 保证库的兼容性)
*
``` C++
void setBuffer(void* buffer, int32_t w, int32_t h, color_depth_t bpp)
{
deleteSprite();
if (bpp != 0) {
_write_conv.setColorDepth(bpp);
_read_conv = _write_conv;
_panel_sprite.setColorDepth(bpp);
}
_panel_sprite.setBuffer(buffer, w, h, &_write_conv);
_img = _panel_sprite.getBuffer();
_sw = w;
_clip_r = w - 1;
_xpivot = w >> 1;
_sh = h;
_clip_b = h - 1;
_ypivot = h >> 1;
}
```
* 完成后请再次尝试编译
* [已经向lovyan03/LovyanGFX发布issue, 等待解决]
*
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
@@ -78,15 +112,33 @@ uint8_t readguyImage::drawImgHandler(int r, LGFX_Sprite *spr){
spr->setRotation(rot);
switch(format&3){
case 1:
spr->drawBmpFile(*baseFs,filename,_x,_y,0,0,offsetx+xd,offsety+yd,scalex,scaley,datum);
spr->drawBmpFile(
#ifdef FS_POINTER
*baseFs
#else
guy->guyFS()
#endif
,filename,_x,_y,0,0,offsetx+xd,offsety+yd,scalex,scaley,datum);
break;
#ifndef ESP8266
case 2:
spr->drawPngFile(*baseFs,filename,_x,_y,0,0,offsetx+xd,offsety+yd,scalex,scaley,datum);
spr->drawPngFile(
#ifdef FS_POINTER
*baseFs
#else
guy->guyFS()
#endif
,filename,_x,_y,0,0,offsetx+xd,offsety+yd,scalex,scaley,datum);
break;
#endif
case 3:
spr->drawJpgFile(*baseFs,filename,_x,_y,0,0,offsetx+xd,offsety+yd,scalex,scaley,datum);
spr->drawJpgFile(
#ifdef FS_POINTER
*baseFs
#else
guy->guyFS()
#endif
,filename,_x,_y,0,0,offsetx+xd,offsety+yd,scalex,scaley,datum);
break;
}
spr->setRotation(0);
@@ -219,7 +271,11 @@ uint8_t readguyImage::getExName(const char* fname, char* exname, size_t exname_l
/// @brief 显示图像
void readguyImage::drawImageFile(bool use16grey){
if(filename == nullptr || filename[0] == 0 || !(baseFs->exists(filename))) return; //文件不存在
if(filename == nullptr || filename[0] == 0
#ifdef FS_POINTER
|| !(baseFs->exists(filename))
#endif
) return; //文件不存在
char ex[8]; //保存文件的扩展名
getExName(filename,ex,7); //获取文件的扩展名.最后一个参数用于防止数组越界
format = 0; //16灰度模式
@@ -243,6 +299,7 @@ void readguyImage::drawImageFile(bool use16grey){
LGFX_Sprite bmpspr;
//首先, 需要获取到内部显存的地址, 用于建立图片分块绘制缓存.
//获取屏幕缓存, 随后分配图片解码所需的内存.
//此处如果出现 convert from `lgfx::v1::color_depth_t` to `uint8_t` 警告(或错误) 请查看本文开头重要消息
bmpspr.setBuffer(_pool,w,_h,lgfx::v1::color_depth_t::grayscale_8bit);
//bmpspr.createSprite(guy_width,(guy_height+7)&0x7ffffff8);
@@ -286,7 +343,11 @@ void readguyImage::drawImageFile(bool use16grey){
}
uint8_t readguyImage::drawImageToBuffer(){
if(filename == nullptr || filename[0] == 0 || !(baseFs->exists(filename))) return 1; //文件不存在
if(filename == nullptr || filename[0] == 0
#ifdef FS_POINTER
|| !(baseFs->exists(filename))
#endif
) return 1; //文件不存在
if( w==0 || h==0 || w>=0x8000 || h>=0x8000 || exPool==nullptr || exPoolSize<1024) return 3; //内存不足
char ex[8]; //保存文件的扩展名
format = 0; //16灰度模式
@@ -309,20 +370,39 @@ uint8_t readguyImage::drawImageToBuffer(){
if(_h==0 || GUY_STAGES>8) return 3; //内存不足以在显示8次之内就... 总之就是内存不够
LGFX_Sprite spr;
//此处如果出现 convert from `lgfx::v1::color_depth_t` to `uint8_t` 警告(或错误) 请查看本文开头重要消息
spr.setBuffer(_pool,w,_h,lgfx::v1::color_depth_t::grayscale_8bit);
for(int i=0;i<GUY_STAGES;i++){
spr.fillScreen(background?0xffff:0);
switch(format&3){
case 1:
spr.drawBmpFile(*baseFs,filename,0,0,0,0,offsetx,offsety+_h*i,scalex,scaley);
spr.drawBmpFile(
#ifdef FS_POINTER
*baseFs
#else
guy->guyFS()
#endif
,filename,0,0,0,0,offsetx,offsety+_h*i,scalex,scaley);
break;
#ifndef ESP8266
case 2:
spr.drawPngFile(*baseFs,filename,0,0,0,0,offsetx,offsety+_h*i,scalex,scaley);
spr.drawPngFile(
#ifdef FS_POINTER
*baseFs
#else
guy->guyFS()
#endif
,filename,0,0,0,0,offsetx,offsety+_h*i,scalex,scaley);
break;
#endif
case 3:
spr.drawJpgFile(*baseFs,filename,0,0,0,0,offsetx,offsety+_h*i,scalex,scaley);
spr.drawJpgFile(
#ifdef FS_POINTER
*baseFs
#else
guy->guyFS()
#endif
,filename,0,0,0,0,offsetx,offsety+_h*i,scalex,scaley);
break;
}
guy->drawImageStage(spr,x,y+_h*i,i,GUY_STAGES);

View File

@@ -9,6 +9,40 @@
* @version 1.0
* @date 2023-11-01
* @note 重要消息: 这是一个实验性功能. 可能你所使用的LGFX库版本较旧而无法通过编译.
*
* (ESPxxxx系列可无视此行) 对于不支持fs::FS的设备 (如PC) 来说, 请前往 guy_image.h 文件并更改第34行的注释
*
* 如果你的项目中无法成功编译源码中的setBuffer, 请更改LovyanGFX库的函数!
* 位于文件 LovyanGFX/src/lgfx/v1/LGFX_Sprite.hpp
* 第155行 void setBuffer 函数:
* 添加为如下内容并保存 (不建议修改库里原有的函数, 保证库的兼容性)
*
``` C++
void setBuffer(void* buffer, int32_t w, int32_t h, color_depth_t bpp)
{
deleteSprite();
if (bpp != 0) {
_write_conv.setColorDepth(bpp);
_read_conv = _write_conv;
_panel_sprite.setColorDepth(bpp);
}
_panel_sprite.setBuffer(buffer, w, h, &_write_conv);
_img = _panel_sprite.getBuffer();
_sw = w;
_clip_r = w - 1;
_xpivot = w >> 1;
_sh = h;
_clip_b = h - 1;
_ypivot = h >> 1;
}
```
* 完成后请再次尝试编译
* [已经向lovyan03/LovyanGFX发布issue, 等待解决]
*
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
@@ -30,15 +64,11 @@
#ifndef _GUY_IMAGE_H_FILE
#define _GUY_IMAGE_H_FILE
#define FS_POINTER //如果你的系统不是ESP系列, 没有FS.h文件也没有File类则注释掉它
#include <Arduino.h>
#include <SPI.h>
#include <FS.h>
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include "readguy.h"
class readguyImage{
public:
readguyImage(ReadguyDriver &_guy):guy(&_guy){
@@ -67,7 +97,9 @@ class readguyImage{
/// @brief 获取文件的扩展名.
static uint8_t getExName(const char* fname, char* exname, size_t exname_len);
#ifdef FS_POINTER
fs::FS *baseFs = nullptr;/// // / //要绘制的图片所属的文件系统
#endif
const char *filename = nullptr; // / //要绘制的图片的文件名和文件路径
int32_t x = 0; //// // / //绘制位置坐标X
int32_t y = 0; //// // / //绘制位置坐标Y

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 KiB

View File

@@ -11,7 +11,7 @@
"type": "git",
"url": "https://github.com/fsender/readguy"
},
"version": "1.4.0",
"version": "1.5.0",
"frameworks": "arduino",
"platforms": ["espressif32", "espressif8266"],
"headers": "readguy.h",

View File

@@ -1,5 +1,5 @@
name=readguy
version=1.4.0
version=1.5.0
author=fsender <f_ender@163.com>
maintainer=fsender <f_ender@163.com>
sentence=A free E-paper display driver library supports 16-level greyscale.

View File

@@ -59,7 +59,7 @@ SOFTWARE.
*/
#include "guy_button.h"
#include "guy_driver_config.h"
#include "guy_config_host.h"
// initalize static counter

View File

@@ -63,10 +63,6 @@ SOFTWARE.
#include "Arduino.h"
#include <stdint.h>
#if defined(ARDUINO_ARCH_ESP32) || defined(ESP8266)
#include <functional>
#endif
#include <Arduino.h>
/////////////////////////////////////////////////////////////////

View File

@@ -3,14 +3,15 @@
* extra/artset/reward , Bilibili .
* QQ群: 926824162 ()
* : .
* @file guy_epaper_config.h
* @file guy_config_host.h
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief EPD驱动基础配置文件. .
* @brief readguy . guy_driver_config.h
* @version 1.0
* @date 2023-09-21
* @date create: 2025/4/7
* last modify: 2025/4/7
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
* Copyright (c) 2022-2025 FriendshipEnder
*
* Apache License, Version 2.0
*
@@ -26,20 +27,113 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _READGUY_CONFIG_HOST_H_FILE
#define _READGUY_CONFIG_HOST_H_FILE
#ifndef _GUY_E_PAPER_CONFIG_H_FILE
#define _GUY_E_PAPER_CONFIG_H_FILE
#if __has_include("readguy_user_config.h")
#undef DYNAMIC_PIN_SETTINGS
#undef READGUY_NVS_PROJECTNAME
#undef READGUY_NVS_CONFIGKEY
#undef READGUY_NVS_DRIVERKEY
#undef READGUY_ENABLE_WIFI
#undef READGUY_ESP_ENABLE_WIFI
#undef READGUY_CONF_AP_SSID
#undef READGUY_CONF_AP_PASS
#undef READGUY_USE_DEFAULT_ICON
#undef READGUY_MDNS_SERVICE
#undef READGUY_UPDATE_SERVER
#undef READGUY_ENABLE_I2C
#undef READGUY_ENABLE_SD
#undef READGUY_USE_LITTLEFS
#undef READGUY_ESP8266_EEPROM_OFFSET
#undef READGUY_ALLOW_DC_AS_BUTTON
#undef READGUY_ALLOW_EPDCS_AS_BUTTON
#undef READGUY_ALLOW_SDCS_AS_BUTTON
#undef READGUY_DEFAULT_MIN_DEBOUNCE_MS
#undef READGUY_LONG_PRESS_MS
#undef READGUY_DOUBLE_PRESS_MS
#undef READGUY_LONG_REPEAT_MS
#undef BTN_LOOPTASK_STACK
#undef BTN_LOOPTASK_CORE_ID
#undef BTN_LOOPTASK_PRIORITY
#undef BTN_LOOPTASK_DELAY
#undef ESP8266_SPI_FREQUENCY
#undef ESP32_DISP_FREQUENCY
#undef ESP32_SD_SPI_FREQUENCY
#undef ESP32_SD_MMC_FREQUENCY
#undef READGUY_SERIAL_DEBUG
#undef READGUY_shareSpi
#undef READGUY_epd_type
#undef READGUY_epd_mosi
#undef READGUY_epd_sclk
#undef READGUY_epd_cs
#undef READGUY_epd_dc
#undef READGUY_epd_rst
#undef READGUY_epd_busy
#undef READGUY_sd_miso
#undef READGUY_sd_mosi
#undef READGUY_sd_sclk
#undef READGUY_sd_cs
#undef READGUY_i2c_sda
#undef READGUY_i2c_scl
#undef READGUY_btn1
#undef READGUY_btn2
#undef READGUY_btn3
#undef READGUY_bl_pin
#undef READGUY_user1
#undef READGUY_user2
#undef READGUY_user3
#undef READGUY_user4
#undef READGUY_user5
#undef READGUY_user6
#undef READGUY_user7
#undef READGUY_user8
#undef READGUY_user9
#undef READGUY_user10
#undef READGUY_rtc_type
#undef MEPD_DEBUG_WAVE
#undef MEPD_DEBUG_WAITTIME
#undef FLOYD_STEINBERG_DITHERING
#undef FLOYD_DITHERING_16GREY
#undef READGUY_583A_DUAL_BUFFER
#include "readguy_user_config.h"
#else
#include "guy_driver_config.h"
#endif
#ifdef ESP8266 //应用于
#define _READGUY_PLATFORM "ESP8266"
//#define READGUY_IDF_TARGET_WITHOUT_FSPI //该器件不能使用fspi
#else
#ifdef CONFIG_IDF_TARGET_ESP32
#define _READGUY_PLATFORM "ESP32"
#define READGUY_IDF_TARGET_WITH_VSPI //该器件拥有vspi
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
#define _READGUY_PLATFORM "ESP32S2"
#define READGUY_IDF_TARGET_MATRIX_SDIO //该器件支持矩阵SDIO
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#define _READGUY_PLATFORM "ESP32S3"
#define READGUY_IDF_TARGET_MATRIX_SDIO //该器件支持矩阵SDIO
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
#define _READGUY_PLATFORM "ESP32C3"
#define READGUY_IDF_TARGET_MATRIX_SDIO //该器件支持矩阵SDIO
#elif defined(CONFIG_IDF_TARGET_ESP32C6) //新增 ESP32C6 (暂未测试)
#define _READGUY_PLATFORM "ESP32C6"
#define READGUY_IDF_TARGET_MATRIX_SDIO //该器件支持矩阵SDIO
#else
#define _READGUY_PLATFORM "Unknown" //Prepare for ESP32-C6, H7, etc.
#warning Unknown platform! Readguy will run with unexpected (maybe hardware) errors!
#endif
#endif
//#define MEPD_DEBUG_WAVE 16 //取消此行注释来监视SPI的通信数据 (用于debug), 可以查看主控和屏幕的通信数据
//#define MEPD_DEBUG_WAITTIME //显示墨水屏的刷新时间, 单位是毫秒
#define FLOYD_STEINBERG_DITHERING //默认使用更好的floyd steinberg抖动算法,取消注释则用bayer图案抖动算法
#define FLOYD_DITHERING_16GREY //使用更好的floyd steinberg抖动算法显示16阶灰度,取消注释则使用阈值填充
// ***********************************************************************
//设备设置: 取消对应设备就可以直接禁用掉对应设备
//非常不建议用户在应用程序中禁用掉设备. 实测根本不会节省很多的空间. 如果要节省代码占用的flash空间,
//请在字库上下功夫.
//要想省空间, 请关闭wifi配置功能并避免使用wifi, 或者在程序中 (尤其是图片素材和字库素材上) 下功夫.
//如果程序不想支持此型号(为了节省flash),请注释掉这一行, 实测每个设备只能节省100字节左右的flash空间
#define READGUY_DEV_154A 0 //1.54寸标准, 甘草酸不酸使用的1.54默认屏幕型号. 1.54汉朔价签也选这个
#define READGUY_DEV_154B 1 //1.54寸Lilygo, lilygo的1.54触摸和1.54背光墨水屏. GDEH0154D67
@@ -68,7 +162,5 @@
#define EPD_DRIVERS_NUM_MAX 21 //此选项请不要取消注释掉, 有几个屏幕就写多少.
#define READGUY_583A_DUAL_BUFFER //对于单缓存的5.83屏幕,启用双缓存支持. 相当不建议注释掉,否则不能刷白色
#endif /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */
Copyright (C) 2025 FriendshipEnder. */

View File

@@ -7,15 +7,17 @@
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief readguy 基础配置文件. 用户可以根据自己对库的编译需求来修改此文件.
*
* 1.5.0 新增!
* 在项目目录里拷贝本文件并重命名为 "readguy_user_config.h" 即可使本配置文件仅在当前项目有效
*
* 如果你希望在程序代码内包含引脚定义, 请参考此文件下方的注释来确定并编译
* 这样就可以只针对你设计的这一个硬件来设定引脚功能.
* 关于屏幕配置, 请参考 guy_epaper/guy_epaper_config.h 文件来配置到底哪些屏幕型号的屏幕会被包含进来
* 关于屏幕配置, 请参考最下方(284行到文件末尾)来配置到底哪些屏幕型号的屏幕会被包含进来
* 可以禁用WiFi功能来减少程序的flash消耗
* @version 1.1
* @date create: 2023-09-21
* last modify: 2023-11-11
* last modify: 2025/4/7
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
@@ -39,15 +41,18 @@
// *** Do not include any file here!
/*
#define _EPD_CS_PIN 15 //D8, 显示屏的片选引脚
#define _EPD_DC_PIN 5 //D1, 显示屏的DC引脚
#define _EPD_RST_PIN -1 //reserved 保留的重置引脚
#define _EPD_BUSY_PIN 4 //D2 显示屏的Busy引脚
#define _SD_CS_PIN 0 //D3, SD卡的片选引脚
#define _BtnL 5 //D1, 左键
#define _BtnM 12 //中间键 D6引脚
#define _BtnR 2 //D4 右键
/**************************** 请不要取消注释这里! *****************************
********* 这里的设置项是无效的, 仅仅用于标注一些开发板的引脚预定义数据. *********
********** 部分热门的, 创新的带墨水屏开发板的引脚定义可能会罗列在这里. **********
*****************************************************************************
(无效设置项) #define _EPD_CS_PIN 15 //D8, 显示屏的片选引脚
(无效设置项) #define _EPD_DC_PIN 5 //D1, 显示屏的DC引脚
(无效设置项) #define _EPD_RST_PIN -1 //reserved 保留的重置引脚
(无效设置项) #define _EPD_BUSY_PIN 4 //D2 显示屏的Busy引脚
(无效设置项) #define _SD_CS_PIN 0 //D3, SD卡的片选引脚
(无效设置项) #define _BtnL 5 //D1, 左键
(无效设置项) #define _BtnM 12 //中间键 D6引脚
(无效设置项) #define _BtnR 2 //D4 右键
//对于甘草酸不酸的新版本板子:
//busy 4 rst 2 dc 0 cs 15 sck / mosi / sdcs 5 btnL rx(3) btnM 0
@@ -70,13 +75,47 @@
/ 关闭此选项自动禁用wifi功能. 如需wifi功能需要自己在程序里加. 但也可以大幅减少flash的占用 */
#define DYNAMIC_PIN_SETTINGS
/// @brief NVS存储配置数据时用的项目名. 必须小于8个字符, 为节省内存, 项目依赖此处的内存块仅分配了8字节.
#define READGUY_NVS_PROJECTNAME "readguy"
/// @brief NVS存储配置数据时用的配置数据键名. 必须小于8个字符, 为节省内存, 项目依赖此处的内存块仅分配了8字节.
#define READGUY_NVS_CONFIGKEY "hwconf"
/// @brief 当使用自定义驱动 (customDriver) 时会通过NVS访问驱动代码. 必须小于8个字符.
/// @note 有关自定义驱动, 可以参考 readme 中提到的在 2.0 版本即将到来的特性.
#define READGUY_NVS_DRIVERKEY "driver"
/// @brief 启用WIFI配网功能.必须先启用 #define DYNAMIC_PIN_SETTINGS. 此选项对 ESP32xx 会减少大量可用flash.
/// @note 注释掉它会破坏跨平台特性
#define READGUY_ENABLE_WIFI
/// @brief AP配网热点的名称和密码. 不可注释
#define READGUY_CONF_AP_SSID "readguy"
#define READGUY_CONF_AP_PASS "12345678"
/** @brief 使用服务器或者WIFI配网时, 在网页上显示项目默认的图标, 默认图标会额外占用1150字节的flash空间
/ 如果想用自己的图标数据库, 请参考配网示例, 在配置时候加入下方的代码. 此处提供了代码.
``` C++
typedef ReadguyDriver::ReadguyWebServer* server_t; //类型名太长太繁琐, 使用typedef减短
typedef ReadguyDriver::serveFunc event_t ; //存储一个WiFi功能事件.
const uint8_t icon[] = {}; //你的图标数据. 可直接把 *.ico 格式图标文件转化为字节数组, 拷贝到此处
void sendIcon(server_t sv){ sv->send_P(200, "image/x-icon", (const char *)icon,sizeof(icon)); }
event_t server_event={"","/favicon",sendIcon};
guy.server_setup(String("Custom Icon"),&server_event,1); //初始化服务器.
``` */
//#define READGUY_USE_DEFAULT_ICON
/** @brief 使用MDNS域名服务. 在设备联网或者打开热点之后, 可以通过域名 readguy.local 来访问配网主页
/ 关闭本功能可节省少许flash. 如需自定义服务名称, 则您可更改此处的字符串, 访问 <自定义名称>.local */
//#define READGUY_MDNS_SERVICE "readguy"
/// @brief 使用固件更新服务. 关闭本功能可节省少许flash. 如需自定义链接名称, 则您可更改此处的字符串.
//#define READGUY_UPDATE_SERVER "固件更新"
/** @brief 启用I2C功能. 可用于联网时钟, 温度计, 陀螺仪等外设. 目前暂不支持库内使用类似函数. 仅可以提供引脚定义
/ @note 现在库提供了获取已存的I2C引脚的接口, 使用时请使用 getI2cSda() 和 getI2cScl() 函数获取I2C的引脚.
/ 本库内不提供任何I2C驱动, 只提供引脚定义的存储和读取, 这几乎不增加多少代码. 因此本宏不再使用 */
//#define READGUY_ENABLE_I2C
//#define READGUY_ENABLE_I2C //已经弃用
/** @brief 启用SD卡功能. 开启此功能将会使用内置SD卡管理功能. 关闭后仅可保存SD卡用到的引脚.
/ @note 会破坏兼容性. 若没有启用通用的SD卡驱动程序, 那么那些跨屏台编译的程序将无法用guyFS读取到SD卡.
@@ -148,13 +187,29 @@
/// @brief ESP32驱动SD卡的速率. 当ESP32在与SD卡共享SPI时, 屏幕依据此处的速率.
#define ESP32_SD_SPI_FREQUENCY 20000000
#define ESP32_SD_MMC_FREQUENCY 40000
/// @brief debug专用, 请保持处于注释状态. 正常开机从NVS读取引脚配置数据, 取消注释则每次开机需要重新配置
//#define READGUY_INDEV_DEBUG 1
/// @brief 串口显示刷屏功能等的信息. 建议开启, 如果是对flash要求十分敏感 可以关闭
/// @brief 串口显示刷屏功能等的信息. 如果是对flash大小要求十分敏感, 或者希望减少串口数据, 可以关闭
#define READGUY_SERIAL_DEBUG
/// @brief 对于单缓存的5.83屏幕,启用双缓存支持. 相当不建议注释掉,否则不能刷白色
#define READGUY_583A_DUAL_BUFFER
/// @brief 取消此行注释来监视SPI的通信数据 (用于debug), 可以查看主控和屏幕的通信数据
//#define MEPD_DEBUG_WAVE 16
/// @brief 显示墨水屏的刷新时间, 单位是毫秒
//#define MEPD_DEBUG_WAITTIME
/// @brief 默认使用更好的floyd steinberg抖动算法,取消注释则用bayer图案抖动算法
#define FLOYD_STEINBERG_DITHERING
/// @brief 使用更好的floyd steinberg抖动算法显示16阶灰度,取消注释则使用阈值填充
#define FLOYD_DITHERING_16GREY
#ifndef DYNAMIC_PIN_SETTINGS
#ifdef ESP8266
#define READGUY_shareSpi 1 //EPD和SD卡是否共享SPI,对于ESP8266必须设置为1
@@ -230,8 +285,12 @@
#define READGUY_user10 -1 //useless
#endif
#define READGUY_rtc_type 0 //使用的RTC型号. 现已弃用 RTC 功能. 保留是为了兼容性 让代码更简单维护
#elif defined(READGUY_ENABLE_WIFI)
#define READGUY_rtc_type 0 //使用的RTC型号. RTC 将在2.0实装 保留是为了兼容性 让代码更简单维护
// ******************************************************************
// ********************** 以下内容不建议用户更改 **********************
// ******************************************************************
#elif defined(READGUY_ENABLE_WIFI) // READGUY_ENABLE_WIFI 依赖 DYNAMIC_PIN_SETTINGS
#define READGUY_ESP_ENABLE_WIFI //使用WIFI进行配网等功能
#endif
#undef READGUY_ENABLE_WIFI

View File

@@ -96,30 +96,34 @@ const unsigned char drvSSD168x::WS_20_30[42] =
};
const unsigned char drvSSD168x::VSH_table[32]=
{/*0x00,0xbc,0xc1,0xc6,0xcb,0x23,0x26,0x28,0x2a,0x2c,0x2e,0x32,0x35,0x39,0x3d,0x41,*/
0x00,0x24,0x28,0x2c,0x30,0x33,0x36,0x38,0x3a,0x3c,0x3e,0x40,0x42,0x44,0x45,0x46,
0x00,0xac,0xb0,0xb6,0xbd,0xc5,0xce,0x26,0x2c,0x33,0x3a,0x42,0x4a,0x4a,0x4a,0x4a,
0x00,0x41,0x3c,0x37,0x32,0x2d,0x28,0x23,0xcb,0xc6,0xc1,0xbc,0xb7,0xb2,0xb0,0xae};
//以下代码均为我 FriendshipEnder 原创, 呵呵哒~~
void drvSSD168x::SetLut() {
static const unsigned char VSH_repeat[16]={
0,1,1,1,1,1,1,1,1,1,1,1,1,2,3,4
};
unsigned int i;
guy_epdCmd(0x3f);
guy_epdParam(greyScaling?0x07:0x22);
guy_epdParam(greyScaling?0x07:0x02); //greyScaling?0x07:0x22
guy_epdCmd(0x03); // gate voltage
guy_epdParam(0x17);
guy_epdParam(0x17); //0x17 orig
guy_epdCmd(0x04); // source voltage
guy_epdParam(greyScaling?pgm_read_byte(VSH_table+16+iLut):pgm_read_byte(VSH_table+iLut));
guy_epdParam(0xA8); // VSH2
guy_epdParam(0x32); // VSL
guy_epdCmd(0x2c); // VCOM
guy_epdParam(0x28);
unsigned char i;
guy_epdParam(0x20); //0x28 orig
guy_epdCmd(0x32);
if(_part){
for(i=0;i<5;i++){
guy_epdParam(i==1?0x80:(i==(greyScaling?0:2)?0x40:0x00));
for(int j=0;j<11;j++) guy_epdParam(0);
}
guy_epdParam(greyScaling?1:iLut);
//guy_epdParam(greyScaling?1:iLut);
guy_epdParam(greyScaling ? 1 : pgm_read_byte(VSH_repeat + iLut));
for(i=0;i<83;i++) guy_epdParam(0);
guy_epdParam(0x22);
for(i=0;i<8;i++) guy_epdParam(0);
@@ -160,6 +164,8 @@ void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单
for(int i=0;i<10;i++) guy_epdParam(i==5?0x40:0x00);
guy_epdCmd(0x3C); //BorderWavefrom
guy_epdParam(0x80);
guy_epdCmd(0x18); //BorderWavefrom
guy_epdParam(0x80);
guy_epdCmd(0x22);
guy_epdParam(0xC0);
@@ -172,9 +178,10 @@ void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单
epd_PowerOn=1;
_part=0;
iLut=15;
guy_epdBusy(20);
}
guy_epdCmd(0x12); //SWRESET
guy_epdBusy(10);
guy_epdBusy(20);
guy_epdCmd(0x01); //Driver output control
guy_epdParam((epdHeight-1)&0xff);

View File

@@ -35,7 +35,8 @@
#include <FS.h>
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include "guy_epaper_config.h"
#include "../guy_config_host.h"
#include <functional>
#define FILL_WHITE ([](int)->uint8_t{return 0xff;})
#define FILL_BLACK ([](int)->uint8_t{return 0x00;})

View File

@@ -128,12 +128,16 @@ public:
auto cfg = _bus_instance.config(); // 获取总线配置的结构。
#ifndef ESP8266
#ifdef CONFIG_IDF_TARGET_ESP32
cfg.spi_host = SPI3_HOST; // 选择要使用的 SPI (VSPI_HOST or HSPI_HOST)
cfg.spi_host = VSPI_HOST; // 选择要使用的 SPI (VSPI_HOST or HSPI_HOST)
#else
cfg.spi_host = SPI1_HOST; // 选择要使用的 SPI (VSPI_HOST or HSPI_HOST)
#endif
cfg.use_lock = true; // 使用锁时设置为 True
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
cfg.dma_channel = SPI_DMA_CH_AUTO; // Set the DMA channel (1 or 2. 0=disable) 设置要打开的 DMA 通道 (0=DMA关闭)
#else
cfg.dma_channel = 0; // Auto DMA channel isn't supported. Don't use DMA by default.
#endif
#endif
cfg.spi_mode = 0; // SPI设置通讯模式 (0 ~ 3)
#if (defined(DISPLAY_TYPE_ST7789_240320) || defined(DISPLAY_TYPE_ST7789_240240) || defined(DISPLAY_TYPE_ST7789_135240))

View File

@@ -6,7 +6,7 @@
* @file guy_version.h
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief readguy 版本控制文件.
* @version 1.3.2
* @version 1.4.2
* @date 2023-09-21
* @attention
@@ -40,26 +40,10 @@
//务必保证这些版本号是一致的.
//另外, 在提交新版本之前, 不要忘记在github上创建release, 否则Arduino IDE会读不到
#define READGUY_V_MAJOR 1
#define READGUY_V_MINOR 4
#define READGUY_V_MINOR 5
#define READGUY_V_PATCH 0
#define READGUY_VERSION_VAL (READGUY_V_MAJOR*1000+READGUY_V_MINOR*100+READGUY_V_PATCH*10)
#define READGUY_VERSION "1.4.0"
#ifdef ESP8266
#define _READGUY_PLATFORM "ESP8266"
#else
#ifdef CONFIG_IDF_TARGET_ESP32
#define _READGUY_PLATFORM "ESP32"
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
#define _READGUY_PLATFORM "ESP32S2"
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#define _READGUY_PLATFORM "ESP32S3"
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
#define _READGUY_PLATFORM "ESP32C3"
#else
#define _READGUY_PLATFORM "Unknown"
#endif
#endif
#define READGUY_VERSION "1.5.0"
#define _GITHUB_LINK "https://github.com/fsender/readguy"
#define _BILIBILI_LINK "https://www.bilibili.com/video/BV1f94y187wz"

View File

@@ -28,9 +28,11 @@
*/
#include "readguy.h"
/* #if (!defined(ESP8266)) //for ESP32, ESP32S2, ESP32S3, ESP32C3
#if (!defined(ESP8266)) //for ESP32, ESP32S2, ESP32S3, ESP32C3
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
#include "esp_flash.h"
#endif */
#endif
#endif
#ifdef READGUY_ESP_ENABLE_WIFI
static const PROGMEM char NOT_SUPPORTED[] = "(不支持此屏幕)";
@@ -186,7 +188,7 @@ const char *ReadguyDriver::epd_drivers_list[EPD_DRIVERS_NUM_MAX]={
//x==62 -> _
//#define R2CHAR(x) (((x)==63)?42:(((x)==62)?95:(((x)>=36)?((x)+61):(((x)>=10)?((x)+55):((x)+48)))))
void ReadguyDriver::ap_setup(){
return ap_setup("readguy","12345678");
return ap_setup(READGUY_CONF_AP_SSID,READGUY_CONF_AP_PASS);
}
void ReadguyDriver::ap_setup(const char *ssid, const char *pass, int m){
//初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
@@ -203,7 +205,9 @@ void ReadguyDriver::ap_setup(const char *ssid, const char *pass, int m){
void ReadguyDriver::server_setup(const String &notify, const serveFunc *serveFuncs, int funcs){
//启动WiFi服务器端, 这样就可以进行配网工作
if(sfuncs!=-1) server_end(); //避免重复服务器setup
#ifdef READGUY_UPDATE_SERVER
httpUpdater.setup(&sv);
#endif
sv.on("/", HTTP_GET, std::bind(&ReadguyDriver::handleInit ,this));
sv.on("/verify", HTTP_POST, std::bind(&ReadguyDriver::handleInitPost ,this)); //此时已经完成了引脚初始化
sv.on("/pinsetup", HTTP_GET, std::bind(&ReadguyDriver::handlePinSetup ,this));
@@ -231,17 +235,16 @@ void ReadguyDriver::server_setup(const String &notify, const serveFunc *serveFun
}
else { sfnames=nullptr; sfevents=nullptr; }
/*sv.on("/favicon.ico", HTTP_GET, [&](){
sv.client().write_P(PSTR("HTTP/1.1 200 OK\r\n"
"Content-Type: image/x-icon\r\n"
"Content-Length: 1150\r\n"
"Connection: close\r\n\r\n"),89);
sv.client().write_P((const char *)faviconData,sizeof(faviconData));
});*/
#ifdef READGUY_USE_DEFAULT_ICON
sv.on("/favicon.ico", HTTP_GET, [&](){
sv.send_P(200,"image/x-icon",(const char *)faviconData,sizeof(faviconData));
});
#endif
sv.begin();
MDNS.begin("readguy");
//MDNS.addService("http","tcp",80);
#ifdef READGUY_MDNS_SERVICE
MDNS.begin(READGUY_MDNS_SERVICE);
MDNS.addService("http","tcp",80);
#endif
#ifdef READGUY_SERIAL_DEBUG
Serial.print(F("[Guy server] Done! visit "));
if(WiFi.getMode() == WIFI_AP) Serial.println(F("192.168.4.1"));
@@ -288,7 +291,9 @@ bool ReadguyDriver::server_loop(){ //此时等待网页操作完成响应...
}
void ReadguyDriver::server_end(){
sv.stop();
#ifdef READGUY_MDNS_SERVICE
MDNS.end();
#endif
sfuncs=-1;
delete [] sfnames;
delete [] sfevents;
@@ -318,11 +323,17 @@ void ReadguyDriver::handleInitPost(){
btnTask.detach();
#else
#ifdef READGUY_ENABLE_SD
#if (defined(READGUY_IDF_TARGET_MATRIX_SDIO))
if(READGUY_shareSpi) SD.end(); else SD_MMC.end();
#else
SD.end();//关闭SD卡
#endif
#ifdef READGUY_IDF_TARGET_WITH_VSPI
if(sd_spi != epd_spi) { //共线时, 不要删除SD
delete sd_spi;
sd_spi=nullptr;
}
#endif
#endif
vTaskDelete(btn_handle);
#endif
@@ -353,7 +364,7 @@ void ReadguyDriver::handleInitPost(){
else if(i==19&&btn_count_>2) config_data[17]=sv.arg(FPSTR(args_name[19])).toInt()+1;
else if(i==20&&btn_count_>2) config_data[17]=-config_data[17];
else if(i==21) config_data[18] = sv.arg(FPSTR(args_name[21])).toInt();
else if(i==22) config_data[19] = sv.arg(FPSTR(args_name[22])).toInt(); //现已弃用 RTC 功能.
else if(i==22) config_data[19] = sv.arg(FPSTR(args_name[22])).toInt(); //RTC 将在2.0实装
else if(i>22){ //用户数据
config_data[i-1] = sv.arg(a_name).toInt();
}
@@ -367,16 +378,16 @@ void ReadguyDriver::handleInitPost(){
}
}
//尝试初始化各个硬件, 可能失败, 然后显示一些东西
#if (defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3))
#if (defined(ESP8266))
if(config_data[3]==-1) config_data[3] = config_data[10];
else config_data[10] = config_data[3];
if(config_data[4]==-1) config_data[4] = config_data[11];
else config_data[11] = config_data[4];
READGUY_shareSpi = true;
#else
if(config_data[10] == config_data[3] && config_data[11] == config_data[4]) //检测到SPI共线
if(config_data[10] == config_data[3] || config_data[11] == config_data[4]) //检测到SPI共线
READGUY_shareSpi = true;
else if(READGUY_shareSpi){
if(READGUY_shareSpi){
if(config_data[3]==-1) config_data[3] = config_data[10];
else config_data[10] = config_data[3];
if(config_data[4]==-1) config_data[4] = config_data[11];
@@ -423,6 +434,9 @@ void ReadguyDriver::handleInitPost(){
Serial.println(F("[Guy] Init details..."));
#endif
setTextSize(1);
#if (defined(READGUY_IDF_TARGET_MATRIX_SDIO))
SD_MMC.end();
#endif
drawCenterString(setSDcardDriver()?"SD Init OK!":"SD Init failed!",
guy_dev->drv_width()>>1,(guy_dev->drv_height()>>1)+20);
setButtonDriver(); //初始化按钮..
@@ -432,7 +446,7 @@ void ReadguyDriver::handleInitPost(){
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);
refresh_begin(0);
guy_dev->drv_fullpart(1);
guy_dev->drv_fullpart(0);
guy_dev->_display((const uint8_t*)getBuffer());
#if (defined(READGUY_ALLOW_DC_AS_BUTTON))
refresh_end();
@@ -574,10 +588,10 @@ void ReadguyDriver::handlePinSetup(){
#else
for(int i=0;i<12;i++){
s += F("<br/>");
#if defined(CONFIG_IDF_TARGET_ESP32C3)
#if (!(defined(READGUY_IDF_TARGET_WITH_VSPI) || defined(READGUY_IDF_TARGET_MATRIX_SDIO)))
if(i==7) {
i+=2; //优化ESP32C3的SPI配置体验 (C3只能共线)
s += F("(ESP32C3不支持SD卡独立SPI总线! SD_MOSI和SD_SCLK沿用EPDMOSI和EPDSCLK)<br/>");
s += F("(" _READGUY_PLATFORM "不支持SD卡独立SPI总线! SD_MOSI和SD_SCLK沿用EPDMOSI和EPDSCLK)<br/>");
}
#endif
#endif
@@ -671,16 +685,32 @@ void ReadguyDriver::handleFinal(){
else s+=F("SD卡已插入.<br/>"); //对于大容量(>2GB)卡, SDFS.info64(*sdInfo)函数调用速度太慢(17秒)
#else
else{
auto cardType = SD.cardType();
uint32_t sz;
uint32_t usesz;
sdcard_type_t cardType;
#if (defined(READGUY_IDF_TARGET_MATRIX_SDIO))
if(READGUY_shareSpi){
#endif
sz=(uint32_t)(SD.cardSize()/1024);
usesz=(uint32_t)(SD.usedBytes()/1024);
cardType=SD.cardType();
#if (defined(READGUY_IDF_TARGET_MATRIX_SDIO))
}
else{
sz=(uint32_t)(SD_MMC.cardSize()/1024);
usesz=(uint32_t)(SD_MMC.usedBytes()/1024);
cardType=SD_MMC.cardType();
}
#endif
s+=F("SD Card Type: ");
if(cardType == CARD_MMC) s+=F("MMC");
else if(cardType == CARD_SD) s+=F("SDSC");
else if(cardType == CARD_SDHC) s+=F("SDHC");
else s+=F("UNKNOWN");
s+=F(", SD card size: ");
s+=(uint32_t)(SD.cardSize()/1024);
s+=sz;
s+=F(", used size: ");
s+=(uint32_t)(SD.usedBytes()/1024);
s+=usesz;
s+=F("KB.<br/>");
}
#endif
@@ -701,10 +731,17 @@ void ReadguyDriver::handleFinal(){
char cbuf[20]="";
#if (defined(ESP8266))
sprintf(cbuf, "0x%08x", ESP.getChipId());
#else
#elif (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0))
uint64_t gotID;
esp_flash_read_unique_chip_id(esp_flash_default_chip,&gotID);
sprintf(cbuf, "%016llx", gotID);
//sprintf(cbuf, "%016llx", gotID);
sprintf(cbuf, "%08x%08x",(unsigned int)(gotID>>32),(unsigned int)(gotID&0xffffffffu));
#else
uint32_t chipId = 0;
for(int i=0; i<17; i=i+8) {
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
}
sprintf(cbuf, "0x%08x",chipId);
#endif
s+=cbuf;
s+=F("<br/>闪存容量: ");
@@ -770,7 +807,7 @@ const PROGMEM char ReadguyDriver::index_cn_html[] = // then write EpdMOSI pin
"将引脚配置输入到框内, 即可成功点亮屏幕.</p><hr/><h2>引脚定义设定</h2><form "
"name=\"input\" action=\"/verify\" method=\"POST\">";
const PROGMEM char ReadguyDriver::index_cn_html2[] =
#if (!defined(ESP8266) && !defined(CONFIG_IDF_TARGET_ESP32C3))
#if (defined(READGUY_IDF_TARGET_WITH_VSPI) || defined(READGUY_IDF_TARGET_MATRIX_SDIO))
"<input type=\"checkbox\" name=\"share\" value=\"1\">墨水屏和SD卡共享SPI<br/>"
#endif
"E-paper 型号<select id=\"et\" onchange=\"ct()\" name=\"epdtype\">";
@@ -784,14 +821,18 @@ const PROGMEM char ReadguyDriver::verify_html[] =
const PROGMEM char ReadguyDriver::verify2_html[] =
"<br/><hr/>完成上述4个操作之后屏幕上将会展现出验证码,输入验证码即可完成硬件配置.<br/></p><form action=\"/fin"
"al\" method=\"POST\"><input type=\'text\' name=\'t_verify\' maxlength=\"6";
const PROGMEM char ReadguyDriver::verifybtn_html[3][224] = {
const PROGMEM char *ReadguyDriver::verifybtn_html[3] = {verifybtn_html1,verifybtn_html2,verifybtn_html3};
const PROGMEM char ReadguyDriver::verifybtn_html1[] =
"一个按键, 功能全保留, 操作可能比较繁琐.<br/>点按:下一个/向下翻页<br/>双击:确定/选择<br/>三连击:返回/退格<br/>"
"长按半秒:上一个/向上翻页<br/>点按紧接着长按: 特殊操作",
"长按半秒:上一个/向上翻页<br/>点按紧接着长按: 特殊操作";
const PROGMEM char ReadguyDriver::verifybtn_html2[] =
"两个按键, 操作可以满足需求.<br/>按键1点按:下一个/向下翻页<br/>按键1长按:上一个/向上翻页<br/>按键2点按:确定/选"
"择<br/>按键2长按:返回/退格<br/>按住按键1点按2:特殊操作",
"择<br/>按键2长按:返回/退格<br/>按住按键1点按2:特殊操作";
const PROGMEM char ReadguyDriver::verifybtn_html3[] =
"三个按键, 操作非常方便流畅.<br/>按键1:上一个/向上翻页<br/>按键2点按:确定/选择<br/>按键2长按: 返回/退格<br/>按"
"键3:下一个/向下翻页<br/>双击点按2:切换输入法等特殊操作"
};
"键3:下一个/向下翻页<br/>双击点按2:切换输入法等特殊操作";
const PROGMEM char ReadguyDriver::final_html[] =
"欢迎使用 readguy</title></head><body><h1>readguy ";
const PROGMEM char ReadguyDriver::afterConfig_html[] =
@@ -807,10 +848,14 @@ const PROGMEM char ReadguyDriver::final2_html[] =
"钥<input type=\'text\' name=\'psk\' maxlength=\"63";
*/
const PROGMEM char ReadguyDriver::end_html[] =
"<p>ReadGuy on device " _READGUY_PLATFORM " <a href=\"/pinsetup\">重新配置引脚</a> <a href=\"/update\">固件更新"
"</a><br/>Copyright © FriendshipEnder <a href=\"" _GITHUB_LINK "\">GitHub</a> <a href=\"" _BILIBILI_LINK "\">"
"<p>ReadGuy on device " _READGUY_PLATFORM " <a href=\"/pinsetup\">重新配置引脚</a>"
#ifdef READGUY_UPDATE_SERVER
" <a href=\"/update\">" READGUY_UPDATE_SERVER "</a>"
#endif
"<br/>Copyright © FriendshipEnder <a href=\"" _GITHUB_LINK "\">GitHub</a> <a href=\"" _BILIBILI_LINK "\">"
"Bilibili</a><br/>版本: " READGUY_VERSION " ,编译日期: " __DATE__ " " __TIME__ "</p></body></html>";
/*const PROGMEM uint8_t ReadguyDriver::faviconData[1150]={
#ifdef READGUY_USE_DEFAULT_ICON
const PROGMEM uint8_t ReadguyDriver::faviconData[1150]={
0x0,0x0,0x1,0x0,0x1,0x0,0x10,0x10,0x0,0x0,0x1,0x0,0x20,0x0,0x68,0x4,0x0,0x0,0x16,0x0,0x0,0x0,0x28,0x0,
0x0,0x0,0x10,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x1,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x40,0x4,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x9d,0xaa,0xe8,0xff,0x74,0x73,0x77,0xff,0x74,0x73,
@@ -859,6 +904,7 @@ const PROGMEM char ReadguyDriver::end_html[] =
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
0x0,0x0,0x0,0x1,0x0,0x0,0x80,0x1,0x0,0x0,0x80,0x0,0x0,0x0,0x80,0x1,0x0,0x0,0x80,0x1,0x0,0x0,0xc0,0x1,
0x0,0x0,0xc0,0x3,0x0,0x0,0xe0,0x3,0x0,0x0,0xf0,0x7,0x0,0x0,0xfc,0x1f,0x0,0x0,0xf0,0xff,0x0,0x0
};*/
};
#endif
#endif /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */

View File

@@ -49,8 +49,9 @@ uint8_t ReadguyDriver::static_sd_cs=0x7f;
volatile uint8_t ReadguyDriver::sd_cs_busy=0;
#endif
const PROGMEM char ReadguyDriver::projname[8] = "readguy";
const PROGMEM char ReadguyDriver::tagname[7] = "hwconf";
const PROGMEM char ReadguyDriver::projname[8] = READGUY_NVS_PROJECTNAME;
const PROGMEM char ReadguyDriver::tagname[8] = READGUY_NVS_CONFIGKEY;
volatile uint8_t ReadguyDriver::spibz=0;
#ifndef DYNAMIC_PIN_SETTINGS
const int8_t ReadguyDriver::config_data[32] = {
@@ -77,7 +78,7 @@ const int8_t ReadguyDriver::config_data[32] = {
READGUY_btn2 ,
READGUY_btn3 ,
READGUY_bl_pin ,//前置光接口引脚IO
READGUY_rtc_type ,//使用的RTC型号. 现已弃用 RTC 功能. 保留是为了兼容性 让代码更简单维护
READGUY_rtc_type ,//使用的RTC型号. RTC 将在2.0实装 保留是为了兼容性 让代码更简单维护
0 ,//READGUY_sd_ok SD卡已经成功初始化
0 ,//READGUY_buttons 按钮个数, 0-3都有可能
-1, //用户自定义变量 同时用于esp32s3使用SDIO卡数据的DAT1 为-1代表不使用SDIO
@@ -86,7 +87,9 @@ const int8_t ReadguyDriver::config_data[32] = {
};
#endif
#ifndef ESP8266
#ifdef READGUY_IDF_TARGET_WITH_VSPI
SPIClass *ReadguyDriver::sd_spi =nullptr;
#endif
SPIClass *ReadguyDriver::epd_spi=nullptr;
TaskHandle_t ReadguyDriver::btn_handle;
#endif
@@ -172,7 +175,7 @@ uint8_t ReadguyDriver::checkEpdDriver(){
#define TEST_ONLY_VALUE 3
#endif
#ifdef READGUY_SERIAL_DEBUG
Serial.printf_P(PSTR("[Guy SPI] shareSpi? %d\n"),READGUY_shareSpi);
if(READGUY_shareSpi) Serial.println(F("[Guy SPI] share EPD and SD SPI."));
#endif
for(int i=TEST_ONLY_VALUE;i<8;i++){
if(i<7 && config_data[i]<0) return 125;//必要的引脚没连接
@@ -312,11 +315,13 @@ uint8_t ReadguyDriver::checkEpdDriver(){
else epd_spi->end();
//epd_spi ->setFrequency(ESP32_DISP_FREQUENCY);
//Serial.println("deleting guy_dev");
#ifdef READGUY_IDF_TARGET_WITH_VSPI
if(READGUY_shareSpi) sd_spi = epd_spi;
else {
if(sd_spi!=nullptr && sd_spi!=&SPI) { sd_spi->end(); delete sd_spi; } //防止SPI被delete掉
sd_spi=nullptr;
}
#endif
epd_spi->begin(READGUY_epd_sclk,READGUY_shareSpi?READGUY_sd_miso:-1,READGUY_epd_mosi);
guy_dev->IfInit(*epd_spi, READGUY_epd_cs, READGUY_epd_dc, READGUY_epd_rst, READGUY_epd_busy);
#endif
@@ -328,7 +333,7 @@ uint8_t ReadguyDriver::checkEpdDriver(){
void ReadguyDriver::setEpdDriver(bool initepd, bool initGFX){
guy_dev->spi_tr_release = in_release;
guy_dev->spi_tr_press = in_press;
if(initepd) guy_dev->drv_init(); //初始化epd驱动层
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;
@@ -351,6 +356,7 @@ void ReadguyDriver::setEpdDriver(bool initepd, bool initGFX){
#ifdef READGUY_SERIAL_DEBUG
Serial.printf_P(PSTR("[Guy EPD] EPD init OK(%d): w: %d, h: %d\n"),guy_dev->drv_ID(),guy_dev->drv_width(),guy_dev->drv_height());
#endif
if(initepd) display(READGUY_SLOW); //25/3/13:feat: 如果initepd为true说明墨水屏需要从上电or休眠初始化, 必定慢刷
}
#ifdef READGUY_ENABLE_SD
bool ReadguyDriver::setSDcardDriver(){
@@ -358,13 +364,18 @@ bool ReadguyDriver::setSDcardDriver(){
对于esp32也要注意这个引脚是否是一个合法的引脚
对于esp8266真的要重写, 比如esp8266需要允许某些引脚是可以复用的
此处的函数必须是可以反复调用的, 即 "可重入函数" 而不会造成任何线程危险 */
if(READGUY_sd_cs>=0
#ifndef ESP8266
&&READGUY_sd_miso!=READGUY_sd_mosi&&READGUY_sd_miso!=READGUY_sd_sclk&&READGUY_sd_miso!=READGUY_sd_cs&&READGUY_sd_mosi!=READGUY_sd_sclk
#ifdef ESP8266
if( READGUY_sd_cs>=0 && READGUY_sd_cs!=READGUY_epd_cs && READGUY_sd_cs!=READGUY_epd_dc\
&& READGUY_sd_cs!=READGUY_epd_rst && READGUY_sd_cs!=READGUY_epd_busy )
#else
if(READGUY_sd_miso!=READGUY_sd_mosi&&READGUY_sd_miso!=READGUY_sd_sclk&&READGUY_sd_miso!=READGUY_sd_cs&&READGUY_sd_mosi!=READGUY_sd_sclk
&& READGUY_sd_mosi!=READGUY_sd_cs && READGUY_sd_sclk!=READGUY_sd_cs && READGUY_sd_miso>=0 && READGUY_sd_mosi>=0 && READGUY_sd_sclk>=0
#if (!defined(READGUY_IDF_TARGET_MATRIX_SDIO))
&& READGUY_sd_cs>=0 && READGUY_sd_cs!=READGUY_epd_cs && READGUY_sd_cs!=READGUY_epd_dc && READGUY_sd_cs!=READGUY_epd_rst && READGUY_sd_cs!=READGUY_epd_busy
#endif
&& READGUY_sd_cs!=READGUY_epd_cs && READGUY_sd_cs!=READGUY_epd_dc && READGUY_sd_cs!=READGUY_epd_rst && READGUY_sd_cs!=READGUY_epd_busy
){ //SD卡的CS检测程序和按键检测程序冲突, 故删掉 (可能引发引脚无冲突但是显示冲突的bug)
)
#endif
{ //SD卡的CS检测程序和按键检测程序冲突, 故删掉 (可能引发引脚无冲突但是显示冲突的bug)
#if (defined(READGUY_ALLOW_SDCS_AS_BUTTON))
setSDbusy(1);
#endif
@@ -373,15 +384,36 @@ bool ReadguyDriver::setSDcardDriver(){
SDFS.setConfig(SDFSConfig(READGUY_sd_cs));
READGUY_sd_ok = SDFS.begin();
#else
if(sd_spi == nullptr) {
#if (defined(CONFIG_IDF_TARGET_ESP32))
sd_spi = new SPIClass(VSPI);
#else
sd_spi = new SPIClass(FSPI); //ESP32S2和S3和C3 不支持VSPI, C3不支持FSPI
#if (defined(READGUY_IDF_TARGET_WITH_VSPI))
if(READGUY_shareSpi) sd_spi = epd_spi;
else{
#ifdef READGUY_SERIAL_DEBUG
Serial.printf_P(PSTR("[Guy SD] SD-VSPI sclk%3d|mosi%3d|miso%3d|ss%5d\n"),\
READGUY_sd_sclk,READGUY_sd_mosi,READGUY_sd_miso,READGUY_sd_cs);
#endif
if(sd_spi == nullptr) sd_spi = new SPIClass(VSPI);
else sd_spi->end();
sd_spi->begin(READGUY_sd_sclk,READGUY_sd_miso,READGUY_sd_mosi); //初始化SPI
}
READGUY_sd_ok = SD.begin(READGUY_sd_cs,*sd_spi,ESP32_SD_SPI_FREQUENCY); //初始化频率为20MHz
READGUY_sd_ok = SD.begin(READGUY_sd_cs,*(READGUY_shareSpi?epd_spi:sd_spi),ESP32_SD_SPI_FREQUENCY);
#elif (defined(READGUY_IDF_TARGET_MATRIX_SDIO))
if(READGUY_shareSpi){
READGUY_sd_ok = SD.begin(READGUY_sd_cs,*epd_spi,ESP32_SD_SPI_FREQUENCY);
}
else{
//if(getReadguyUseSdio()){ //4-wire SDIO
#ifdef READGUY_SERIAL_DEBUG
Serial.printf_P(PSTR("[Guy SD] SDMMC clk%3d|cmd%3d|d0 %3d|d1 %3d|d2 %3d|d3 %3d\n"),\
READGUY_sd_sclk,READGUY_sd_mosi,READGUY_sd_miso,READGUY_user1,READGUY_user2,READGUY_sd_cs);
#endif
if(READGUY_sd_cs>=0) pinMode(READGUY_sd_cs, INPUT_PULLUP); //默认上拉
SD_MMC.setPins(READGUY_sd_sclk,READGUY_sd_mosi,READGUY_sd_miso,READGUY_user1,READGUY_user2,READGUY_sd_cs);
//#else //不支持独立总线, 所以不会执行
// sd_spi = new SPIClass(FSPI); //ESP32S2和S3和C3 不支持VSPI, C3不支持FSPI
// sd_spi->begin(READGUY_sd_sclk,READGUY_sd_miso,READGUY_sd_mosi); //初始化SPI
READGUY_sd_ok = SD_MMC.begin("/sd",!getReadguyUseSdio(),false,ESP32_SD_MMC_FREQUENCY); //初始化频率为20MHz
}
#endif
#endif
#if (defined(READGUY_ALLOW_SDCS_AS_BUTTON))
setSDbusy(0);
@@ -394,7 +426,8 @@ bool ReadguyDriver::setSDcardDriver(){
#endif
//guyFS().begin(); //初始化内部FS
#ifdef READGUY_USE_LITTLEFS
LittleFS.begin();
if(!LittleFS.begin())
LittleFS.format(); //初始化失败时, 格式化文件系统
#else
SPIFFS.begin();
#endif
@@ -405,7 +438,8 @@ bool ReadguyDriver::setSDcardDriver(){
bool ReadguyDriver::setSDcardDriver(){
READGUY_sd_ok=0;
#ifdef READGUY_USE_LITTLEFS
LittleFS.begin();
if(!LittleFS.begin())
LittleFS.format(); //初始化失败时, 格式化文件系统
#else
SPIFFS.begin();
#endif
@@ -478,7 +512,8 @@ void ReadguyDriver::setButtonDriver(){
btn_rd[0].long_press_ms = 20; //只有长按, 按一下也是长按,
btn_rd[0].double_press_ms = 20; //不识别双击三击,
btn_rd[0].setLongRepeatMode(1); //并且开启连按
btn_rd[1].enScanDT(0); //不识别双击或三击(默认) 2024/2/25更新:需要支持连按适配拨轮
//2024/2/25更新:需要支持连按适配拨轮
btn_rd[1].enScanDT(1); //识别双击或三击(默认) 2025/3/12更新:默认开启识别, 但按下确定键的响应会稍微变慢
btn_rd[1].setLongRepeatMode(0); //三按键 确定按键 设置为不允许连按
btn_rd[2].long_press_ms = 20; //只有长按, 按一下也是长按, 并且开启连按
btn_rd[2].double_press_ms = 20; //不识别双击三击,
@@ -519,14 +554,22 @@ void ReadguyDriver::setButtonDriver(){
analogWriteFreq(400); //8266不宜太快
analogWriteResolution(8); //其实完全可以再快点的
analogWrite(READGUY_bl_pin,currentBright);
#else
#if (defined ( ESP_IDF_VERSION_VAL ) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)))
//ledcAttach(READGUY_bl_pin,8000,8);
analogWrite(READGUY_bl_pin, currentBright);
analogWriteFrequency(READGUY_bl_pin, 8000); //esp32宜快一些, 减少频闪影响
analogWriteResolution(READGUY_bl_pin, 8); //其实完全可以再快点的
#else
ledcSetup(0, 8000, 8);
ledcAttachPin(READGUY_bl_pin, 0);//稍后加入PWM驱动...
ledcWrite(0, currentBright);
#endif
#endif
}
else {
currentBright=-1; //引脚不支持PWM,设置为亮起
pinMode(READGUY_bl_pin, OUTPUT);
digitalWrite(READGUY_bl_pin,HIGH);
}
} //关于按键策略, 我们在此使用多个Button2的类, 然后在一个task共享变量来确定上一个按键状态
@@ -538,6 +581,9 @@ fs::FS &ReadguyDriver::guyFS(uint8_t initSD){
#ifdef ESP8266
return SDFS;
#else
#if (defined(READGUY_IDF_TARGET_MATRIX_SDIO))
if(!READGUY_shareSpi) return SD_MMC;
#endif
return SD;
#endif
}
@@ -560,14 +606,21 @@ fs::FS &ReadguyDriver::guyFS(uint8_t initSD){
void ReadguyDriver::setBright(int d){
if(currentBright>=0 && d>=0 && d<=255){
currentBright=d;
#ifdef ESP8266
#if ((defined (ESP8266)))
analogWrite(READGUY_bl_pin,d);
#else
#if (defined ( ESP_IDF_VERSION_VAL ) )
#if ( (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)))
analogWrite(READGUY_bl_pin,d);
#else
ledcWrite(0, d);
#endif
#endif
#endif
}
else if(currentBright>=-2 && currentBright<0){ //-1为不支持PWM的亮起,-2为不支持PWM的熄灭
currentBright=d?-1:-2;
pinMode(READGUY_bl_pin, OUTPUT);
digitalWrite(READGUY_bl_pin,d?HIGH:LOW);
}
}
@@ -686,7 +739,10 @@ void ReadguyDriver::invertDisplay(){
}
void ReadguyDriver::sleepEPD(){
if(READGUY_cali==127) {
if(READGUY_bl_pin>=0) digitalWrite(READGUY_bl_pin, LOW); //关闭背光灯, 节省电量
if(READGUY_bl_pin>=0) {
pinMode(READGUY_bl_pin, OUTPUT);
digitalWrite(READGUY_bl_pin, LOW); //关闭背光灯, 节省电量
}
guy_dev->drv_sleep();
}
}

View File

@@ -35,6 +35,7 @@
#include <Arduino.h>
#include <SPI.h>
#include <FS.h>
#include <functional>
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
@@ -91,7 +92,7 @@
#include "guy_button.h" //改自Button2精简而来
#include "guy_version.h"
#include "guy_driver_config.h" //config
#include "guy_config_host.h" //config
#ifdef READGUY_USE_LITTLEFS
#include <LittleFS.h>
#else
@@ -105,9 +106,13 @@
#ifdef READGUY_ESP_ENABLE_WIFI
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#ifdef READGUY_MDNS_SERVICE
#include <ESP8266mDNS.h>
#endif
#ifdef READGUY_UPDATE_SERVER
#include "ESP8266HTTPUpdateServer.h"
#endif
#endif
#ifdef READGUY_ENABLE_SD
#include <SDFS.h>
#endif
@@ -117,10 +122,17 @@
#ifdef READGUY_ESP_ENABLE_WIFI
#include <WiFi.h>
#include <WebServer.h>
#ifdef READGUY_MDNS_SERVICE
#include <ESPmDNS.h>
#endif
#ifdef READGUY_UPDATE_SERVER
#include "HTTPUpdateServer.h"
#endif
#endif
#ifdef READGUY_ENABLE_SD
#if (defined(READGUY_IDF_TARGET_MATRIX_SDIO))
#include <SD_MMC.h>
#endif
#include <SD.h>
#endif
#include <freertos/FreeRTOS.h>
@@ -151,7 +163,7 @@
#define READGUY_btn2 (config_data[16])
#define READGUY_btn3 (config_data[17])
#define READGUY_bl_pin (config_data[18])//前置光接口引脚IO
#define READGUY_rtc_type (config_data[19])//现已弃用 RTC 功能. 保留是为了兼容性 让代码更简单维护
#define READGUY_rtc_type (config_data[19])//RTC 将在2.0实装 保留是为了兼容性 让代码更简单维护
#define READGUY_sd_ok (config_data[20]) //SD卡已经成功初始化
#define READGUY_buttons (config_data[21]) //按钮个数, 0-3都有可能
@@ -184,15 +196,25 @@
#define GUY_BTN_OK 4 //返回/退出
#define GUY_BTN_BACK 8 //特殊操作(如切换输入法)
#if __cplusplus >= 201304L
#define RG_IL_CONEXP constexpr inline
#else
#define RG_IL_CONEXP inline
#endif
class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
public:
#ifdef READGUY_ESP_ENABLE_WIFI
#ifdef ESP8266
typedef ESP8266WebServer ReadguyWebServer;
#ifdef READGUY_UPDATE_SERVER
typedef ESP8266HTTPUpdateServer ReadguyUpdateServer;
#endif
#else
typedef WebServer ReadguyWebServer;
#ifdef READGUY_UPDATE_SERVER
typedef HTTPUpdateServer ReadguyUpdateServer;
#endif
#endif
#endif
ReadguyDriver();
@@ -361,7 +383,7 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
//以下是支持的所有屏幕型号 Add devices here!
//添加屏幕驱动范例: 直接添加对应屏幕的类就可以用了
static const char projname[8];
static const char tagname[7];
static const char tagname[8];
//uint8_t config_wifi=0; //是否强行在初始化期间设置WiFi.
void nvs_init(); //初始化持久存储器.
void nvs_deinit();//保存持久存储器的内容
@@ -373,7 +395,7 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
#else
static const int8_t config_data[32];
int8_t READGUY_sd_ok = 0;
int8_t READGUY_cali = 0;
int8_t READGUY_cali = 127;
int8_t READGUY_buttons = 0; //按钮个数, 0-3都有可能
#endif
int16_t epdPartRefresh = 0; //连续快刷次数
@@ -404,7 +426,9 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
#endif
#ifdef READGUY_ESP_ENABLE_WIFI
ReadguyWebServer sv;
#ifdef READGUY_UPDATE_SERVER
ReadguyUpdateServer httpUpdater;
#endif
String guy_notify=emptyString; //嵌入在网页中的自定义标语
int sfuncs=-1;
String* sfnames=nullptr;
@@ -444,12 +468,17 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
static const PROGMEM char index_cn_html16[];
static const PROGMEM char verify_html[];
static const PROGMEM char verify2_html[];
static const PROGMEM char verifybtn_html[3][224];
static const PROGMEM char *verifybtn_html[3];
static const PROGMEM char verifybtn_html1[];
static const PROGMEM char verifybtn_html2[];
static const PROGMEM char verifybtn_html3[];
static const PROGMEM char final_html[];
static const PROGMEM char afterConfig_html[];
static const PROGMEM char home_html[];
static const PROGMEM char end_html[];
//static const PROGMEM uint8_t faviconData[1150];
#ifdef READGUY_USE_DEFAULT_ICON
static const PROGMEM uint8_t faviconData[1150];
#endif
#endif
static void looptask(); //按键服务函数
static uint8_t rd_btn_f(uint8_t btn, bool activeLow);
@@ -481,67 +510,67 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
#endif
}
public: //增加了一些返回系统状态变量的函数, 它们是静态的, 而且不会对程序造成任何影响.
constexpr int getShareSpi() const { return READGUY_shareSpi; }
constexpr int getEpdType () const { return READGUY_epd_type; } // 对应的epd驱动程序代号, -1为未指定
RG_IL_CONEXP int getShareSpi() const { return READGUY_shareSpi; }
RG_IL_CONEXP int getEpdType () const { return READGUY_epd_type; } // 对应的epd驱动程序代号, -1为未指定
//显示驱动部分, 显示默认使用vspi (vspi也是默认SPI库的通道)
constexpr int getEpdMosi () const { return READGUY_epd_mosi; } // 目标显示器的 MOSI 引脚
constexpr int getEpdSclk () const { return READGUY_epd_sclk; } // 目标显示器的 SCLK 引脚
constexpr int getEpdCs () const { return READGUY_epd_cs; } // 目标显示器的 CS 引脚
constexpr int getEpdDc () const { return READGUY_epd_dc; } // 目标显示器的 DC 引脚
constexpr int getEpdRst () const { return READGUY_epd_rst; } // 目标显示器的 RST 引脚
constexpr int getEpdBusy () const { return READGUY_epd_busy; } // 目标显示器的 BUSY 引脚
RG_IL_CONEXP int getEpdMosi () const { return READGUY_epd_mosi; } // 目标显示器的 MOSI 引脚
RG_IL_CONEXP int getEpdSclk () const { return READGUY_epd_sclk; } // 目标显示器的 SCLK 引脚
RG_IL_CONEXP int getEpdCs () const { return READGUY_epd_cs; } // 目标显示器的 CS 引脚
RG_IL_CONEXP int getEpdDc () const { return READGUY_epd_dc; } // 目标显示器的 DC 引脚
RG_IL_CONEXP int getEpdRst () const { return READGUY_epd_rst; } // 目标显示器的 RST 引脚
RG_IL_CONEXP int getEpdBusy () const { return READGUY_epd_busy; } // 目标显示器的 BUSY 引脚
//sd卡驱动部分, 默认使用hspi (sd卡建议用hspi)
constexpr int getSdMiso () const { return READGUY_sd_miso; } // 目标sd卡的 MISO 引脚, sd_share_spi == 1 时无效
constexpr int getSdMosi () const { return READGUY_sd_mosi; }// 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
constexpr int getSdSclk () const { return READGUY_sd_sclk; }// 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
constexpr int getSdCs () const { return READGUY_sd_cs; }// 目标sd卡的CS引脚. 对ESP32S3, 返回127代表使用SDMMC
constexpr int getI2cSda () const { return READGUY_i2c_sda; }// 目标i2c总线的SDA引脚, 当且仅当启用i2c总线时才生效
constexpr int getI2cScl () const { return READGUY_i2c_scl; }// 目标i2c总线的SCL引脚, 当且仅当启用i2c总线时才生效
RG_IL_CONEXP int getSdMiso () const { return READGUY_sd_miso; } // 目标sd卡的 MISO 引脚, sd_share_spi == 1 时无效
RG_IL_CONEXP int getSdMosi () const { return READGUY_sd_mosi; }// 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
RG_IL_CONEXP int getSdSclk () const { return READGUY_sd_sclk; }// 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
RG_IL_CONEXP int getSdCs () const { return READGUY_sd_cs; }// 目标sd卡的CS引脚. 对ESP32S3, 返回127代表使用SDMMC
RG_IL_CONEXP int getI2cSda () const { return READGUY_i2c_sda; }// 目标i2c总线的SDA引脚, 当且仅当启用i2c总线时才生效
RG_IL_CONEXP int getI2cScl () const { return READGUY_i2c_scl; }// 目标i2c总线的SCL引脚, 当且仅当启用i2c总线时才生效
//按键驱动部分, 为负代表高触发, 否则低触发,
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
constexpr int getBtn1Pin () const { return abs((int)READGUY_btn1)-1; }
constexpr int getBtn2Pin () const { return abs((int)READGUY_btn2)-1; }
constexpr int getBtn3Pin () const { return abs((int)READGUY_btn3)-1; }
constexpr int getBtn1Info() const { return READGUY_btn1; }
constexpr int getBtn2Info() const { return READGUY_btn2; }
constexpr int getBtn3Info() const { return READGUY_btn3; }
constexpr int getBlPin () const { return READGUY_bl_pin; } //前置光接口引脚IO
constexpr int getRtcType () const { return READGUY_rtc_type; } //现已弃用 RTC 功能. 保留是为了兼容性 让代码更简单维护
constexpr int getButtonsCount() const { return READGUY_buttons; } //按钮个数, 0-3都有可能
constexpr int getReadguy_user1 () const { return READGUY_user1; } //用户变量
constexpr int getReadguy_user2 () const { return READGUY_user2; } //用户变量
constexpr int getReadguy_user3 () const { return READGUY_user3; } //用户变量
constexpr int getReadguy_user4 () const { return READGUY_user4; } //用户变量
constexpr int getReadguy_user5 () const { return READGUY_user5; } //用户变量
constexpr int getReadguy_user6 () const { return READGUY_user6; } //用户变量
constexpr int getReadguy_user7 () const { return READGUY_user7; } //用户变量
constexpr int getReadguy_user8 () const { return READGUY_user8; } //用户变量
constexpr int getReadguy_user9 () const { return READGUY_user9; } //用户变量
constexpr int getReadguy_user10() const { return READGUY_user10;} //用户变量
constexpr int getReadguyUseSdio() const { //返回程序调用SD卡时 是否使用了SDIO
RG_IL_CONEXP int getBtn1Pin () const { return abs((int)READGUY_btn1)-1; }
RG_IL_CONEXP int getBtn2Pin () const { return abs((int)READGUY_btn2)-1; }
RG_IL_CONEXP int getBtn3Pin () const { return abs((int)READGUY_btn3)-1; }
RG_IL_CONEXP int getBtn1Info() const { return READGUY_btn1; }
RG_IL_CONEXP int getBtn2Info() const { return READGUY_btn2; }
RG_IL_CONEXP int getBtn3Info() const { return READGUY_btn3; }
RG_IL_CONEXP int getBlPin () const { return READGUY_bl_pin; } //前置光接口引脚IO
RG_IL_CONEXP int getRtcType () const { return READGUY_rtc_type; } //RTC 将在2.0实装 保留是为了兼容性 让代码更简单维护
RG_IL_CONEXP int getButtonsCount() const { return READGUY_buttons; } //按钮个数, 0-3都有可能
RG_IL_CONEXP int getReadguy_user1 () const { return READGUY_user1; } //用户变量
RG_IL_CONEXP int getReadguy_user2 () const { return READGUY_user2; } //用户变量
RG_IL_CONEXP int getReadguy_user3 () const { return READGUY_user3; } //用户变量
RG_IL_CONEXP int getReadguy_user4 () const { return READGUY_user4; } //用户变量
RG_IL_CONEXP int getReadguy_user5 () const { return READGUY_user5; } //用户变量
RG_IL_CONEXP int getReadguy_user6 () const { return READGUY_user6; } //用户变量
RG_IL_CONEXP int getReadguy_user7 () const { return READGUY_user7; } //用户变量
RG_IL_CONEXP int getReadguy_user8 () const { return READGUY_user8; } //用户变量
RG_IL_CONEXP int getReadguy_user9 () const { return READGUY_user9; } //用户变量
RG_IL_CONEXP int getReadguy_user10() const { return READGUY_user10;} //用户变量
RG_IL_CONEXP bool getReadguyUseSdio() const { //返回程序调用SD卡时 是否使用了SDIO
#ifdef CONFIG_IDF_TARGET_ESP32S3 //仅对ESP32S3可用
return (READGUY_user1 != -1) && (READGUY_user2 != -1);
return (READGUY_user1 != -1) && (READGUY_user2 != -1) && (READGUY_sd_cs != -1);
#else
return 0; //非ESP32S3平台不可用SDIO
#endif
} //用于esp32s3使用SDIO卡数据的DAT2
#ifdef CONFIG_IDF_TARGET_ESP32S3 //仅对ESP32S3可用
constexpr int getSdio_dat0 () const { return getReadguyUseSdio()?READGUY_sd_miso:-1; } //用于esp32s3使用SDIO卡数据的DAT0
constexpr int getSdio_dat1 () const { return getReadguyUseSdio()?READGUY_user1 :-1; } //用于esp32s3使用SDIO卡数据的DAT1
constexpr int getSdio_dat2 () const { return getReadguyUseSdio()?READGUY_user2 :-1; } //用于esp32s3使用SDIO卡数据的DAT2
constexpr int getSdio_dat3 () const { return getReadguyUseSdio()?READGUY_sd_cs :-1; } //用于esp32s3使用SDIO卡数据的DAT3
constexpr int getSdio_clk () const { return getReadguyUseSdio()?READGUY_sd_sclk:-1; } //用于esp32s3使用SDIO卡数据的CLK
constexpr int getSdio_cmd () const { return getReadguyUseSdio()?READGUY_sd_mosi:-1; } //用于esp32s3使用SDIO卡数据的CMD
RG_IL_CONEXP int getSdio_dat0 () const { return getReadguyUseSdio()?READGUY_sd_miso:-1; } //用于esp32s3使用SDIO卡数据的DAT0
RG_IL_CONEXP int getSdio_dat1 () const { return getReadguyUseSdio()?READGUY_user1 :-1; } //用于esp32s3使用SDIO卡数据的DAT1
RG_IL_CONEXP int getSdio_dat2 () const { return getReadguyUseSdio()?READGUY_user2 :-1; } //用于esp32s3使用SDIO卡数据的DAT2
RG_IL_CONEXP int getSdio_dat3 () const { return getReadguyUseSdio()?READGUY_sd_cs :-1; } //用于esp32s3使用SDIO卡数据的DAT3
RG_IL_CONEXP int getSdio_clk () const { return getReadguyUseSdio()?READGUY_sd_sclk:-1; } //用于esp32s3使用SDIO卡数据的CLK
RG_IL_CONEXP int getSdio_cmd () const { return getReadguyUseSdio()?READGUY_sd_mosi:-1; } //用于esp32s3使用SDIO卡数据的CMD
#else
constexpr int getSdio_dat0 () const { return -1; } //用于esp32s3使用SDIO卡数据的DAT0
constexpr int getSdio_dat1 () const { return -1; } //用于esp32s3使用SDIO卡数据的DAT1
constexpr int getSdio_dat2 () const { return -1; } //用于esp32s3使用SDIO卡数据的DAT2
constexpr int getSdio_dat3 () const { return -1; } //用于esp32s3使用SDIO卡数据的DAT3
constexpr int getSdio_clk () const { return -1; } //用于esp32s3使用SDIO卡数据的CLK
constexpr int getSdio_cmd () const { return -1; } //用于esp32s3使用SDIO卡数据的CMD
RG_IL_CONEXP int getSdio_dat0 () const { return -1; } //用于esp32s3使用SDIO卡数据的DAT0
RG_IL_CONEXP int getSdio_dat1 () const { return -1; } //用于esp32s3使用SDIO卡数据的DAT1
RG_IL_CONEXP int getSdio_dat2 () const { return -1; } //用于esp32s3使用SDIO卡数据的DAT2
RG_IL_CONEXP int getSdio_dat3 () const { return -1; } //用于esp32s3使用SDIO卡数据的DAT3
RG_IL_CONEXP int getSdio_clk () const { return -1; } //用于esp32s3使用SDIO卡数据的CLK
RG_IL_CONEXP int getSdio_cmd () const { return -1; } //用于esp32s3使用SDIO卡数据的CMD
#endif
//constexpr int memWidth () const { return guy_width ; } //返回显存宽度(不是画幅宽度),不会随着画布旋转改变
//constexpr int memHeight () const { return guy_height ; } //返回显存高度(不是画幅高度),不会随着画布旋转改变
//RG_IL_CONEXP int memWidth () const { return guy_width ; } //返回显存宽度(不是画幅宽度),不会随着画布旋转改变
//RG_IL_CONEXP 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 (getRotation()&1)?drvHeight():drvWidth(); }
@@ -562,5 +591,6 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
void drawImageStage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,int32_t x,int32_t y,
uint8_t stage,uint8_t totalstage,int32_t zoomw=0,int32_t zoomh=0);
};
#undef RG_IL_CONEXP
#endif /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */