#include <rtthread.h>
#include "stm32f10x.h"
// 分辨率(H:0-479 V:0-271)
unsigned int HDP=479;
unsigned int VDP=271;
unsigned int HT=531;
unsigned int HPS=43;
unsigned int LPS=8;
unsigned char HPW=1;
unsigned int VT=288;
unsigned int VPS=12;
unsigned int FPS=4;
unsigned char VPW=10;
#define Bank1_LCD_D ((uint32_t)0x60020000) //disp Data ram
#define Bank1_LCD_C ((uint32_t)0x60000000) //disp Reg ram
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
void LCD_WR_REG(u16 index)
{
*(__IO uint16_t *) (Bank1_LCD_C)= index;
}
u16 LCD_RD_DAT(void)
{
u16 a=0;
a=*(__IO uint16_t *) (Bank1_LCD_D);
return(a);
}
void LCD_WR_DAT(u16 val)
{
*(__IO uint16_t *) (Bank1_LCD_D)= val;
}
void _set_window(u16 x1, u16 y1, u16 x2, u16 y2)
{
LCD_WR_REG(0x002A);
LCD_WR_DAT(x1>>8);
LCD_WR_DAT(x1&0x00ff);
LCD_WR_DAT(x2>>8);
LCD_WR_DAT(x2&0x00ff);
LCD_WR_REG(0x002b);
LCD_WR_DAT(y1>>8);
LCD_WR_DAT(y1&0x00ff);
LCD_WR_DAT(y2>>8);
LCD_WR_DAT(y2&0x00ff);
}
void _set_cursor(u16 x,u16 y)
{
_set_window(x, y, HDP, VDP);
}
void lcd_set_pixel(const char* pixel, int x, int y)
{
_set_cursor(x, y);
LCD_WR_REG(0x2c);
LCD_WR_DAT(*(rt_uint16_t*)pixel);
}
void lcd_get_pixel(char* pixel, int x, int y)
{
_set_cursor(x, y);
LCD_WR_REG(0x2e);
*(rt_uint16_t*)pixel = LCD_RD_DAT();
}
void lcd_draw_hline(const char* pixel, int x1, int x2, int y)
{
_set_cursor(x1, y);
LCD_WR_REG(0x2c);
while (x1 < x2)
{
LCD_WR_DAT(*(rt_uint16_t*)pixel);
x1++;
}
}
void lcd_draw_vline(const char* pixel, int x, int y1, int y2)
{
_set_window(x, y1, x, y2);
LCD_WR_REG(0x2c);
while (y1 < y2)
{
LCD_WR_DAT(*(rt_uint16_t*)pixel);
y1++;
}
}
void lcd_blit_line(const char* pixels, int x, int y, rt_size_t size)
{
rt_uint16_t *ptr;
ptr = (rt_uint16_t*)pixels;
_set_cursor(x, y);
LCD_WR_REG(0x2c);
while (size)
{
LCD_WR_DAT(*ptr ++);
size --;
}
}
void lcd_clear()
{
int w = HDP + 1, h = VDP + 1;
_set_cursor(0, 0);
LCD_WR_REG(0x2c);
while (w--)
{
while(h--)
{
LCD_WR_DAT(0xffff);
}
h = VDP + 1;
}
}
void LCD_INIT(void)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_1);
Delay(0xAFFFF);
GPIO_SetBits(GPIOE, GPIO_Pin_1 );
Delay(0xAFFFF);
LCD_WR_REG(0x00E2); // PLL=10*36/3=120M
LCD_WR_DAT(0x0023); //N=0x36 for 6.5M, 0x23 for 10M crystal
LCD_WR_DAT(0x0002);
LCD_WR_DAT(0x0004);
LCD_WR_REG(0x00E0);
LCD_WR_DAT(0x0001);
Delay(0xAFFF);
LCD_WR_REG(0x00E0);
LCD_WR_DAT(0x0003);
Delay(0xAFFF);
LCD_WR_REG(0x0001);
Delay(0xAFFF);
LCD_WR_REG(0x00E6); //PLL setting for PCLK, depends on resolution
LCD_WR_DAT(0x0001);
LCD_WR_DAT(0x0033);
LCD_WR_DAT(0x0032);
LCD_WR_REG(0x00B0); //module
LCD_WR_DAT(0x0000);
LCD_WR_DAT(0x0000);
LCD_WR_DAT((HDP>>8)&0X00FF); //Set HDP
LCD_WR_DAT(HDP&0X00FF);
LCD_WR_DAT((VDP>>8)&0X00FF); //Set VDP
LCD_WR_DAT(VDP&0X00FF);
LCD_WR_DAT(0x0000);
LCD_WR_REG(0x00B4); //HSYNC
LCD_WR_DAT((HT>>8)&0X00FF); //Set HT
LCD_WR_DAT(HT&0X00FF);
LCD_WR_DAT((HPS>>8)&0X00FF); //Set HPS
LCD_WR_DAT(HPS&0X00FF);
LCD_WR_DAT(HPW); //Set HPW
LCD_WR_DAT((LPS>>8)&0X00FF); //Set HPS
LCD_WR_DAT(LPS&0X00FF);
LCD_WR_DAT(0x0000);
LCD_WR_REG(0x00B6); //VSYNC
LCD_WR_DAT((VT>>8)&0X00FF); //Set VT
LCD_WR_DAT(VT&0X00FF);
LCD_WR_DAT((VPS>>8)&0X00FF); //Set VPS
LCD_WR_DAT(VPS&0X00FF);
LCD_WR_DAT(VPW); //Set VPW
LCD_WR_DAT((FPS>>8)&0X00FF); //Set FPS
LCD_WR_DAT(FPS&0X00FF);
LCD_WR_REG(0x00BA);
LCD_WR_DAT(0x000F); //GPIO[3:0] out 1
LCD_WR_REG(0x00B8);
LCD_WR_DAT(0x0007); //GPIO3=input, GPIO[2:0]=output
LCD_WR_DAT(0x0001); //GPIO0 normal
LCD_WR_REG(0x0036); //rotation
LCD_WR_DAT(0x0000);
LCD_WR_REG(0x00F0); //16位 565 color module
LCD_WR_DAT(0x0003);
Delay(0xAFFF);
LCD_WR_REG(0x0029); //display on
LCD_WR_REG(0x00BE); //set PWM for B/L
LCD_WR_DAT(0x0006);
LCD_WR_DAT(0x0080);
LCD_WR_DAT(0x0001);
LCD_WR_DAT(0x00f0);
LCD_WR_DAT(0x0000);
LCD_WR_DAT(0x0000);
LCD_WR_REG(0x00d0);// backlight
LCD_WR_DAT(0x000d);
}
void GPIO_INIT(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
| RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE| RCC_APB2Periph_GPIOF , ENABLE);
}
void FSMC_LCD_Init(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD, GPIO_Pin_13);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
p.FSMC_AddressSetupTime = 0x02;
p.FSMC_AddressHoldTime = 0x00;
p.FSMC_DataSetupTime = 0x05;
p.FSMC_BusTurnAroundDuration = 0x00;
p.FSMC_CLKDivision = 0x00;
p.FSMC_DataLatency = 0x00;
p.FSMC_AccessMode = FSMC_AccessMode_B;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}
struct rt_device_graphic_ops ssd1963_ops =
{
lcd_set_pixel,
lcd_get_pixel,
lcd_draw_hline,
lcd_draw_vline,
lcd_blit_line
};
struct rt_device _lcd_device;
static rt_err_t lcd_init(rt_device_t dev)
{
return RT_EOK;
}
static rt_err_t lcd_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
static rt_err_t lcd_close(rt_device_t dev)
{
return RT_EOK;
}
static rt_err_t lcd_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
switch (cmd)
{
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *info;
info = (struct rt_device_graphic_info*) args;
RT_ASSERT(info != RT_NULL);
info->bits_per_pixel = 16;
info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565P;
info->framebuffer = RT_NULL;
info->width = HDP + 1;
info->height = VDP + 1;
}
break;
case RTGRAPHIC_CTRL_RECT_UPDATE:
/* nothong to be done */
break;
default:
break;
}
return RT_EOK;
}
void rt_hw_lcd_init(void)
{
/* register lcd device */
_lcd_device.type = RT_Device_Class_Graphic;
_lcd_device.init = lcd_init;
_lcd_device.open = lcd_open;
_lcd_device.close = lcd_close;
_lcd_device.control = lcd_control;
_lcd_device.read = RT_NULL;
_lcd_device.write = RT_NULL;
_lcd_device.user_data = &ssd1963_ops;
GPIO_INIT();
FSMC_LCD_Init();
LCD_INIT();
lcd_clear();
/* register graphic device driver */
rt_device_register(&_lcd_device, "lcd",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
}