📄 test_lcd.c
字号:
/*
* AT91SAM9261 LCD Controller
*
* (C) Copyright 2001-2002
* Wolfgang Denk, DENX Software Engineering -- wd@denx.de
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Terminal settings:
* SERIAL DEBUG PORT
* ------------------
* Communication speed: 115200 bps
* Number of data bits: 8
* Number of stop bits: 1
* Parity: none
*
* Jumplers:
* Set J12 (VDDCORE)
* Set J8 (VDDOSC VDDPLL)
* Set J13 (FORCE POWER ON)
* Remove J4 (BOOT MODE SELECT)
* Set J21 on 1-2 position
*/
/************************************************************************/
/* HEADER FILES */
/************************************************************************/
#include <stdlib.h>
#include <inarm.h>
#include "AT91SAM9261_init.h"
#include "main.h"
void AT91F_Test_TouchScreen(void);
#undef CONFIG_LCD_LOGO
#include "lcd.h"
#include "lcd_lut.h"
extern int drv_lcd_init (void);
extern void lcd_clearscreen (void);
#ifdef CONFIG_LCD
#define LCD_BPP LCD_COLOR8
#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
/* More or less configurable parameters for LCDC controller*/
#define SIDSAFB_FIFO_SIZE 512
#define SIDSAFB_DMA_BURST_LEN 16
#define SIDSAFB_CRST_VAL 0xc8 // 0xda
#define AT91C_PMC_HCK1 ((unsigned int) 0x1 << 17) // (PMC) AHB LCDCK Clock Output
AT91PS_SYS AT91_SYS = (AT91PS_SYS)AT91C_BASE_SYS;
/* 640x480x16 @ 61 Hz */
vidinfo_t panel_info = {
240, // vl_col:
320, // vl_row:
64, // vl_width:
86, // vl_height:
4965000, // vl_pixclock:
/* LCD configuration register */
0, // vl_clkp; Clock polarity
0, // vl_oep; Output Enable polarity
FB_SYNC_HOR_HIGH_ACT, // vl_hsp: Horizontal Sync polarity
FB_SYNC_VERT_HIGH_ACT, // vl_vsp: Vertical Sync polarity
0, // vl_dp; Data polarity
3, // vl_bpix; Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16
0, // vl_lbw; LCD Bus width, 0 = 4, 1 = 8
0, // vl_splt; Split display, 0 = single-scan, 1 = dual-scan
0, // vl_clor; Color, 0 = mono, 1 = color
1, // vl_tft: 0 = passive, 1 = TFT
/* Horizontal control Timing */
5, // vl_hpw:
1, // vl_blw:
33,// vl_elw:
/* Vertical control Timing */
1, // vl_vpw:
1, // vl_bfw:
0, // vl_efw:
};
/*----------------------------------------------------------------------*/
void lcd_setcolreg (void);
void lcd_ctrl_init (void *lcdbase);
void lcd_enable (void);
static void lcd_init_lut(void);
int lcd_line_length;
int lcd_color_fg;
int lcd_color_bg;
char *lcd_base; /* Start of framebuffer memory */
char *lcd_console_address; /* Start of console buffer */
short console_col;
short console_row;
/************************************************************************/
static void AT91F_LCDC_TFT_CfgPIO (void)
{
AT91_SYS->PIOB_PDR = (AT91C_PB1_LCDHSYNC | AT91C_PB2_LCDDOTCK | AT91C_PB3_LCDDEN |
AT91C_PB4_LCDCC | AT91C_PB7_LCDD2 | AT91C_PB8_LCDD3 |
AT91C_PB9_LCDD4 | AT91C_PB10_LCDD5 | AT91C_PB11_LCDD6 |
AT91C_PB12_LCDD7 | AT91C_PB15_LCDD10 | AT91C_PB16_LCDD11 |
AT91C_PB17_LCDD12 | AT91C_PB18_LCDD13 | AT91C_PB19_LCDD14 |
AT91C_PB20_LCDD15 | AT91C_PB23_LCDD18 | AT91C_PB24_LCDD19 |
AT91C_PB25_LCDD20 | AT91C_PB26_LCDD21 | AT91C_PB27_LCDD22 |
AT91C_PB28_LCDD23);
AT91_SYS->PIOB_BSR = (AT91C_PB23_LCDD18 | AT91C_PB24_LCDD19 | AT91C_PB25_LCDD20 |
AT91C_PB26_LCDD21 | AT91C_PB27_LCDD22 | AT91C_PB28_LCDD23);
// Configure PA12 in pio to enable LCD
AT91_SYS->PIOA_PER = AT91C_PIO_PA12;
AT91_SYS->PIOA_OER = AT91C_PIO_PA12;
AT91_SYS->PIOA_CODR = AT91C_PIO_PA12;
}
static void lcd_init_lut(void)
{
unsigned int i;
for(i =0; i <256; i++)
{
panel_info.controller.lcdc->LCDC_LUT_ENTRY[i] = ((rgbPalette[i].red) >> 3 |
((rgbPalette[i].green & 0xf8) << 2) |
((rgbPalette[i].blue & 0xf8) << 7));
}
}
void lcd_ctrl_init (void *lcdbase)
{
unsigned long value;
AT91F_LCDC_TFT_CfgPIO();
/* Enable HCLOCK in PMC */
AT91_SYS->PMC_SCER = AT91C_PMC_HCK1;
/* Init controller field in panel_info */
panel_info.controller.lcdc = (AT91PS_LCDC) AT91C_BASE_LCDC;
panel_info.controller.frame_buffer = (unsigned long) lcdbase;
/* Turn off the LCD controller and the DMA controller */
panel_info.controller.lcdc->LCDC_PWRCON = 0x0C;
panel_info.controller.lcdc->LCDC_DMACON = 0;
// Reset LCDC DMA
panel_info.controller.lcdc->LCDC_DMACON = AT91C_LCDC_DMARST;
/* ...set frame size and burst length = 8 words (?) */
value = ((unsigned int)panel_info.vl_row * (unsigned int)panel_info.vl_col * (unsigned int)NBITS(panel_info.vl_bpix)) / 32;
value |= (unsigned long)((512 - 1) << 24);
panel_info.controller.lcdc->LCDC_FRMCFG = value;
/* Set pixel clock */
value = AT91C_MASTER_CLOCK_FOR_I2S / panel_info.vl_pixclock;
if (AT91C_MASTER_CLOCK_FOR_I2S % panel_info.vl_pixclock)
value++;
value = (value / 2) - 1;
if (!value)
{
panel_info.controller.lcdc->LCDC_LCDCON1 = AT91C_LCDC_BYPASS;
}
else
{
panel_info.controller.lcdc->LCDC_LCDCON1 = value << 12;
}
/* Initialize control register 2 */
if (panel_info.vl_tft)
{
value = ( AT91C_LCDC_MEMOR_LITTLEIND | AT91C_LCDC_DISTYPE_TFT | AT91C_LCDC_CLKMOD);
}
else
{
value = ( AT91C_LCDC_MEMOR_LITTLEIND | AT91C_LCDC_CLKMOD);
}
if (!((unsigned int)panel_info.vl_hsp & FB_SYNC_HOR_HIGH_ACT))
{
value |= 1 << 10; /* INVLINE */
}
if (!((unsigned int)panel_info.vl_vsp & FB_SYNC_VERT_HIGH_ACT))
{
value |= 1 << 9; /* INVFRAME */
}
value |= (unsigned int)(panel_info.vl_bpix << 5);
panel_info.controller.lcdc->LCDC_LCDCON2 = value;
lcd_init_lut();
/* Vertical timing */
value = (unsigned int)((panel_info.vl_vpw - 1) << 16);
value |= (unsigned int)(panel_info.vl_bfw << 8);
value |= (unsigned int)panel_info.vl_efw;
panel_info.controller.lcdc->LCDC_TIM1 = value;
/* Horizontal timing */
value = (unsigned int)((panel_info.vl_elw - 1) << 21);
value |= (unsigned int)((panel_info.vl_hpw - 1) << 8);
value |= (unsigned int)(panel_info.vl_blw - 1);
panel_info.controller.lcdc->LCDC_TIM2 = value;
value = (unsigned int)((panel_info.vl_col - 1) << 21);
value |= (unsigned int)(panel_info.vl_row - 1);
panel_info.controller.lcdc->LCDC_LCDFRCFG = value;
/* FIFO Threshold: Use formula from data sheet */
value = SIDSAFB_FIFO_SIZE - (2 * SIDSAFB_DMA_BURST_LEN + 3);
//value = 512;
panel_info.controller.lcdc->LCDC_FIFO = value;
/* Toggle LCD_MODE every frame */
value = 0;
panel_info.controller.lcdc->LCDC_MVAL = value;
/* Disable all interrupts */
panel_info.controller.lcdc->LCDC_IDR = ~0UL;
// Set contrast
value = AT91C_LCDC_PS_DIVIDEDBYEIGHT | AT91C_LCDC_POL_POSITIVEPULSE | AT91C_LCDC_ENA_PWMGEMENABLED;
panel_info.controller.lcdc->LCDC_CTRSTCON = value;
panel_info.controller.lcdc->LCDC_CTRSTVAL = 0xDA;
panel_info.controller.lcdc->LCDC_BA1 = (unsigned int)lcdbase;
panel_info.controller.lcdc->LCDC_FRMCFG = (15 << 24) + ((unsigned int)panel_info.vl_col * (unsigned int)panel_info.vl_row * (unsigned int)NBITS(panel_info.vl_bpix)) / 32;
panel_info.controller.lcdc->LCDC_DMACON = AT91C_LCDC_DMAEN;
panel_info.controller.lcdc->LCDC_PWRCON = AT91C_LCDC_PWR | 0x0c;
}
/*----------------------------------------------------------------------*/
#if LCD_BPP == LCD_COLOR8
void lcd_setcolreg (void)
{
lcd_init_lut();
}
#endif /* LCD_COLOR8 */
/*----------------------------------------------------------------------*/
void lcd_enable (void)
{
}
/*----------------------------------------------------------------------*/
void lcd_disable (void)
{
}
/*----------------------------------------------------------------------*/
ulong calc_fbsize (void)
{
ulong size;
int line_length = ((unsigned int)panel_info.vl_col * (unsigned int)NBITS(panel_info.vl_bpix)) / 8;
size = line_length * (unsigned int)panel_info.vl_row;
size += PAGE_SIZE;
return size;
}
#endif /* CONFIG_LCD */
//*----------------------------------------------------------------------------
//* \fn AT91F_Test_LCD
//* \brief Test LCD
//*----------------------------------------------------------------------------
void main (void)
{
volatile int dummy, value, i, j;
// Init AIC
for (int i = 0; i < 32; ++i) {
AT91F_AIC_DisableIt(AT91C_BASE_AIC, i);
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, i, AT91C_AIC_PRIOR_LOWEST, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, AT91F_UndefHandler);
}
AT91C_BASE_AIC->AIC_SPU = (unsigned int) AT91F_SpuriousHandler;
AT91C_BASE_AIC->AIC_DCR = 0;
// Open PIO for DBGU
AT91F_DBGU_CfgPIO();
// Configure DBGU
AT91F_US_Configure ((AT91PS_USART) AT91C_BASE_DBGU, // DBGU base address
Fmclk,
AT91C_US_ASYNC_MODE, // mode Register to be programmed
AT91C_BAUD_RATE , // baudrate to be programmed
0); // timeguard to be programmed
// Enable Transmitter
AT91F_US_EnableTx((AT91PS_USART) AT91C_BASE_DBGU);
AT91F_US_EnableRx((AT91PS_USART) AT91C_BASE_DBGU);
AT91F_DBGU_Printk("#-I- AT91SAM9261 Basic LCDC/TFT DISPLAY and Backlight\n\r");
AT91F_DBGU_Printk("\r\n#############################\r\n");
AT91F_DBGU_Printk("# LCDC/TFT DISPLAY #\r\n");
AT91F_DBGU_Printk("# Backlight and touchscreen #\r\n");
AT91F_DBGU_Printk("# Basic for SAM9261 #\r\n");
AT91F_DBGU_Printk("#############################\r\n");
__enable_interrupt();
drv_lcd_init();
AT91F_DBGU_Printk("-I- Press a key to start Backlight Tests\n\r");
while(!AT91F_US_RxReady((AT91PS_USART)AT91C_BASE_DBGU));
dummy = AT91F_US_GetChar((AT91PS_USART)AT91C_BASE_DBGU);
AT91F_DBGU_Printk("-I- Press a key to stop the test...\n\r");
while(!AT91F_US_RxReady((AT91PS_USART)AT91C_BASE_DBGU))
{
value = 0;
for (j=0; j<5; j++, value+=0x20)
{
panel_info.controller.lcdc->LCDC_CTRSTVAL = value; // State OFF
for (i=0; i<2500000; i++);
}
}
dummy = AT91F_US_GetChar((AT91PS_USART)AT91C_BASE_DBGU);
lcd_clearscreen();
panel_info.controller.lcdc->LCDC_CTRSTVAL = 0x80;
AT91F_Test_TouchScreen();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -