diff -r 2fb8b9db1c86 -r d55eb581a87c baseport/syborg/serial/syborg_serial.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/serial/syborg_serial.cpp Tue Aug 04 10:28:23 2009 +0100 @@ -0,0 +1,252 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Minimalistic serial driver +* +* TODO: Handle multiple Units, hardcoded FIFO Size +*/ + +#include "syborg_serial.h" + +//#define DPRINT(x) Kern::Printf(x) +//#define DPRINT2(x,y) Kern::Printf(x,y) + +#define DPRINT(x) +#define DPRINT2(x,y) + +// --------------------------------------------------------------- +// --------------------------------------------------------------- + +DDriverSyborgComm::DDriverSyborgComm() +{ + iVersion=TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber); +} + +TInt DDriverSyborgComm::Install() +{ + DPRINT("DDriverSyborgComm::Install"); + return SetName(&KPddName); +} + +void DDriverSyborgComm::GetCaps(TDes8 &aDes) const +{ + DPRINT("DDriverSyborgComm::GetCaps"); + + TCommCaps3 capsBuf; + TCommCapsV03 &c=capsBuf(); + c.iRate=KCapsBps110|KCapsBps150|KCapsBps300|KCapsBps600|KCapsBps1200|KCapsBps2400|KCapsBps4800|KCapsBps9600|KCapsBps19200|KCapsBps38400|KCapsBps57600|KCapsBps115200|KCapsBps230400; + c.iDataBits=KCapsData5|KCapsData6|KCapsData7|KCapsData8; + c.iStopBits=KCapsStop1|KCapsStop2; + c.iParity=KCapsParityNone|KCapsParityEven|KCapsParityOdd; + c.iHandshake=KCapsObeyXoffSupported|KCapsSendXoffSupported|KCapsObeyCTSSupported|KCapsFailCTSSupported|KCapsObeyDSRSupported|KCapsFailDSRSupported|KCapsObeyDCDSupported|KCapsFailDCDSupported|KCapsFreeRTSSupported|KCapsFreeDTRSupported; + c.iSignals=KCapsSignalCTSSupported|KCapsSignalDSRSupported|KCapsSignalDCDSupported|KCapsSignalRTSSupported|KCapsSignalDTRSupported; + c.iSIR=0; + c.iNotificationCaps=KNotifyDataAvailableSupported|KNotifySignalsChangeSupported; + c.iFifo=KCapsHasFifo; + c.iRoleCaps=0; + c.iFlowControlCaps=0; + c.iBreakSupported=ETrue; + aDes.FillZ(aDes.MaxLength()); + aDes=capsBuf.Left(Min(capsBuf.Length(),aDes.MaxLength())); +} + +TInt DDriverSyborgComm::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer) +{ + DPRINT("DDriverSyborgComm::Create"); + + DCommSyborgSoc* pD=new DCommSyborgSoc; + aChannel=pD; + TInt r=KErrNoMemory; + if (pD) + r=pD->DoCreate(aUnit,anInfo); + return r; +} + +TInt DDriverSyborgComm::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer) +{ + DPRINT("DDriverSyborgComm::Validate"); + if ((!Kern::QueryVersionSupported(iVersion,aVer)) || + (!Kern::QueryVersionSupported(aVer,TVersion(KMinimumLddMajorVersion,KMinimumLddMinorVersion,KMinimumLddBuild)))) + return KErrNotSupported; + return KErrNone; +} + +// --------------------------------------------------------------- +// --------------------------------------------------------------- + +DCommSyborgSoc::DCommSyborgSoc() +{ +} + +DCommSyborgSoc::~DCommSyborgSoc() +{ + Interrupt::Unbind(iIrq); +} + +TInt DCommSyborgSoc::DoCreate(TInt aUnit, const TDesC8* /*anInfo*/) +{ + DPRINT2("DCommSyborgSoc::DoCreate %d",aUnit); + switch(aUnit) + { + case 0: + iPortAddr = KHwBaseUart0; + iIrq = EIntSerial0; + break; + case 1: + iPortAddr = KHwBaseUart1; + iIrq = EIntSerial1; + break; + case 2: + iPortAddr = KHwBaseUart2; + iIrq = EIntSerial2; + break; + case 3: + iPortAddr = KHwBaseUart3; + iIrq = EIntSerial3; + break; + default: + iPortAddr = KHwBaseUart0; + iIrq = EIntSerial0; + break; + } + + Interrupt::Bind(EIntSerial0,Isr,this); + + return KErrNone; + +} + +TInt DCommSyborgSoc::Start() +{ + DPRINT("DCommSyborgSoc::Start"); + WriteReg(iPortAddr, SERIAL_INT_ENABLE, 0x1); + Interrupt::Enable(iIrq); + return KErrNone; +} + +void DCommSyborgSoc::Stop(TStopMode aMode) +{ + DPRINT("DCommSyborgSoc::Stop"); + WriteReg(iPortAddr, SERIAL_INT_ENABLE, 0x0); + Interrupt::Disable(iIrq); +} + +void DCommSyborgSoc::Break(TBool aState) +{ + DPRINT("DCommSyborgSoc::Break"); +} + +void DCommSyborgSoc::EnableTransmit() +{ + DPRINT("DCommSyborgSoc::EnableTransmit"); + while (Kern::PowerGood()) + { + TInt r=TransmitIsr(); + if (r<0) + break; + WriteReg(iPortAddr, SERIAL_DATA, r); + } +} + +TUint DCommSyborgSoc::Signals() const +{ + DPRINT("DCommSyborgSoc::Signals"); + return(0); +} + +void DCommSyborgSoc::SetSignals(TUint aSetMask, TUint aClearMask) +{ + DPRINT("DCommSyborgSoc::SetSignals"); +} + +TInt DCommSyborgSoc::ValidateConfig(const TCommConfigV01 &aConfig) const +{ + DPRINT("DCommSyborgSoc::ValidateConfig"); + return KErrNone; +} + +void DCommSyborgSoc::Configure(TCommConfigV01 &aConfig) +{ + DPRINT("DCommSyborgSoc::Configure"); +} + +void DCommSyborgSoc::Caps(TDes8 &aCaps) const +{ + DPRINT("DCommSyborgSoc::Caps"); + TCommCaps3 capsBuf; + TCommCapsV03 &c=capsBuf(); + c.iRate=KCapsBps110|KCapsBps150|KCapsBps300|KCapsBps600|KCapsBps1200|KCapsBps2400|KCapsBps4800|KCapsBps9600|KCapsBps19200|KCapsBps38400|KCapsBps57600|KCapsBps115200|KCapsBps230400; + c.iDataBits=KCapsData5|KCapsData6|KCapsData7|KCapsData8; + c.iStopBits=KCapsStop1|KCapsStop2; + c.iParity=KCapsParityNone|KCapsParityEven|KCapsParityOdd; + c.iHandshake=KCapsObeyXoffSupported|KCapsSendXoffSupported|KCapsObeyCTSSupported|KCapsFailCTSSupported|KCapsObeyDSRSupported|KCapsFailDSRSupported|KCapsObeyDCDSupported|KCapsFailDCDSupported|KCapsFreeRTSSupported|KCapsFreeDTRSupported; + c.iSignals=KCapsSignalCTSSupported|KCapsSignalDSRSupported|KCapsSignalDCDSupported|KCapsSignalRTSSupported|KCapsSignalDTRSupported; + c.iSIR=0; + c.iNotificationCaps=KNotifyDataAvailableSupported|KNotifySignalsChangeSupported; + c.iFifo=KCapsHasFifo; + c.iRoleCaps=0; + c.iFlowControlCaps=0; + c.iBreakSupported=ETrue; + aCaps.FillZ(aCaps.MaxLength()); + aCaps=capsBuf.Left(Min(capsBuf.Length(),aCaps.MaxLength())); +} + +TInt DCommSyborgSoc::DisableIrqs() +{ + DPRINT("DCommSyborgSoc::DisableIrqs"); + return NKern::DisableAllInterrupts(); +} + +void DCommSyborgSoc::RestoreIrqs(TInt aIrq) +{ + DPRINT("DCommSyborgSoc::RestoreIrqs"); + NKern::RestoreInterrupts(aIrq); +} + +TDfcQue* DCommSyborgSoc::DfcQ(TInt /*aUnit*/) +{ + return Kern::DfcQue0(); +} + +void DCommSyborgSoc::CheckConfig(TCommConfigV01& aConfig) +{ + DPRINT("DCommSyborgSoc::CheckConfig"); +} + +void DCommSyborgSoc::Isr(TAny* aPtr) +{ + DCommSyborgSoc& d=*(DCommSyborgSoc*)aPtr; + TUint rx[32]; + TInt rxi=0; + + DPRINT2("DCommSyborgSoc::Isr %x",d.iIrq); + + // Is now auto clear + // WriteReg(d.iPortAddr, SERIAL_CLEAR_INT, 0x0); // clear interrupts + + while(ReadReg(d.iPortAddr, SERIAL_FIFO_COUNT)!=0) { + TUint ch = ReadReg(d.iPortAddr, SERIAL_DATA); + rx[rxi++]=ch; + } + d.ReceiveIsr(rx,rxi,0); +} + +// --------------------------------------------------------------- +// --------------------------------------------------------------- + +DECLARE_STANDARD_PDD() +{ + DPRINT("DECLARE_STANDARD_PDD()"); + return new DDriverSyborgComm; +} +