os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,389 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// template\template_variant\specific\keyboard.cpp
1.18 +// Access to Template interruptible keyboard
1.19 +// The code here implements a simple interrupt-driven keyboard driver.
1.20 +// This is an alternative to the polled driver in keyboard.cpp.
1.21 +// This example assumes that we have an intelligent keyboard controller
1.22 +// which:
1.23 +// scans the keyboard automatically
1.24 +// generates an interrupt when a key is pressed or released
1.25 +// You can use this code as a starting point and modify it to suit
1.26 +// your hardware.
1.27 +//
1.28 +//
1.29 +
1.30 +#include <template_assp.h>
1.31 +#include "iolines.h"
1.32 +#include "platform.h"
1.33 +#include <kernel/kpower.h>
1.34 +#include <e32keys.h>
1.35 +//
1.36 +//
1.37 +// TO DO: (optional)
1.38 +//
1.39 +// Modify this conversion table to suit your keyboard layout
1.40 +//
1.41 +// This example assumes that the following keyboard layout:
1.42 +//
1.43 +// <----Row0-----><-----Row1-------><---Row2-----><-----Row3-------><-------Row4-----------><------Row5------><-----Row6-------><---Row7--->
1.44 +// LAlt Column0
1.45 +// ' \ TAB Z A X Column1
1.46 +// LShift Column2
1.47 +// LCtrl Column3
1.48 +// Fn Column4
1.49 +// Esc Del Q CapLk S C 3 Column5
1.50 +// 1 W D V 4 Column6
1.51 +// 2 T E F B 5 Column7
1.52 +// 9 Y R K G N 6 Column8
1.53 +// 0 U O L H M 7 Column9
1.54 +// - I P ; J , 8 Column10
1.55 +// = Enter [ ' / . Prog Column11
1.56 +// RShift Column12
1.57 +// BkSp DnArrow ] UpArrow LeftArrow Space RightArrow Column13
1.58 +// Column14
1.59 +// Column15
1.60 +// EXAMPLE ONLY
1.61 +const TUint8 convertCode[] =
1.62 + {
1.63 + EStdKeyNull , EStdKeyLeftAlt , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column0
1.64 + EStdKeyNull , EStdKeyHash ,EStdKeyBackSlash, EStdKeyTab , 'Z' , 'A' , 'X' ,EStdKeyNull, // Column1
1.65 + EStdKeyNull , EStdKeyNull ,EStdKeyLeftShift, EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column2
1.66 + EStdKeyNull , EStdKeyLeftCtrl , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column3
1.67 + EStdKeyNull , EStdKeyLeftFunc , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column4
1.68 + EStdKeyNull , EStdKeyEscape , EStdKeyDelete , 'Q' , EStdKeyCapsLock , 'S' , 'C' , '3' , // Column5
1.69 + EStdKeyNull , '1' , EStdKeyNull , 'W' , EStdKeyNull , 'D' , 'V' , '4' , // Column6
1.70 + EStdKeyNull , '2' , 'T' , 'E' , EStdKeyNull , 'F' , 'B' , '5' , // Column7
1.71 + EStdKeyNull , '9' , 'Y' , 'R' , 'K' , 'G' , 'N' , '6' , // Column8
1.72 + EStdKeyNull , '0' , 'U' , 'O' , 'L' , 'H' , 'M' , '7' , // Column9
1.73 + EStdKeyNull , EStdKeyMinus , 'I' , 'P' , EStdKeySemiColon , 'J' , EStdKeyComma , '8' , // Column10
1.74 + EStdKeyNull , EStdKeyEquals , EStdKeyEnter ,EStdKeySquareBracketLeft,EStdKeySingleQuote,EStdKeyForwardSlash, EStdKeyFullStop ,EStdKeyMenu, // Column11
1.75 + EStdKeyNull , EStdKeyNull ,EStdKeyRightShift, EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column12
1.76 + EStdKeyNull , EStdKeyBackspace ,EStdKeyDownArrow,EStdKeySquareBracketRight,EStdKeyUpArrow , EStdKeyLeftArrow , EStdKeySpace ,EStdKeyRightArrow, // Column13
1.77 + EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column14
1.78 + EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull // Column15
1.79 + };
1.80 +
1.81 +// EXAMPLE ONLY
1.82 +const TInt KFlagKeyPressed = 0x80; // As an example, we'll assume the top bit indicates pressed/released
1.83 +
1.84 +// EXAMPLE ONLY
1.85 +const TKeyboard KConfigKeyboardType = EKeyboard_Full;
1.86 +const TInt KConfigKeyboardDeviceKeys = 0;
1.87 +const TInt KConfigKeyboardAppsKeys = 0;
1.88 +//
1.89 +//
1.90 +_LIT(KLitKeyboard,"Keyboard");
1.91 +
1.92 +class DKeyboardTemplate : public DPowerHandler
1.93 + {
1.94 +public:
1.95 + DKeyboardTemplate();
1.96 + TInt Create();
1.97 +public: // from DPowerHandler
1.98 + void PowerUp();
1.99 + void PowerDown(TPowerState);
1.100 + TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
1.101 + void KeyboardInfo(TKeyboardInfoV01& aInfo);
1.102 + void KeyboardOn();
1.103 + void KeyboardOff();
1.104 + void HandleMsg(TMessageBase* aMsg);
1.105 +private:
1.106 + static void Isr(TAny* aPtr);
1.107 + static void EventDfcFn(TAny* aPtr);
1.108 + void EventDfc();
1.109 +
1.110 + void PowerUpDfc();
1.111 + static void PowerUpDfcFn(TAny* aPtr);
1.112 + void PowerDownDfc();
1.113 + static void PowerDownDfcFn(TAny* aPtr);
1.114 +private:
1.115 + void KeyboardPowerUp();
1.116 + TUint GetKeyCode();
1.117 + TBool IsKeyReady();
1.118 +public:
1.119 + TDfcQue* iDfcQ;
1.120 + TMessageQue iMsgQ;
1.121 + TDfc iPowerUpDfc;
1.122 + TDfc iPowerDownDfc;
1.123 +private:
1.124 + TDfc iEventDfc;
1.125 + TBool iKeyboardOn;
1.126 + };
1.127 +
1.128 +LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
1.129 + {
1.130 + DKeyboardTemplate* pH=(DKeyboardTemplate*)aPtr;
1.131 + return pH->HalFunction(aFunction,a1,a2);
1.132 + }
1.133 +
1.134 +void rxMsg(TAny* aPtr)
1.135 + {
1.136 + DKeyboardTemplate& h=*(DKeyboardTemplate*)aPtr;
1.137 + TMessageBase* pM=h.iMsgQ.iMessage;
1.138 + if (pM)
1.139 + h.HandleMsg(pM);
1.140 + }
1.141 +
1.142 +//
1.143 +// Keyboard class
1.144 +//
1.145 +DKeyboardTemplate::DKeyboardTemplate()
1.146 + : DPowerHandler(KLitKeyboard),
1.147 + iMsgQ(rxMsg,this,NULL,1),
1.148 + iPowerUpDfc(PowerUpDfcFn,this,6),
1.149 + iPowerDownDfc(PowerDownDfcFn,this,7),
1.150 + iEventDfc(EventDfcFn,this,1)
1.151 + {
1.152 + }
1.153 +
1.154 +TInt DKeyboardTemplate::Create()
1.155 +//
1.156 +// Initialisation. Bind and enable the interrupt.
1.157 +//
1.158 + {
1.159 + iDfcQ=Kern::DfcQue0();
1.160 +
1.161 + iKeyboardOn = EFalse;
1.162 + // install the HAL function
1.163 + TInt r=Kern::AddHalEntry(EHalGroupKeyboard,halFunction,this);
1.164 + if (r!=KErrNone)
1.165 + return r;
1.166 +
1.167 + iEventDfc.SetDfcQ(iDfcQ);
1.168 + iPowerUpDfc.SetDfcQ(iDfcQ);
1.169 + iPowerDownDfc.SetDfcQ(iDfcQ);
1.170 + iMsgQ.SetDfcQ(iDfcQ);
1.171 + iMsgQ.Receive();
1.172 +
1.173 + // Bind the key event interrupt
1.174 + r=Interrupt::Bind(KIntIdKeyboard,Isr,this);
1.175 + if (r==KErrNone)
1.176 + {
1.177 + // install the power handler
1.178 + Add();
1.179 + KeyboardPowerUp();
1.180 + }
1.181 + return r;
1.182 + }
1.183 +
1.184 +void DKeyboardTemplate::Isr(TAny* aPtr)
1.185 + {
1.186 + DKeyboardTemplate& k=*(DKeyboardTemplate*)aPtr;
1.187 + Interrupt::Disable(KIntIdKeyboard);
1.188 + k.iEventDfc.Add();
1.189 + }
1.190 +
1.191 +void DKeyboardTemplate::EventDfcFn(TAny* aPtr)
1.192 + {
1.193 + ((DKeyboardTemplate*)aPtr)->EventDfc();
1.194 + }
1.195 +
1.196 +void DKeyboardTemplate::EventDfc()
1.197 + {
1.198 + __KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardTemplate::EventDfc"));
1.199 +
1.200 + TInt irq=NKern::DisableAllInterrupts();
1.201 + while (IsKeyReady()) // while there are keys in the controller's output buffer
1.202 + {
1.203 + NKern::RestoreInterrupts(irq);
1.204 + TRawEvent e;
1.205 + TUint keyCode=GetKeyCode(); // Read keycodes from controller
1.206 + __KTRACE_OPT(KHARDWARE,Kern::Printf("#%02x",keyCode));
1.207 +
1.208 + //
1.209 + // TO DO: (mandatory)
1.210 + //
1.211 + // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released)
1.212 + // as per below EXAMPLE ONLY:
1.213 + //
1.214 + TUint bareCode=keyCode&~KFlagKeyPressed;
1.215 + TUint8 stdKey=convertCode[bareCode];
1.216 + if (keyCode&KFlagKeyPressed)
1.217 + e.Set(TRawEvent::EKeyUp,stdKey,0);
1.218 + else
1.219 + e.Set(TRawEvent::EKeyDown,stdKey,0);
1.220 + Kern::AddEvent(e);
1.221 + NKern::Sleep(1); // pause before reading more keycodes
1.222 + irq=NKern::DisableAllInterrupts();
1.223 + }
1.224 + Interrupt::Enable(KIntIdKeyboard);
1.225 + NKern::RestoreInterrupts(irq);
1.226 + }
1.227 +
1.228 +TBool DKeyboardTemplate::IsKeyReady()
1.229 + {
1.230 + //
1.231 + // TO DO: (mandatory)
1.232 + //
1.233 + // Return ETrue if the keyboard controller has a key event waiting to be read
1.234 + //
1.235 +
1.236 + return EFalse; // EXAMPLE ONLY
1.237 + }
1.238 +
1.239 +TUint DKeyboardTemplate::GetKeyCode()
1.240 + {
1.241 + //
1.242 + // TO DO: (mandatory)
1.243 + //
1.244 + // Read and return the next available keycode from the keyboard controller
1.245 + //
1.246 +
1.247 + return 0; // EXAMPLE ONLY
1.248 + }
1.249 +
1.250 +void DKeyboardTemplate::PowerUpDfcFn(TAny* aPtr)
1.251 + {
1.252 + ((DKeyboardTemplate*)aPtr)->PowerUpDfc();
1.253 + }
1.254 +
1.255 +void DKeyboardTemplate::PowerDownDfcFn(TAny* aPtr)
1.256 + {
1.257 + ((DKeyboardTemplate*)aPtr)->PowerDownDfc();
1.258 + }
1.259 +
1.260 +
1.261 +void DKeyboardTemplate::KeyboardPowerUp()
1.262 + {
1.263 + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardPowerUp()"));
1.264 +
1.265 + iKeyboardOn = ETrue;
1.266 +
1.267 + // Send key up events for EStdKeyOff (Fn+Esc) event
1.268 + TRawEvent e;
1.269 + e.Set(TRawEvent::EKeyUp,EStdKeyEscape,0);
1.270 + Kern::AddEvent(e);
1.271 + e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0);
1.272 + Kern::AddEvent(e);
1.273 + }
1.274 +
1.275 +void DKeyboardTemplate::PowerUp()
1.276 + {
1.277 + iPowerUpDfc.Enque(); // schedules DFC to execute on this driver's thread
1.278 + }
1.279 +
1.280 +void DKeyboardTemplate::PowerUpDfc()
1.281 + {
1.282 + __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerUpDfc()"));
1.283 + KeyboardOn();
1.284 + PowerUpDone(); // must be called from a different thread than PowerUp()
1.285 + }
1.286 +
1.287 +void DKeyboardTemplate::KeyboardOn()
1.288 + {
1.289 + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOn() iKeyboardOn=%d", iKeyboardOn));
1.290 +
1.291 + if (!iKeyboardOn) // may be powered up from Power Manager or HAL
1.292 + {
1.293 + KeyboardPowerUp();
1.294 + }
1.295 + }
1.296 +
1.297 +void DKeyboardTemplate::PowerDown(TPowerState)
1.298 + {
1.299 + iPowerDownDfc.Enque(); // schedules DFC to execute on this driver's thread
1.300 + }
1.301 +
1.302 +void DKeyboardTemplate::PowerDownDfc()
1.303 + {
1.304 + __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerDownDfc()"));
1.305 + KeyboardOff();
1.306 + PowerDownDone(); // must be called from a different thread than PowerDown()
1.307 + }
1.308 +
1.309 +void DKeyboardTemplate::KeyboardOff()
1.310 + {
1.311 + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOff() iKeyboardOn=%d", iKeyboardOn));
1.312 +
1.313 + if (iKeyboardOn) // may have already been powered down by the HAL
1.314 + {
1.315 + iKeyboardOn = EFalse;
1.316 + Interrupt::Disable(KIntIdKeyboard);
1.317 + }
1.318 + iEventDfc.Cancel();
1.319 + }
1.320 +
1.321 +void DKeyboardTemplate::HandleMsg(TMessageBase* aMsg)
1.322 + {
1.323 + if (aMsg->iValue)
1.324 + KeyboardOn();
1.325 + else
1.326 + KeyboardOff();
1.327 + aMsg->Complete(KErrNone,ETrue);
1.328 + }
1.329 +
1.330 +void DKeyboardTemplate::KeyboardInfo(TKeyboardInfoV01& aInfo)
1.331 + {
1.332 + __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::KeyboardInfo"));
1.333 +
1.334 + aInfo.iKeyboardType=KConfigKeyboardType;
1.335 + aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys;
1.336 + aInfo.iAppsKeys=KConfigKeyboardAppsKeys;
1.337 + }
1.338 +
1.339 +TInt DKeyboardTemplate::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
1.340 + {
1.341 + TInt r=KErrNone;
1.342 + __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::HalFunction %d", aFunction));
1.343 + switch(aFunction)
1.344 + {
1.345 + case EKeyboardHalKeyboardInfo:
1.346 + {
1.347 + TPckgBuf<TKeyboardInfoV01> kPckg;
1.348 + KeyboardInfo(kPckg());
1.349 + Kern::InfoCopy(*(TDes8*)a1,kPckg);
1.350 + break;
1.351 + }
1.352 + case EKeyboardHalSetKeyboardState:
1.353 + {
1.354 + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState")))
1.355 + return KErrPermissionDenied;
1.356 + if ((TBool)a1)
1.357 + {
1.358 + TThreadMessage& m=Kern::Message();
1.359 + m.iValue = ETrue;
1.360 + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up
1.361 + }
1.362 + else
1.363 + {
1.364 + TThreadMessage& m=Kern::Message();
1.365 + m.iValue = EFalse;
1.366 + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down
1.367 + }
1.368 + }
1.369 + break;
1.370 + case EKeyboardHalKeyboardState:
1.371 + kumemput32(a1, &iKeyboardOn, sizeof(TBool));
1.372 + break;
1.373 + default:
1.374 + r=KErrNotSupported;
1.375 + break;
1.376 + }
1.377 + return r;
1.378 + }
1.379 +
1.380 +DECLARE_STANDARD_EXTENSION()
1.381 + {
1.382 + __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver"));
1.383 +
1.384 + // create keyboard driver
1.385 + TInt r=KErrNoMemory;
1.386 + DKeyboardTemplate* pK=new DKeyboardTemplate;
1.387 + if (pK)
1.388 + r=pK->Create();
1.389 +
1.390 + __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
1.391 + return r;
1.392 + }