os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp
Update contrib.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // template\template_variant\specific\keyboard.cpp
15 // Access to Template interruptible keyboard
16 // The code here implements a simple interrupt-driven keyboard driver.
17 // This is an alternative to the polled driver in keyboard.cpp.
18 // This example assumes that we have an intelligent keyboard controller
20 // scans the keyboard automatically
21 // generates an interrupt when a key is pressed or released
22 // You can use this code as a starting point and modify it to suit
27 #include <template_assp.h>
30 #include <kernel/kpower.h>
36 // Modify this conversion table to suit your keyboard layout
38 // This example assumes that the following keyboard layout:
40 // <----Row0-----><-----Row1-------><---Row2-----><-----Row3-------><-------Row4-----------><------Row5------><-----Row6-------><---Row7--->
42 // ' \ TAB Z A X Column1
46 // Esc Del Q CapLk S C 3 Column5
48 // 2 T E F B 5 Column7
49 // 9 Y R K G N 6 Column8
50 // 0 U O L H M 7 Column9
51 // - I P ; J , 8 Column10
52 // = Enter [ ' / . Prog Column11
54 // BkSp DnArrow ] UpArrow LeftArrow Space RightArrow Column13
58 const TUint8 convertCode[] =
60 EStdKeyNull , EStdKeyLeftAlt , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column0
61 EStdKeyNull , EStdKeyHash ,EStdKeyBackSlash, EStdKeyTab , 'Z' , 'A' , 'X' ,EStdKeyNull, // Column1
62 EStdKeyNull , EStdKeyNull ,EStdKeyLeftShift, EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column2
63 EStdKeyNull , EStdKeyLeftCtrl , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column3
64 EStdKeyNull , EStdKeyLeftFunc , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column4
65 EStdKeyNull , EStdKeyEscape , EStdKeyDelete , 'Q' , EStdKeyCapsLock , 'S' , 'C' , '3' , // Column5
66 EStdKeyNull , '1' , EStdKeyNull , 'W' , EStdKeyNull , 'D' , 'V' , '4' , // Column6
67 EStdKeyNull , '2' , 'T' , 'E' , EStdKeyNull , 'F' , 'B' , '5' , // Column7
68 EStdKeyNull , '9' , 'Y' , 'R' , 'K' , 'G' , 'N' , '6' , // Column8
69 EStdKeyNull , '0' , 'U' , 'O' , 'L' , 'H' , 'M' , '7' , // Column9
70 EStdKeyNull , EStdKeyMinus , 'I' , 'P' , EStdKeySemiColon , 'J' , EStdKeyComma , '8' , // Column10
71 EStdKeyNull , EStdKeyEquals , EStdKeyEnter ,EStdKeySquareBracketLeft,EStdKeySingleQuote,EStdKeyForwardSlash, EStdKeyFullStop ,EStdKeyMenu, // Column11
72 EStdKeyNull , EStdKeyNull ,EStdKeyRightShift, EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column12
73 EStdKeyNull , EStdKeyBackspace ,EStdKeyDownArrow,EStdKeySquareBracketRight,EStdKeyUpArrow , EStdKeyLeftArrow , EStdKeySpace ,EStdKeyRightArrow, // Column13
74 EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column14
75 EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull // Column15
79 const TInt KFlagKeyPressed = 0x80; // As an example, we'll assume the top bit indicates pressed/released
82 const TKeyboard KConfigKeyboardType = EKeyboard_Full;
83 const TInt KConfigKeyboardDeviceKeys = 0;
84 const TInt KConfigKeyboardAppsKeys = 0;
87 _LIT(KLitKeyboard,"Keyboard");
89 class DKeyboardTemplate : public DPowerHandler
94 public: // from DPowerHandler
96 void PowerDown(TPowerState);
97 TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
98 void KeyboardInfo(TKeyboardInfoV01& aInfo);
101 void HandleMsg(TMessageBase* aMsg);
103 static void Isr(TAny* aPtr);
104 static void EventDfcFn(TAny* aPtr);
108 static void PowerUpDfcFn(TAny* aPtr);
110 static void PowerDownDfcFn(TAny* aPtr);
112 void KeyboardPowerUp();
125 LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
127 DKeyboardTemplate* pH=(DKeyboardTemplate*)aPtr;
128 return pH->HalFunction(aFunction,a1,a2);
131 void rxMsg(TAny* aPtr)
133 DKeyboardTemplate& h=*(DKeyboardTemplate*)aPtr;
134 TMessageBase* pM=h.iMsgQ.iMessage;
142 DKeyboardTemplate::DKeyboardTemplate()
143 : DPowerHandler(KLitKeyboard),
144 iMsgQ(rxMsg,this,NULL,1),
145 iPowerUpDfc(PowerUpDfcFn,this,6),
146 iPowerDownDfc(PowerDownDfcFn,this,7),
147 iEventDfc(EventDfcFn,this,1)
151 TInt DKeyboardTemplate::Create()
153 // Initialisation. Bind and enable the interrupt.
156 iDfcQ=Kern::DfcQue0();
158 iKeyboardOn = EFalse;
159 // install the HAL function
160 TInt r=Kern::AddHalEntry(EHalGroupKeyboard,halFunction,this);
164 iEventDfc.SetDfcQ(iDfcQ);
165 iPowerUpDfc.SetDfcQ(iDfcQ);
166 iPowerDownDfc.SetDfcQ(iDfcQ);
167 iMsgQ.SetDfcQ(iDfcQ);
170 // Bind the key event interrupt
171 r=Interrupt::Bind(KIntIdKeyboard,Isr,this);
174 // install the power handler
181 void DKeyboardTemplate::Isr(TAny* aPtr)
183 DKeyboardTemplate& k=*(DKeyboardTemplate*)aPtr;
184 Interrupt::Disable(KIntIdKeyboard);
188 void DKeyboardTemplate::EventDfcFn(TAny* aPtr)
190 ((DKeyboardTemplate*)aPtr)->EventDfc();
193 void DKeyboardTemplate::EventDfc()
195 __KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardTemplate::EventDfc"));
197 TInt irq=NKern::DisableAllInterrupts();
198 while (IsKeyReady()) // while there are keys in the controller's output buffer
200 NKern::RestoreInterrupts(irq);
202 TUint keyCode=GetKeyCode(); // Read keycodes from controller
203 __KTRACE_OPT(KHARDWARE,Kern::Printf("#%02x",keyCode));
206 // TO DO: (mandatory)
208 // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released)
209 // as per below EXAMPLE ONLY:
211 TUint bareCode=keyCode&~KFlagKeyPressed;
212 TUint8 stdKey=convertCode[bareCode];
213 if (keyCode&KFlagKeyPressed)
214 e.Set(TRawEvent::EKeyUp,stdKey,0);
216 e.Set(TRawEvent::EKeyDown,stdKey,0);
218 NKern::Sleep(1); // pause before reading more keycodes
219 irq=NKern::DisableAllInterrupts();
221 Interrupt::Enable(KIntIdKeyboard);
222 NKern::RestoreInterrupts(irq);
225 TBool DKeyboardTemplate::IsKeyReady()
228 // TO DO: (mandatory)
230 // Return ETrue if the keyboard controller has a key event waiting to be read
233 return EFalse; // EXAMPLE ONLY
236 TUint DKeyboardTemplate::GetKeyCode()
239 // TO DO: (mandatory)
241 // Read and return the next available keycode from the keyboard controller
244 return 0; // EXAMPLE ONLY
247 void DKeyboardTemplate::PowerUpDfcFn(TAny* aPtr)
249 ((DKeyboardTemplate*)aPtr)->PowerUpDfc();
252 void DKeyboardTemplate::PowerDownDfcFn(TAny* aPtr)
254 ((DKeyboardTemplate*)aPtr)->PowerDownDfc();
258 void DKeyboardTemplate::KeyboardPowerUp()
260 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardPowerUp()"));
264 // Send key up events for EStdKeyOff (Fn+Esc) event
266 e.Set(TRawEvent::EKeyUp,EStdKeyEscape,0);
268 e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0);
272 void DKeyboardTemplate::PowerUp()
274 iPowerUpDfc.Enque(); // schedules DFC to execute on this driver's thread
277 void DKeyboardTemplate::PowerUpDfc()
279 __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerUpDfc()"));
281 PowerUpDone(); // must be called from a different thread than PowerUp()
284 void DKeyboardTemplate::KeyboardOn()
286 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOn() iKeyboardOn=%d", iKeyboardOn));
288 if (!iKeyboardOn) // may be powered up from Power Manager or HAL
294 void DKeyboardTemplate::PowerDown(TPowerState)
296 iPowerDownDfc.Enque(); // schedules DFC to execute on this driver's thread
299 void DKeyboardTemplate::PowerDownDfc()
301 __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerDownDfc()"));
303 PowerDownDone(); // must be called from a different thread than PowerDown()
306 void DKeyboardTemplate::KeyboardOff()
308 __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOff() iKeyboardOn=%d", iKeyboardOn));
310 if (iKeyboardOn) // may have already been powered down by the HAL
312 iKeyboardOn = EFalse;
313 Interrupt::Disable(KIntIdKeyboard);
318 void DKeyboardTemplate::HandleMsg(TMessageBase* aMsg)
324 aMsg->Complete(KErrNone,ETrue);
327 void DKeyboardTemplate::KeyboardInfo(TKeyboardInfoV01& aInfo)
329 __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::KeyboardInfo"));
331 aInfo.iKeyboardType=KConfigKeyboardType;
332 aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys;
333 aInfo.iAppsKeys=KConfigKeyboardAppsKeys;
336 TInt DKeyboardTemplate::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
339 __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::HalFunction %d", aFunction));
342 case EKeyboardHalKeyboardInfo:
344 TPckgBuf<TKeyboardInfoV01> kPckg;
345 KeyboardInfo(kPckg());
346 Kern::InfoCopy(*(TDes8*)a1,kPckg);
349 case EKeyboardHalSetKeyboardState:
351 if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState")))
352 return KErrPermissionDenied;
355 TThreadMessage& m=Kern::Message();
357 m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up
361 TThreadMessage& m=Kern::Message();
363 m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down
367 case EKeyboardHalKeyboardState:
368 kumemput32(a1, &iKeyboardOn, sizeof(TBool));
377 DECLARE_STANDARD_EXTENSION()
379 __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver"));
381 // create keyboard driver
383 DKeyboardTemplate* pK=new DKeyboardTemplate;
387 __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));