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