ESP32S2软件设计
开机logo
实现开机logo功能,该功能旨在展示屏驱动的正常工作。logo图片以内嵌jpeg文件数组的形式呈现,具体实现位于logo.c文件中。如需更新logo,仅需替换logo_jpg数组的内容即可,但需确保图片尺寸不超过320*240像素,以确保显示效果的兼容性。转换jpeg文件为数组的工作借助了Jamesits提供的bin2array工具,该工具采用python脚本实现文件格式的转换。
USB设备与数据接收
本文基于IDF自带的tinyusb框架,构建了一个具有特定厂商ID(VID)为303A和产品ID(PID)为1986的USB外设设备。该设备实现了一个vendor自定义的USB设备类,并配备了一个输入IN管道。
通过注册tud_vendor_rx_cb回调处理函数,软件能够接收并处理来自USB的数据包,每次最多接收64字节的数据。在接收数据后,软件首先进行头部解析,若检测到起始标志位(byte[0]的bit7置位),则识别为一个新操作的开始,并解析相应的参数(如total_size, top, bottom等)。解析完成后,软件将有效数据推入缓存区disp_rx_ring_buf中,以便后续解码操作使用。
解码
在解码环节,显示线程负责从disp_rx_ring_buf中读取数据进行处理。由于当前处理的数据均为jpeg格式的显示数据,因此软件采用jpeg解码算法进行处理。jpg解码采用了适合单片机的开源项目jpgdec。其主要的特点是采用流式数据,无非等待接收完整jpg才能解码。
屏幕显示
采用了流行的SPI接口LCD,引脚占用少,性能优异,本文利用DMA模式的SPI进行数据传输,其运行频率设定为40Mhz。理论上,该配置能够支持高达30fps的帧率。若SPI频率能够提升至80Mhz,且屏幕硬件支持,则帧率可进一步提升至60fps,从而带来更为流畅和高效的视觉体验。
帧率性能优化
初始阶段,帧率仅维持在8fps,视觉体验颇为滞涩,近似于幻灯片效果。因此,我们深入剖析了性能瓶颈的成因。主要问题在于显示流程的串行性,即接收一帧数据耗时10ms,解码jpg数据需60ms,再通过DMA传输上屏显示需40ms。
针对这一问题,我们确定了优化关键——实施流水线并行处理,即在解码过程中同时刷新数据。举例来说,若一帧数据的处理及传输各自耗时50ms,则串行处理需时100ms,而并行处理则仅需50ms。此外,为减少非必要开销,我们建议单次DMA数据传输量不宜过少,以5kB为宜,具体数值应根据实际情况与数据进行调优。
具体实施方案为:在接收jpg数据的同时进行解码,并将解码与DMA传输并行执行。为此,我们创建了两组各含8320个像素的缓冲数组,采用乒乓工作模式。每当解码完成一行8320个像素的数据时,即启动一次DMA传输上屏,同时继续解码下一行8*320像素数据,如此循环往复。
经过上述优化措施,最终将帧率提升至15fps,基本实现了流畅播放的效果。