diff -r e54443a6878c -r 0e5a77c79f1e tracesrv/reference/sf/adapt/osrndtools.nokia/xtiv2/drivers/src/xtirx.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tracesrv/reference/sf/adapt/osrndtools.nokia/xtiv2/drivers/src/xtirx.cpp Mon Oct 25 18:15:05 2010 +0100 @@ -0,0 +1,949 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: +* +*/ + + +/** @file + +XtiRx driver receives the data from Musti and sends it to Trace Core. + +*///========================================================================= + + +//- Include Files ---------------------------------------------------------- + +#include +#include +#include +#include +#include "xtirx.h" +#include "xtitx.h" +#include "XtiDebug.h" + +//- Namespace --------------------------------------------------------------- + + +//- Using ------------------------------------------------------------------- + + +//- External Data ----------------------------------------------------------- + + +//- External Function Prototypes -------------------------------------------- + + +//- Constants --------------------------------------------------------------- + +const TInt KBitsInByte = 8; // the amount of bits in byte +const TInt KBitsInDataLengthMsg = 32; // the amount of bits in data length message +const TInt KMaxWakeupResponceCounterValue = 20; // the maximum number of attempts to writing to TraceCore buffer +const TInt KWakeupResponceTimerInterval = 100000; // time interval of attempts to writing to TraceCore buffer (microseconds) +const TUint KBitRate = 115200; // bit rate +const TUint8 KDefaultDfcPriority = 3; // Default DFC queue priority +const TInt KInterruptId = TRap::EIntIdASR001_MUSTI_BUFFERFULL; // Uart interrupt line +const TInt KPollPeriodMs = 2; // time interval of checking if the Uart RX buffer has data (milliseconds) +const TInt KIdleTimerInterval = 500000; // time interval for idle timer (microseconds) +const TInt KResetTimerInterval = 800000; // time interval for idle timer (microseconds) +const TInt KMaxPoll = 25; // the maximum number of checking if the Uart RX buffer has data +const TUint KMaxXtiMessageLength = 8204; // Maximum size of XTI message send by Musti +const TUint KClearPoll = 3; // Used when clearing UART buffer + + +/** The name of the created XTI RX thread */ +_LIT( KThreadName, "XtiRxThread" ); + +/** DFC thread priority */ +const TInt KDfcThreadPriority = 26; + + +//- Macros ------------------------------------------------------------------ + +//- Global and Local Variables ---------------------------------------------- + +XtiRx* XtiRx::iXtiRxPtr = NULL; + +TBool HasUartRxFifoData( TAny* aPtr ); + +_LIT(KXTIRXDriver, "XTI RX Driver"); + +//- Local Function Prototypes ----------------------------------------------- + +//=========================================================================== + +//- Local Functions --------------------------------------------------------- + +//=========================================================================== + +//- Member Functions -------------------------------------------------------- +void XtiRx::GPIOwakeIsr(TAny* aPtr) + { + XTI_TRACE( Kern::Printf("XtiRx::GPIOwakeIsr") ) + XTI_TRACE( Kern::Printf("XtiRx::GPIOwakeIsr <<") ) + } + +/* +----------------------------------------------------------------------------- + + XtiRx + + XtiRx + + Constructor +----------------------------------------------------------------------------- +*/ + +XtiRx::XtiRx() + : iDfcQueue( NULL ) + , iReceiveDataDfc( ReceiveDataDfc, this, KDefaultDfcPriority ) + , iGPIOWakeupDfc( GPIOWakeupDfc, this, KDefaultDfcPriority ) + , iSetPowerDfc( SetPowerDfc, this, KDefaultDfcPriority ) + , iClearPowerDfc( ClearPowerDfc, this, KDefaultDfcPriority ) + , iClocksOn( EFalse ) + , iTraceCoreDfcPtr( NULL ) + , iRxBufferPtr( NULL ) + , iRxState( KRxStateIdle ) + , iReceiveBufferFree( EFalse ) + , iMessagelength( 0 ) + , iWakeupResponseCounter( 0 ) + , iClientId( 0 ) + { + + // Register the PRM client + TInt r = TPowerResourceManager::RegisterClient( iClientId, KXTIRXDriver ); + __ASSERT_DEBUG(r==KErrNone,Kern::Fault("Registration with the power manager failed",r)); + } + + +/* +----------------------------------------------------------------------------- + XtiRx + + ~XtiRx + + Destructor +----------------------------------------------------------------------------- +*/ +XtiRx::~XtiRx() + { + iRxBufferPtr = NULL; + iTraceCoreDfcPtr = NULL; + + // Deregister the PRM client + TPowerResourceManager::DeRegisterClient( iClientId ); + iDfcQueue = NULL; + } + +/* +---------------------------------------------------------------------------- + + XtiRx + + Instance + + Return an instance to XtiRx interface. This method returns the + only XtiRx instance system can have, it is not possible to create + new instances of this class. + + Return Values: iXtiRxPtr* An instance to XtiRx class + +----------------------------------------------------------------------------- +*/ +XtiRx* XtiRx::Instance( ) + { + XTI_TRACE( Kern::Printf("XtiRx::Instance") ) + // Allow only 1 instance of XtiRx to exists at any time + if ( iXtiRxPtr == NULL ) + { + iXtiRxPtr = new XtiRx(); + } + return iXtiRxPtr; + } + +/* +---------------------------------------------------------------------------- + + XtiRx + + Init + + Bind Uart interrupt, configure Uart HW and start receiving the data + + Return Values: KErrNone or error code + +----------------------------------------------------------------------------- +*/ +TInt XtiRx::Init() + { + XTI_TRACE( Kern::Printf("XtiRx::Init >>") ) + TInt ret( KErrNone ); + SetPowerRequirements(); + + XTI_TRACE( Kern::Printf("XtiRx::Init - Bind method Isr to uart interrupt 0x%x", KInterruptId) ) + ret = Interrupt::Bind( KInterruptId, Isr, this ); + + if( ret == KErrNone ) + { + ret = Configure(); + if( ret == KErrNone ) + { + ret = Start(); + } + } + XTI_TRACE( Kern::Printf("XtiRx::Init <<, ret= %d", ret)) + return ret; + } + +/* +---------------------------------------------------------------------------- + + XtiRx + + ConfigureUart + + Configure Uart HW. + + Return Value: KErrNone or error code + +----------------------------------------------------------------------------- +*/ +TInt XtiRx::ConfigureUart() const +{ + XTI_TRACE( Kern::Printf("XtiRx::ConfigureUart >>") ) + + TInt ret( KErrNone ); + + XTI_TRACE( Kern::Printf("XtiRx::ConfigureUart - Disable uart interrupt 0x%x", KInterruptId) ) + ret = Interrupt::Disable( KInterruptId ); + __ASSERT_DEBUG(ret == KErrNone, Kern::Fault( ("XtiRx::ConfigureUart"), __LINE__ )); + + TUint32 clock_in_hz = TRap::McuppClockInHz(); + + TUint32 baud_rate = 2304000; // Use Musti default bit rate + + + // Integer part of bitduration value for Rx (the bit window) + + TUint32 mcuClock; + mcuClock = clock_in_hz / baud_rate; + TUint32 rx_bitduration = (TUint32)((mcuClock - 3) / 2); + TUint32 rx_modulo = rx_bitduration / 5; // Use the recommended 20% + + + // Fractional part: The formula is rewritten like this in order to + // be able to use integer math: + // + // rx_bitduration = clock_in_hz / (2 * baud_rate) - 3/2 + // + // Thus the fractional part of rx_bitduration can be calculated as + // + // f = f1 - f2 + // + // where + // + // f1 = fractional_part_of( clock_in_hz / (2 * baud_rate) ) + // + // f2 = fractional_part_of( 3/2 ) + // + // The two fractional parts are calculated as follows: + // + // f1 = ( clock_in_hz % (2 * baud_rate) ) * ( 2^32 / 2 * baud_rate ) + // = ( clock_in_hz % (2 * baud_rate) ) * ( 2^31 / baud_rate ) + // + // + // f2 = ( 3 % 2 ) * ( 2^32 / 2 ) + // = 1 * 2^31 + // + TUint32 rx_fraction = (clock_in_hz % (baud_rate << 1)) * ( (TUint32)(1<<31)/baud_rate ) - (TUint32)(1<<31); + + XTI_TRACE( Kern::Printf( "XtiRx Rx parameters:" )); + XTI_TRACE( Kern::Printf( "Baud %u", baud_rate ) ); + XTI_TRACE( Kern::Printf( "Mcupp clock freq %u", clock_in_hz ) ); + XTI_TRACE( Kern::Printf( "Write registers:" )); + XTI_TRACE( Kern::Printf( "RX-bitduration %u", rx_bitduration) ); + XTI_TRACE( Kern::Printf( "RX-pulseduration %u", rx_bitduration) ); + XTI_TRACE( Kern::Printf( "RX-fraction %u", rx_fraction) ); + XTI_TRACE( Kern::Printf( "RX-modulo %u", rx_modulo) ); + + // Configure static Rx parameters + // Setting up ASR001 + TRap::SetRegister32(ASR001_T_V_MODE_RUN, KRapRegXTIASR001_MODE); + TRap::SetRegister32(rx_modulo, KRapRegXTIASR001_MODULO); + TRap::SetRegister32(ASR001_T_V_POLARITY_POSITIVE, KRapRegXTIASR001_POLARITY); + TRap::SetRegister32(ASR001_T_V_FLOW_OFF, KRapRegXTIASR001_FLOW); + TRap::SetRegister32(ASR001_T_V_RXSTATE_IDLE, KRapRegXTIASR001_RXSTATE); + TRap::SetRegister32(rx_bitduration, KRapRegXTIASR001_BITDURATION); /* Bitrate = 2304000 b/s */ + TRap::SetRegister32(rx_bitduration, KRapRegXTIASR001_PULSEDURATION); + TRap::SetRegister32(rx_fraction, KRapRegXTIASR001_FRACTION); + // Note that only the upper bits of the written fraction will have effect + // e.g. 0x40000000 + //TRap::SetRegister32(0x42AAAAAA, KRapRegXTIASR001_FRACTION); + TRap::SetRegister32(0x02, KRapRegXTIASR001_THRESHOLD); + TRap::SetRegister32(0x07, KRapRegXTIASR001_DATABITS); /* 8 Data bits */ + TRap::SetRegister32(0x00, KRapRegXTIASR001_STOPBITS); /* 1 Stop bits */ + TRap::SetRegister32(ASR001_T_V_PARITY_NONE, KRapRegXTIASR001_PARITY); /* No parity */ + TRap::SetRegister32(0x00, KRapRegXTIASR001_WATERMARK); + + + XTI_TRACE( Kern::Printf("XtiRx::ConfigureUart <<") ) + return ret; +} + +/* +---------------------------------------------------------------------------- + + XtiRx + + Configure + + Configure HW. + + Return Value: KErrNone or error code + +----------------------------------------------------------------------------- +*/ +TInt XtiRx::Configure() const + { + TInt ret( KErrNone ); + + XTI_TRACE( Kern::Printf("XtiRx::Configure >>") ) + + // Configure UART + ret = ConfigureUart(); + __ASSERT_DEBUG(ret == KErrNone, Kern::Fault( ("XtiRx::Configure"), __LINE__ )); + + XTI_TRACE( Kern::Printf("XtiRx::Configure <<") ) + return ret; + + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + Isr + + Uart interrupt service routine + + @param aPtr Pointer to XtiRx object + +----------------------------------------------------------------------------- +*/ +void XtiRx::Isr(TAny* aPtr) + { + XTI_TRACE( Kern::Printf("XtiRx::Isr >>") ) + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::Isr - Null pointer!"), 0 )); + + XTI_TRACE( Kern::Printf("XtiRx::Isr - Disable uart interrupt 0x%x", KInterruptId) ) + TInt ret = Interrupt::Disable( KInterruptId ); + __ASSERT_DEBUG(ret == KErrNone, Kern::Fault( ("XtiRx::Isr"), __LINE__ )); + + XtiRx& self = *static_cast( aPtr ); + XTI_TRACE( Kern::Printf("XtiRx::Isr - Add ReceiveDataDfc") ) + self.iReceiveDataDfc.Add(); + + XTI_TRACE( Kern::Printf("XtiRx::Isr <<") ) + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + ReceiveDataDfc + + Function called in DFC context after Uart interrupt. Reads the data + from Uart RX FIFO and saves the data to the buffer which is defined + XtiRx::Register function. + + @param aPtr Pointer to XtiRx object + +----------------------------------------------------------------------------- +*/ +void XtiRx::ReceiveDataDfc( TAny* aPtr ) + { + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc >>") ) + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::ReceiveDataDfc - Null pointer!"), 0 )); + + XtiRx& self = *static_cast< XtiRx* >( aPtr ); + TInt ret( KErrNone ); + + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Cancel timer") ) + self.iIdleTimer.Cancel(); + // Start timer safety timer to clear state machine if problems + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Start timer safety timer to clear state machine if problems") ) + self.iIdleTimer.OneShot( KResetTimerInterval, XtiRx::ResetReceiveState, aPtr ); + + self.SetPowerRequirements(); + if( self.iRxState == KRxStateIdle ) + { + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - XTI state = KRxStateIdle") ) + TInt count(0); + // Clear Uart RX buffer + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Clear Uart RX buffer") ) + + while( TRap::Register32(KRapRegXTIASR001_GAUGE) != 0 || count < KClearPoll ) + { + TInt r = Kern::PollingWait(HasUartRxFifoData, (TAny*)&self , KPollPeriodMs, KMaxPoll); + if( r == KErrNone ) + { + TRap::Register32(KRapRegXTIASR001_DATA); + } + count++; + } + + // check if Trace Core has read the previous data package + if( self.iReceiveBufferFree ) + { + if( ret == KErrNone ) + { + // Send bit rate to Musti + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Send bit rate to Musti") ) + XtiTx::SetBitRate( KBitRate ); + // Waiting for the data length message + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Waiting for the data length message") ) + self.iRxState = KRxStateWaitDataLenMsg; + } + } + else + { + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Buffer not free -> start timer") ) + self.iWakeupResponseTimer.OneShot( KWakeupResponceTimerInterval, XtiRx::ReceiveDataDfc, aPtr ); + self.iWakeupResponseCounter++; + if( self.iWakeupResponseCounter == KMaxWakeupResponceCounterValue ) + { + self.iWakeupResponseTimer.Cancel(); + ret = KErrGeneral; + } + } + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Enable uart interrupt 0x%x", KInterruptId) ) + Interrupt::Enable( KInterruptId ); + } + else if( self.iRxState == KRxStateWaitDataLenMsg ) + { + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - XTI state = KRxStateWaitDataLenMsg") ) + self.iMessagelength = 0; + // Read XTI message length. The number of bytes is sent as a 32-bit binary little-endian integer. + TInt r( KErrNone ); + for( TInt i = 0 ; (i < KBitsInDataLengthMsg) ; i += KBitsInByte ) + { + //TUint32 len = 0; + r = Kern::PollingWait(HasUartRxFifoData, (TAny*)&self , KPollPeriodMs, KMaxPoll); + if( r == KErrNone ) + { + //len = TRap::Register32(KRapRegXTIASR001_DATA) << i; + self.iMessagelength += TRap::Register32(KRapRegXTIASR001_DATA) << i; + } + //__DEBUG_ONLY (Kern::Printf("XtiRx::ReceiveDataDfc - len = %d", len) ); + //self.iMessagelength += len; + } + __DEBUG_ONLY (Kern::Printf("XtiRx::ReceiveDataDfc - iMessagelength = %d", self.iMessagelength) ); + // acknowledgement to Musti + + if( r == KErrNone ) + { + XtiTx::SendDataLenAckMsg(); + self.iRxState = KRxStateWaitDataMsg; + } + else + { + self.iXtiRxPtr->iReceiveBufferFree = ETrue; + self.iXtiRxPtr->iRxBufferPtr->Zero(); // set data length to zero + self.iRxState = KRxStateIdle; + } + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Enable uart interrupt 0x%x", KInterruptId) ) + Interrupt::Enable( KInterruptId ); + } + else + { + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - XTI state = KRxStateWaitDataMsg") ) + ret = self.ReadData(); + if( ret == KErrNone ) + { + // acknowledgement to Musti + XtiTx::SendDataRxAckMsg(); + self.iReceiveBufferFree = EFalse; + // Cancel reset timer + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Cancel reset timer") ) + self.iIdleTimer.Cancel(); + // inform Trace core that the data is in the receive buffer + self.iTraceCoreDfcPtr->Enque(); + // Start standby timer + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Start standby timer") ) + self.iRxState = KRxStateIdle; + self.iIdleTimer.OneShot( KIdleTimerInterval, XtiRx::StandbyMode, aPtr ); + } + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc - Enable uart interrupt 0x%x", KInterruptId) ) + Interrupt::Enable( KInterruptId ); + } + XTI_TRACE( Kern::Printf("XtiRx::ReceiveDataDfc <<") ) + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + GPIOWakeupDfc + + Function called in DFC context after GPIO interrupt. Mux the UART PIN and + start UART clocks + + @param aPtr Pointer to XtiRx object + +----------------------------------------------------------------------------- +*/ +void XtiRx::GPIOWakeupDfc( TAny* aPtr ) +{ + XTI_TRACE( Kern::Printf("XtiRx::GPIOWakeupDfc >>") ) + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::GPIOWakeupDfc - Null pointer!"), 0 )); + + XtiRx& self = *static_cast< XtiRx* >( aPtr ); + + self.SetPowerRequirements(); + + XTI_TRACE( Kern::Printf("XtiRx::GPIOWakeupDfc - Enable uart interrupt 0x%x", KInterruptId) ) + TInt ret = Interrupt::Enable( KInterruptId ); + __ASSERT_DEBUG(ret == KErrNone, Kern::Fault( ("XtiRx::GPIOWakeupDfc"), __LINE__ )); + + XTI_TRACE( Kern::Printf("XtiRx::GPIOWakeupDfc <<" ) ) +} + + +/* +---------------------------------------------------------------------------- + + XtiRx + + GPIODeepSleepWakeupDfc + + Function called in DFC context after GPIO interrupt in deep sleep. Mux the UART PIN and + start UART clocks + + @param aPtr Pointer to XtiRx object + +----------------------------------------------------------------------------- +*/ +void XtiRx::GPIODeepSleepWakeupDfc( TAny* aPtr ) +{ + XTI_TRACE( Kern::Printf("XtiRx::GPIODeepSleepWakeupDfc >>") ) + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::GPIODeepSleepWakeupDfc - Null pointer!"), 0 )); + + XtiRx& self = *static_cast< XtiRx* >( aPtr ); + + XTI_TRACE( Kern::Printf("XtiRx::GPIODeepSleepWakeupDfc - Bind method Isr to uart interrupt 0x%x", KInterruptId) ) + TInt ret = Interrupt::Bind( KInterruptId, Isr, aPtr ); + + self.SetPowerRequirements(); + + self.ConfigureUart(); + + XTI_TRACE( Kern::Printf("XtiRx::GPIODeepSleepWakeupDfc - Enable uart interrupt 0x%x", KInterruptId) ) + ret = Interrupt::Enable( KInterruptId ); + __ASSERT_DEBUG(ret == KErrNone, Kern::Fault( ("XtiRx::GPIODeepSleepWakeupDfc"), __LINE__ )); + + XTI_TRACE( Kern::Printf("XtiRx::GPIODeepSleepWakeupDfc <<" ) ) +} + +/* +---------------------------------------------------------------------------- + + XtiRx + + SetPowerDfc + + Call SetPowerRequirements + + @param aPtr Pointer to XtiRx object + +----------------------------------------------------------------------------- +*/ +void XtiRx::SetPowerDfc( TAny* aPtr ) +{ + XTI_TRACE( Kern::Printf("XtiRx::SetPowerDfc >>") ) + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::SetPowerDfc - Null pointer!"), 0 )); + + XtiRx& self = *static_cast< XtiRx* >( aPtr ); + + self.SetPowerRequirements(); + + XTI_TRACE( Kern::Printf( "XtiRx::SetPowerDfc <<" ) ) +} + + +/* +---------------------------------------------------------------------------- + + XtiRx + + ClearPowerDfc + + Call ClearPowerRequirements + + @param aPtr Pointer to XtiRx object + +----------------------------------------------------------------------------- +*/ +void XtiRx::ClearPowerDfc( TAny* aPtr ) +{ + XTI_TRACE( Kern::Printf("XtiRx::ClearPowerDfc >>") ) + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::ClearPowerDfc - Null pointer!"), 0 )); + + XtiRx& self = *static_cast< XtiRx* >( aPtr ); + + self.ClearPowerRequirements(); + + XTI_TRACE( Kern::Printf( "XtiRx::ClearPowerDfc <<" ) ) +} + + + +/* +---------------------------------------------------------------------------- + + XtiRx + + ReadRxData + + Read data from Uart RX FIFO + + Return Value: KErrNone or error code +----------------------------------------------------------------------------- +*/ +TInt XtiRx::ReadData() + { + XTI_TRACE( Kern::Printf("XtiRx::ReadData >>") ) + TInt ret( KErrNone ); + TInt error( KErrNone ); + TUint32 character( 0 ); + __ASSERT_DEBUG(iRxBufferPtr != NULL, Kern::Fault( ("XtiRx::ReadData - Null pointer!"), 0 )); + iRxBufferPtr->Zero(); // set data length to zero + + if( iMessagelength > KMaxXtiMessageLength ) + { + XTI_TRACE( Kern::Printf("XtiRx::ReadData - Message is greater than the maximum size of XTI message") ) + ret = KErrGeneral; + } + else + { + while( iMessagelength != 0 && ret == KErrNone ) + { + ret = Kern::PollingWait(HasUartRxFifoData, this , KPollPeriodMs, KMaxPoll); + if( ret == KErrNone ) + { + character = TRap::Register32(KRapRegXTIASR001_DATA); + XTI_TRACE( Kern::Printf("XtiRx::ReadData - data = 0x%x",character) ) + error = character >> KBitsInByte; + character = character & KMaxTUint8; + + /*Check for receive errors + Error flags are OR'ed into the high bits of char + */ + + if( error & ASR001_T_V_ERROR_OVERRUN) + { + XTI_TRACE( Kern::Printf("XtiRx::ReadData - Overrun ERROR") ) + ret = KErrCommsOverrun; + } + if( error & ASR001_T_V_ERROR_PARITY) + { + XTI_TRACE( Kern::Printf("XtiRx::ReadData - Parity ERROR") ) + ret = KErrCommsParity; + } + if( error & ASR001_T_V_ERROR_FRAMING ) + { + XTI_TRACE( Kern::Printf("XtiRx::ReadData - Framing ERROR") ) + ret = KErrCommsFrame; + } + + iRxBufferPtr->Append( character ); + iMessagelength--; + } + } + } + + XTI_TRACE( Kern::Printf("XtiRx::ReadData <<, ret= %d", ret) ) + return ret; + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + Register + + This method is used to register an user to the driver. + + @param aDfc Pointer to the DFC function which is called by the XTI driver when the data is + available in the receive buffer. + + @param aBuf Receive buffer + + Return Value: KErrNone or error code + +----------------------------------------------------------------------------- +*/ +EXPORT_C TInt XtiRx::Register( TDfc* aDfc, TDes8& aBuf ) + { + __ASSERT_DEBUG(aDfc != NULL, Kern::Fault( ("XtiRx::Register - Null pointer!"), 0 )); + XTI_TRACE( Kern::Printf("XtiRx::Register >>") ) + TInt ret(KErrNone); + + // Create DFC thread inside of which the operations are performed + if( iXtiRxPtr != NULL ) + { + ret = Kern::DfcQCreate( iXtiRxPtr->iDfcQueue, KDfcThreadPriority, &KThreadName ); + } + else + { + ret = KErrGeneral; + } + + if(ret == KErrNone ) + { + iXtiRxPtr->iReceiveDataDfc.SetDfcQ( iXtiRxPtr->iDfcQueue ); + iXtiRxPtr->iGPIOWakeupDfc.SetDfcQ( iXtiRxPtr->iDfcQueue ); + iXtiRxPtr->iSetPowerDfc.SetDfcQ( iXtiRxPtr->iDfcQueue ); + iXtiRxPtr->iClearPowerDfc.SetDfcQ( iXtiRxPtr->iDfcQueue ); + + ret = iXtiRxPtr->Init(); + if( ret == KErrNone ) + { + iXtiRxPtr->iTraceCoreDfcPtr = aDfc; + iXtiRxPtr->iRxBufferPtr = &aBuf; + iXtiRxPtr->iReceiveBufferFree = ETrue; + } + } + + XTI_TRACE( Kern::Printf("XtiRx::Register <<, ret= %d",ret) ) + iXtiRxPtr->ClearPowerRequirements(); + return ret; + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + SetReceiveBufferRead + + User of the driver calls this function when the receive buffer has been read + +----------------------------------------------------------------------------- +*/ +EXPORT_C void XtiRx::SetReceiveBufferRead() + { + XTI_TRACE( Kern::Printf("XtiRx::SetReceiveBufferRead >>") ) + iXtiRxPtr->iReceiveBufferFree = ETrue; + iXtiRxPtr->iRxBufferPtr->Zero(); // set data length to zero + XTI_TRACE( Kern::Printf("XtiRx::SetReceiveBufferRead <<") ) + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + Start + + Start receiving characters + + Return Value: KErrNone or error code + +----------------------------------------------------------------------------- +*/ + +TInt XtiRx::Start() const + { + XTI_TRACE( Kern::Printf( "XtiRx::Start >>") ) + TInt ret(KErrNone); + + // Clear Uart RX buffer + XTI_TRACE( Kern::Printf( "XtiRx::Start - Clear Uart RX buffer") ) + while( TRap::Register32(KRapRegXTIASR001_GAUGE) ) + { + TRap::Register32(KRapRegXTIASR001_DATA); + } + + if( ret == KErrNone ) + { + // Enable Uart interrupt + XTI_TRACE( Kern::Printf( "XtiRx::Start - Enable uart interrupt 0x%x", KInterruptId) ) + ret = Interrupt::Enable( KInterruptId ); + } + XTI_TRACE( Kern::Printf( "XtiRx::Start <<, ret= %d",ret) ) + return ret; + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + SetPowerRequirements + + Set power requirements + +----------------------------------------------------------------------------- +*/ +void XtiRx::SetPowerRequirements() + { + XTI_TRACE( Kern::Printf( "XtiRx::SetPowerRequirements >>") ) + + if( iClocksOn == EFalse ) + { + // Request to enable a clock resource + XTI_TRACE( Kern::Printf( "XtiRx::SetPowerRequirements - Request to enable a clock resource") ) + + iClocksOn = ETrue; + } + XTI_TRACE( Kern::Printf( "XtiRx::SetPowerRequirements <<" ) ) + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + ClearPowerRequirements + + Clear power requirements + +----------------------------------------------------------------------------- +*/ +void XtiRx::ClearPowerRequirements() + { + XTI_TRACE( Kern::Printf( "XtiRx::ClearPowerRequirements >>") ) + + if( iClocksOn ) + { + iClocksOn = EFalse; + } + XTI_TRACE( Kern::Printf( "XtiRx::ClearPowerRequirements <<" ) ) + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + StandbyMode + + Set the driver to standby mode + +----------------------------------------------------------------------------- +*/ +void XtiRx::StandbyMode( TAny* aPtr ) + { + XTI_TRACE( Kern::Printf( "XtiRx::StandbyMode >>") ) + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::StandbyMode - Null pointer!"), 0 )); + XtiRx& self = *static_cast< XtiRx* >( aPtr ); + XTI_TRACE( Kern::Printf( "XtiRx::StandbyMode - Enque ClearPowerDfc") ) + self.iClearPowerDfc.Enque(); + self.iRxState = KRxStateIdle; + XTI_TRACE( Kern::Printf( "XtiRx::StandbyMode <<" ) ) + } + + +/* +---------------------------------------------------------------------------- + + XtiRx + + ResetReceiveState + + Reset receiver state machine. + +----------------------------------------------------------------------------- +*/ +void XtiRx::ResetReceiveState( TAny* aPtr ) + { + XTI_TRACE( Kern::Printf( "XtiRx::ResetReceiveState >>") ) + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::ResetReceiveState - Null pointer!"), 0 )); + XtiRx& self = *static_cast< XtiRx* >( aPtr ); + self.iXtiRxPtr->iReceiveBufferFree = ETrue; + self.iXtiRxPtr->iRxBufferPtr->Zero(); // set data length to zero + XTI_TRACE( Kern::Printf( "XtiRx::ResetReceiveState - Enque ClearPowerDfc") ) + self.iClearPowerDfc.Enque(); + self.iRxState = KRxStateIdle; + XTI_TRACE( Kern::Printf( "XtiRx::ResetReceiveState <<" ) ) + } + + + + +//=========================================================================== + +//- Global Functions -------------------------------------------------------- + +/* +---------------------------------------------------------------------------- + + HasUartRxFifoData + + Check if there is data in the Uart RX FiFo. + + @param aPtr Pointer to XtiRx object + + Return Values: ETrue ot EFalse + +----------------------------------------------------------------------------- +*/ +TBool HasUartRxFifoData( TAny* aPtr ) + { + __ASSERT_DEBUG(aPtr != NULL, Kern::Fault( ("XtiRx::HasUartRxFifoData - Null pointer!"), 0 )); + TBool ret( ETrue ); + + if( TRap::Register32(KRapRegXTIASR001_GAUGE) == 0 ) + { + XTI_TRACE( Kern::Printf("XtiRx::HasUartRxFifoData - No data in RX FIFO") ) + ret = EFalse; + } + + return ret; + } + + +//--------------------------------------------------------------------------- +/** + The entry point for a standard extension. Creates Xti extension. + + @return KErrNone, if successful +*/ +DECLARE_STANDARD_EXTENSION() + { + TInt ret( KErrNoMemory ); + XtiRx* xtirx = XtiRx::Instance(); + if ( xtirx != NULL ) + { + ret = KErrNone; + } + return ret; + } + +//- Namespace --------------------------------------------------------------- + +// End of File