1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/uart.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,722 @@
1.4 +// Copyright (c) 1998-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\uart.cpp
1.18 +// pdd for serial ports
1.19 +// assume Modem Control Signals change cause an interrupt
1.20 +//
1.21 +//
1.22 +
1.23 +
1.24 +#include <drivers/comm.h>
1.25 +#include <template_assp.h>
1.26 +#include "iolines.h"
1.27 +#include <e32hal.h>
1.28 +
1.29 +_LIT(KPddName,"Comm.Template");
1.30 +
1.31 +// needs ldd version..
1.32 +const TInt KMinimumLddMajorVersion=1;
1.33 +const TInt KMinimumLddMinorVersion=1;
1.34 +const TInt KMinimumLddBuild=122;
1.35 +
1.36 +//
1.37 +// TO DO: (mandatory)
1.38 +//
1.39 +// Define here the UART enumeration data for the serial ports.
1.40 +// It is a good idea to define each enumerated value as a bit mask that can be written to (or OR-ed or AND-ed to)
1.41 +// a hardware register to provide the configuration option desired (the following are EXAMPLES ONLY):
1.42 +//
1.43 +// EXAMPLE ONLY
1.44 +enum TUartBaudRate
1.45 + {
1.46 + EUartBaudRate115200/* =bitmask for 115200 Baud */,
1.47 + EUartBaudRate76800/* =bitmask for 76800 Baud */,
1.48 + EUartBaudRate57600/* =bitmask for 57600 Baud */,
1.49 + EUartBaudRate38400/* =bitmask for 38400 Baud */,
1.50 + EUartBaudRate19200/* =bitmask for 19200 Baud */,
1.51 + EUartBaudRate14400/* =bitmask for 14400 Baud */,
1.52 + EUartBaudRate9600/* =bitmask for 9600 Baud */,
1.53 + EUartBaudRate4800/* =bitmask for 4800 Baud */,
1.54 + EUartBaudRate2400/* =bitmask for 2400 Baud */,
1.55 + EUartBaudRate1200/* =bitmask for 1200 Baud */,
1.56 + EUartBaudRate600/* =bitmask for 600 Baud */,
1.57 + EUartBaudRate300/* =bitmask for 300 Baud */,
1.58 + EUartBaudRate150/* =bitmask for 150 Baud */,
1.59 + EUartBaudRate110/* =bitmask for 110 Baud */
1.60 + };
1.61 +// EXAMPLE ONLY
1.62 +enum TUartBreak
1.63 + {
1.64 + EUartBreakOff/* =bitmask for turning Break Off */,
1.65 + EUartBreakOn/* =bitmask for turning Break On */
1.66 + };
1.67 +// EXAMPLE ONLY
1.68 +enum TUartParity
1.69 + {
1.70 + EUartParityNone/* =bitmask for no Parity */,
1.71 + EUartParityOdd/* =bitmask for odd Parity */,
1.72 + EUartParityEven/* =bitmask for even Parity */
1.73 + };
1.74 +// EXAMPLE ONLY
1.75 +enum TUartStopBit
1.76 + {
1.77 + EUartStopBitOne/* =bitmask for one stop bit */,
1.78 + EUartStopBitTwo/* =bitmask for two stop bits */
1.79 + };
1.80 +enum TUartDataLength
1.81 + {
1.82 + EUartDataLength5/* =bitmask for five data bits */,
1.83 + EUartDataLength6/* =bitmask for six data bits */,
1.84 + EUartDataLength7/* =bitmask for seven data bits */,
1.85 + EUartDataLength8/* =bitmask for eight data bits */
1.86 + };
1.87 +
1.88 +//
1.89 +// TO DO: (mandatory)
1.90 +//
1.91 +// Lookup table to convert EPOC baud rates into hardware-specific baud rate values
1.92 +// Unsupported baud rates select the nearest lower rate.
1.93 +//
1.94 +// EXAMPLE ONLY
1.95 +static const TUartBaudRate BaudRate[19] =
1.96 + {
1.97 + EUartBaudRate110,EUartBaudRate110,EUartBaudRate110,
1.98 + EUartBaudRate110,EUartBaudRate150,EUartBaudRate300,
1.99 + EUartBaudRate600,EUartBaudRate1200,EUartBaudRate110,
1.100 + EUartBaudRate110,EUartBaudRate2400,EUartBaudRate110,
1.101 + EUartBaudRate4800,EUartBaudRate110,EUartBaudRate9600,
1.102 + EUartBaudRate19200,EUartBaudRate38400,EUartBaudRate57600,
1.103 + EUartBaudRate115200
1.104 + };
1.105 +
1.106 +//
1.107 +// TO DO: (mandatory)
1.108 +//
1.109 +// Lookup table to convert EPOC parity settings into hardware-specific values
1.110 +//
1.111 +// EXAMPLE ONLY
1.112 +static const TUartParity Parity[3] =
1.113 + {
1.114 + EUartParityNone,EUartParityEven,EUartParityOdd
1.115 + };
1.116 +
1.117 +//
1.118 +// TO DO: (mandatory)
1.119 +//
1.120 +// Lookup table to convert EPOC stop bit values into hardware-specific values
1.121 +//
1.122 +// EXAMPLE ONLY
1.123 +static const TUartStopBit StopBit[2] =
1.124 + {
1.125 + EUartStopBitOne,EUartStopBitTwo
1.126 + };
1.127 +
1.128 +//
1.129 +// TO DO: (mandatory)
1.130 +//
1.131 +// Lookup table to convert EPOC data bit settings into hardware-specific values
1.132 +//
1.133 +// EXAMPLE ONLY
1.134 +static const TUartDataLength DataLength[4] =
1.135 + {
1.136 + EUartDataLength5,EUartDataLength6,
1.137 + EUartDataLength7,EUartDataLength8
1.138 + };
1.139 +
1.140 +
1.141 +
1.142 +class DDriverComm : public DPhysicalDevice
1.143 + {
1.144 +public:
1.145 + DDriverComm();
1.146 + virtual TInt Install();
1.147 + virtual void GetCaps(TDes8 &aDes) const;
1.148 + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
1.149 + virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
1.150 + };
1.151 +
1.152 +class DCommTemplate : public DComm
1.153 + {
1.154 +public:
1.155 + DCommTemplate();
1.156 + ~DCommTemplate();
1.157 + TInt DoCreate(TInt aUnit, const TDesC8* anInfo);
1.158 +public:
1.159 + virtual TInt Start();
1.160 + virtual void Stop(TStopMode aMode);
1.161 + virtual void Break(TBool aState);
1.162 + virtual void EnableTransmit();
1.163 + virtual TUint Signals() const;
1.164 + virtual void SetSignals(TUint aSetMask,TUint aClearMask);
1.165 + virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const;
1.166 + virtual void Configure(TCommConfigV01 &aConfig);
1.167 + virtual void Caps(TDes8 &aCaps) const;
1.168 + virtual TInt DisableIrqs();
1.169 + virtual void RestoreIrqs(TInt aIrq);
1.170 + virtual TDfcQue* DfcQ(TInt aUnit);
1.171 + virtual void CheckConfig(TCommConfigV01& aConfig);
1.172 +public:
1.173 + static void Isr(TAny* aPtr);
1.174 +public:
1.175 + TInt iInterruptId;
1.176 + TInt iUnit;
1.177 + TLinAddr iPortAddr;
1.178 + TInt iInInterrupt;
1.179 + TUint iSignals;
1.180 + TDynamicDfcQue* iDfcQ;
1.181 + };
1.182 +
1.183 +
1.184 +DDriverComm::DDriverComm()
1.185 +//
1.186 +// Constructor
1.187 +//
1.188 + {
1.189 + //
1.190 + // TO DO: (mandatory)
1.191 + //
1.192 + // Set up iUnitMask with the number of Units (Serial Ports) supported by this PDD,
1.193 + // 1 bit set per Unit supported e.g.:
1.194 + // iUnitsMask=0x7; -> supports units 0, 1, 2
1.195 + //
1.196 + iVersion=TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber);
1.197 + }
1.198 +
1.199 +TInt DDriverComm::Install()
1.200 +//
1.201 +// Install the driver
1.202 +//
1.203 + {
1.204 +
1.205 + return SetName(&KPddName);
1.206 + }
1.207 +
1.208 +void GetTemplateCommsCaps(TDes8 &aCaps, TInt aUnit)
1.209 + {
1.210 + TCommCaps2 capsBuf;
1.211 + //
1.212 + // TO DO: (mandatory)
1.213 + //
1.214 + // Fill in the Caps structure with the relevant information for this Unit, e.g
1.215 + // TCommCapsV02 &c=capsBuf();
1.216 + // c.iRate=(OR in as many KCapsBpsXXX as bit rates supported);
1.217 + // c.iDataBits=(OR in as many KCapsDataXXX as data length configuration supported);
1.218 + // c.iStopBits=(OR in as many KCapsStopXXX as the number of stop bits configurations supported);
1.219 + // c.iParity=(OR in as many KCapsParityXXX as parity configuration supported);
1.220 + // c.iHandshake=(OR in all KCapsObeyXXXSupported, KCapsSendXXXSupported, KCapsFailXXXSupported, KCapsFreeXXXSupported
1.221 + // as required for this Unit's configuration);.
1.222 + // c.iSignals=(OR in as many KCapsSignalXXXSupported as Modem control signals controllable by this Unit);
1.223 + // c.iSIR=(0 or OR in as many KCapsSIRXXX as IR bit rates supported);
1.224 + // c.iNotificationCaps=(OR in as many KNotifyXXXSupported as notifications supported by this Unit);
1.225 + // c.iFifo=(0 or KCapsHasFifo);
1.226 + // c.iRoleCaps=(0 or KCapsRoleSwitchSupported);
1.227 + // c.iFlowControlCaps=(0 or KCapsFlowControlStatusSupported);
1.228 + /** @see TCommCapsV02 */
1.229 + //
1.230 + aCaps.FillZ(aCaps.MaxLength());
1.231 + aCaps=capsBuf.Left(Min(capsBuf.Length(),aCaps.MaxLength()));
1.232 + }
1.233 +
1.234 +void DDriverComm::GetCaps(TDes8 &aDes) const
1.235 +//
1.236 +// Return the drivers capabilities
1.237 +//
1.238 + {
1.239 + GetTemplateCommsCaps(aDes, 0);
1.240 + }
1.241 +
1.242 +TInt DDriverComm::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
1.243 +//
1.244 +// Create a driver
1.245 +//
1.246 + {
1.247 + DCommTemplate* pD=new DCommTemplate;
1.248 + aChannel=pD;
1.249 + TInt r=KErrNoMemory;
1.250 + if (pD)
1.251 + r=pD->DoCreate(aUnit,anInfo);
1.252 + return r;
1.253 + }
1.254 +
1.255 +TInt DDriverComm::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer)
1.256 +//
1.257 +// Validate the requested configuration (Version and Unit)
1.258 +//
1.259 + {
1.260 + if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(KMinimumLddMajorVersion,KMinimumLddMinorVersion,KMinimumLddBuild))))
1.261 + return KErrNotSupported;
1.262 + //
1.263 + // TO DO: (mandatory)
1.264 + //
1.265 + // Return KErrNotSupported if aUnit is not in the supported range for this driver, KErrNone if it is
1.266 + //
1.267 + return KErrNone;
1.268 + }
1.269 +
1.270 +DCommTemplate::DCommTemplate()
1.271 +//
1.272 +// Constructor
1.273 +//
1.274 + {
1.275 + iInterruptId=-1; // -1 means not bound
1.276 + }
1.277 +
1.278 +DCommTemplate::~DCommTemplate()
1.279 +//
1.280 +// Destructor
1.281 +//
1.282 + {
1.283 + if (iInterruptId>=0)
1.284 + Interrupt::Unbind(iInterruptId);
1.285 +
1.286 + if (iDfcQ)
1.287 + {
1.288 + iDfcQ->Destroy();
1.289 + }
1.290 + }
1.291 +
1.292 +const TInt KDCommTemplDfcThreadPriority = 24;
1.293 +_LIT(KDCommTemplDfcThread,"DCommTemplDfcThread");
1.294 +
1.295 +TInt DCommTemplate::DoCreate(TInt aUnit, const TDesC8* /*anInfo*/)
1.296 +//
1.297 +// Sets up the PDD
1.298 +//
1.299 + {
1.300 + iUnit=aUnit;
1.301 + TInt irq=-1;
1.302 + //
1.303 + // TO DO: (mandatory)
1.304 + //
1.305 + // Create own DFC queue
1.306 + TInt r = Kern::DynamicDfcQCreate(iDfcQ, KDCommTemplDfcThreadPriority, KDCommTemplDfcThread);
1.307 +
1.308 + if (r != KErrNone)
1.309 + return r;
1.310 +
1.311 + // Set iPortAddr and irq with the Linear Base address of the UART and the Interrupt ID coresponding to aUnit
1.312 + //
1.313 +
1.314 + // bind to UART interrupt
1.315 + r=Interrupt::Bind(irq,Isr,this);
1.316 + if (r==KErrNone)
1.317 + iInterruptId=irq;
1.318 +
1.319 + //
1.320 + // TO DO: (optional)
1.321 + //
1.322 + // Any other setting up of UART hardware registers, required for:
1.323 + // - Disabling the UART operation
1.324 + // - disabling all UART Interrupts
1.325 + // - clearing all Rx errors
1.326 + // - clearing all UART interrupts
1.327 + // - de-activating output Modem Control signals
1.328 + //
1.329 +
1.330 + Variant::MarkDebugPortOff();
1.331 + return r;
1.332 + }
1.333 +
1.334 +TDfcQue* DCommTemplate::DfcQ(TInt aUnit)
1.335 +//
1.336 +// Return the DFC queue to be used for this device
1.337 +// For UARTs just use the standard low priority DFC queue
1.338 +// For Serial PC cards, use the PC card controller thread for the socket in question.
1.339 +//
1.340 + {
1.341 + return aUnit==iUnit ? iDfcQ : NULL;
1.342 + }
1.343 +
1.344 +TInt DCommTemplate::Start()
1.345 +//
1.346 +// Start receiving characters
1.347 +//
1.348 + {
1.349 + iTransmitting=EFalse; // if EnableTransmit() called before Start()
1.350 +
1.351 + //
1.352 + // TO DO: (mandatory)
1.353 + //
1.354 + // Set up hardware registers to enable the UART and switch receive mode on
1.355 + //
1.356 +
1.357 + // if (iUnit!=IR Port) TO DO: (mandatory): Implement
1.358 + {
1.359 + iSignals=Signals();
1.360 + iLdd->UpdateSignals(iSignals);
1.361 + }
1.362 +
1.363 + //
1.364 + // TO DO: (optional)
1.365 + //
1.366 + // If Unit is IR Port may need to start the IR port
1.367 + //
1.368 + Interrupt::Enable(iInterruptId);
1.369 + return KErrNone;
1.370 + }
1.371 +
1.372 +TBool FinishedTransmitting(TAny* aPtr)
1.373 + {
1.374 + //
1.375 + // TO DO: (mandatory)
1.376 + //
1.377 + // Return ETrue if UART is still transmitting, EFalse Otherwise
1.378 + //
1.379 + return EFalse; // EXAMPLE ONLY
1.380 + }
1.381 +
1.382 +void DCommTemplate::Stop(TStopMode aMode)
1.383 +//
1.384 +// Stop receiving characters
1.385 +//
1.386 + {
1.387 + switch (aMode)
1.388 + {
1.389 + case EStopNormal:
1.390 + case EStopPwrDown:
1.391 + Interrupt::Disable(iInterruptId);
1.392 + iTransmitting=EFalse;
1.393 +
1.394 + // wait for uart to stop tranmitting
1.395 + Kern::PollingWait(FinishedTransmitting,this,3,100);
1.396 +
1.397 + //
1.398 + // TO DO: (optional)
1.399 + //
1.400 + // Any other setting up of UART hardware registers, required for:
1.401 + // - Disabling the UART operation
1.402 + // - disabling all UART Interrupts
1.403 + // - disabling Transmit and Receive pathes
1.404 + // - clearing all UART interrupts
1.405 + //
1.406 + break;
1.407 + case EStopEmergency:
1.408 + Interrupt::Disable(iInterruptId);
1.409 + iTransmitting=EFalse;
1.410 + break;
1.411 + }
1.412 + //
1.413 + // TO DO: (optional)
1.414 + //
1.415 + // If Unit is IR Port may need to stop the IR port
1.416 + //
1.417 + Variant::MarkDebugPortOff();
1.418 + }
1.419 +
1.420 +void DCommTemplate::Break(TBool aState)
1.421 +//
1.422 +// Start or stop the uart breaking
1.423 +//
1.424 + {
1.425 + if (aState)
1.426 + {
1.427 + //
1.428 + // TO DO: (mandatory)
1.429 + //
1.430 + // Enable sending a Break (space) condition
1.431 + //
1.432 + }
1.433 + else
1.434 + {
1.435 + //
1.436 + // TO DO: (mandatory)
1.437 + //
1.438 + // Stop sending a Break (space) condition
1.439 + //
1.440 + }
1.441 + }
1.442 +
1.443 +void DCommTemplate::EnableTransmit()
1.444 +//
1.445 +// Start sending characters.
1.446 +//
1.447 + {
1.448 + TBool tx = (TBool)__e32_atomic_swp_ord32(&iTransmitting, 1);
1.449 + if (tx)
1.450 + return;
1.451 + TInt r = 0;
1.452 + while (/* (Transmit FIFO Not full) && */ Kern::PowerGood()) // TO DO: (mandatory): Implement
1.453 + {
1.454 + TInt r=TransmitIsr();
1.455 + if(r<0)
1.456 + {
1.457 + //no more to send
1.458 + iTransmitting=EFalse;
1.459 + break;
1.460 + }
1.461 + //
1.462 + // TO DO: (mandatory)
1.463 + //
1.464 + // Write transmit character into transmit FIFO or output register
1.465 + //
1.466 + }
1.467 + TInt irq=0;
1.468 + if (!iInInterrupt) // CheckTxBuffer adds a Dfc: can only run from ISR or with NKernel locked
1.469 + {
1.470 + NKern::Lock();
1.471 + irq=NKern::DisableAllInterrupts();
1.472 + }
1.473 + CheckTxBuffer();
1.474 + if (!iInInterrupt)
1.475 + {
1.476 + NKern::RestoreInterrupts(irq);
1.477 + NKern::Unlock();
1.478 + }
1.479 + //
1.480 + // TO DO: (mandatory)
1.481 + //
1.482 + // Enable transmission of data
1.483 + //
1.484 + if (r>=0) // only enable interrupt if there's more data to send
1.485 + {
1.486 + //
1.487 + // TO DO: (mandatory)
1.488 + //
1.489 + // Enable transmit interrupt in the Hardware (Interrupt::Enable() has already been called in Start())
1.490 + //
1.491 + }
1.492 + }
1.493 +
1.494 +TUint DCommTemplate::Signals() const
1.495 +//
1.496 +// Read and translate the modem lines
1.497 +//
1.498 + {
1.499 + TUint signals=0;
1.500 + //
1.501 + // TO DO: (mandatory)
1.502 + //
1.503 + // If the UART corresponding to iUnit supports Modem Control Signals, read them and return a bitmask with one or
1.504 + // more of the following OR-ed in:
1.505 + // - KSignalDTR,
1.506 + // - KSignalRTS,
1.507 + // - KSignalDSR,
1.508 + // - KSignalCTS,
1.509 + // - KSignalDCD.
1.510 + //
1.511 + return signals;
1.512 + }
1.513 +
1.514 +void DCommTemplate::SetSignals(TUint aSetMask, TUint aClearMask)
1.515 +//
1.516 +// Set signals.
1.517 +//
1.518 + {
1.519 + //
1.520 + // TO DO: (mandatory)
1.521 + //
1.522 + // If the UART corresponding to iUnit supports Modem Control Signals, converts the flags in aSetMask and aClearMask
1.523 + // into hardware-specific bitmasks to write to the UART modem/handshake output register(s).
1.524 + // aSetMask, aClearMask will have one or more of the following OR-ed in:
1.525 + // - KSignalDTR,
1.526 + // - KSignalRTS,
1.527 + //
1.528 + }
1.529 +
1.530 +TInt DCommTemplate::ValidateConfig(const TCommConfigV01 &aConfig) const
1.531 +//
1.532 +// Check a config structure.
1.533 +//
1.534 + {
1.535 + //
1.536 + // TO DO: (mandatory)
1.537 + //
1.538 + // Checks the the options in aConfig are supported by the UART corresponding to iUnit
1.539 + // May need to check:
1.540 + // - aConfig.iParity (contains one of EParityXXX)
1.541 + /** @see TParity */
1.542 + // - aConfig.iRate (contains one of EBpsXXX)
1.543 + /** @see TBps */
1.544 + // - aConfig.iDataBits (contains one of EDataXXX)
1.545 + /** @see TDataBits */
1.546 + // - aConfig.iStopBits (contains one of EStopXXX)
1.547 + /** @see TDataBits */
1.548 + // - aConfig.iHandshake (contains one of KConfigObeyXXX or KConfigSendXXX or KConfigFailXXX or KConfigFreeXXX)
1.549 + // - aConfig.iParityError (contains KConfigParityErrorFail or KConfigParityErrorIgnore or KConfigParityErrorReplaceChar)
1.550 + // - aConfig.iFifo (contains ether EFifoEnable or EFifoDisable)
1.551 + /** @see TFifo */
1.552 + // - aConfig.iSpecialRate (may contain a rate not listed under TBps)
1.553 + // - aConfig.iTerminatorCount (conatains number of special characters used as terminators)
1.554 + // - aConfig.iTerminator[] (contains a list of special characters which can be used as terminators)
1.555 + // - aConfig.iXonChar (contains the character used as XON - software flow control)
1.556 + // - aConfig.iXoffChar (contains the character used as XOFF - software flow control)
1.557 + // - aConfig.iParityErrorChar (contains the character used to replace bytes received with a parity error)
1.558 + // - aConfig.iSIREnable (contains either ESIREnable or ESIRDisable)
1.559 + /** @see TSir */
1.560 + // - aConfig.iSIRSettings (contains one of KConfigSIRXXX)
1.561 + // and returns KErrNotSupported if the UART corresponding to iUnit does not support this configuration
1.562 + //
1.563 + return KErrNone;
1.564 + }
1.565 +
1.566 +void DCommTemplate::CheckConfig(TCommConfigV01& aConfig)
1.567 + {
1.568 + //
1.569 + // TO DO: (optional)
1.570 + //
1.571 + // Validates the default configuration that is defined when a channel is first opened
1.572 + //
1.573 + }
1.574 +
1.575 +TInt DCommTemplate::DisableIrqs()
1.576 +//
1.577 +// Disable normal interrupts
1.578 +//
1.579 + {
1.580 +
1.581 + return NKern::DisableInterrupts(1);
1.582 + }
1.583 +
1.584 +void DCommTemplate::RestoreIrqs(TInt aLevel)
1.585 +//
1.586 +// Restore normal interrupts
1.587 +//
1.588 + {
1.589 +
1.590 + NKern::RestoreInterrupts(aLevel);
1.591 + }
1.592 +
1.593 +void DCommTemplate::Configure(TCommConfigV01 &aConfig)
1.594 +//
1.595 +// Configure the UART from aConfig
1.596 +//
1.597 + {
1.598 + Kern::PollingWait(FinishedTransmitting,this,3,100); // wait for uart to stop tranmitting
1.599 +
1.600 + //
1.601 + // TO DO: (optional)
1.602 + //
1.603 + // Ensure Tx, Rx and the UART are disabled and disable sending Break (space) condition.
1.604 + // May need to modify clocks settings, pin functions etc.
1.605 + //
1.606 +
1.607 + //
1.608 + // TO DO: (mandatory)
1.609 + //
1.610 + // Set communications parameters such as:
1.611 + // - Baud rate
1.612 + // - Parity
1.613 + // - Stop bits
1.614 + // - Data bits
1.615 + // These can be obtained from aConfig using the look-up tables above, e.g.
1.616 + // TUint baudRate=BaudRate[aConfig.iRate];
1.617 + // TUint parity=Parity[aConfig.iParity];
1.618 + // TUint stopBits=StopBit[aConfig.iStopBits];
1.619 + // TUint dataBits=DataLength[aConfig.iDataBits];
1.620 + // Write these to the appropriate hardware registers using iPortAddr to identify which ste of register to modify
1.621 + //
1.622 +
1.623 + //
1.624 + // TO DO: (optional)
1.625 + //
1.626 + // If the UART corresponding to iUnit supports IR may need to set up IR transceiver
1.627 + //
1.628 + }
1.629 +
1.630 +void DCommTemplate::Caps(TDes8 &aCaps) const
1.631 +//
1.632 +// return our caps
1.633 +//
1.634 + {
1.635 + GetTemplateCommsCaps(aCaps,iUnit);
1.636 + }
1.637 +
1.638 +void DCommTemplate::Isr(TAny* aPtr)
1.639 +//
1.640 +// Service the UART interrupt
1.641 +//
1.642 + {
1.643 + DCommTemplate& d=*(DCommTemplate*)aPtr;
1.644 + d.iInInterrupt=1; // going in...
1.645 + // TUint portAddr=d.iPortAddr; TO DO: (mandatory): Uncomment this
1.646 +
1.647 + //
1.648 + // TO DO: (mandatory)
1.649 + //
1.650 + // Read the interrupt source register to determine if it is a Receive, Transmit or Modem Signals change interrupt.
1.651 + // If required also, clear interrupts at the source.
1.652 + // Then process the interrupt condition as in the following pseudo-code extract:
1.653 + //
1.654 + // if((Received character Interrupts) || (Error in received character Interupt)) TO DO: (mandatory): Implement
1.655 + {
1.656 + TUint rx[32];
1.657 + TUint xon=d.iLdd->iRxXonChar;
1.658 + TUint xoff=d.iLdd->iRxXoffChar;
1.659 + TInt rxi=0;
1.660 + TInt x=0;
1.661 + TUint ch=0;
1.662 + // while((Receive FIFO not empty) && Kern::PowerGood()) TO DO: (mandatory): Implement
1.663 + {
1.664 + TUint regStatus1=0;
1.665 + // NOTE: for some hardware the order the following 2 operations is performed may have to be reversed
1.666 + // if(Error in received character interrupt) TO DO: (mandatory): Implement
1.667 + // regStatus1=(Read receive error bitmask off appropriate register);
1.668 + // ch=(Read received character);
1.669 +
1.670 + // coverity[dead_error_condition]
1.671 + // The next line should be reachable when this template file is edited for use
1.672 + if(regStatus1!=0) // if error in this character
1.673 + {
1.674 + // if (ch & (Parity Error)) TO DO: (mandatory): Implement
1.675 + ch|=KReceiveIsrParityError;
1.676 + // if (ch & (Framing Error)) TO DO: (mandatory): Implement
1.677 + ch|=KReceiveIsrFrameError;
1.678 + // if (ch & (Overrun)) TO DO: (mandatory): Implement
1.679 + ch|=KReceiveIsrOverrunError;
1.680 + }
1.681 + if (ch==xon)
1.682 + x=1;
1.683 + else if (ch==xoff)
1.684 + x=-1;
1.685 + else
1.686 + rx[rxi++]=ch;
1.687 + }
1.688 + d.ReceiveIsr(rx,rxi,x);
1.689 + }
1.690 + // if((Transmitted character Interrupt)) TO DO: (mandatory): Implement
1.691 + {
1.692 + while(/* (Transmit FIFO Not full) && */ Kern::PowerGood()) // TO DO: (mandatory): Implement
1.693 + {
1.694 + TInt r=d.TransmitIsr();
1.695 + if(r<0)
1.696 + {
1.697 + //no more to send
1.698 + //
1.699 + // TO DO: (mandatory)
1.700 + //
1.701 + // Disable the Transmit Interrupt in Hardware
1.702 + d.iTransmitting=EFalse;
1.703 + break;
1.704 + }
1.705 + // (write transmit character to output FIFO or Data register) TO DO: (mandatory): Implement
1.706 + }
1.707 + d.CheckTxBuffer();
1.708 + }
1.709 + // if((Modem Signals changed Interrupt)) TO DO: (mandatory): Implement
1.710 + {
1.711 + TUint signals=d.Signals()&KDTEInputSignals;
1.712 + if (signals != d.iSignals)
1.713 + {
1.714 + d.iSignals=signals;
1.715 + d.iLdd->StateIsr(signals);
1.716 + }
1.717 + }
1.718 + d.iInInterrupt=0; // going out...
1.719 + }
1.720 +
1.721 +DECLARE_STANDARD_PDD()
1.722 + {
1.723 + return new DDriverComm;
1.724 + }
1.725 +