os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// template\template_variant\specific\keyboard.cpp
sl@0
    15
// Access to Template interruptible keyboard
sl@0
    16
// The code here implements a simple interrupt-driven keyboard driver.
sl@0
    17
// This is an alternative to the polled driver in keyboard.cpp.
sl@0
    18
// This example assumes that we have an intelligent keyboard controller
sl@0
    19
// which:
sl@0
    20
// scans the keyboard automatically
sl@0
    21
// generates an interrupt when a key is pressed or released
sl@0
    22
// You can use this code as a starting point and modify it to suit
sl@0
    23
// your hardware.
sl@0
    24
// 
sl@0
    25
//
sl@0
    26
sl@0
    27
#include <template_assp.h>
sl@0
    28
#include "iolines.h"
sl@0
    29
#include "platform.h"
sl@0
    30
#include <kernel/kpower.h>
sl@0
    31
#include <e32keys.h>
sl@0
    32
//
sl@0
    33
//
sl@0
    34
// TO DO: (optional)
sl@0
    35
//
sl@0
    36
// Modify this conversion table to suit your keyboard layout
sl@0
    37
//
sl@0
    38
// This example assumes that the following keyboard layout:
sl@0
    39
//
sl@0
    40
// <----Row0-----><-----Row1-------><---Row2-----><-----Row3-------><-------Row4-----------><------Row5------><-----Row6-------><---Row7--->
sl@0
    41
//		LAlt																																Column0
sl@0
    42
//		'				\				TAB				Z					A						X										Column1
sl@0
    43
//						LShift																												Column2
sl@0
    44
//		LCtrl																																Column3
sl@0
    45
//		Fn																																	Column4
sl@0
    46
//		Esc				Del				Q				CapLk				S						C				3						Column5
sl@0
    47
//		1								W									D						V				4						Column6
sl@0
    48
//		2				T				E									F						B				5						Column7
sl@0
    49
//		9				Y				R				K					G						N				6						Column8
sl@0
    50
//		0				U				O				L					H						M				7						Column9
sl@0
    51
//		-				I				P				;					J						,				8						Column10
sl@0
    52
//		=				Enter			[				'					/						.				Prog					Column11
sl@0
    53
//						RShift																												Column12
sl@0
    54
//		BkSp			DnArrow			]				UpArrow				LeftArrow				Space			RightArrow				Column13
sl@0
    55
//																																			Column14
sl@0
    56
//																																			Column15
sl@0
    57
// EXAMPLE ONLY
sl@0
    58
const TUint8 convertCode[] =
sl@0
    59
	{
sl@0
    60
	EStdKeyNull ,   EStdKeyLeftAlt  ,  EStdKeyNull   ,   EStdKeyNull    ,      EStdKeyNull      ,   EStdKeyNull     ,    EStdKeyNull    ,EStdKeyNull,       // Column0
sl@0
    61
	EStdKeyNull ,   EStdKeyHash     ,EStdKeyBackSlash,   EStdKeyTab     ,          'Z'          ,       'A'         ,       'X'         ,EStdKeyNull,       // Column1
sl@0
    62
	EStdKeyNull ,    EStdKeyNull    ,EStdKeyLeftShift,   EStdKeyNull    ,      EStdKeyNull      ,   EStdKeyNull     ,    EStdKeyNull    ,EStdKeyNull,       // Column2
sl@0
    63
	EStdKeyNull ,  EStdKeyLeftCtrl  ,  EStdKeyNull   ,   EStdKeyNull    ,      EStdKeyNull      ,   EStdKeyNull     ,    EStdKeyNull    ,EStdKeyNull,       // Column3
sl@0
    64
	EStdKeyNull ,  EStdKeyLeftFunc  ,  EStdKeyNull   ,   EStdKeyNull    ,      EStdKeyNull      ,   EStdKeyNull     ,    EStdKeyNull    ,EStdKeyNull,       // Column4
sl@0
    65
	EStdKeyNull ,   EStdKeyEscape   , EStdKeyDelete  ,      'Q'         ,      EStdKeyCapsLock  ,       'S'         ,        'C'        ,   '3'     ,       // Column5
sl@0
    66
	EStdKeyNull ,       '1'         ,  EStdKeyNull   ,      'W'         ,      EStdKeyNull      ,       'D'         ,        'V'        ,   '4'     ,       // Column6
sl@0
    67
	EStdKeyNull ,       '2'         ,     'T'        ,      'E'         ,      EStdKeyNull      ,       'F'         ,        'B'        ,   '5'     ,       // Column7
sl@0
    68
	EStdKeyNull ,       '9'         ,     'Y'        ,      'R'         ,          'K'          ,       'G'         ,        'N'        ,   '6'     ,       // Column8
sl@0
    69
	EStdKeyNull ,       '0'         ,     'U'        ,      'O'         ,          'L'          ,       'H'         ,        'M'        ,   '7'     ,       // Column9
sl@0
    70
	EStdKeyNull ,    EStdKeyMinus   ,     'I'        ,      'P'         ,    EStdKeySemiColon   ,       'J'         ,    EStdKeyComma   ,   '8'     ,       // Column10
sl@0
    71
	EStdKeyNull ,    EStdKeyEquals  ,  EStdKeyEnter  ,EStdKeySquareBracketLeft,EStdKeySingleQuote,EStdKeyForwardSlash, EStdKeyFullStop  ,EStdKeyMenu,       // Column11
sl@0
    72
	EStdKeyNull ,    EStdKeyNull    ,EStdKeyRightShift,   EStdKeyNull   ,      EStdKeyNull      ,   EStdKeyNull     ,    EStdKeyNull    ,EStdKeyNull,       // Column12
sl@0
    73
	EStdKeyNull ,  EStdKeyBackspace ,EStdKeyDownArrow,EStdKeySquareBracketRight,EStdKeyUpArrow  , EStdKeyLeftArrow  ,    EStdKeySpace   ,EStdKeyRightArrow, // Column13
sl@0
    74
	EStdKeyNull ,    EStdKeyNull    ,  EStdKeyNull   ,   EStdKeyNull    ,      EStdKeyNull      ,   EStdKeyNull     ,    EStdKeyNull    ,EStdKeyNull,       // Column14
sl@0
    75
	EStdKeyNull ,    EStdKeyNull    ,  EStdKeyNull   ,   EStdKeyNull    ,      EStdKeyNull      ,   EStdKeyNull     ,    EStdKeyNull    ,EStdKeyNull        // Column15
sl@0
    76
	};
sl@0
    77
sl@0
    78
// EXAMPLE ONLY
sl@0
    79
const TInt KFlagKeyPressed = 0x80;		// As an example, we'll assume the top bit indicates pressed/released
sl@0
    80
sl@0
    81
// EXAMPLE ONLY
sl@0
    82
const TKeyboard	KConfigKeyboardType = EKeyboard_Full;
sl@0
    83
const TInt KConfigKeyboardDeviceKeys = 0;
sl@0
    84
const TInt KConfigKeyboardAppsKeys = 0;
sl@0
    85
//
sl@0
    86
//
sl@0
    87
_LIT(KLitKeyboard,"Keyboard");
sl@0
    88
sl@0
    89
class DKeyboardTemplate : public DPowerHandler
sl@0
    90
	{
sl@0
    91
public:
sl@0
    92
	DKeyboardTemplate();
sl@0
    93
	TInt Create();
sl@0
    94
public: // from DPowerHandler
sl@0
    95
	void PowerUp();
sl@0
    96
	void PowerDown(TPowerState);
sl@0
    97
	TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
sl@0
    98
	void KeyboardInfo(TKeyboardInfoV01& aInfo);
sl@0
    99
	void KeyboardOn();
sl@0
   100
	void KeyboardOff();
sl@0
   101
	void HandleMsg(TMessageBase* aMsg);
sl@0
   102
private:
sl@0
   103
	static void Isr(TAny* aPtr);
sl@0
   104
	static void EventDfcFn(TAny* aPtr);
sl@0
   105
	void EventDfc();
sl@0
   106
sl@0
   107
	void PowerUpDfc();
sl@0
   108
	static void PowerUpDfcFn(TAny* aPtr);
sl@0
   109
	void PowerDownDfc();
sl@0
   110
	static void PowerDownDfcFn(TAny* aPtr);
sl@0
   111
private:
sl@0
   112
	void KeyboardPowerUp();
sl@0
   113
	TUint GetKeyCode();
sl@0
   114
	TBool IsKeyReady();
sl@0
   115
public:
sl@0
   116
	TDfcQue* iDfcQ;
sl@0
   117
	TMessageQue iMsgQ;	
sl@0
   118
	TDfc iPowerUpDfc;
sl@0
   119
	TDfc iPowerDownDfc;	
sl@0
   120
private:
sl@0
   121
	TDfc iEventDfc;
sl@0
   122
	TBool iKeyboardOn;
sl@0
   123
	};
sl@0
   124
sl@0
   125
LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
sl@0
   126
	{
sl@0
   127
	DKeyboardTemplate* pH=(DKeyboardTemplate*)aPtr;
sl@0
   128
	return pH->HalFunction(aFunction,a1,a2);
sl@0
   129
	}
sl@0
   130
sl@0
   131
void rxMsg(TAny* aPtr)
sl@0
   132
	{
sl@0
   133
	DKeyboardTemplate& h=*(DKeyboardTemplate*)aPtr;
sl@0
   134
	TMessageBase* pM=h.iMsgQ.iMessage;
sl@0
   135
	if (pM)
sl@0
   136
		h.HandleMsg(pM);
sl@0
   137
	}
sl@0
   138
sl@0
   139
//
sl@0
   140
//	Keyboard class
sl@0
   141
//
sl@0
   142
DKeyboardTemplate::DKeyboardTemplate()
sl@0
   143
	:	DPowerHandler(KLitKeyboard), 
sl@0
   144
		iMsgQ(rxMsg,this,NULL,1),
sl@0
   145
		iPowerUpDfc(PowerUpDfcFn,this,6),
sl@0
   146
		iPowerDownDfc(PowerDownDfcFn,this,7),
sl@0
   147
		iEventDfc(EventDfcFn,this,1)
sl@0
   148
	{
sl@0
   149
	}
sl@0
   150
sl@0
   151
TInt DKeyboardTemplate::Create()
sl@0
   152
//
sl@0
   153
// Initialisation. Bind and enable the interrupt.
sl@0
   154
//
sl@0
   155
	{
sl@0
   156
	iDfcQ=Kern::DfcQue0();
sl@0
   157
sl@0
   158
	iKeyboardOn = EFalse;	
sl@0
   159
		// install the HAL function
sl@0
   160
	TInt r=Kern::AddHalEntry(EHalGroupKeyboard,halFunction,this);
sl@0
   161
	if (r!=KErrNone)
sl@0
   162
		return r;
sl@0
   163
sl@0
   164
	iEventDfc.SetDfcQ(iDfcQ);
sl@0
   165
	iPowerUpDfc.SetDfcQ(iDfcQ);
sl@0
   166
	iPowerDownDfc.SetDfcQ(iDfcQ);
sl@0
   167
	iMsgQ.SetDfcQ(iDfcQ);
sl@0
   168
	iMsgQ.Receive();
sl@0
   169
sl@0
   170
	// Bind the key event interrupt
sl@0
   171
	r=Interrupt::Bind(KIntIdKeyboard,Isr,this);
sl@0
   172
	if (r==KErrNone)
sl@0
   173
		{
sl@0
   174
		// install the power handler
sl@0
   175
		Add();
sl@0
   176
		KeyboardPowerUp();
sl@0
   177
		}
sl@0
   178
	return r;
sl@0
   179
	}
sl@0
   180
sl@0
   181
void DKeyboardTemplate::Isr(TAny* aPtr)
sl@0
   182
	{
sl@0
   183
	DKeyboardTemplate& k=*(DKeyboardTemplate*)aPtr;
sl@0
   184
	Interrupt::Disable(KIntIdKeyboard);
sl@0
   185
	k.iEventDfc.Add();
sl@0
   186
	}
sl@0
   187
sl@0
   188
void DKeyboardTemplate::EventDfcFn(TAny* aPtr)
sl@0
   189
	{
sl@0
   190
	((DKeyboardTemplate*)aPtr)->EventDfc();
sl@0
   191
	}
sl@0
   192
sl@0
   193
void DKeyboardTemplate::EventDfc()
sl@0
   194
	{
sl@0
   195
	__KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardTemplate::EventDfc"));
sl@0
   196
sl@0
   197
	TInt irq=NKern::DisableAllInterrupts();
sl@0
   198
	while (IsKeyReady())						// while there are keys in the controller's output buffer
sl@0
   199
		{
sl@0
   200
		NKern::RestoreInterrupts(irq);
sl@0
   201
		TRawEvent e;
sl@0
   202
		TUint keyCode=GetKeyCode();				// Read keycodes from controller
sl@0
   203
		__KTRACE_OPT(KHARDWARE,Kern::Printf("#%02x",keyCode));
sl@0
   204
sl@0
   205
		//
sl@0
   206
		// TO DO: (mandatory)
sl@0
   207
		//
sl@0
   208
		// Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released)
sl@0
   209
		// as per below EXAMPLE ONLY:
sl@0
   210
		//
sl@0
   211
		TUint bareCode=keyCode&~KFlagKeyPressed;
sl@0
   212
		TUint8 stdKey=convertCode[bareCode];
sl@0
   213
		if (keyCode&KFlagKeyPressed)
sl@0
   214
			e.Set(TRawEvent::EKeyUp,stdKey,0);
sl@0
   215
		else
sl@0
   216
			e.Set(TRawEvent::EKeyDown,stdKey,0);
sl@0
   217
		Kern::AddEvent(e);
sl@0
   218
		NKern::Sleep(1);						// pause before reading more keycodes
sl@0
   219
		irq=NKern::DisableAllInterrupts();
sl@0
   220
		}
sl@0
   221
	Interrupt::Enable(KIntIdKeyboard);
sl@0
   222
	NKern::RestoreInterrupts(irq);
sl@0
   223
	}
sl@0
   224
sl@0
   225
TBool DKeyboardTemplate::IsKeyReady()
sl@0
   226
	{
sl@0
   227
	//
sl@0
   228
	// TO DO: (mandatory)
sl@0
   229
	//
sl@0
   230
	// Return ETrue if the keyboard controller has a key event waiting to be read
sl@0
   231
	//
sl@0
   232
sl@0
   233
	return EFalse;	// EXAMPLE ONLY
sl@0
   234
	}
sl@0
   235
sl@0
   236
TUint DKeyboardTemplate::GetKeyCode()
sl@0
   237
	{
sl@0
   238
	//
sl@0
   239
	// TO DO: (mandatory)
sl@0
   240
	//
sl@0
   241
	// Read and return the next available keycode from the keyboard controller
sl@0
   242
	//
sl@0
   243
sl@0
   244
	return 0;	// EXAMPLE ONLY
sl@0
   245
	}
sl@0
   246
sl@0
   247
void DKeyboardTemplate::PowerUpDfcFn(TAny* aPtr)
sl@0
   248
	{
sl@0
   249
	((DKeyboardTemplate*)aPtr)->PowerUpDfc();
sl@0
   250
	}
sl@0
   251
sl@0
   252
void DKeyboardTemplate::PowerDownDfcFn(TAny* aPtr)
sl@0
   253
	{
sl@0
   254
	((DKeyboardTemplate*)aPtr)->PowerDownDfc();
sl@0
   255
	}
sl@0
   256
sl@0
   257
sl@0
   258
void DKeyboardTemplate::KeyboardPowerUp()
sl@0
   259
	{
sl@0
   260
	__KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardPowerUp()"));
sl@0
   261
sl@0
   262
	iKeyboardOn = ETrue;
sl@0
   263
sl@0
   264
	// Send key up events for EStdKeyOff (Fn+Esc) event 
sl@0
   265
	TRawEvent e;
sl@0
   266
	e.Set(TRawEvent::EKeyUp,EStdKeyEscape,0);
sl@0
   267
	Kern::AddEvent(e);
sl@0
   268
	e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0);
sl@0
   269
	Kern::AddEvent(e);
sl@0
   270
	}
sl@0
   271
sl@0
   272
void DKeyboardTemplate::PowerUp()
sl@0
   273
	{
sl@0
   274
	iPowerUpDfc.Enque();	// schedules DFC to execute on this driver's thread
sl@0
   275
	}
sl@0
   276
sl@0
   277
void DKeyboardTemplate::PowerUpDfc()
sl@0
   278
	{
sl@0
   279
	__KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerUpDfc()"));
sl@0
   280
	KeyboardOn();
sl@0
   281
	PowerUpDone();		// must be called from a different thread than PowerUp()
sl@0
   282
	}
sl@0
   283
sl@0
   284
void DKeyboardTemplate::KeyboardOn()
sl@0
   285
	{
sl@0
   286
	__KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOn() iKeyboardOn=%d", iKeyboardOn));
sl@0
   287
sl@0
   288
	if (!iKeyboardOn)	// may be powered up from Power Manager or HAL
sl@0
   289
		{
sl@0
   290
		KeyboardPowerUp();
sl@0
   291
		}
sl@0
   292
	}
sl@0
   293
sl@0
   294
void DKeyboardTemplate::PowerDown(TPowerState)
sl@0
   295
	{
sl@0
   296
	iPowerDownDfc.Enque();	// schedules DFC to execute on this driver's thread
sl@0
   297
	}
sl@0
   298
sl@0
   299
void DKeyboardTemplate::PowerDownDfc()
sl@0
   300
	{
sl@0
   301
	__KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardTemplate::PowerDownDfc()"));
sl@0
   302
	KeyboardOff();
sl@0
   303
	PowerDownDone();		// must be called from a different thread than PowerDown()
sl@0
   304
	}
sl@0
   305
sl@0
   306
void DKeyboardTemplate::KeyboardOff()
sl@0
   307
	{
sl@0
   308
	__KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardTemplate::KeyboardOff() iKeyboardOn=%d", iKeyboardOn));
sl@0
   309
sl@0
   310
	if (iKeyboardOn)	// may have already been powered down by the HAL
sl@0
   311
		{
sl@0
   312
		iKeyboardOn = EFalse;
sl@0
   313
		Interrupt::Disable(KIntIdKeyboard);
sl@0
   314
		}
sl@0
   315
	iEventDfc.Cancel();
sl@0
   316
	}
sl@0
   317
sl@0
   318
void DKeyboardTemplate::HandleMsg(TMessageBase* aMsg)
sl@0
   319
	{
sl@0
   320
	if (aMsg->iValue)
sl@0
   321
		KeyboardOn();
sl@0
   322
	else
sl@0
   323
		KeyboardOff();
sl@0
   324
	aMsg->Complete(KErrNone,ETrue);
sl@0
   325
	}
sl@0
   326
sl@0
   327
void DKeyboardTemplate::KeyboardInfo(TKeyboardInfoV01& aInfo)
sl@0
   328
	{
sl@0
   329
	__KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::KeyboardInfo"));
sl@0
   330
sl@0
   331
	aInfo.iKeyboardType=KConfigKeyboardType;
sl@0
   332
	aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys;
sl@0
   333
	aInfo.iAppsKeys=KConfigKeyboardAppsKeys;
sl@0
   334
	}
sl@0
   335
sl@0
   336
TInt DKeyboardTemplate::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
sl@0
   337
	{
sl@0
   338
	TInt r=KErrNone;
sl@0
   339
	__KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardTemplate::HalFunction %d", aFunction));
sl@0
   340
	switch(aFunction)
sl@0
   341
		{
sl@0
   342
		case EKeyboardHalKeyboardInfo:
sl@0
   343
			{
sl@0
   344
			TPckgBuf<TKeyboardInfoV01> kPckg;
sl@0
   345
			KeyboardInfo(kPckg());
sl@0
   346
			Kern::InfoCopy(*(TDes8*)a1,kPckg);
sl@0
   347
			break;
sl@0
   348
			}
sl@0
   349
		case EKeyboardHalSetKeyboardState:
sl@0
   350
			{
sl@0
   351
			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState")))
sl@0
   352
				return KErrPermissionDenied;
sl@0
   353
			if ((TBool)a1)
sl@0
   354
				{
sl@0
   355
				TThreadMessage& m=Kern::Message();
sl@0
   356
				m.iValue = ETrue;
sl@0
   357
				m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered up
sl@0
   358
				}
sl@0
   359
			else
sl@0
   360
				{
sl@0
   361
				TThreadMessage& m=Kern::Message();
sl@0
   362
				m.iValue = EFalse;
sl@0
   363
				m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered down
sl@0
   364
				}
sl@0
   365
			}
sl@0
   366
			break;
sl@0
   367
		case EKeyboardHalKeyboardState:
sl@0
   368
			kumemput32(a1, &iKeyboardOn, sizeof(TBool));
sl@0
   369
			break;
sl@0
   370
		default:
sl@0
   371
			r=KErrNotSupported;
sl@0
   372
			break;
sl@0
   373
		}
sl@0
   374
	return r;
sl@0
   375
	}
sl@0
   376
sl@0
   377
DECLARE_STANDARD_EXTENSION()
sl@0
   378
	{
sl@0
   379
	__KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver"));
sl@0
   380
sl@0
   381
	// create keyboard driver
sl@0
   382
	TInt r=KErrNoMemory;
sl@0
   383
	DKeyboardTemplate* pK=new DKeyboardTemplate;
sl@0
   384
	if (pK)
sl@0
   385
		r=pK->Create();
sl@0
   386
sl@0
   387
	__KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
sl@0
   388
	return r;
sl@0
   389
	}