Prechádzať zdrojové kódy

update lcd driver

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1610 bbd45198-f89e-11dd-88c7-29a3b14d5316
wuyangyong 14 rokov pred
rodič
commit
b5f7c6cb44

+ 12 - 1
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)
 

+ 3 - 0
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)
 

+ 27 - 0
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()

+ 284 - 0
bsp/stm32f10x/calibration.c

@@ -0,0 +1,284 @@
+#include <rtgui/rtgui.h>
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/window.h>
+
+#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 <finsh.h>
+void calibration()
+{
+	calibration_init();
+}
+FINSH_FUNCTION_EXPORT(calibration, perform touch calibration);
+#endif

+ 26 - 0
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

+ 5 - 1
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'

+ 531 - 0
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);
+}
+

+ 34 - 0
bsp/stm32f10x/ssd1289.h

@@ -0,0 +1,34 @@
+#ifndef SSD1289_H_INCLUDED
+#define SSD1289_H_INCLUDED
+
+#include <rtthread.h>
+
+// 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

+ 0 - 15
bsp/stm32f10x/stm32_rom.sct

@@ -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)
-  }
-}
-

+ 26 - 25
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.
   *
-  * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
   */
 
 /* 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****/

+ 390 - 0
bsp/stm32f10x/template.uvproj

@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_proj.xsd">
+
+  <SchemaVersion>1.1</SchemaVersion>
+
+  <Header>### uVision Project, (C) Keil Software</Header>
+
+  <Targets>
+    <Target>
+      <TargetName>rtthread-stm32</TargetName>
+      <ToolsetNumber>0x4</ToolsetNumber>
+      <ToolsetName>ARM-ADS</ToolsetName>
+      <TargetOption>
+        <TargetCommonOption>
+          <Device>STM32F103ZE</Device>
+          <Vendor>STMicroelectronics</Vendor>
+          <Cpu>IRAM(0x20000000-0x2000FFFF) IROM(0x8000000-0x807FFFF) CLOCK(8000000) CPUTYPE("Cortex-M3")</Cpu>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile>"STARTUP\ST\STM32F10x.s" ("STM32 Startup Code")</StartupFile>
+          <FlashDriverDll>UL2CM3(-O14 -S0 -C0 -N00("ARM Cortex-M3") -D00(1BA00477) -L00(4) -FO7 -FD20000000 -FC800 -FN1 -FF0STM32F10x_512 -FS08000000 -FL080000)</FlashDriverDll>
+          <DeviceId>4216</DeviceId>
+          <RegisterFile>stm32f10x_lib.h</RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>SFD\ST\STM32F10xx\STM32F10xxE.sfr</SFDFile>
+          <UseEnv>0</UseEnv>
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath>ST\STM32F10x\</RegisterFilePath>
+          <DBRegisterFilePath>ST\STM32F10x\</DBRegisterFilePath>
+          <TargetStatus>
+            <Error>0</Error>
+            <ExitCodeStop>0</ExitCodeStop>
+            <ButtonStop>0</ButtonStop>
+            <NotGenerated>0</NotGenerated>
+            <InvalidFlash>1</InvalidFlash>
+          </TargetStatus>
+          <OutputDirectory>.\obj\</OutputDirectory>
+          <OutputName>rtthread-stm32</OutputName>
+          <CreateExecutable>1</CreateExecutable>
+          <CreateLib>0</CreateLib>
+          <CreateHexFile>0</CreateHexFile>
+          <DebugInformation>1</DebugInformation>
+          <BrowseInformation>1</BrowseInformation>
+          <ListingPath>.\obj\</ListingPath>
+          <HexFormatSelection>1</HexFormatSelection>
+          <Merge32K>0</Merge32K>
+          <CreateBatchFile>0</CreateBatchFile>
+          <BeforeCompile>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+          </BeforeCompile>
+          <BeforeMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+          </BeforeMake>
+          <AfterMake>
+            <RunUserProg1>0</RunUserProg1>
+            <RunUserProg2>0</RunUserProg2>
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
+            <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
+            <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+          </AfterMake>
+          <SelectedForBatchBuild>0</SelectedForBatchBuild>
+          <SVCSIdString></SVCSIdString>
+        </TargetCommonOption>
+        <CommonProperty>
+          <UseCPPCompiler>0</UseCPPCompiler>
+          <RVCTCodeConst>0</RVCTCodeConst>
+          <RVCTZI>0</RVCTZI>
+          <RVCTOtherData>0</RVCTOtherData>
+          <ModuleSelection>0</ModuleSelection>
+          <IncludeInBuild>1</IncludeInBuild>
+          <AlwaysBuild>0</AlwaysBuild>
+          <GenerateAssemblyFile>0</GenerateAssemblyFile>
+          <AssembleAssemblyFile>0</AssembleAssemblyFile>
+          <PublicsOnly>0</PublicsOnly>
+          <StopOnExitCode>3</StopOnExitCode>
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
+        </CommonProperty>
+        <DllOption>
+          <SimDllName>SARMCM3.DLL</SimDllName>
+          <SimDllArguments></SimDllArguments>
+          <SimDlgDll>DARMSTM.DLL</SimDlgDll>
+          <SimDlgDllArguments>-pSTM32F103ZE</SimDlgDllArguments>
+          <TargetDllName>SARMCM3.DLL</TargetDllName>
+          <TargetDllArguments></TargetDllArguments>
+          <TargetDlgDll>TARMSTM.DLL</TargetDlgDll>
+          <TargetDlgDllArguments>-pSTM32F103ZE</TargetDlgDllArguments>
+        </DllOption>
+        <DebugOption>
+          <OPTHX>
+            <HexSelection>1</HexSelection>
+            <HexRangeLowAddress>0</HexRangeLowAddress>
+            <HexRangeHighAddress>0</HexRangeHighAddress>
+            <HexOffset>0</HexOffset>
+            <Oh166RecLen>16</Oh166RecLen>
+          </OPTHX>
+          <Simulator>
+            <UseSimulator>1</UseSimulator>
+            <LoadApplicationAtStartup>1</LoadApplicationAtStartup>
+            <RunToMain>1</RunToMain>
+            <RestoreBreakpoints>1</RestoreBreakpoints>
+            <RestoreWatchpoints>1</RestoreWatchpoints>
+            <RestoreMemoryDisplay>1</RestoreMemoryDisplay>
+            <RestoreFunctions>1</RestoreFunctions>
+            <RestoreToolbox>1</RestoreToolbox>
+            <LimitSpeedToRealTime>0</LimitSpeedToRealTime>
+          </Simulator>
+          <Target>
+            <UseTarget>0</UseTarget>
+            <LoadApplicationAtStartup>1</LoadApplicationAtStartup>
+            <RunToMain>0</RunToMain>
+            <RestoreBreakpoints>1</RestoreBreakpoints>
+            <RestoreWatchpoints>1</RestoreWatchpoints>
+            <RestoreMemoryDisplay>1</RestoreMemoryDisplay>
+            <RestoreFunctions>0</RestoreFunctions>
+            <RestoreToolbox>1</RestoreToolbox>
+          </Target>
+          <RunDebugAfterBuild>0</RunDebugAfterBuild>
+          <TargetSelection>0</TargetSelection>
+          <SimDlls>
+            <CpuDll></CpuDll>
+            <CpuDllArguments></CpuDllArguments>
+            <PeripheralDll></PeripheralDll>
+            <PeripheralDllArguments></PeripheralDllArguments>
+            <InitializationFile></InitializationFile>
+          </SimDlls>
+          <TargetDlls>
+            <CpuDll></CpuDll>
+            <CpuDllArguments></CpuDllArguments>
+            <PeripheralDll></PeripheralDll>
+            <PeripheralDllArguments></PeripheralDllArguments>
+            <InitializationFile></InitializationFile>
+            <Driver>BIN\UL2CM3.DLL</Driver>
+          </TargetDlls>
+        </DebugOption>
+        <Utilities>
+          <Flash1>
+            <UseTargetDll>1</UseTargetDll>
+            <UseExternalTool>0</UseExternalTool>
+            <RunIndependent>0</RunIndependent>
+            <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
+            <Capability>1</Capability>
+            <DriverSelection>4096</DriverSelection>
+          </Flash1>
+          <Flash2>BIN\UL2CM3.DLL</Flash2>
+          <Flash3>"" ()</Flash3>
+          <Flash4></Flash4>
+        </Utilities>
+        <TargetArmAds>
+          <ArmAdsMisc>
+            <GenerateListings>0</GenerateListings>
+            <asHll>1</asHll>
+            <asAsm>1</asAsm>
+            <asMacX>1</asMacX>
+            <asSyms>1</asSyms>
+            <asFals>1</asFals>
+            <asDbgD>1</asDbgD>
+            <asForm>1</asForm>
+            <ldLst>0</ldLst>
+            <ldmm>1</ldmm>
+            <ldXref>1</ldXref>
+            <BigEnd>0</BigEnd>
+            <AdsALst>1</AdsALst>
+            <AdsACrf>1</AdsACrf>
+            <AdsANop>0</AdsANop>
+            <AdsANot>0</AdsANot>
+            <AdsLLst>1</AdsLLst>
+            <AdsLmap>1</AdsLmap>
+            <AdsLcgr>1</AdsLcgr>
+            <AdsLsym>1</AdsLsym>
+            <AdsLszi>1</AdsLszi>
+            <AdsLtoi>1</AdsLtoi>
+            <AdsLsun>1</AdsLsun>
+            <AdsLven>1</AdsLven>
+            <AdsLsxf>1</AdsLsxf>
+            <RvctClst>0</RvctClst>
+            <GenPPlst>0</GenPPlst>
+            <AdsCpuType>"Cortex-M3"</AdsCpuType>
+            <RvctDeviceName></RvctDeviceName>
+            <mOS>0</mOS>
+            <uocRom>0</uocRom>
+            <uocRam>0</uocRam>
+            <hadIROM>1</hadIROM>
+            <hadIRAM>1</hadIRAM>
+            <hadXRAM>0</hadXRAM>
+            <uocXRam>0</uocXRam>
+            <RvdsVP>0</RvdsVP>
+            <hadIRAM2>0</hadIRAM2>
+            <hadIROM2>0</hadIROM2>
+            <StupSel>8</StupSel>
+            <useUlib>0</useUlib>
+            <EndSel>0</EndSel>
+            <uLtcg>0</uLtcg>
+            <RoSelD>3</RoSelD>
+            <RwSelD>3</RwSelD>
+            <CodeSel>0</CodeSel>
+            <OptFeed>0</OptFeed>
+            <NoZi1>0</NoZi1>
+            <NoZi2>0</NoZi2>
+            <NoZi3>0</NoZi3>
+            <NoZi4>0</NoZi4>
+            <NoZi5>0</NoZi5>
+            <Ro1Chk>0</Ro1Chk>
+            <Ro2Chk>0</Ro2Chk>
+            <Ro3Chk>0</Ro3Chk>
+            <Ir1Chk>1</Ir1Chk>
+            <Ir2Chk>0</Ir2Chk>
+            <Ra1Chk>0</Ra1Chk>
+            <Ra2Chk>0</Ra2Chk>
+            <Ra3Chk>0</Ra3Chk>
+            <Im1Chk>1</Im1Chk>
+            <Im2Chk>0</Im2Chk>
+            <OnChipMemories>
+              <Ocm1>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm1>
+              <Ocm2>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm2>
+              <Ocm3>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm3>
+              <Ocm4>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm4>
+              <Ocm5>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm5>
+              <Ocm6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </Ocm6>
+              <IRAM>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x10000</Size>
+              </IRAM>
+              <IROM>
+                <Type>1</Type>
+                <StartAddress>0x8000000</StartAddress>
+                <Size>0x80000</Size>
+              </IROM>
+              <XRAM>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </XRAM>
+              <OCR_RVCT1>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT1>
+              <OCR_RVCT2>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT2>
+              <OCR_RVCT3>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT3>
+              <OCR_RVCT4>
+                <Type>1</Type>
+                <StartAddress>0x8000000</StartAddress>
+                <Size>0x80000</Size>
+              </OCR_RVCT4>
+              <OCR_RVCT5>
+                <Type>1</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT5>
+              <OCR_RVCT6>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT6>
+              <OCR_RVCT7>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT7>
+              <OCR_RVCT8>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT8>
+              <OCR_RVCT9>
+                <Type>0</Type>
+                <StartAddress>0x20000000</StartAddress>
+                <Size>0x10000</Size>
+              </OCR_RVCT9>
+              <OCR_RVCT10>
+                <Type>0</Type>
+                <StartAddress>0x0</StartAddress>
+                <Size>0x0</Size>
+              </OCR_RVCT10>
+            </OnChipMemories>
+            <RvctStartVector></RvctStartVector>
+          </ArmAdsMisc>
+          <Cads>
+            <interw>1</interw>
+            <Optim>1</Optim>
+            <oTime>0</oTime>
+            <SplitLS>0</SplitLS>
+            <OneElfS>0</OneElfS>
+            <Strict>0</Strict>
+            <EnumInt>0</EnumInt>
+            <PlainCh>0</PlainCh>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <wLevel>0</wLevel>
+            <uThumb>0</uThumb>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Cads>
+          <Aads>
+            <interw>1</interw>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <thumb>0</thumb>
+            <SplitLS>0</SplitLS>
+            <SwStkChk>0</SwStkChk>
+            <NoWarn>0</NoWarn>
+            <VariousControls>
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
+            </VariousControls>
+          </Aads>
+          <LDads>
+            <umfTarg>1</umfTarg>
+            <Ropi>0</Ropi>
+            <Rwpi>0</Rwpi>
+            <noStLib>0</noStLib>
+            <RepFail>1</RepFail>
+            <useFile>0</useFile>
+            <TextAddressRange>0x08000000</TextAddressRange>
+            <DataAddressRange>0x20000000</DataAddressRange>
+            <ScatterFile></ScatterFile>
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc></Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
+          </LDads>
+        </TargetArmAds>
+      </TargetOption>
+      <Groups>
+      </Groups>
+    </Target>
+  </Targets>
+
+</Project>

+ 471 - 0
bsp/stm32f10x/touch.c

@@ -0,0 +1,471 @@
+#include <stdbool.h>
+#include "stm32f10x.h"
+
+#include "board.h"
+#include "touch.h"
+
+#include <rtthread.h>
+#include <rtgui/event.h>
+#include <rtgui/kbddef.h>
+#include <rtgui/rtgui_server.h>
+#include <rtgui/rtgui_system.h>
+
+/*
+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.x<touch->x+previous_keep)
+                && (touch_previous.x>touch->x-previous_keep)
+                && (touch_previous.y<touch->y+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 <finsh.h>
+
+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 ) ;

+ 21 - 0
bsp/stm32f10x/touch.h

@@ -0,0 +1,21 @@
+#ifndef __TOUCH_H__
+#define __TOUCH_H__
+
+#include <rtthread.h>
+
+#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
+