navienginebsp/naviengine_assp/uart/vserialkeyb.cpp
changeset 0 5de814552237
equal deleted inserted replaced
-1:000000000000 0:5de814552237
       
     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 * naviengine_assp\uart\vserialkeyb.cpp
       
    16 * Serial keyboard driver
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 /**
       
    23  @file
       
    24  @internalTechnology
       
    25 */
       
    26 
       
    27 #include <e32keys.h>
       
    28 #include <comm.h>
       
    29 #include <assp.h>
       
    30 #include "../naviengine_priv.h"
       
    31 #include "../naviengine.h"
       
    32 #include "uart16550_ne.h"
       
    33 #include "vserialkeyb.h"
       
    34 
       
    35 
       
    36 #define SHIFTED(x)   (0x8000|(x))
       
    37 #define ISSHIFTED(x) (0x8000&(x))
       
    38 #define FUNCED(x)    (0x4000|(x))
       
    39 #define ISFUNCED(x)  (0x4000&(x))
       
    40 #define CTRLED(x)    (0x2000|(x))
       
    41 #define ISCTRLED(x)  (0x2000&(x))
       
    42 #define STDKEY(x)    (0x1FFF&(x))
       
    43 
       
    44 /*
       
    45  *  Definition of the converting table for the receive char
       
    46  *  through the serial port.
       
    47  *
       
    48  */
       
    49 const TUint16 convertCodeSerial[] =
       
    50 {
       
    51 /*00*/	EStdKeyNull,
       
    52 /*01*/	EStdKeyHome,				// ^A
       
    53 /*02*/	EStdKeyLeftArrow,			// ^B
       
    54 /*03*/	EStdKeyEscape,				// ^C
       
    55 /*04*/	SHIFTED(EStdKeyDownArrow),	// ^D - move window down
       
    56 /*05*/	EStdKeyEnd,					// ^E
       
    57 /*06*/	EStdKeyRightArrow,			// ^F
       
    58 /*07*/	EStdKeyNull,
       
    59 /*08*/	EStdKeyBackspace,			// ^H - Reserved!
       
    60 /*09*/	EStdKeyTab,					// ^I - Reserved!
       
    61 /*0a*/	EStdKeyNull,
       
    62 /*0b*/	EStdKeyIncContrast,			// ^K
       
    63 /*0c*/	EStdKeyDecContrast,			// ^L
       
    64 /*0d*/	EStdKeyEnter,				// ^M - Reserved!
       
    65 /*0e*/	EStdKeyDownArrow,			// ^N
       
    66 /*0f*/	EStdKeyNull,				// ^O = instant death
       
    67 /*10*/	EStdKeyUpArrow,				// ^P
       
    68 /*11*/	CTRLED(EStdKeyLeftArrow),	// ^Q - make window narrower
       
    69 /*12*/	CTRLED(FUNCED('5')),		// ^R - rotate windows in text window server
       
    70 /*13*/	EStdKeyNull,
       
    71 /*14*/	CTRLED(EStdKeyDownArrow),	// ^T - make window taller
       
    72 /*15*/	SHIFTED(EStdKeyUpArrow),	// ^U - move window up
       
    73 /*16*/	EStdKeyNull,
       
    74 /*17*/	CTRLED(EStdKeyRightArrow),	// ^W - make window wider
       
    75 /*18*/	SHIFTED(EStdKeyRightArrow),	// ^X - move window right
       
    76 /*19*/	CTRLED(EStdKeyUpArrow),		// ^Y - make window shorter
       
    77 /*1a*/	SHIFTED(EStdKeyLeftArrow),	// ^Z - move window left
       
    78 /*1b*/	EStdKeyEscape,				// ^[ - Reserved!
       
    79 /*1c*/	EStdKeyNull,
       
    80 /*1d*/	EStdKeyNull,
       
    81 /*1e*/	EStdKeyNull,
       
    82 /*1f*/	EStdKeyNull,
       
    83 /*20*/	EStdKeySpace,
       
    84 /*21*/	SHIFTED('1'),		// !
       
    85 /*22*/	SHIFTED('2'),		// "
       
    86 /*23*/	EStdKeyHash,		// #
       
    87 /*24*/	SHIFTED('4'),		// $
       
    88 /*25*/	SHIFTED('5'),		// %
       
    89 /*26*/	SHIFTED('7'),		// &
       
    90 /*27*/	EStdKeySingleQuote,
       
    91 /*28*/	SHIFTED('9'),		// (
       
    92 /*29*/	SHIFTED('0'),		// )
       
    93 /*2a*/	SHIFTED('8'),		// *
       
    94 /*2b*/	SHIFTED(EStdKeyEquals),	// +
       
    95 /*2c*/	EStdKeyComma,
       
    96 /*2d*/	EStdKeyMinus,
       
    97 /*2e*/	EStdKeyFullStop,
       
    98 /*2f*/	EStdKeyForwardSlash,
       
    99 /*30*/	'0',
       
   100 /*31*/	'1',
       
   101 /*32*/	'2',
       
   102 /*33*/	'3',
       
   103 /*34*/	'4',
       
   104 /*35*/	'5',
       
   105 /*36*/	'6',
       
   106 /*37*/	'7',
       
   107 /*38*/	'8',
       
   108 /*39*/	'9',
       
   109 /*3a*/	SHIFTED(EStdKeySemiColon),	// :
       
   110 /*3b*/	EStdKeySemiColon,
       
   111 /*3c*/	SHIFTED(EStdKeyComma),		// <
       
   112 /*3d*/	EStdKeyEquals,
       
   113 /*3e*/	SHIFTED(EStdKeyFullStop),	// >
       
   114 /*3f*/	SHIFTED(EStdKeyForwardSlash),	// ?
       
   115 /*40*/	SHIFTED(EStdKeySingleQuote),	// @
       
   116 /*41*/	SHIFTED('A'),
       
   117 /*42*/	SHIFTED('B'),
       
   118 /*43*/	SHIFTED('C'),
       
   119 /*44*/	SHIFTED('D'),
       
   120 /*45*/	SHIFTED('E'),
       
   121 /*46*/	SHIFTED('F'),
       
   122 /*47*/	SHIFTED('G'),
       
   123 /*48*/	SHIFTED('H'),
       
   124 /*49*/	SHIFTED('I'),
       
   125 /*4a*/	SHIFTED('J'),
       
   126 /*4b*/	SHIFTED('K'),
       
   127 /*4c*/	SHIFTED('L'),
       
   128 /*4d*/	SHIFTED('M'),
       
   129 /*4e*/	SHIFTED('N'),
       
   130 /*4f*/	SHIFTED('O'),
       
   131 /*50*/	SHIFTED('P'),
       
   132 /*51*/	SHIFTED('Q'),
       
   133 /*52*/	SHIFTED('R'),
       
   134 /*53*/	SHIFTED('S'),
       
   135 /*54*/	SHIFTED('T'),
       
   136 /*55*/	SHIFTED('U'),
       
   137 /*56*/	SHIFTED('V'),
       
   138 /*57*/	SHIFTED('W'),
       
   139 /*58*/	SHIFTED('X'),
       
   140 /*59*/	SHIFTED('Y'),
       
   141 /*5a*/	SHIFTED('Z'),
       
   142 /*5b*/	EStdKeySquareBracketLeft,
       
   143 /*5c*/	EStdKeyBackSlash,
       
   144 /*5d*/	EStdKeySquareBracketRight,
       
   145 /*5e*/	SHIFTED('6'),			// ^
       
   146 /*5f*/	SHIFTED(EStdKeyMinus),	// _
       
   147 /*60*/	EStdKeyBacklightToggle,	// Actually `
       
   148 /*61*/	'A',
       
   149 /*62*/	'B',
       
   150 /*63*/	'C',
       
   151 /*64*/	'D',
       
   152 /*65*/	'E',
       
   153 /*66*/	'F',
       
   154 /*67*/	'G',
       
   155 /*68*/	'H',
       
   156 /*69*/	'I',
       
   157 /*6a*/	'J',
       
   158 /*6b*/	'K',
       
   159 /*6c*/	'L',
       
   160 /*6d*/	'M',
       
   161 /*6e*/	'N',
       
   162 /*6f*/	'O',
       
   163 /*70*/	'P',
       
   164 /*71*/	'Q',
       
   165 /*72*/	'R',
       
   166 /*73*/	'S',
       
   167 /*74*/	'T',
       
   168 /*75*/	'U',
       
   169 /*76*/	'V',
       
   170 /*77*/	'W',
       
   171 /*78*/	'X',
       
   172 /*79*/	'Y',
       
   173 /*7a*/	'Z',
       
   174 /*7b*/	SHIFTED(EStdKeySquareBracketLeft),
       
   175 /*7c*/	SHIFTED(EStdKeyBackSlash),
       
   176 /*7d*/	SHIFTED(EStdKeySquareBracketRight),
       
   177 /*7e*/	SHIFTED(EStdKeyHash),
       
   178 /*7f*/	EKeyDelete
       
   179 }; /* end of array - convertCodeSerial - */
       
   180 
       
   181 typedef struct
       
   182 	{
       
   183 	TUint8 seq[maxSeq+1];
       
   184 	TUint32 convertedCode;
       
   185 	} keyType;
       
   186 
       
   187 const keyType escapeCodes[] =
       
   188 {
       
   189 	// Three escape codes in a row that completes a sequence
       
   190 	{ {0x1b, 0x4f, 0x50, 0,    0,    0,}, EStdKeyMenu,                       }, // F1 gives menu key
       
   191 	{ {0x1b, 0x4f, 0x51, 0,    0,    0,}, EStdKeyF2,                         }, // F2
       
   192 	{ {0x1b, 0x4f, 0x52, 0,    0,    0,}, EStdKeyF3,                         }, // F3
       
   193 	{ {0x1b, 0x4f, 0x53, 0,    0,    0,}, EStdKeyF4,                         }, // F4
       
   194 	{ {0x1b, 0x4f, 0x74, 0,    0,    0,}, EStdKeyDevice3,                    }, // F5 gives S60 centre press
       
   195 	{ {0x1b, 0x4f, 0x75, 0,    0,    0,}, EStdKeyDevice0,                    }, // F6 gives S60 left softkey
       
   196 	{ {0x1b, 0x4f, 0x76, 0,    0,    0,}, EStdKeyDevice1,                    }, // F7 gives S60 right softkey
       
   197 	{ {0x1b, 0x4f, 0x6c, 0,    0,    0,}, EStdKeyApplication0,               }, // F8 gives S60 application softkey
       
   198 	{ {0x1b, 0x4f, 0x77, 0,    0,    0,}, EStdKeyF9,                         }, // F9
       
   199 	{ {0x1b, 0x4f, 0x78, 0,    0,    0,}, EStdKeyF10,                        }, // F10
       
   200 
       
   201 	{ {0x1b, 0x5b, 0x41, 0,    0,    0,}, EStdKeyUpArrow,                    }, // Arrow keys
       
   202 	{ {0x1b, 0x5b, 0x42, 0,    0,    0,}, EStdKeyDownArrow,                  }, // Arrow keys
       
   203 	{ {0x1b, 0x5b, 0x43, 0,    0,    0,}, EStdKeyRightArrow,                 }, // Arrow keys
       
   204 	{ {0x1b, 0x5b, 0x44, 0,    0,    0,}, EStdKeyLeftArrow,                  }, // Arrow keys
       
   205 
       
   206 	// Four escape codes in a row that completes a sequence
       
   207 	{ {0x1b, 0x5b, 0x31, 0x7e, 0,    0,}, EStdKeyHome,                       }, // Home key
       
   208 	{ {0x1b, 0x5b, 0x34, 0x7e, 0,    0,}, EStdKeyEnd,                        }, // End key
       
   209 	{ {0x1b, 0x5b, 0x35, 0x7e, 0,    0,}, EStdKeyPageUp,                     }, // Page Up key
       
   210 	{ {0x1b, 0x5b, 0x36, 0x7e, 0,    0,}, EStdKeyPageDown,                   }, // Page down key
       
   211 	{ {0x1b, 0x5b, 0x32, 0x7e, 0,    0,}, EStdKeyInsert,                     }, // Page down key
       
   212 
       
   213 	// Five escape codes in a row that completes a sequence
       
   214 	{ {0x1b, 0x5b, 0x32, 0x33, 0x7e, 0,}, EStdKeyF11,                        }, // F11
       
   215 	{ {0x1b, 0x5b, 0x32, 0x34, 0x7e, 0,}, EStdKeyF12,                        }, // F12
       
   216 
       
   217 	// end of table - should be all zeros
       
   218     { {0,    0,    0,    0,    0,    0,}, 0,                                 }
       
   219 };
       
   220 
       
   221 TSerialKeyboard::TSerialKeyboard()
       
   222 				: iKeyDfc( KeyDfcFn, this, Kern::DfcQue0(), 1 ), iSeqNum(0)
       
   223 	{
       
   224     for (TUint i=0; i<maxSeq; i++)
       
   225         {
       
   226         iCode[i]=0;
       
   227         }
       
   228 	}
       
   229  
       
   230 TInt TSerialKeyboard::Create()
       
   231 	{
       
   232 //	__KTRACE_OPT(KBOOT,Kern::Printf(_L("+TKeyboardSerial::Init"))) ;
       
   233 	TUint base;
       
   234 	TUint baud;
       
   235 
       
   236 	iKeyboardPort = GetSerialPort(baud);
       
   237 
       
   238 	switch(iKeyboardPort)
       
   239 		{
       
   240 	case 1:		base=KHwBaseUart1; break;
       
   241 	case 2:		base=KHwBaseUart2; break;
       
   242 	default:	base=KHwBaseUart0;
       
   243 				iKeyboardPort = 0; //JTAG debug port, use port #0
       
   244 		}
       
   245 
       
   246 	__KTRACE_OPT(KBOOT,Kern::Printf("SERIAL KEYBOARD DRIVER: keyboard port=%d", iKeyboardPort ));
       
   247 
       
   248 	iUart = new T16550Uart;
       
   249 	if (iUart)
       
   250 		{
       
   251 		iUart->iBase = (TUint8*)base;
       
   252 		iUart->SetIER(0);
       
   253 		iUart->SetLCR(0);
       
   254 		iUart->SetFCR(0);
       
   255 		iUart->SetMCR(0);
       
   256 		}
       
   257 	else
       
   258 		return KErrNoMemory;
       
   259 	
       
   260  	iInterrupt=Interrupt::Bind(KIntIdUart0+iKeyboardPort,Isr,this);
       
   261 	if (iInterrupt<0)
       
   262  	{
       
   263 		delete iUart;
       
   264 		return iInterrupt;
       
   265  	}
       
   266    
       
   267 	iUart->SetLCR(K16550LCR_Data8|K16550LCR_DLAB);
       
   268 	iUart->SetBaudRateDivisor((baud==230400) ? KBaudRateDiv_230400 : KBaudRateDiv_default);
       
   269 	iUart->SetLCR(K16550LCR_Data8);
       
   270 	iUart->SetFCR(K16550FCR_Enable|K16550FCR_RxReset|K16550FCR_TxReset|K16550FCR_RxTrig8);
       
   271 	iUart->SetIER(K16550IER_RDAI);// enable receiving data
       
   272 
       
   273 	Interrupt::Enable(iInterrupt);
       
   274     
       
   275 	return KErrNone;
       
   276 	}
       
   277 
       
   278 
       
   279 void TSerialKeyboard::Isr( TAny* aPtr )
       
   280 	//
       
   281 	// Interrupt service routine. Called when we receive an interrupt
       
   282 	// on the IRQ line it is bound to. If it's a receive, queues DFC
       
   283 	// to post the event into the event queue.
       
   284 	//
       
   285 	{
       
   286 	TSerialKeyboard* self = (TSerialKeyboard*)aPtr;
       
   287 	T16550Uart& u=*(self->iUart);
       
   288 
       
   289 	TUint isr=u.ISR();
       
   290 	if (isr & K16550ISR_NotPending)
       
   291 		return;
       
   292 	isr&=K16550ISR_IntIdMask;
       
   293  
       
   294 	if (isr==K16550ISR_RDAI || isr==K16550ISR_RLSI)
       
   295 		{
       
   296 		__KTRACE_OPT(KEXTENSION,Kern::Printf("TSerialKeyboard::Isr:RHR"));
       
   297 		TUint ch=u.RxData();
       
   298 		if (ch==31)
       
   299 			__crash();	// CTRL-? = instant death
       
   300 		if (self->iSeqNum < maxSeq)
       
   301 			{
       
   302 			self->iCode[self->iSeqNum] = ch;
       
   303 			self->iSeqNum++;
       
   304 			self->iKeyDfc.Add();
       
   305 			Interrupt::Disable(self->iInterrupt); // Can only handle one char at a time
       
   306 			}
       
   307 		}
       
   308 	}
       
   309 	
       
   310 void TSerialKeyboard::KeyDfcFn( TAny* aPtr )
       
   311 	//
       
   312 	// DFC function. Just calls inline function KeyDfc()
       
   313 	//
       
   314 	{
       
   315 	__KTRACE_OPT(KEXTENSION,Kern::Printf("TSerialKeyboard::KeyDfcFn"));
       
   316 	((TSerialKeyboard*)aPtr)->KeyDfc();
       
   317 	}
       
   318 
       
   319 void TSerialKeyboard::AddConvertedEvent(TUint aKey)
       
   320 	{
       
   321 	// split aKey into keycode and shift, func, ctrl status
       
   322 	TBool isShifted = ISSHIFTED(aKey);
       
   323 	TBool isFunced = ISFUNCED(aKey);
       
   324 	TBool isCtrled = ISCTRLED(aKey);
       
   325 	TUint8 stdKey = STDKEY(aKey);
       
   326 
       
   327 	// post it as a sequence of events
       
   328 	TRawEvent e;
       
   329 	if (isShifted)
       
   330 		{
       
   331 		e.Set(TRawEvent::EKeyDown,EStdKeyRightShift,0);
       
   332 		Kern::AddEvent(e);
       
   333 		}
       
   334 	if (isCtrled)
       
   335 		{
       
   336 		e.Set(TRawEvent::EKeyDown,EStdKeyLeftCtrl,0);
       
   337 		Kern::AddEvent(e);
       
   338 		}
       
   339 	if (isFunced)
       
   340 		{
       
   341 		e.Set(TRawEvent::EKeyDown,EStdKeyLeftFunc,0);
       
   342 		Kern::AddEvent(e);
       
   343 		}
       
   344 
       
   345 	e.Set(TRawEvent::EKeyDown,stdKey,0);
       
   346 	Kern::AddEvent(e);
       
   347 
       
   348 	e.Set(TRawEvent::EKeyUp,stdKey,0);
       
   349 	Kern::AddEvent(e);
       
   350 
       
   351 	if (isFunced)
       
   352 		{
       
   353 		e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0);
       
   354 		Kern::AddEvent(e);
       
   355 		}
       
   356 	if (isCtrled)
       
   357 		{
       
   358 		e.Set(TRawEvent::EKeyUp,EStdKeyLeftCtrl,0);
       
   359 		Kern::AddEvent(e);
       
   360 		}
       
   361 	if (isShifted)
       
   362 		{
       
   363 		e.Set(TRawEvent::EKeyUp,EStdKeyRightShift,0);
       
   364 		Kern::AddEvent(e);
       
   365 		}
       
   366 	}
       
   367 	
       
   368 void TSerialKeyboard::AddUnconvertedEvent(TUint aKey)
       
   369 	{
       
   370 	TUint16 convertedKey = convertCodeSerial[aKey];
       
   371 	AddConvertedEvent(convertedKey);
       
   372 	}
       
   373 	
       
   374 inline void TSerialKeyboard::KeyDfc()
       
   375 	//
       
   376 	// Processes received characters
       
   377 	//
       
   378 	{
       
   379 	__KTRACE_OPT(KEXTENSION, Kern::Printf("KEY: iSeqNum=%x, key=%x", iSeqNum, iCode[iSeqNum-1]));
       
   380 
       
   381 	switch (iSeqNum)
       
   382 		{
       
   383 	case 1:
       
   384 		if (iCode[0] != EEscapingStart)
       
   385 			{
       
   386 			// Unknown escape sequence - just pass chars as normal events
       
   387 			AddUnconvertedEvent(iCode[0]);
       
   388 			iSeqNum = 0;
       
   389 			}
       
   390 		break;
       
   391 	case 2:
       
   392 		if ((iCode[1] != EEscapingType1) && iCode[1] != EEscapingType2)
       
   393 			{
       
   394 			// Unknown escape sequence - just pass chars as normal events
       
   395 			AddUnconvertedEvent(iCode[0]);
       
   396 			AddUnconvertedEvent(iCode[1]);
       
   397 			iSeqNum = 0;
       
   398 			}
       
   399 		break;
       
   400 	case 3:
       
   401 	case 4:
       
   402 	case 5:
       
   403 		{
       
   404 		TUint escCodeindex = 0; // index into the escape code list
       
   405 		TUint seqIndex     = 0; // index into the current code sequence
       
   406         TUint bestMatch    = 0; // keep a track of the best number of matches so far
       
   407 		while (escapeCodes[escCodeindex].seq[0] != 0)
       
   408 			{
       
   409 			for (seqIndex = 0; seqIndex<iSeqNum; seqIndex++)
       
   410 				{
       
   411 				if (iCode[seqIndex] != escapeCodes[escCodeindex].seq[seqIndex])
       
   412 					{
       
   413 					break; // out of for loop
       
   414 					}
       
   415 				}
       
   416 			if (seqIndex > bestMatch)
       
   417 				{
       
   418 				bestMatch = seqIndex;
       
   419 				}
       
   420 			if (escapeCodes[escCodeindex].seq[seqIndex] == 0)
       
   421 				{
       
   422 				AddConvertedEvent(escapeCodes[escCodeindex].convertedCode);
       
   423 				iSeqNum = 0;
       
   424 				break; // out of while loop
       
   425 				}
       
   426 			escCodeindex++;
       
   427 			}
       
   428 
       
   429 		if (  (bestMatch < iSeqNum) // if we couldn't match all numbers in the sequence so far, this must not be a valid sequence
       
   430 		   || (iSeqNum == maxSeq)   // if we reached the max number of codes in a sequence, this must also not be a valid sequence
       
   431 		   )
       
   432 			{
       
   433 			if (escapeCodes[escCodeindex].seq[0] == 0)
       
   434 				{
       
   435 				// Unknown escape sequence - just pass chars as normal events
       
   436 				for (TUint i=0; i < iSeqNum; i++)
       
   437 					{
       
   438 					AddUnconvertedEvent(iCode[i]);
       
   439 					}
       
   440 				}
       
   441 			iSeqNum = 0;
       
   442 			}
       
   443 		}
       
   444 		break;
       
   445 	default:
       
   446 		// Should never reach here!
       
   447 		iSeqNum = 0;
       
   448 		break;
       
   449 		};
       
   450 	Interrupt::Enable(iInterrupt); // Can handle new chars now
       
   451 	} /* end of function - KeyDfc - */
       
   452 
       
   453 //
       
   454 // Kernel Extension entry point
       
   455 //
       
   456 DECLARE_STANDARD_EXTENSION()
       
   457 	{
       
   458 	__KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver"));
       
   459 
       
   460 	// create keyboard driver
       
   461 	TInt r=KErrNoMemory;
       
   462 	TSerialKeyboard* keyboard = new TSerialKeyboard;
       
   463 	if ( keyboard )
       
   464 		{
       
   465 		r=keyboard->Create();
       
   466 		}
       
   467 
       
   468 	__KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
       
   469 	return r;
       
   470 	}