This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320C6748:RGB LCD 显示不对齐问题

Guru**** 2782445 points

Other Parts Discussed in Thread: TMS320C6748

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1213793/tms320c6748-rgb-lcd-display-misalignment-issue

器件型号:TMS320C6748

P. Latform TMS320C6748.

LCD 接口:RGB565

活动屏幕尺寸:480*360

问题描述

在不同的 CPU 频率下、会显示相同的图片、数据每秒定期刷新一次。

当 CPU 频率设置为100MHz 时、图片将正常显示。 当频率增加到200MHz 或300MHz 时、数据刷新时、显示屏将会被错误定位。

正常图片和序列图表:

(图 1).正常显示

如图1所示、这是正常显示。

CPU 频率为100MHz、LCD_PCLK 频率为10MHz、屏幕刷新率约为51Hz。

逻辑分析仪捕获的信号如图2所示(红色框表示1帧范围):

(图 2).序列图对应于图 1

通道0:PCLK (10MHz)、

通道1:VS (51.6Hz)、

通道2:HS (19.8kHz)、

频道3:de、ó n

通道4:DATA0。

异常图片和序列图:

(图 3)。异常显示 A                      (图 4)。异常显示 B

如图3、 图4所示、这是异常显示。

CPU 频率为300MHz、LCD_PCLK 频率为10MHz、屏幕刷新率约为51Hz。

逻辑分析仪捕获的信号如图5所示(红色框表示1帧范围):

(图 5).序列图对应于图 3

正常和异常序列的比较分析:

由于(图1)和(图3)显示的内容基本相同、因此您可以通过比较确定、图5下面红色框中显示的内容只是一个数据帧。 但图5中的数据不与帧信号同步、例如 VS 和 DE。

(图6).DATA0数据波形比较

可以看出、图片显示的偏移是由数据和 VS 帧信号的同步引起的。

问题:

  • 上述显示位移是否与 CPU 频率有关?
  • 光栅 LCD 控制器通过 DMA 将图像数据发送到 LCD 显示屏。 如果 CPU 此时将图像数据写入显示缓冲区、是否会发生冲突? 如果存在冲突、如何解决?

  • 光栅 LCD 控制器通过 DMA 将图像数据发送到 LCD 显示屏。 如果 CPU 还使用 DMA 进行数据传输、是否会发生冲突? 如果存在冲突、如何解决?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    头文件 lcd_drv.h

    #ifndef _LCD_DRV_H_
    #define _LCD_DRV_H_
    
    #include <xdc/std.h>
    #include <stdio.h>
    #include <stdarg.h>
    
    #include "lcd_drv.h"
    
    //================================宏定义=========================================================
    
    // LCD 分辨率
    #define LCD_WIDTH               (480)
    #define LCD_HEIGHT              (360)
    
    // 调试板的大小和偏移
    #define PALETTE_SIZE            32
    #define PALETTE_OFFSET          4
    
    // TFT LCD显存数据结构体
    typedef struct
    {
    	uint8_t palette[PALETTE_OFFSET+PALETTE_SIZE];
    	uint16_t dat[LCD_HEIGHT][LCD_WIDTH];
    }fb_data_t;
    
    void tft_lcd_draw_pixel(uint16_t x, uint16_t y, uint16_t color);
    void tft_lcd_draw_xline(uint16_t x, uint16_t y, uint16_t length, uint16_t color);
    void tft_lcd_draw_yline(uint16_t x, uint16_t y, uint16_t length, uint16_t color);
    void tft_lcd_fill_rectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color, uint8_t dir_mode);
    
    void lcdc_raster_init(unsigned int cpu_freq);
    
    #endif
    
    
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    源文件 lcd_drv.c

    #include <xdc/std.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include "hw_types.h"
    #include "soc_C6748.h"
    #include "hw_psc_C6748.h"
    #include "hw_syscfg0_C6748.h"
    
    #include "psc.h"
    #include "gpio.h"
    #include "spi.h"
    #include "lidd.h"
    #include "raster.h"
    
    #include "lcd_drv.h"
    #include "Drv_SpiFlash.h"
    
    #include "board.h"
    
    #include "DEBUG_config.h"
    
    /************************外部变量******************************/
    //无
    
    /************************全局变量******************************/
    //无
    
    /************************模块局部变量******************************/
    //无
    
    #define GrOffScreen16BPPSize(lWidth, lHeight)            \
            (4 + (16*2) + (lWidth * lHeight * 2))
    
    #pragma DATA_ALIGN(g_pucBuffer0, 4);
    unsigned char g_pucBuffer0[GrOffScreen16BPPSize(LCD_WIDTH, LCD_HEIGHT)];
    
    // 图形库显示结构
    // tDisplay g_s800x480x16Display;
    
    // 调色板
    unsigned short palette_32b[PALETTE_SIZE/2] =
    			{0x4000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
    			 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u};
    
    // 全局显示上下文
    // tContext g_sContext;
    /****************************************************************************/
    /*                                                                          */
    /*              LCD 中断服务函数                                            */
    /*                                                                          */
    /****************************************************************************/
    void LCDIsr(void)
    {
        unsigned int  status;
    
        status = RasterIntStatus(SOC_LCDC_0_REGS,RASTER_END_OF_FRAME0_INT_STAT |
                                                 RASTER_END_OF_FRAME1_INT_STAT );
    
        RasterClearGetIntStatus(SOC_LCDC_0_REGS, status);
    }
    
    // 输入频率的单位是MHz
    void lcdc_raster_init(unsigned int cpu_freq)
    {
        // 禁用光栅
        RasterDisable(SOC_LCDC_0_REGS);
        
        // 时钟配置
        RasterClkConfig(SOC_LCDC_0_REGS,10000000, cpu_freq*1000000/2);
    
        // 配置 LCD DMA 控制器
        RasterDMAConfig(SOC_LCDC_0_REGS, RASTER_DOUBLE_FRAME_BUFFER,
                        RASTER_BURST_SIZE_16, RASTER_FIFO_THRESHOLD_8,
                        RASTER_BIG_ENDIAN_DISABLE);
    
        // 模式配置(例如:TFT 或者 STN,彩色或者黑白 等等)
        RasterModeConfig(SOC_LCDC_0_REGS, RASTER_DISPLAY_MODE_TFT,
                         RASTER_PALETTE_DATA, RASTER_COLOR, RASTER_RIGHT_ALIGNED);
    
        // 帧缓存数据以 LSB 方式排列
        RasterLSBDataOrderSelect(SOC_LCDC_0_REGS);
        
        // 禁用 Nibble 模式
        RasterNibbleModeDisable(SOC_LCDC_0_REGS);
       
        // 配置光栅控制器极性
        RasterTiming2Configure(SOC_LCDC_0_REGS, RASTER_FRAME_CLOCK_LOW |
                                                RASTER_LINE_CLOCK_LOW  |
                                                RASTER_PIXEL_CLOCK_LOW |
                                                RASTER_SYNC_EDGE_RISING|
                                                RASTER_SYNC_CTRL_ACTIVE|
                                                RASTER_AC_BIAS_HIGH     , 0, 255);
    
    	// RasterHparamConfig(baseAddr,     numOfppl, hsw,hfp,hbp);
        RasterHparamConfig(SOC_LCDC_0_REGS, LCD_WIDTH, 10, 4, 10);
    	// RasterVparamConfig( baseAddr,    Lpp,       vsw,vfp,vbp);
    	RasterVparamConfig(SOC_LCDC_0_REGS, LCD_HEIGHT, 4, 8, 12);
    
    	// 配置 FIFO DMA 延时
    	RasterFIFODMADelayConfig(SOC_LCDC_0_REGS, 2);
    
        unsigned int i = 0, j = 0;
    	unsigned char *src, *dest;
    
      	// 配置基本框架
    	RasterDMAFBConfig(SOC_LCDC_0_REGS,
    					  (unsigned int)(g_pucBuffer0+PALETTE_OFFSET),
    					  (unsigned int)(g_pucBuffer0+PALETTE_OFFSET) + sizeof(g_pucBuffer0) - 2 - PALETTE_OFFSET,
    					  0);
    
    	RasterDMAFBConfig(SOC_LCDC_0_REGS,
    					  (unsigned int)(g_pucBuffer0+PALETTE_OFFSET),
    					  (unsigned int)(g_pucBuffer0+PALETTE_OFFSET) + sizeof(g_pucBuffer0) - 2 - PALETTE_OFFSET,
    					  1);
    
    	// 拷贝调色板到离屏显存中
    	src = (unsigned char *)palette_32b;
    	dest = (unsigned char *)(g_pucBuffer0+PALETTE_OFFSET);
    	for( i = 4; i < (PALETTE_SIZE+4); i++)
    	{
    		*dest++ = *src++;
    	}
    
    	// 使能LCD帧结束中断
    	RasterEndOfFrameIntEnable(SOC_LCDC_0_REGS);
    
    	// 使能光栅
    	RasterEnable(SOC_LCDC_0_REGS);
    }
    
    /****************************************************************************/
    unsigned int LCDVersionGet(void)
    {
        return 1;
    }
    
    /**
     * @brief: TFT LCD写一个像素到显存
     * @author: lusd
     * @param [in] x, 横轴坐标, 范围0~479
     * @param [in] y, 纵轴坐标, 范围0~359
     * @param [in] color, RGB565颜色值
     * @return none.
     */
    void tft_lcd_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
    {
    	fb_data_t *fb_dat;
    
    	if ((x < LCD_WIDTH) && (y < LCD_HEIGHT)) {
    		fb_dat = (fb_data_t *)(g_pucBuffer0);
    		fb_dat->dat[y][x] = color;
    	}
    }
    
    
    /**
     * @brief: TFT LCD在显存中画横线
     * @author: lusd
     * @param [in] x, 横轴起始坐标, 范围0~479
     * @param [in] y, 纵轴起始坐标, 范围0~359
     * @param [in] length, 长度, 范围0~479, 超出屏幕部分忽略
     * @param [in] color, RGB565颜色值
     * @return none.
     */
    void tft_lcd_draw_xline(uint16_t x, uint16_t y, uint16_t length, uint16_t color)
    {
    	uint16_t *dest16;
    	fb_data_t *fb_dat;
    
    	if ((x < LCD_WIDTH) && (y < LCD_HEIGHT)) {
    		fb_dat = (fb_data_t *)(g_pucBuffer0);
    		dest16 = &(fb_dat->dat[y][x]);
    		if ((x + length) > LCD_WIDTH) {
    			length = LCD_WIDTH - x;
    		}
    		while (length--) {
    			*dest16++ = color;
    		}		
    	}
    }
    
    /**
     * @brief: TFT LCD在显存中画竖线
     * @author: lusd
     * @param [in] x, 横轴起始坐标, 范围0~479
     * @param [in] y, 纵轴起始坐标, 范围0~359
     * @param [in] length, 长度, 范围0~359, 超出屏幕部分忽略
     * @param [in] color, RGB565颜色值
     * @return none.
     */
    void tft_lcd_draw_yline(uint16_t x, uint16_t y, uint16_t length, uint16_t color)
    {
    	uint16_t h, y_end;
    	fb_data_t *fb_dat;
    
    	if ((x < LCD_WIDTH) && (y < LCD_HEIGHT)) {
    		fb_dat = (fb_data_t *)(g_pucBuffer0);
    		if ((y + length) > LCD_HEIGHT) {
    			length = LCD_HEIGHT - y;
    		}
    		y_end = y + length;
    		for (h=y; h<y_end; h++) {
    			fb_dat->dat[h][x] = color;
    		}
    	}
    }
    
    /**
     * @brief: TFT LCD在显存中填充一个矩形区域
     * @author: lusd
     * @param [in] x, 横轴起始坐标, 范围0~479
     * @param [in] y, 纵轴起始坐标, 范围0~359
     * @param [in] width, 宽, 范围0~479, 超出屏幕部分忽略
     * @param [in] height, 高, 范围0~359, 超出屏幕部分忽略
     * @param [in] color, RGB565颜色值
     * @return none.
     */
    void tft_lcd_fill_rectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
    {
    	uint16_t w, h, x_end, y_end;
    	fb_data_t *fb_dat;
    
    	if ((x < LCD_WIDTH) && (y < LCD_HEIGHT)) {
    		fb_dat = (fb_data_t *)(g_pucBuffer0);
    		if ((x + width) > LCD_WIDTH) {
    			width = LCD_WIDTH - x;
    		}
    		if ((y + height) > LCD_HEIGHT) {
    			height = LCD_HEIGHT - y;
    		}
    		x_end = x + width;
    		y_end = y + height;
    
    		for (h=y; h<y_end; h++) {
    			for (w=x; w<x_end; w++) {
    				fb_dat->dat[h][w] = color;
    			}
    		}
    	}
    }
    
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Shide

    很抱歉让你久等了。 很遗憾、此系列器件不再支持 RTOS/barermetal/Starterware 查询。  

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1071334/notice-regarding-processor-sdk-ti-rtos-for-am335x-am437x-omap-l13x-c674x-k2g-devices

    目前尚不清楚 CPU 频率为何会有所不同

    请查看是否有一些旧帖子像以下帮助一样

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/223339/c6748-lcdc-clarifications

    e2e.ti.com/.../OMAP_2D00_L1x_5F00_C674x_5F00_AM1x-LCD-Controller-_2800_LCDC_2900_-Throughput-and-Optimization-Techniques-_2D00_-Texas-Instruments-Wiki.pdf

    我还附上了在旧帖子中链接的 pdf 版本的 wiki

    希望这对您有所帮助  

    此致

    Mukul  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Mukul

    感谢您的答复。

    如您所说、Starterware 已不再受支持。  是否有任何其他 C6748外设驱动程序库可用?

    能否提供一些测试光栅 LCD 控制器的示例?

    Br.

    世德路

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    遗憾的是、我们没有任何其他库或示例可供共享。

    此致、
    Krunal.