comparison src/cs/drivers/drv_app/kpd/board/kpd_scan_functions.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children 4dd30fac5933
comparison
equal deleted inserted replaced
-1:000000000000 0:4e78acac3d88
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.h"
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 /*@}*/