rt-thread-official/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.c

317 lines
10 KiB
C

/*!
\file gd32f450z_lcd_eval.c
\brief firmware functions to manage LCD
*/
/*
Copyright (C) 2016 GigaDevice
2016-10-19, V1.0.0, firmware for GD32F450Z
*/
#include "gd32f450z_lcd_eval.h"
static void delay(uint32_t time);
/*!
\brief enable the LCD
\param[in] none
\param[out] none
\retval none
*/
void lcd_enable(void)
{
gpio_bit_set(LCD_CS_GPIO_PORT, LCD_CS_PIN);
}
/*!
\brief disable the LCD
\param[in] none
\param[out] none
\retval none
*/
void lcd_disable(void)
{
gpio_bit_reset(LCD_CS_GPIO_PORT, LCD_CS_PIN);
}
/*!
\brief configure the LCD control line
\param[in] none
\param[out] none
\retval none
*/
void lcd_ctrl_line_config(void)
{
/* enable GPIOs clock*/
rcu_periph_clock_enable(LCD_CS_GPIO_CLK);
rcu_periph_clock_enable(LCD_RS_GPIO_CLK);
/* configure LCD_CS_GPIO_PORT(PD11) and LCD_RS_GPIO_PORT(PE3) */
gpio_mode_set(LCD_CS_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LCD_CS_PIN);
gpio_output_options_set(LCD_CS_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,LCD_CS_PIN);
gpio_mode_set(LCD_RS_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LCD_RS_PIN);
gpio_output_options_set(LCD_RS_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,LCD_RS_PIN);
/* set the chip select pin */
lcd_ctrl_line_set(LCD_CS_GPIO_PORT, LCD_CS_PIN);
}
/*!
\brief set the LCD control line
\param[in] gpiox: control line GPIO
\arg LCD_CS_GPIO_PORT: LCD chip select GPIO
\arg LCD_RS_GPIO_PORT: LCD register/RAM selection GPIO
\param[in] gpiopin: control line pin
\arg LCD_CS_PIN: LCD chip select pin
\arg LCD_RS_PIN: LCD register/RAM selection pin
\param[out] none
\retval none
*/
void lcd_ctrl_line_set(uint32_t gpiox, uint16_t gpiopin)
{
gpio_bit_set(gpiox, gpiopin);
}
/*!
\brief reset the LCD control line
\param[in] gpiox: control line GPIO
\arg LCD_CS_GPIO_PORT: LCD chip select GPIO
\arg LCD_RS_GPIO_PORT: LCD register/RAM selection GPIO
\param[in] gpiopin: control line pin
\arg LCD_CS_PIN: LCD chip select pin
\arg LCD_RS_PIN: LCD register/RAM selection pin
\param[out] none
\retval none
*/
void lcd_ctrl_line_reset(uint32_t gpiox, uint16_t gpiopin)
{
gpio_bit_reset(gpiox, gpiopin);
}
/*!
\brief configure the LCD SPI and it's GPIOs
\param[in] none
\param[out] none
\retval none
*/
void lcd_spi_config(void)
{
spi_parameter_struct spi_init_struct;
rcu_periph_clock_enable(RCU_GPIOG);
rcu_periph_clock_enable(RCU_SPI5);
/* configure SPI5_SCK(PG13) and SPI5_MOSI(PG14) */
gpio_af_set(GPIOG,GPIO_AF_5,GPIO_PIN_13);
gpio_af_set(GPIOG,GPIO_AF_5,GPIO_PIN_14);
gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13|GPIO_PIN_14);
gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13|GPIO_PIN_14);
spi_i2s_deinit(SPI5);
if(0 == (SPI_CTL0(LCD_SPI) & SPI_CTL0_SPIEN)){
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_16;
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init(LCD_SPI, &spi_init_struct);
spi_enable(LCD_SPI);
}
}
/*!
\brief write command to select LCD register
\param[in] lcd_register: the address of the selected register
\param[out] none
\retval none
*/
void lcd_command_write(uint8_t lcd_register)
{
/* reset LCD_RS to send command */
lcd_ctrl_line_reset(LCD_RS_GPIO_PORT, LCD_RS_PIN);
/* reset LCD control line and send command */
lcd_disable();
while(RESET == spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TBE)) ;
spi_i2s_data_transmit(LCD_SPI, lcd_register);
/* wait until a data is sent */
while(RESET != spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TRANS));
lcd_enable();
}
/*!
\brief write data to select LCD register
\param[in] value: the value that will be written to the selected register
\param[out] none
\retval none
*/
void lcd_data_write(uint8_t value)
{
/* set LCD_RS to send data */
lcd_ctrl_line_set(LCD_RS_GPIO_PORT, LCD_RS_PIN);
/* reset LCD control line and send data */
lcd_disable();
while(RESET == spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TBE)) ;
spi_i2s_data_transmit(LCD_SPI, value);
/* wait until a data is sent */
while(RESET != spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TRANS)) ;
lcd_enable();
}
/*!
\brief configure the LCD based on the power on sequence
\param[in] none
\param[out] none
\retval none
*/
void lcd_power_on(void)
{
lcd_command_write(0x11);
delay(120);
lcd_command_write(0x36);
lcd_data_write(0x48);
lcd_command_write(0x3A);
lcd_data_write(0x55);
lcd_command_write(0xB4);
lcd_data_write(0x11);
lcd_command_write(0xB3);
lcd_data_write(0x00);
lcd_data_write(0x00);
lcd_data_write(0x00);
lcd_data_write(0x20);
lcd_command_write(0xC0);
lcd_data_write(0x10);
lcd_data_write(0x3B);
lcd_data_write(0x00);
lcd_data_write(0x12);
lcd_data_write(0x01);
lcd_command_write(0xC5);
lcd_data_write(0x07);
lcd_command_write(0xC8);
lcd_data_write(0x01 );
lcd_data_write(0x36);
lcd_data_write(0x00);
lcd_data_write(0x02);
lcd_data_write(0x00);
lcd_data_write(0x1C);
lcd_data_write(0x77);
lcd_data_write(0x14);
lcd_data_write(0x67);
lcd_data_write(0x20);
lcd_data_write(0x0E);
lcd_data_write(0x00);
lcd_command_write(0xD0);
lcd_data_write(0x44);
lcd_data_write(0x41 );
lcd_data_write(0x08);
lcd_data_write(0xC2);
lcd_command_write(0xD1);
lcd_data_write(0x50);
lcd_data_write(0x11);
lcd_command_write(0xD2);
lcd_data_write(0x05);
lcd_data_write(0x12);
lcd_command_write(0xC6);
lcd_data_write(0x83);
lcd_command_write(0x29);
delay(5);
}
/**
* @brief New Version 3.5" TFT RGB Hardware needs add this initilize funtion ---By xufei 2016.10.21
Modified by GAO HAIYANG, test pass, 17, Nov, 2016
* @param None
* @retval None
*/
void lcd_power_on3(void)
{
lcd_command_write(0xC0);//power control1 command/w/
lcd_data_write(0x0A); // P-Gamma level//4.1875v
lcd_data_write(0x0A); // N-Gamma level
lcd_command_write(0xC1); // BT & VC Setting//power contrl2 command/w/
lcd_data_write(0x41);
lcd_data_write(0x07); // VCI1 = 2.5V
lcd_command_write(0xC2); // DC1.DC0 Setting//power control3 for normal mode
lcd_data_write(0x33);
lcd_command_write(0xC5);//VCOM control
lcd_data_write(0x00); //NV memory is not programmed
lcd_data_write(0x42); // VCM Setting
lcd_data_write(0x80); // VCM Register Enable
lcd_command_write(0xB0); //interface mode control //Polarity Setting
lcd_data_write(0x02);
lcd_command_write(0xB1);//frame rate control for normal mode
lcd_data_write(0xB0); // Frame Rate Setting//70 frame per second//no division for internal clocks
lcd_data_write(0x11);//17 clocks per line period for idle mode at cpu interface
lcd_command_write(0xB4);//dispaly inversion control
lcd_data_write(0x00); // disable Z-inversion , column inversion
lcd_command_write(0xB6); //display function control// RM.DM Setting
lcd_data_write(0x70);////0xF0
lcd_data_write(0x02);//direction of gate scan: G1->G480 one by one, source scan: S1->S960, scan cycle if interval scan in non-display area
lcd_data_write(0x3B); // number of lines to drive LCD: 8*(0x3C) = 480
lcd_command_write(0xB7); // Entry Mode
lcd_data_write(0x07); // disable low voltage detection, normal display,
lcd_command_write(0xF0); // Enter ENG , must be set before gamma setting
lcd_data_write(0x36);
lcd_data_write(0xA5);
lcd_data_write(0xD3);
lcd_command_write(0xE5); // Open gamma function , must be set before gamma setting
lcd_data_write(0x80);
lcd_command_write(0xE5); // Page 1
lcd_data_write(0x01);
lcd_command_write(0XB3); // WEMODE=0(Page 1) , pixels over window setting will be ignored.//frame rate control in partial mode/full colors
lcd_data_write(0x00);
lcd_command_write(0xE5); // Page 0
lcd_data_write(0x00);
lcd_command_write(0xF0); // Exit ENG , must be set before gamma setting
lcd_data_write(0x36);
lcd_data_write(0xA5);
lcd_data_write(0x53);
lcd_command_write(0xE0); // Gamma setting
//y fine adjustment register for positive polarity
lcd_data_write(0x00);
lcd_data_write(0x35);
lcd_data_write(0x33);
//y gradient adjustment register for positive polarity
lcd_data_write(0x00);
//y amplitude adjustment register for positive polarity
lcd_data_write(0x00);
lcd_data_write(0x00);
//y fine adjustment register for negative polarity
lcd_data_write(0x00);
lcd_data_write(0x35);
lcd_data_write(0x33);
//y gradient adjustment register for negative polarity
lcd_data_write(0x00);
//y amplitude adjustment register for negative polarity
lcd_data_write(0x00);
lcd_data_write(0x00);
lcd_command_write(0x36); // memory data access control //
lcd_data_write(0x48);//
lcd_command_write(0x3A); // interface pixel format setting
lcd_data_write(0x55);//16-bits
lcd_command_write(0x11); // Exit sleep mode
lcd_command_write(0x29); // Display on
delay(10);
}
/*!
\brief insert a delay time
\param[in] time: delay time length
\param[out] none
\retval none
*/
static void delay(uint32_t time)
{
uint32_t timecount = time;
while(0 != timecount--);
}