EtherCAT从站状态机在PREOP to SAFEOP的过程中调用UINT16 StartInputHandler(void)函数,该函数主要有以下4个作用:
01 将过程输出、输入物理地址给到ESC,判定buffer重叠。
02 设定从站同步模式(FREERUN, SM, DC),计算同步周期。
03 设定全局变量(bEscIntEnabled,bDcSyncActive,ALEventMask),以使MainLoop进入正确的同步模式进行PDO。
04 开启看门狗。
下文对UINT16 StartInputHandler(void)函数进行了注释。
UINT16 StartInputHandler(void)函数由backoff SSC v5i12提供。
/
/**
\return AL Status Code (see ecatslv.h ALSTATUSCODE_....)
\brief This function is called in case of the state transition from PREOP to SAFEOP.
|brief the areas of the Sync Managers will be checked for overlapping,
\brief the synchronization mode (Free Run, Synchron, Distributed Clocks) is selected,
\brief the requested cycle time will be checked, the watchdog is started
\brief and the AL Event Mask register will be set
*////
UINT16 StartInputHandler(void)
{
TSYNCMAN ESCMEM * pSyncMan;
UINT8 dcControl;
UINT16 wdiv = 0;
/*ECATCHANGE_START(V5.11) ECAT4*/
UINT16 wd = 0;
/*ECATCHANGE_END(V5.11) ECAT4*/
UINT32 cycleTimeSync0 = 0; /* Sync0 cycle time */
UINT32 cycleTimeSync1 = 0; /* Delay between the Sync0 and Sycn1 signal. A new Sync1 cycle starts on the next Sync0 signal after Sync1 signal.*/
BOOL bSubordinatedCycles = FALSE;
UINT16 nPdInputBuffer = 3;
UINT16 nPdOutputBuffer = 3;
//you can configure this two variable , to set DC mode by yourself. See line 771 to 809. - Javan
UINT16 SyncType0x1C32 = 0; /* Helper variable for sync type for SM2 (required if no CoE is supported or no output process data available)*/
UINT16 SyncType0x1C33 = 0; /* Helper variable for sync type for SM3 (required if no CoE is supported or no input process data available)*/
UINT16 u16MinSuppSyncType = 0xFFFF; /* Minimum supported Sync Types */
u16MinSuppSyncType &= sSyncManOutPar.u16SyncTypesSupported;
u16MinSuppSyncType &= sSyncManInPar.u16SyncTypesSupported;
u16ALEventMask = 0;
/*
01 --- Check if SyncManager areas overlapping ---
*/
bEcatFirstOutputsReceived = FALSE;//Here the bEcatFirstOutputsReceived has been set false. - Javan
/* get a pointer to the Sync Manager Channel 2 (Outputs) */
/*ECATCHANGE_START(V5.11) HW1*/
pSyncMan = GetSyncMan(PROCESS_DATA_OUT);
/*ECATCHANGE_END(V5.11) HW1*/
/* store the address of the Sync Manager Channel 2 (Outputs) */
nEscAddrOutputData = pSyncMan->PhysicalStartAddress;//SM2:Here first get physical address for esc output. - Javan
/* get the number of output buffer used for calculating the address areas */
if (pSyncMan->Settings[SM_SETTING_CONTROL_OFFSET] & SM_SETTING_MODE_ONE_BUFFER_VALUE)
{
nPdOutputBuffer = 1;
}
/* get a pointer to the Sync Manager Channel 3 (Inputs) */
/*ECATCHANGE_START(V5.11) HW1*/
pSyncMan = GetSyncMan(PROCESS_DATA_IN);
/*ECATCHANGE_END(V5.11) HW1*/
/* store the address of the Sync Manager Channel 3 (Inputs)*/
nEscAddrInputData = pSyncMan->PhysicalStartAddress;//SM3:Here first get physical address for esc input. - Javan
/* get the number of input buffer used for calculating the address areas */
if ( pSyncMan->Settings[SM_SETTING_CONTROL_OFFSET] & SM_SETTING_MODE_ONE_BUFFER_VALUE )
nPdInputBuffer = 1;
/* it has be checked if the Sync Manager memory areas for Inputs and Outputs will not overlap
the Sync Manager memory areas for the Mailbox */
//Check overlap. - Javan
if (((nEscAddrInputData + nPdInputSize * nPdInputBuffer) > u16EscAddrSendMbx && (nEscAddrInputData < (u16EscAddrSendMbx + u16SendMbxSize)))
|| ((nEscAddrInputData + nPdInputSize * nPdInputBuffer) > u16EscAddrReceiveMbx && (nEscAddrInputData < (u16EscAddrReceiveMbx + u16ReceiveMbxSize)))
)
{
return ALSTATUSCODE_INVALIDSMINCFG;
}
if (
((nEscAddrOutputData + nPdOutputSize * nPdOutputBuffer) > u16EscAddrSendMbx && (nEscAddrOutputData < (u16EscAddrSendMbx + u16SendMbxSize)))
||((nEscAddrOutputData + nPdOutputSize * nPdOutputBuffer) > u16EscAddrReceiveMbx && (nEscAddrOutputData < (u16EscAddrReceiveMbx + u16ReceiveMbxSize)))
||
((nEscAddrOutputData + nPdOutputSize * nPdOutputBuffer) > nEscAddrInputData && (nEscAddrOutputData < (nEscAddrInputData + nPdInputSize)))
)
{
/* Sync Manager Channel 2 memory area (Outputs) overlaps the Sync Manager memory areas for the Mailbox
or the Sync Manager Channel 3 memory area (Inputs) */
return ALSTATUSCODE_INVALIDSMOUTCFG;
}
/*
02 --- Check configured synchronisation ---!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
/* Get the DC Control/Activation register value*/
/*Read register 0x981 (corresponding masks are adapted)*/
HW_EscReadByte(dcControl, ESC_DC_SYNC_ACTIVATION_OFFSET);
//Get cycle time for syncx from master. - Javan
// Cycle time for Sync0
HW_EscReadDWord(cycleTimeSync0, ESC_DC_SYNC0_CYCLETIME_OFFSET);
cycleTimeSync0 = SWAPDWORD(cycleTimeSync0)