comparison src/cs/drivers/drv_app/kpd/board/kpd_scan_functions.c @ 0:945cf7f506b2

src/cs: chipsetsw import from tcs211-fcmodem binary blobs and LCD demo files have been excluded, all line endings are LF only
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 25 Sep 2016 22:50:11 +0000
parents
children 385841ccb7f8
comparison
equal deleted inserted replaced
-1:000000000000 0:945cf7f506b2
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 /*@}*/