os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/variant.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1994-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 // template\template_variant\specific\variant.cpp
    15 // 
    16 //
    17 
    18 #include "variant.h"
    19 #include "mconf.h"
    20 #include <videodriver.h>
    21 #include <drivers/xyin.h>
    22 #include "template_power.h"
    23 
    24 //These constants define Custom Restart Reasons in SuperPage::iHwStartupReason
    25 const TUint KHtCustomRestartMax	  = 0xff;
    26 const TUint KHtCustomRestartShift = 8;
    27 const TUint KHtCustomRestartMask  = KHtCustomRestartMax << KHtCustomRestartShift; 
    28 
    29 const TUint KHtRestartStartupModesMax = 0xf; // Variable, platform dependant 
    30 const TUint KHtRestartStartupModesShift = 16; // Variable, platform dependant 
    31 const TUint KHtRestartStartupModesMask = KHtRestartStartupModesMax << KHtRestartStartupModesShift;
    32 
    33 void TemplateVariantFault(TInt aLine)
    34 	{
    35 	Kern::Fault("TemplateVariant",aLine);
    36 	}
    37 
    38 #define V_FAULT()	TemplateVariantFault(__LINE__)
    39 
    40 // Debug output
    41 #define XON								17
    42 #define XOFF							19
    43 #define DEBUG_XON_XOFF					0		// Non-zero if we want XON-XOFF handshaking
    44 
    45 GLDEF_D Template TheVariant;
    46 TUint32 Variant::iBaseAddress=0;
    47 
    48 TUint32 Template::HandlerData[3];
    49 SInterruptHandler Template::Handlers[ENumXInts];
    50 
    51 extern void XIntDispatch(TAny*);
    52 
    53 EXPORT_C Asic* VariantInitialise()
    54 	{
    55 	return &TheVariant;
    56 	}
    57 
    58 Template::Template()
    59 	{
    60 	iDebugInitialised=EFalse;
    61 	}
    62 
    63 //
    64 // TO DO: (optional)
    65 //
    66 // Specify the RAM zone configuration.
    67 //
    68 // The lowest addressed zone must have the highest preference as the bootstrap 
    69 // will always allocate from the lowest address up.  Once the kernel has initialised
    70 // then the zone preferences will decide from which RAM zone memory is allocated.
    71 //
    72 // 	const TUint KVariantRamZoneCount = ?;
    73 //	static const SRamZone KRamZoneConfig[KVariantRamZoneCount+1] = 
    74 //				 			iBase      iSize   		iID	iPref	iFlags
    75 //				{
    76 //				__SRAM_ZONE(0x????????, 0x???????, 	?,	?, 		?), 
    77 //				...
    78 //				__SRAM_ZONE(0x????????, 0x???????, 	?, 	?, 		?),
    79 //				__SRAM_ZONE_END, // end of zone list
    80 //				};
    81 //
    82 
    83 TInt Template::RamZoneCallback(TRamZoneOp aOp, TAny* aId, const TAny* aMasks)
    84 	{
    85 	//
    86 	// TO DO: (optional)
    87 	//
    88 	// Handle RAM zone operations requested by the kernel.
    89 	//
    90 	return TheVariant.DoRamZoneCallback(aOp, (TUint)aId, (const TUint*)aMasks);
    91 	}
    92 
    93 
    94 TInt Template::DoRamZoneCallback(TRamZoneOp aOp, TUint aId, const TUint* aMasks)
    95 	{
    96 	//
    97 	// TO DO: (optional)
    98 	//
    99 	// Handle RAM zone operations requested by the kernel.
   100 	//
   101 	// Three types of operation need to be supported:
   102 	//	ERamZoneOp_Init:		Update power state of the RAM zones after the
   103 	//							kernel has initialised.
   104 	//	ERamZoneOp_PowerUp:		A RAM zone changing from used to empty.
   105 	//	ERamZoneOp_PowerDown:	A RAM zone changing from empty to used.
   106 	//
   107  
   108 	switch (aOp)
   109 		{
   110 		case ERamZoneOp_Init:	
   111 			break;
   112 		case ERamZoneOp_PowerUp:
   113 			break;
   114 		case ERamZoneOp_PowerDown:
   115 			break;
   116 		default:
   117 			return KErrNotSupported;
   118 		}
   119 	return KErrNone;
   120 	}
   121 
   122 
   123 void Template::Init1()
   124 	{
   125 	__KTRACE_OPT(KBOOT,Kern::Printf("Template::Init1()"));
   126 
   127 	//
   128 	// TO DO: (mandatory)
   129 	//
   130 	// Configure Memory controller and Memrory Bus parameters (in addition to what was done in the Bootstrap)
   131 	//
   132 	__KTRACE_OPT(KBOOT,Kern::Printf("Memory Configuration done"));
   133 
   134 	//
   135 	// TO DO: (optional)
   136 	//
   137 	// Inform the kernel of the RAM zone configuration via Epoc::SetRamZoneConfig().
   138 	// For devices that wish to reduce power consumption of the RAM IC(s) the callback functions
   139 	// RamZoneCallback() and DoRamZoneCallback() will need to be implemented and passed 
   140 	// to Epoc::SetRamZoneConfig() as the parameter aCallback.
   141 	// The kernel will assume that all RAM ICs are fully intialised and ready for use from boot.
   142 	//
   143 
   144 	//
   145 	// TO DO: (optional)
   146 	//
   147 	// Initialise other critical hardware functions such as I/O interfaces, etc, not done by Bootstrap
   148 	//
   149 	// if CPU is Sleep-capable, and requires some preparation to be put in that state (code provided in Bootstrap),
   150 	// the address of the idle code is writen at this location by the Bootstrap
   151 	// e.g.
   152 	// iIdleFunction=*(TLinAddr*)((TUint8*)&Kern::SuperPage()+0x1000);
   153 	//
   154 	TemplateAssp::Init1();
   155 	}
   156 
   157 void Template::Init3()
   158 	{
   159 	__KTRACE_OPT(KBOOT,Kern::Printf("Template::Init3()"));
   160 
   161 	TemplateAssp::Init3();
   162 
   163 	Variant::Init3();
   164 	//
   165 	// TO DO: (optional)
   166 	//
   167 	// Initialise other accessor classes, if required
   168 	//
   169 
   170 	InitInterrupts();
   171 	}
   172 
   173 void Variant::Init3()
   174 //
   175 // Phase 3 initialisation
   176 //
   177     {
   178 	__KTRACE_OPT(KHARDWARE, Kern::Printf(">Variant::Init3"));
   179 
   180 	//
   181 	// TO DO: (optional)
   182 	//
   183 	// Initialise any Variant class data members here, map in Variant and external hardware addresses
   184 	//
   185 	DPlatChunkHw* pC=NULL;
   186 	TInt r=DPlatChunkHw::New(pC,KHwVariantPhysBase,0x2000,EMapAttrSupRw|EMapAttrFullyBlocking);
   187     __ASSERT_ALWAYS(r==KErrNone,V_FAULT());
   188 	iBaseAddress=pC->LinearAddress();
   189 	}
   190 
   191 EXPORT_C TUint Variant::BaseLinAddress()
   192 	{
   193 	return((TUint)iBaseAddress);
   194 	}
   195 
   196 EXPORT_C void Variant::MarkDebugPortOff()
   197 	{
   198 	TheVariant.iDebugInitialised=EFalse;
   199 	}
   200 
   201 EXPORT_C void Variant::UartInit()
   202 	{
   203 	NKern::Lock();
   204 	if (!TheVariant.iDebugInitialised)
   205 		{
   206 		//
   207 		// TO DO: (mandatory)
   208 		//
   209 		// Reset and initialise the UART used to output debug strings
   210 		//
   211 		TheVariant.iDebugInitialised=ETrue;
   212 		}
   213 	NKern::Unlock();
   214 	}
   215 
   216 void Template::DebugInit()
   217 	{
   218 	//
   219 	// TO DO: (mandatory)
   220 	//
   221 	// Initialise the UART used for outputting Debug Strings (no Interrupts), as in the following EXAMPLE ONLY:
   222 	//
   223 	Variant::UartInit();
   224 	TTemplate::BootWaitMilliSeconds(10);	// wait loop to ensure that the port is fully initialised and output buffer empty
   225 	}
   226 
   227 void Template::DebugOutput(TUint aLetter)
   228 //
   229 // Output a character to the debug port
   230 //
   231     {
   232 	if (!iDebugInitialised)
   233 		{
   234 		DebugInit();
   235 		}
   236 		//
   237 		// TO DO: (mandatory)
   238 		//
   239 		// Write the character aLetter to the UART output register and wait until sent (do NOT use interrupts!)
   240 		//
   241     }
   242 
   243 void Template::Idle()
   244 //
   245 // The NULL thread idle loop
   246 //
   247 	{
   248 	// Idle the CPU, suppressing the system tick if possible
   249 
   250 	//
   251 	// TO DO: (optional)
   252 	//
   253 	// Idle Tick supression: 
   254 	// 1- obtain the number of idle Ticks before the next NTimer expiration (NTimerQ::IdleTime())
   255 	// 2- if the number of Ticks is large enough (criteria to be defined) reset the Hardware Timer
   256 	//    to only interrupt again when the corresponding time has expired.
   257 	//   2.1- the calculation of the new value to program the Hardware Timer with should take in 
   258 	//		  consideration the rounding value (NTimerQ::iRounding)
   259 	//  3- call the low level Sleep function (e'g. Bootstrap: address in iIdleFunction)
   260 	//  4- on coming back from Idle need to read the Hardware Timer and determine if woken up due to 
   261 	//     timer expiration (system time for new match<=current system time<system time for new match-tick period)
   262 	//     or some other Interrupt.
   263 	//	 4.1- if timer expiration, adjust System Time by adding the number of Ticks suppressed to NTimerQ::iMsCount
   264 	//   4.2- if other interrupt, calculate the number of Ticks skipped until woken up and adjust the System Time as
   265 	//		  above
   266 	//
   267 	// Support for different Sleep Modes:
   268 	// Often the Sleep mode a platform can go to depends on how many resources such as clocks/voltages can be 
   269 	// turned Off or lowered to a suitable level. If different Sleep modes are supported this code may need 
   270 	// to be able to find out what power resources are On or Off or used to what level. This could be achieved by
   271 	// enquiring the Resource Manager (see \template_variant\inc\template_power.h).
   272 	// Then a decision could be made to what Sleep level we go to.
   273 	//
   274 	// Example calls:
   275 	// Obtain the number of Idle Ticks before the next NTimer expiration
   276 	// TInt aTicksLeft = NTimerQ::IdleTime();
   277 	// ... 
   278 	// Find out the deepest Sleep mode available for current resource usage and sleeping time
   279 	// TemplateResourceManager* aManager = TTemplatePowerController::ResourceManager();
   280 	// TemplateResourceManager::TSleepModes aMode = aManager -> MapSleepMode(aTicksLeft*MsTickPeriod());
   281 	// ...
   282 	// Find out the state of some particular resources
   283 	// TBool aResourceState = aManager -> GetResourceState(TemplateResourceManager::AsynchBinResourceUsedByZOnly);
   284 	// TUint aResourceLevel = aManager -> GetResourceLevel(TemplateResourceManager::SynchMlResourceUsedByXOnly);
   285 	// ...
   286 	}
   287 
   288 TInt Template::VariantHal(TInt aFunction, TAny* a1, TAny* a2)
   289 	{
   290 	TInt r=KErrNone;
   291 	switch(aFunction)
   292 		{
   293 		case EVariantHalVariantInfo:
   294 			{
   295 			TVariantInfoV01Buf infoBuf;
   296 			TVariantInfoV01& info=infoBuf();
   297 			info.iRomVersion=Epoc::RomHeader().iVersion;
   298 
   299 			//
   300 			// TO DO: (mandatory)
   301 			//
   302 			// Fill in the TVariantInfoV01 info structure
   303 			//	info.iMachineUniqueId=;
   304 			//	info.iLedCapabilities=;
   305 			//	info.iProcessorClockInKHz=;
   306 			//	info.iSpeedFactor=;
   307 			//
   308 			Kern::InfoCopy(*(TDes8*)a1,infoBuf);
   309 			break;
   310 			}
   311 		case EVariantHalDebugPortSet:
   312 			{
   313 			//
   314 			// TO DO: (mandatory)
   315 			//
   316 			// Write the iDebugPort field of the SuperPage, as in the following EXAMPLE ONLY:
   317 			//
   318 			TUint32 thePort = (TUint32)a1;
   319 			switch(thePort)
   320 				{
   321 				case 1:
   322 				case 2:
   323 				case 3:
   324 					TheVariant.iDebugInitialised=EFalse;
   325 				case (TUint32)KNullDebugPort:
   326 					Kern::SuperPage().iDebugPort = thePort;
   327 					break;
   328 				default:
   329 					r=KErrNotSupported;
   330 				}
   331 			break;
   332 			}
   333 		case EVariantHalDebugPortGet:
   334 			{
   335 			//
   336 			// TO DO: (mandatory)
   337 			//
   338 			// Obtain the Linear address of the Uart used for outputting Debug strings as in the following EXAMPLE ONLY:
   339 			//
   340 
   341 			TUint32 thePort = TTemplate::DebugPortAddr();
   342 			kumemput32(a1, &thePort, sizeof(TUint32));
   343 			break;
   344 			}
   345 		case EVariantHalSwitches:
   346 			{
   347 			//
   348 			// TO DO: (optional)
   349 			//
   350 			// Read the state of any switches, as in the following EXAMPLE ONLY:
   351 			//
   352 			TUint32 x = Variant::Switches();
   353 			kumemput32(a1, &x, sizeof(x));
   354 			break;
   355 			}
   356 		case EVariantHalLedMaskSet:
   357 			{
   358 			//
   359 			// TO DO: (optional)
   360 			//
   361 			// Set the state of any on-board LEDs, e.g:
   362 			// TUint32 aLedMask=(TUint32)a1;
   363 			// Variant::ModifyLedState(~aLedMask,aLedMask);
   364 			//
   365 			break;
   366 			}
   367 		case EVariantHalLedMaskGet:
   368 			{
   369 			//
   370 			// TO DO: (optional)
   371 			//
   372 			// Read the state of any on-board LEDs, e.g:
   373 			// TUint32 x = Variant::LedState();
   374 			// kumemput32(a1, &x, sizeof(x));
   375 			//
   376 			break;
   377 			}
   378 
   379 		case EVariantHalCustomRestartReason:
   380 			{
   381 			//Restart reason is stored in super page
   382 			TInt x = (Kern::SuperPage().iHwStartupReason & KHtCustomRestartMask) >> KHtCustomRestartShift ;
   383 			kumemput32(a1, &x, sizeof(TInt));
   384 			break;
   385 			}
   386 
   387 		case EVariantHalCustomRestart:
   388 			{
   389 			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart")))
   390 				return KErrPermissionDenied;
   391 			if ((TUint)a1 > KHtCustomRestartMax)
   392 				return KErrArgument;
   393 			Kern::Restart((TInt)a1 << KHtCustomRestartShift);
   394 			}
   395 			break;
   396 
   397 		case EVariantHalCaseState:
   398 			{
   399 			//
   400 			// TO DO: (optional)
   401 			//
   402 			// Read the state of the case, e.g:
   403 			// TUint32 x = Variant::CaseState();
   404 			// kumemput32(a1, &x, sizeof(x));
   405 			//
   406 			break;
   407 			}
   408 
   409 		case EVariantHalPersistStartupMode:
   410 			{
   411 			if (!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
   412 				return KErrPermissionDenied;
   413 
   414 			if ((TUint)a1 > KHtRestartStartupModesMax ) // Restart startup mode max value
   415 				return KErrArgument;
   416 			//
   417 			// TO DO: (optional)
   418 			//
   419 			// Store the restart reason locally,
   420 			// which will eventually be picked up by
   421 			// the power controller, e.g:
   422 			// iCustomRestartReason = (TUint)a1;
   423 			break;
   424 			}
   425 
   426 
   427 		case EVariantHalGetPersistedStartupMode:
   428 			{
   429 			//
   430 			// TO DO: (optional)
   431 			//
   432 			// Read the restart startup mode, e.g:
   433 			// TInt startup = (Kern::SuperPage().iHwStartupReason & KHtRestartStartupModesMask) >> KHtRestartStartupModesShift;
   434 			// kumemput32(a1, &startup, sizeof(TInt));
   435 			break; 			
   436 			}
   437 
   438 		case EVariantHalGetMaximumCustomRestartReasons:
   439 			{
   440 			//
   441 			// TO DO: (optional)
   442 			//
   443 			// Read the maximum custom restart reason, e.g:
   444 			// kumemput32(a1, &KHtCustomRestartMax, sizeof(TUint));
   445 			break;
   446 			}
   447 
   448 
   449 		case EVariantHalGetMaximumRestartStartupModes:
   450 			{
   451 			//
   452 			// TO DO: (optional)
   453 			//
   454 			// Read the maximum restart startup mode, e.g:
   455 			// kumemput32(a1, &KHtRestartStartupModesMax, sizeof(TUint));
   456 			break;
   457 			}
   458 
   459      	case EVariantHalProfilingDefaultInterruptBase:
   460 			{
   461 			//
   462             // TO DO: (optional)
   463             //
   464             //Set the default interrupt number for the sampling profiler.   
   465             //TInt interruptNumber = KIntCpuProfilingDefaultInterruptBase;
   466 			//kumemput(a1,&interruptNumber,sizeof(interruptNumber));
   467 			break;
   468 			}
   469 
   470 		default:
   471 			r=KErrNotSupported;
   472 			break;
   473 		}
   474 	return r;
   475 	}
   476 
   477 TPtr8 Template::MachineConfiguration()
   478 	{
   479 	return TPtr8((TUint8*)&Kern::MachineConfig(),sizeof(TActualMachineConfig),sizeof(TActualMachineConfig));
   480 	}
   481 
   482 TInt Template::VideoRamSize()
   483 	{
   484 	//
   485 	// TO DO: (mandatory)
   486 	//
   487 	// Return the size of the area of RAM used to store the Video Buffer, as in the following EXAMPLE ONLY:
   488 	//
   489 	return 0x28000;
   490 	}
   491 
   492 EXPORT_C void Variant::PowerReset()
   493 	{
   494 	//
   495 	// TO DO: (optional)
   496 	//
   497 	// Reset all power supplies
   498 	//
   499 	}
   500 
   501 EXPORT_C TUint Variant::Switches()
   502 	{
   503 	//
   504 	// TO DO: (optional)
   505 	//
   506 	// Read the state of on-board switches
   507 	//
   508 	return 0;		// EXAMPLE ONLY
   509 	}
   510 
   511 /******************************************************************************
   512  * Interrupt handling/dispatch
   513  ******************************************************************************/
   514 TInt Template::InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr)
   515 	{
   516 	TUint id=anId&0x7fffffff;	// mask off second-level interrupt mask
   517 	if (id>=ENumXInts)
   518 		return KErrArgument;
   519 	TInt r=KErrNone;
   520 	SInterruptHandler& h=Handlers[id];
   521 	TInt irq=NKern::DisableAllInterrupts();
   522 	if (h.iIsr!=Spurious)
   523 		r=KErrInUse;
   524 	else
   525 		{
   526 		h.iIsr=anIsr;
   527 		h.iPtr=aPtr;
   528 		}
   529 	NKern::RestoreInterrupts(irq);
   530 	return r;
   531 	}
   532 
   533 TInt Template::InterruptUnbind(TInt anId)
   534 	{
   535 	TUint id=anId&0x7fffffff;	// mask off second-level interrupt mask
   536 	if (id>=ENumXInts)
   537 		return KErrArgument;
   538 	InterruptDisable(anId);
   539 	InterruptClear(anId);
   540 	TInt r=KErrNone;
   541 	SInterruptHandler& h=Handlers[id];
   542 	TInt irq=NKern::DisableAllInterrupts();
   543 	if (h.iIsr!=Spurious)
   544 		{
   545 		h.iIsr=Spurious;
   546 		h.iPtr=(TAny*)id;
   547 		}
   548 	NKern::RestoreInterrupts(irq);
   549 	return r;
   550 	}
   551 
   552 TInt Template::InterruptEnable(TInt anId)
   553 	{
   554 	TUint id=anId&0x7fffffff;	// mask off second-level interrupt mask
   555 	if (id>=ENumXInts)
   556 		return KErrArgument;
   557 	TInt r=KErrNone;
   558 	SInterruptHandler& h=Handlers[id];
   559 	TInt irq=NKern::DisableAllInterrupts();
   560 	if (h.iIsr==Spurious)
   561 		r=KErrNotReady;
   562 	else
   563 		{
   564 		//
   565 		// TO DO: (mandatory)
   566 		//
   567 		// Enable the hardware interrupt in the source, e.g.
   568 		// Variant::EnableInt(anId);
   569 		//
   570 		}
   571 	NKern::RestoreInterrupts(irq);
   572 	return r;
   573 	}
   574 
   575 TInt Template::InterruptDisable(TInt anId)
   576 	{
   577 	TUint id=anId&0x7fffffff;	// mask off second-level interrupt mask
   578 	if (id>=ENumXInts)
   579 		return KErrArgument;
   580 	//
   581 	// TO DO: (mandatory)
   582 	//
   583 	// Disable the hardware interrupt in the source, e.g.
   584 	// Variant::DisableInt(anId);
   585 	//
   586 	return KErrNone;
   587 	}
   588 
   589 TInt Template::InterruptClear(TInt anId)
   590 	{
   591 	TUint id=anId&0x7fffffff;
   592 	if (id>=ENumXInts)
   593 		return KErrArgument;
   594 	//
   595 	// TO DO: (mandatory)
   596 	//
   597 	// Clear the hardware interrupt in the source, e.g.
   598 	// Variant::ClearInt(anId);
   599 	//
   600 	return KErrNone;
   601 	}
   602 
   603 void Template::InitInterrupts()
   604 	{
   605 	// Set up the variant interrupt dispatcher
   606 
   607 	// all interrupts initially unbound
   608 	TInt i;
   609 	for (i=0; i<(TInt)ENumXInts; i++)
   610 		{
   611 		Handlers[i].iPtr=(TAny*)i;
   612 		Handlers[i].iIsr=Spurious;
   613 		}
   614 
   615 	// Set up data for 2nd level interrupt dispatcher
   616 	HandlerData[0]=Variant::BaseLinAddress();	// Linear Base address of 2nd level Int Controller
   617 	HandlerData[1]=(TUint32)&Handlers[0];		// Pointer to handler array
   618 	HandlerData[2]=0;							// 
   619 	
   620 	//
   621 	// TO DO: (mandatory)
   622 	//
   623 	// set up ASSP expansion interrupt to generate interrupts whenever a 2nd level interrupt occurrs
   624 	// 
   625 
   626 	// bind Template ASSP expansion interrupt input to our interrupt dispatcher
   627 	TInt r=Interrupt::Bind(KIntIdExpansion, XIntDispatch, HandlerData);
   628 	__ASSERT_ALWAYS(r==KErrNone,V_FAULT());
   629 	Interrupt::Enable(KIntIdExpansion);				// enable expansion interrupt
   630 	}
   631 
   632 void Template::Spurious(TAny* aId)
   633 	{
   634 	TUint32 id=((TUint32)aId)|0x80000000u;
   635 	Kern::Fault("SpuriousInt",id);
   636 	}
   637 
   638 
   639 // USB Client controller
   640 
   641 TBool Template::UsbClientConnectorDetectable()
   642 	{
   643 	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorDetectable"));
   644 
   645 	// TO DO: The return value should reflect the actual situation.
   646 	return ETrue;
   647 	}
   648 
   649 
   650 TBool Template::UsbClientConnectorInserted()
   651  	{
   652 	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorInserted"));
   653 
   654 	// TO DO: Query cable status here. The return value should reflect the actual current state.
   655 	return ETrue;
   656 	}
   657 
   658 
   659 TInt Template::RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr)
   660 	{
   661 	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::RegisterUsbClientConnectorCallback"));
   662 
   663 	iUsbClientConnectorCallback = aCallback;
   664 	iUsbClientConnectorCallbackArg = aPtr;
   665 
   666 	// TO DO: Register and enable the interrupt(s) for detecting USB cable insertion/removal here.
   667 	// (Register UsbClientConnectorIsr.)
   668 
   669 	// TO DO: The return value should reflect the actual situation.
   670 	return KErrNone;
   671 	}
   672 
   673 
   674 void Template::UnregisterUsbClientConnectorCallback()
   675 	{
   676 	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UnregisterUsbClientConnectorCallback"));
   677 
   678 	// TO DO: Disable and unbind the interrupt(s) for detecting USB cable insertion/removal here.
   679 
   680 	iUsbClientConnectorCallback = NULL;
   681 	iUsbClientConnectorCallbackArg = NULL;
   682 	}
   683 
   684 
   685 TBool Template::UsbSoftwareConnectable()
   686 	{
   687 	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbSoftwareConnectable"));
   688 
   689 	// TO DO: The return value should reflect the actual situation.
   690 	return ETrue;
   691 	}
   692 
   693 
   694 TInt Template::UsbConnect()
   695 	{
   696 	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbConnect"));
   697 
   698 	// TO DO: Do here whatever is necessary for the UDC to appear on the bus (and thus to the host).
   699 
   700 	return KErrNone;
   701 	}
   702 
   703 
   704 TInt Template::UsbDisconnect()
   705 	{
   706 	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbDisconnect"));
   707 
   708 	// TO DO: Do here whatever is necessary for the UDC to appear disconnected from the bus (and thus from the
   709 	// host).
   710 
   711 	return KErrNone;
   712 	}
   713 
   714 
   715 void Template::UsbClientConnectorIsr(TAny *aPtr)
   716 //
   717 // Services the USB cable interrupt.
   718 //
   719 	{
   720 	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorIsr()"));
   721 
   722 	Template* tm = static_cast<Template*>(aPtr);
   723 
   724 	// TO DO: Service interrupt here: determmine cause, clear condition flag (if applicable), etc.
   725 
   726 	if (tm->UsbClientConnectorInserted())
   727 		{
   728 		__KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now inserted."));
   729 		}
   730 	else
   731 		{
   732 		__KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now removed."));
   733 		}
   734 
   735 	// Important: Inform the USB stack.
   736 	if (tm->iUsbClientConnectorCallback)
   737 		{
   738 		(*tm->iUsbClientConnectorCallback)(tm->iUsbClientConnectorCallbackArg);
   739 		}
   740 	}
   741 
   742 
   743 //---eof