omap3530/shared/serialkeyb/serialkeyboard.cpp
changeset 0 6663340f3fc9
child 21 524118fd998f
equal deleted inserted replaced
-1:000000000000 0:6663340f3fc9
       
     1 // Copyright (c) 2007-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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // omap3530/shared/serialkeyb/serialkeyboard.mmp
       
    15 // Simple serial keyboard implementation for Beagle baseport
       
    16 //
       
    17 
       
    18 #include <platform.h>
       
    19 #include <e32keys.h>
       
    20 #include <assp/omap3530_assp/omap3530_assp_priv.h>
       
    21 #include <assp/omap3530_assp/omap3530_uart.h>
       
    22 //#include <drivers/resourceman.h>
       
    23 
       
    24 const TInt KMagicCrashValue = 15;
       
    25 
       
    26 
       
    27 #define SHIFTED(x)   (0x8000|(x))
       
    28 #define ISSHIFTED(x) (0x8000&(x))
       
    29 #define CTRLED(x)    (0x2000|(x))
       
    30 #define ISCTRL(x)  (0x2000&(x))
       
    31 #define FUNCED(x)    (0x4000|(x))
       
    32 #define ISFUNC(x)  (0x4000&(x))
       
    33 #define STDKEY(x)    (0x1FFF&(x))
       
    34 
       
    35 static const TUint16 KScanCode[] =
       
    36 	{
       
    37 	/*00*/	EStdKeyNull,
       
    38 	/*01*/	EStdKeyHome,				// ^A
       
    39 	/*02*/	EStdKeyLeftArrow,			// ^B
       
    40 	/*03*/	EStdKeyEscape,				// ^C
       
    41 	/*04*/	SHIFTED(EStdKeyDownArrow),	// ^D - move window down
       
    42 	/*05*/	EStdKeyEnd,					// ^E
       
    43 	/*06*/	EStdKeyRightArrow,			// ^F
       
    44 	/*07*/	EStdKeyNull,
       
    45 	/*08*/	EStdKeyBackspace,			// ^H - Reserved!
       
    46 	/*09*/	EStdKeyTab,					// ^I - Reserved!
       
    47 	/*0a*/	EStdKeyNull,
       
    48 	/*0b*/	EStdKeyIncContrast,			// ^K
       
    49 	/*0c*/	EStdKeyDecContrast,			// ^L
       
    50 	/*0d*/	EStdKeyEnter,				// ^M - Reserved!
       
    51 	/*0e*/	EStdKeyDownArrow,			// ^N
       
    52 	/*0f*/	EStdKeyNull,				// ^O = instant death
       
    53 	/*10*/	EStdKeyUpArrow,				// ^P
       
    54 	/*11*/	CTRLED(EStdKeyLeftArrow),	// ^Q - make window narrower
       
    55 	/*12*/	CTRLED(FUNCED('5')),		// ^R - rotate windows in text window server
       
    56 	/*13*/	EStdKeyNull,
       
    57 	/*14*/	CTRLED(EStdKeyDownArrow),	// ^T - make window taller
       
    58 	/*15*/	SHIFTED(EStdKeyUpArrow),	// ^U - move window up
       
    59 	/*16*/	EStdKeyNull,
       
    60 	/*17*/	CTRLED(EStdKeyRightArrow),	// ^W - make window wider
       
    61 	/*18*/	SHIFTED(EStdKeyRightArrow),	// ^X - move window right
       
    62 	/*19*/	CTRLED(EStdKeyUpArrow),		// ^Y - make window shorter
       
    63 	/*1a*/	SHIFTED(EStdKeyLeftArrow),	// ^Z - move window left
       
    64 	/*1b*/	EStdKeyEscape,				// ^[ - Reserved!
       
    65 	/*1c*/	EStdKeyNull,
       
    66 	/*1d*/	EStdKeyNull,
       
    67 	/*1e*/	EStdKeyNull,
       
    68 	/*1f*/	EStdKeyNull,
       
    69 	/*20*/	EStdKeySpace,
       
    70 	/*21*/	SHIFTED('1'),		// !
       
    71 	/*22*/	SHIFTED('2'),		// "
       
    72 	/*23*/	EStdKeyHash,		// #
       
    73 	/*24*/	SHIFTED('4'),		// $
       
    74 	/*25*/	SHIFTED('5'),		// %
       
    75 	/*26*/	SHIFTED('7'),		// &
       
    76 	/*27*/	EStdKeySingleQuote,
       
    77 	/*28*/	SHIFTED('9'),		// (
       
    78 	/*29*/	SHIFTED('0'),		// )
       
    79 	/*2a*/	SHIFTED('8'),		// *
       
    80 	/*2b*/	SHIFTED(EStdKeyEquals),	// +
       
    81 	/*2c*/	EStdKeyComma,
       
    82 	/*2d*/	EStdKeyMinus,
       
    83 	/*2e*/	EStdKeyFullStop,
       
    84 	/*2f*/	EStdKeyForwardSlash,
       
    85 	/*30*/	'0',
       
    86 	/*31*/	'1',
       
    87 	/*32*/	'2',
       
    88 	/*33*/	'3',
       
    89 	/*34*/	'4',
       
    90 	/*35*/	'5',
       
    91 	/*36*/	'6',
       
    92 	/*37*/	'7',
       
    93 	/*38*/	'8',
       
    94 	/*39*/	'9',
       
    95 	/*3a*/	SHIFTED(EStdKeySemiColon),	// :
       
    96 	/*3b*/	EStdKeySemiColon,
       
    97 	/*3c*/	SHIFTED(EStdKeyComma),		// <
       
    98 	/*3d*/	EStdKeyEquals,
       
    99 	/*3e*/	SHIFTED(EStdKeyFullStop),	// >
       
   100 	/*3f*/	SHIFTED(EStdKeyForwardSlash),	// ?
       
   101 	/*40*/	SHIFTED(EStdKeySingleQuote),	// @
       
   102 	/*41*/	SHIFTED('A'),
       
   103 	/*42*/	SHIFTED('B'),
       
   104 	/*43*/	SHIFTED('C'),
       
   105 	/*44*/	SHIFTED('D'),
       
   106 	/*45*/	SHIFTED('E'),
       
   107 	/*46*/	SHIFTED('F'),
       
   108 	/*47*/	SHIFTED('G'),
       
   109 	/*48*/	SHIFTED('H'),
       
   110 	/*49*/	SHIFTED('I'),
       
   111 	/*4a*/	SHIFTED('J'),
       
   112 	/*4b*/	SHIFTED('K'),
       
   113 	/*4c*/	SHIFTED('L'),
       
   114 	/*4d*/	SHIFTED('M'),
       
   115 	/*4e*/	SHIFTED('N'),
       
   116 	/*4f*/	SHIFTED('O'),
       
   117 	/*50*/	SHIFTED('P'),
       
   118 	/*51*/	SHIFTED('Q'),
       
   119 	/*52*/	SHIFTED('R'),
       
   120 	/*53*/	SHIFTED('S'),
       
   121 	/*54*/	SHIFTED('T'),
       
   122 	/*55*/	SHIFTED('U'),
       
   123 	/*56*/	SHIFTED('V'),
       
   124 	/*57*/	SHIFTED('W'),
       
   125 	/*58*/	SHIFTED('X'),
       
   126 	/*59*/	SHIFTED('Y'),
       
   127 	/*5a*/	SHIFTED('Z'),
       
   128 	/*5b*/	EStdKeySquareBracketLeft,
       
   129 	/*5c*/	EStdKeyBackSlash,
       
   130 	/*5d*/	EStdKeySquareBracketRight,
       
   131 	/*5e*/	SHIFTED('6'),			// ^
       
   132 	/*5f*/	SHIFTED(EStdKeyMinus),	// _
       
   133 	/*60*/	EStdKeyBacklightToggle,	// Actually `
       
   134 	/*61*/	'A',
       
   135 	/*62*/	'B',
       
   136 	/*63*/	'C',
       
   137 	/*64*/	'D',
       
   138 	/*65*/	'E',
       
   139 	/*66*/	'F',
       
   140 	/*67*/	'G',
       
   141 	/*68*/	'H',
       
   142 	/*69*/	'I',
       
   143 	/*6a*/	'J',
       
   144 	/*6b*/	'K',
       
   145 	/*6c*/	'L',
       
   146 	/*6d*/	'M',
       
   147 	/*6e*/	'N',
       
   148 	/*6f*/	'O',
       
   149 	/*70*/	'P',
       
   150 	/*71*/	'Q',
       
   151 	/*72*/	'R',
       
   152 	/*73*/	'S',
       
   153 	/*74*/	'T',
       
   154 	/*75*/	'U',
       
   155 	/*76*/	'V',
       
   156 	/*77*/	'W',
       
   157 	/*78*/	'X',
       
   158 	/*79*/	'Y',
       
   159 	/*7a*/	'Z',
       
   160 	/*7b*/	SHIFTED(EStdKeySquareBracketLeft),
       
   161 	/*7c*/	SHIFTED(EStdKeyBackSlash),
       
   162 	/*7d*/	SHIFTED(EStdKeySquareBracketRight),
       
   163 	/*7e*/	SHIFTED(EStdKeyHash),
       
   164 	/*7f*/	EKeyDelete
       
   165 	};
       
   166 
       
   167 static const TUint16 KEscapedScanCode[] =
       
   168 	{
       
   169 	EStdKeyUpArrow,
       
   170 	EStdKeyDownArrow,
       
   171 	EStdKeyRightArrow,
       
   172 	EStdKeyLeftArrow
       
   173 	};
       
   174 
       
   175 const TUint8 KEscapeChar = 0x1b;
       
   176 const TUint8 KEscapeBase = 0x41;
       
   177 const TUint8 KEscapeCount = sizeof(KEscapedScanCode) / sizeof(KEscapedScanCode[0]);
       
   178 const TUint16 KEscapeScanCode = EStdKeyEscape;
       
   179 
       
   180 NONSHARABLE_CLASS(TSerialKeyboard) : public DBase
       
   181 	{
       
   182 public:
       
   183 	inline TSerialKeyboard();
       
   184 	TInt Create();
       
   185 
       
   186 private:
       
   187 	static void UartIsr( TAny* aParam );
       
   188 	static void AddKeyDfc( TAny* aParam );
       
   189 	void AddKey( TUint aKey );
       
   190 	
       
   191 
       
   192 private:
       
   193 	enum TState
       
   194 		{
       
   195 		ENormal,
       
   196 		EEscaping1,
       
   197 		EEscaping2
       
   198 		};
       
   199 
       
   200 	TDfc				iAddKeyDfc;
       
   201 	Omap3530Uart::TUart	iUart;
       
   202 	TUint				iPrmClientId;
       
   203 	TState				iState : 8;
       
   204 	TUint8				iKey;
       
   205 	};
       
   206 
       
   207 inline TSerialKeyboard::TSerialKeyboard()
       
   208 :	iAddKeyDfc( AddKeyDfc, this, Kern::DfcQue0(), 1 ),
       
   209 	iUart( Omap3530Assp::DebugPortNumber() ),
       
   210 	iState( ENormal )
       
   211 	{
       
   212 	// Convert the scan rate from milliseconds to nanokernel ticks (normally 1/64 of a second)
       
   213 	}
       
   214 
       
   215 TInt TSerialKeyboard::Create()
       
   216 	{
       
   217 	TInt r = KErrNone;
       
   218 
       
   219 	const Omap3530Uart::TUartNumber portNumber( Omap3530Assp::DebugPortNumber() );
       
   220 	
       
   221 	if( portNumber >= 0 )
       
   222 		{
       
   223 		// Register with the power resource manager
       
   224 		_LIT( KName, "serkey" );
       
   225 		/*r = PowerResourceManager::RegisterClient( iPrmClientId, KName );
       
   226 		if( r != KErrNone )
       
   227 			{
       
   228 			return r;
       
   229 			}*/
       
   230 
       
   231 		__KTRACE_OPT(KBOOT,Kern::Printf("+TSerialKeyboardl::Create:PRM client ID=%x", iPrmClientId )) ;
       
   232 		Kern::Printf("+TSerialKeyboardl::Create:PRM client ID=%x", iPrmClientId );
       
   233 
       
   234  		r = Interrupt::Bind( iUart.InterruptId(), UartIsr, this );
       
   235 		if ( r < 0 )
       
   236  			{
       
   237 			return r;
       
   238  			}
       
   239 
       
   240 		// Ask power resource manager to turn on clocks to the UART
       
   241 		// (this could take some time but we're not in any hurry)
       
   242 		/*r = PowerResourceManager::ChangeResourceState( iPrmClientId, iUart.PrmFunctionClk(), Prcm::EClkOn );
       
   243 		if( KErrNone != r )
       
   244 			{
       
   245 			return r;
       
   246 			}*/
       
   247 			
       
   248 		/*r = PowerResourceManager::ChangeResourceState( iPrmClientId, iUart.PrmInterfaceClk(), Prcm::EClkOn );
       
   249 		if( KErrNone != r )
       
   250 			{
       
   251 			return r;
       
   252 			}*/
       
   253 
       
   254 		// We can assume that the debug output code has already initialized the UART, we just need to prepare it for RX
       
   255 		iUart.EnableFifo( Omap3530Uart::TUart::EEnabled, Omap3530Uart::TUart::ETriggerUnchanged, Omap3530Uart::TUart::ETrigger8 );
       
   256 		iUart.EnableInterrupt( Omap3530Uart::TUart::EIntRhr );
       
   257 
       
   258 		Interrupt::Enable( iUart.InterruptId() );
       
   259 		}
       
   260 
       
   261 	return r;
       
   262 	}
       
   263 
       
   264 void TSerialKeyboard::UartIsr( TAny* aParam )
       
   265 	{
       
   266 	TSerialKeyboard* self = reinterpret_cast<TSerialKeyboard*>( aParam );
       
   267 	
       
   268 	const TUint iir = Omap3530Uart::IIR::iMem.Read( self->iUart );
       
   269 
       
   270 	if ( 0 == (iir bitand Omap3530Uart::IIR::IT_PENDING::KMask) )
       
   271 		{
       
   272 		const TUint pending = iir bitand Omap3530Uart::IIR::IT_TYPE::KFieldMask;
       
   273 
       
   274 		// Although the TI datasheet descrivwed IT_TYPE as being an enumerated priority-decoded interrupt
       
   275 		// it appears to actually be a bitmask of active interrupt sources
       
   276 		if ( (pending bitand Omap3530Uart::IIR::IT_TYPE::ERHR) || (pending bitand Omap3530Uart::IIR::IT_TYPE::ERxLineStatus) )
       
   277 			{
       
   278 			TUint byte = self->iUart.Read();
       
   279 			
       
   280 			if( KMagicCrashValue == byte )
       
   281 				{
       
   282 				Kern::Fault( "SERKEY-FORCED", 0 );
       
   283 				}
       
   284 			else
       
   285 				{
       
   286 				self->iKey = byte;
       
   287 				self->iAddKeyDfc.Add();
       
   288 				Interrupt::Disable( self->iUart.InterruptId() );
       
   289 				}
       
   290 			}
       
   291 		}
       
   292 	}
       
   293 
       
   294 void TSerialKeyboard::AddKeyDfc( TAny* aParam )
       
   295 	{
       
   296 	TSerialKeyboard* self = reinterpret_cast<TSerialKeyboard*>( aParam );
       
   297 
       
   298 	switch ( self->iState )
       
   299 		{
       
   300 	case ENormal:
       
   301 		if ( self->iKey == KEscapeChar )
       
   302 			{
       
   303 			self->iState = EEscaping1;
       
   304 			}
       
   305 		else
       
   306 			{
       
   307 			self->AddKey( KScanCode[ self->iKey ] );
       
   308 			}
       
   309 		break;
       
   310 
       
   311 	case EEscaping1:
       
   312 		if ( self->iKey == KEscapeChar )
       
   313 			{
       
   314 			self->iState = EEscaping2;
       
   315 			}
       
   316 		else
       
   317 			{
       
   318 			self->AddKey( KEscapeScanCode );
       
   319 			self->AddKey( KScanCode[ self->iKey ] );
       
   320 			self->iState = ENormal;
       
   321 			}
       
   322 		break;
       
   323 
       
   324 	case EEscaping2:
       
   325 		{
       
   326 		TInt index = self->iKey - KEscapeBase;
       
   327 		
       
   328 		if ( (index >= 0) && (index < KEscapeCount) )
       
   329 			{
       
   330 			self->AddKey( KEscapedScanCode[ index ] );
       
   331 			}
       
   332 		else
       
   333 			{
       
   334 			self->AddKey( KEscapeScanCode );
       
   335 			self->AddKey( KScanCode[ self->iKey ] );
       
   336 			}
       
   337 		self->iState = ENormal;
       
   338 		}
       
   339 		break;
       
   340 
       
   341 	default:
       
   342 		self->iState = ENormal;
       
   343 		break;
       
   344 		};
       
   345 
       
   346 	Interrupt::Enable( self->iUart.InterruptId() );
       
   347 	}
       
   348 
       
   349 void TSerialKeyboard::AddKey( TUint aKey )
       
   350 	{
       
   351 	const TBool shifted = ISSHIFTED(aKey);
       
   352 	const TBool ctrl = ISCTRL(aKey);
       
   353 	const TBool func = ISFUNC(aKey);
       
   354 	const TUint8 stdKey = STDKEY(aKey);
       
   355 
       
   356 	TRawEvent e;
       
   357 
       
   358 	if ( func )
       
   359 		{
       
   360 		e.Set( TRawEvent::EKeyDown, EStdKeyRightFunc, 0 );
       
   361 		Kern::AddEvent( e );
       
   362 		}
       
   363 	
       
   364 	if ( ctrl )
       
   365 		{
       
   366 		e.Set( TRawEvent::EKeyDown, EStdKeyRightCtrl, 0 );
       
   367 		Kern::AddEvent( e );
       
   368 		}
       
   369 
       
   370 	if ( shifted )
       
   371 		{
       
   372 		e.Set( TRawEvent::EKeyDown, EStdKeyRightShift, 0 );
       
   373 		Kern::AddEvent( e );
       
   374 		}
       
   375 
       
   376 	e.Set( TRawEvent::EKeyDown, stdKey, 0 );
       
   377 	Kern::AddEvent( e );
       
   378 	e.Set( TRawEvent::EKeyUp, stdKey, 0 );
       
   379 	Kern::AddEvent( e );
       
   380 
       
   381 	if ( shifted )
       
   382 		{
       
   383 		e.Set( TRawEvent::EKeyUp, EStdKeyRightShift, 0 );
       
   384 		Kern::AddEvent( e );
       
   385 		}
       
   386 
       
   387 	if ( ctrl )
       
   388 		{
       
   389 		e.Set( TRawEvent::EKeyUp, EStdKeyRightCtrl, 0 );
       
   390 		Kern::AddEvent( e );
       
   391 		}
       
   392 
       
   393 	if ( func )
       
   394 		{
       
   395 		e.Set( TRawEvent::EKeyUp, EStdKeyRightFunc, 0 );
       
   396 		Kern::AddEvent( e );
       
   397 		}
       
   398 	}
       
   399 
       
   400 
       
   401 DECLARE_STANDARD_EXTENSION()
       
   402 	{
       
   403 	__KTRACE_OPT(KEXTENSION,Kern::Printf("Starting serial keyboard driver"));
       
   404 
       
   405 	TInt r = KErrNoMemory;
       
   406 	TSerialKeyboard* keyboard = new TSerialKeyboard;
       
   407 	if ( keyboard )
       
   408 		{
       
   409 		r = keyboard->Create();
       
   410 		}
       
   411 
       
   412 	__KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
       
   413 	return r;
       
   414 	}