os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp
changeset 0 bde4ae8d615e
     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 +	}