1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/variant.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,743 @@
1.4 +// Copyright (c) 1994-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\variant.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "variant.h"
1.22 +#include "mconf.h"
1.23 +#include <videodriver.h>
1.24 +#include <drivers/xyin.h>
1.25 +#include "template_power.h"
1.26 +
1.27 +//These constants define Custom Restart Reasons in SuperPage::iHwStartupReason
1.28 +const TUint KHtCustomRestartMax = 0xff;
1.29 +const TUint KHtCustomRestartShift = 8;
1.30 +const TUint KHtCustomRestartMask = KHtCustomRestartMax << KHtCustomRestartShift;
1.31 +
1.32 +const TUint KHtRestartStartupModesMax = 0xf; // Variable, platform dependant
1.33 +const TUint KHtRestartStartupModesShift = 16; // Variable, platform dependant
1.34 +const TUint KHtRestartStartupModesMask = KHtRestartStartupModesMax << KHtRestartStartupModesShift;
1.35 +
1.36 +void TemplateVariantFault(TInt aLine)
1.37 + {
1.38 + Kern::Fault("TemplateVariant",aLine);
1.39 + }
1.40 +
1.41 +#define V_FAULT() TemplateVariantFault(__LINE__)
1.42 +
1.43 +// Debug output
1.44 +#define XON 17
1.45 +#define XOFF 19
1.46 +#define DEBUG_XON_XOFF 0 // Non-zero if we want XON-XOFF handshaking
1.47 +
1.48 +GLDEF_D Template TheVariant;
1.49 +TUint32 Variant::iBaseAddress=0;
1.50 +
1.51 +TUint32 Template::HandlerData[3];
1.52 +SInterruptHandler Template::Handlers[ENumXInts];
1.53 +
1.54 +extern void XIntDispatch(TAny*);
1.55 +
1.56 +EXPORT_C Asic* VariantInitialise()
1.57 + {
1.58 + return &TheVariant;
1.59 + }
1.60 +
1.61 +Template::Template()
1.62 + {
1.63 + iDebugInitialised=EFalse;
1.64 + }
1.65 +
1.66 +//
1.67 +// TO DO: (optional)
1.68 +//
1.69 +// Specify the RAM zone configuration.
1.70 +//
1.71 +// The lowest addressed zone must have the highest preference as the bootstrap
1.72 +// will always allocate from the lowest address up. Once the kernel has initialised
1.73 +// then the zone preferences will decide from which RAM zone memory is allocated.
1.74 +//
1.75 +// const TUint KVariantRamZoneCount = ?;
1.76 +// static const SRamZone KRamZoneConfig[KVariantRamZoneCount+1] =
1.77 +// iBase iSize iID iPref iFlags
1.78 +// {
1.79 +// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?),
1.80 +// ...
1.81 +// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?),
1.82 +// __SRAM_ZONE_END, // end of zone list
1.83 +// };
1.84 +//
1.85 +
1.86 +TInt Template::RamZoneCallback(TRamZoneOp aOp, TAny* aId, const TAny* aMasks)
1.87 + {
1.88 + //
1.89 + // TO DO: (optional)
1.90 + //
1.91 + // Handle RAM zone operations requested by the kernel.
1.92 + //
1.93 + return TheVariant.DoRamZoneCallback(aOp, (TUint)aId, (const TUint*)aMasks);
1.94 + }
1.95 +
1.96 +
1.97 +TInt Template::DoRamZoneCallback(TRamZoneOp aOp, TUint aId, const TUint* aMasks)
1.98 + {
1.99 + //
1.100 + // TO DO: (optional)
1.101 + //
1.102 + // Handle RAM zone operations requested by the kernel.
1.103 + //
1.104 + // Three types of operation need to be supported:
1.105 + // ERamZoneOp_Init: Update power state of the RAM zones after the
1.106 + // kernel has initialised.
1.107 + // ERamZoneOp_PowerUp: A RAM zone changing from used to empty.
1.108 + // ERamZoneOp_PowerDown: A RAM zone changing from empty to used.
1.109 + //
1.110 +
1.111 + switch (aOp)
1.112 + {
1.113 + case ERamZoneOp_Init:
1.114 + break;
1.115 + case ERamZoneOp_PowerUp:
1.116 + break;
1.117 + case ERamZoneOp_PowerDown:
1.118 + break;
1.119 + default:
1.120 + return KErrNotSupported;
1.121 + }
1.122 + return KErrNone;
1.123 + }
1.124 +
1.125 +
1.126 +void Template::Init1()
1.127 + {
1.128 + __KTRACE_OPT(KBOOT,Kern::Printf("Template::Init1()"));
1.129 +
1.130 + //
1.131 + // TO DO: (mandatory)
1.132 + //
1.133 + // Configure Memory controller and Memrory Bus parameters (in addition to what was done in the Bootstrap)
1.134 + //
1.135 + __KTRACE_OPT(KBOOT,Kern::Printf("Memory Configuration done"));
1.136 +
1.137 + //
1.138 + // TO DO: (optional)
1.139 + //
1.140 + // Inform the kernel of the RAM zone configuration via Epoc::SetRamZoneConfig().
1.141 + // For devices that wish to reduce power consumption of the RAM IC(s) the callback functions
1.142 + // RamZoneCallback() and DoRamZoneCallback() will need to be implemented and passed
1.143 + // to Epoc::SetRamZoneConfig() as the parameter aCallback.
1.144 + // The kernel will assume that all RAM ICs are fully intialised and ready for use from boot.
1.145 + //
1.146 +
1.147 + //
1.148 + // TO DO: (optional)
1.149 + //
1.150 + // Initialise other critical hardware functions such as I/O interfaces, etc, not done by Bootstrap
1.151 + //
1.152 + // if CPU is Sleep-capable, and requires some preparation to be put in that state (code provided in Bootstrap),
1.153 + // the address of the idle code is writen at this location by the Bootstrap
1.154 + // e.g.
1.155 + // iIdleFunction=*(TLinAddr*)((TUint8*)&Kern::SuperPage()+0x1000);
1.156 + //
1.157 + TemplateAssp::Init1();
1.158 + }
1.159 +
1.160 +void Template::Init3()
1.161 + {
1.162 + __KTRACE_OPT(KBOOT,Kern::Printf("Template::Init3()"));
1.163 +
1.164 + TemplateAssp::Init3();
1.165 +
1.166 + Variant::Init3();
1.167 + //
1.168 + // TO DO: (optional)
1.169 + //
1.170 + // Initialise other accessor classes, if required
1.171 + //
1.172 +
1.173 + InitInterrupts();
1.174 + }
1.175 +
1.176 +void Variant::Init3()
1.177 +//
1.178 +// Phase 3 initialisation
1.179 +//
1.180 + {
1.181 + __KTRACE_OPT(KHARDWARE, Kern::Printf(">Variant::Init3"));
1.182 +
1.183 + //
1.184 + // TO DO: (optional)
1.185 + //
1.186 + // Initialise any Variant class data members here, map in Variant and external hardware addresses
1.187 + //
1.188 + DPlatChunkHw* pC=NULL;
1.189 + TInt r=DPlatChunkHw::New(pC,KHwVariantPhysBase,0x2000,EMapAttrSupRw|EMapAttrFullyBlocking);
1.190 + __ASSERT_ALWAYS(r==KErrNone,V_FAULT());
1.191 + iBaseAddress=pC->LinearAddress();
1.192 + }
1.193 +
1.194 +EXPORT_C TUint Variant::BaseLinAddress()
1.195 + {
1.196 + return((TUint)iBaseAddress);
1.197 + }
1.198 +
1.199 +EXPORT_C void Variant::MarkDebugPortOff()
1.200 + {
1.201 + TheVariant.iDebugInitialised=EFalse;
1.202 + }
1.203 +
1.204 +EXPORT_C void Variant::UartInit()
1.205 + {
1.206 + NKern::Lock();
1.207 + if (!TheVariant.iDebugInitialised)
1.208 + {
1.209 + //
1.210 + // TO DO: (mandatory)
1.211 + //
1.212 + // Reset and initialise the UART used to output debug strings
1.213 + //
1.214 + TheVariant.iDebugInitialised=ETrue;
1.215 + }
1.216 + NKern::Unlock();
1.217 + }
1.218 +
1.219 +void Template::DebugInit()
1.220 + {
1.221 + //
1.222 + // TO DO: (mandatory)
1.223 + //
1.224 + // Initialise the UART used for outputting Debug Strings (no Interrupts), as in the following EXAMPLE ONLY:
1.225 + //
1.226 + Variant::UartInit();
1.227 + TTemplate::BootWaitMilliSeconds(10); // wait loop to ensure that the port is fully initialised and output buffer empty
1.228 + }
1.229 +
1.230 +void Template::DebugOutput(TUint aLetter)
1.231 +//
1.232 +// Output a character to the debug port
1.233 +//
1.234 + {
1.235 + if (!iDebugInitialised)
1.236 + {
1.237 + DebugInit();
1.238 + }
1.239 + //
1.240 + // TO DO: (mandatory)
1.241 + //
1.242 + // Write the character aLetter to the UART output register and wait until sent (do NOT use interrupts!)
1.243 + //
1.244 + }
1.245 +
1.246 +void Template::Idle()
1.247 +//
1.248 +// The NULL thread idle loop
1.249 +//
1.250 + {
1.251 + // Idle the CPU, suppressing the system tick if possible
1.252 +
1.253 + //
1.254 + // TO DO: (optional)
1.255 + //
1.256 + // Idle Tick supression:
1.257 + // 1- obtain the number of idle Ticks before the next NTimer expiration (NTimerQ::IdleTime())
1.258 + // 2- if the number of Ticks is large enough (criteria to be defined) reset the Hardware Timer
1.259 + // to only interrupt again when the corresponding time has expired.
1.260 + // 2.1- the calculation of the new value to program the Hardware Timer with should take in
1.261 + // consideration the rounding value (NTimerQ::iRounding)
1.262 + // 3- call the low level Sleep function (e'g. Bootstrap: address in iIdleFunction)
1.263 + // 4- on coming back from Idle need to read the Hardware Timer and determine if woken up due to
1.264 + // timer expiration (system time for new match<=current system time<system time for new match-tick period)
1.265 + // or some other Interrupt.
1.266 + // 4.1- if timer expiration, adjust System Time by adding the number of Ticks suppressed to NTimerQ::iMsCount
1.267 + // 4.2- if other interrupt, calculate the number of Ticks skipped until woken up and adjust the System Time as
1.268 + // above
1.269 + //
1.270 + // Support for different Sleep Modes:
1.271 + // Often the Sleep mode a platform can go to depends on how many resources such as clocks/voltages can be
1.272 + // turned Off or lowered to a suitable level. If different Sleep modes are supported this code may need
1.273 + // to be able to find out what power resources are On or Off or used to what level. This could be achieved by
1.274 + // enquiring the Resource Manager (see \template_variant\inc\template_power.h).
1.275 + // Then a decision could be made to what Sleep level we go to.
1.276 + //
1.277 + // Example calls:
1.278 + // Obtain the number of Idle Ticks before the next NTimer expiration
1.279 + // TInt aTicksLeft = NTimerQ::IdleTime();
1.280 + // ...
1.281 + // Find out the deepest Sleep mode available for current resource usage and sleeping time
1.282 + // TemplateResourceManager* aManager = TTemplatePowerController::ResourceManager();
1.283 + // TemplateResourceManager::TSleepModes aMode = aManager -> MapSleepMode(aTicksLeft*MsTickPeriod());
1.284 + // ...
1.285 + // Find out the state of some particular resources
1.286 + // TBool aResourceState = aManager -> GetResourceState(TemplateResourceManager::AsynchBinResourceUsedByZOnly);
1.287 + // TUint aResourceLevel = aManager -> GetResourceLevel(TemplateResourceManager::SynchMlResourceUsedByXOnly);
1.288 + // ...
1.289 + }
1.290 +
1.291 +TInt Template::VariantHal(TInt aFunction, TAny* a1, TAny* a2)
1.292 + {
1.293 + TInt r=KErrNone;
1.294 + switch(aFunction)
1.295 + {
1.296 + case EVariantHalVariantInfo:
1.297 + {
1.298 + TVariantInfoV01Buf infoBuf;
1.299 + TVariantInfoV01& info=infoBuf();
1.300 + info.iRomVersion=Epoc::RomHeader().iVersion;
1.301 +
1.302 + //
1.303 + // TO DO: (mandatory)
1.304 + //
1.305 + // Fill in the TVariantInfoV01 info structure
1.306 + // info.iMachineUniqueId=;
1.307 + // info.iLedCapabilities=;
1.308 + // info.iProcessorClockInKHz=;
1.309 + // info.iSpeedFactor=;
1.310 + //
1.311 + Kern::InfoCopy(*(TDes8*)a1,infoBuf);
1.312 + break;
1.313 + }
1.314 + case EVariantHalDebugPortSet:
1.315 + {
1.316 + //
1.317 + // TO DO: (mandatory)
1.318 + //
1.319 + // Write the iDebugPort field of the SuperPage, as in the following EXAMPLE ONLY:
1.320 + //
1.321 + TUint32 thePort = (TUint32)a1;
1.322 + switch(thePort)
1.323 + {
1.324 + case 1:
1.325 + case 2:
1.326 + case 3:
1.327 + TheVariant.iDebugInitialised=EFalse;
1.328 + case (TUint32)KNullDebugPort:
1.329 + Kern::SuperPage().iDebugPort = thePort;
1.330 + break;
1.331 + default:
1.332 + r=KErrNotSupported;
1.333 + }
1.334 + break;
1.335 + }
1.336 + case EVariantHalDebugPortGet:
1.337 + {
1.338 + //
1.339 + // TO DO: (mandatory)
1.340 + //
1.341 + // Obtain the Linear address of the Uart used for outputting Debug strings as in the following EXAMPLE ONLY:
1.342 + //
1.343 +
1.344 + TUint32 thePort = TTemplate::DebugPortAddr();
1.345 + kumemput32(a1, &thePort, sizeof(TUint32));
1.346 + break;
1.347 + }
1.348 + case EVariantHalSwitches:
1.349 + {
1.350 + //
1.351 + // TO DO: (optional)
1.352 + //
1.353 + // Read the state of any switches, as in the following EXAMPLE ONLY:
1.354 + //
1.355 + TUint32 x = Variant::Switches();
1.356 + kumemput32(a1, &x, sizeof(x));
1.357 + break;
1.358 + }
1.359 + case EVariantHalLedMaskSet:
1.360 + {
1.361 + //
1.362 + // TO DO: (optional)
1.363 + //
1.364 + // Set the state of any on-board LEDs, e.g:
1.365 + // TUint32 aLedMask=(TUint32)a1;
1.366 + // Variant::ModifyLedState(~aLedMask,aLedMask);
1.367 + //
1.368 + break;
1.369 + }
1.370 + case EVariantHalLedMaskGet:
1.371 + {
1.372 + //
1.373 + // TO DO: (optional)
1.374 + //
1.375 + // Read the state of any on-board LEDs, e.g:
1.376 + // TUint32 x = Variant::LedState();
1.377 + // kumemput32(a1, &x, sizeof(x));
1.378 + //
1.379 + break;
1.380 + }
1.381 +
1.382 + case EVariantHalCustomRestartReason:
1.383 + {
1.384 + //Restart reason is stored in super page
1.385 + TInt x = (Kern::SuperPage().iHwStartupReason & KHtCustomRestartMask) >> KHtCustomRestartShift ;
1.386 + kumemput32(a1, &x, sizeof(TInt));
1.387 + break;
1.388 + }
1.389 +
1.390 + case EVariantHalCustomRestart:
1.391 + {
1.392 + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart")))
1.393 + return KErrPermissionDenied;
1.394 + if ((TUint)a1 > KHtCustomRestartMax)
1.395 + return KErrArgument;
1.396 + Kern::Restart((TInt)a1 << KHtCustomRestartShift);
1.397 + }
1.398 + break;
1.399 +
1.400 + case EVariantHalCaseState:
1.401 + {
1.402 + //
1.403 + // TO DO: (optional)
1.404 + //
1.405 + // Read the state of the case, e.g:
1.406 + // TUint32 x = Variant::CaseState();
1.407 + // kumemput32(a1, &x, sizeof(x));
1.408 + //
1.409 + break;
1.410 + }
1.411 +
1.412 + case EVariantHalPersistStartupMode:
1.413 + {
1.414 + if (!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
1.415 + return KErrPermissionDenied;
1.416 +
1.417 + if ((TUint)a1 > KHtRestartStartupModesMax ) // Restart startup mode max value
1.418 + return KErrArgument;
1.419 + //
1.420 + // TO DO: (optional)
1.421 + //
1.422 + // Store the restart reason locally,
1.423 + // which will eventually be picked up by
1.424 + // the power controller, e.g:
1.425 + // iCustomRestartReason = (TUint)a1;
1.426 + break;
1.427 + }
1.428 +
1.429 +
1.430 + case EVariantHalGetPersistedStartupMode:
1.431 + {
1.432 + //
1.433 + // TO DO: (optional)
1.434 + //
1.435 + // Read the restart startup mode, e.g:
1.436 + // TInt startup = (Kern::SuperPage().iHwStartupReason & KHtRestartStartupModesMask) >> KHtRestartStartupModesShift;
1.437 + // kumemput32(a1, &startup, sizeof(TInt));
1.438 + break;
1.439 + }
1.440 +
1.441 + case EVariantHalGetMaximumCustomRestartReasons:
1.442 + {
1.443 + //
1.444 + // TO DO: (optional)
1.445 + //
1.446 + // Read the maximum custom restart reason, e.g:
1.447 + // kumemput32(a1, &KHtCustomRestartMax, sizeof(TUint));
1.448 + break;
1.449 + }
1.450 +
1.451 +
1.452 + case EVariantHalGetMaximumRestartStartupModes:
1.453 + {
1.454 + //
1.455 + // TO DO: (optional)
1.456 + //
1.457 + // Read the maximum restart startup mode, e.g:
1.458 + // kumemput32(a1, &KHtRestartStartupModesMax, sizeof(TUint));
1.459 + break;
1.460 + }
1.461 +
1.462 + case EVariantHalProfilingDefaultInterruptBase:
1.463 + {
1.464 + //
1.465 + // TO DO: (optional)
1.466 + //
1.467 + //Set the default interrupt number for the sampling profiler.
1.468 + //TInt interruptNumber = KIntCpuProfilingDefaultInterruptBase;
1.469 + //kumemput(a1,&interruptNumber,sizeof(interruptNumber));
1.470 + break;
1.471 + }
1.472 +
1.473 + default:
1.474 + r=KErrNotSupported;
1.475 + break;
1.476 + }
1.477 + return r;
1.478 + }
1.479 +
1.480 +TPtr8 Template::MachineConfiguration()
1.481 + {
1.482 + return TPtr8((TUint8*)&Kern::MachineConfig(),sizeof(TActualMachineConfig),sizeof(TActualMachineConfig));
1.483 + }
1.484 +
1.485 +TInt Template::VideoRamSize()
1.486 + {
1.487 + //
1.488 + // TO DO: (mandatory)
1.489 + //
1.490 + // Return the size of the area of RAM used to store the Video Buffer, as in the following EXAMPLE ONLY:
1.491 + //
1.492 + return 0x28000;
1.493 + }
1.494 +
1.495 +EXPORT_C void Variant::PowerReset()
1.496 + {
1.497 + //
1.498 + // TO DO: (optional)
1.499 + //
1.500 + // Reset all power supplies
1.501 + //
1.502 + }
1.503 +
1.504 +EXPORT_C TUint Variant::Switches()
1.505 + {
1.506 + //
1.507 + // TO DO: (optional)
1.508 + //
1.509 + // Read the state of on-board switches
1.510 + //
1.511 + return 0; // EXAMPLE ONLY
1.512 + }
1.513 +
1.514 +/******************************************************************************
1.515 + * Interrupt handling/dispatch
1.516 + ******************************************************************************/
1.517 +TInt Template::InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr)
1.518 + {
1.519 + TUint id=anId&0x7fffffff; // mask off second-level interrupt mask
1.520 + if (id>=ENumXInts)
1.521 + return KErrArgument;
1.522 + TInt r=KErrNone;
1.523 + SInterruptHandler& h=Handlers[id];
1.524 + TInt irq=NKern::DisableAllInterrupts();
1.525 + if (h.iIsr!=Spurious)
1.526 + r=KErrInUse;
1.527 + else
1.528 + {
1.529 + h.iIsr=anIsr;
1.530 + h.iPtr=aPtr;
1.531 + }
1.532 + NKern::RestoreInterrupts(irq);
1.533 + return r;
1.534 + }
1.535 +
1.536 +TInt Template::InterruptUnbind(TInt anId)
1.537 + {
1.538 + TUint id=anId&0x7fffffff; // mask off second-level interrupt mask
1.539 + if (id>=ENumXInts)
1.540 + return KErrArgument;
1.541 + InterruptDisable(anId);
1.542 + InterruptClear(anId);
1.543 + TInt r=KErrNone;
1.544 + SInterruptHandler& h=Handlers[id];
1.545 + TInt irq=NKern::DisableAllInterrupts();
1.546 + if (h.iIsr!=Spurious)
1.547 + {
1.548 + h.iIsr=Spurious;
1.549 + h.iPtr=(TAny*)id;
1.550 + }
1.551 + NKern::RestoreInterrupts(irq);
1.552 + return r;
1.553 + }
1.554 +
1.555 +TInt Template::InterruptEnable(TInt anId)
1.556 + {
1.557 + TUint id=anId&0x7fffffff; // mask off second-level interrupt mask
1.558 + if (id>=ENumXInts)
1.559 + return KErrArgument;
1.560 + TInt r=KErrNone;
1.561 + SInterruptHandler& h=Handlers[id];
1.562 + TInt irq=NKern::DisableAllInterrupts();
1.563 + if (h.iIsr==Spurious)
1.564 + r=KErrNotReady;
1.565 + else
1.566 + {
1.567 + //
1.568 + // TO DO: (mandatory)
1.569 + //
1.570 + // Enable the hardware interrupt in the source, e.g.
1.571 + // Variant::EnableInt(anId);
1.572 + //
1.573 + }
1.574 + NKern::RestoreInterrupts(irq);
1.575 + return r;
1.576 + }
1.577 +
1.578 +TInt Template::InterruptDisable(TInt anId)
1.579 + {
1.580 + TUint id=anId&0x7fffffff; // mask off second-level interrupt mask
1.581 + if (id>=ENumXInts)
1.582 + return KErrArgument;
1.583 + //
1.584 + // TO DO: (mandatory)
1.585 + //
1.586 + // Disable the hardware interrupt in the source, e.g.
1.587 + // Variant::DisableInt(anId);
1.588 + //
1.589 + return KErrNone;
1.590 + }
1.591 +
1.592 +TInt Template::InterruptClear(TInt anId)
1.593 + {
1.594 + TUint id=anId&0x7fffffff;
1.595 + if (id>=ENumXInts)
1.596 + return KErrArgument;
1.597 + //
1.598 + // TO DO: (mandatory)
1.599 + //
1.600 + // Clear the hardware interrupt in the source, e.g.
1.601 + // Variant::ClearInt(anId);
1.602 + //
1.603 + return KErrNone;
1.604 + }
1.605 +
1.606 +void Template::InitInterrupts()
1.607 + {
1.608 + // Set up the variant interrupt dispatcher
1.609 +
1.610 + // all interrupts initially unbound
1.611 + TInt i;
1.612 + for (i=0; i<(TInt)ENumXInts; i++)
1.613 + {
1.614 + Handlers[i].iPtr=(TAny*)i;
1.615 + Handlers[i].iIsr=Spurious;
1.616 + }
1.617 +
1.618 + // Set up data for 2nd level interrupt dispatcher
1.619 + HandlerData[0]=Variant::BaseLinAddress(); // Linear Base address of 2nd level Int Controller
1.620 + HandlerData[1]=(TUint32)&Handlers[0]; // Pointer to handler array
1.621 + HandlerData[2]=0; //
1.622 +
1.623 + //
1.624 + // TO DO: (mandatory)
1.625 + //
1.626 + // set up ASSP expansion interrupt to generate interrupts whenever a 2nd level interrupt occurrs
1.627 + //
1.628 +
1.629 + // bind Template ASSP expansion interrupt input to our interrupt dispatcher
1.630 + TInt r=Interrupt::Bind(KIntIdExpansion, XIntDispatch, HandlerData);
1.631 + __ASSERT_ALWAYS(r==KErrNone,V_FAULT());
1.632 + Interrupt::Enable(KIntIdExpansion); // enable expansion interrupt
1.633 + }
1.634 +
1.635 +void Template::Spurious(TAny* aId)
1.636 + {
1.637 + TUint32 id=((TUint32)aId)|0x80000000u;
1.638 + Kern::Fault("SpuriousInt",id);
1.639 + }
1.640 +
1.641 +
1.642 +// USB Client controller
1.643 +
1.644 +TBool Template::UsbClientConnectorDetectable()
1.645 + {
1.646 + __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorDetectable"));
1.647 +
1.648 + // TO DO: The return value should reflect the actual situation.
1.649 + return ETrue;
1.650 + }
1.651 +
1.652 +
1.653 +TBool Template::UsbClientConnectorInserted()
1.654 + {
1.655 + __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorInserted"));
1.656 +
1.657 + // TO DO: Query cable status here. The return value should reflect the actual current state.
1.658 + return ETrue;
1.659 + }
1.660 +
1.661 +
1.662 +TInt Template::RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr)
1.663 + {
1.664 + __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::RegisterUsbClientConnectorCallback"));
1.665 +
1.666 + iUsbClientConnectorCallback = aCallback;
1.667 + iUsbClientConnectorCallbackArg = aPtr;
1.668 +
1.669 + // TO DO: Register and enable the interrupt(s) for detecting USB cable insertion/removal here.
1.670 + // (Register UsbClientConnectorIsr.)
1.671 +
1.672 + // TO DO: The return value should reflect the actual situation.
1.673 + return KErrNone;
1.674 + }
1.675 +
1.676 +
1.677 +void Template::UnregisterUsbClientConnectorCallback()
1.678 + {
1.679 + __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UnregisterUsbClientConnectorCallback"));
1.680 +
1.681 + // TO DO: Disable and unbind the interrupt(s) for detecting USB cable insertion/removal here.
1.682 +
1.683 + iUsbClientConnectorCallback = NULL;
1.684 + iUsbClientConnectorCallbackArg = NULL;
1.685 + }
1.686 +
1.687 +
1.688 +TBool Template::UsbSoftwareConnectable()
1.689 + {
1.690 + __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbSoftwareConnectable"));
1.691 +
1.692 + // TO DO: The return value should reflect the actual situation.
1.693 + return ETrue;
1.694 + }
1.695 +
1.696 +
1.697 +TInt Template::UsbConnect()
1.698 + {
1.699 + __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbConnect"));
1.700 +
1.701 + // TO DO: Do here whatever is necessary for the UDC to appear on the bus (and thus to the host).
1.702 +
1.703 + return KErrNone;
1.704 + }
1.705 +
1.706 +
1.707 +TInt Template::UsbDisconnect()
1.708 + {
1.709 + __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbDisconnect"));
1.710 +
1.711 + // TO DO: Do here whatever is necessary for the UDC to appear disconnected from the bus (and thus from the
1.712 + // host).
1.713 +
1.714 + return KErrNone;
1.715 + }
1.716 +
1.717 +
1.718 +void Template::UsbClientConnectorIsr(TAny *aPtr)
1.719 +//
1.720 +// Services the USB cable interrupt.
1.721 +//
1.722 + {
1.723 + __KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorIsr()"));
1.724 +
1.725 + Template* tm = static_cast<Template*>(aPtr);
1.726 +
1.727 + // TO DO: Service interrupt here: determmine cause, clear condition flag (if applicable), etc.
1.728 +
1.729 + if (tm->UsbClientConnectorInserted())
1.730 + {
1.731 + __KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now inserted."));
1.732 + }
1.733 + else
1.734 + {
1.735 + __KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now removed."));
1.736 + }
1.737 +
1.738 + // Important: Inform the USB stack.
1.739 + if (tm->iUsbClientConnectorCallback)
1.740 + {
1.741 + (*tm->iUsbClientConnectorCallback)(tm->iUsbClientConnectorCallbackArg);
1.742 + }
1.743 + }
1.744 +
1.745 +
1.746 +//---eof