//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaGetPerIntItvUS -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // // Returns the current periodic interval in micro seconds // UInt32 DtaGetPerIntItvUS(DtaDeviceData* pDvcData) { UInt64 Value64; DT_ASSERT(pDvcData->m_DevInfo.m_PerIntClkBit >= 17); Value64 = 1000000 * ((UInt64)1<<pDvcData->m_DevInfo.m_PerIntClkBit); return (UInt32)DtDivide64(Value64, pDvcData->m_DevInfo.m_RefClk, NULL); }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaNonIpTxSetFailsafeCfg -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaNonIpTxSetFailsafeCfg(DtaNonIpPort* pNonIpPort, Int Enable, Int Timeout) { // Enable / disable failsafe pNonIpPort->m_FailsafeEnable = (Enable != 0) ? TRUE : FALSE; // Store timeout and calculate timeout counter if timeout is provided if (Timeout > 0) { pNonIpPort->m_FailsafeTimeout = Timeout; pNonIpPort->m_FailsafeTimeoutCnt = (UInt32)DtDivide64((UInt64)Timeout*1000, pNonIpPort->m_pDvcData->m_DevInfo.m_PerIntItvUS, NULL); } return DT_STATUS_OK; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaUartWrite -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaUartWrite( DtaUartPort* pUart, UInt8* pBuf, Int NumBytes, Int* pTimeout) { DtStatus Status = DT_STATUS_OK; Int FifoSize, FifoFree; volatile UInt8* pFwbRegs = pUart->m_pFwbRegs; #ifdef WINBUILD LARGE_INTEGER StartTime, CurTime; #else struct timespec StartTime, CurTime; #endif Int TimeElapsed = 0; #ifdef WINBUILD KeQueryTickCount(&StartTime); #else getnstimeofday(&StartTime); #endif if (pTimeout==NULL || *pTimeout<=0) return DT_STATUS_INVALID_PARAMETER; // Get current space in FIFO FifoSize = DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->Config_TxFifoSize); FifoFree = FifoSize - DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->TxStat_FifoLoad); while (NumBytes > FifoFree) { // Write as many bytes as fit in the buffer while (FifoFree-- > 0) { DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->TxData, *pBuf++); NumBytes--; } DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->TxCtrl_HalfEmptyIntEnable, 1); Status = DtEventWaitUnInt(&pUart->m_TxEvent, *pTimeout - TimeElapsed); #ifdef WINBUILD KeQueryTickCount(&CurTime); TimeElapsed = (Int)((CurTime.QuadPart - StartTime.QuadPart)*KeQueryTimeIncrement() / 10000); #else getnstimeofday(&CurTime); TimeElapsed = DtDivide64(((CurTime.tv_sec-StartTime.tv_sec)*1000000000LL + (CurTime.tv_nsec-StartTime.tv_nsec)), 1000000, NULL); #endif if (TimeElapsed > *pTimeout) return DT_STATUS_TIMEOUT; FifoFree = FifoSize - DtaFwbRegRead(pFwbRegs,&pUart->m_pFwbUart->TxStat_FifoLoad); } DT_ASSERT(NumBytes <= FifoFree); while (NumBytes-- > 0) { DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->TxData, *pBuf++); } #ifdef WINBUILD KeQueryTickCount(&CurTime); TimeElapsed = (Int)((CurTime.QuadPart - StartTime.QuadPart)*KeQueryTimeIncrement() / 10000); #else getnstimeofday(&CurTime); TimeElapsed = DtDivide64(((CurTime.tv_sec-StartTime.tv_sec)*1000000000LL + (CurTime.tv_nsec-StartTime.tv_nsec)), 1000000, NULL); #endif if (TimeElapsed > *pTimeout) return DT_STATUS_TIMEOUT; // Wait for completion DtEventReset(&pUart->m_TxEvent); DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->TxCtrl_EmptyIntEnable, 1); Status = DtEventWaitUnInt(&pUart->m_TxEvent, *pTimeout - TimeElapsed); if (!DT_SUCCESS(Status)) { #ifdef WINBUILD KeQueryTickCount(&CurTime); TimeElapsed = (Int)((CurTime.QuadPart - StartTime.QuadPart)*KeQueryTimeIncrement() / 10000); #else getnstimeofday(&CurTime); TimeElapsed = DtDivide64(((CurTime.tv_sec-StartTime.tv_sec)*1000000000LL + (CurTime.tv_nsec-StartTime.tv_nsec)), 1000000, NULL); #endif *pTimeout -= TimeElapsed; return Status; } return DT_STATUS_OK; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaUartWrite -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // DtStatus DtaUartRead( DtaUartPort* pUart, UInt8* pBuf, Int BytesToRead, Int Timeout, Int* pNumBytesRead) { DtStatus Status = DT_STATUS_OK; Int NumBytesAvail, NumCanRead, FifoSize, i; Int Idx = 0; volatile UInt8* pFwbRegs = pUart->m_pFwbRegs; #ifdef WINBUILD LARGE_INTEGER StartTime, CurTime; #else struct timespec StartTime, CurTime; #endif Int TimeElapsed; Int OrigTimeout = Timeout; *pNumBytesRead = 0; // Check timeout if (Timeout < -1) return DT_STATUS_INVALID_PARAMETER; #ifdef WINBUILD KeQueryTickCount(&StartTime); #else getnstimeofday(&StartTime); #endif FifoSize = DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->Config_RxFifoSize); NumBytesAvail = DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->RxStat_FifoLoad); do { NumCanRead = (BytesToRead < NumBytesAvail) ? BytesToRead : NumBytesAvail; // Read available data from FIFO for (i=0; i<NumCanRead; i++) pBuf[Idx++] = (UInt8)DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->RxData); BytesToRead -= NumCanRead; *pNumBytesRead += NumCanRead; // Ready? if (BytesToRead==0 || Timeout==0) break; // Wait for data available event DtEventReset(&pUart->m_RxEvent); if (BytesToRead < FifoSize/2) DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->RxCtrl_DataIdleIntEnable, 1); else DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->RxCtrl_HalfFullIntEnable, 1); Status = DtEventWait(&pUart->m_RxEvent, Timeout); if (!DT_SUCCESS(Status)) break; // Check how much is availble now NumBytesAvail = DtaFwbRegRead(pFwbRegs, &pUart->m_pFwbUart->RxStat_FifoLoad); if (Timeout == -1) continue; #ifdef WINBUILD KeQueryTickCount(&CurTime); TimeElapsed = (Int)((CurTime.QuadPart - StartTime.QuadPart)*KeQueryTimeIncrement() / 10000); #else getnstimeofday(&CurTime); TimeElapsed = DtDivide64(((CurTime.tv_sec-StartTime.tv_sec)*1000000000LL + (CurTime.tv_nsec-StartTime.tv_nsec)), 1000000, NULL); #endif Timeout = OrigTimeout - TimeElapsed; } while (Timeout > 0); // Reception ready DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->RxCtrl_DataIdleIntEnable, 0); DtaFwbRegWrite(pFwbRegs, &pUart->m_pFwbUart->RxCtrl_HalfFullIntEnable, 0); // A timeout is not an error in this case. Let userspace deal with the fact that // the read operation is not complete. if (Status == DT_STATUS_TIMEOUT) Status = DT_STATUS_OK; return Status; }