GadgetSeed  0.9.6
stm32f7xxx-disc_ts.c
[詳解]
1 /** @file
2  @brief STM32F7xxx Discovery Touch Sensor
3 
4  @date 2017.02.05
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 #if defined(GSC_TARGET_SYSTEM_STM32F746GDISCOVERY)
23 #include "stm32746g_discovery_ts.h"
24 #elif defined(GSC_TARGET_SYSTEM_STM32F769IDISCOVERY)
25 #include "stm32f769i_discovery_ts.h"
26 #endif
27 
28 #define LCD_WIDTH GSC_GRAPHICS_DISPLAY_WIDTH ///< LCD幅ドット数
29 #define LCD_HEIGHT GSC_GRAPHICS_DISPLAY_HEIGHT ///< LCD高さドット数
30 
31 #define MOVEEVENTINTERVAL 20 ///< EVT_TOUCHMOVEの最小送信間隔
32 
33 static struct st_event ts_evq;
34 #define MAX_TS_EVENT_QUEUE 4
35 static unsigned char ts_data[MAX_TS_EVENT_QUEUE];
36 static struct st_mutex ts_mutex;
37 
38 static unsigned short levent;
39 static unsigned int ltime;
40 static unsigned short lpos_x;
41 static unsigned short lpos_y;
42 
43 static void inthdr_exti15_10(unsigned int intnum, void *sp)
44 {
45  DKFPRINTF(0x01, "INT %d(%d)\n", (int)intnum, HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_13));
46 
47  HAL_NVIC_DisableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn));
48  __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13);
49 
50  event_wakeup_ISR(sp, &ts_evq, 0);
51 }
52 
53 #define SIZEOFSTACK (1024*4)
54 static struct st_tcb tcb;
55 static unsigned int stack[SIZEOFSTACK/sizeof(unsigned int)];
56 
57 extern const struct st_device ts_device;
58 
59 static int ts_task(char *arg)
60 {
61  TS_StateTypeDef TS_State;
62  struct st_sysevent ev;
63 
64  while(1) {
65  if(event_wait(&ts_evq, 0, 50) == 0) {
66  continue;
67  }
68 
69  lock_device((struct st_device *)&ts_device, 0);
70  BSP_TS_GetState(&TS_State);
71  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]);
72  HAL_NVIC_EnableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn));
73  unlock_device((struct st_device *)&ts_device);
74 
75  switch(levent) {
76  case EVT_NULL:
77  case EVT_TOUCHEND:
78  if(TS_State.touchDetected != 0) {
79  ev.what = EVT_TOUCHSTART;
80  ev.pos_x = TS_State.touchX[0];
81  ev.pos_y = TS_State.touchY[0];
82  ltime = get_kernel_time();
83  } else {
84  // イベントなし
85  continue;
86  }
87  break;
88 
89  case EVT_TOUCHSTART:
90  case EVT_TOUCHMOVE:
91  if(TS_State.touchDetected != 0) {
92  if((lpos_x != TS_State.touchX[0]) ||
93  (lpos_y != TS_State.touchY[0])) {
94  unsigned int ntime = get_kernel_time();
95  if((ntime - ltime) >= MOVEEVENTINTERVAL) {
96  // イベントが密集するのを防ぐ
97  ev.what = EVT_TOUCHMOVE;
98  ev.pos_x = TS_State.touchX[0];
99  ev.pos_y = TS_State.touchY[0];
100  ltime = ntime;
101  } else {
102  // イベントなし
103  continue;
104  }
105  } else {
106  // イベントなし
107  continue;
108  }
109  } else {
110  ev.what = EVT_TOUCHEND;
111  ev.pos_x = lpos_x;
112  ev.pos_y = lpos_y;
113  }
114  break;
115 
116  default:
117  break;
118  }
119 
120  levent = ev.what;
121  lpos_x = ev.pos_x;
122  lpos_y = ev.pos_y;
123 
124  push_event_interrupt(0, &ev);
125  }
126 
127  return 0;
128 }
129 
130 static int ts_register(struct st_device *dev, char *param)
131 {
132  levent = EVT_NULL;
133  ltime = 0;
134  lpos_x = 0;
135  lpos_y = 0;
136 
137  eventqueue_register_ISR(&ts_evq, "touch_sn", ts_data, sizeof(unsigned char), MAX_TS_EVENT_QUEUE);
138 
139  register_interrupt(IRQ2VECT(EXTI15_10_IRQn), inthdr_exti15_10);
140 
141  task_add(ts_task, "touch_sensor", 1, &tcb,
142  stack, SIZEOFSTACK, 0);
143 
144  BSP_TS_Init(LCD_WIDTH, LCD_HEIGHT);
145  BSP_TS_ITConfig();
146  // 多重割り込みはカーネルが対応していないので
147  HAL_NVIC_SetPriority(TS_INT_EXTI_IRQn, 0, 0); // 割り込みプライオリティは最低(0)
148 
149  return 0;
150 }
151 
152 const struct st_device ts_device = {
154  .explan = "STM32F7xxx-Disc Touch Sensor",
155  .mutex = &ts_mutex,
156  .register_dev = ts_register,
157 };
#define LCD_HEIGHT
LCD高さドット数
#define EVT_TOUCHEND
(画面に)タッチした状態から離した
Definition: sysevent.h:33
画像表示デバイスドライバ ioctl 用マクロ定義
#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
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
#define MOVEEVENTINTERVAL
EVT_TOUCHMOVEの最小送信間隔
static int ts_task(char *arg)
システムイベント
MUTEX
Definition: mutex.h:13
イベント
Definition: event.h:15
#define LCD_WIDTH
LCD幅ドット数
システムコール
割り込みハンドラ
#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