⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
字号:
/*
 * File      : lcd.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006, RT-Thread Develop Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://openlab.rt-thread.com/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2007-03-20     Bernard      the first version
 */

#include <rtthread.h>

#include "pxa270.h"

/*
 * LCD Controller
 */
/* Controller Control Register 0 */
#define  LCCR0_ENB		(1U<<0)	/* LCD Controller Enable */
#define  LCCR0_CMS		(1U<<1)	/* Color/Mono select */
#define  LCCR0_SDS		(1U<<2)	/* Single/Dual -panel */
#define  LCCR0_LDM		(1U<<3)	/* LCD Disable Done Mask */
#define  LCCR0_SFM		(1U<<4)	/* Start of Frame Mask */
#define  LCCR0_IUM		(1U<<5)	/* Input FIFO Underrun Mask */
#define  LCCR0_EFM		(1U<<6)	/* End of Frame Mask */
#define  LCCR0_PAS		(1U<<7)	/* Passive/Active Display select */
#define  LCCR0_DPD		(1U<<9)	/* Double-Pixel Data pin mode */
#define  LCCR0_DIS		(1U<<10) /* LCD Disable */
#define  LCCR0_QDM		(1U<<11) /* LCD Quick Disable Mask */
#define  LCCR0_BM		(1U<<20) /* Branch Mask */
#define  LCCR0_OUM		(1U<<21) /* Output FIFO Underrun Mask */
/* PXA270 */
#define  LCCR0_LCDT		(1U<<22) /* LCD Panel Type */
#define  LCCR0_RDSTM	(1U<<23) /* Read Status Interrupt Mask */
#define  LCCR0_CMDIM	(1U<<24) /* Command Interrupt Mask */
#define  LCCR0_OUC		(1U<<25) /* Overlay Underlay Control */
#define  LCCR0_LDDALT	(1U<<26) /* LDD Alternate Mapping Control Bit */

#define  LCCR0_IMASK	(LCCR0_LDM|LCCR0_SFM|LCCR0_IUM|LCCR0_EFM|LCCR0_QDM|LCCR0_BM|LCCR0_OUM)

/* Controller Control Register 2 */
#define  LCCR3_BPP_SHIFT 24		/* Bits per pixel */
#define  LCCR3_BPP		(0x07<<LCCR3_BPP_SHIFT)

/* controller status register */
#define  LCSR_LDD		(1U<<0) /* LCD disable done */
#define  LCSR_SOF		(1U<<1) /* Start of frame */

#define LCDPANEL_VSP	(1<<0)	/* L_FCLK pin is active low */
#define LCDPANEL_HSP	(1<<1)	/* L_LCLK pin is active low */

#define RT_HW_LCD_WIDTH		640
#define RT_HW_LCD_HEIGHT	480

/* LCD DMA Descriptor */
struct rt_hw_lcd_dma_descriptor {
	rt_uint32	fdadr;	/* next frame descriptor */
	rt_uint32	fsadr;	/* frame start address */
	rt_uint32	fidr;	/* frame ID */
	rt_uint32	ldcmd;	/* DMA command */
#define	LDCMD_PAL		(1U<<26)	/* Palette buffer */
#define LDCMD_SOFINT	(1U<<22)	/* Start of Frame interrupt */
#define LDCMD_EOFINT	(1U<<21)	/* End of Frame interrupt */
};

/* DMA frame buffer */
volatile rt_uint8 _rt_hw_framebuffer[RT_HW_LCD_WIDTH * RT_HW_LCD_HEIGHT * 2] __attribute__ ((aligned (256)));
volatile struct rt_hw_lcd_dma_descriptor _rt_hw_lcd_dma_descriptor __attribute__ ((aligned (256)));

void rt_hw_lcd_init()
{
	rt_int32 lccr0, lscr;
	
	lccr0 = PXA2X0_LCDC_LCCR0;
	if (lccr0 & LCCR0_ENB)
	{
		PXA2X0_LCDC_LCCR0 = lccr0 | LCCR0_LDM;
		lccr0 = PXA2X0_LCDC_LCCR0;	/* paranoia */
		lccr0 |= LCCR0_DIS;
		PXA2X0_LCDC_LCCR0 = lccr0 | LCCR0_DIS;
		do
		{
			lscr = PXA2X0_LCDC_LCSR;
		} while (!(lscr & LCSR_LDD));
	}

	/* enable clock */
	
	PXA2X0_LCDC_LCCR0 = LCCR0_IMASK;

	/*
	 * setup GP[77:58] for LCD
	 */
	
	/* set lcd geometry */
	lccr0 = LCCR0_IMASK | LCCR0_PAS;
	lccr0 |= LCCR0_LDDALT |
		LCCR0_OUC |
	    LCCR0_CMDIM |
	    LCCR0_RDSTM;
	
	PXA2X0_LCDC_LCCR0 = lccr0;
	
	/* set width */
	PXA2X0_LCDC_LCCR1 = (RT_HW_LCD_WIDTH - 1) | 
	    ((0x28 - 1) << 10) |
	    ((0x2e - 1) << 16) |
	    ((0x7d - 1) << 24);
	
	/* set height */
	PXA2X0_LCDC_LCCR2 = (RT_HW_LCD_HEIGHT - 1) |
		((0x02 - 1) << 10) |
		((0x01 - 1) << 16) |
		((0x00 - 1) << 24);
	
	/* set bpp */
	PXA2X0_LCDC_LCCR3 = ((1 << 0) | (0 << 8) |
	    ((LCDPANEL_VSP | LCDPANEL_HSP) << 20) |
	    (4 << LCCR3_BPP_SHIFT)); 	/* 16bpp */
}

void rt_hw_lcd_update()
{
	/* set DMA descriptor */
	_rt_hw_lcd_dma_descriptor.fdadr = (rt_uint32) &_rt_hw_lcd_dma_descriptor;
	_rt_hw_lcd_dma_descriptor.fsadr = (rt_uint32) &_rt_hw_framebuffer[0];
	_rt_hw_lcd_dma_descriptor.fidr 	= 0;	/* QEMU akita does not care this parameter */
	_rt_hw_lcd_dma_descriptor.ldcmd = 0;	/* QEMU akita does not care this parameter */

	/* configure the framebuffer for DMA */
	PXA2X0_LCDC_FDADR0 = (rt_uint32) &_rt_hw_lcd_dma_descriptor;
	
	/* clear status */
	PXA2X0_LCDC_LCSR = 0;
	
	/* enable LCDC */
	PXA2X0_LCDC_LCCR0 = PXA2X0_LCDC_LCCR0 | LCCR0_ENB;
}

#define PIXEL_RED 	0xf800
#define PIXEL_GREEN	0x07e0
#define PIXEL_BLUE	0x001f

void rt_hw_lcd_draw_pixel(int x, int y, short p)
{
	_rt_hw_framebuffer[(x + y * RT_HW_LCD_WIDTH) * 2    ] = p;
	_rt_hw_framebuffer[(x + y * RT_HW_LCD_WIDTH) * 2 + 1] = p >> 8;
}

void rt_hw_lcd_draw_hline(int y, short p)
{
	rt_uint32 idx;
	for (idx = 0; idx < RT_HW_LCD_WIDTH; idx ++)
	{
		rt_hw_lcd_draw_pixel(idx, y, p);
	}
}

void rt_hw_lcd_draw_vline(int x, short p)
{
	rt_uint32 idy;
	for (idy = 0; idy < RT_HW_LCD_HEIGHT; idy ++)
	{
		rt_hw_lcd_draw_pixel(x, idy, p);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -