FreeCalypso > hg > fc-selenite
comparison src/cs/drivers/drv_app/kpd/board/kpd_scan_functions.c @ 0:b6a5e36de839
src/cs: initial import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 15 Jul 2018 04:39:26 +0000 |
parents | |
children | 7409b22cac61 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b6a5e36de839 |
---|---|
1 /** | |
2 * @file kpd_scan_functions.c | |
3 * | |
4 * Implementation of hardware keypad interface functions. | |
5 * These functions implement the keypad interface with the windows. | |
6 * | |
7 * @author Laurent Sollier (l-sollier@ti.com) | |
8 * @version 0.1 | |
9 */ | |
10 | |
11 /* | |
12 * History: | |
13 * | |
14 * Date Author Modification | |
15 * ------------------------------------ | |
16 * 10/10/2001 L Sollier Create | |
17 * | |
18 * | |
19 * (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved | |
20 */ | |
21 #include "board.cfg" | |
22 #include "fc-target.cfg" | |
23 | |
24 #include "nucleus.h" /* used for HISR */ | |
25 | |
26 #include "kpd/kpd_scan_functions.h" | |
27 #include "kpd/kpd_cfg.h" | |
28 #include "kpd/kpd_physical_key_def.h" | |
29 #include "kpd/kpd_messages_i.h" | |
30 #include "kpd/kpd_env.h" | |
31 | |
32 #include "rvf/rvf_api.h" | |
33 #include "rvm/rvm_use_id_list.h" | |
34 #include "rvf/rvf_env.h" | |
35 | |
36 #if (CHIPSET == 12) | |
37 #include "inth/sys_inth.h" | |
38 #else | |
39 #include "armio/armio.h" | |
40 #include "inth/iq.h" | |
41 #endif | |
42 | |
43 #include "memif/mem.h" | |
44 | |
45 | |
46 #if (CHIPSET == 12) | |
47 #define KBR_CTRL_REG (MEM_KEYBOARD + 0x00) /* KBR control reg */ | |
48 #define KBR_DEBOUNCING_TIME (MEM_KEYBOARD + 0x02) /* KBR debouncing time reg */ | |
49 #define KBR_STATE_MACHINE_STATUS (MEM_KEYBOARD + 0x0E) /* KBR state machine status reg */ | |
50 #define KBR_IN (MEM_KEYBOARD + 0x10) /* KBR inputs (rows) */ | |
51 #define KBR_OUT (MEM_KEYBOARD + 0x12) /* KBR outputs (columns) */ | |
52 #endif | |
53 | |
54 | |
55 #if (CHIPSET == 12) | |
56 #define KP_ROW_IN KBR_IN | |
57 #define KP_COL_OUT KBR_OUT | |
58 #else | |
59 #define KP_ROW_IN ARMIO_KBR_IN | |
60 #define KP_COL_OUT ARMIO_KBR_OUT | |
61 #endif | |
62 | |
63 | |
64 #if (BOARD == 7) | |
65 #define KP_ROWS 5 | |
66 #define KP_COLS 4 | |
67 | |
68 const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]= | |
69 { | |
70 /* Layout of B-Sample */ | |
71 {KPD_PKEY_SOFT_LEFT, KPD_PKEY_UP, KPD_PKEY_DOWN, KPD_PKEY_SOFT_RIGHT}, | |
72 {KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_GREEN}, | |
73 {KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6, KPD_PKEY_NULL}, | |
74 {KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_NULL}, | |
75 {KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE,KPD_PKEY_NULL}, | |
76 }; | |
77 #elif ((BOARD == 8) || (BOARD == 9)) | |
78 #define KP_ROWS 5 | |
79 #define KP_COLS 4 | |
80 const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]= | |
81 { | |
82 /* Layout of C-Sample */ | |
83 {KPD_PKEY_UP, KPD_PKEY_GREEN,KPD_PKEY_SOFT_RIGHT,KPD_PKEY_DOWN}, | |
84 {KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_SOFT_LEFT}, | |
85 {KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6, KPD_PKEY_NULL}, | |
86 {KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_NULL}, | |
87 {KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE, KPD_PKEY_NULL}, | |
88 }; | |
89 #elif defined(CONFIG_TARGET_COMPAL) | |
90 #define KP_ROWS 5 | |
91 #define KP_COLS 4 | |
92 const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]= | |
93 { | |
94 /* Mot C1xx keypad */ | |
95 {KPD_PKEY_GREEN, KPD_PKEY_3, KPD_PKEY_2, KPD_PKEY_1}, | |
96 {KPD_PKEY_UP, KPD_PKEY_6, KPD_PKEY_5, KPD_PKEY_4}, | |
97 {KPD_PKEY_DOWN, KPD_PKEY_9, KPD_PKEY_8, KPD_PKEY_7}, | |
98 {KPD_PKEY_LEFT, KPD_PKEY_DIESE, KPD_PKEY_0, KPD_PKEY_STAR}, | |
99 {KPD_PKEY_RIGHT, KPD_PKEY_SOFT_RIGHT, KPD_PKEY_NAV_CENTER,KPD_PKEY_SOFT_LEFT}, | |
100 }; | |
101 #elif defined(CONFIG_TARGET_PIRELLI) | |
102 #define KP_ROWS 5 | |
103 #define KP_COLS 5 | |
104 const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]= | |
105 { | |
106 /* Pirelli's keypad */ | |
107 {KPD_PKEY_NAV_CENTER, KPD_PKEY_LEFT, KPD_PKEY_RIGHT, KPD_PKEY_UP, KPD_PKEY_NULL}, | |
108 {KPD_PKEY_SOFT_LEFT, KPD_PKEY_SOFT_RIGHT, KPD_PKEY_GREEN, KPD_PKEY_DOWN, KPD_PKEY_VOL_UP}, | |
109 {KPD_PKEY_3, KPD_PKEY_6, KPD_PKEY_9, KPD_PKEY_DIESE, KPD_PKEY_VOL_DOWN}, | |
110 {KPD_PKEY_2, KPD_PKEY_5, KPD_PKEY_8, KPD_PKEY_0, KPD_PKEY_REC}, | |
111 {KPD_PKEY_1, KPD_PKEY_4, KPD_PKEY_7, KPD_PKEY_STAR, KPD_PKEY_NULL}, | |
112 }; | |
113 #elif ((BOARD == 40) || (BOARD == 41) || (BOARD == 42) || (BOARD == 43)) | |
114 #define KP_ROWS 5 | |
115 #define KP_COLS 5 | |
116 const T_KPD_PHYSICAL_KEY_ID keypad_layout[KP_ROWS][KP_COLS]= | |
117 { | |
118 /* Layout of D-Sample and E-Sample */ | |
119 {KPD_PKEY_GREEN, KPD_PKEY_VOL_DOWN, KPD_PKEY_VOL_UP,KPD_PKEY_SOFT_LEFT, KPD_PKEY_LEFT}, | |
120 {KPD_PKEY_1, KPD_PKEY_2, KPD_PKEY_3, KPD_PKEY_REC, KPD_PKEY_RIGHT}, | |
121 {KPD_PKEY_4, KPD_PKEY_5, KPD_PKEY_6, KPD_PKEY_SOFT_RIGHT, KPD_PKEY_UP}, | |
122 {KPD_PKEY_7, KPD_PKEY_8, KPD_PKEY_9, KPD_PKEY_NULL, KPD_PKEY_DOWN}, | |
123 {KPD_PKEY_STAR, KPD_PKEY_0, KPD_PKEY_DIESE, KPD_PKEY_NULL, KPD_PKEY_NAV_CENTER}, | |
124 }; | |
125 #endif | |
126 | |
127 #define KP_ACTIVATE(i) (~(1<<i)) | |
128 #define KP_IS_ACTIVE(rows,i) ((rows & (1<<i)) == 0) | |
129 #define KP_ALL_OFF 0x1F | |
130 #define KP_ALL_ON 0 | |
131 | |
132 extern T_KPD_ENV_CTRL_BLK* kpd_env_ctrl_blk; | |
133 | |
134 typedef struct { NU_HISR hisr; | |
135 char hisr_stack[512]; | |
136 } T_HISR_INFOS; | |
137 | |
138 static T_HISR_INFOS hisr_infos = {0}; | |
139 | |
140 | |
141 /** | |
142 * @name Functions implementation | |
143 * | |
144 */ | |
145 /*@{*/ | |
146 | |
147 | |
148 #if (CHIPSET == 12) | |
149 | |
150 /** kpd_init_ctrl_reg : Initialize the Control register | |
151 */ | |
152 void kpd_init_ctrl_reg(const UINT8 software_nreset, | |
153 const T_KPD_Nsoftware_mode nsoftware_mode, | |
154 const T_KPD_PTV ptv, | |
155 const T_KPD_EnableDetection long_key_process_en, | |
156 const T_KPD_EnableDetection time_out_empty_en, | |
157 const T_KPD_EnableDetection time_out_long_key_en, | |
158 const T_KPD_EnableDetection repeat_mode_en) | |
159 { | |
160 volatile UINT16 status_reg; | |
161 status_reg = *(volatile UINT16*) KBR_STATE_MACHINE_STATUS; | |
162 | |
163 if ( (status_reg != KPD_TEST_TIMER_DEBOUNCING) && (status_reg != KPD_TEST_TIMER_LONG_KEY) && | |
164 (status_reg != KPD_TEST_TIMER_TIME_OUT) && (status_reg != KPD_TEST_TIMER_REPEAT_KEY) ) | |
165 { | |
166 | |
167 /* The PTV can be programmed since the timer is not running */ | |
168 | |
169 *(volatile UINT16*) KBR_CTRL_REG = (software_nreset | | |
170 nsoftware_mode << 1 | | |
171 ptv << 2 | | |
172 long_key_process_en << 5 | | |
173 time_out_empty_en << 6 | | |
174 time_out_long_key_en << 7 | | |
175 repeat_mode_en << 8); | |
176 } | |
177 else | |
178 { | |
179 | |
180 /* The PTV must not be programmed when the timer is running */ | |
181 | |
182 SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 0, 1, software_nreset); | |
183 SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 1, 1, nsoftware_mode); | |
184 SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 5, 1, long_key_process_en); | |
185 SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 6, 1, time_out_empty_en); | |
186 SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 7, 1, time_out_long_key_en); | |
187 SetGroupBits16(*(volatile unsigned short *)(KBR_CTRL_REG), 8, 1, repeat_mode_en); | |
188 } | |
189 } | |
190 | |
191 | |
192 /** kpd_software_reset : reset software | |
193 */ | |
194 void kpd_software_reset(void) | |
195 { | |
196 volatile UINT16 mem_reg; | |
197 | |
198 mem_reg = (*(volatile UINT16*) KBR_CTRL_REG) & 0xFFFE; | |
199 *(volatile UINT16*) KBR_CTRL_REG = mem_reg; | |
200 | |
201 } | |
202 | |
203 | |
204 /** kpd_set_debouncing_time : Set the desired value of debouncing time | |
205 */ | |
206 void kpd_set_debouncing_time(const UINT8 debouncing_time) | |
207 { | |
208 | |
209 *(volatile UINT16*) KBR_DEBOUNCING_TIME = debouncing_time; | |
210 | |
211 } | |
212 | |
213 #endif /* #if (CHIPSET == 12) */ | |
214 | |
215 | |
216 | |
217 | |
218 /** | |
219 * function: hisr_entry | |
220 */ | |
221 static void hisr_entry(void) | |
222 { | |
223 T_RVF_MB_STATUS mb_status; | |
224 T_KPD_KEY_PRESSED_MSG* msg_key_pressed; | |
225 T_KPD_PHYSICAL_KEY_ID key; | |
226 | |
227 /* Reserve memory for message */ | |
228 mb_status = rvf_get_buf (kpd_env_ctrl_blk->prim_id, sizeof(T_KPD_KEY_PRESSED_MSG), (void **) &msg_key_pressed); | |
229 | |
230 if (mb_status != RVF_RED) /* Memory allocation success */ | |
231 { | |
232 /* Fill the message */ | |
233 msg_key_pressed->hdr.msg_id = KPD_KEY_PRESSED_MSG; | |
234 /* Virtual key id is not yet known */ | |
235 msg_key_pressed->value = KPD_PKEY_NULL; | |
236 if (mb_status == RVF_GREEN) | |
237 msg_key_pressed->key_to_process = TRUE; | |
238 else | |
239 msg_key_pressed->key_to_process = FALSE; | |
240 | |
241 /* Send message to the keypad task */ | |
242 rvf_send_msg(kpd_env_ctrl_blk->addr_id, msg_key_pressed); | |
243 } | |
244 else | |
245 { | |
246 KPD_SEND_TRACE("KPD: Not enough memory to send new key pressed", RV_TRACE_LEVEL_ERROR); | |
247 kpd_acknowledge_key_pressed(); | |
248 } | |
249 } | |
250 | |
251 | |
252 /** | |
253 * function: kpd_initialize_keypad_hardware | |
254 */ | |
255 void kpd_initialize_keypad_hardware(void) | |
256 { | |
257 /* HISR creation */ | |
258 NU_Create_HISR(&hisr_infos.hisr, | |
259 "KPD_HISR", | |
260 hisr_entry, | |
261 2, | |
262 hisr_infos.hisr_stack, | |
263 sizeof(hisr_infos.hisr_stack)); | |
264 | |
265 | |
266 #if (CHIPSET == 12) | |
267 /* Init control register ; hardware decoding */ | |
268 kpd_init_ctrl_reg(1, HARDWARE_DECODING, KPD_CLK_DIV32, | |
269 KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED, | |
270 KPD_DETECTION_DISABLED, KPD_DETECTION_DISABLED); | |
271 | |
272 /* Debouncing time = 64ms */ | |
273 kpd_set_debouncing_time(0x3F); | |
274 | |
275 #endif | |
276 | |
277 /* Activate all outputs */ | |
278 *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON; | |
279 | |
280 /* Unmask keypad interrupt */ | |
281 #if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41)) | |
282 AI_UnmaskIT (ARMIO_MASKIT_KBD); | |
283 #elif (CHIPSET == 12) | |
284 F_INTH_ENABLE_ONE_IT(C_INTH_KEYBOARD_IT); | |
285 #else | |
286 IQ_Unmask (IQ_ARMIO); | |
287 #endif | |
288 } | |
289 | |
290 | |
291 | |
292 /** | |
293 * function: kpd_key_handler | |
294 */ | |
295 void kpd_key_handler(void) | |
296 { | |
297 /* If keypad is not started, return immediately */ | |
298 if ( (kpd_env_ctrl_blk == 0) || (kpd_env_ctrl_blk->swe_is_initialized == FALSE) ) | |
299 { | |
300 kpd_acknowledge_key_pressed(); | |
301 } | |
302 else | |
303 { | |
304 /* Mask keypad interrupt until key is released */ | |
305 #if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41)) | |
306 AI_MaskIT (ARMIO_MASKIT_KBD); | |
307 #elif (CHIPSET == 12) | |
308 F_INTH_DISABLE_ONE_IT(C_INTH_KEYBOARD_IT); | |
309 #else | |
310 IQ_Mask(IQ_ARMIO); | |
311 #endif | |
312 | |
313 /* Activate HISR to process the key event */ | |
314 NU_Activate_HISR(&hisr_infos.hisr); | |
315 } | |
316 } | |
317 | |
318 /** | |
319 * function: kpd_acknowledge_key_pressed | |
320 */ | |
321 void kpd_acknowledge_key_pressed(void) | |
322 { | |
323 /* Unmask keypad interrupt */ | |
324 #if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41)) | |
325 AI_UnmaskIT (ARMIO_MASKIT_KBD); | |
326 #elif (CHIPSET == 12) | |
327 F_INTH_ENABLE_ONE_IT(C_INTH_KEYBOARD_IT); | |
328 #else | |
329 IQ_Unmask (IQ_ARMIO); | |
330 #endif | |
331 } | |
332 | |
333 | |
334 /* | |
335 * delay | |
336 * | |
337 * Wait a while to let bus settle | |
338 * Magic value found by trial and error | |
339 * | |
340 */ | |
341 static void delay(void) | |
342 { | |
343 volatile int i; | |
344 | |
345 for (i=0;i<10;i++) ; | |
346 } | |
347 | |
348 /** | |
349 * function: kpd_scan_keypad | |
350 */ | |
351 T_KPD_PHYSICAL_KEY_ID kpd_scan_keypad(void) | |
352 { | |
353 int row, col; | |
354 volatile UINT16 rows; | |
355 | |
356 /* Activate all columns to find if any row is active */ | |
357 *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON; | |
358 delay(); | |
359 | |
360 rows = (*(volatile UINT16*) KP_ROW_IN) & 0x1F; | |
361 if (rows == KP_ALL_OFF) | |
362 return KPD_PKEY_NULL; | |
363 | |
364 /* Deactivate all columns */ | |
365 *(volatile UINT16*) KP_COL_OUT = KP_ALL_OFF; | |
366 | |
367 #ifdef CONFIG_TARGET_COMPAL | |
368 /* Compal's power key handling */ | |
369 delay(); | |
370 rows = (*(volatile UINT16*) KP_ROW_IN) & 0x1F; | |
371 if (KP_IS_ACTIVE(rows,4)) | |
372 { | |
373 /* Reactivate all columns */ | |
374 *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON; | |
375 return KPD_PKEY_RED; | |
376 } | |
377 #endif | |
378 | |
379 /* Activate 1 column at a time */ | |
380 for (col = 0; col < KP_COLS; col++) | |
381 { | |
382 *(volatile UINT16*) KP_COL_OUT = (KP_ACTIVATE(col)); | |
383 delay(); | |
384 | |
385 /* Find which row is active */ | |
386 rows = (*(volatile UINT16*) KP_ROW_IN) & 0x1F; | |
387 | |
388 if (rows != KP_ALL_OFF) | |
389 { | |
390 for (row = 0; row < KP_ROWS; row++) | |
391 { | |
392 /* first active row */ | |
393 if ( KP_IS_ACTIVE(rows,row)) | |
394 { | |
395 /* Reactivate all columns */ | |
396 *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON; | |
397 /* DO NOT remove this comment. It allows to simply define the link physical layout | |
398 and physical key Id (for a new keypad) */ | |
399 //KPD_SEND_TRACE_PARAM("KPD: Keypad layout check ", keypad_layout[row][col], RV_TRACE_LEVEL_DEBUG_HIGH); | |
400 return keypad_layout[row][col]; | |
401 } | |
402 } | |
403 } | |
404 } | |
405 | |
406 /* No row was active - Reactivate all columns and return */ | |
407 *(volatile UINT16*) KP_COL_OUT = KP_ALL_ON; | |
408 return KPD_PKEY_NULL; | |
409 } | |
410 | |
411 | |
412 /*@}*/ |