123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604 |
- /*!
- \file gd32f307c_lcd_eval.c
- \brief LCD driver functions
- \version 2017-02-10, V1.0.0, firmware for GD32F30x
- \version 2018-10-10, V1.1.0, firmware for GD32F30x
- \version 2018-12-25, V2.0.0, firmware for GD32F30x
- \version 2020-09-30, V2.1.0, firmware for GD32F30x
- */
- /*
- Copyright (c) 2020, GigaDevice Semiconductor Inc.
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holder nor the names of its contributors
- may be used to endorse or promote products derived from this software without
- specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- OF SUCH DAMAGE.
- */
- #include "drv_usb_hw.h"
- #include "gd32f307c_lcd_eval.h"
- #include "lcd_font.h"
- #include <string.h>
- #define LCD_ILI9320 0x8989
- #define LCD_ILI9325 0x9325
- #define ABS(X) ((X) > 0 ? (X) : -(X))
- static font_struct *cur_fonts;
- /* set the cursor of LCD */
- static void lcd_cursor_set(uint16_t x,uint16_t y);
- __IO uint16_t cur_text_color = 0x0000U;
- __IO uint16_t cur_back_color = 0xFFFFU;
- __IO uint16_t cur_text_direction = CHAR_DIRECTION_HORIZONTAL;
- /*!
- \brief initializes the LCD of GD EVAL board
- \param[in] none
- \param[out] none
- \retval none
- */
- void gd_eval_lcd_init(void)
- {
- __IO uint32_t lcd_id = 0;
- exmc_lcd_init();
- usb_mdelay(50);
- /* Read the LCD ID */
- lcd_id = lcd_register_read(R0);
- /* check if the LCD is ILI9320 controller */
- if (LCD_ILI9320 == lcd_id) {
- lcd_init();
- }
- }
- /*!
- \brief lcd peripheral initialize
- \param[in] none
- \param[out] none
- \retval none
- */
- void exmc_lcd_init(void)
- {
- exmc_norsram_parameter_struct lcd_init_struct;
- exmc_norsram_timing_parameter_struct lcd_timing_init_struct;
- /* EXMC clock enable */
- rcu_periph_clock_enable(RCU_EXMC);
- /* GPIO clock enable */
- rcu_periph_clock_enable(RCU_GPIOD);
- rcu_periph_clock_enable(RCU_GPIOE);
- rcu_periph_clock_enable(RCU_GPIOG);
- /* configure EXMC_D[0~15]*/
- /* PD14(EXMC_D0), PD15(EXMC_D1),PD0(EXMC_D2), PD1(EXMC_D3), PD8(EXMC_D13), PD9(EXMC_D14), PD10(EXMC_D15) */
- gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_8 | GPIO_PIN_9 |
- GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15);
- /* PE7(EXMC_D4), PE8(EXMC_D5), PE9(EXMC_D6), PE10(EXMC_D7), PE11(EXMC_D8), PE12(EXMC_D9),
- PE13(EXMC_D10), PE14(EXMC_D11), PE15(EXMC_D12) */
- gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, 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);
- /* configure PE2(EXMC_A23) */
- gpio_init(GPIOE, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
-
- /* configure PD4(NOE) and PD5(NWE) */
- gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5);
- /* configure EXMC NE1 */
- gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
- lcd_timing_init_struct.asyn_access_mode = EXMC_ACCESS_MODE_A;
- lcd_timing_init_struct.syn_data_latency = EXMC_DATALAT_2_CLK;
- lcd_timing_init_struct.syn_clk_division = EXMC_SYN_CLOCK_RATIO_DISABLE;
- lcd_timing_init_struct.bus_latency = 2;
- lcd_timing_init_struct.asyn_data_setuptime = 10;
- lcd_timing_init_struct.asyn_address_holdtime = 2;
- lcd_timing_init_struct.asyn_address_setuptime = 5;
- lcd_init_struct.norsram_region = EXMC_BANK0_NORSRAM_REGION0;
- lcd_init_struct.write_mode = EXMC_ASYN_WRITE;
- lcd_init_struct.extended_mode = DISABLE;
- lcd_init_struct.asyn_wait = DISABLE;
- lcd_init_struct.nwait_signal = DISABLE;
- lcd_init_struct.memory_write = ENABLE;
- lcd_init_struct.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
- lcd_init_struct.wrap_burst_mode = DISABLE;
- lcd_init_struct.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
- lcd_init_struct.burst_mode = DISABLE;
- lcd_init_struct.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
- lcd_init_struct.memory_type = EXMC_MEMORY_TYPE_SRAM;
- lcd_init_struct.address_data_mux = DISABLE;
- lcd_init_struct.read_write_timing = &lcd_timing_init_struct;
- lcd_init_struct.write_timing = &lcd_timing_init_struct;
- exmc_norsram_init(&lcd_init_struct);
- exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION1);
- }
- /*!
- \brief write data to the selected LCD register
- \param[in] register_id: the selected register id
- \param[in] value: the register value to be written
- \param[out] none
- \retval none
- */
- void lcd_register_write(uint16_t register_id,uint16_t value)
- {
- *(__IO uint16_t *) (BANK0_LCD_C)= register_id;
- *(__IO uint16_t *) (BANK0_LCD_D)= value;
- }
- /*!
- \brief read the value of LCD register
- \param[in] register_id: the register id
- \param[out] none
- \retval the register value
- */
- uint16_t lcd_register_read(uint8_t register_id)
- {
- uint16_t data;
- *(__IO uint16_t *) (BANK0_LCD_C)= register_id;
- data = *(__IO uint16_t *) (BANK0_LCD_D);
- return data;
- }
- /*!
- \brief write command to LCD register
- \param[in] value: the register value to be written
- \param[out] none
- \retval none
- */
- void lcd_command_write(uint16_t value)
- {
- /* write 16-bit index, then write reg */
- *(__IO uint16_t *) (BANK0_LCD_D) = value;
- }
- /*!
- \brief prepare to write to the LCD GRAM register(R22h)
- \param[in] none
- \param[out] none
- \retval none
- */
- void lcd_gram_write_prepare(void)
- {
- *(__IO uint16_t *) (BANK0_LCD_C) = 0x0022;
- }
- /*!
- \brief write RGB code to the LCD GRAM register
- \param[in] rgb_code: the pixel color in RGB mode (5-6-5)
- \param[out] none
- \retval none
- */
- void lcd_gram_write(uint16_t rgb_code)
- {
- /* write 16-bit GRAM register */
- *(__IO uint16_t *) (BANK0_LCD_D) = rgb_code;
- }
- /*!
- \brief read data from GRAM
- \param[in] none
- \param[out] none
- \retval GRAM value
- */
- uint16_t lcd_gram_read(void)
- {
- uint16_t data;
-
- /* write GRAM register (R22h) */
- *(__IO uint16_t *) (BANK0_LCD_C) = 0x0022;
- /* dummy read (invalid data) */
- *(__IO uint16_t *) (BANK0_LCD_D);
- data = *(__IO uint16_t *) (BANK0_LCD_D);
- return data;
- }
- /*!
- \brief initialize the LCD
- \param[in] none
- \param[out] none
- \retval none
- */
- void lcd_init(void)
- {
- uint16_t i;
- if(1){ /*!< if(device_code == 0x8989) */
- lcd_register_write(0x0000,0x0001);
- lcd_register_write(0x0003,0xA8A4);
- lcd_register_write(0x000C,0x0000);
- lcd_register_write(0x000D,0x080C);
- lcd_register_write(0x000E,0x2B00);
- lcd_register_write(0x001E,0x00B0);
- lcd_register_write(0x0001,0x693F);
- lcd_register_write(0x0002,0x0600);
- lcd_register_write(0x0010,0x0000);
- lcd_register_write(0x0011,0x6070);
- lcd_register_write(0x0005,0x0000);
- lcd_register_write(0x0006,0x0000);
- lcd_register_write(0x0016,0xEF1C);
- lcd_register_write(0x0017,0x0003);
- lcd_register_write(0x0007,0x0233);
- lcd_register_write(0x000B,0x0000);
- lcd_register_write(0x000F,0x0000);
- lcd_register_write(0x0041,0x0000);
- lcd_register_write(0x0042,0x0000);
- lcd_register_write(0x0048,0x0000);
- lcd_register_write(0x0049,0x013F);
- lcd_register_write(0x004A,0x0000);
- lcd_register_write(0x004B,0x0000);
- lcd_register_write(0x0044,0xEF00);
- lcd_register_write(0x0045,0x0000);
- lcd_register_write(0x0046,0x013F);
- lcd_register_write(0x0030,0x0707);
- lcd_register_write(0x0031,0x0204);
- lcd_register_write(0x0032,0x0204);
- lcd_register_write(0x0033,0x0502);
- lcd_register_write(0x0034,0x0507);
- lcd_register_write(0x0035,0x0204);
- lcd_register_write(0x0036,0x0204);
- lcd_register_write(0x0037,0x0502);
- lcd_register_write(0x003A,0x0302);
- lcd_register_write(0x003B,0x0302);
- lcd_register_write(0x0023,0x0000);
- lcd_register_write(0x0024,0x0000);
- lcd_register_write(0x0025,0x8000);
- lcd_register_write(0x004e,0);
- lcd_register_write(0x004f,0);
- }else{
- return;
- }
-
- for(i=50000;i>0;i--);
- }
- /*!
- \brief set the text color
- \param[in] color: LCD color
- \arg LCD_COLOR_WHITE
- \arg LCD_COLOR_BLACK
- \arg LCD_COLOR_GREY
- \arg LCD_COLOR_BLUE
- \arg LCD_COLOR_BLUE2
- \arg LCD_COLOR_RED
- \arg LCD_COLOR_MAGENTA
- \arg LCD_COLOR_GREEN
- \arg LCD_COLOR_CYAN
- \arg LCD_COLOR_YELLOW
- \param[out] none
- \retval none
- */
- void lcd_text_color_set(__IO uint16_t color)
- {
- cur_text_color = color;
- }
- /*!
- \brief get the current text color
- \param[in] none
- \param[out] none
- \retval LCD color
- \arg LCD_COLOR_WHITE
- \arg LCD_COLOR_BLACK
- \arg LCD_COLOR_GREY
- \arg LCD_COLOR_BLUE
- \arg LCD_COLOR_BLUE2
- \arg LCD_COLOR_RED
- \arg LCD_COLOR_MAGENTA
- \arg LCD_COLOR_GREEN
- \arg LCD_COLOR_CYAN
- \arg LCD_COLOR_YELLOW
- */
- uint16_t lcd_text_color_get(void)
- {
- return cur_text_color;
- }
- /*!
- \brief set the background color
- \param[in] color: LCD color
- \arg LCD_COLOR_WHITE
- \arg LCD_COLOR_BLACK
- \arg LCD_COLOR_GREY
- \arg LCD_COLOR_BLUE
- \arg LCD_COLOR_BLUE2
- \arg LCD_COLOR_RED
- \arg LCD_COLOR_MAGENTA
- \arg LCD_COLOR_GREEN
- \arg LCD_COLOR_CYAN
- \arg LCD_COLOR_YELLOW
- \param[out] none
- \retval none
- */
- void lcd_background_color_set(__IO uint16_t color)
- {
- cur_back_color = color;
- }
- /*!
- \brief get the current background color
- \param[in] none
- \param[out] none
- \retval LCD color
- \arg LCD_COLOR_WHITE
- \arg LCD_COLOR_BLACK
- \arg LCD_COLOR_GREY
- \arg LCD_COLOR_BLUE
- \arg LCD_COLOR_BLUE2
- \arg LCD_COLOR_RED
- \arg LCD_COLOR_MAGENTA
- \arg LCD_COLOR_GREEN
- \arg LCD_COLOR_CYAN
- \arg LCD_COLOR_YELLOW
- */
- uint16_t lcd_background_color_get(void)
- {
- return cur_back_color;
- }
- /*!
- \brief set the text font
- \param[in] font: the text font
- \param[out] none
- \retval none
- */
- void lcd_font_set(font_struct *fonts)
- {
- cur_fonts = fonts;
- }
- /*!
- \brief get the text font
- \param[in] none
- \param[out] none
- \retval the text font
- */
- font_struct *lcd_font_get(void)
- {
- return cur_fonts;
- }
- /*!
- \brief set the cursor of LCD
- \param[in] x: the row-coordinate
- \param[in] y: the column-coordinate
- \param[out] none
- \retval none
- */
- static void lcd_cursor_set(uint16_t x,uint16_t y)
- {
- lcd_register_write(0x004e,x);
- lcd_register_write(0x004f,y);
- }
- /*!
- \brief clear the LCD screen to the specified color
- \param[in] color: specified screen color
- \param[out] none
- \retval none
- */
- void lcd_clear(uint16_t color)
- {
- uint32_t index=0;
- lcd_cursor_set(0,0);
- /* prepare to write GRAM */
- lcd_gram_write_prepare();
- for(index=0;index<76800;index++){
- *(__IO uint16_t *) (BANK0_LCD_D) = color;
- }
- }
- /*!
- \brief set the point according to the specified position and color
- \param[in] x: the row-coordinate
- \param[in] y: the column-coordinate
- \param[in] point: specified color of the point
- \param[out] none
- \retval none
- */
- void lcd_point_set(uint16_t x,uint16_t y,uint16_t point)
- {
- if ((x > 240)||(y > 320)){
- return;
- }
- lcd_cursor_set(x,y);
- lcd_gram_write_prepare();
- lcd_gram_write(point);
- }
- /*!
- \brief get point GRAM according to the specified position
- \param[in] x: the row-coordinate
- \param[in] y: the column-coordinate
- \param[out] none
- \retval GRAM value of point
- */
- uint16_t lcd_point_get(uint16_t x,uint16_t y)
- {
- uint16_t data;
-
- if ((x > 240)||(y > 320)){
- return 0;
- }
-
- lcd_cursor_set(x,y);
- data = lcd_gram_read();
- return data;
- }
- /*!
- \brief draw a horizontal line on LCD screen
- \param[in] x: the row-coordinate
- \param[in] start_y: the start column-coordinate
- \param[in] end_y: the end column-coordinate
- \param[in] color: specified color of the point
- \param[in] width: line width
- \param[out] none
- \retval none
- */
- void lcd_hline_draw(uint16_t x,uint16_t start_y,uint16_t end_y,uint16_t color,uint16_t width)
- {
- uint16_t i, y;
- for (i = 0; i < width; i++) {
- uint16_t sx = x + i;
- for (y = start_y; y < end_y; y++) {
- lcd_point_set(sx, y, color);
- }
- }
- }
- /*!
- \brief draw a rectangle according to the specified position and color
- \param[in] start_x: the start position of row-coordinate
- \param[in] start_y: the start position of column-coordinate
- \param[in] end_x: the end position of row-coordinate
- \param[in] end_y: the end position of column-coordinate
- \param[in] point: specified color of the point
- \param[out] none
- \retval none
- */
- void lcd_rectangle_draw(uint16_t start_x,uint16_t start_y,uint16_t end_x,uint16_t end_y,uint16_t point)
- {
- uint16_t x,y;
- x=start_x;
- y=start_y;
- /* draw four lines */
- for(x=start_x;x<end_x;x++){
- /* draw a point */
- lcd_point_set(x,y,point);
- }
- for(y=start_y;y<end_y;y++){
- lcd_point_set(x,y,point);
- }
- for(x=end_x;x>start_x;x--){
- lcd_point_set(x,y,point);
- }
- for(y=end_y;y>start_y;y--){
- lcd_point_set(x,y,point);
- }
- }
- /*!
- \brief fill the specified color to a rectangle
- \param[in] start_x: the start position of row-coordinate
- \param[in] start_y: the start position of column-coordinate
- \param[in] end_x: the end position of row-coordinate
- \param[in] end_y: the end position of column-coordinate
- \param[in] color: specified color
- \param[out] none
- \retval none
- */
- void lcd_rectangle_fill(uint16_t start_x,uint16_t start_y,uint16_t width,uint16_t height)
- {
- uint16_t x, y;
- x = start_x;
- y = start_y;
- for (x = start_x; x < start_x+width; x++) {
- for (y = start_y; y < start_y+height; y++) {
- lcd_point_set(x, y, cur_text_color);
- }
- }
- }
- /*!
- \brief display a char on LCD screen according to the specified position
- \param[in] x: the start position of row-coordinate
- \param[in] y: the start position of column-coordinate
- \param[in] c: the char
- \param[in] char_color: the color of char
- \param[in] c_format: the struct of char format
- font: CHAR_FONT_8_16 or CHAR_FONT_16_24
- direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
- char_color: the color of char
- bk_color: the color of backgroud
- \param[out] none
- \retval none
- */
- void lcd_char_display(uint16_t x,uint16_t y,uint8_t c)
- {
- uint16_t i = 0, j = 0;
- uint8_t temp_char = 0;
- for (i = 0; i < cur_fonts->height; i++) {
- temp_char = cur_fonts->table[((c - 0x20) * 16) + i];
- if(CHAR_DIRECTION_HORIZONTAL == cur_text_direction){
- for (j = 0; j < cur_fonts->width; j++) {
- if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
- /* set point of char */
- lcd_point_set(x - i, y + j, cur_text_color);
- } else {
- /* set point of background */
- lcd_point_set(x - i, y + j, cur_back_color);
- }
- }
- }else{
- for (j = 0; j < cur_fonts->width; j++) {
- if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
- /* set point of char */
- lcd_point_set(x + j, y + i, cur_text_color);
- } else {
- /* set point of background */
- lcd_point_set(x + j, y + i, cur_back_color);
- }
- }
- }
- }
- }
- /* display the vertical character on LCD */
- void lcd_vertical_char_display(uint16_t line, uint16_t column, uint8_t ascii)
- {
- lcd_char_display(line, column, ascii);
- }
- void lcd_vertical_string_display(uint16_t stringline, uint16_t offset, uint8_t *ptr)
- {
- uint16_t i = 0U;
- int len = strlen((const char *)ptr);
- for (i = 0; i < len; i ++) {
- lcd_char_display(stringline, (offset + 8 * i), *ptr++);
- }
- }
|