--- /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 <rap.h>
+#include <kernel/kernel.h>
+#include <rap_priv.h>
+#include <PowerResourceManager.h>
+#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<XtiRx*>( 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