www.pudn.com > ethercat-slave-source-code.rar > sampleappl.c, change:2013-05-03,size:13617b


/** 
\addtogroup SampleAppl Sample Application 
@{ 
*/ 
 
/** 
\file Sampleappl.c 
\author EthercatSSC@beckhoff.com 
\brief Implementation 
 
\version 5.10 
 
<br>Changes to version V5.01:<br> 
V5.10 ECAT10: Add missing include 'objdef.h'<br> 
              Add process data size calculation to sampleappl<br> 
V5.10 ECAT6: Add "USE_DEFAULT_MAIN" to enable or disable the main function<br> 
V5.10 FC1100: Stop stack if hardware init failed<br> 
<br>Changes to version V5.0:<br> 
V5.01 APPL2: Update Sample Application Output mapping<br> 
V5.0: file created 
*/ 
 
 
/*----------------------------------------------------------------------------------------- 
------ 
------    Includes 
------ 
-----------------------------------------------------------------------------------------*/ 
#include "ecat_def.h" 
 
#if SAMPLE_APPLICATION 
 
#include "ecatslv.h" 
#if COE_SUPPORTED 
/* ECATCHANGE_START(V5.10) ECAT10*/ 
#include "objdef.h" 
/* ECATCHANGE_END(V5.10) ECAT10*/ 
#endif 
#include "ecatappl.h" 
 
#define _SAMPLE_APPLICATION_ 
#include "Sampleappl.h" 
#undef _SAMPLE_APPLICATION_ 
 
 
/*-------------------------------------------------------------------------------------- 
------ 
------    local types and defines 
------ 
--------------------------------------------------------------------------------------*/ 
 
/*----------------------------------------------------------------------------------------- 
------ 
------    local variables and constants 
------ 
-----------------------------------------------------------------------------------------*/ 
 
/*----------------------------------------------------------------------------------------- 
------ 
------    application specific functions 
------ 
-----------------------------------------------------------------------------------------*/ 
 
/*----------------------------------------------------------------------------------------- 
------ 
------    generic functions 
------ 
-----------------------------------------------------------------------------------------*/ 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 \brief    The function is called when an error state was acknowledged by the master 
 
*//////////////////////////////////////////////////////////////////////////////////////// 
 
void    APPL_AckErrorInd(UINT16 stateTrans) 
{ 
 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 \return    AL Status Code (see ecatslv.h ALSTATUSCODE_....) 
 
 \brief    The function is called in the state transition from INIT to PREOP when 
             all general settings were checked to start the mailbox handler. This function 
             informs the application about the state transition, the application can refuse 
             the state transition when returning an AL Status error code. 
            The return code NOERROR_INWORK can be used, if the application cannot confirm 
            the state transition immediately, in that case this function will be called cyclically 
            until a value unequal NOERROR_INWORK is returned 
 
*//////////////////////////////////////////////////////////////////////////////////////// 
 
UINT16 APPL_StartMailboxHandler(void) 
{ 
    return ALSTATUSCODE_NOERROR; 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 \return     0, NOERROR_INWORK 
 
 \brief    The function is called in the state transition from PREEOP to INIT 
             to stop the mailbox handler. This functions informs the application 
             about the state transition, the application cannot refuse 
             the state transition. 
 
*//////////////////////////////////////////////////////////////////////////////////////// 
 
UINT16 APPL_StopMailboxHandler(void) 
{ 
    return ALSTATUSCODE_NOERROR; 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 \param    pIntMask    pointer to the AL Event Mask which will be written to the AL event Mask 
                        register (0x204) when this function is succeeded. The event mask can be adapted 
                        in this function 
 \return    AL Status Code (see ecatslv.h ALSTATUSCODE_....) 
 
 \brief    The function is called in the state transition from PREOP to SAFEOP when 
           all general settings were checked to start the input handler. This function 
           informs the application about the state transition, the application can refuse 
           the state transition when returning an AL Status error code. 
           The return code NOERROR_INWORK can be used, if the application cannot confirm 
           the state transition immediately, in that case the application need to be complete  
           the transition by calling ECAT_StateChange. 
*//////////////////////////////////////////////////////////////////////////////////////// 
 
UINT16 APPL_StartInputHandler(UINT16 *pIntMask) 
{ 
    return ALSTATUSCODE_NOERROR; 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 \return     0, NOERROR_INWORK 
 
 \brief    The function is called in the state transition from SAFEOP to PREEOP 
             to stop the input handler. This functions informs the application 
             about the state transition, the application cannot refuse 
             the state transition. 
 
*//////////////////////////////////////////////////////////////////////////////////////// 
 
UINT16 APPL_StopInputHandler(void) 
{ 
    return ALSTATUSCODE_NOERROR; 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 \return    AL Status Code (see ecatslv.h ALSTATUSCODE_....) 
 
 \brief    The function is called in the state transition from SAFEOP to OP when 
             all general settings were checked to start the output handler. This function 
             informs the application about the state transition, the application can refuse 
             the state transition when returning an AL Status error code. 
           The return code NOERROR_INWORK can be used, if the application cannot confirm 
           the state transition immediately, in that case the application need to be complete  
           the transition by calling ECAT_StateChange. 
*//////////////////////////////////////////////////////////////////////////////////////// 
 
UINT16 APPL_StartOutputHandler(void) 
{ 
    return ALSTATUSCODE_NOERROR; 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 \return     0, NOERROR_INWORK 
 
 \brief    The function is called in the state transition from OP to SAFEOP 
             to stop the output handler. This functions informs the application 
             about the state transition, the application cannot refuse 
             the state transition. 
 
*//////////////////////////////////////////////////////////////////////////////////////// 
 
UINT16 APPL_StopOutputHandler(void) 
{ 
    return ALSTATUSCODE_NOERROR; 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
\return     0(ALSTATUSCODE_NOERROR), NOERROR_INWORK 
\param      pInputSize  pointer to save the input process data length 
\param      pOutputSize  pointer to save the output process data length 
 
\brief    This function calculates the process data sizes from the actual SM-PDO-Assign 
            and PDO mapping 
*//////////////////////////////////////////////////////////////////////////////////////// 
UINT16 APPL_GenerateMapping(UINT16 *pInputSize,UINT16 *pOutputSize) 
{ 
#if COE_SUPPORTED 
/* ECATCHANGE_START(V5.10) ECAT10*/ 
    UINT16 result = ALSTATUSCODE_NOERROR; 
    UINT16 PDOAssignEntryCnt = 0; 
    OBJCONST TOBJECT OBJMEM * pPDO = NULL; 
    UINT16 PDOSubindex0 = 0; 
    UINT32 *pPDOEntry = NULL; 
    UINT16 PDOEntryCnt = 0; 
    UINT16 InputSize = 0; 
    UINT16 OutputSize = 0; 
 
    /*Scan object 0x1C12 RXPDO assign*/ 
    for(PDOAssignEntryCnt = 0; PDOAssignEntryCnt < sRxPDOassign.u16SubIndex0; PDOAssignEntryCnt++) 
    { 
        pPDO = OBJ_GetObjectHandle(sRxPDOassign.aEntries[PDOAssignEntryCnt]); 
        if(pPDO != NULL) 
        { 
            PDOSubindex0 = *((UINT16 *)pPDO->pVarPtr); 
            for(PDOEntryCnt = 0; PDOEntryCnt < PDOSubindex0; PDOEntryCnt++) 
            { 
                pPDOEntry = (UINT32 *)((UINT8 *)pPDO->pVarPtr + (OBJ_GetEntryOffset((PDOEntryCnt+1),pPDO)>>3));    //goto PDO entry 
                // we increment the expected output size depending on the mapped Entry 
                OutputSize += (UINT16) ((*pPDOEntry) & 0xFF); 
            } 
        } 
        else 
        { 
            /*assigned PDO was not found in object dictionary. return invalid mapping*/ 
            OutputSize = 0; 
            result = ALSTATUSCODE_INVALIDOUTPUTMAPPING; 
            break; 
        } 
    } 
 
    OutputSize = (OutputSize + 7) >> 3; 
 
    if(result == 0) 
    { 
        /*Scan Object 0x1C13 TXPDO assign*/ 
        for(PDOAssignEntryCnt = 0; PDOAssignEntryCnt < sTxPDOassign.u16SubIndex0; PDOAssignEntryCnt++) 
        { 
            pPDO = OBJ_GetObjectHandle(sTxPDOassign.aEntries[PDOAssignEntryCnt]); 
            if(pPDO != NULL) 
            { 
                PDOSubindex0 = *((UINT16 *)pPDO->pVarPtr); 
                for(PDOEntryCnt = 0; PDOEntryCnt < PDOSubindex0; PDOEntryCnt++) 
                { 
                    pPDOEntry = (UINT32 *)((UINT8 *)pPDO->pVarPtr + (OBJ_GetEntryOffset((PDOEntryCnt+1),pPDO)>>3));    //goto PDO entry 
                    // we increment the expected output size depending on the mapped Entry 
                    InputSize += (UINT16) ((*pPDOEntry) & 0xFF); 
                } 
            } 
            else 
            { 
                /*assigned PDO was not found in object dictionary. return invalid mapping*/ 
                InputSize = 0; 
                result = ALSTATUSCODE_INVALIDINPUTMAPPING; 
                break; 
            } 
        } 
    } 
    InputSize = (InputSize + 7) >> 3; 
 
    *pInputSize = InputSize; 
    *pOutputSize = OutputSize; 
    return result; 
/* ECATCHANGE_END(V5.10) ECAT10*/ 
#else 
    *pInputSize = PD_INPUT_SIZE; 
    *pOutputSize = PD_OUTPUT_SIZE; 
     
    return ALSTATUSCODE_NOERROR; 
#endif 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
\param      pData  pointer to input process data 
 
\brief      This function will copies the inputs from the local memory to the ESC memory 
            to the hardware 
*//////////////////////////////////////////////////////////////////////////////////////// 
#if _PIC18 && AL_EVENT_ENABLED 
/* the pragma interrupt_level is used to tell the compiler that these functions will not 
   be called at the same time from the main function and the interrupt routine */ 
#pragma interrupt_level 1 
#endif 
void APPL_InputMapping(UINT16* pData) 
{ 
    MEMCPY(pData,&InputCounter,SIZEOF(InputCounter)); 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
\param      pData  pointer to output process data 
 
\brief    This function will copies the outputs from the ESC memory to the local memory 
            to the hardware 
*//////////////////////////////////////////////////////////////////////////////////////// 
#if _PIC18  && AL_EVENT_ENABLED 
/* the pragma interrupt_level is used to tell the compiler that these functions will not 
   be called at the same time from the main function and the interrupt routine */ 
#pragma interrupt_level 1 
#endif 
void APPL_OutputMapping(UINT16* pData) 
{ 
    MEMCPY(&OutputCounter,pData,SIZEOF(OutputCounter)); 
} 
 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
\brief    This function will called from the synchronisation ISR  
            or from the mainloop if no synchronisation is supported 
*//////////////////////////////////////////////////////////////////////////////////////// 
void APPL_Application(void) 
{ 
    /*Hardware independent sample application*/ 
    if(OutputCounter > 0) 
    { 
        InputCounter = OutputCounter+1; 
    } 
    else 
    { 
        InputCounter++; 
    } 
} 
 
#if EXPLICIT_DEVICE_ID 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 \return    The Explicit Device ID of the EtherCAT slave 
 
 \brief     Calculate the Explicit Device ID 
*//////////////////////////////////////////////////////////////////////////////////////// 
UINT16 APPL_GetDeviceID() 
{ 
    return 0xBABA; 
} 
#endif 
 
/*ECATCHANGE_START(V5.10) ECAT6*/ 
#if USE_DEFAULT_MAIN 
/*ECATCHANGE_END(V5.10) ECAT6*/ 
///////////////////////////////////////////////////////////////////////////////////////// 
/** 
 
 \brief    This is the main function 
 
*//////////////////////////////////////////////////////////////////////////////////////// 
#if _PIC24 
int main(void) 
#else 
void main(void) 
#endif 
{ 
    /* initialize the Hardware and the EtherCAT Slave Controller */ 
#if FC1100_HW 
/*ECATCHANGE_START(V5.10) FC1100*/ 
    if(HW_Init()) 
    { 
        HW_Release(); 
        return; 
    } 
/*ECATCHANGE_END(V5.10) FC1100*/ 
#else 
    HW_Init(); 
#endif 
    MainInit(); 
 
    bRunApplication = TRUE; 
    do 
    { 
        MainLoop(); 
 
    } while (bRunApplication == TRUE); 
 
    HW_Release(); 
#if _PIC24 
    return 0; 
#endif 
} 
#endif //#if USE_DEFAULT_MAIN 
 
#endif //#if SAMPLE_APPLICATION 
 
/** @} */