KDocs 研发资料库
  • 手表穿戴技术应用文档入口汇总
  • JL707N穿戴客述问题FAQ
  • 彩屏仓 硬件开发指南 与 量产作业流程规范
  • 彩屏仓 AC98N和JL701烧录升级注意事项
  • JL707 硬件开发资料
  • JL707 手表硬件设计注意事项 总结
  • 穿戴生产烧录OTA和key文件添加使用说明
  • JL707N-入门到进阶开发指导文档
  • 彩屏仓982相关
  • 彩屏仓耳机介绍
  • 杰理701_707双屏demo介绍
  • 707电子吧唧开发资料
  • GPIO相关
  • UART串口相关
  • SPI相关
  • nandflash相关
  • norflash相关
  • IIC相关
  • PWM相关
  • SD卡相关
  • 定时器TIMER
  • 文件系统接口设计说明文档
  • 音视频录像开发流程
  • rdec编码器
  • 穿戴功耗数据标准
  • 手表蓝牙开发文档
  • 701蓝牙PAN联网demo
  • BLE开发使用说明
  • 701手表2.0.0版本SDK EQ在线调试和离线调试方法 V1.1
  • JL707 手表喇叭输出声音大小评估方法 V1.0
  • JL707 手表音频EQ调试方法 V1.0
  • AC707N 手表通话写卡 软件配置方法
  • 录音功能
  • 701手表2.X.X系列SDK调试EQ配置方法及音频调试技巧V1.1
  • 701手表104版本SDK EQ在线调试和离线调试方法 V1.1
  • mic2dac示例
  • P11 SensorHub相关
  • 手表升级操作文档
  • AC707NGPU
  • DBI模块介绍
  • GPU模块介绍
  • 701N屏幕驱动配置说明
  • 701N_UI编辑工具用户手册
  • 支付宝资料
  • 支付宝硬件接入资料
  • 支付宝乘车码接入资料
  • CAT1 接入文档
  • 701N_WATCH_CAT1开发说明
  • Findmy功能
  • music模式相关
  • 707电池曲线
  • 707N内置FLASH挂载FAT文件系统251112_v1.2
  • AC707N_本地视频播放demo(AVI-MJPEG-PCM)
  • 光波导屏幕调试
  • 耳机研发和生产流程 指南
  • 707-NandFlash 代码和UI资源独立烧录方案
  • 彩屏仓时间同步补丁
  • 彩屏仓抖音点赞移植
  • 707LVGLv8双屏开发
  • 707N蓝牙互传图传demo
  • AVIPCM数据流接入AIVOICE
  • Flash分区操作demo
  • 手表发射问题
  • 701_707 双备份升级DEMO
  • 707_乘车码刷码失败问题_共性

707N彩屏仓屏显调试

📎 原始文档:https://www.kdocs.cn/l/ctX5e9qrEXTe 707N彩屏屏显调试

1.常规带RAM屏的驱动基本配置:

📌屏驱动C文件基本配置部分

#define LCD_DRIVE_CONFIG:屏幕接口配置,其中“单线SPI+DC屏”建议使用SPI_4WIRE_RGB565_1T8B模式,707的D1引脚接屏DC。其它按照701配置即可。
#define SCR_X 0 :2A指令的偏移,并非画面偏移
#define SCR_Y 0 :2B指令的偏移,并非画面偏移
LCD_BLOCK_H:分块高度,分块的操作流程在gpu_task.c开放了一部分。
.fps = 65:数据接口速率,如SPI的速率。

初始化指令、进出休眠接口、纯色debug模式、ID、LOGO配置等等请参考9B71的屏驱动代码配置方式即
具体调用指令顺序请跟踪lcd_drv_init()代码。

💡GRAM屏的数据顺序

CPU ->GRAM -> 屏幕

  1. CPU发送2A/2B/2C/3C指定区域写到GRAM:这一步是将图像数据写入图形内存(GRAM)。不同的区域(如2A、2B、2C、3C)可能代表不同的图像层或图形对象,CPU将这些数据传输到GRAM中,以便后续处理。
  2. Scanline扫描:显示控制器会逐行扫描GRAM中的数据,并将其转换为屏幕上可见的图像。这个过程通常是通过逐行读取内存中的像素数据,并将其发送到显示设备来完成的。 image

💡TE信号同步

  • FMARK信号:scanline到某一个屏幕垂直方向的某一个位置,触发中断信号输出,即TE信号,用于通知CPU发同步发送显示数据。
  • 1TE模式:超前模式,即1TE发一帧数据,比如TE是60Hz,实际显示是60FPS。
  • 2TE模式:滞后模式,即2TE发一帧数据,比如TE是60Hz,实际显示是30FPS。

📌屏幕调切线常用寄存器(仅供参考,具体查看屏IC的数据手册):

0x35:设置FMARK信号垂直位置,如果有一条固定切线,一般是推数据稍微超前了一下scanline,因此需要加大FMARK信号的位置让数据总体滞后。tear line
0x36:通过SPI获取屏幕scanline的位置,只有部分屏幕支持,代替TE功能。
0xC6:设置scanline的刷新频率,也是TE频率,也是GRAM显示到显示屏的频率。

📌2TE模式消除切线的方法(整屏刷):

  • 2倍的TE周期 > CPU写到GRAM的时间 > 1倍的TE周期
  • 确保W与R永远不相交
  • SPI速率要适中,不能太快和太慢
  • 触发SPI数据可能要稍微滞后一点scanline,如SPI推屏稍微滞后一点TE中断,或者触发TE的位置往下调(0x35) image 如上图示为2TE推屏模式,上方为spi数据,下方为TE信信号,1触发A帧发送SPI,并要在2-3之间结束,即C需要在2-3之间,然后3再次触发下一帧即B帧发送SPI,D要在4-5之间,以此类推。

📌1TE模式消除切线的方法(整屏刷):

  • CPU写到GRAM的时间 < 1倍的TE周期
  • 确保W与R永远不相交
  • SPI速度尽量调高
  • 触发SPI数据可能要稍微超前一点scanline,如SPI推屏稍微超前一点TE中断,或者触发TE的位置往上调(0x35) image 如上图示为1TE推屏模式,上方为spi数据,下方为TE信信号,1触发A帧发送SPI,并要在1-2之间结束,即C需要在1-2之间,然后2再次触发下一帧即B帧发送SPI,D要在2-3之间,以此类推。

📌局部刷

核心思路只要保证W与R永远不相交即可,具体何时触发需要程序软件去预估scanline位置,具体代码可参考#define TCFG_LCD_TE_USED_PEND与#define TCFG_LCD_TE_QUICK_SYNC所包含代码。

参考资料:
https://www.bilibili.com/read/cv18740493/
https://www.bilibili.com/read/cv28161505/

📌添加9307与3030屏驱动案例

  1. 在屏触摸驱动文件添加屏幕型号对应触摸配置信息,根据实际情况去调试是否使用镜像翻转,以及设置好触摸范围。 cst816.c
// 触摸信息配置
#if (defined TCFG_LCD_NB3030_172X320 && TCFG_LCD_NB3030_172X320)
#define X_MIRROR        1
#define Y_MIRROR        0
#define VK_X            320
#define VK_Y            172
#define TP_FPS          60
#elif (defined TCFG_LCD_GC9307_172X320 && TCFG_LCD_GC9307_172X320)
#define X_MIRROR        1
#define Y_MIRROR        0
#define VK_X            320
#define VK_Y            172
#define TP_FPS          60
  1. 配置好TP 的中断和复位IO
//*********************************************************************************//
//                                 tp   配置                                      //
//*********************************************************************************//
#define TCFG_TOUCH_PANEL_ENABLE                 1
#define TCFG_TP_CST816D_ENABLE                  1
#define TCFG_TP_SLEEP_EN                        1
#define TCFG_TP_INT_IO                          IO_PORTB_01 //TP中断脚
#define TCFG_TP_RESET_IO                        IO_PORTA_02 //TP复位脚
  1. LCD添加屏驱动的宏
    //*********************************************************************************//
//                                 LCD   配置                                      //
//*********************************************************************************//

#define TCFG_SPI_LCD_ENABLE 1//spi lcd开关
#define TCFG_LCD_NB3030_172X320 1
#define TCFG_LCD_GC9307_172X320 0
  1. LCD配置TE,根据实际情况开关,有些屏幕没有TE引出,可以关闭TCFG_LCD_TE_USED_PEND与这TCFG_LCD_TE_QUICK_SYNC两个宏,如小屏的9307。
#define TCFG_LCD_TE_USED_PEND   0//1
#define TCFG_LCD_TE_QUICK_SYNC                  0//1//te优化策略

如果关闭TE出现编译不过,添加空函数变量:

volatile int64_t dc_te_absolute_us;
volatile int64_t dc_start_absolute_us;
volatile  int  lcd_spi_last_us   = 25 * 1000;
u32 lcd_get_te_frame_period_us(void)
{
    return 16000;
}
  1. LCD与TP供电口配置,如果电路图是PC1供电,芯片内部PC1与PC2是双绑的,需要将pin_en与pin_en_ex两个引脚同时配置,如去除PC1供电:
LCD_SPI_PLATFORM_DATA_BEGIN(lcd_spi_data) = {
    .pin_reset = IO_PORTB_00,//IO_PORTC_03,

    .pin_en =    NO_CONFIG_PORT,//IO_PORTC_01,
    .pin_en_ex = NO_CONFIG_PORT,//IO_PORTC_02,

    .pin_te = TCFG_LCD_TE_IO,
    .pin_bl = TCFG_LCD_BL_IO,
    LCD_SPI_PLATFORM_DATA_END()
};
  1. LCD其它引脚配置更改
#define TCFG_LCD_PIN_RESET IO_PORTB_00//IO_PORTA_03 // LCD RESET
#define TCFG_LCD_PIN_CS IO_PORTA_07//IO_PORTA_04 // LCD CS
#define TCFG_LCD_PIN_BL NO_CONFIG_PORT // LCD BLCKLIGHT
#define TCFG_LCD_PIN_DC IO_PORTA_09//IO_PORTA_02 // LCD DC
#define TCFG_LCD_PIN_EN NO_CONFIG_PORT // LCD EN
#define TCFG_LCD_PIN_TE IO_PORTC_00 // LCD TE
  1. lcd_conf.h新添加LCD_WIDTH与LCD_HEIGHT宏
#include "app_config.h"

#if defined(TCFG_LCD_NB3030_172X320) && TCFG_LCD_NB3030_172X320
#define LCD_WIDTH  320
#define LCD_HEIGHT 172
#endif

#if defined(TCFG_LCD_GC9307_172X320) && TCFG_LCD_GC9307_172X320
#define LCD_WIDTH  320
#define LCD_HEIGHT 172
#endif
  1. 添加设置TE的相位,用于切线与帧率优化,根据实际情况调试
#if (defined TCFG_LCD_NB3030_172X320 && TCFG_LCD_NB3030_172X320)
const int  lcd_te_display_line = 0x80;
#elif (defined TCFG_LCD_GC9307_172X320 && TCFG_LCD_GC9307_172X320)
const int  lcd_te_display_line = 0x80;
  1. makefile或者cbp添加屏幕驱动文件
cpu/br35/ui_driver/lcd_drive/lcd_spi/lcd_spi_gc9307_RQ_BOE_172x320.c \
cpu/br35/ui_driver/lcd_drive/lcd_spi/oled_spi_nb3030_172x320.c \

📌LCD初始化

lcd_drv_init()

📌JL框架合成推屏

以分3块双BUF举例

GPU任务合成分块1合成分块2合成分块3合成分块1合成分块2合成分块3合成分块1
DMA推屏推屏分块3推屏分块1推屏分块2推屏分块3推屏分块1推屏分块2推屏分块3
UI任务用户层JL UI,包括动画,拿资源,配置下一帧的任务链ui_platform.c用户层UI,配置下一帧任务链
// GPU任务
static void jlgpu_task(void *p)
{
    int ret;
    int msg[32] = {0};

    while (1) {
        ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
        if (ret != OS_TASKQ) {
            continue;
        }

        switch (msg[0]) {
        case GPU_MSG_DRAW:
            IO_GPU_HIGH();
            pJLGPUMultTaskList_t mult_list = (pJLGPUMultTaskList_t)msg[2];
            jlgpu_scheduler_kick_start(mult_list, &__this->dc);
            break;
        case GPU_MSG_OTHER:
            break;
        default:
            break;
        }
    }
}

UI任务配置GPU的任务链在:ui_platform.c文件,第三方框架可参考。

📌第三方推屏接口(2A、2B、2C、3C)

/* ------------------------------------------------------------------------------------*/
/**
 * @brief lcd_set_draw_area 设置LCD显示区域(2A, 2B命令)
 *
 * @param xstart X起始像素坐标
 * @param xend   X结束像素坐标
 * @param ystart Y起始像素坐标
 * @param yend   Y结束像素坐标
 */
/* ------------------------------------------------------------------------------------*/
void lcd_set_draw_area(int xstart, int xend, int ystart, int yend);


/* ------------------------------------------------------------------------------------*/
/**
 * @brief lcd_draw DBI硬件写显示数据到LCD, 非阻塞接口,与lcd_set_draw_area配合使用
 *
 * @param buf     待写出数据
 * @param xstart  X起始像素坐标
 * @param xend    X结束像素坐标
 * @param ystart  Y起始像素坐标
 * @param yend    Y结束像素坐标
 */
/* ------------------------------------------------------------------------------------*/
void lcd_draw(u8 *buf, int xstart, int xend, int ystart, int yend);

/* ------------------------------------------------------------------------------------*/
/**
 * @brief lcd_draw_continue DBI硬件以续传方式写显示数据到LCD, 非阻塞接口,与lcd_set_draw_area、lcd_draw配合使用
 *
 * @param buf     待写出数据
 * @param xstart  X起始像素坐标
 * @param xend    X结束像素坐标
 * @param ystart  Y起始像素坐标
 * @param yend    Y结束像素坐标
 */
/* ------------------------------------------------------------------------------------*/
void lcd_draw_continue(u8 *buf, int xstart, int xend, int ystart, int yend);

2.横屏设计

💡方法一:LCD寄存器90/270旋转(UI横屏设计,横屏推送)

  • 寄存器设置
    

    值得一提的是,这类LCD一般有一个指令用于设置行列地址转换的,可以变更LCD的横竖屏。比如ST7789的0x36指令参数的MV位:
    image

    尽管这在我们看起来是切换了横竖屏,但对于扫描线scanline而言,始终与LCD的排线互相垂直,手册中也有提到这一点,扫描线与MV位无关。
    image ST7789手册关于MV和TE的描述
    这里看似在说TE信号,实际上TE信号就是由扫描线触发的,因此可得知扫描线不受MV的影响。
    也就是说,当你设置了MV,试图把竖屏当横屏或者横屏当做竖屏使用时,扫描线依旧是垂直的.

  • 旋转后传输路径以及斜切现象 flowchart 上方cpu为常规推屏,下方cpu为经过MV90/270翻转后推屏,可以看出与scanline方向不一致

image 左图为常规推屏两线不相交、右图为MV翻转后出现切切现象

  • 解决斜切的理论方法 让总体的分块推的方向保持和Scan Line方向一致,即第一块、到第二块、到第三块的方向与scanline一致,分块不能太大也不能太小,太大达不到scanline与推屏错开的效果,太小绘制效率会下降,需要互相兼顾,选取合适的分块数。并且分块需要是原图的X方向分块,不能是Y方向,才能确保更改数据部分与scanline不发生相交。
    flowchart 此外,要注意部分小屏幕,如172*320的NB3030和GC9307,如上图所示,红色部分才是真正的显示屏部分,位于GRAM的中间,屏幕左上起始点相对GRAM起始点偏移34,针对这种小屏需要给2A或者2B指令一个34偏移,一般默认是要给2A偏移,MV翻转后则给2B偏移,具体实操参考下文例子。

📌X轴分块+MV硬件旋转修(未验证过)

以 NB3030和GC9307为例

  • 软件使能X轴分块:#define DRAW_X_DIV_EN 1
  • 调整X轴分块刷的总体方向(从左至右或者从右至左):#define DRAW_R_TO_L 0
  • 给屏驱动初始化修改0x36寄存器,使能MV,如下:
#define MY 0//1     //Y反向(画面)
#define MX 1//0     //X反向(画面)
#define MV 1     //90旋转(画面)
#define ML 0//1     //LCD垂直反向(SCANLINE)
#define BGR 1       //大小端颜色
#define MH 0//0     //LCD水平反向(SCANLINE)

_BEGIN_, 0x36, (MY<<7)|(MX<<6)|(MV<<5)|(ML<<4)|(BGR<<3)|(MH<<2), _END_,
  • 设置好绘制区域的偏移,一般LCD寄存器使能MV后2B可能需要偏移,如172*320 9307需偏移34,所以给SCR_Y 34
#define SCR_X       0  // 2A偏移
#define SCR_Y       34 // 2B偏移
#define SCR_W       LCD_WIDTH     //    画面宽度
#define SCR_H       LCD_HEIGHT    //    画面高度

💡方法二:CPU软件旋转90/270度(UI横屏设计 竖屏推送)

同样需要让总体的分块推的方向保持和Scan Line方向一致,需要原图(即以UI工程的图为准)的X方向分块,软件端作旋转,从而实现推屏与scanline同方向并且互相错开:
flowchart

📌X轴分块+软件旋转修改如下(已验证过)

以 NB3030和GC9307为例

  • 软件使能X轴分块:#define DRAW_X_DIV_EN 1
  • 调整X轴分块刷的总体方向(从左至右或者从右至左):#define DRAW_R_TO_L 0
  • 使能BUF软件旋转:#define DRAW_BUF_ROTATE 1
  • 旋转90度还是270度:#define RBUF_270 1
// 消除屏幕切线优化
#define DRAW_X_DIV_EN      1//UI横屏设计,使能X方向分块,让分块buf与scanline扫描方向一致
#if DRAW_X_DIV_EN
#define DRAW_R_TO_L        0//X方向反向分块刷
#define DRAW_BUF_ROTATE    1//使能BUF旋转
#define RBUF_270           1//1:270 0:90
#endif
  • 设置好绘制区域的偏移,小屏2A可能需要偏移,如172*320 9307需偏移34,所以给SCR_X 34
#define SCR_X       34  // 2A偏移
#define SCR_Y       0 // 2B偏移
#define SCR_W       LCD_WIDTH     //    画面宽度
#define SCR_H       LCD_HEIGHT    //    画面高度

📌具体横屏代码参考 #define DRAW_X_DIV_EN所包含的代码。

3.sram buf 做90/270度旋转,使用GPU与CPU的区别

9307 320172 90/270度条件下测试,一共分9块。
sw_rgb565buf_rotate():CPU软件实现,测试耗时260us
9 = 2.3ms。
hw_rgb565buf_rotate():GPU硬件实现,测试耗时1.1ms*9 = 10ms。
以下为CPU与GPU具体实现BUF 90/270度方法举例:

// CPU方法
static void sw_rgb565buf_rotate(u16 * rot_buf, u16 * src_color_p, int area_w, int area_h){

    uint32_t invert = (area_w * area_h) - 1;
    uint32_t initial_i = ((area_w - 1) * area_h);
    for(u16 y = 0; y < area_h; y++) {
        uint32_t i = initial_i + y;
#if(RBUF_270)
            i = invert - i;
#endif
        for(u16 x = 0; x < area_w; x++) {
            rot_buf[i] = *(src_color_p++);
#if(RBUF_270)
                i += area_h;
#else
                i -= area_h;
#endif
        }
    }
}
// GPU方法
static void hw_rgb565buf_rotate(u16 * rot_buf, u16 * src_color_p, int area_w, int area_h){
    //  输出区域
    struct rect mask_r_temp = {0};
    struct rect * mask_r = &mask_r_temp;
    mask_r->left = 0;
    mask_r->top = 0;
    mask_r->width = area_w;
    mask_r->height = area_h;

    struct rect disp_r_temp = {0};
    struct rect * disp_r = &disp_r_temp;
    disp_r->left = 0;
    disp_r->top = 0;
    disp_r->width = area_h;
    disp_r->height = area_w;

    uint8_t  * mask_buf = src_color_p;
    uint8_t  * disp_buf = rot_buf;

    int in_format = GPU_FORMAT_RGB565;

    u16 color =0xff;
    int r = ((color >> 11) & 0x1f) << 3;
    int g = ((color >> 5) & 0x3f) << 2;
    int b = ((color) & 0x1f) << 3;
    // printf("%s (%d %d %d %d) (%d %d %d %d) %x %x (%d %d %d)", __func__,
    //        mask_r->left, mask_r->top, mask_r->width, mask_r->height,
    //        disp_r->left, disp_r->top, disp_r->width, disp_r->height,
    //        (int)mask_buf, (int)disp_buf, r, g, b);

    gpu_out_params_t out_param = { 0 };
    gpu_basic_params_t basic_param = { 0 };
    gpu_transform_params_t transform_param = {0};

    out_param.data = (uint8_t *)disp_buf;
    out_param.win_x_min = disp_r->left;
    out_param.win_x_max = disp_r->left + disp_r->width ;
    out_param.win_y_min = disp_r->top;
    out_param.win_y_max = disp_r->top +  disp_r->height ;
    out_param.stride = disp_r->width * 2;
    out_param.format = GPU_FORMAT_RGB565;

    basic_param.act_x_min = disp_r->left;//mask_r->left ;
    basic_param.act_x_max = disp_r->left + disp_r->width;//mask_r->left + mask_r->width;
    basic_param.act_y_min = disp_r->top;//mask_r->top ;
    basic_param.act_y_max = disp_r->top + disp_r->height;//mask_r->top + mask_r->height;
    // basic_param.act_x_min = draw_r->left ;
    // basic_param.act_x_max = draw_r->left + draw_r->width ;
    // basic_param.act_y_min = draw_r->top ;
    // basic_param.act_y_max = draw_r->top + draw_r->height;
    // printf("basic:{%d %d %d %d}", basic_param.act_x_min, basic_param.act_x_max, basic_param.act_y_min, basic_param.act_y_max);
    basic_param.alpha = 255;
    basic_param.red = r;
    basic_param.green = g;
    basic_param.blue = b;
    basic_param.layer_en = 1;
    basic_param.blend_mode = 1;
    basic_param.global_alpha = 128; //范围:0-128
    basic_param.premult  = 0;

    gpu_texture_params_t texture_param = { 0 };
    texture_param.adr_mode = 1;
    texture_param.data = mask_buf;
    texture_param.format = in_format;
    texture_param.compress_mode = 0;
    texture_param.stride = (mask_r->width * gpu_get_format_bpp(in_format) + 7) / 8 ;
    texture_param.compress_size = mask_r->width;
    texture_param.big_end = 0;

    float zoom_w = (float)1 / 1.0;
    float zoom_h = (float)1 / 1.0;
    gpu_matrix_t matrix = {0};
    gpu_matrix_set_identity(&matrix);
    float tran_x = area_h;//area_w;//10;//(float)mask_r->left;
    float tran_y = 0;//(float)mask_r->top;

    


    gpu_matrix_translate(&matrix, -tran_x, -tran_y);
    // gpu_matrix_scale(&matrix, zoom_w, zoom_h);
    static float aaaa = -3.14159/2.0;

    // g_printf("11 %f %f %f %f %f %f", matrix.m[0][0],matrix.m[0][1],matrix.m[0][2],matrix.m[1][0],matrix.m[1][1],matrix.m[1][2]);
    gpu_matrix_rotate(&matrix, aaaa);
    // g_printf("22 %f %f %f %f %f %f", matrix.m[0][0],matrix.m[0][1],matrix.m[0][2],matrix.m[1][0],matrix.m[1][1],matrix.m[1][2]);

    // printf("%s %f %f %f %f\n", __func__, zoom_w, zoom_h, tran_x, tran_y);
    transform_param.M00 = matrix.m[0][0];
    transform_param.M01 = matrix.m[0][1];
    transform_param.M02 = matrix.m[0][2] - 0.5 * transform_param.M00 - 0.5 * transform_param.M01 + 0.5;
    transform_param.M10 = matrix.m[1][0];
    transform_param.M11 = matrix.m[1][1];
    transform_param.M12 = matrix.m[1][2] - 0.5 * transform_param.M10 - 0.5 * transform_param.M11 + 0.5;
    transform_param.fg_x_min = 0;
    transform_param.fg_x_max = mask_r->width;
    transform_param.fg_y_min = 0;
    transform_param.fg_y_max = mask_r->height;
    transform_param.sample_mode = 0;
    transform_param.shift_sel = 6;
    uint8_t mode = GPU_TEXTURE_AFFINE;
    gpu_reset_all_regs(mode);
    gpu_texture_affine(&basic_param, &texture_param, &transform_param);
    gpu_set_out_layer(&out_param);
    gpu_isr_sem_clr();
    gpu_run();
    gpu_wait_done();

}

解释:90/270旋转这是特殊情况,可以不考虑cos'sin'以及浮点运算,CPU只是做交换的简易运算,主频高,因此会比较快速;而硬件运算会复杂很多,包括了三角函数以及浮点,矩阵变换,滤波等,所以时间会比CPU偏慢,这种情况只针对90/270特殊角度下成立,其它角度下依旧是GPU比旋转比软件要快的。目前小屏横屏90/270旋转还是用软件旋转方案比较现实和可靠。

4.彩屏仓开发板其它配置

修改波特率到1M,PC1输出用于debug

#define TCFG_DEBUG_UART_TX_PIN IO_PORTC_01//IO_PORTA_11//IO_PORTB_03 // 输出IO
#define TCFG_DEBUG_UART_BAUDRATE 1000000//0x1e8480 // 波特率

7076内置FLASH容量改成8M

#define     CONFIG_FLASH_SIZE 0x800000//0x1000000 // flash容量