diff --git a/bsp/stm32f10x/SConscript b/bsp/stm32f10x/SConscript index 33909578796c0dc4bca17da6065c06bd07bed962..854017f2999c09d3967b99412ca2d9cbfba5e985 100644 --- a/bsp/stm32f10x/SConscript +++ b/bsp/stm32f10x/SConscript @@ -17,8 +17,19 @@ if GetDepend('RT_USING_LWIP'): else: src_drv += ['enc28j60.c'] + ['dm9000a.c'] +if GetDepend('RT_USING_RTGUI'): + src_drv += ['key.c', 'touch.c', 'calibration.c'] + +if GetDepend('RT_USING_RTGUI'): + if rtconfig.RT_USING_LCD_TYPE == 'FMT0371': + src_drv += ['lcd_a70.c'] + elif rtconfig.RT_USING_LCD_TYPE == 'ILI932X': + src_drv += ['ili_lcd_general.c'] + elif rtconfig.RT_USING_LCD_TYPE == 'SSD1289': + src_drv += ['ssd1289.c'] + src = src_bsp + src_drv -CPPPATH = [RTT_ROOT + '/bsp/stm32f10x'] +CPPPATH = [ GetCurrentDir() ] CPPDEFINES = [] group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) diff --git a/bsp/stm32f10x/SConstruct b/bsp/stm32f10x/SConstruct index 2151b715e50b70dc648e03f84408abeb79a7a923..cdb96402d81a9e77c19698d19e52a1e45a844ae7 100644 --- a/bsp/stm32f10x/SConstruct +++ b/bsp/stm32f10x/SConstruct @@ -29,6 +29,9 @@ objs = PrepareBuilding(env, RTT_ROOT) # STM32 firemare library building script objs = objs + SConscript(RTT_ROOT + '/bsp/stm32f10x/Libraries/SConscript', variant_dir='build/bsp/Libraries', duplicate=0) +if GetDepend('RT_USING_RTGUI'): + objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', variant_dir='build/examples/gui', duplicate=0) + # build program env.Program(TARGET, objs) diff --git a/bsp/stm32f10x/application.c b/bsp/stm32f10x/application.c index 56df272b4bf44de460843062d0786fe656431c33..32f664cb5eb678a6b924eb64ba74a06f96020302 100644 --- a/bsp/stm32f10x/application.c +++ b/bsp/stm32f10x/application.c @@ -115,6 +115,33 @@ void rt_init_thread_entry(void* parameter) rt_kprintf("TCP/IP initialized!\n"); } #endif + +#ifdef RT_USING_RTGUI + { + rt_device_t lcd; + + /* init lcd */ + rt_hw_lcd_init(); + + /* init touch panel */ + rtgui_touch_hw_init(); + + /* init keypad */ + rt_hw_key_init(); + + /* re-init device driver */ + rt_device_init_all(); + + /* find lcd device */ + lcd = rt_device_find("lcd"); + + /* set lcd device as rtgui graphic driver */ + rtgui_graphic_set_device(lcd); + + /* startup rtgui */ + rtgui_startup(); + } +#endif /* #ifdef RT_USING_RTGUI */ } int rt_application_init() diff --git a/bsp/stm32f10x/calibration.c b/bsp/stm32f10x/calibration.c new file mode 100644 index 0000000000000000000000000000000000000000..92bd10fe446d6e433d4b112f5ee24bf298720ffb --- /dev/null +++ b/bsp/stm32f10x/calibration.c @@ -0,0 +1,284 @@ +#include +#include +#include +#include + +#include "touch.h" + +#define CALIBRATION_STEP_LEFTTOP 0 +#define CALIBRATION_STEP_RIGHTTOP 1 +#define CALIBRATION_STEP_RIGHTBOTTOM 2 +#define CALIBRATION_STEP_LEFTBOTTOM 3 +#define CALIBRATION_STEP_CENTER 4 + +#define TOUCH_WIN_UPDATE 1 +#define TOUCH_WIN_CLOSE 2 + +#define CALIBRATION_WIDTH 15 +#define CALIBRATION_HEIGHT 15 + +struct calibration_session +{ + rt_uint8_t step; + + struct calibration_data data; + + rt_uint16_t width; rt_uint16_t height; + + rt_device_t device; + rt_thread_t tid; +}; +static struct calibration_session* calibration_ptr = RT_NULL; + +static void calibration_data_post(rt_uint16_t x, rt_uint16_t y) +{ + if (calibration_ptr != RT_NULL) + { + switch (calibration_ptr->step) + { + case CALIBRATION_STEP_LEFTTOP: + calibration_ptr->data.min_x = x; + calibration_ptr->data.min_y = y; + break; + + case CALIBRATION_STEP_RIGHTTOP: + calibration_ptr->data.max_x = x; + calibration_ptr->data.min_y = (calibration_ptr->data.min_y + y)/2; + break; + + case CALIBRATION_STEP_LEFTBOTTOM: + calibration_ptr->data.min_x = (calibration_ptr->data.min_x + x)/2; + calibration_ptr->data.max_y = y; + break; + + case CALIBRATION_STEP_RIGHTBOTTOM: + calibration_ptr->data.max_x = (calibration_ptr->data.max_x + x)/2; + calibration_ptr->data.max_y = (calibration_ptr->data.max_y + y)/2; + break; + + case CALIBRATION_STEP_CENTER: + /* calibration done */ + { + rt_uint16_t w, h; + + struct rtgui_event_command ecmd; + RTGUI_EVENT_COMMAND_INIT(&ecmd); + ecmd.command_id = TOUCH_WIN_CLOSE; + + /* calculate calibrated data */ + if (calibration_ptr->data.max_x > calibration_ptr->data.min_x) + w = calibration_ptr->data.max_x - calibration_ptr->data.min_x; + else + w = calibration_ptr->data.min_x - calibration_ptr->data.max_x; + w = (w/(calibration_ptr->width - 2 * CALIBRATION_WIDTH)) * CALIBRATION_WIDTH; + + if (calibration_ptr->data.max_y > calibration_ptr->data.min_y) + h = calibration_ptr->data.max_y - calibration_ptr->data.min_y; + else + h = calibration_ptr->data.min_y - calibration_ptr->data.max_y; + h = (h/(calibration_ptr->height - 2 * CALIBRATION_HEIGHT)) * CALIBRATION_HEIGHT; + + rt_kprintf("w: %d, h: %d\n", w, h); + + if (calibration_ptr->data.max_x > calibration_ptr->data.min_x) + { + calibration_ptr->data.min_x -= w; + calibration_ptr->data.max_x += w; + } + else + { + calibration_ptr->data.min_x += w; + calibration_ptr->data.max_x -= w; + } + + if (calibration_ptr->data.max_y > calibration_ptr->data.min_y) + { + calibration_ptr->data.min_y -= h; + calibration_ptr->data.max_y += h; + } + else + { + calibration_ptr->data.min_y += h; + calibration_ptr->data.max_y -= h; + } + + rt_kprintf("calibration data: (%d, %d), (%d, %d)\n", + calibration_ptr->data.min_x, + calibration_ptr->data.max_x, + calibration_ptr->data.min_y, + calibration_ptr->data.max_y); + rtgui_thread_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command)); + } + return; + } + + calibration_ptr->step ++; + + /* post command event */ + { + struct rtgui_event_command ecmd; + RTGUI_EVENT_COMMAND_INIT(&ecmd); + ecmd.command_id = TOUCH_WIN_UPDATE; + + rtgui_thread_send(calibration_ptr->tid, &ecmd.parent, sizeof(struct rtgui_event_command)); + } + } +} + +rt_bool_t calibration_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +{ + switch (event->type) + { + case RTGUI_EVENT_PAINT: + { + struct rtgui_dc* dc; + struct rtgui_rect rect; + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) break; + + /* get rect information */ + rtgui_widget_get_rect(widget, &rect); + + /* clear whole window */ + RTGUI_WIDGET_BACKGROUND(widget) = white; + rtgui_dc_fill_rect(dc, &rect); + + /* reset color */ + RTGUI_WIDGET_BACKGROUND(widget) = green; + RTGUI_WIDGET_FOREGROUND(widget) = black; + + switch (calibration_ptr->step) + { + case CALIBRATION_STEP_LEFTTOP: + rtgui_dc_draw_hline(dc, 0, 2 * CALIBRATION_WIDTH, CALIBRATION_HEIGHT); + rtgui_dc_draw_vline(dc, CALIBRATION_WIDTH, 0, 2 * CALIBRATION_HEIGHT); + RTGUI_WIDGET_FOREGROUND(widget) = red; + rtgui_dc_fill_circle(dc, CALIBRATION_WIDTH, CALIBRATION_HEIGHT, 4); + break; + + case CALIBRATION_STEP_RIGHTTOP: + rtgui_dc_draw_hline(dc, calibration_ptr->width - 2 * CALIBRATION_WIDTH, + calibration_ptr->width, CALIBRATION_HEIGHT); + rtgui_dc_draw_vline(dc, calibration_ptr->width - CALIBRATION_WIDTH, 0, 2 * CALIBRATION_HEIGHT); + RTGUI_WIDGET_FOREGROUND(widget) = red; + rtgui_dc_fill_circle(dc, calibration_ptr->width - CALIBRATION_WIDTH, CALIBRATION_HEIGHT, 4); + break; + + case CALIBRATION_STEP_LEFTBOTTOM: + rtgui_dc_draw_hline(dc, 0, 2 * CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT); + rtgui_dc_draw_vline(dc, CALIBRATION_WIDTH, calibration_ptr->height - 2 * CALIBRATION_HEIGHT, calibration_ptr->height); + RTGUI_WIDGET_FOREGROUND(widget) = red; + rtgui_dc_fill_circle(dc, CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT, 4); + break; + + case CALIBRATION_STEP_RIGHTBOTTOM: + rtgui_dc_draw_hline(dc, calibration_ptr->width - 2 * CALIBRATION_WIDTH, + calibration_ptr->width, calibration_ptr->height - CALIBRATION_HEIGHT); + rtgui_dc_draw_vline(dc, calibration_ptr->width - CALIBRATION_WIDTH, calibration_ptr->height - 2 * CALIBRATION_HEIGHT, calibration_ptr->height); + RTGUI_WIDGET_FOREGROUND(widget) = red; + rtgui_dc_fill_circle(dc, calibration_ptr->width - CALIBRATION_WIDTH, calibration_ptr->height - CALIBRATION_HEIGHT, 4); + break; + + case CALIBRATION_STEP_CENTER: + rtgui_dc_draw_hline(dc, calibration_ptr->width/2 - CALIBRATION_WIDTH, calibration_ptr->width/2 + CALIBRATION_WIDTH, calibration_ptr->height/2); + rtgui_dc_draw_vline(dc, calibration_ptr->width/2, calibration_ptr->height/2 - CALIBRATION_HEIGHT, calibration_ptr->height/2 + CALIBRATION_HEIGHT); + RTGUI_WIDGET_FOREGROUND(widget) = red; + rtgui_dc_fill_circle(dc, calibration_ptr->width/2, calibration_ptr->height/2, 4); + break; + } + rtgui_dc_end_drawing(dc); + } + break; + + case RTGUI_EVENT_COMMAND: + { + struct rtgui_event_command* ecmd = (struct rtgui_event_command*)event; + + switch (ecmd->command_id) + { + case TOUCH_WIN_UPDATE: + rtgui_widget_update(widget); + break; + case TOUCH_WIN_CLOSE: + rtgui_win_close(RTGUI_WIN(widget)); + break; + } + } + return RT_TRUE; + + default: + rtgui_win_event_handler(widget, event); + } + + return RT_FALSE; +} + +void calibration_entry(void* parameter) +{ + rt_mq_t mq; + rtgui_win_t* win; + struct rtgui_rect rect; + + mq = rt_mq_create("cali", 40, 8, RT_IPC_FLAG_FIFO); + if (mq == RT_NULL) return; + + rtgui_thread_register(rt_thread_self(), mq); + + rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &rect); + + /* set screen rect */ + calibration_ptr->width = rect.x2; + calibration_ptr->height = rect.y2; + + /* create calibration window */ + win = rtgui_win_create(RT_NULL, + "calibration", &rect, RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER); + rtgui_widget_set_event_handler(RTGUI_WIDGET(win), calibration_event_handler); + if (win != RT_NULL) + { + rtgui_win_show(win, RT_FALSE); + // rtgui_widget_update(RTGUI_WIDGET(win)); + rtgui_win_event_loop(win); + } + + rtgui_thread_deregister(rt_thread_self()); + rt_mq_delete(mq); + + /* set calibration data */ + rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION_DATA, &calibration_ptr->data); + + /* recover to normal */ + rt_device_control(calibration_ptr->device, RT_TOUCH_NORMAL, RT_NULL); + + /* release memory */ + rt_free(calibration_ptr); + calibration_ptr = RT_NULL; +} + +void calibration_init() +{ + rt_device_t device; + + device = rt_device_find("touch"); + if (device == RT_NULL) return; /* no this device */ + + calibration_ptr = (struct calibration_session*)rt_malloc(sizeof(struct calibration_session)); + rt_memset(calibration_ptr, 0, sizeof(struct calibration_data)); + calibration_ptr->device = device; + + rt_device_control(calibration_ptr->device, RT_TOUCH_CALIBRATION, (void*)calibration_data_post); + + calibration_ptr->tid = rt_thread_create("cali", calibration_entry, RT_NULL, + 2048, 20, 5); + if (calibration_ptr->tid != RT_NULL) rt_thread_startup(calibration_ptr->tid); +} + +#ifdef RT_USING_FINSH +#include +void calibration() +{ + calibration_init(); +} +FINSH_FUNCTION_EXPORT(calibration, perform touch calibration); +#endif diff --git a/bsp/stm32f10x/rtconfig.h b/bsp/stm32f10x/rtconfig.h index 111e56b9217b2cd72bd42be751f9f0827d48f32b..f523cccf0b125603aca8640ade5ad80d09481149 100644 --- a/bsp/stm32f10x/rtconfig.h +++ b/bsp/stm32f10x/rtconfig.h @@ -138,4 +138,30 @@ #define RT_LWIP_ETHTHREAD_MBOX_SIZE 10 #define RT_LWIP_ETHTHREAD_STACKSIZE 512 +/* SECTION: RT-Thread/GUI */ +#define RT_USING_RTGUI + +/* name length of RTGUI object */ +#define RTGUI_NAME_MAX 12 +/* support 16 weight font */ +#define RTGUI_USING_FONT16 +/* support Chinese font */ +#define RTGUI_USING_FONTHZ +/* use DFS as file interface */ +#define RTGUI_USING_DFS_FILERW +/* use font file as Chinese font */ +#define RTGUI_USING_HZ_FILE +/* use Chinese bitmap font */ +#define RTGUI_USING_HZ_BMP +/* use small size in RTGUI */ +#define RTGUI_USING_SMALL_SIZE +/* use mouse cursor */ +/* #define RTGUI_USING_MOUSE_CURSOR */ +/* default font size in RTGUI */ +#define RTGUI_DEFAULT_FONT_SIZE 16 + +/* image support */ +/* #define RTGUI_IMAGE_XPM */ +/* #define RTGUI_IMAGE_BMP */ + #endif diff --git a/bsp/stm32f10x/rtconfig.py b/bsp/stm32f10x/rtconfig.py index 474757e725b8b715497e6443c0f02794cf77301a..222dc8ca83e6f4619e077b09c4bf424cd9707ffe 100644 --- a/bsp/stm32f10x/rtconfig.py +++ b/bsp/stm32f10x/rtconfig.py @@ -3,12 +3,16 @@ ARCH='arm' CPU='stm32' CROSS_TOOL='keil' +# lcd panel options +# 'FMT0371','ILI932X', 'SSD1289' +RT_USING_LCD_TYPE = 'SSD1289' + # cross_tool provides the cross compiler # EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - EXEC_PATH = 'E:/Program Files/CodeSourcery/Sourcery G++ Lite/bin' + EXEC_PATH = 'D:/SourceryGCC/bin' elif CROSS_TOOL == 'keil': PLATFORM = 'armcc' EXEC_PATH = 'E:/Keil' diff --git a/bsp/stm32f10x/ssd1289.c b/bsp/stm32f10x/ssd1289.c new file mode 100644 index 0000000000000000000000000000000000000000..94c2117d2760a0b5810f41da30357b1041e0557c --- /dev/null +++ b/bsp/stm32f10x/ssd1289.c @@ -0,0 +1,531 @@ +#include "ssd1289.h" + +// Compatible list: +// ssd1289 + +//内联函数定义,用以提高性能 +#ifdef __CC_ARM /* ARM Compiler */ +#define lcd_inline static __inline +#elif defined (__ICCARM__) /* for IAR Compiler */ +#define lcd_inline inline +#elif defined (__GNUC__) /* GNU GCC Compiler */ +#define lcd_inline static __inline +#else +#define lcd_inline static +#endif + +#define rw_data_prepare() write_cmd(34) + + +/********* control ***********/ +#include "stm32f10x.h" +#include "board.h" + +//输出重定向.当不进行重定向时. +#define printf rt_kprintf //使用rt_kprintf来输出 +//#define printf(...) //无输出 + +/* LCD is connected to the FSMC_Bank1_NOR/SRAM2 and NE2 is used as ship select signal */ +/* RS <==> A2 */ +#define LCD_REG (*((volatile unsigned short *) 0x64000000)) /* RS = 0 */ +#define LCD_RAM (*((volatile unsigned short *) 0x64000008)) /* RS = 1 */ + +static void LCD_FSMCConfig(void) +{ + FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; + FSMC_NORSRAMTimingInitTypeDef Timing_read,Timing_write; + + /* FSMC GPIO configure */ + { + GPIO_InitTypeDef GPIO_InitStructure; + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF + | RCC_APB2Periph_GPIOG, ENABLE); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + + /* + FSMC_D0 ~ FSMC_D3 + PD14 FSMC_D0 PD15 FSMC_D1 PD0 FSMC_D2 PD1 FSMC_D3 + */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_14 | GPIO_Pin_15; + GPIO_Init(GPIOD,&GPIO_InitStructure); + + /* + FSMC_D4 ~ FSMC_D12 + PE7 ~ PE15 FSMC_D4 ~ FSMC_D12 + */ + 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); + + /* FSMC_D13 ~ FSMC_D15 PD8 ~ PD10 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; + GPIO_Init(GPIOD,&GPIO_InitStructure); + + /* + FSMC_A0 ~ FSMC_A5 FSMC_A6 ~ FSMC_A9 + PF0 ~ PF5 PF12 ~ PF15 + */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 + | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; + GPIO_Init(GPIOF,&GPIO_InitStructure); + + /* FSMC_A10 ~ FSMC_A15 PG0 ~ PG5 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; + GPIO_Init(GPIOG,&GPIO_InitStructure); + + /* FSMC_A16 ~ FSMC_A18 PD11 ~ PD13 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; + GPIO_Init(GPIOD,&GPIO_InitStructure); + + /* RD-PD4 WR-PD5 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; + GPIO_Init(GPIOD,&GPIO_InitStructure); + + /* NBL0-PE0 NBL1-PE1 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; + GPIO_Init(GPIOE,&GPIO_InitStructure); + + /* NE1/NCE2 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; + GPIO_Init(GPIOD,&GPIO_InitStructure); + /* NE2 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; + GPIO_Init(GPIOG,&GPIO_InitStructure); + /* NE3 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_Init(GPIOG,&GPIO_InitStructure); + /* NE4 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; + GPIO_Init(GPIOG,&GPIO_InitStructure); + } + /* FSMC GPIO configure */ + + /*-- FSMC Configuration -------------------------------------------------*/ + Timing_read.FSMC_AddressSetupTime = 30; /* 地址建立时间 */ + Timing_read.FSMC_DataSetupTime = 30; /* 数据建立时间 */ + Timing_read.FSMC_AccessMode = FSMC_AccessMode_A; /* FSMC 访问模式 */ + + Timing_write.FSMC_AddressSetupTime = 3; /* 地址建立时间 */ + Timing_write.FSMC_DataSetupTime = 3; /* 数据建立时间 */ + Timing_write.FSMC_AccessMode = FSMC_AccessMode_A; /* FSMC 访问模式 */ + + /* Color LCD configuration ------------------------------------ + LCD configured as follow: + - Data/Address MUX = Disable + - Memory Type = SRAM + - Data Width = 16bit + - Write Operation = Enable + - Extended Mode = Enable + - Asynchronous Wait = Disable */ + FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; + FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; + FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; + FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_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_Enable; + FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &Timing_read; + FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &Timing_write; + + FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); + FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE); +} + +static void delay(int cnt) +{ + volatile unsigned int dl; + while(cnt--) + { + for(dl=0; dl<500; dl++); + } +} + +static void lcd_port_init(void) +{ + LCD_FSMCConfig(); +} + +lcd_inline void write_cmd(unsigned short cmd) +{ + LCD_REG = cmd; +} + +lcd_inline unsigned short read_data(void) +{ + return LCD_RAM; +} + +lcd_inline void write_data(unsigned short data_code ) +{ + LCD_RAM = data_code; +} + +lcd_inline void write_reg(unsigned char reg_addr,unsigned short reg_val) +{ + write_cmd(reg_addr); + write_data(reg_val); +} + +lcd_inline unsigned short read_reg(unsigned char reg_addr) +{ + unsigned short val=0; + write_cmd(reg_addr); + val = read_data(); + return (val); +} + +/********* control <只移植以上函数即可> ***********/ + +static unsigned short deviceid=0;//设置一个静态变量用来保存LCD的ID + +//static unsigned short BGR2RGB(unsigned short c) +//{ +// u16 r, g, b, rgb; +// +// b = (c>>0) & 0x1f; +// g = (c>>5) & 0x3f; +// r = (c>>11) & 0x1f; +// +// rgb = (b<<11) + (g<<5) + (r<<0); +// +// return( rgb ); +//} + +static void lcd_SetCursor(unsigned int x,unsigned int y) +{ + write_reg(0x004e,x); /* 0-239 */ + write_reg(0x004f,y); /* 0-319 */ +} + +/* 读取指定地址的GRAM */ +static unsigned short lcd_read_gram(unsigned int x,unsigned int y) +{ + unsigned short temp; + lcd_SetCursor(x,y); + rw_data_prepare(); + /* dummy read */ + temp = read_data(); + temp = read_data(); + return temp; +} + +static void lcd_clear(unsigned short Color) +{ + unsigned int index=0; + lcd_SetCursor(0,0); + rw_data_prepare(); /* Prepare to write GRAM */ + for (index=0; index<(LCD_WIDTH*LCD_HEIGHT); index++) + { + write_data(Color); + } +} + +static void lcd_data_bus_test(void) +{ + unsigned short temp1; + unsigned short temp2; +// /* [5:4]-ID~ID0 [3]-AM-1垂直-0水平 */ +// write_reg(0x0003,(1<<12)|(1<<5)|(1<<4) | (0<<3) ); + + /* wirte */ + lcd_SetCursor(0,0); + rw_data_prepare(); + write_data(0x5555); + + lcd_SetCursor(1,0); + rw_data_prepare(); + write_data(0xAAAA); + + /* read */ + lcd_SetCursor(0,0); + temp1 = lcd_read_gram(0,0); + temp2 = lcd_read_gram(1,0); + + if( (temp1 == 0x5555) && (temp2 == 0xAAAA) ) + { + printf(" data bus test pass!\r\n"); + } + else + { + printf(" data bus test error: %04X %04X\r\n",temp1,temp2); + } +} + +static void lcd_gram_test(void) +{ + unsigned short temp; + unsigned int test_x; + unsigned int test_y; + + printf(" LCD GRAM test...."); + + /* write */ + temp=0; + write_reg(0x0011,0x6030 | (0<<3)); // AM=0 hline + + lcd_SetCursor(0,0); + rw_data_prepare(); + for(test_y=0; test_y<76800; test_y++) + { + write_data(temp); + temp++; + }/* write */ + + /* read */ + temp=0; + { + for(test_y=0; test_y<320; test_y++) + { + for(test_x=0; test_x<240; test_x++) + { + if( lcd_read_gram(test_x,test_y) != temp++) + { + printf(" LCD GRAM ERR!!\r\n"); + return ; + } + } + } + printf(" TEST PASS!\r\n"); + }/* read */ +} + +void ssd1289_init(void) +{ + lcd_port_init(); + deviceid = read_reg(0x00); + + /* deviceid check */ + if( deviceid != 0x8989 ) + { + printf("Invalid LCD ID:%08X\r\n",deviceid); + printf("Please check you hardware and configure.\r\n"); + } + else + { + printf("\r\nLCD Device ID : %04X ",deviceid); + } + + // power supply setting + // set R07h at 0021h (GON=1,DTE=0,D[1:0]=01) + write_reg(0x0007,0x0021); + // set R00h at 0001h (OSCEN=1) + write_reg(0x0000,0x0001); + // set R07h at 0023h (GON=1,DTE=0,D[1:0]=11) + write_reg(0x0007,0x0023); + // set R10h at 0000h (Exit sleep mode) + write_reg(0x0010,0x0000); + // Wait 30ms + delay(3000); + // set R07h at 0033h (GON=1,DTE=1,D[1:0]=11) + write_reg(0x0007,0x0033); + // Entry mode setting (R11h) + // R11H Entry mode + // vsmode DFM1 DFM0 TRANS OEDef WMode DMode1 DMode0 TY1 TY0 ID1 ID0 AM LG2 LG2 LG0 + // 0 1 1 0 0 0 0 0 0 1 1 1 * 0 0 0 + write_reg(0x0011,0x6070); + // LCD driver AC setting (R02h) + write_reg(0x0002,0x0600); + // power control 1 + // DCT3 DCT2 DCT1 DCT0 BT2 BT1 BT0 0 DC3 DC2 DC1 DC0 AP2 AP1 AP0 0 + // 1 0 1 0 1 0 0 0 1 0 1 0 0 1 0 0 + // DCT[3:0] fosc/4 BT[2:0] DC{3:0] fosc/4 + write_reg(0x0003,0x0804);//0xA8A4 + write_reg(0x000C,0x0000);// + write_reg(0x000D,0x0808);// 0x080C --> 0x0808 + // power control 4 + // 0 0 VCOMG VDV4 VDV3 VDV2 VDV1 VDV0 0 0 0 0 0 0 0 0 + // 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 + write_reg(0x000E,0x2900); + write_reg(0x001E,0x00B8); + write_reg(0x0001,0x2B3F);//驱动输出控制320*240 0x6B3F + write_reg(0x0010,0x0000); + write_reg(0x0005,0x0000); + write_reg(0x0006,0x0000); + write_reg(0x0016,0xEF1C); + write_reg(0x0017,0x0003); + write_reg(0x0007,0x0233);//0x0233 + write_reg(0x000B,0x0000|(3<<6)); + write_reg(0x000F,0x0000);//扫描开始地址 + write_reg(0x0041,0x0000); + write_reg(0x0042,0x0000); + write_reg(0x0048,0x0000); + write_reg(0x0049,0x013F); + write_reg(0x004A,0x0000); + write_reg(0x004B,0x0000); + write_reg(0x0044,0xEF00); + write_reg(0x0045,0x0000); + write_reg(0x0046,0x013F); + write_reg(0x0030,0x0707); + write_reg(0x0031,0x0204); + write_reg(0x0032,0x0204); + write_reg(0x0033,0x0502); + write_reg(0x0034,0x0507); + write_reg(0x0035,0x0204); + write_reg(0x0036,0x0204); + write_reg(0x0037,0x0502); + write_reg(0x003A,0x0302); + write_reg(0x003B,0x0302); + write_reg(0x0023,0x0000); + write_reg(0x0024,0x0000); + write_reg(0x0025,0x8000); // 65hz + write_reg(0x004f,0); // 行首址0 + write_reg(0x004e,0); // 列首址0 + + //数据总线测试,用于测试硬件连接是否正常. + lcd_data_bus_test(); + //GRAM测试,此测试可以测试LCD控制器内部GRAM.测试通过保证硬件正常 +// lcd_gram_test(); + + //清屏 + lcd_clear( Blue ); +} + +/* 设置像素点 颜色,X,Y */ +void ssd1289_lcd_set_pixel(const char* pixel, int x, int y) +{ + lcd_SetCursor(x,y); + + rw_data_prepare(); + write_data(*(rt_uint16_t*)pixel); +} + +/* 获取像素点颜色 */ +void ssd1289_lcd_get_pixel(char* pixel, int x, int y) +{ + *(rt_uint16_t*)pixel = lcd_read_gram(x, y); +} + +/* 画水平线 */ +void ssd1289_lcd_draw_hline(const char* pixel, int x1, int x2, int y) +{ + /* [5:4]-ID~ID0 [3]-AM-1垂直-0水平 */ + write_reg(0x0011,0x6030 | (0<<3)); // AM=0 hline + + lcd_SetCursor(x1, y); + rw_data_prepare(); /* Prepare to write GRAM */ + while (x1 < x2) + { + write_data(*(rt_uint16_t*)pixel); + x1++; + } +} + +/* 垂直线 */ +void ssd1289_lcd_draw_vline(const char* pixel, int x, int y1, int y2) +{ + /* [5:4]-ID~ID0 [3]-AM-1垂直-0水平 */ + write_reg(0x0011,0x6070 | (1<<3)); // AM=0 vline + + lcd_SetCursor(x, y1); + rw_data_prepare(); /* Prepare to write GRAM */ + while (y1 < y2) + { + write_data(*(rt_uint16_t*)pixel); + y1++; + } +} + +/* blit a line */ +void ssd1289_lcd_blit_line(const char* pixels, int x, int y, rt_size_t size) +{ + rt_uint16_t *ptr; + + ptr = (rt_uint16_t*)pixels; + + /* [5:4]-ID~ID0 [3]-AM-1垂直-0水平 */ + write_reg(0x0011,0x6070 | (0<<3)); // AM=0 hline + + lcd_SetCursor(x, y); + rw_data_prepare(); /* Prepare to write GRAM */ + while (size) + { + write_data(*ptr ++); + size --; + } +} + +struct rt_device_graphic_ops ssd1289_ops = +{ + ssd1289_lcd_set_pixel, + ssd1289_lcd_get_pixel, + ssd1289_lcd_draw_hline, + ssd1289_lcd_draw_vline, + ssd1289_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 = 240; + info->height = 320; + } + break; + + case RTGRAPHIC_CTRL_RECT_UPDATE: + /* nothong to be done */ + break; + + default: + break; + } + + return RT_EOK; +} + +void rt_hw_lcd_init(void) +{ + extern struct rt_device_graphic_ops ssd1289_ops; + + /* 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 = &ssd1289_ops; + ssd1289_init(); + + /* register graphic device driver */ + rt_device_register(&_lcd_device, "lcd", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE); +} + diff --git a/bsp/stm32f10x/ssd1289.h b/bsp/stm32f10x/ssd1289.h new file mode 100644 index 0000000000000000000000000000000000000000..b2041dff60bc24f4950a555cdc5ad50178427ebc --- /dev/null +++ b/bsp/stm32f10x/ssd1289.h @@ -0,0 +1,34 @@ +#ifndef SSD1289_H_INCLUDED +#define SSD1289_H_INCLUDED + +#include + +// Compatible list: +// ssd1289 + +/* LCD color */ +#define White 0xFFFF +#define Black 0x0000 +#define Grey 0xF7DE +#define Blue 0x001F +#define Blue2 0x051F +#define Red 0xF800 +#define Magenta 0xF81F +#define Green 0x07E0 +#define Cyan 0x7FFF +#define Yellow 0xFFE0 + +/*---------------------- Graphic LCD size definitions ------------------------*/ +#define LCD_WIDTH 240 /* Screen Width (in pixels) */ +#define LCD_HEIGHT 320 /* Screen Hight (in pixels) */ +#define BPP 16 /* Bits per pixel */ +#define BYPP ((BPP+7)/8) /* Bytes per pixel */ + +void ssd1289_init(void); + +//#define _ILI_REVERSE_DIRECTION_ + +rt_size_t lcd_ssd1289_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size); +rt_size_t lcd_ssd1289_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size); + +#endif // SSD1289_H_INCLUDED diff --git a/bsp/stm32f10x/stm32_rom.sct b/bsp/stm32f10x/stm32_rom.sct deleted file mode 100644 index 0835abf43e781cddf45207f6fad946f12221105a..0000000000000000000000000000000000000000 --- a/bsp/stm32f10x/stm32_rom.sct +++ /dev/null @@ -1,15 +0,0 @@ -; ************************************************************* -; *** Scatter-Loading Description File generated by uVision *** -; ************************************************************* - -LR_IROM1 0x08000000 0x00080000 { ; load region size_region - ER_IROM1 0x08000000 0x00080000 { ; load address = execution address - *.o (RESET, +First) - *(InRoot$$Sections) - .ANY (+RO) - } - RW_IRAM1 0x20000000 0x00010000 { ; RW data - .ANY (+RW +ZI) - } -} - diff --git a/bsp/stm32f10x/stm32f10x_conf.h b/bsp/stm32f10x/stm32f10x_conf.h index ad179fe4c2bda9bf9f694887f0bcbf4fba0b1cb0..59549e3bf12e31fc54797e492f64a0d80006de43 100644 --- a/bsp/stm32f10x/stm32f10x_conf.h +++ b/bsp/stm32f10x/stm32f10x_conf.h @@ -1,12 +1,12 @@ /** ****************************************************************************** - * @file Project/Template/stm32f10x_conf.h + * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_conf.h * @author MCD Application Team - * @version V3.1.0 - * @date 06/19/2009 + * @version V3.5.0 + * @date 08-April-2011 * @brief Library configuration file. ****************************************************************************** - * @copy + * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE @@ -15,7 +15,8 @@ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * - *

© COPYRIGHT 2009 STMicroelectronics

+ *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** */ /* Define to prevent recursive inclusion -------------------------------------*/ @@ -23,33 +24,34 @@ #define __STM32F10x_CONF_H /* Includes ------------------------------------------------------------------*/ -/* Uncomment the line below to enable peripheral header file inclusion */ -/* #include "stm32f10x_adc.h" */ +/* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */ +#include "stm32f10x_adc.h" #include "stm32f10x_bkp.h" -/* #include "stm32f10x_can.h" */ -/* #include "stm32f10x_crc.h" */ -/* #include "stm32f10x_dac.h" */ -/* #include "stm32f10x_dbgmcu.h" */ -/* #include "stm32f10x_dma.h" */ +#include "stm32f10x_can.h" +#include "stm32f10x_cec.h" +#include "stm32f10x_crc.h" +#include "stm32f10x_dac.h" +#include "stm32f10x_dbgmcu.h" +#include "stm32f10x_dma.h" #include "stm32f10x_exti.h" #include "stm32f10x_flash.h" -//#include "stm32f10x_fsmc.h" +#include "stm32f10x_fsmc.h" #include "stm32f10x_gpio.h" -/* #include "stm32f10x_i2c.h" */ -/* #include "stm32f10x_iwdg.h" */ +#include "stm32f10x_i2c.h" +#include "stm32f10x_iwdg.h" #include "stm32f10x_pwr.h" #include "stm32f10x_rcc.h" #include "stm32f10x_rtc.h" -/* #include "stm32f10x_sdio.h" */ -//#include "stm32f10x_spi.h" -/* #include "stm32f10x_tim.h" */ +#include "stm32f10x_sdio.h" +#include "stm32f10x_spi.h" +#include "stm32f10x_tim.h" #include "stm32f10x_usart.h" -/* #include "stm32f10x_wwdg.h" */ +#include "stm32f10x_wwdg.h" #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ -/* Uncomment the line below to expanse the "assert_param" macro in the +/* Uncomment the line below to expanse the "assert_param" macro in the Standard Peripheral Library drivers code */ /* #define USE_FULL_ASSERT 1 */ @@ -58,10 +60,9 @@ /** * @brief The assert_param macro is used for function's parameters check. - * @param expr: If expr is false, it calls assert_failed function - * which reports the name of the source file and the source - * line number of the call that failed. - * If expr is true, it returns no value. + * @param expr: If expr is false, it calls assert_failed function which reports + * the name of the source file and the source line number of the call + * that failed. If expr is true, it returns no value. * @retval None */ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) @@ -73,4 +74,4 @@ #endif /* __STM32F10x_CONF_H */ -/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/bsp/stm32f10x/template.uvproj b/bsp/stm32f10x/template.uvproj new file mode 100644 index 0000000000000000000000000000000000000000..e37f1f1c6f9fd684935d3c18f5eb7b07c217c06f --- /dev/null +++ b/bsp/stm32f10x/template.uvproj @@ -0,0 +1,390 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread-stm32 + 0x4 + ARM-ADS + + + STM32F103ZE + STMicroelectronics + IRAM(0x20000000-0x2000FFFF) IROM(0x8000000-0x807FFFF) CLOCK(8000000) CPUTYPE("Cortex-M3") + + "STARTUP\ST\STM32F10x.s" ("STM32 Startup Code") + UL2CM3(-O14 -S0 -C0 -N00("ARM Cortex-M3") -D00(1BA00477) -L00(4) -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_512 -FS08000000 -FL080000) + 4216 + stm32f10x_lib.h + + + + + + + + + + SFD\ST\STM32F10xx\STM32F10xxE.sfr + 0 + + + + ST\STM32F10x\ + ST\STM32F10x\ + + 0 + 0 + 0 + 0 + 1 + + .\obj\ + rtthread-stm32 + 1 + 0 + 0 + 1 + 1 + .\obj\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + + + SARMCM3.DLL + + DARMSTM.DLL + -pSTM32F103ZE + SARMCM3.DLL + + TARMSTM.DLL + -pSTM32F103ZE + + + + 1 + 0 + 0 + 0 + 16 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + + + 0 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + + 0 + 0 + + + + + + + + + + + + + + BIN\UL2CM3.DLL + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + BIN\UL2CM3.DLL + "" () + + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M3" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + + +
diff --git a/bsp/stm32f10x/touch.c b/bsp/stm32f10x/touch.c new file mode 100644 index 0000000000000000000000000000000000000000..f657562d0f64e3341395e5f6e255768f83f6c799 --- /dev/null +++ b/bsp/stm32f10x/touch.c @@ -0,0 +1,471 @@ +#include +#include "stm32f10x.h" + +#include "board.h" +#include "touch.h" + +#include +#include +#include +#include +#include + +/* +MISO PA6 +MOSI PA7 +CLK PA5 +CS PC4 +*/ + +#define CS_0() GPIO_ResetBits(GPIOC,GPIO_Pin_4) +#define CS_1() GPIO_SetBits(GPIOC,GPIO_Pin_4) + +/* +7 6 - 4 3 2 1-0 +s A2-A0 MODE SER/DFR PD1-PD0 +*/ +#define TOUCH_MSR_Y 0x90 //读X轴坐标指令 addr:1 +#define TOUCH_MSR_X 0xD0 //读Y轴坐标指令 addr:3 + +struct rtgui_touch_device +{ + struct rt_device parent; + + rt_timer_t poll_timer; + rt_uint16_t x, y; + + rt_bool_t calibrating; + rt_touch_calibration_func_t calibration_func; + + rt_uint16_t min_x, max_x; + rt_uint16_t min_y, max_y; +}; +static struct rtgui_touch_device *touch = RT_NULL; + +extern unsigned char SPI_WriteByte(unsigned char data); +rt_inline void EXTI_Enable(rt_uint32_t enable); + +struct rt_semaphore spi1_lock; + +void rt_hw_spi1_baud_rate(uint16_t SPI_BaudRatePrescaler) +{ + SPI1->CR1 &= ~SPI_BaudRatePrescaler_256; + SPI1->CR1 |= SPI_BaudRatePrescaler; +} + +uint8_t SPI_WriteByte(unsigned char data) +{ + //Wait until the transmit buffer is empty + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); + // Send the byte + SPI_I2S_SendData(SPI1, data); + + //Wait until a data is received + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); + // Get the received data + data = SPI_I2S_ReceiveData(SPI1); + + // Return the shifted data + return data; +} + +//SPI写数据 +static void WriteDataTo7843(unsigned char num) +{ + SPI_WriteByte(num); +} + +#define X_WIDTH 240 +#define Y_WIDTH 320 + +static void rtgui_touch_calculate() +{ + if (touch != RT_NULL) + { + rt_sem_take(&spi1_lock, RT_WAITING_FOREVER); + /* SPI1 configure */ + rt_hw_spi1_baud_rate(SPI_BaudRatePrescaler_64);/* 72M/64=1.125M */ + + //读取触摸值 + { + rt_uint16_t tmpx[10]; + rt_uint16_t tmpy[10]; + unsigned int i; + + for(i=0; i<10; i++) + { + CS_0(); + WriteDataTo7843(TOUCH_MSR_X); /* read X */ + tmpx[i] = SPI_WriteByte(0x00)<<4; /* read MSB bit[11:8] */ + tmpx[i] |= ((SPI_WriteByte(TOUCH_MSR_Y)>>4)&0x0F ); /* read LSB bit[7:0] */ + tmpy[i] = SPI_WriteByte(0x00)<<4; /* read MSB bit[11:8] */ + tmpy[i] |= ((SPI_WriteByte(0x00)>>4)&0x0F ); /* read LSB bit[7:0] */ + WriteDataTo7843( 1<<7 ); /* 打开中断 */ + CS_1(); + } + + //去最高值与最低值,再取平均值 + { + rt_uint32_t min_x = 0xFFFF,min_y = 0xFFFF; + rt_uint32_t max_x = 0,max_y = 0; + rt_uint32_t total_x = 0; + rt_uint32_t total_y = 0; + unsigned int i; + + for(i=0;i<10;i++) + { + if( tmpx[i] < min_x ) + { + min_x = tmpx[i]; + } + if( tmpx[i] > max_x ) + { + max_x = tmpx[i]; + } + total_x += tmpx[i]; + + if( tmpy[i] < min_y ) + { + min_y = tmpy[i]; + } + if( tmpy[i] > max_y ) + { + max_y = tmpy[i]; + } + total_y += tmpy[i]; + } + total_x = total_x - min_x - max_x; + total_y = total_y - min_y - max_y; + touch->x = total_x / 8; + touch->y = total_y / 8; + }//去最高值与最低值,再取平均值 + }//读取触摸值 + + rt_sem_release(&spi1_lock); + + /* if it's not in calibration status */ + if (touch->calibrating != RT_TRUE) + { + if (touch->max_x > touch->min_x) + { + touch->x = (touch->x - touch->min_x) * X_WIDTH/(touch->max_x - touch->min_x); + } + else + { + touch->x = (touch->min_x - touch->x) * X_WIDTH/(touch->min_x - touch->max_x); + } + + if (touch->max_y > touch->min_y) + { + touch->y = (touch->y - touch->min_y) * Y_WIDTH /(touch->max_y - touch->min_y); + } + else + { + touch->y = (touch->min_y - touch->y) * Y_WIDTH /(touch->min_y - touch->max_y); + } + } + } +} + +static unsigned int flag = 0; +void touch_timeout(void* parameter) +{ + struct rtgui_event_mouse emouse; + static struct _touch_previous + { + rt_uint32_t x; + rt_uint32_t y; + } touch_previous; + + if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) != 0) + { + int tmer = RT_TICK_PER_SECOND/8 ; + EXTI_Enable(1); + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP); + + /* use old value */ + emouse.x = touch->x; + emouse.y = touch->y; + + /* stop timer */ + rt_timer_stop(touch->poll_timer); + rt_kprintf("touch up: (%d, %d)\n", emouse.x, emouse.y); + flag = 0; + + if ((touch->calibrating == RT_TRUE) && (touch->calibration_func != RT_NULL)) + { + /* callback function */ + touch->calibration_func(emouse.x, emouse.y); + } + rt_timer_control(touch->poll_timer , RT_TIMER_CTRL_SET_TIME , &tmer); + } + else + { + if(flag == 0) + { + int tmer = RT_TICK_PER_SECOND/20 ; + /* calculation */ + rtgui_touch_calculate(); + + /* send mouse event */ + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.parent.sender = RT_NULL; + + emouse.x = touch->x; + emouse.y = touch->y; + + touch_previous.x = touch->x; + touch_previous.y = touch->y; + + /* init mouse button */ + emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN); + +// rt_kprintf("touch down: (%d, %d)\n", emouse.x, emouse.y); + flag = 1; + rt_timer_control(touch->poll_timer , RT_TIMER_CTRL_SET_TIME , &tmer); + } + else + { + /* calculation */ + rtgui_touch_calculate(); + +#define previous_keep 8 + //判断移动距离是否小于previous_keep,减少误动作. + if( + (touch_previous.xx+previous_keep) + && (touch_previous.x>touch->x-previous_keep) + && (touch_previous.yy+previous_keep) + && (touch_previous.y>touch->y-previous_keep) ) + { + return; + } + + touch_previous.x = touch->x; + touch_previous.y = touch->y; + + /* send mouse event */ + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON ; + emouse.parent.sender = RT_NULL; + + emouse.x = touch->x; + emouse.y = touch->y; + + /* init mouse button */ + emouse.button = (RTGUI_MOUSE_BUTTON_RIGHT |RTGUI_MOUSE_BUTTON_DOWN); +// rt_kprintf("touch motion: (%d, %d)\n", emouse.x, emouse.y); + } + } + + /* send event to server */ + if (touch->calibrating != RT_TRUE) + rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); +} + +static void NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + /* Enable the EXTI0 Interrupt */ + NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + +rt_inline void EXTI_Enable(rt_uint32_t enable) +{ + EXTI_InitTypeDef EXTI_InitStructure; + + /* Configure EXTI */ + EXTI_InitStructure.EXTI_Line = EXTI_Line1; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//Falling下降沿 Rising上升 + + if (enable) + { + /* enable */ + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + } + else + { + /* disable */ + EXTI_InitStructure.EXTI_LineCmd = DISABLE; + } + + EXTI_Init(&EXTI_InitStructure); + EXTI_ClearITPendingBit(EXTI_Line1); +} + +static void EXTI_Configuration(void) +{ + /* PB1 touch INT */ + { + GPIO_InitTypeDef GPIO_InitStructure; + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_Init(GPIOB,&GPIO_InitStructure); + } + + GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); + + /* Configure EXTI */ + EXTI_Enable(1); +} + +/* RT-Thread Device Interface */ +static rt_err_t rtgui_touch_init (rt_device_t dev) +{ + NVIC_Configuration(); + EXTI_Configuration(); + + /* PC4 touch CS */ + { + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; + GPIO_Init(GPIOC,&GPIO_InitStructure); + CS_1(); + } + + CS_0(); + WriteDataTo7843( 1<<7 ); /* 打开中断 */ + CS_1(); + + return RT_EOK; +} + +static rt_err_t rtgui_touch_control (rt_device_t dev, rt_uint8_t cmd, void *args) +{ + switch (cmd) + { + case RT_TOUCH_CALIBRATION: + touch->calibrating = RT_TRUE; + touch->calibration_func = (rt_touch_calibration_func_t)args; + break; + + case RT_TOUCH_NORMAL: + touch->calibrating = RT_FALSE; + break; + + case RT_TOUCH_CALIBRATION_DATA: + { + struct calibration_data* data; + + data = (struct calibration_data*) args; + + //update + touch->min_x = data->min_x; + touch->max_x = data->max_x; + touch->min_y = data->min_y; + touch->max_y = data->max_y; + } + break; + } + + return RT_EOK; +} + +void EXTI1_IRQHandler(void) +{ + /* disable interrupt */ + EXTI_Enable(0); + + /* start timer */ + rt_timer_start(touch->poll_timer); + + EXTI_ClearITPendingBit(EXTI_Line1); +} + +void rtgui_touch_hw_init(void) +{ + /* SPI1 config */ + { + GPIO_InitTypeDef GPIO_InitStructure; + SPI_InitTypeDef SPI_InitStructure; + + /* Enable SPI1 Periph clock */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA + | RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1, + ENABLE); + + /* Configure SPI1 pins: PA5-SCK, PA6-MISO and PA7-MOSI */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /*------------------------ SPI1 configuration ------------------------*/ + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;/* 72M/64=1.125M */ + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + + SPI_I2S_DeInit(SPI1); + SPI_Init(SPI1, &SPI_InitStructure); + + /* Enable SPI_MASTER */ + SPI_Cmd(SPI1, ENABLE); + SPI_CalculateCRC(SPI1, DISABLE); + + if (rt_sem_init(&spi1_lock, "spi1lock", 1, RT_IPC_FLAG_FIFO) != RT_EOK) + { + rt_kprintf("init spi1 lock semaphore failed\n"); + } + } /* SPI1 config */ + + touch = (struct rtgui_touch_device*)rt_malloc (sizeof(struct rtgui_touch_device)); + if (touch == RT_NULL) return; /* no memory yet */ + + /* clear device structure */ + rt_memset(&(touch->parent), 0, sizeof(struct rt_device)); + touch->calibrating = false; + + /* init device structure */ + touch->parent.type = RT_Device_Class_Unknown; + touch->parent.init = rtgui_touch_init; + touch->parent.control = rtgui_touch_control; + touch->parent.user_data = RT_NULL; + + /* create 1/8 second timer */ + touch->poll_timer = rt_timer_create("touch", touch_timeout, RT_NULL, + RT_TICK_PER_SECOND/8, RT_TIMER_FLAG_PERIODIC); + + /* register touch device to RT-Thread */ + rt_device_register(&(touch->parent), "touch", RT_DEVICE_FLAG_RDWR); +} + +#include + +void touch_t( rt_uint16_t x , rt_uint16_t y ) +{ + struct rtgui_event_mouse emouse ; + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.parent.sender = RT_NULL; + + emouse.x = x ; + emouse.y = y ; + /* init mouse button */ + emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN ); + rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); + + rt_thread_delay(2) ; + emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP ); + rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); +} + + +FINSH_FUNCTION_EXPORT(touch_t, x & y ) ; diff --git a/bsp/stm32f10x/touch.h b/bsp/stm32f10x/touch.h new file mode 100644 index 0000000000000000000000000000000000000000..2a1296bbefda62b329f8c03271d5f370ccf639f1 --- /dev/null +++ b/bsp/stm32f10x/touch.h @@ -0,0 +1,21 @@ +#ifndef __TOUCH_H__ +#define __TOUCH_H__ + +#include + +#define RT_TOUCH_NORMAL 0 +#define RT_TOUCH_CALIBRATION_DATA 1 +#define RT_TOUCH_CALIBRATION 2 + +struct calibration_data +{ + rt_uint16_t min_x, max_x; + rt_uint16_t min_y, max_y; +}; + +typedef void (*rt_touch_calibration_func_t)(rt_uint16_t x, rt_uint16_t y); + +void rtgui_touch_hw_init(void); + +#endif +