GadgetSeed  0.9.6
32f469i-disc_ts.c
[詳解]
1 /** @file
2  @brief STM32F469I Discovery Touch Sensor
3 
4  @date 2018.08.17
5  @author Takashi SHUDO
6 */
7 
8 #include "sysconfig.h"
9 #include "device.h"
10 #include "interrupt.h"
11 #include "device/video_ioctl.h"
12 #include "device/ts_ioctl.h"
13 #include "timer.h"
14 #include "tkprintf.h"
15 #include "sysevent.h"
16 #include "task/syscall.h"
17 
18 //#define DEBUGKBITS 0x03
19 #include "dkprintf.h"
20 
21 
22 #include "stm32469i_discovery_ts.h"
23 
24 #define LCD_WIDTH GSC_GRAPHICS_DISPLAY_WIDTH ///< LCD幅ドット数
25 #define LCD_HEIGHT GSC_GRAPHICS_DISPLAY_HEIGHT ///< LCD高さドット数
26 
27 #define MOVEEVENTINTERVAL 20 ///< EVT_TOUCHMOVEの最小送信間隔
28 
29 static struct st_event ts_evq;
30 #define MAX_TS_EVENT_QUEUE 4
31 static unsigned char ts_data[MAX_TS_EVENT_QUEUE];
32 static struct st_mutex ts_mutex;
33 
34 static unsigned short levent;
35 static unsigned int ltime;
36 static unsigned short lpos_x;
37 static unsigned short lpos_y;
38 
39 static void inthdr_exti9_5(unsigned int intnum, void *sp)
40 {
41  DKFPRINTF(0x01, "INT %d(%d)\n", (int)intnum, HAL_GPIO_ReadPin(GPIOI, TS_INT_PIN));
42 
43  HAL_NVIC_DisableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn));
44  __HAL_GPIO_EXTI_CLEAR_IT(TS_INT_PIN);
45 
46  event_wakeup_ISR(sp, &ts_evq, 0);
47 }
48 
49 #define SIZEOFSTACK (1024*4)
50 static struct st_tcb tcb;
51 static unsigned int stack[SIZEOFSTACK/sizeof(unsigned int)];
52 
53 extern const struct st_device ts_device;
54 
55 static int ts_task(char *arg)
56 {
57  TS_StateTypeDef TS_State;
58  struct st_sysevent ev;
59 
60  while(1) {
61  if(event_wait(&ts_evq, 0, 50) == 0) {
62  continue;
63  }
64 
65  lock_device((struct st_device *)&ts_device, 0);
66  BSP_TS_GetState(&TS_State);
67  DKFPRINTF(0x01, "[%08ld] D:%d X:%d Y:%d\n", (int)get_kernel_time(), TS_State.touchDetected, TS_State.touchX[0], TS_State.touchY[0]);
68  HAL_NVIC_EnableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn));
69  unlock_device((struct st_device *)&ts_device);
70 
71  switch(levent) {
72  case EVT_NULL:
73  case EVT_TOUCHEND:
74  if(TS_State.touchDetected != 0) {
75  ev.what = EVT_TOUCHSTART;
76  ev.pos_x = TS_State.touchX[0];
77  ev.pos_y = TS_State.touchY[0];
78  ltime = get_kernel_time();
79  } else {
80  // イベントなし
81  continue;
82  }
83  break;
84 
85  case EVT_TOUCHSTART:
86  case EVT_TOUCHMOVE:
87  if(TS_State.touchDetected != 0) {
88  if((lpos_x != TS_State.touchX[0]) ||
89  (lpos_y != TS_State.touchY[0])) {
90  unsigned int ntime = get_kernel_time();
91  if((ntime - ltime) >= MOVEEVENTINTERVAL) {
92  // イベントが密集するのを防ぐ
93  ev.what = EVT_TOUCHMOVE;
94  ev.pos_x = TS_State.touchX[0];
95  ev.pos_y = TS_State.touchY[0];
96  ltime = ntime;
97  } else {
98  // イベントなし
99  continue;
100  }
101  } else {
102  // イベントなし
103  continue;
104  }
105  } else {
106  ev.what = EVT_TOUCHEND;
107  ev.pos_x = lpos_x;
108  ev.pos_y = lpos_y;
109  }
110  break;
111 
112  default:
113  break;
114  }
115 
116  levent = ev.what;
117  lpos_x = ev.pos_x;
118  lpos_y = ev.pos_y;
119 
120  push_event_interrupt(0, &ev);
121  }
122 
123  return 0;
124 }
125 
126 static int ts_register(struct st_device *dev, char *param)
127 {
128  levent = EVT_NULL;
129  ltime = 0;
130  lpos_x = 0;
131  lpos_y = 0;
132 
133  eventqueue_register_ISR(&ts_evq, "touch_sn", ts_data, sizeof(unsigned char), MAX_TS_EVENT_QUEUE);
134 
135  register_interrupt(IRQ2VECT(TS_INT_EXTI_IRQn), inthdr_exti9_5);
136 
137  task_add(ts_task, "touch_sensor", 1, &tcb,
138  stack, SIZEOFSTACK, 0);
139 
140  BSP_TS_Init(LCD_WIDTH, LCD_HEIGHT);
141  BSP_TS_ITConfig();
142  // 多重割り込みはカーネルが対応していないので
143  HAL_NVIC_SetPriority(TS_INT_EXTI_IRQn, 0, 0); // 割り込みプライオリティは最低(0)
144 
145  return 0;
146 }
147 
148 const struct st_device ts_device = {
150  .explan = "32F469IDISCOVERY Touch Sensor",
151  .mutex = &ts_mutex,
152  .register_dev = ts_register,
153 };
#define EVT_TOUCHEND
(画面に)タッチした状態から離した
Definition: sysevent.h:33
画像表示デバイスドライバ ioctl 用マクロ定義
#define LCD_HEIGHT
LCD高さドット数
#define DEF_DEV_NAME_TS
標準タッチセンサデバイス名
Definition: ts_ioctl.h:15
int task_add(task_func func, char *name, int priority, struct st_tcb *tcb, unsigned int *stack, int stack_size, char *arg)
タスクを追加する
Definition: syscall_api.c:188
カーネルタイマ
タッチセンサドライバ ioctl 用マクロ定義
void eventqueue_register_ISR(struct st_event *evtque, const char *name, void *args, unsigned int arg_size, int arg_count)
イベントキューを登録する
Definition: event.c:36
void event_wakeup_ISR(void *sp, struct st_event *evtque, void *arg)
イベントキューにイベントを登録し、イベント待ちタスクを起動する
Definition: task.c:923
#define LCD_WIDTH
LCD幅ドット数
void push_event_interrupt(void *sp, struct st_sysevent *event)
割り込みハンドラからシステムイベントを登録する
Definition: sysevent.c:146
int unlock_device(struct st_device *dev)
デバイスをアンロックする
Definition: device.c:343
カーネル用機能限定printf
static int ts_task(char *arg)
#define MOVEEVENTINTERVAL
EVT_TOUCHMOVEの最小送信間隔
システムイベント
MUTEX
Definition: mutex.h:13
イベント
Definition: event.h:15
システムコール
割り込みハンドラ
#define EVT_TOUCHSTART
(画面に)タッチした
Definition: sysevent.h:31
#define EVT_TOUCHMOVE
(画面に)タッチしたまま動かした
Definition: sysevent.h:32
#define EVT_NULL
イベント無し
Definition: sysevent.h:25
システムイベント
Definition: sysevent.h:12
unsigned long long get_kernel_time(void)
カーネル時間を取得する
Definition: timer.c:192
デバイスドライバAPI
デバイスドライバ構造体
Definition: device.h:25
カーネル、ドライバ(非タスク)デバッグ用マクロ
char name[MAX_DEVNAMELRN]
デバイス名文字列
Definition: device.h:26
タスクコンテキスト
Definition: tcb.h:32
int lock_device(struct st_device *dev, unsigned int timeout)
デバイスをロックする
Definition: device.c:310
int event_wait(struct st_event *evtque, void *argp, unsigned int timeout)
タスクをイベント待ち状態にする
Definition: syscall_api.c:364