//------------------------------------------------------------------------------
UINT32 timestamp_calcTimeDiff(tTimestamp* pTimeStampPrevious_p,
                              tTimestamp* pTimeStampCurrent_p)
{
    UINT32 timeDiffTicks;

    timeDiffTicks = pTimeStampCurrent_p->timeStamp - pTimeStampPrevious_p->timeStamp;

    return OMETH_TICKS_2_NS(timeDiffTicks);
}
コード例 #2
0
DWORD PUBLIC EplTgtTimeStampTimeDiffNs (tEplTgtTimeStamp* pTimeStampPredecessor_p,
                                        tEplTgtTimeStamp* pTimeStampSuccessor_p)
{
DWORD dwTimeDiffTicks;

    dwTimeDiffTicks = pTimeStampSuccessor_p->m_dwTimeStamp
                      - pTimeStampPredecessor_p->m_dwTimeStamp;

    return OMETH_TICKS_2_NS(dwTimeDiffTicks);

}
コード例 #3
0
static tEplKernel EdrvCyclicProcessTxBufferList(void)
{
tEplKernel      Ret = kEplSuccessful;
tEdrvTxBuffer*  pTxBuffer = NULL;
DWORD            udwAbsTime; //absolute time accumulator
BOOL             fFirstPkt = TRUE; //flag to identify first packet
DWORD            udwMacTimeEntry = EDRV_GET_MAC_TIME(); //MAC TIME AT FUNCTION CALL
//DWORD            udwMacTimePlusOffset = udwMacTimeEntry + EdrvCyclicInstance_l.m_dwTxProcDur; //plus offset
DWORD            udwCycleMin = 0; //absolute minimum cycle time
DWORD            udwCycleMax = 0; //absolute maximum cycle time
DWORD            udwNextOffNs = 0; //next earliest tx time
DWORD            udwNextTimerIrqNs = EdrvCyclicInstance_l.m_dwCycleLenUs * 1000UL; //time of next timer irq

    if( EdrvCyclicInstance_l.m_fNextCycleValid == FALSE )
    {
        //use current time + negative shift to set a valid next cycle
        EdrvCyclicInstance_l.m_dwNextCycleTime = udwMacTimeEntry + OMETH_US_2_TICKS(EDRVCYC_NEG_SHIFT_US);

        //next timer IRQ correction
        udwNextTimerIrqNs -= OMETH_TICKS_2_NS(EdrvCyclicInstance_l.m_dwTxProcDur);

        EdrvCyclicInstance_l.m_fNextCycleValid = TRUE;

    }
    else
    {
        //cycle is valid, compensate next timer irq

        //calculate time difference of Next SoC - approx. entry of this function
        DWORD udwDiff;
        DWORD udwDiffNs;

        udwDiff = EdrvCyclicInstance_l.m_dwNextCycleTime - udwMacTimeEntry;

        if( udwDiff & 0x80000000UL )
        {
            udwDiff = udwMacTimeEntry - EdrvCyclicInstance_l.m_dwNextCycleTime;
            udwDiffNs = OMETH_TICKS_2_NS(udwDiff);
            udwNextTimerIrqNs -= (EDRVCYC_NEG_SHIFT_US * 1000UL + udwDiffNs);
            Ret = EdrvCyclicCycleTimeViolation(udwNextTimerIrqNs);
            goto CycleDone;
        }

        //substract TX buffer list processing from cycle time
        udwNextTimerIrqNs -= OMETH_TICKS_2_NS(EdrvCyclicInstance_l.m_dwTxProcDur);

        udwDiffNs = OMETH_TICKS_2_NS(udwDiff);

        if( udwDiffNs > (EDRVCYC_NEG_SHIFT_US * 1000UL) )
        {
            //time difference is larger negative shift
            udwNextTimerIrqNs += (udwDiffNs - EDRVCYC_NEG_SHIFT_US * 1000UL);
        }
        else if( udwDiffNs > (EDRVCYC_MIN_SHIFT_US * 1000UL) )
        {
            //time difference is shorter than negative shift but larger than minimum
            udwNextTimerIrqNs -= (EDRVCYC_NEG_SHIFT_US * 1000UL - udwDiffNs);
        }
        else
        {
            //time difference is too short => cycle violation!
            udwNextTimerIrqNs -= (EDRVCYC_NEG_SHIFT_US * 1000UL - udwDiffNs);
            Ret = EdrvCyclicCycleTimeViolation(udwNextTimerIrqNs);
            goto CycleDone;
        }
    }

    //set accumulator for cycle window calculation
    udwAbsTime = EdrvCyclicInstance_l.m_dwNextCycleTime; //get cycle start time

    //set limits to verify if time triggered tx is within cycle
    // note: otherwise openMAC would be confused
    udwCycleMin = EdrvCyclicInstance_l.m_dwNextCycleTime; //minimum limit
    udwCycleMax = EdrvCyclicInstance_l.m_dwNextCycleTime + \
            OMETH_US_2_TICKS(EdrvCyclicInstance_l.m_dwCycleLenUs); //maximum limit

    //loop through TX buffer list
    while ((pTxBuffer = EdrvCyclicInstance_l.m_paTxBufferList[EdrvCyclicInstance_l.m_uiCurTxBufferEntry]) != NULL)
    {
        //compare TX buffer time offset with next offset (considers IPG and last packet length)
        //note: otherwise openMAC is confused if time-trig TX starts within other time-trig TX!
        if( (fFirstPkt == FALSE) && (udwNextOffNs > pTxBuffer->m_dwTimeOffsetNs) )
        {
            udwAbsTime += OMETH_NS_2_TICKS(udwNextOffNs); //accumulate offset
        }
        else
        {
            udwAbsTime += OMETH_NS_2_TICKS(pTxBuffer->m_dwTimeOffsetNs); //accumulate offset
        }
        fFirstPkt = FALSE; //first packet is surely out...

        //verify if packet TX start time is within cycle window
        if( (udwAbsTime - udwCycleMin) > (udwCycleMax - udwCycleMin) )
        {
            //packet is outside of the window
            Ret = EdrvCyclicCycleTimeViolation(udwNextTimerIrqNs);
            goto CycleDone;
        }

        //pTxBuffer->m_dwTimeOffsetNs = udwAbsTime | 1; //lowest bit enables time triggered send
        //set the absolute TX start time, and OR the lowest bit to give Edrv a hint
        pTxBuffer->m_dwTimeOffsetAbsTk = udwAbsTime | 1; //lowest bit enables time triggered send

        Ret = EdrvSendTxMsg(pTxBuffer);
        if (Ret != kEplSuccessful)
        {
            goto Exit;
        }

        //set the absolute TX start time to zero
        // -> If the TX buffer is reused as manual TX, EdrvSendTxMsg is not confused!
        pTxBuffer->m_dwTimeOffsetAbsTk = 0;

        //calculate the length of the sent packet, add IPG and thus know the next earliest TX time
        {
            DWORD udwLength = pTxBuffer->m_uiTxMsgLen;

            //consider padding!
            if( udwLength < 60UL )
            {
                udwLength = 60UL;
            }

            // ( pre + header + payload + padding + crc ) * 80ns/byte + 960ns = next TX time
            udwNextOffNs = EDRVCYC_BYTETIME_NS * (EDRVCYC_PREAMB_SIZE + ETH_CRC_SIZE + udwLength) + EDRVCYC_IPG_NS;
        }

        //switch to next TX buffer
        EdrvCyclicInstance_l.m_uiCurTxBufferEntry++;
    }

    //set up next timer interrupt
    Ret = EplTimerHighReskModifyTimerNs(&EdrvCyclicInstance_l.m_TimerHdlCycle,
        udwNextTimerIrqNs,
        EdrvCyclicCbTimerCycle,
        0L,
        FALSE);

    if (Ret != kEplSuccessful)
    {
        PRINTF("%s: EplTimerHighReskModifyTimerNs ret=0x%X\n", __func__, Ret);
        goto Exit;
    }

CycleDone:
    //calculate next cycle
    EdrvCyclicInstance_l.m_dwNextCycleTime += OMETH_US_2_TICKS(EdrvCyclicInstance_l.m_dwCycleLenUs);

Exit:
    return Ret;
}