//------------------------------------------------------------------------------
tOplkError pdoucal_getRxPdo(BYTE** ppPdo_p, UINT channelId_p, WORD pdoSize_p)
{
    OPLK_ATOMIC_T    readBuf;
    UNUSED_PARAMETER(pdoSize_p);    // Used to avoid compiler warning if OPLK_DCACHE_INVALIDATE is not set

    // Invalidate data cache for addressed txChannelInfo
    OPLK_DCACHE_INVALIDATE(&(pPdoMem_l->rxChannelInfo[channelId_p]), sizeof(tPdoBufferInfo));

    if (pPdoMem_l->rxChannelInfo[channelId_p].newData)
    {
        readBuf = pPdoMem_l->rxChannelInfo[channelId_p].readBuf;
        OPLK_ATOMIC_EXCHANGE(&pPdoMem_l->rxChannelInfo[channelId_p].cleanBuf,
                             readBuf,
                             pPdoMem_l->rxChannelInfo[channelId_p].readBuf);
        pPdoMem_l->rxChannelInfo[channelId_p].newData = 0;

        // Flush data cache for variables changed in this function
        OPLK_DCACHE_FLUSH(&(pPdoMem_l->rxChannelInfo[channelId_p].readBuf), sizeof(OPLK_ATOMIC_T));
        OPLK_DCACHE_FLUSH(&(pPdoMem_l->rxChannelInfo[channelId_p].newData), sizeof(UINT8));
    }

    readBuf = pPdoMem_l->rxChannelInfo[channelId_p].readBuf;
    *ppPdo_p = pTripleBuf_l[readBuf] + pPdoMem_l->rxChannelInfo[channelId_p].channelOffset;

    OPLK_DCACHE_INVALIDATE(*ppPdo_p, pdoSize_p);

    return kErrorOk;
}
예제 #2
0
//------------------------------------------------------------------------------
static tTimesyncSocTime* getSocTime(void)
{
    tTimesyncSocTimeTripleBuf*  pTripleBuf;
    OPLK_ATOMIC_T               readBuf;

    pTripleBuf = &pSharedMemory_l->socTime;

    OPLK_DCACHE_INVALIDATE(pTripleBuf, sizeof(*pTripleBuf));

    if (pTripleBuf->newData)
    {
        // Switch triple buffer because there is new data available!
        readBuf = pTripleBuf->read;
        OPLK_ATOMIC_EXCHANGE(&pTripleBuf->clean, readBuf, pTripleBuf->read);

        pTripleBuf->newData = 0;

        OPLK_DCACHE_FLUSH(&pTripleBuf->clean, sizeof(pTripleBuf->clean));
        OPLK_DCACHE_FLUSH(&pTripleBuf->read, sizeof(pTripleBuf->read));
        OPLK_DCACHE_FLUSH(&pTripleBuf->newData, sizeof(pTripleBuf->newData));
    }

    readBuf = pTripleBuf->read;

    // Return reference to read buffer
    return &pTripleBuf->aTripleBuf[readBuf];
}
//------------------------------------------------------------------------------
tOplkError pdoucal_setTxPdo(UINT channelId_p, BYTE* pPdo_p, WORD pdoSize_p)
{
    OPLK_ATOMIC_T    temp;
    UNUSED_PARAMETER(pPdo_p);       // Used to avoid compiler warning if OPLK_DCACHE_FLUSH is not set
    UNUSED_PARAMETER(pdoSize_p);    // Used to avoid compiler warning if OPLK_DCACHE_FLUSH is not set

    OPLK_DCACHE_FLUSH(pPdo_p, pdoSize_p);

    //TRACE("%s() chan:%d wi:%d\n", __func__, channelId_p, pPdoMem_l->txChannelInfo[channelId_p].writeBuf);

    // Invalidate data cache already done in pdoucal_getTxPdoAdrs()

    temp = pPdoMem_l->txChannelInfo[channelId_p].writeBuf;
    OPLK_ATOMIC_EXCHANGE(&pPdoMem_l->txChannelInfo[channelId_p].cleanBuf,
                         temp,
                         pPdoMem_l->txChannelInfo[channelId_p].writeBuf);
    pPdoMem_l->txChannelInfo[channelId_p].newData = 1;

    // Flush data cache for variables changed in this function
    OPLK_DCACHE_FLUSH(&(pPdoMem_l->txChannelInfo[channelId_p].writeBuf), sizeof(OPLK_ATOMIC_T));
    OPLK_DCACHE_FLUSH(&(pPdoMem_l->txChannelInfo[channelId_p].newData), sizeof(UINT8));

    //TRACE("%s() chan:%d new wi:%d\n", __func__, channelId_p, pPdoMem_l->txChannelInfo[channelId_p].writeBuf);

    return kErrorOk;
}
//------------------------------------------------------------------------------
static tOplkError setNetTime(void)
{
    OPLK_ATOMIC_T  writeBuf;
    tOplkError     ret = kErrorOk;
    BOOL           fValidSystemTime = FALSE;

    writeBuf = instance_l.pSharedMemory->userToKernelSocTime.write;
    // Get system clock time
    ret = target_getSystemTime(&instance_l.pSharedMemory->userToKernelSocTime.aTripleBuf[writeBuf].netTime,
                               &fValidSystemTime);

    if (ret != kErrorOk)
    {
        DEBUG_LVL_ERROR_TRACE("%s Failed to get current system time!\n",
                              __func__);
        return ret;
    }

    if (fValidSystemTime)
    {
        OPLK_ATOMIC_EXCHANGE(&instance_l.pSharedMemory->userToKernelSocTime.clean,
                             writeBuf,
                             instance_l.pSharedMemory->userToKernelSocTime.write);
        // Set the newData flag to indicate that a new data is available in the shared buffer
        instance_l.pSharedMemory->userToKernelSocTime.newData = 1;

        // Flush data cache for variables changed in this function
        OPLK_DCACHE_FLUSH(&instance_l.pSharedMemory->userToKernelSocTime.write, sizeof(OPLK_ATOMIC_T));
        OPLK_DCACHE_FLUSH(&instance_l.pSharedMemory->userToKernelSocTime.newData, sizeof(UINT8));
    }

    return ret;
}
//------------------------------------------------------------------------------
void errhndkcal_setMnCnLossPresThresholdCnt(UINT nodeIdx_p,
                                            UINT32 thresholdCnt_p)
{
    pErrHndObjects_l->aMnCnLossPres[nodeIdx_p].thresholdCnt = thresholdCnt_p;

    OPLK_DCACHE_FLUSH(&pErrHndObjects_l->aMnCnLossPres[nodeIdx_p], sizeof(tErrorObject));
}
//------------------------------------------------------------------------------
tOplkError timesynck_init(void)
{
    tOplkError  ret;

    OPLK_MEMSET(&timesynckInstance_l, 0, sizeof(timesynckInstance_l));

    timesynckInstance_l.syncEventCycle = 1; // Default every cycle

    ret = timesynckcal_init();
    if (ret != kErrorOk)
        return ret;

#if defined(CONFIG_INCLUDE_SOC_TIME_FORWARD)
    timesynckInstance_l.pSharedMemory = timesynckcal_getSharedMemory();
    if (timesynckInstance_l.pSharedMemory == NULL)
        return kErrorNoResource;

    // Initialize shared memory
    OPLK_MEMSET(timesynckInstance_l.pSharedMemory, 0, sizeof(*timesynckInstance_l.pSharedMemory));

    // Initialize triple buffer
    timesynckInstance_l.pSharedMemory->kernelToUserSocTime.clean = 0;
    timesynckInstance_l.pSharedMemory->kernelToUserSocTime.read = 1;
    timesynckInstance_l.pSharedMemory->kernelToUserSocTime.write = 2;

    OPLK_DCACHE_FLUSH(timesynckInstance_l.pSharedMemory, sizeof(*timesynckInstance_l.pSharedMemory));
#endif

    return ret;
}
//------------------------------------------------------------------------------
void errhndkcal_setMnCycTimeExceedCounters(UINT32 cumulativeCnt_p,
                                           UINT32 thresholdCnt_p)
{
    pErrHndObjects_l->mnCycTimeExceed.cumulativeCnt = cumulativeCnt_p;
    pErrHndObjects_l->mnCycTimeExceed.thresholdCnt = thresholdCnt_p;

    OPLK_DCACHE_FLUSH(&pErrHndObjects_l->mnCycTimeExceed, sizeof(tErrorObject));
}
//------------------------------------------------------------------------------
void errhndkcal_setCnCrcCounters(UINT32 cumulativeCnt_p,
                                 UINT32 thresholdCnt_p)
{
    pErrHndObjects_l->cnCrcErr.cumulativeCnt = cumulativeCnt_p;
    pErrHndObjects_l->cnCrcErr.thresholdCnt = thresholdCnt_p;

    OPLK_DCACHE_FLUSH(&pErrHndObjects_l->cnCrcErr, sizeof(tErrorObject));
}
//------------------------------------------------------------------------------
tOplkError timesynck_getNetTime(tNetTime* pNetTime_p, BOOL* pNewData_p)
{
    OPLK_ATOMIC_T readBuf;

    if ((timesynckInstance_l.pSharedMemory == NULL) || (pNetTime_p == NULL) ||
        (pNewData_p == NULL))
    {
        DEBUG_LVL_ERROR_TRACE("%s Pointer to memory is invalid!\n",
                              __func__);
        return kErrorNoResource;
    }

    if (timesynckInstance_l.pSharedMemory->userToKernelSocTime.newData)
    {
        *pNewData_p = TRUE;
        readBuf = timesynckInstance_l.pSharedMemory->userToKernelSocTime.read;

        OPLK_ATOMIC_EXCHANGE(&timesynckInstance_l.pSharedMemory->userToKernelSocTime.clean,
                             readBuf,
                             timesynckInstance_l.pSharedMemory->userToKernelSocTime.read);
        // Once the read from buffer is done, reset the newData
        timesynckInstance_l.pSharedMemory->userToKernelSocTime.newData = 0;

        // Flush data cache for variables changed in this function
        OPLK_DCACHE_FLUSH(&timesynckInstance_l.pSharedMemory->userToKernelSocTime.read,
                          sizeof(OPLK_ATOMIC_T));
        OPLK_DCACHE_FLUSH(&timesynckInstance_l.pSharedMemory->userToKernelSocTime.newData,
                          sizeof(UINT8));

        pNetTime_p->nsec = timesynckInstance_l.pSharedMemory->userToKernelSocTime.aTripleBuf[0].netTime.nsec;
        pNetTime_p->sec = timesynckInstance_l.pSharedMemory->userToKernelSocTime.aTripleBuf[0].netTime.sec;
    }
    else
        *pNewData_p = FALSE;

    return kErrorOk;
}
//------------------------------------------------------------------------------
tOplkError timesynck_setSocTime(const tTimesyncSocTime* pSocTime_p)
{
    tTimesyncSocTimeTripleBuf*  pTripleBuf;
    OPLK_ATOMIC_T               writeBuf;
    tTimesyncSocTime*           pBuffer;

    // Check parameter validity
    ASSERT(pSocTime_p != NULL);

    if (timesynckInstance_l.pSharedMemory == NULL)
    {
        // Looks like the CAL has no SoC time forward support, but feature is
        // enabled!
        DEBUG_LVL_ERROR_TRACE("%s Pointer to shared memory is invalid!\n",
                              __func__);
        return kErrorNoResource;
    }

    pTripleBuf = &timesynckInstance_l.pSharedMemory->kernelToUserSocTime;

    OPLK_DCACHE_INVALIDATE(pTripleBuf, sizeof(*pTripleBuf));

    writeBuf = pTripleBuf->write;
    pBuffer = &pTripleBuf->aTripleBuf[writeBuf];

    OPLK_MEMCPY(pBuffer, pSocTime_p, sizeof(*pBuffer));

    OPLK_ATOMIC_EXCHANGE(&pTripleBuf->clean, writeBuf, pTripleBuf->write);

    pTripleBuf->newData = 1;

    OPLK_DCACHE_FLUSH(&pTripleBuf->clean, sizeof(pTripleBuf->clean));
    OPLK_DCACHE_FLUSH(&pTripleBuf->write, sizeof(pTripleBuf->write));
    OPLK_DCACHE_FLUSH(&pTripleBuf->newData, sizeof(pTripleBuf->newData));

    return kErrorOk;
}
//------------------------------------------------------------------------------
void errhndkcal_setMnCycTimeExceedThresholdCnt(UINT32 thresholdCnt_p)
{
    pErrHndObjects_l->mnCycTimeExceed.thresholdCnt = thresholdCnt_p;

    OPLK_DCACHE_FLUSH(&pErrHndObjects_l->mnCycTimeExceed, sizeof(tErrorObject));
}
//------------------------------------------------------------------------------
void errhndkcal_setMnCrcThresholdCnt(UINT32 thresholdCnt_p)
{
    pErrHndObjects_l->mnCrcErr.thresholdCnt = thresholdCnt_p;

    OPLK_DCACHE_FLUSH(&pErrHndObjects_l->mnCrcErr, sizeof(tErrorObject));
}
//------------------------------------------------------------------------------
void errhndkcal_setLossPreqThresholdCnt(UINT32 thresholdCnt_p)
{
    pErrHndObjects_l->cnLossPreq.thresholdCnt = thresholdCnt_p;

    OPLK_DCACHE_FLUSH(&pErrHndObjects_l->cnLossPreq, sizeof(tErrorObject));
}