📄 lcd.c.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 + -