GadgetSeed  0.9.6
stm32f769i-disc_button.c
[詳解]
1 /** @file
2  @brief STM32F769I Discovery 簡易キードライバ
3 
4  @date 2017.01.08
5  @author Takashi SHUDO
6 
7  @note
8 
9  PA0 KEY0
10 */
11 
12 #include "interrupt.h"
13 #include "device.h"
14 #include "sysevent.h"
15 #include "key.h"
16 #include "tkprintf.h"
17 #include "timer.h"
18 
19 #include "stm32f7xx_hal.h"
20 
21 //#define DEBUGKBITS 0x03
22 #include "dkprintf.h"
23 
24 
25 //#define USE_GPIO_INTERRUPT
26 
27 #define SCANINTTIME 20 //!< スキャン間隔(20ms)
28 #define KEYLINEBITS 1
29 
30 /* KEY Input Definition */
31 #define GPIO_KEY_USER1 (GPIOA)
32 #define RCC_AHBPeriph_GPIO_KEY_USER1 (RCC_AHB1ENR_GPIOAEN)
33 #define KEY_USER1 (GPIO_PIN_0)
34 
35 static unsigned short key_stat; // キー状態
36 
37 static const unsigned char key_map[KEYLINEBITS] = {
38  KEY_GB_ESC
39 };
40 
41 static void KEY_Configuration(void)
42 {
43  GPIO_InitTypeDef GPIO_InitStructure;
44 
45  /* Enable GPIO_LED clock */
46  RCC->AHB1ENR |= (RCC_AHBPeriph_GPIO_KEY_USER1);
47 
48  /* Configure GPIO for LEDs as Output push-pull */
49  GPIO_InitStructure.Pin = KEY_USER1;
50  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
51  GPIO_InitStructure.Pull = GPIO_NOPULL;
52  GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
53  GPIO_InitStructure.Alternate = 0;
54  HAL_GPIO_Init(GPIO_KEY_USER1, &GPIO_InitStructure);
55 }
56 
57 static void init_gpio(void)
58 {
59  KEY_Configuration();
60 }
61 
62 static unsigned short scan_gpio(void)
63 {
64  unsigned short rt;
65 
66  /*
67  ポート状態が1ならばOn、0ならばOff
68  関数は1のビットがOn
69  */
70  rt = (HAL_GPIO_ReadPin(GPIO_KEY_USER1, KEY_USER1)<<0);
71 
72  DKPRINTF(0x02, "PORT=%04X\n", (int)rt);
73 
74  return rt;
75 }
76 
77 static void scan_key(void *sp)
78 {
79  int i;
80  unsigned short mask;
81  unsigned short bit;
82  struct st_sysevent event;
83  int flg_evt = 0;
84 
85  mask = 0x0001;
86  bit = scan_gpio();
87 
88  for(i=0; i<KEYLINEBITS; i++) {
89  if(bit & mask) {
90  // 押されている
91  if((key_stat & mask) == 0) {
92  // 前は押されていなかった
93  event.what = EVT_KEYDOWN;
94  event.arg = key_map[i];
95  DKPRINTF(0x01, "EVT_KEYDOWN(%d)\n",
96  event.arg);
97  key_stat |= mask;
98  push_event_interrupt(sp, &event);
99  flg_evt = 1;
100  }
101  } else {
102  // いまは押されていなくて
103  if(key_stat & mask) {
104  // 前は押されていた
105  event.what = EVT_KEYUP;
106  event.arg = key_map[i];
107  DKPRINTF(0x01, "EVT_KEYUP(%d)\n",
108  event.arg);
109  key_stat &= ~mask;
110  push_event_interrupt(sp, &event);
111  flg_evt = 1;
112  }
113  }
114  mask <<= 1;
115  }
116 
117  // push したイベント分、カウンタを進める必要がある
118  if(flg_evt) {
120  }
121 }
122 
123 #ifndef USE_GPIO_INTERRUPT
124 static void key_timer(void *sp, unsigned long long stime)
125 {
126  scan_key(sp);
127 }
128 
129 #else
130 static void inthdr_exti2(unsigned long intnum, void *sp)
131 {
132  __HAL_GPIO_EXTI_CLEAR_IT(EXTI_IMR_MR2);
133  DKPRINTF(0x02, "INT %d(%d)\n", (int)intnum, HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2));
134 
135  scan_key(sp);
136 }
137 
138 static void inthdr_exti4(unsigned long intnum, void *sp)
139 {
140  __HAL_GPIO_EXTI_CLEAR_IT(EXTI_IMR_MR4);
141  DKPRINTF(0x02, "INT %d(%d)\n", (int)intnum, HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4));
142 
143  scan_key(sp);
144 }
145 
146 static void inthdr_exti9_5(unsigned long intnum, void *sp)
147 {
148  __HAL_GPIO_EXTI_CLEAR_IT(EXTI_IMR_MR5);
149  DKPRINTF(0x02, "INT %d(%d)\n", (int)intnum, HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5));
150 
151  scan_key(sp);
152 }
153 
154 static void inthdr_exti15_10(unsigned long intnum, void *sp)
155 {
156  __HAL_GPIO_EXTI_CLEAR_IT(EXTI_IMR_MR12);
157  DKPRINTF(0x02, "INT %d(%d)\n", (int)intnum, HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12));
158 
159  scan_key(sp);
160 }
161 #endif
162 
163 static int gpio_button_register(struct st_device *dev, char *param)
164 {
165  key_stat = 0;
166 
167  init_gpio();
168 
169 #ifdef USE_GPIO_INTERRUPT
170  register_interrupt(IRQ2VECT(EXTI2_IRQn), inthdr_exti2);
171  register_interrupt(IRQ2VECT(EXTI4_IRQn), inthdr_exti4);
172  register_interrupt(IRQ2VECT(EXTI9_5_IRQn), inthdr_exti9_5);
173  register_interrupt(IRQ2VECT(EXTI15_10_IRQn), inthdr_exti15_10);
174 #else
175  register_timer_func(key_timer, SCANINTTIME);
176 #endif
177 
178  return 0;
179 }
180 
181 const struct st_device gpio_button_device = {
182  .name = DEF_DEV_NAME_INPUT,
183  .explan = "STM32F769I-Disc GPIO Button",
184  .register_dev = gpio_button_register,
185 };
#define EVT_KEYDOWN
キーを押した
Definition: sysevent.h:27
unsigned short arg
イベント引数
Definition: sysevent.h:14
int register_timer_func(timer_func func, unsigned long interval)
周期処理を追加する
Definition: timer.c:274
void set_event_interrupt(void *sp)
割り込みハンドラからシステムイベント待ちタスクを起床する
Definition: sysevent.c:158
カーネルタイマ
#define EVT_KEYUP
キーを離した
Definition: sysevent.h:28
void push_event_interrupt(void *sp, struct st_sysevent *event)
割り込みハンドラからシステムイベントを登録する
Definition: sysevent.c:146
カーネル用機能限定printf
システムイベント
割り込みハンドラ
#define SCANINTTIME
スキャン間隔(20ms)
システムイベント
Definition: sysevent.h:12
デバイスドライバAPI
デバイスドライバ構造体
Definition: device.h:25
カーネル、ドライバ(非タスク)デバッグ用マクロ
DADG109Aキーコード定義
char name[MAX_DEVNAMELRN]
デバイス名文字列
Definition: device.h:26