touch.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. #include <stdbool.h>
  2. #include "stm32f10x.h"
  3. #include "board.h"
  4. #include "touch.h"
  5. #include <rtthread.h>
  6. #include <rtgui/event.h>
  7. #include <rtgui/kbddef.h>
  8. #include <rtgui/rtgui_server.h>
  9. #include <rtgui/rtgui_system.h>
  10. /*
  11. MISO PA6
  12. MOSI PA7
  13. CLK PA5
  14. CS PC4
  15. */
  16. #define CS_0() GPIO_ResetBits(GPIOC,GPIO_Pin_4)
  17. #define CS_1() GPIO_SetBits(GPIOC,GPIO_Pin_4)
  18. /*
  19. 7 6 - 4 3 2 1-0
  20. s A2-A0 MODE SER/DFR PD1-PD0
  21. */
  22. #define TOUCH_MSR_Y 0x90 //读X轴坐标指令 addr:1
  23. #define TOUCH_MSR_X 0xD0 //读Y轴坐标指令 addr:3
  24. struct rtgui_touch_device
  25. {
  26. struct rt_device parent;
  27. rt_timer_t poll_timer;
  28. rt_uint16_t x, y;
  29. rt_bool_t calibrating;
  30. rt_touch_calibration_func_t calibration_func;
  31. rt_uint16_t min_x, max_x;
  32. rt_uint16_t min_y, max_y;
  33. };
  34. static struct rtgui_touch_device *touch = RT_NULL;
  35. extern unsigned char SPI_WriteByte(unsigned char data);
  36. rt_inline void EXTI_Enable(rt_uint32_t enable);
  37. struct rt_semaphore spi1_lock;
  38. void rt_hw_spi1_baud_rate(uint16_t SPI_BaudRatePrescaler)
  39. {
  40. SPI1->CR1 &= ~SPI_BaudRatePrescaler_256;
  41. SPI1->CR1 |= SPI_BaudRatePrescaler;
  42. }
  43. uint8_t SPI_WriteByte(unsigned char data)
  44. {
  45. //Wait until the transmit buffer is empty
  46. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  47. // Send the byte
  48. SPI_I2S_SendData(SPI1, data);
  49. //Wait until a data is received
  50. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  51. // Get the received data
  52. data = SPI_I2S_ReceiveData(SPI1);
  53. // Return the shifted data
  54. return data;
  55. }
  56. //SPI写数据
  57. static void WriteDataTo7843(unsigned char num)
  58. {
  59. SPI_WriteByte(num);
  60. }
  61. #define X_WIDTH 240
  62. #define Y_WIDTH 320
  63. static void rtgui_touch_calculate()
  64. {
  65. if (touch != RT_NULL)
  66. {
  67. rt_sem_take(&spi1_lock, RT_WAITING_FOREVER);
  68. /* SPI1 configure */
  69. rt_hw_spi1_baud_rate(SPI_BaudRatePrescaler_64);/* 72M/64=1.125M */
  70. //读取触摸值
  71. {
  72. rt_uint16_t tmpx[10];
  73. rt_uint16_t tmpy[10];
  74. unsigned int i;
  75. /* From the datasheet:
  76. * When the very first CLK after the control byte comes in, the
  77. * DOUT of ADS7843 is not valid. So we could only get 7bits from
  78. * the first SPI_WriteByte. And the got the following 5 bits from
  79. * another SPI_WriteByte.(aligned MSB)
  80. */
  81. for(i=0; i<10; i++)
  82. {
  83. CS_0();
  84. WriteDataTo7843(TOUCH_MSR_X);
  85. tmpx[i] = (SPI_WriteByte(0x00) & 0x7F) << 5;
  86. tmpx[i] |= (SPI_WriteByte(TOUCH_MSR_Y) >> 3) & 0x1F;
  87. tmpy[i] = (SPI_WriteByte(0x00) & 0x7F) << 5;
  88. tmpy[i] |= (SPI_WriteByte(0x00) >> 3) & 0x1F;
  89. WriteDataTo7843( 1<<7 ); /* 打开中断 */
  90. CS_1();
  91. }
  92. //去最高值与最低值,再取平均值
  93. {
  94. rt_uint32_t min_x = 0xFFFF,min_y = 0xFFFF;
  95. rt_uint32_t max_x = 0,max_y = 0;
  96. rt_uint32_t total_x = 0;
  97. rt_uint32_t total_y = 0;
  98. unsigned int i;
  99. for(i=0;i<10;i++)
  100. {
  101. if( tmpx[i] < min_x )
  102. {
  103. min_x = tmpx[i];
  104. }
  105. if( tmpx[i] > max_x )
  106. {
  107. max_x = tmpx[i];
  108. }
  109. total_x += tmpx[i];
  110. if( tmpy[i] < min_y )
  111. {
  112. min_y = tmpy[i];
  113. }
  114. if( tmpy[i] > max_y )
  115. {
  116. max_y = tmpy[i];
  117. }
  118. total_y += tmpy[i];
  119. }
  120. total_x = total_x - min_x - max_x;
  121. total_y = total_y - min_y - max_y;
  122. touch->x = total_x / 8;
  123. touch->y = total_y / 8;
  124. }//去最高值与最低值,再取平均值
  125. }//读取触摸值
  126. rt_sem_release(&spi1_lock);
  127. /* if it's not in calibration status */
  128. if (touch->calibrating != RT_TRUE)
  129. {
  130. if (touch->max_x > touch->min_x)
  131. {
  132. touch->x = (touch->x - touch->min_x) * X_WIDTH/(touch->max_x - touch->min_x);
  133. }
  134. else
  135. {
  136. touch->x = (touch->min_x - touch->x) * X_WIDTH/(touch->min_x - touch->max_x);
  137. }
  138. if (touch->max_y > touch->min_y)
  139. {
  140. touch->y = (touch->y - touch->min_y) * Y_WIDTH /(touch->max_y - touch->min_y);
  141. }
  142. else
  143. {
  144. touch->y = (touch->min_y - touch->y) * Y_WIDTH /(touch->min_y - touch->max_y);
  145. }
  146. }
  147. }
  148. }
  149. static unsigned int flag = 0;
  150. void touch_timeout(void* parameter)
  151. {
  152. struct rtgui_event_mouse emouse;
  153. static struct _touch_previous
  154. {
  155. rt_uint32_t x;
  156. rt_uint32_t y;
  157. } touch_previous;
  158. if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) != 0)
  159. {
  160. int tmer = RT_TICK_PER_SECOND/8 ;
  161. EXTI_Enable(1);
  162. emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
  163. emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP);
  164. /* use old value */
  165. emouse.x = touch->x;
  166. emouse.y = touch->y;
  167. /* stop timer */
  168. rt_timer_stop(touch->poll_timer);
  169. rt_kprintf("touch up: (%d, %d)\n", emouse.x, emouse.y);
  170. flag = 0;
  171. if ((touch->calibrating == RT_TRUE) && (touch->calibration_func != RT_NULL))
  172. {
  173. /* callback function */
  174. touch->calibration_func(emouse.x, emouse.y);
  175. }
  176. rt_timer_control(touch->poll_timer , RT_TIMER_CTRL_SET_TIME , &tmer);
  177. }
  178. else
  179. {
  180. if(flag == 0)
  181. {
  182. int tmer = RT_TICK_PER_SECOND/20 ;
  183. /* calculation */
  184. rtgui_touch_calculate();
  185. /* send mouse event */
  186. emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
  187. emouse.parent.sender = RT_NULL;
  188. emouse.x = touch->x;
  189. emouse.y = touch->y;
  190. touch_previous.x = touch->x;
  191. touch_previous.y = touch->y;
  192. /* init mouse button */
  193. emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN);
  194. // rt_kprintf("touch down: (%d, %d)\n", emouse.x, emouse.y);
  195. flag = 1;
  196. rt_timer_control(touch->poll_timer , RT_TIMER_CTRL_SET_TIME , &tmer);
  197. }
  198. else
  199. {
  200. /* calculation */
  201. rtgui_touch_calculate();
  202. #define previous_keep 8
  203. //判断移动距离是否小于previous_keep,减少误动作.
  204. if(
  205. (touch_previous.x<touch->x+previous_keep)
  206. && (touch_previous.x>touch->x-previous_keep)
  207. && (touch_previous.y<touch->y+previous_keep)
  208. && (touch_previous.y>touch->y-previous_keep) )
  209. {
  210. return;
  211. }
  212. touch_previous.x = touch->x;
  213. touch_previous.y = touch->y;
  214. /* send mouse event */
  215. emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON ;
  216. emouse.parent.sender = RT_NULL;
  217. emouse.x = touch->x;
  218. emouse.y = touch->y;
  219. /* init mouse button */
  220. emouse.button = (RTGUI_MOUSE_BUTTON_RIGHT |RTGUI_MOUSE_BUTTON_DOWN);
  221. // rt_kprintf("touch motion: (%d, %d)\n", emouse.x, emouse.y);
  222. }
  223. }
  224. /* send event to server */
  225. if (touch->calibrating != RT_TRUE)
  226. rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
  227. }
  228. static void NVIC_Configuration(void)
  229. {
  230. NVIC_InitTypeDef NVIC_InitStructure;
  231. /* Enable the EXTI0 Interrupt */
  232. NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  233. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  234. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  235. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  236. NVIC_Init(&NVIC_InitStructure);
  237. }
  238. rt_inline void EXTI_Enable(rt_uint32_t enable)
  239. {
  240. EXTI_InitTypeDef EXTI_InitStructure;
  241. /* Configure EXTI */
  242. EXTI_InitStructure.EXTI_Line = EXTI_Line1;
  243. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  244. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//Falling下降沿 Rising上升
  245. if (enable)
  246. {
  247. /* enable */
  248. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  249. }
  250. else
  251. {
  252. /* disable */
  253. EXTI_InitStructure.EXTI_LineCmd = DISABLE;
  254. }
  255. EXTI_Init(&EXTI_InitStructure);
  256. EXTI_ClearITPendingBit(EXTI_Line1);
  257. }
  258. static void EXTI_Configuration(void)
  259. {
  260. /* PB1 touch INT */
  261. {
  262. GPIO_InitTypeDef GPIO_InitStructure;
  263. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  264. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  265. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  266. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  267. GPIO_Init(GPIOB,&GPIO_InitStructure);
  268. }
  269. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
  270. /* Configure EXTI */
  271. EXTI_Enable(1);
  272. }
  273. /* RT-Thread Device Interface */
  274. static rt_err_t rtgui_touch_init (rt_device_t dev)
  275. {
  276. NVIC_Configuration();
  277. EXTI_Configuration();
  278. /* PC4 touch CS */
  279. {
  280. GPIO_InitTypeDef GPIO_InitStructure;
  281. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
  282. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  283. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  284. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  285. GPIO_Init(GPIOC,&GPIO_InitStructure);
  286. CS_1();
  287. }
  288. CS_0();
  289. WriteDataTo7843( 1<<7 ); /* 打开中断 */
  290. CS_1();
  291. return RT_EOK;
  292. }
  293. static rt_err_t rtgui_touch_control (rt_device_t dev, rt_uint8_t cmd, void *args)
  294. {
  295. switch (cmd)
  296. {
  297. case RT_TOUCH_CALIBRATION:
  298. touch->calibrating = RT_TRUE;
  299. touch->calibration_func = (rt_touch_calibration_func_t)args;
  300. break;
  301. case RT_TOUCH_NORMAL:
  302. touch->calibrating = RT_FALSE;
  303. break;
  304. case RT_TOUCH_CALIBRATION_DATA:
  305. {
  306. struct calibration_data* data;
  307. data = (struct calibration_data*) args;
  308. //update
  309. touch->min_x = data->min_x;
  310. touch->max_x = data->max_x;
  311. touch->min_y = data->min_y;
  312. touch->max_y = data->max_y;
  313. }
  314. break;
  315. }
  316. return RT_EOK;
  317. }
  318. void EXTI1_IRQHandler(void)
  319. {
  320. /* disable interrupt */
  321. EXTI_Enable(0);
  322. /* start timer */
  323. rt_timer_start(touch->poll_timer);
  324. EXTI_ClearITPendingBit(EXTI_Line1);
  325. }
  326. void rtgui_touch_hw_init(void)
  327. {
  328. /* SPI1 config */
  329. {
  330. GPIO_InitTypeDef GPIO_InitStructure;
  331. SPI_InitTypeDef SPI_InitStructure;
  332. /* Enable SPI1 Periph clock */
  333. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
  334. | RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1,
  335. ENABLE);
  336. /* Configure SPI1 pins: PA5-SCK, PA6-MISO and PA7-MOSI */
  337. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  338. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  339. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  340. GPIO_Init(GPIOA, &GPIO_InitStructure);
  341. /*------------------------ SPI1 configuration ------------------------*/
  342. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx;
  343. SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  344. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  345. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  346. SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  347. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  348. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;/* 72M/64=1.125M */
  349. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  350. SPI_InitStructure.SPI_CRCPolynomial = 7;
  351. SPI_I2S_DeInit(SPI1);
  352. SPI_Init(SPI1, &SPI_InitStructure);
  353. /* Enable SPI_MASTER */
  354. SPI_Cmd(SPI1, ENABLE);
  355. SPI_CalculateCRC(SPI1, DISABLE);
  356. if (rt_sem_init(&spi1_lock, "spi1lock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
  357. {
  358. rt_kprintf("init spi1 lock semaphore failed\n");
  359. }
  360. } /* SPI1 config */
  361. touch = (struct rtgui_touch_device*)rt_malloc (sizeof(struct rtgui_touch_device));
  362. if (touch == RT_NULL) return; /* no memory yet */
  363. /* clear device structure */
  364. rt_memset(&(touch->parent), 0, sizeof(struct rt_device));
  365. touch->calibrating = false;
  366. /* init device structure */
  367. touch->parent.type = RT_Device_Class_Unknown;
  368. touch->parent.init = rtgui_touch_init;
  369. touch->parent.control = rtgui_touch_control;
  370. touch->parent.user_data = RT_NULL;
  371. /* create 1/8 second timer */
  372. touch->poll_timer = rt_timer_create("touch", touch_timeout, RT_NULL,
  373. RT_TICK_PER_SECOND/8, RT_TIMER_FLAG_PERIODIC);
  374. /* register touch device to RT-Thread */
  375. rt_device_register(&(touch->parent), "touch", RT_DEVICE_FLAG_RDWR);
  376. }
  377. #include <finsh.h>
  378. void touch_t( rt_uint16_t x , rt_uint16_t y )
  379. {
  380. struct rtgui_event_mouse emouse ;
  381. emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
  382. emouse.parent.sender = RT_NULL;
  383. emouse.x = x ;
  384. emouse.y = y ;
  385. /* init mouse button */
  386. emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_DOWN );
  387. rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
  388. rt_thread_delay(2) ;
  389. emouse.button = (RTGUI_MOUSE_BUTTON_LEFT |RTGUI_MOUSE_BUTTON_UP );
  390. rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
  391. }
  392. FINSH_FUNCTION_EXPORT(touch_t, x & y ) ;