|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * ne1_tb\specific\keypad.cpp |
|
16 * This file contains the implementation of Keypad for the NEC LCD. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 |
|
22 #include <naviengine.h> |
|
23 #include <naviengine_priv.h> |
|
24 #include <e32event.h> |
|
25 #include <e32event_private.h> |
|
26 #include <e32keys.h> |
|
27 #include "lcdgce.h" |
|
28 |
|
29 |
|
30 // =-==LCD keypad settings and registers================== |
|
31 const TUint KKeybPollTime = 100; |
|
32 const TUint KHWKeyRL = KHwFPGABase + 0x0410; // Key return line |
|
33 const TUint KHWKeySR = KHwFPGABase + 0x0418; // Key scan register |
|
34 |
|
35 // Scan codes for buttons: (scan_register_value | (1<<line+4)) |
|
36 // SW1 - is on scan line 1 |
|
37 const TUint KHwKeyCodeArrowUp = 0x21; // SW1 Up |
|
38 const TUint KHwKeyCodeArrowRight = 0x22; // SW1 Right |
|
39 const TUint KHwKeyCodeArrowLeft = 0x24; // SW1 Left |
|
40 const TUint KHwKeyCodeArrowDown = 0x28; // SW1 Down |
|
41 const TUint KHwKeyCodeButtonCentre = 0x30; // SW1 Centre press |
|
42 const TUint KHwKeyCodeButtonLeft = 0x81; // SW2 - is on scan line 3 |
|
43 const TUint KHwKeyCodeButtonRight = 0x41; // SW3 - is on scan line 2 |
|
44 |
|
45 const TUint KHwKeyNumArrowUp = 0; |
|
46 const TUint KHwKeyNumArrowDown = 1; |
|
47 const TUint KHwKeyNumArrowLeft = 2; |
|
48 const TUint KHwKeyNumArrowRight = 3; |
|
49 const TUint KHwKeyNumButtonCentre = 4; |
|
50 const TUint KHwKeyNumButtonLeft = 5; |
|
51 const TUint KHwKeyNumButtonRight = 6; |
|
52 |
|
53 //#define __KTRACE(s) s |
|
54 #define __KTRACE(s) |
|
55 |
|
56 enum TKeyMode |
|
57 { |
|
58 EKeyModeS60 = 0, |
|
59 EKeyModeTechview = 1, |
|
60 |
|
61 // This must be the last entry in the list |
|
62 EKeyModes |
|
63 }; |
|
64 |
|
65 class DNE1Keypad |
|
66 { |
|
67 public: |
|
68 DNE1Keypad(); |
|
69 TInt DoCreate(); |
|
70 static void GetScanCodes(TAny* aPtr); |
|
71 void ProcessKey(TUint aKeyNum, TInt aState); |
|
72 |
|
73 private: |
|
74 |
|
75 inline void AddEventForKey(TUint aKeyCode, TRawEvent::TType aEventType); |
|
76 NTimer iKeyboardTimer; |
|
77 TUint iKeyStates; |
|
78 TKeyMode iKeyMode; |
|
79 }; |
|
80 |
|
81 |
|
82 /* Macro to detect is the key is shifted */ |
|
83 #define SHIFTED(x) (0x8000|(x)) |
|
84 #define ISSHIFTED(x) (0x8000&(x)) |
|
85 #define FUNCED(x) (0x4000|(x)) |
|
86 #define ISFUNCED(x) (0x4000&(x)) |
|
87 #define CTRLED(x) (0x2000|(x)) |
|
88 #define ISCTRLED(x) (0x2000&(x)) |
|
89 #define STDKEY(x) (0x1FFF&(x)) |
|
90 |
|
91 // modify this table to change the key mapping |
|
92 const TUint16 convertCode[][EKeyModes] = |
|
93 { |
|
94 // S60 TechView |
|
95 { EStdKeyUpArrow, EStdKeyUpArrow, }, // SW1 Up |
|
96 { EStdKeyDownArrow, EStdKeyDownArrow, }, // SW1 Down |
|
97 { EStdKeyLeftArrow, EStdKeyLeftArrow, }, // SW1 Left |
|
98 { EStdKeyRightArrow, EStdKeyRightArrow, }, // SW1 Right |
|
99 { EStdKeyDevice3, EStdKeyEnter, }, // SW1 Centre Press |
|
100 { EStdKeyDevice0, EStdKeyEscape, }, // SW2 |
|
101 { EStdKeyDevice1, EStdKeyMenu, }, // SW3 |
|
102 }; |
|
103 |
|
104 void DNE1Keypad::AddEventForKey(TUint aKeyCode, TRawEvent::TType aEventType) |
|
105 { |
|
106 // convert character to keycode and shift, func, ctrl status |
|
107 TUint16 code = convertCode[aKeyCode][iKeyMode]; |
|
108 TBool isShifted = ISSHIFTED(code); |
|
109 TBool isFunced = ISFUNCED(code); |
|
110 TBool isCtrled = ISCTRLED(code); |
|
111 TUint8 stdKey = STDKEY(code); |
|
112 TRawEvent e; |
|
113 |
|
114 if (aEventType == TRawEvent::EKeyDown) |
|
115 { |
|
116 // post it as a sequence of events |
|
117 if (isShifted) |
|
118 { |
|
119 e.Set(TRawEvent::EKeyDown,EStdKeyRightShift,0); |
|
120 Kern::AddEvent(e); |
|
121 } |
|
122 if (isCtrled) |
|
123 { |
|
124 e.Set(TRawEvent::EKeyDown,EStdKeyLeftCtrl,0); |
|
125 Kern::AddEvent(e); |
|
126 } |
|
127 if (isFunced) |
|
128 { |
|
129 e.Set(TRawEvent::EKeyDown,EStdKeyLeftFunc,0); |
|
130 Kern::AddEvent(e); |
|
131 } |
|
132 } |
|
133 |
|
134 e.Set(aEventType,stdKey,0); |
|
135 Kern::AddEvent(e); |
|
136 |
|
137 if (TRawEvent::EKeyUp) |
|
138 { |
|
139 if (isFunced) |
|
140 { |
|
141 e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0); |
|
142 Kern::AddEvent(e); |
|
143 } |
|
144 if (isCtrled) |
|
145 { |
|
146 e.Set(TRawEvent::EKeyUp,EStdKeyLeftCtrl,0); |
|
147 Kern::AddEvent(e); |
|
148 } |
|
149 if (isShifted) |
|
150 { |
|
151 e.Set(TRawEvent::EKeyUp,EStdKeyRightShift,0); |
|
152 Kern::AddEvent(e); |
|
153 } |
|
154 } |
|
155 } |
|
156 |
|
157 void DNE1Keypad::ProcessKey(TUint aKeyNum, TInt aState) |
|
158 { |
|
159 // if the key was pressed last time AND key is now not pressed |
|
160 if ((iKeyStates & (1<<aKeyNum)) && (aState == 0)) |
|
161 { |
|
162 // send a key up event |
|
163 __KTRACE(Kern::Printf("issue KeyUp for key %d ", aKeyNum)); |
|
164 AddEventForKey(aKeyNum,TRawEvent::EKeyUp); |
|
165 |
|
166 // mark this key as released.. |
|
167 iKeyStates &= ~(1<<aKeyNum); |
|
168 } |
|
169 // if the key was NOT pressed last time AND key is now pressed |
|
170 else if (!(iKeyStates & (1<<aKeyNum)) && (aState == 1)) |
|
171 { |
|
172 // send a key down event |
|
173 __KTRACE(Kern::Printf("issue KeyDown for key %d ", aKeyNum)); |
|
174 AddEventForKey(aKeyNum,TRawEvent::EKeyDown); |
|
175 |
|
176 // mark this key as pressed down.. |
|
177 iKeyStates |= (1<<aKeyNum); |
|
178 } |
|
179 } |
|
180 |
|
181 |
|
182 void DNE1Keypad::GetScanCodes(TAny* aPtr) |
|
183 { |
|
184 DNE1Keypad* pD=(DNE1Keypad*)aPtr; |
|
185 |
|
186 TInt keyRow, key=0; |
|
187 for(keyRow = 1; keyRow < 4; ++keyRow) |
|
188 { |
|
189 AsspRegister::Write16(KHWKeySR, keyRow); // make line active.. |
|
190 TUint16 skey = AsspRegister::Read16(KHWKeyRL); // and scan it, 1=key was pressed.. |
|
191 |
|
192 if(skey) |
|
193 { |
|
194 key = (skey | (1<<(keyRow+4))); |
|
195 } |
|
196 } |
|
197 |
|
198 // process each key in turn, passing the current state |
|
199 pD->ProcessKey(KHwKeyNumArrowUp, ((key & KHwKeyCodeArrowUp )==KHwKeyCodeArrowUp )); |
|
200 pD->ProcessKey(KHwKeyNumArrowRight, ((key & KHwKeyCodeArrowRight )==KHwKeyCodeArrowRight )); |
|
201 pD->ProcessKey(KHwKeyNumArrowLeft, ((key & KHwKeyCodeArrowLeft )==KHwKeyCodeArrowLeft )); |
|
202 pD->ProcessKey(KHwKeyNumArrowDown, ((key & KHwKeyCodeArrowDown )==KHwKeyCodeArrowDown )); |
|
203 pD->ProcessKey(KHwKeyNumButtonCentre, ((key & KHwKeyCodeButtonCentre)==KHwKeyCodeButtonCentre)); |
|
204 pD->ProcessKey(KHwKeyNumButtonLeft, ((key & KHwKeyCodeButtonLeft )==KHwKeyCodeButtonLeft )); |
|
205 pD->ProcessKey(KHwKeyNumButtonRight, ((key & KHwKeyCodeButtonRight )==KHwKeyCodeButtonRight )); |
|
206 |
|
207 pD->iKeyboardTimer.Again(KKeybPollTime); |
|
208 } |
|
209 |
|
210 DNE1Keypad::DNE1Keypad() : |
|
211 iKeyboardTimer(GetScanCodes, this), |
|
212 iKeyStates(0) |
|
213 { |
|
214 TUint idMode = AsspRegister::Read32(KHwIDMODE); |
|
215 TUint keyMode = (idMode & KHmKeyConfigSwitch) >> KHsKeyConfigSwitch; |
|
216 |
|
217 switch (keyMode) |
|
218 { |
|
219 default: |
|
220 case 0: iKeyMode = EKeyModeTechview; break; |
|
221 case 1: iKeyMode = EKeyModeS60; break; |
|
222 } |
|
223 } |
|
224 |
|
225 TInt DNE1Keypad::DoCreate() |
|
226 { |
|
227 iKeyboardTimer.OneShot(KKeybPollTime, ETrue); |
|
228 return KErrNone; |
|
229 } |
|
230 |
|
231 |
|
232 DECLARE_STANDARD_EXTENSION() |
|
233 { |
|
234 // check the display mode - and if LCD is not on |
|
235 // (any of ANALOG modes is set)- do not create/start the driver.. |
|
236 TInt r = KErrNoMemory; |
|
237 TInt mode = ReadDipSwitchDisplayMode(); |
|
238 if(mode == DISPLAY_MODE_ANALOG_VGA || |
|
239 mode == DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE_OLD || |
|
240 mode == DISPLAY_MODE_ANALOG_QVGA_PORTRAIT || |
|
241 mode == DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE) |
|
242 { |
|
243 __KTRACE(Kern::Printf("keypad.cpp: LCD panel not switched on...\nwill not start the driver")); |
|
244 r = KErrNone; // just return.. |
|
245 } |
|
246 else |
|
247 { |
|
248 DNE1Keypad* pD= new DNE1Keypad; |
|
249 if (pD) |
|
250 r = pD->DoCreate(); |
|
251 } |
|
252 |
|
253 return r; |
|
254 } |