把 BOOT 侧已上板跑通的 SSC/HBI 移植层一次性入库(comm/ecat + gd32e50x_exmc), 并修掉「刷完首启 APP 报 EXMC 总线未就绪、断电重上即好」这条实测链: - v1.1.0.13:jumpToApplication 前补一发 LAN9252 RST#。BOOT 侧 HBI 全是索引两步事务, bootEcatDeinit 末尾的 writeReg32 把 HBI_IDX_0 留在 0x0054,而 APP 起板探针判 IDX_0==0x1234(DS 9.5.4.2 复位默认值),带着残值跳进去就直接报总线未就绪。 - v1.1.0.14:那一发不能无条件下发。path=jump_latest_now(上电 3ms 直跳、这轮 ESC 从没 起过)也在电源刚稳的窗口里拉了 RST#,释放点距上电仅约 15ms,板上表现为每次上电都停 在 BOOT 里(串口停在 [J5-HEX];microlib + putChar 逐字符阻塞等 TBE,故日志停在半截 = CPU 真停在那儿,不是尾巴没刷出来)。现由 s_escBusUp 门控(bootEcatBringup 里 exmcInit 成功才置位);脉宽从 delay_1us(按 4cycle/迭代标定,实测 30ms 只走出 8ms) 换成 DWT CYCCNT 真 30ms + 释放后 2ms;跳转前打 [J6] boot v<ver> handoff。 delay_1ms 在这里不可用:本函数跑在 __disable_irq() 之后,SysTick 中断不递减就是永久 死等,而 BOOT 没开 IWDG —— 那会变成刷完直接静默变砖。 v1.1.0.12 的两条一并入库:10s OTA 窗口的活性判据并上 ecatSessionActive(防半截灌写被 当合法 APP 跳进去、HardFault→复位→留守 10s 形成活锁);0x100A 上报真版本串 (DEVICE_SW_VERSION_LEN 0x3→0x10,acSoftwareversion 显式给 LEN+1 防越界读)。 板上实测:v1.1.0.14 上电直跳恢复正常,APP v1.6.34 起板,自检 ethercat 不再降级。
181 lines
5.8 KiB
C
181 lines
5.8 KiB
C
/**
|
|
\addtogroup CoE CAN Application Profile over EtherCAT
|
|
@{
|
|
*/
|
|
|
|
/**
|
|
\file ecatcoe.c
|
|
\author EthercatSSC@beckhoff.com
|
|
\brief Implementation
|
|
This file contains the CoE mailbox interface
|
|
|
|
\version 5.11
|
|
|
|
<br>Changes to version V5.0:<br>
|
|
V5.11 COE4: "change prototype of ""COE_ContinueInd()"" return <> 0 if a failure occurred"<br>
|
|
V5.11 ECAT10: change PROTO handling to prevent compiler errors<br>
|
|
V5.11 TEST6: add test object to trigger Slave-to-Slave communication<br>
|
|
V5.11 TEST7: add test behaviour to send an emergency on every SDO request (in SafeOP)<br>
|
|
<br>Changes to version V4.40:<br>
|
|
V5.0 SDO7: "SDOS_SdoInfoInd()" never return pending SDO Info service. Delete "NOERROR_INWORK" handling.<br>
|
|
<br>Changes to version V4.08:<br>
|
|
V4.40 SDO1: add initial value for "nSdoInfoFragmentsLeft"<br>
|
|
V4.40 MBX6: change return value if no mailbox buffer is available<br>
|
|
V4.08 MBX 1: If the switch MAILBOX_QUEUE was set, we have to put all SDO Info Responses in the Send Queue
|
|
*/
|
|
|
|
/*---------------------------------------------------------------------------------------
|
|
------
|
|
------ Includes
|
|
------
|
|
---------------------------------------------------------------------------------------*/
|
|
|
|
#include "ecat_def.h"
|
|
|
|
|
|
#include "sdoserv.h"
|
|
#define _ECATCOE_ 1
|
|
#include "ecatcoe.h"
|
|
#undef _ECATCOE_
|
|
/* ECATCHANGE_START(V5.11) ECAT10*/
|
|
/*remove definition of _ECATCOE_ (#ifdef is used in ecatcoe.h)*/
|
|
/* ECATCHANGE_END(V5.11) ECAT10*/
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------------------
|
|
------
|
|
------ internal Types and Defines
|
|
------
|
|
---------------------------------------------------------------------------------------*/
|
|
|
|
#define ECATCOE 0x4300
|
|
#define ECATCOEMAX 0x02
|
|
|
|
/*---------------------------------------------------------------------------------------
|
|
------
|
|
------ static variables
|
|
------
|
|
---------------------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------------------
|
|
------
|
|
------ static functions
|
|
------
|
|
---------------------------------------------------------------------------------------*/
|
|
|
|
/*---------------------------------------------------------------------------------------
|
|
------
|
|
------ functions
|
|
------
|
|
---------------------------------------------------------------------------------------*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
|
|
\brief This function intialize the CoE Interface.
|
|
*////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void COE_Init(void)
|
|
{
|
|
pCoeSendStored = 0;
|
|
nSdoInfoFragmentsLeft = 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
\param pCoeMbx Pointer to the received mailbox data from the master.
|
|
|
|
\return result of the operation (0 (success) or mailbox error code (MBXERR_.... defined in
|
|
mailbox.h))
|
|
|
|
\brief This function is called when a CoE (CAN application layer over EtherCAT) service is received from
|
|
the master.
|
|
*////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
UINT8 COE_ServiceInd(TCOEMBX MBXMEM *pCoeMbx)
|
|
{
|
|
UINT8 result = 0;
|
|
|
|
switch ((pCoeMbx->CoeHeader & COEHEADER_COESERVICEMASK) >> COEHEADER_COESERVICESHIFT)
|
|
{
|
|
case COESERVICE_SDOREQUEST:
|
|
/* SDO-Request received, call SDOS_SdoInd to process the SDO-Request
|
|
if an existing SDO-Stack shall be used, the corresponding function
|
|
should be called */
|
|
result = SDOS_SdoInd( (TINITSDOMBX MBXMEM *) pCoeMbx );
|
|
break;
|
|
|
|
case COESERVICE_SDOINFO:
|
|
/* SDO-Information Request received, call SDOS_SdoInfoInd to process the SDO-Request */
|
|
result = SDOS_SdoInfoInd( (TSDOINFORMATION MBXMEM *) pCoeMbx );
|
|
/*NOERROR_INWORK is never returned by SDOS_SdoInfoInd() => delete return code handling*/
|
|
break;
|
|
|
|
|
|
case COESERVICE_SDORESPONSE:
|
|
case COESERVICE_EMERGENCY:
|
|
case COESERVICE_TXPDO:
|
|
case COESERVICE_RXPDO:
|
|
case COESERVICE_TXPDOREMREQ:
|
|
case COESERVICE_RXPDOREMREQ:
|
|
/* these CoE services are not supported yet */
|
|
result = MBXERR_SERVICENOTSUPPORTED;
|
|
break;
|
|
|
|
default:
|
|
result = MBXERR_INVALIDHEADER;
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
\param pMbx Pointer to the free mailbox to sent.
|
|
|
|
\return result of the operation (0 (success)
|
|
|
|
\brief This function is called when a CoE service to be sent is stored and can
|
|
\brief be put in the send mailbox.
|
|
*////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*ECATCHANGE_START(V5.11) COE4*/
|
|
UINT8 COE_ContinueInd(TMBX MBXMEM * pMbx)
|
|
/*ECATCHANGE_END(V5.11) COE4*/
|
|
{
|
|
if (pCoeSendStored)
|
|
{
|
|
/* send the stored CoE service which could not be sent before */
|
|
MBX_MailboxSendReq(pCoeSendStored, 0);
|
|
pCoeSendStored = 0;
|
|
}
|
|
else
|
|
{
|
|
/* send the next fragment of the last CoE service (only for SDO-Information possible) */
|
|
/* in mailbox queue mode pMbx is always 0, so a mailbox buffer shall be get */
|
|
pMbx = (TMBX MBXMEM *) APPL_AllocMailboxBuffer(SIZEOF(TMBX));
|
|
/* it shall be checked if a valid pointer was returned */
|
|
/*ECATCHANGE_START(V5.11) COE4*/
|
|
if (pMbx == NULL)
|
|
{
|
|
return MBXERR_NOMOREMEMORY;
|
|
}
|
|
else
|
|
/*ECATCHANGE_END(V5.11) COE4*/
|
|
{
|
|
/* copy the stored SDO-Info-Header in the request */
|
|
MBXMEMCPY(pMbx, aSdoInfoHeader, SDO_INFO_HEADER_BYTE_SIZE);
|
|
/* call SDOS_SdoInfoInd to generate and send the next fragment */
|
|
SDOS_SdoInfoInd( (TSDOINFORMATION MBXMEM *) pMbx );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/** @} */
|
|
|
|
|
|
|