完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
概要 单片机esp32s2+SPI屏实现一个win10 USB接口显示器。 目前FPS在~13FPS,纯黑屏幕时能摸到20FPS。 主机使用IDD显示驱动方案,将屏幕进行JPEG压缩,然后通过URB(USB请求包)发送到下位机。下位机解压并发DMA传输写屏达到高性能。下位机esp32s2只支持全速度12Mhz,所以必须高压缩的JPEG才能有高FPS. 为了获得较稳定的FPS,采用了动态码率策略,会依据图像情况,进行压缩率调整。
以下链接与卖家只是我买的地方,仅作参考,只是型号是一样的,东西是同一种,有门道能找到更便宜的卖家最好。 像ESP-12H-Kit单独买模块小板就只要10块,适合自己做PCB板。 最近也支持了st7789这种屏。
这个是组双屏的效果,通常一个屏就好了。 3.硬件连接图 4 .安装说明 4.1 ESP32-S2固件更新 使用下载工具更新固件。第一次应该要更新所有的文件,包括bootloader.bin,partion-table.bin 4.2 windows驱动安装 因为目前没有给驱动签名,所以要关掉windows对驱动的检查,使用测试模式。 如果相对比较稳定后,看要不要弄个签名,淘宝上卖家签名一次要300! 4.2.1 启用测试模式 使用管理员身份打开命令行cmd bcdedit /set testsigning on 重启系统,桌面右下角会有一个测试模式的水印。如下图。 如果要关掉,使用bcdedit /set testsigning off 然后重启即可。 4.2.2 安装驱动 1. 插入已经更新好esp32s2设备,这一步应该的固件。会被windows识别为未知设备,如下图。我们的USB设备号为:USBVID_303A&PID_1986 2. 复制驱动文件到桌面,或者其它地方。
有兴趣的可以自己魔改,增加更多的设置,和更大的屏幕。
4.1 esp32s2 设备固件编译 Esp-idf版本:v4.3-beta3 4.1.1. esp32s2_u***disp 复制到esp-idf目录下 本身就是一个esp-idf工程 4.1.2 更新tinyu*** Tinyu***.tgz 解压合并放入esp-idf/components/tinyu***。图省事没有生成patch.大家可以用比较工具比较差异,改动并不大,主要是增加 vendor模式。需要注意的是,目前USB的改法是个临时方案,可能会对其它tinyu***有影响。 4.1.3 配置工程 进入esp32s2_u***disp idf.py set-target esp32s2 #设置目标芯片 idf.py menuconfig #修改配置, 相关4个配置如下:主要是配置LCD管脚,提高CPU频率到 240M,编译为O2性能模式,使能 tinyUSB 4.1.4 编译 idf.py build 生成固件 4.1.5 可选的杂项 串口连接S2查看工作状态 默认打印FPS 开机logo 实现了一个开机图片,一个重要的功能是表明屏驱动在工作。是内嵌jpeg 文件的数组。具体是 logo.c 实现。 只要替换这个logo_jpg数组的内容即可。大小不要超过320*240. 我是用 git://github.com/Jamesits/bin2array.git 实现转换的,python小工具。 4.2 windows驱动编译 本人使用是vs2015+wdk10,也可以使用vs2019+wdk10等。大家可以自己看情况,网上也有相关教程。如果不想魔改,这个驱动也应该够用了。能魔改更好。 打开工程,右键工程,选择生成。 然后会在类似下面的路径生成驱动包。这个是x64的,应该没人用32位的系统吧?
从设计实现上,本软件是支持2种数据模式,一种rgb565直传,一种是jpeg压缩数据。 USB传输也实现了两种:一种是同步,一种是异步模式。异步从理论上讲性能要好一些。 rgb565直传,同步模式主要是为了调试而存在了。 6.1 ESP32固件架构 U***实现了一个vendor自己定义的USB设备,有一个in 管道。 注册一个回调处理函数tud_vendor_rx_cb,收到一个数据包64字节。 先进行头解析,如果是起始包byte[0] bit7 置位,表明一个操作开始,解析相应参数(total_size,top,bottom,...)。 然后将数据推入缓存disp_rx_ring_buf中。 显示线程,从disp_rx_ring_buf抽取数据进程处理,目前都是jpeg的显示数据,所以都会走jpeg显示处理,边接收数据边解码,积累到足够多时(一次多传输点,能降低额外开销,提高速度),启动SPI dma进行送显。同时会交换ping-pong buffer. 并行进行,提高FPS. 主机与设备通讯协议是沿用rpu***disp的协议。就是消息头改了下: 该协议的要点: USB是包消息,并且是固定长度64byte(大体如此),最后一个包例外。所以每个包第一个字节是协议占用,表明类型。好处是方便定位消息头部:如果第一个字节的bit7置位,就是一个新的操作,否则是数据。这样利于出错恢复。 解码与屏幕刷新: 1.这种是dma模式的spi,跑的是40Mhz,理论带宽可以跑到30 fps,如果spi是80Mhz的.屏幕也支持的话,就加倍了60fps。 2.另外一个关键点是边解码边刷数据,并行做。比如数据一帧要50ms.传输也要50ms.那串行就要100.并行就只要50ms. 3.一次刷dma数据不要太少,建议一次传5kb,降低非必要开销。具体大小要和数据配合调优。 6.2 windows驱动架构 大体框架是基于MS的idd驱动sampledriver,所以我只讲增加的部分。 1.在void SwapChainProcessor::RunCore()采集屏幕数据,当前没有找dirty区域,因为懒。 直接复制整个屏幕.
不才,欢迎相互交流下经验。 7.1 windows调试: 主要有2种,一种是用tracevew来查看驱动日志,另一种是windbg。 目前没有明显的bug,应该都用不上。只是开发过程中用得比较多。 7.2 esp32调试: 主要是log,当然也有一些高级点的调试,比如通过panic dump信息来正面刚来调试。 7.进一步的工作: 提高FPS,当前的瓶颈在于JPEG解码开销。 可能的方法:
320*240对于桌面来说,分辨率小了些。因此可以考虑用安卓手机来当下位机显示器。 |
|||||
|
|||||
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2956 浏览 16 评论
3457 浏览 1 评论
8996 浏览 16 评论
4050 浏览 18 评论
1107浏览 3评论
572浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1858浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 05:54 , Processed in 1.126645 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号