From ce4c351ebceb3313248a9823a877216912a29f04 Mon Sep 17 00:00:00 2001 From: tanek liang Date: Wed, 23 Aug 2017 19:19:52 +0800 Subject: [PATCH] add sdram and lcd driver --- bsp/gd32450z-eval/applications/application.c | 41 +- bsp/gd32450z-eval/applications/rtgui_demo.c | 127 +++++ bsp/gd32450z-eval/applications/rtgui_demo.h | 20 + bsp/gd32450z-eval/drivers/SConscript | 3 + bsp/gd32450z-eval/drivers/board.h | 9 +- bsp/gd32450z-eval/drivers/drv_exmc_sdram.c | 315 +++++++++++ bsp/gd32450z-eval/drivers/drv_exmc_sdram.h | 32 ++ bsp/gd32450z-eval/drivers/drv_lcd.c | 266 +++++++++ bsp/gd32450z-eval/drivers/drv_usart.c | 519 +++++++++--------- bsp/gd32450z-eval/drivers/gd32f450z_eval.h | 118 ++++ .../drivers/gd32f450z_lcd_eval.c | 316 +++++++++++ .../drivers/gd32f450z_lcd_eval.h | 55 ++ bsp/gd32450z-eval/gd32_rom.icf | 3 + bsp/gd32450z-eval/project.ewp | 155 +++++- bsp/gd32450z-eval/project.uvproj | 299 ++++------ bsp/gd32450z-eval/project.uvprojx | 304 ++++++++-- bsp/gd32450z-eval/rtconfig.h | 18 +- 17 files changed, 2050 insertions(+), 550 deletions(-) create mode 100644 bsp/gd32450z-eval/applications/rtgui_demo.c create mode 100644 bsp/gd32450z-eval/applications/rtgui_demo.h create mode 100644 bsp/gd32450z-eval/drivers/drv_exmc_sdram.c create mode 100644 bsp/gd32450z-eval/drivers/drv_exmc_sdram.h create mode 100644 bsp/gd32450z-eval/drivers/drv_lcd.c create mode 100644 bsp/gd32450z-eval/drivers/gd32f450z_eval.h create mode 100644 bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.c create mode 100644 bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.h diff --git a/bsp/gd32450z-eval/applications/application.c b/bsp/gd32450z-eval/applications/application.c index f3cf980f3..5284d36e8 100644 --- a/bsp/gd32450z-eval/applications/application.c +++ b/bsp/gd32450z-eval/applications/application.c @@ -15,31 +15,64 @@ #include #include -#include "finsh.h" +#include + +#ifdef RT_USING_GUIENGINE +#include "rtgui_demo.h" +#include +#endif #include +void gd_eval_led_init (void) +{ + /* enable the led clock */ + rcu_periph_clock_enable(RCU_GPIOD); + /* configure led GPIO port */ + gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_4); + gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4); + + GPIO_BC(GPIOD) = GPIO_PIN_4; +} + void rt_init_thread_entry(void* parameter) { /* initialization RT-Thread Components */ #ifdef RT_USING_COMPONENTS_INIT rt_components_init(); #endif + + gd_eval_led_init(); + +#ifdef RT_USING_GUIENGINE + { + rt_device_t device; + + device = rt_device_find("lcd"); + /* re-set graphic device */ + rtgui_graphic_set_device(device); + + rt_gui_demo_init(); + } +#endif + + while(1) + { + GPIO_TG(GPIOD) = GPIO_PIN_4; + rt_thread_delay(RT_TICK_PER_SECOND); + } } int rt_application_init() { rt_thread_t tid; - tid = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX/3, 20); if (tid != RT_NULL) rt_thread_startup(tid); - - return 0; } diff --git a/bsp/gd32450z-eval/applications/rtgui_demo.c b/bsp/gd32450z-eval/applications/rtgui_demo.c new file mode 100644 index 000000000..998dae6da --- /dev/null +++ b/bsp/gd32450z-eval/applications/rtgui_demo.c @@ -0,0 +1,127 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "finsh.h" +#include "rtgui_demo.h" + +#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +#ifdef RT_USING_GUIENGINE + +struct rtgui_win *main_win; +rt_bool_t dc_event_handler(struct rtgui_object *object, rtgui_event_t *event); + +static void rt_gui_demo_entry(void *parameter) +{ + struct rtgui_app *app; + //struct rtgui_dc *dc; + + DEBUG_PRINTF("gui demo entry\n"); + + /* create gui app */ + app = rtgui_app_create("gui_demo"); + if (app == RT_NULL) + { + DEBUG_PRINTF("rtgui_app_create faild\n"); + return; + } + + /* create main window */ + main_win = rtgui_mainwin_create(RT_NULL, + "UiWindow", RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER); + if (main_win == RT_NULL) + { + DEBUG_PRINTF("main_win is null\n"); + rtgui_app_destroy(app); + return; + } + + rtgui_object_set_event_handler(RTGUI_OBJECT(main_win), dc_event_handler); + + DEBUG_PRINTF("rtgui_win_show\n"); + rtgui_win_show(main_win, RT_FALSE); + + DEBUG_PRINTF("rtgui_app_run\n"); + rtgui_app_run(app); + + DEBUG_PRINTF("rtgui_win_destroy\n"); + rtgui_win_destroy(main_win); + + DEBUG_PRINTF("rtgui_app_destroy\n"); + rtgui_app_destroy(app); +} + +rt_bool_t dc_event_handler(struct rtgui_object *object, rtgui_event_t *event) +{ + struct rtgui_widget *widget = RTGUI_WIDGET(object); + + if (event->type == RTGUI_EVENT_PAINT) + { + struct rtgui_dc *dc; + rtgui_rect_t rect; + + rt_kprintf("\r\n RTGUI_EVENT_PAINT \r\n"); + rtgui_win_event_handler(RTGUI_OBJECT(widget), event); + + rtgui_widget_get_rect(widget, &rect); + DEBUG_PRINTF("widget react x1: %d, y1: %d, x2: %d, y2: %d\r\n", + rect.x1, rect.y1, rect.x2, rect.y2); + + dc = rtgui_dc_begin_drawing(widget); + if(dc == RT_NULL) + { + DEBUG_PRINTF("\r\n dc is null \r\n"); + return RT_FALSE; + } + + rtgui_dc_draw_line(dc, rect.x1, rect.y1, rect.x2, rect.y2); + rtgui_dc_draw_line(dc, rect.x1, rect.y2, rect.x2, rect.y1); + + rect.x1 += (rect.x2 - rect.x1) / 2; + rect.y1 += (rect.y2 - rect.y1) / 2; + rtgui_dc_draw_text_stroke(dc, __DATE__"--"__TIME__, &rect, HIGH_LIGHT, BLUE); + + + rtgui_dc_end_drawing(dc); + } + return RT_FALSE; +} + +int rt_gui_demo_init(void) +{ + rt_thread_t tid; + tid = rt_thread_create("mygui", + rt_gui_demo_entry, RT_NULL, + 2048, 25, 10); + + if (tid != RT_NULL) + rt_thread_startup(tid); + + return 0; +} +#endif /* RT_USING_GUIENGINE */ diff --git a/bsp/gd32450z-eval/applications/rtgui_demo.h b/bsp/gd32450z-eval/applications/rtgui_demo.h new file mode 100644 index 000000000..e27f7b560 --- /dev/null +++ b/bsp/gd32450z-eval/applications/rtgui_demo.h @@ -0,0 +1,20 @@ +/* + * File : dc.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-02 tanek first version + */ +#ifndef __APP_GUI_DEMO_H__ +#define __APP_GUI_DEMO_H__ + +extern int rt_gui_demo_init(void); + +#endif + diff --git a/bsp/gd32450z-eval/drivers/SConscript b/bsp/gd32450z-eval/drivers/SConscript index a3dc5cf59..12ddae883 100644 --- a/bsp/gd32450z-eval/drivers/SConscript +++ b/bsp/gd32450z-eval/drivers/SConscript @@ -7,7 +7,10 @@ cwd = os.path.join(str(Dir('#')), 'drivers') # add the general drivers. src = Split(""" board.c +drv_exmc_sdram.c drv_usart.c +gd32f450z_lcd_eval.c +drv_lcd.c """) CPPPATH = [cwd] diff --git a/bsp/gd32450z-eval/drivers/board.h b/bsp/gd32450z-eval/drivers/board.h index ecfd8b17b..c91005d02 100644 --- a/bsp/gd32450z-eval/drivers/board.h +++ b/bsp/gd32450z-eval/drivers/board.h @@ -18,12 +18,9 @@ #include -// Begin Address of External SDRAM -// Default: 0xD0000000 -#define EXT_SDRAM_BEGIN SDRAM_BANK_ADDR /* the begining address of external SDRAM */ -// End Address of External SRAM -// Default: 0xD0800000 -#define EXT_SDRAM_END (SDRAM_BANK_ADDR + W9825G6KH_SIZE) /* the end address of external SDRAM */ + +#define EXT_SDRAM_BEGIN (0xC0000000U) /* the begining address of external SDRAM */ +#define EXT_SDRAM_END (EXT_SDRAM_BEGIN + (32U * 1024 * 1024)) /* the end address of external SDRAM */ // Internal SRAM memory size[Kbytes] <8-64> // Default: 64 diff --git a/bsp/gd32450z-eval/drivers/drv_exmc_sdram.c b/bsp/gd32450z-eval/drivers/drv_exmc_sdram.c new file mode 100644 index 000000000..41355987b --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_exmc_sdram.c @@ -0,0 +1,315 @@ +/*! + \file main.c + \brief exmc sdram(MICRON 48LC16M16A2) driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, demo for GD32F4xx +*/ + +#include "gd32f4xx.h" +#include "drv_exmc_sdram.h" +#include + +/* define mode register content */ +/* burst length */ +#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0003) + +/* burst type */ +#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) + +/* CAS latency */ +#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) + +/* write mode */ +#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) + +#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) + +#define SDRAM_TIMEOUT ((uint32_t)0x0000FFFF) + +static void delay_1ms(volatile uint32_t count) +{ + count *= 1000; + while (count--) + { + count = count; + } +} + +/*! + \brief sdram peripheral initialize + \param[in] sdram_device: specifie the SDRAM device + \param[out] none + \retval none +*/ +void exmc_synchronous_dynamic_ram_init(uint32_t sdram_device) +{ + exmc_sdram_parameter_struct sdram_init_struct; + exmc_sdram_timing_parameter_struct sdram_timing_init_struct; + exmc_sdram_command_parameter_struct sdram_command_init_struct; + + uint32_t command_content = 0, bank_select; + uint32_t timeout = SDRAM_TIMEOUT; + + /* enable EXMC clock*/ + rcu_periph_clock_enable(RCU_EXMC); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_GPIOD); + rcu_periph_clock_enable(RCU_GPIOE); + rcu_periph_clock_enable(RCU_GPIOF); + rcu_periph_clock_enable(RCU_GPIOG); + rcu_periph_clock_enable(RCU_GPIOH); + + /* common GPIO configuration */ + /* SDNWE(PC0),SDNE0(PC2),SDCKE0(PC3) pin configuration */ + gpio_af_set(GPIOC, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); + + /* D2(PD0),D3(PD1),D13(PD8),D14(PD9),D15(PD10),D0(PD14),D1(PD15) pin configuration */ + gpio_af_set(GPIOD, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | + GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | + GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_output_options_set(GPIOD, GPIO_OTYPE_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); + + /* NBL0(PE0),NBL1(PE1),D4(PE7),D5(PE8),D6(PE9),D7(PE10),D8(PE11),D9(PE12),D10(PE13),D11(PE14),D12(PE15) pin configuration */ + gpio_af_set(GPIOE, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | 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_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | 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_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | 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); + + /* A0(PF0),A1(PF1),A2(PF2),A3(PF3),A4(PF4),A5(PF5),NRAS(PF11),A6(PF12),A7(PF13),A8(PF14),A9(PF15) pin configuration */ + gpio_af_set(GPIOF, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | + GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | + GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | + GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + + /* A10(PG0),A11(PG1),A12(PG2),A14(PG4),A15(PG5),SDCLK(PG8),NCAS(PG15) pin configuration */ + gpio_af_set(GPIOG, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | + GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15); + gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | + GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15); + gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | + GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15); + + /* specify which SDRAM to read and write */ + if(EXMC_SDRAM_DEVICE0 == sdram_device){ + bank_select = EXMC_SDRAM_DEVICE0_SELECT; + }else{ + bank_select = EXMC_SDRAM_DEVICE1_SELECT; + } + + /* EXMC SDRAM device initialization sequence --------------------------------*/ + /* Step 1 : configure SDRAM timing registers --------------------------------*/ + /* LMRD: 2 clock cycles */ + sdram_timing_init_struct.load_mode_register_delay = 2; + /* XSRD: min = 67ns */ + sdram_timing_init_struct.exit_selfrefresh_delay = 7; + /* RASD: min=42ns , max=120k (ns) */ + sdram_timing_init_struct.row_address_select_delay = 5; + /* ARFD: min=60ns */ + sdram_timing_init_struct.auto_refresh_delay = 6; + /* WRD: min=1 Clock cycles +6ns */ + sdram_timing_init_struct.write_recovery_delay = 2; + /* RPD: min=18ns */ + sdram_timing_init_struct.row_precharge_delay = 2; + /* RCD: min=18ns */ + sdram_timing_init_struct.row_to_column_delay = 2; + + /* step 2 : configure SDRAM control registers ---------------------------------*/ + sdram_init_struct.sdram_device = sdram_device; + sdram_init_struct.column_address_width = EXMC_SDRAM_COW_ADDRESS_9; + sdram_init_struct.row_address_width = EXMC_SDRAM_ROW_ADDRESS_13; + sdram_init_struct.data_width = EXMC_SDRAM_DATABUS_WIDTH_16B; + sdram_init_struct.internal_bank_number = EXMC_SDRAM_4_INTER_BANK; + sdram_init_struct.cas_latency = EXMC_CAS_LATENCY_3_SDCLK; + sdram_init_struct.write_protection = DISABLE; + sdram_init_struct.sdclock_config = EXMC_SDCLK_PERIODS_2_HCLK; + sdram_init_struct.brust_read_switch = ENABLE; + sdram_init_struct.pipeline_read_delay = EXMC_PIPELINE_DELAY_1_HCLK; + sdram_init_struct.timing = &sdram_timing_init_struct; + /* EXMC SDRAM bank initialization */ + exmc_sdram_init(&sdram_init_struct); + + /* step 3 : configure CKE high command---------------------------------------*/ + sdram_command_init_struct.command = EXMC_SDRAM_CLOCK_ENABLE; + sdram_command_init_struct.bank_select = bank_select; + sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_1_SDCLK; + sdram_command_init_struct.mode_register_content = 0; + /* wait until the SDRAM controller is ready */ + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } + /* send the command */ + exmc_sdram_command_config(&sdram_command_init_struct); + + /* step 4 : insert 10ms delay----------------------------------------------*/ + delay_1ms(10); + + /* step 5 : configure precharge all command----------------------------------*/ + sdram_command_init_struct.command = EXMC_SDRAM_PRECHARGE_ALL; + sdram_command_init_struct.bank_select = bank_select; + sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_1_SDCLK; + sdram_command_init_struct.mode_register_content = 0; + /* wait until the SDRAM controller is ready */ + timeout = SDRAM_TIMEOUT; + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } + /* send the command */ + exmc_sdram_command_config(&sdram_command_init_struct); + + /* step 6 : configure Auto-Refresh command-----------------------------------*/ + sdram_command_init_struct.command = EXMC_SDRAM_AUTO_REFRESH; + sdram_command_init_struct.bank_select = bank_select; + sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_8_SDCLK; + sdram_command_init_struct.mode_register_content = 0; + /* wait until the SDRAM controller is ready */ + timeout = SDRAM_TIMEOUT; + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } + /* send the command */ + exmc_sdram_command_config(&sdram_command_init_struct); + + /* step 7 : configure load mode register command-----------------------------*/ + /* program mode register */ + command_content = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | + SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | + SDRAM_MODEREG_CAS_LATENCY_3 | + SDRAM_MODEREG_OPERATING_MODE_STANDARD | + SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; + + sdram_command_init_struct.command = EXMC_SDRAM_LOAD_MODE_REGISTER; + sdram_command_init_struct.bank_select = bank_select; + sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_1_SDCLK; + sdram_command_init_struct.mode_register_content = command_content; + + /* wait until the SDRAM controller is ready */ + timeout = SDRAM_TIMEOUT; + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } + /* send the command */ + exmc_sdram_command_config(&sdram_command_init_struct); + + /* step 8 : set the auto-refresh rate counter--------------------------------*/ + /* 64ms, 8192-cycle refresh, 64ms/8192=7.81us */ + /* SDCLK_Freq = SYS_Freq/2 */ + /* (7.81 us * SDCLK_Freq) - 20 */ + exmc_sdram_refresh_count_set(761); + + /* wait until the SDRAM controller is ready */ + timeout = SDRAM_TIMEOUT; + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } +} + +/*! + \brief fill the buffer with specified value + \param[in] pbuffer: pointer on the buffer to fill + \param[in] buffersize: size of the buffer to fill + \param[in] value: value to fill on the buffer + \param[out] none + \retval none +*/ +void fill_buffer(uint8_t *pbuffer, uint16_t buffer_lengh, uint16_t offset) +{ + uint16_t index = 0; + + /* put in global buffer same values */ + for (index = 0; index < buffer_lengh; index++ ){ + pbuffer[index] = index + offset; + } +} + +/*! + \brief write a byte buffer(data is 8 bits) to the EXMC SDRAM memory + \param[in] sdram_device: specify which a SDRAM memory block is written + \param[in] pbuffer: pointer to buffer + \param[in] writeaddr: SDRAM memory internal address from which the data will be written + \param[in] numbytetowrite: number of bytes to write + \param[out] none + \retval none +*/ +void sdram_writebuffer_8(uint32_t sdram_device,uint8_t* pbuffer, uint32_t writeaddr, uint32_t numbytetowrite) +{ + uint32_t temp_addr; + + /* Select the base address according to EXMC_Bank */ + if(sdram_device == EXMC_SDRAM_DEVICE0){ + temp_addr = SDRAM_DEVICE0_ADDR; + }else{ + temp_addr = SDRAM_DEVICE1_ADDR; + } + + /* While there is data to write */ + for(; numbytetowrite != 0; numbytetowrite--) { + /* Transfer data to the memory */ + *(uint8_t *) (temp_addr + writeaddr) = *pbuffer++; + + /* Increment the address*/ + writeaddr += 1; + } +} + +/*! + \brief read a block of 8-bit data from the EXMC SDRAM memory + \param[in] sdram_device: specify which a SDRAM memory block is written + \param[in] pbuffer: pointer to buffer + \param[in] readaddr: SDRAM memory internal address to read from + \param[in] numbytetoread: number of bytes to read + \param[out] none + \retval none +*/ +void sdram_readbuffer_8(uint32_t sdram_device,uint8_t* pbuffer, uint32_t readaddr, uint32_t numbytetoread) +{ + uint32_t temp_addr; + + /* select the base address according to EXMC_Bank */ + if(sdram_device == EXMC_SDRAM_DEVICE0){ + temp_addr = SDRAM_DEVICE0_ADDR; + }else{ + temp_addr = SDRAM_DEVICE1_ADDR; + } + + /* while there is data to read */ + for(; numbytetoread != 0; numbytetoread--){ + /* read a byte from the memory */ + *pbuffer++ = *(uint8_t*) (temp_addr + readaddr); + + /* increment the address */ + readaddr += 1; + } +} + +int rt_hw_sdram_init(void) +{ + exmc_synchronous_dynamic_ram_init(EXMC_SDRAM_DEVICE0); + return 0; +} +INIT_BOARD_EXPORT(rt_hw_sdram_init); + diff --git a/bsp/gd32450z-eval/drivers/drv_exmc_sdram.h b/bsp/gd32450z-eval/drivers/drv_exmc_sdram.h new file mode 100644 index 000000000..b859d3622 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_exmc_sdram.h @@ -0,0 +1,32 @@ +/*! + \file exmc_nandflash.h + \brief the header file of sdram(MICRON 48LC16M16A2) driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, demo for GD32F4xx +*/ + +#ifndef EXMC_SDRAM_H +#define EXMC_SDRAM_H + +#include "gd32f4xx.h" + +/* sdram peripheral initialize */ +void exmc_synchronous_dynamic_ram_init(uint32_t sdram_device); + +/* fill the buffer with specified value */ +void fill_buffer(uint8_t *pbuffer, uint16_t buffer_lengh, uint16_t offset); + +/* write a byte buffer(data is 8 bits) to the EXMC SDRAM memory */ +void sdram_writebuffer_8(uint32_t sdram_device,uint8_t* pbuffer, uint32_t writeaddr, uint32_t numbytetowrite); + +/* read a block of 8-bit data from the EXMC SDRAM memory */ +void sdram_readbuffer_8(uint32_t sdram_device,uint8_t* pbuffer, uint32_t readaddr, uint32_t numbytetoread); + +#define SDRAM_DEVICE0_ADDR ((uint32_t)0xC0000000) +#define SDRAM_DEVICE1_ADDR ((uint32_t)0xD0000000) + +#endif /* EXMC_SDRAM_H */ diff --git a/bsp/gd32450z-eval/drivers/drv_lcd.c b/bsp/gd32450z-eval/drivers/drv_lcd.c new file mode 100644 index 000000000..7ed43e80b --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_lcd.c @@ -0,0 +1,266 @@ +/* + * File : usart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Tanek the first version + */ + +#include "gd32f450z_lcd_eval.h" +#include +#include +#include + +#include + +#define RT_HW_LCD_WIDTH ((uint16_t)320) /* LCD PIXEL WIDTH */ +#define RT_HW_LCD_HEIGHT ((uint16_t)480) /* LCD PIXEL HEIGHT */ + +#define LCD_480_320_HSYNC ((uint32_t)10) /* Horizontal synchronization */ +#define LCD_480_320_HBP ((uint32_t)20) /* Horizontal back porch */ +#define LCD_480_320_HFP ((uint32_t)40) /* Horizontal front porch */ +#define LCD_480_320_VSYNC ((uint32_t)2) /* Vertical synchronization */ +#define LCD_480_320_VBP ((uint32_t)1) /* Vertical back porch */ +#define LCD_480_320_VFP ((uint32_t)4) /* Vertical front porch */ + +#define LCD_BITS_PER_PIXEL 16 + + +static rt_uint16_t *lcd_framebuffer = RT_NULL; +static rt_uint16_t *_rt_framebuffer = RT_NULL; + +static struct rt_device_graphic_info _lcd_info; +static struct rt_device lcd; + +/*! + \brief configure TLI GPIO + \param[in] none + \param[out] none + \retval none +*/ +static void tli_gpio_config(void) +{ + /* enable the periphral clock */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_GPIOD); + rcu_periph_clock_enable(RCU_GPIOF); + rcu_periph_clock_enable(RCU_GPIOG); + + /* configure HSYNC(PC6), VSYNC(PA4), PCLK(PG7), DE(PF10) */ + /* configure LCD_R7(PG6), LCD_R6(PA8), LCD_R5(PA12), LCD_R4(PA11), LCD_R3(PB0), + LCD_G7(PD3), LCD_G6(PC7), LCD_G5(PB11), LCD_G4(PB10), LCD_G3(PG10), LCD_G2(PA6), + LCD_B7(PB9), LCD_B6(PB8), LCD_B5(PA3), LCD_B4(PG12), LCD_B3(PG11) */ + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_3); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_4); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_6); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_12); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_11); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_8); + + gpio_af_set(GPIOB,GPIO_AF_9,GPIO_PIN_0); + gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_10); + gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_11); + gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_8); + gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_9); + + gpio_af_set(GPIOC,GPIO_AF_14,GPIO_PIN_6); + gpio_af_set(GPIOC,GPIO_AF_14,GPIO_PIN_7); + + gpio_af_set(GPIOD,GPIO_AF_14,GPIO_PIN_3); + + gpio_af_set(GPIOF,GPIO_AF_14,GPIO_PIN_10); + + gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_6); + gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_7); + gpio_af_set(GPIOG,GPIO_AF_9,GPIO_PIN_10); + gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_11); + gpio_af_set(GPIOG,GPIO_AF_9,GPIO_PIN_12); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_6 + |GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4|GPIO_PIN_3 + |GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 + |GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 + |GPIO_PIN_11); + + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_6|GPIO_PIN_7); + + gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); + gpio_output_options_set(GPIOD, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_3); + + gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); + gpio_output_options_set(GPIOF, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_10); + + gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12); + gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12); +} + +/*! + \brief LCD Configuration + \param[in] none + \param[out] none + \retval none +*/ +static void lcd_config(void) +{ + /* configure the LCD control line */ + lcd_ctrl_line_config(); + lcd_disable(); + lcd_enable(); + + /* configure the GPIO of TLI */ + tli_gpio_config(); + /* configure the LCD_SPI */ + lcd_spi_config(); + + /* power on the LCD */ + //lcd_power_on(); + lcd_power_on3(); //New Version 3.5" TFT RGB Hardware needs use this initilize funtion ---By xufei 2016.10.21 +} + +/*! + \brief configure TLI peripheral + \param[in] none + \param[out] none + \retval none +*/ +static void tli_config(void) +{ + tli_parameter_struct tli_init_struct; + tli_layer_parameter_struct tli_layer_init_struct; + + rcu_periph_clock_enable(RCU_TLI); + tli_gpio_config(); + + /* configure the PLLSAI clock to generate lcd clock */ + if(ERROR == rcu_pllsai_config(192, 2, 3, 3)){ + while(1); + } + rcu_tli_clock_div_config(RCU_PLLSAIR_DIV8); + rcu_osci_on(RCU_PLLSAI_CK); + if(ERROR == rcu_osci_stab_wait(RCU_PLLSAI_CK)){ + while(1); + } + + /* TLI initialization */ + tli_init_struct.signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW; + tli_init_struct.signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW; + tli_init_struct.signalpolarity_de = TLI_DE_ACTLIVE_LOW; + tli_init_struct.signalpolarity_pixelck = TLI_PIXEL_CLOCK_TLI; + + /* LCD display timing configuration */ + tli_init_struct.synpsz_hpsz = LCD_480_320_HSYNC; + tli_init_struct.synpsz_vpsz = LCD_480_320_VSYNC; + tli_init_struct.backpsz_hbpsz = LCD_480_320_HSYNC + LCD_480_320_HBP; + tli_init_struct.backpsz_vbpsz = LCD_480_320_VSYNC + LCD_480_320_VBP; + tli_init_struct.activesz_hasz = RT_HW_LCD_WIDTH + LCD_480_320_HSYNC + LCD_480_320_HBP; + tli_init_struct.activesz_vasz = RT_HW_LCD_HEIGHT + LCD_480_320_VSYNC + LCD_480_320_VBP; + tli_init_struct.totalsz_htsz = RT_HW_LCD_WIDTH + LCD_480_320_HSYNC + LCD_480_320_HBP + LCD_480_320_HFP; + tli_init_struct.totalsz_vtsz = RT_HW_LCD_HEIGHT + LCD_480_320_VSYNC + LCD_480_320_VBP + LCD_480_320_VFP; + + /* LCD background color configure*/ + tli_init_struct.backcolor_red = 0x00; + tli_init_struct.backcolor_green = 0x00; + tli_init_struct.backcolor_blue = 0x00; + tli_init(&tli_init_struct); + + lcd_framebuffer = rt_malloc(sizeof(rt_uint16_t) * RT_HW_LCD_HEIGHT * RT_HW_LCD_WIDTH); + RT_ASSERT(lcd_framebuffer != NULL); + rt_memset(lcd_framebuffer, 0, sizeof(rt_uint16_t) * RT_HW_LCD_WIDTH * RT_HW_LCD_HEIGHT); + + /* TLI layer0 configuration */ + tli_layer_init_struct.layer_window_leftpos = tli_init_struct.backpsz_hbpsz + 1; + tli_layer_init_struct.layer_window_rightpos = tli_init_struct.backpsz_hbpsz + RT_HW_LCD_WIDTH; + tli_layer_init_struct.layer_window_toppos = tli_init_struct.backpsz_vbpsz + 1; + tli_layer_init_struct.layer_window_bottompos = tli_init_struct.backpsz_vbpsz + RT_HW_LCD_HEIGHT; + + tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565; + tli_layer_init_struct.layer_sa = 0xFF; + tli_layer_init_struct.layer_default_blue = 0x00; + tli_layer_init_struct.layer_default_green = 0x00; + tli_layer_init_struct.layer_default_red = 0x00; + tli_layer_init_struct.layer_default_alpha = 0x00; + tli_layer_init_struct.layer_acf1 = LAYER_ACF1_PASA; + tli_layer_init_struct.layer_acf2 = LAYER_ACF2_PASA; + tli_layer_init_struct.layer_frame_bufaddr = (uint32_t)lcd_framebuffer; + tli_layer_init_struct.layer_frame_line_length = ((RT_HW_LCD_WIDTH * 2) + 3); + tli_layer_init_struct.layer_frame_buf_stride_offset = (RT_HW_LCD_WIDTH * 2); + tli_layer_init_struct.layer_frame_total_line_number = RT_HW_LCD_HEIGHT; + + tli_layer_init(LAYER0, &tli_layer_init_struct); +} + +static rt_err_t rt_lcd_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + switch (cmd) + { + case RTGRAPHIC_CTRL_RECT_UPDATE: + { + memcpy((void *)lcd_framebuffer, _rt_framebuffer, sizeof(rt_uint16_t)*RT_HW_LCD_HEIGHT * RT_HW_LCD_WIDTH); + } + break; + + case RTGRAPHIC_CTRL_POWERON: + break; + + case RTGRAPHIC_CTRL_POWEROFF: + break; + + case RTGRAPHIC_CTRL_GET_INFO: + memcpy(args, &_lcd_info, sizeof(_lcd_info)); + break; + + case RTGRAPHIC_CTRL_SET_MODE: + break; + } + + return RT_EOK; +} + +int gd32_hw_lcd_init(void) +{ + _rt_framebuffer = rt_malloc_align(sizeof(rt_uint16_t) * RT_HW_LCD_WIDTH * RT_HW_LCD_HEIGHT, 32); + if (_rt_framebuffer == RT_NULL) + return -1; /* no memory yet */ + + lcd_config(); + tli_config(); + tli_layer_enable(LAYER0); + tli_reload_config(TLI_FRAME_BLANK_RELOAD_EN); + tli_enable(); + + _lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL; + _lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565; + _lcd_info.framebuffer = (void *)_rt_framebuffer; + _lcd_info.width = RT_HW_LCD_WIDTH; + _lcd_info.height = RT_HW_LCD_HEIGHT; + + lcd.type = RT_Device_Class_Graphic; + lcd.init = NULL; + lcd.open = NULL; + lcd.close = NULL; + lcd.read = NULL; + lcd.write = NULL; + lcd.control = rt_lcd_control; + lcd.user_data = (void *)&_lcd_info; + + /* register lcd device to RT-Thread */ + rt_device_register(&lcd, "lcd", RT_DEVICE_FLAG_RDWR); + + return 0; +} +INIT_DEVICE_EXPORT(gd32_hw_lcd_init); diff --git a/bsp/gd32450z-eval/drivers/drv_usart.c b/bsp/gd32450z-eval/drivers/drv_usart.c index 6bd4487d6..0535848f2 100644 --- a/bsp/gd32450z-eval/drivers/drv_usart.c +++ b/bsp/gd32450z-eval/drivers/drv_usart.c @@ -20,6 +20,16 @@ #include #include +#ifdef RT_USING_SERIAL + +#if !defined(RT_USING_USART0) && !defined(RT_USING_USART1) && \ + !defined(RT_USING_USART2) && !defined(RT_USING_UART3) && \ + !defined(RT_USING_UART4) && !defined(RT_USING_USART5) && \ + !defined(RT_USING_UART6) && !defined(RT_USING_UART7) +#error "Please define " + +#endif + #include /* GD32 uart driver */ @@ -27,203 +37,37 @@ struct gd32_uart { uint32_t uart_periph; //Todo: 3bits - IRQn_Type irqn; //Todo: 7bits - + IRQn_Type irqn; //Todo: 7bits rcu_periph_enum per_clk; //Todo: 5bits rcu_periph_enum tx_gpio_clk; //Todo: 5bits rcu_periph_enum rx_gpio_clk; //Todo: 5bits - uint32_t tx_port; //Todo: 4bits uint16_t tx_af; //Todo: 4bits uint16_t tx_pin; //Todo: 4bits - uint32_t rx_port; //Todo: 4bits uint16_t rx_af; //Todo: 4bits uint16_t rx_pin; //Todo: 4bits -}; - -/** -* @brief UART MSP Initialization -* This function configures the hardware resources used in this example: -* - Peripheral's clock enable -* - Peripheral's GPIO Configuration -* - NVIC configuration for UART interrupt request enable -* @param huart: UART handle pointer -* @retval None -*/ -void gd32_uart_gpio_init(struct gd32_uart *uart) -{ - /* enable USART clock */ - rcu_periph_clock_enable(uart->tx_gpio_clk); - rcu_periph_clock_enable(uart->rx_gpio_clk); - rcu_periph_clock_enable(uart->per_clk); - - /* connect port to USARTx_Tx */ - gpio_af_set(uart->tx_port, uart->tx_af, uart->tx_pin); - - /* connect port to USARTx_Rx */ - gpio_af_set(uart->rx_port, uart->rx_af, uart->rx_pin); - - /* configure USART Tx as alternate function push-pull */ - gpio_mode_set(uart->tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, uart->tx_pin); - gpio_output_options_set(uart->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->tx_pin); - - /* configure USART Rx as alternate function push-pull */ - gpio_mode_set(uart->rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, uart->rx_pin); - gpio_output_options_set(uart->rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->rx_pin); - - NVIC_SetPriority(uart->irqn, 0); - NVIC_EnableIRQ(uart->irqn); -} - -static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg) -{ - struct gd32_uart *uart; - - RT_ASSERT(serial != RT_NULL); - RT_ASSERT(cfg != RT_NULL); - - uart = (struct gd32_uart *)serial->parent.user_data; - - gd32_uart_gpio_init(uart); - - usart_baudrate_set(uart->uart_periph, cfg->baud_rate); - - switch (cfg->data_bits) - { - case DATA_BITS_9: - usart_word_length_set(uart->uart_periph, USART_WL_9BIT); - break; - - default: - usart_word_length_set(uart->uart_periph, USART_WL_8BIT); - break; - } - - switch (cfg->stop_bits) - { - case STOP_BITS_2: - usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT); - break; - default: - usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT); - break; - } - - switch (cfg->parity) - { - case PARITY_ODD: - usart_parity_config(uart->uart_periph, USART_PM_ODD); - break; - case PARITY_EVEN: - usart_parity_config(uart->uart_periph, USART_PM_EVEN); - break; - default: - usart_parity_config(uart->uart_periph, USART_PM_NONE); - break; - } - - usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE); - usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE); - usart_enable(uart->uart_periph); - - return RT_EOK; -} - -static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg) -{ - struct gd32_uart *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct gd32_uart *)serial->parent.user_data; - - switch (cmd) - { - case RT_DEVICE_CTRL_CLR_INT: - /* disable rx irq */ - NVIC_DisableIRQ(uart->irqn); - /* disable interrupt */ - usart_interrupt_disable(uart->uart_periph, USART_INTEN_RBNEIE); - - break; - case RT_DEVICE_CTRL_SET_INT: - /* enable rx irq */ - NVIC_EnableIRQ(uart->irqn); - /* enable interrupt */ - usart_interrupt_enable(uart->uart_periph, USART_INTEN_RBNEIE); - break; - } - - return RT_EOK; -} - -static int gd32_putc(struct rt_serial_device *serial, char ch) -{ - struct gd32_uart *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct gd32_uart *)serial->parent.user_data; - - usart_data_transmit(uart->uart_periph, ch); - while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET)); - - return 1; -} -static int gd32_getc(struct rt_serial_device *serial) -{ - int ch; - struct gd32_uart *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct gd32_uart *)serial->parent.user_data; - - ch = -1; - if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET) - ch = usart_data_receive(uart->uart_periph); - return ch; -} - -/** - * Uart common interrupt process. This need add to uart ISR. - * - * @param serial serial device - */ -static void uart_isr(struct rt_serial_device *serial) -{ - struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data; - - RT_ASSERT(uart != RT_NULL); - - /* UART in mode Receiver -------------------------------------------------*/ - if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_RBNEIE) != RESET) && - (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)) - { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); - /* Clear RXNE interrupt flag */ - usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE); - } -} - -static const struct rt_uart_ops gd32_uart_ops = -{ - gd32_configure, - gd32_control, - gd32_putc, - gd32_getc, + struct rt_serial_device * serial; + char *device_name; }; +static void uart_isr(struct rt_serial_device *serial); + #if defined(RT_USING_USART0) +struct rt_serial_device serial0; + /* UART1 device driver structure */ -struct gd32_uart usart0 = +const struct gd32_uart usart0 = { USART0, // uart peripheral index USART0_IRQn, // uart iqrn RCU_USART0, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock GPIOA, GPIO_AF_7, GPIO_PIN_9, // tx port, tx alternate, tx pin GPIOA, GPIO_AF_7, GPIO_PIN_10, // rx port, rx alternate, rx pin + &serial0, + "uart0", }; -struct rt_serial_device serial0; void USART0_IRQHandler(void) { @@ -239,16 +83,18 @@ void USART0_IRQHandler(void) #endif /* RT_USING_USART0 */ #if defined(RT_USING_USART1) +struct rt_serial_device serial1; /* UART1 device driver structure */ -struct gd32_uart usart1 = +const struct gd32_uart usart1 = { USART1, // uart peripheral index USART1_IRQn, // uart iqrn RCU_USART1, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock GPIOA, GPIO_AF_7, GPIO_PIN_2, // tx port, tx alternate, tx pin GPIOA, GPIO_AF_7, GPIO_PIN_3, // rx port, rx alternate, rx pin + &serial1, + "uart1", }; -struct rt_serial_device serial1; void USART1_IRQHandler(void) { @@ -264,16 +110,18 @@ void USART1_IRQHandler(void) #endif /* RT_USING_UART1 */ #if defined(RT_USING_USART2) +struct rt_serial_device serial2; /* UART2 device driver structure */ -struct gd32_uart usart2 = +const struct gd32_uart usart2 = { USART2, // uart peripheral index USART2_IRQn, // uart iqrn RCU_USART2, RCU_GPIOB, RCU_GPIOB, // periph clock, tx gpio clock, rt gpio clock GPIOB, GPIO_AF_7, GPIO_PIN_10, // tx port, tx alternate, tx pin GPIOB, GPIO_AF_7, GPIO_PIN_11, // rx port, rx alternate, rx pin + &serial2, + "uart2", }; -struct rt_serial_device serial2; void USART2_IRQHandler(void) { @@ -289,16 +137,18 @@ void USART2_IRQHandler(void) #endif /* RT_USING_UART2 */ #if defined(RT_USING_UART3) +struct rt_serial_device serial3; /* UART3 device driver structure */ -struct gd32_uart uart3 = +const struct gd32_uart uart3 = { UART3, // uart peripheral index UART3_IRQn, // uart iqrn RCU_UART3, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock GPIOC, GPIO_AF_8, GPIO_PIN_10, // tx port, tx alternate, tx pin GPIOC, GPIO_AF_8, GPIO_PIN_11, // rx port, rx alternate, rx pin + &serial3, + "uart3", }; -struct rt_serial_device serial3; void UART3_IRQHandler(void) { @@ -314,16 +164,18 @@ void UART3_IRQHandler(void) #endif /* RT_USING_UART3 */ #if defined(RT_USING_UART4) +struct rt_serial_device serial4; /* UART4 device driver structure */ -struct gd32_uart uart4 = +const struct gd32_uart uart4 = { UART4, // uart peripheral index UART4_IRQn, // uart iqrn RCU_UART4, RCU_GPIOC, RCU_GPIOD, // periph clock, tx gpio clock, rt gpio clock GPIOC, GPIO_AF_8, GPIO_PIN_12, // tx port, tx alternate, tx pin GPIOD, GPIO_AF_8, GPIO_PIN_2, // rx port, rx alternate, rx pin + &serial4, + "uart4", }; -struct rt_serial_device serial4; void UART4_IRQHandler(void) { @@ -338,16 +190,18 @@ void UART4_IRQHandler(void) #endif /* RT_USING_UART4 */ #if defined(RT_USING_USART5) +struct rt_serial_device serial5; /* UART5 device driver structure */ -struct gd32_uart usart5 = +const struct gd32_uart usart5 = { USART5, // uart peripheral index USART5_IRQn, // uart iqrn RCU_USART5, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock GPIOC, GPIO_AF_8, GPIO_PIN_6, // tx port, tx alternate, tx pin GPIOC, GPIO_AF_8, GPIO_PIN_7, // rx port, rx alternate, rx pin + &serial5, + "uart5", }; -struct rt_serial_device serial5; void USART5_IRQHandler(void) { @@ -363,16 +217,18 @@ void USART5_IRQHandler(void) #endif /* RT_USING_UART5 */ #if defined(RT_USING_UART6) +struct rt_serial_device serial6; /* UART6 device driver structure */ -struct gd32_uart uart6 = +const struct gd32_uart uart6 = { UART6, // uart peripheral index UART6_IRQn, // uart iqrn RCU_UART6, RCU_GPIOE, RCU_GPIOE, // periph clock, tx gpio clock, rt gpio clock GPIOE, GPIO_AF_8, GPIO_PIN_7, // tx port, tx alternate, tx pin GPIOE, GPIO_AF_8, GPIO_PIN_8, // rx port, rx alternate, rx pin + &serial6, + "uart6", }; -struct rt_serial_device serial6; void UART6_IRQHandler(void) { @@ -388,16 +244,18 @@ void UART6_IRQHandler(void) #endif /* RT_USING_UART6 */ #if defined(RT_USING_UART7) +struct rt_serial_device serial7; /* UART7 device driver structure */ -struct gd32_uart uart7 = +const struct gd32_uart uart7 = { UART7, // uart peripheral index UART7_IRQn, // uart iqrn RCU_UART7, RCU_GPIOE, RCU_GPIOE, // periph clock, tx gpio clock, rt gpio clock GPIOE, GPIO_AF_8, GPIO_PIN_0, // tx port, tx alternate, tx pin GPIOE, GPIO_AF_8, GPIO_PIN_1, // rx port, rx alternate, rx pin + &serial7, + "uart7", }; -struct rt_serial_device serial7; void UART7_IRQHandler(void) { @@ -413,115 +271,228 @@ void UART7_IRQHandler(void) #endif /* RT_USING_UART7 */ -int gd32_hw_usart_init(void) +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example: +* - Peripheral's clock enable +* - Peripheral's GPIO Configuration +* - NVIC configuration for UART interrupt request enable +* @param huart: UART handle pointer +* @retval None +*/ +void gd32_uart_gpio_init(struct gd32_uart *uart) +{ + /* enable USART clock */ + rcu_periph_clock_enable(uart->tx_gpio_clk); + rcu_periph_clock_enable(uart->rx_gpio_clk); + rcu_periph_clock_enable(uart->per_clk); + + /* connect port to USARTx_Tx */ + gpio_af_set(uart->tx_port, uart->tx_af, uart->tx_pin); + + /* connect port to USARTx_Rx */ + gpio_af_set(uart->rx_port, uart->rx_af, uart->rx_pin); + + /* configure USART Tx as alternate function push-pull */ + gpio_mode_set(uart->tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, uart->tx_pin); + gpio_output_options_set(uart->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->tx_pin); + + /* configure USART Rx as alternate function push-pull */ + gpio_mode_set(uart->rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, uart->rx_pin); + gpio_output_options_set(uart->rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->rx_pin); + + NVIC_SetPriority(uart->irqn, 0); + NVIC_EnableIRQ(uart->irqn); +} + +static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { struct gd32_uart *uart; - struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart = (struct gd32_uart *)serial->parent.user_data; -#ifdef RT_USING_USART0 - uart = &usart0; + gd32_uart_gpio_init(uart); + + usart_baudrate_set(uart->uart_periph, cfg->baud_rate); - serial0.ops = &gd32_uart_ops; - serial0.config = config; + switch (cfg->data_bits) + { + case DATA_BITS_9: + usart_word_length_set(uart->uart_periph, USART_WL_9BIT); + break; - /* register UART1 device */ - rt_hw_serial_register(&serial0, - "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); -#endif /* RT_USING_USART0 */ + default: + usart_word_length_set(uart->uart_periph, USART_WL_8BIT); + break; + } + switch (cfg->stop_bits) + { + case STOP_BITS_2: + usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT); + break; + default: + usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT); + break; + } -#ifdef RT_USING_USART1 - uart = &usart1; + switch (cfg->parity) + { + case PARITY_ODD: + usart_parity_config(uart->uart_periph, USART_PM_ODD); + break; + case PARITY_EVEN: + usart_parity_config(uart->uart_periph, USART_PM_EVEN); + break; + default: + usart_parity_config(uart->uart_periph, USART_PM_NONE); + break; + } - serial1.ops = &gd32_uart_ops; - serial1.config = config; + usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE); + usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE); + usart_enable(uart->uart_periph); - /* register UART1 device */ - rt_hw_serial_register(&serial1, - "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); -#endif /* RT_USING_UART1 */ + return RT_EOK; +} -#ifdef RT_USING_USART2 - uart = &usart2; +static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct gd32_uart *uart; - serial2.ops = &gd32_uart_ops; - serial2.config = config; + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; - /* register UART2 device */ - rt_hw_serial_register(&serial2, - "uart2", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); -#endif /* RT_USING_UART2 */ + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + NVIC_DisableIRQ(uart->irqn); + /* disable interrupt */ + usart_interrupt_disable(uart->uart_periph, USART_INTEN_RBNEIE); -#ifdef RT_USING_UART3 - uart = &uart3; + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + NVIC_EnableIRQ(uart->irqn); + /* enable interrupt */ + usart_interrupt_enable(uart->uart_periph, USART_INTEN_RBNEIE); + break; + } - serial3.ops = &gd32_uart_ops; - serial3.config = config; + return RT_EOK; +} - /* register UART3 device */ - rt_hw_serial_register(&serial3, - "uart3", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); -#endif /* RT_USING_UART3 */ +static int gd32_putc(struct rt_serial_device *serial, char ch) +{ + struct gd32_uart *uart; -#ifdef RT_USING_UART4 - uart = &uart4; + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; - serial4.ops = &gd32_uart_ops; - serial4.config = config; + usart_data_transmit(uart->uart_periph, ch); + while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET)); + + return 1; +} - /* register UART4 device */ - rt_hw_serial_register(&serial4, - "uart4", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); -#endif /* RT_USING_UART4 */ +static int gd32_getc(struct rt_serial_device *serial) +{ + int ch; + struct gd32_uart *uart; -#ifdef RT_USING_USART5 - uart = &usart5; + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; - serial5.ops = &gd32_uart_ops; - serial5.config = config; + ch = -1; + if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET) + ch = usart_data_receive(uart->uart_periph); + return ch; +} - /* register UART5 device */ - rt_hw_serial_register(&serial5, - "uart5", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); -#endif /* RT_USING_UART5 */ - -#ifdef RT_USING_UART6 - uart = &uart6; +/** + * Uart common interrupt process. This need add to uart ISR. + * + * @param serial serial device + */ +static void uart_isr(struct rt_serial_device *serial) +{ + struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data; - serial6.ops = &gd32_uart_ops; - serial6.config = config; + RT_ASSERT(uart != RT_NULL); - /* register UART6 device */ - rt_hw_serial_register(&serial6, - "uart6", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); -#endif /* RT_USING_UART6 */ - -#ifdef RT_USING_UART7 - uart = &uart7; + /* UART in mode Receiver -------------------------------------------------*/ + if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_RBNEIE) != RESET) && + (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + /* Clear RXNE interrupt flag */ + usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE); + } +} + +static const struct rt_uart_ops gd32_uart_ops = +{ + gd32_configure, + gd32_control, + gd32_putc, + gd32_getc, +}; - serial7.ops = &gd32_uart_ops; - serial7.config = config; +int gd32_hw_usart_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + int i; + static const struct gd32_uart * uarts[] = { + #ifdef RT_USING_USART0 + &usart0, + #endif + + #ifdef RT_USING_USART1 + &usart1, + #endif + + #ifdef RT_USING_USART2 + &usart2, + #endif + + #ifdef RT_USING_UART3 + &uart3, + #endif + + #ifdef RT_USING_UART4 + &uart4, + #endif + + #ifdef RT_USING_USART5 + &usart5, + #endif + + #ifdef RT_USING_UART6 + &uart6, + #endif + + #ifdef RT_USING_UART7 + &uart7, + #endif + }; + + for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++) + { + uarts[i]->serial->ops = &gd32_uart_ops; + uarts[i]->serial->config = config; + + /* register UART1 device */ + rt_hw_serial_register(uarts[i]->serial, + uarts[i]->device_name, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + (void *)uarts[i]); + } - /* register UART7 device */ - rt_hw_serial_register(&serial7, - "uart7", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - uart); -#endif /* RT_USING_UART7 */ return 0; } INIT_BOARD_EXPORT(gd32_hw_usart_init); +#endif diff --git a/bsp/gd32450z-eval/drivers/gd32f450z_eval.h b/bsp/gd32450z-eval/drivers/gd32f450z_eval.h new file mode 100644 index 000000000..73ea9baaa --- /dev/null +++ b/bsp/gd32450z-eval/drivers/gd32f450z_eval.h @@ -0,0 +1,118 @@ +/*! + \file gd32f450z_eval.h + \brief definitions for GD32F450_EVAL's leds, keys and COM ports hardware resources +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, firmware for GD32F450Z +*/ + +#ifndef GD32F450Z_EVAL_H +#define GD32F450Z_EVAL_H + +#ifdef cplusplus + extern "C" { +#endif + +#include "gd32f4xx.h" + +/* exported types */ +typedef enum +{ + LED1 = 0, + LED2 = 1, + LED3 = 2 +} led_typedef_enum; + +typedef enum +{ + KEY_WAKEUP = 0, + KEY_TAMPER = 1, + KEY_USER = 2 +} key_typedef_enum; + +typedef enum +{ + KEY_MODE_GPIO = 0, + KEY_MODE_EXTI = 1 +} keymode_typedef_enum; + +/* eval board low layer led */ +#define LEDn 3U + +#define LED1_PIN GPIO_PIN_4 +#define LED1_GPIO_PORT GPIOD +#define LED1_GPIO_CLK RCU_GPIOD + +#define LED2_PIN GPIO_PIN_5 +#define LED2_GPIO_PORT GPIOD +#define LED2_GPIO_CLK RCU_GPIOD + +#define LED3_PIN GPIO_PIN_3 +#define LED3_GPIO_PORT GPIOG +#define LED3_GPIO_CLK RCU_GPIOG + +#define COMn 1U +#define EVAL_COM1 USART0 +#define EVAL_COM1_CLK RCU_USART0 + +#define EVAL_COM1_TX_PIN GPIO_PIN_9 +#define EVAL_COM1_RX_PIN GPIO_PIN_10 + +#define EVAL_COM_GPIO_PORT GPIOA +#define EVAL_COM_GPIO_CLK RCU_GPIOA +#define EVAL_COM_AF GPIO_AF_7 + +#define KEYn 3U + +/* tamper push-button */ +#define TAMPER_KEY_PIN GPIO_PIN_13 +#define TAMPER_KEY_GPIO_PORT GPIOC +#define TAMPER_KEY_GPIO_CLK RCU_GPIOC +#define TAMPER_KEY_EXTI_LINE EXTI_13 +#define TAMPER_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOC +#define TAMPER_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN13 +#define TAMPER_KEY_EXTI_IRQn EXTI10_15_IRQn + +/* wakeup push-button */ +#define WAKEUP_KEY_PIN GPIO_PIN_0 +#define WAKEUP_KEY_GPIO_PORT GPIOA +#define WAKEUP_KEY_GPIO_CLK RCU_GPIOA +#define WAKEUP_KEY_EXTI_LINE EXTI_0 +#define WAKEUP_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOA +#define WAKEUP_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN0 +#define WAKEUP_KEY_EXTI_IRQn EXTI0_IRQn + +/* user push-button */ +#define USER_KEY_PIN GPIO_PIN_14 +#define USER_KEY_GPIO_PORT GPIOB +#define USER_KEY_GPIO_CLK RCU_GPIOB +#define USER_KEY_EXTI_LINE EXTI_14 +#define USER_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOB +#define USER_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN14 +#define USER_KEY_EXTI_IRQn EXTI10_15_IRQn + +/* function declarations */ +/* configures led GPIO */ +void gd_eval_led_init(led_typedef_enum lednum); +/* turn on selected led */ +void gd_eval_led_on(led_typedef_enum lednum); +/* turn off selected led */ +void gd_eval_led_off(led_typedef_enum lednum); +/* toggle the selected led */ +void gd_eval_led_toggle(led_typedef_enum lednum); +/* configure key */ +void gd_eval_key_init(key_typedef_enum key_num, keymode_typedef_enum key_mode); +/* return the selected button state */ +uint8_t gd_eval_key_state_get(key_typedef_enum button); +/* configure COM port */ +void gd_eval_com_init(uint32_t com); + + +#ifdef cplusplus +} +#endif + +#endif /* GD32F450Z_EVAL_H */ diff --git a/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.c b/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.c new file mode 100644 index 000000000..8a309a1a7 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.c @@ -0,0 +1,316 @@ +/*! + \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--); +} diff --git a/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.h b/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.h new file mode 100644 index 000000000..815925a17 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.h @@ -0,0 +1,55 @@ +/*! + \file gd32f450z_lcd_eval.h + \brief definitions for GD32F450Z_EVAL's LCD +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, firmware for GD32F450Z +*/ + +#ifndef GD32F450Z_LCD_EVAL_H +#define GD32F450Z_LCD_EVAL_H + +#include "gd32f450z_eval.h" + +#define LCD_CS_PIN GPIO_PIN_11 +#define LCD_CS_GPIO_PORT GPIOD +#define LCD_CS_GPIO_CLK RCU_GPIOD + +#define LCD_RS_PIN GPIO_PIN_3 +#define LCD_RS_GPIO_PORT GPIOE +#define LCD_RS_GPIO_CLK RCU_GPIOE + +#define LCD_SPI_SCK_PIN GPIO_PIN_13 +#define LCD_SPI_SCK_GPIO_PORT GPIOG +#define LCD_SPI_SCK_GPIO_CLK RCU_GPIOG + +#define LCD_SPI_MOSI_PIN GPIO_PIN_14 +#define LCD_SPI_MOSI_GPIO_PORT GPIOG +#define LCD_SPI_MOSI_GPIO_CLK RCU_GPIOG + +#define LCD_SPI SPI5 +#define LCD_SPI_CLK RCU_SPI5 + +/* enable the LCD */ +void lcd_enable(void); +/* disable the LCD */ +void lcd_disable(void); +/* configure the LCD control line */ +void lcd_ctrl_line_config(void); +/* set the LCD control line */ +void lcd_ctrl_line_set(uint32_t gpiox, uint16_t gpiopin); +/* reset the LCD control line */ +void lcd_ctrl_line_reset(uint32_t gpiox, uint16_t gpiopin); +/* configure the LCD SPI and it's GPIOs */ +void lcd_spi_config(void); +/* write command to select LCD register */ +void lcd_command_write(uint8_t lcd_register); +/* write data to select LCD register */ +void lcd_data_write(uint8_t value); +/* configure the LCD based on the power on sequence */ +void lcd_power_on(void); +void lcd_power_on3(void); +#endif /* GD32F450Z_LCD_EVAL_H */ diff --git a/bsp/gd32450z-eval/gd32_rom.icf b/bsp/gd32450z-eval/gd32_rom.icf index d35cb36af..1741be6a7 100644 --- a/bsp/gd32450z-eval/gd32_rom.icf +++ b/bsp/gd32450z-eval/gd32_rom.icf @@ -29,6 +29,9 @@ define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; +keep { section FSymTab }; +keep { section VSymTab }; +keep { section .rti_fn* }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; diff --git a/bsp/gd32450z-eval/project.ewp b/bsp/gd32450z-eval/project.ewp index c4f4eb5ac..28ab78cad 100644 --- a/bsp/gd32450z-eval/project.ewp +++ b/bsp/gd32450z-eval/project.ewp @@ -32,11 +32,11 @@