sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // template\template_variant\specific\uart.cpp sl@0: // pdd for serial ports sl@0: // assume Modem Control Signals change cause an interrupt sl@0: // sl@0: // sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include "iolines.h" sl@0: #include sl@0: sl@0: _LIT(KPddName,"Comm.Template"); sl@0: sl@0: // needs ldd version.. sl@0: const TInt KMinimumLddMajorVersion=1; sl@0: const TInt KMinimumLddMinorVersion=1; sl@0: const TInt KMinimumLddBuild=122; sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Define here the UART enumeration data for the serial ports. sl@0: // 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) sl@0: // a hardware register to provide the configuration option desired (the following are EXAMPLES ONLY): sl@0: // sl@0: // EXAMPLE ONLY sl@0: enum TUartBaudRate sl@0: { sl@0: EUartBaudRate115200/* =bitmask for 115200 Baud */, sl@0: EUartBaudRate76800/* =bitmask for 76800 Baud */, sl@0: EUartBaudRate57600/* =bitmask for 57600 Baud */, sl@0: EUartBaudRate38400/* =bitmask for 38400 Baud */, sl@0: EUartBaudRate19200/* =bitmask for 19200 Baud */, sl@0: EUartBaudRate14400/* =bitmask for 14400 Baud */, sl@0: EUartBaudRate9600/* =bitmask for 9600 Baud */, sl@0: EUartBaudRate4800/* =bitmask for 4800 Baud */, sl@0: EUartBaudRate2400/* =bitmask for 2400 Baud */, sl@0: EUartBaudRate1200/* =bitmask for 1200 Baud */, sl@0: EUartBaudRate600/* =bitmask for 600 Baud */, sl@0: EUartBaudRate300/* =bitmask for 300 Baud */, sl@0: EUartBaudRate150/* =bitmask for 150 Baud */, sl@0: EUartBaudRate110/* =bitmask for 110 Baud */ sl@0: }; sl@0: // EXAMPLE ONLY sl@0: enum TUartBreak sl@0: { sl@0: EUartBreakOff/* =bitmask for turning Break Off */, sl@0: EUartBreakOn/* =bitmask for turning Break On */ sl@0: }; sl@0: // EXAMPLE ONLY sl@0: enum TUartParity sl@0: { sl@0: EUartParityNone/* =bitmask for no Parity */, sl@0: EUartParityOdd/* =bitmask for odd Parity */, sl@0: EUartParityEven/* =bitmask for even Parity */ sl@0: }; sl@0: // EXAMPLE ONLY sl@0: enum TUartStopBit sl@0: { sl@0: EUartStopBitOne/* =bitmask for one stop bit */, sl@0: EUartStopBitTwo/* =bitmask for two stop bits */ sl@0: }; sl@0: enum TUartDataLength sl@0: { sl@0: EUartDataLength5/* =bitmask for five data bits */, sl@0: EUartDataLength6/* =bitmask for six data bits */, sl@0: EUartDataLength7/* =bitmask for seven data bits */, sl@0: EUartDataLength8/* =bitmask for eight data bits */ sl@0: }; sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Lookup table to convert EPOC baud rates into hardware-specific baud rate values sl@0: // Unsupported baud rates select the nearest lower rate. sl@0: // sl@0: // EXAMPLE ONLY sl@0: static const TUartBaudRate BaudRate[19] = sl@0: { sl@0: EUartBaudRate110,EUartBaudRate110,EUartBaudRate110, sl@0: EUartBaudRate110,EUartBaudRate150,EUartBaudRate300, sl@0: EUartBaudRate600,EUartBaudRate1200,EUartBaudRate110, sl@0: EUartBaudRate110,EUartBaudRate2400,EUartBaudRate110, sl@0: EUartBaudRate4800,EUartBaudRate110,EUartBaudRate9600, sl@0: EUartBaudRate19200,EUartBaudRate38400,EUartBaudRate57600, sl@0: EUartBaudRate115200 sl@0: }; sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Lookup table to convert EPOC parity settings into hardware-specific values sl@0: // sl@0: // EXAMPLE ONLY sl@0: static const TUartParity Parity[3] = sl@0: { sl@0: EUartParityNone,EUartParityEven,EUartParityOdd sl@0: }; sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Lookup table to convert EPOC stop bit values into hardware-specific values sl@0: // sl@0: // EXAMPLE ONLY sl@0: static const TUartStopBit StopBit[2] = sl@0: { sl@0: EUartStopBitOne,EUartStopBitTwo sl@0: }; sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Lookup table to convert EPOC data bit settings into hardware-specific values sl@0: // sl@0: // EXAMPLE ONLY sl@0: static const TUartDataLength DataLength[4] = sl@0: { sl@0: EUartDataLength5,EUartDataLength6, sl@0: EUartDataLength7,EUartDataLength8 sl@0: }; sl@0: sl@0: sl@0: sl@0: class DDriverComm : public DPhysicalDevice sl@0: { sl@0: public: sl@0: DDriverComm(); sl@0: virtual TInt Install(); sl@0: virtual void GetCaps(TDes8 &aDes) const; sl@0: virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); sl@0: virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); sl@0: }; sl@0: sl@0: class DCommTemplate : public DComm sl@0: { sl@0: public: sl@0: DCommTemplate(); sl@0: ~DCommTemplate(); sl@0: TInt DoCreate(TInt aUnit, const TDesC8* anInfo); sl@0: public: sl@0: virtual TInt Start(); sl@0: virtual void Stop(TStopMode aMode); sl@0: virtual void Break(TBool aState); sl@0: virtual void EnableTransmit(); sl@0: virtual TUint Signals() const; sl@0: virtual void SetSignals(TUint aSetMask,TUint aClearMask); sl@0: virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const; sl@0: virtual void Configure(TCommConfigV01 &aConfig); sl@0: virtual void Caps(TDes8 &aCaps) const; sl@0: virtual TInt DisableIrqs(); sl@0: virtual void RestoreIrqs(TInt aIrq); sl@0: virtual TDfcQue* DfcQ(TInt aUnit); sl@0: virtual void CheckConfig(TCommConfigV01& aConfig); sl@0: public: sl@0: static void Isr(TAny* aPtr); sl@0: public: sl@0: TInt iInterruptId; sl@0: TInt iUnit; sl@0: TLinAddr iPortAddr; sl@0: TInt iInInterrupt; sl@0: TUint iSignals; sl@0: TDynamicDfcQue* iDfcQ; sl@0: }; sl@0: sl@0: sl@0: DDriverComm::DDriverComm() sl@0: // sl@0: // Constructor sl@0: // sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Set up iUnitMask with the number of Units (Serial Ports) supported by this PDD, sl@0: // 1 bit set per Unit supported e.g.: sl@0: // iUnitsMask=0x7; -> supports units 0, 1, 2 sl@0: // sl@0: iVersion=TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber); sl@0: } sl@0: sl@0: TInt DDriverComm::Install() sl@0: // sl@0: // Install the driver sl@0: // sl@0: { sl@0: sl@0: return SetName(&KPddName); sl@0: } sl@0: sl@0: void GetTemplateCommsCaps(TDes8 &aCaps, TInt aUnit) sl@0: { sl@0: TCommCaps2 capsBuf; sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Fill in the Caps structure with the relevant information for this Unit, e.g sl@0: // TCommCapsV02 &c=capsBuf(); sl@0: // c.iRate=(OR in as many KCapsBpsXXX as bit rates supported); sl@0: // c.iDataBits=(OR in as many KCapsDataXXX as data length configuration supported); sl@0: // c.iStopBits=(OR in as many KCapsStopXXX as the number of stop bits configurations supported); sl@0: // c.iParity=(OR in as many KCapsParityXXX as parity configuration supported); sl@0: // c.iHandshake=(OR in all KCapsObeyXXXSupported, KCapsSendXXXSupported, KCapsFailXXXSupported, KCapsFreeXXXSupported sl@0: // as required for this Unit's configuration);. sl@0: // c.iSignals=(OR in as many KCapsSignalXXXSupported as Modem control signals controllable by this Unit); sl@0: // c.iSIR=(0 or OR in as many KCapsSIRXXX as IR bit rates supported); sl@0: // c.iNotificationCaps=(OR in as many KNotifyXXXSupported as notifications supported by this Unit); sl@0: // c.iFifo=(0 or KCapsHasFifo); sl@0: // c.iRoleCaps=(0 or KCapsRoleSwitchSupported); sl@0: // c.iFlowControlCaps=(0 or KCapsFlowControlStatusSupported); sl@0: /** @see TCommCapsV02 */ sl@0: // sl@0: aCaps.FillZ(aCaps.MaxLength()); sl@0: aCaps=capsBuf.Left(Min(capsBuf.Length(),aCaps.MaxLength())); sl@0: } sl@0: sl@0: void DDriverComm::GetCaps(TDes8 &aDes) const sl@0: // sl@0: // Return the drivers capabilities sl@0: // sl@0: { sl@0: GetTemplateCommsCaps(aDes, 0); sl@0: } sl@0: sl@0: TInt DDriverComm::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer) sl@0: // sl@0: // Create a driver sl@0: // sl@0: { sl@0: DCommTemplate* pD=new DCommTemplate; sl@0: aChannel=pD; sl@0: TInt r=KErrNoMemory; sl@0: if (pD) sl@0: r=pD->DoCreate(aUnit,anInfo); sl@0: return r; sl@0: } sl@0: sl@0: TInt DDriverComm::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer) sl@0: // sl@0: // Validate the requested configuration (Version and Unit) sl@0: // sl@0: { sl@0: if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(KMinimumLddMajorVersion,KMinimumLddMinorVersion,KMinimumLddBuild)))) sl@0: return KErrNotSupported; sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Return KErrNotSupported if aUnit is not in the supported range for this driver, KErrNone if it is sl@0: // sl@0: return KErrNone; sl@0: } sl@0: sl@0: DCommTemplate::DCommTemplate() sl@0: // sl@0: // Constructor sl@0: // sl@0: { sl@0: iInterruptId=-1; // -1 means not bound sl@0: } sl@0: sl@0: DCommTemplate::~DCommTemplate() sl@0: // sl@0: // Destructor sl@0: // sl@0: { sl@0: if (iInterruptId>=0) sl@0: Interrupt::Unbind(iInterruptId); sl@0: sl@0: if (iDfcQ) sl@0: { sl@0: iDfcQ->Destroy(); sl@0: } sl@0: } sl@0: sl@0: const TInt KDCommTemplDfcThreadPriority = 24; sl@0: _LIT(KDCommTemplDfcThread,"DCommTemplDfcThread"); sl@0: sl@0: TInt DCommTemplate::DoCreate(TInt aUnit, const TDesC8* /*anInfo*/) sl@0: // sl@0: // Sets up the PDD sl@0: // sl@0: { sl@0: iUnit=aUnit; sl@0: TInt irq=-1; sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Create own DFC queue sl@0: TInt r = Kern::DynamicDfcQCreate(iDfcQ, KDCommTemplDfcThreadPriority, KDCommTemplDfcThread); sl@0: sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // Set iPortAddr and irq with the Linear Base address of the UART and the Interrupt ID coresponding to aUnit sl@0: // sl@0: sl@0: // bind to UART interrupt sl@0: r=Interrupt::Bind(irq,Isr,this); sl@0: if (r==KErrNone) sl@0: iInterruptId=irq; sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Any other setting up of UART hardware registers, required for: sl@0: // - Disabling the UART operation sl@0: // - disabling all UART Interrupts sl@0: // - clearing all Rx errors sl@0: // - clearing all UART interrupts sl@0: // - de-activating output Modem Control signals sl@0: // sl@0: sl@0: Variant::MarkDebugPortOff(); sl@0: return r; sl@0: } sl@0: sl@0: TDfcQue* DCommTemplate::DfcQ(TInt aUnit) sl@0: // sl@0: // Return the DFC queue to be used for this device sl@0: // For UARTs just use the standard low priority DFC queue sl@0: // For Serial PC cards, use the PC card controller thread for the socket in question. sl@0: // sl@0: { sl@0: return aUnit==iUnit ? iDfcQ : NULL; sl@0: } sl@0: sl@0: TInt DCommTemplate::Start() sl@0: // sl@0: // Start receiving characters sl@0: // sl@0: { sl@0: iTransmitting=EFalse; // if EnableTransmit() called before Start() sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Set up hardware registers to enable the UART and switch receive mode on sl@0: // sl@0: sl@0: // if (iUnit!=IR Port) TO DO: (mandatory): Implement sl@0: { sl@0: iSignals=Signals(); sl@0: iLdd->UpdateSignals(iSignals); sl@0: } sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // If Unit is IR Port may need to start the IR port sl@0: // sl@0: Interrupt::Enable(iInterruptId); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TBool FinishedTransmitting(TAny* aPtr) sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Return ETrue if UART is still transmitting, EFalse Otherwise sl@0: // sl@0: return EFalse; // EXAMPLE ONLY sl@0: } sl@0: sl@0: void DCommTemplate::Stop(TStopMode aMode) sl@0: // sl@0: // Stop receiving characters sl@0: // sl@0: { sl@0: switch (aMode) sl@0: { sl@0: case EStopNormal: sl@0: case EStopPwrDown: sl@0: Interrupt::Disable(iInterruptId); sl@0: iTransmitting=EFalse; sl@0: sl@0: // wait for uart to stop tranmitting sl@0: Kern::PollingWait(FinishedTransmitting,this,3,100); sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Any other setting up of UART hardware registers, required for: sl@0: // - Disabling the UART operation sl@0: // - disabling all UART Interrupts sl@0: // - disabling Transmit and Receive pathes sl@0: // - clearing all UART interrupts sl@0: // sl@0: break; sl@0: case EStopEmergency: sl@0: Interrupt::Disable(iInterruptId); sl@0: iTransmitting=EFalse; sl@0: break; sl@0: } sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // If Unit is IR Port may need to stop the IR port sl@0: // sl@0: Variant::MarkDebugPortOff(); sl@0: } sl@0: sl@0: void DCommTemplate::Break(TBool aState) sl@0: // sl@0: // Start or stop the uart breaking sl@0: // sl@0: { sl@0: if (aState) sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Enable sending a Break (space) condition sl@0: // sl@0: } sl@0: else sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Stop sending a Break (space) condition sl@0: // sl@0: } sl@0: } sl@0: sl@0: void DCommTemplate::EnableTransmit() sl@0: // sl@0: // Start sending characters. sl@0: // sl@0: { sl@0: TBool tx = (TBool)__e32_atomic_swp_ord32(&iTransmitting, 1); sl@0: if (tx) sl@0: return; sl@0: TInt r = 0; sl@0: while (/* (Transmit FIFO Not full) && */ Kern::PowerGood()) // TO DO: (mandatory): Implement sl@0: { sl@0: TInt r=TransmitIsr(); sl@0: if(r<0) sl@0: { sl@0: //no more to send sl@0: iTransmitting=EFalse; sl@0: break; sl@0: } sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Write transmit character into transmit FIFO or output register sl@0: // sl@0: } sl@0: TInt irq=0; sl@0: if (!iInInterrupt) // CheckTxBuffer adds a Dfc: can only run from ISR or with NKernel locked sl@0: { sl@0: NKern::Lock(); sl@0: irq=NKern::DisableAllInterrupts(); sl@0: } sl@0: CheckTxBuffer(); sl@0: if (!iInInterrupt) sl@0: { sl@0: NKern::RestoreInterrupts(irq); sl@0: NKern::Unlock(); sl@0: } sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Enable transmission of data sl@0: // sl@0: if (r>=0) // only enable interrupt if there's more data to send sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Enable transmit interrupt in the Hardware (Interrupt::Enable() has already been called in Start()) sl@0: // sl@0: } sl@0: } sl@0: sl@0: TUint DCommTemplate::Signals() const sl@0: // sl@0: // Read and translate the modem lines sl@0: // sl@0: { sl@0: TUint signals=0; sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // If the UART corresponding to iUnit supports Modem Control Signals, read them and return a bitmask with one or sl@0: // more of the following OR-ed in: sl@0: // - KSignalDTR, sl@0: // - KSignalRTS, sl@0: // - KSignalDSR, sl@0: // - KSignalCTS, sl@0: // - KSignalDCD. sl@0: // sl@0: return signals; sl@0: } sl@0: sl@0: void DCommTemplate::SetSignals(TUint aSetMask, TUint aClearMask) sl@0: // sl@0: // Set signals. sl@0: // sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // If the UART corresponding to iUnit supports Modem Control Signals, converts the flags in aSetMask and aClearMask sl@0: // into hardware-specific bitmasks to write to the UART modem/handshake output register(s). sl@0: // aSetMask, aClearMask will have one or more of the following OR-ed in: sl@0: // - KSignalDTR, sl@0: // - KSignalRTS, sl@0: // sl@0: } sl@0: sl@0: TInt DCommTemplate::ValidateConfig(const TCommConfigV01 &aConfig) const sl@0: // sl@0: // Check a config structure. sl@0: // sl@0: { sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Checks the the options in aConfig are supported by the UART corresponding to iUnit sl@0: // May need to check: sl@0: // - aConfig.iParity (contains one of EParityXXX) sl@0: /** @see TParity */ sl@0: // - aConfig.iRate (contains one of EBpsXXX) sl@0: /** @see TBps */ sl@0: // - aConfig.iDataBits (contains one of EDataXXX) sl@0: /** @see TDataBits */ sl@0: // - aConfig.iStopBits (contains one of EStopXXX) sl@0: /** @see TDataBits */ sl@0: // - aConfig.iHandshake (contains one of KConfigObeyXXX or KConfigSendXXX or KConfigFailXXX or KConfigFreeXXX) sl@0: // - aConfig.iParityError (contains KConfigParityErrorFail or KConfigParityErrorIgnore or KConfigParityErrorReplaceChar) sl@0: // - aConfig.iFifo (contains ether EFifoEnable or EFifoDisable) sl@0: /** @see TFifo */ sl@0: // - aConfig.iSpecialRate (may contain a rate not listed under TBps) sl@0: // - aConfig.iTerminatorCount (conatains number of special characters used as terminators) sl@0: // - aConfig.iTerminator[] (contains a list of special characters which can be used as terminators) sl@0: // - aConfig.iXonChar (contains the character used as XON - software flow control) sl@0: // - aConfig.iXoffChar (contains the character used as XOFF - software flow control) sl@0: // - aConfig.iParityErrorChar (contains the character used to replace bytes received with a parity error) sl@0: // - aConfig.iSIREnable (contains either ESIREnable or ESIRDisable) sl@0: /** @see TSir */ sl@0: // - aConfig.iSIRSettings (contains one of KConfigSIRXXX) sl@0: // and returns KErrNotSupported if the UART corresponding to iUnit does not support this configuration sl@0: // sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DCommTemplate::CheckConfig(TCommConfigV01& aConfig) sl@0: { sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Validates the default configuration that is defined when a channel is first opened sl@0: // sl@0: } sl@0: sl@0: TInt DCommTemplate::DisableIrqs() sl@0: // sl@0: // Disable normal interrupts sl@0: // sl@0: { sl@0: sl@0: return NKern::DisableInterrupts(1); sl@0: } sl@0: sl@0: void DCommTemplate::RestoreIrqs(TInt aLevel) sl@0: // sl@0: // Restore normal interrupts sl@0: // sl@0: { sl@0: sl@0: NKern::RestoreInterrupts(aLevel); sl@0: } sl@0: sl@0: void DCommTemplate::Configure(TCommConfigV01 &aConfig) sl@0: // sl@0: // Configure the UART from aConfig sl@0: // sl@0: { sl@0: Kern::PollingWait(FinishedTransmitting,this,3,100); // wait for uart to stop tranmitting sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // Ensure Tx, Rx and the UART are disabled and disable sending Break (space) condition. sl@0: // May need to modify clocks settings, pin functions etc. sl@0: // sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Set communications parameters such as: sl@0: // - Baud rate sl@0: // - Parity sl@0: // - Stop bits sl@0: // - Data bits sl@0: // These can be obtained from aConfig using the look-up tables above, e.g. sl@0: // TUint baudRate=BaudRate[aConfig.iRate]; sl@0: // TUint parity=Parity[aConfig.iParity]; sl@0: // TUint stopBits=StopBit[aConfig.iStopBits]; sl@0: // TUint dataBits=DataLength[aConfig.iDataBits]; sl@0: // Write these to the appropriate hardware registers using iPortAddr to identify which ste of register to modify sl@0: // sl@0: sl@0: // sl@0: // TO DO: (optional) sl@0: // sl@0: // If the UART corresponding to iUnit supports IR may need to set up IR transceiver sl@0: // sl@0: } sl@0: sl@0: void DCommTemplate::Caps(TDes8 &aCaps) const sl@0: // sl@0: // return our caps sl@0: // sl@0: { sl@0: GetTemplateCommsCaps(aCaps,iUnit); sl@0: } sl@0: sl@0: void DCommTemplate::Isr(TAny* aPtr) sl@0: // sl@0: // Service the UART interrupt sl@0: // sl@0: { sl@0: DCommTemplate& d=*(DCommTemplate*)aPtr; sl@0: d.iInInterrupt=1; // going in... sl@0: // TUint portAddr=d.iPortAddr; TO DO: (mandatory): Uncomment this sl@0: sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Read the interrupt source register to determine if it is a Receive, Transmit or Modem Signals change interrupt. sl@0: // If required also, clear interrupts at the source. sl@0: // Then process the interrupt condition as in the following pseudo-code extract: sl@0: // sl@0: // if((Received character Interrupts) || (Error in received character Interupt)) TO DO: (mandatory): Implement sl@0: { sl@0: TUint rx[32]; sl@0: TUint xon=d.iLdd->iRxXonChar; sl@0: TUint xoff=d.iLdd->iRxXoffChar; sl@0: TInt rxi=0; sl@0: TInt x=0; sl@0: TUint ch=0; sl@0: // while((Receive FIFO not empty) && Kern::PowerGood()) TO DO: (mandatory): Implement sl@0: { sl@0: TUint regStatus1=0; sl@0: // NOTE: for some hardware the order the following 2 operations is performed may have to be reversed sl@0: // if(Error in received character interrupt) TO DO: (mandatory): Implement sl@0: // regStatus1=(Read receive error bitmask off appropriate register); sl@0: // ch=(Read received character); sl@0: sl@0: // coverity[dead_error_condition] sl@0: // The next line should be reachable when this template file is edited for use sl@0: if(regStatus1!=0) // if error in this character sl@0: { sl@0: // if (ch & (Parity Error)) TO DO: (mandatory): Implement sl@0: ch|=KReceiveIsrParityError; sl@0: // if (ch & (Framing Error)) TO DO: (mandatory): Implement sl@0: ch|=KReceiveIsrFrameError; sl@0: // if (ch & (Overrun)) TO DO: (mandatory): Implement sl@0: ch|=KReceiveIsrOverrunError; sl@0: } sl@0: if (ch==xon) sl@0: x=1; sl@0: else if (ch==xoff) sl@0: x=-1; sl@0: else sl@0: rx[rxi++]=ch; sl@0: } sl@0: d.ReceiveIsr(rx,rxi,x); sl@0: } sl@0: // if((Transmitted character Interrupt)) TO DO: (mandatory): Implement sl@0: { sl@0: while(/* (Transmit FIFO Not full) && */ Kern::PowerGood()) // TO DO: (mandatory): Implement sl@0: { sl@0: TInt r=d.TransmitIsr(); sl@0: if(r<0) sl@0: { sl@0: //no more to send sl@0: // sl@0: // TO DO: (mandatory) sl@0: // sl@0: // Disable the Transmit Interrupt in Hardware sl@0: d.iTransmitting=EFalse; sl@0: break; sl@0: } sl@0: // (write transmit character to output FIFO or Data register) TO DO: (mandatory): Implement sl@0: } sl@0: d.CheckTxBuffer(); sl@0: } sl@0: // if((Modem Signals changed Interrupt)) TO DO: (mandatory): Implement sl@0: { sl@0: TUint signals=d.Signals()&KDTEInputSignals; sl@0: if (signals != d.iSignals) sl@0: { sl@0: d.iSignals=signals; sl@0: d.iLdd->StateIsr(signals); sl@0: } sl@0: } sl@0: d.iInInterrupt=0; // going out... sl@0: } sl@0: sl@0: DECLARE_STANDARD_PDD() sl@0: { sl@0: return new DDriverComm; sl@0: } sl@0: