/* Read EEPROM from slave bypassing cache. APRD method.
* 从站绕过缓存读取 EEPROM。APRD方法
* @param[in] context = context struct
* 上下文结构体
* @param[in] aiadr = auto increment address of slave
* 从站自增地址
* @param[in] eeproma = (WORD) Address in the EEPROM
* (WORD单位)EEPROM 中的地址
* @param[in] timeout = Timeout in us.
* 超时时间[单位:us(微秒)]
* @return EEPROM data 64bit or 32bit
* 64bit EEPROM数据 或 32bit EEPROM数据
*/
uint64 ecx_readeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, int timeout)
{
uint16 estat;/* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
uint32 edat32;/* 32bit EEPROM数据 */
uint64 edat64;/* 64bit EEPROM数据 */
ec_eepromt ed;/* EtherCAT EEPROM 通信记录 */
int wkc,/* 工作计数器 */
cnt, /* 试行次数:最大三回 */
nackcnt = 0;/* EEprom 状态机错误应答试行次数:最大三回 */
edat64 = 0;/* 64bit EEPROM数据 */
edat32 = 0;/* 32bit EEPROM数据 */
/* 在超时时间内、设置EEprom 状态机忙位busy→idle */
if (ecx_eeprom_waitnotbusyAP(
context, /* 上下文结构体 */
aiadr,/* 从站自增地址 */
&estat,/* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
timeout))/* 超时时间[单位:us(微秒)] */
{
/*
0x0502:0x0503.11
Checksum Error at in ESC Configuration Area: ESC配置区校验
0: Checksum ok :校验和正确
1: Checksum error :校验和错误
0x0502:0x0503.12
EEPROM loading status: 器件信息校验
0: EEPROM loaded, device information ok : 器件信息正确
1: EEPROM not loaded, device information not available : 从EEPROM装载器件信息错误
(EEPROM loading in progress or finished with a failure)
0x0502:0x0503.13
Error Acknowledge/Command: 命令应答
0: No error :无错误
1: Missing EEPROM acknowledge or invalid command EEPROM emulation only:
PDI writes 1 if a temporary failure has occurred. :EEPROM无应答,或命令无效
0x0502:0x0503.14
Error Write Enable: 写使能错误
0: No error:无错误
1: Write Command without Write enable:请求写命令时无写使能
*/
if (estat /* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
& EC_ESTAT_EMASK/* EEprom 状态机错误标志掩码 Reg0x0502.11~14 EEPROM Control/Status */
) /* error bits are set *//* 错误位已设置 */
{
estat/* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
= htoes(/* 大小端转换操作宏 uint16 */
EC_ECMD_NOP); /* clear error bits */
wkc = /* 工作计数器 */
ecx_APWR(// 自增式物理写(APWR) Auto increment physical write
context->port, /* 端口(port) */
aiadr,/* 从站自增地址 */
ECT_REG_EEPCTL,// EEPROM Control/Status EEP控制/EEP状态 EEPROM控制和状态寄存器[0x0502:0x0503]
sizeof(estat),/* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
&estat,/* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
EC_TIMEOUTRET3);/* 安全数据传输的超时时间值,最大重试次数为三次 */
}
do
{
ed.comm/* Ethercat EEprom 命令类型 */
= htoes(/* 大小端转换操作宏 uint16 */
EC_ECMD_READ);/* 读 */
ed.addr/* EEPROM 地址 */
= htoes(/* 大小端转换操作宏 uint16 */
eeproma);/* (WORD单位)EEPROM 中的地址 */
ed.d2 = 0x0000;/* 第二个EEPROM地址设为0 */
cnt = 0;/* 试行次数:最大三回 */
do
{
wkc = /* 工作计数器 */
ecx_APWR(// 自增式物理写(APWR) Auto increment physical write
context->port,/* 端口(port) */
aiadr, /* 从站自增地址 */
ECT_REG_EEPCTL,// EEPROM Control/Status EEP控制/EEP状态 EEPROM控制和状态寄存器[0x0502:0x0503]
sizeof(ed), /* EtherCAT EEPROM 通信记录大小=6 */
&ed, /* EtherCAT EEPROM 通信记录 */
EC_TIMEOUTRET);/* 发送帧(tx frame)返回到接收(rx)的超时时间[单位:us(微秒)]=2000 */
}
while ((wkc/* 工作计数器 */ <= 0)
&& (cnt++/* 试行次数:最大三回 */
< EC_DEFAULTRETRIES));/* 默认重试次数,如果 WKC <= 0 */
if (wkc/* 工作计数器 */)
{
/* 睡眠函数,休眠到要求的时间(指定的延迟时间[单位:usec]) */
osal_usleep(
EC_LOCALDELAY/* eeprom准备循环的延迟时间[单位:us(微秒)] */);
estat = 0x0000;/* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
/* 在超时时间内、设置EEprom 状态机忙位busy→idle */
if (ecx_eeprom_waitnotbusyAP(
context,/* 上下文结构体 */
aiadr, /* 从站自增地址 */
&estat, /* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
timeout))/* 超时时间[单位:us(微秒)] */
{
if (estat/* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
& EC_ESTAT_NACK)/* EEprom 状态机错误应答 */
{
nackcnt++;/* EEprom 状态机错误应答试行次数:最大三回 */
/* 睡眠函数,休眠到要求的时间(指定的延迟时间[单位:usec]) */
osal_usleep(
EC_LOCALDELAY/* eeprom准备循环的延迟时间[单位:us(微秒)] */ * 5);
}
else/* EEprom 状态机错误应答位为0,跳出循环 */
{
nackcnt = 0;/* EEprom 状态机错误应答试行次数:最大三回 */
if (estat & /* Reg0x0502:0x0503 EEPROM Control/Status EEP控制/EEP状态 */
EC_ESTAT_R64)/* EEprom 状态机读取大小:支持读字节数[0: 4 Bytes:4个字节;1: 8 Bytes:8个字节] */
{
cnt = 0;/* 试行次数:最大三回 */
do
{
wkc = /* 工作计数器 */
ecx_APRD(// 自增式物理读(APRD) Auto increment physical read
context->port,/* 端口(port) */
aiadr, /* 从站自增地址 */
ECT_REG_EEPDAT,// EEPROM Data:EEPROM数据=0x0508
sizeof(edat64),/* 64bit EEPROM数据 */
&edat64, /* 8 Bytes:8个字节 */
EC_TIMEOUTRET);/* 发送帧(tx frame)返回到接收(rx)的超时时间[单位:us(微秒)]=2000 */
}
while ((wkc/* 工作计数器 */ <= 0)
&& (cnt++ /* 试行次数:最大三回 */
< EC_DEFAULTRETRIES/* 默认重试次数,如果 WKC <= 0 */));
}
else
{
cnt = 0;/* 试行次数:最大三回 */
do
{
wkc = /* 工作计数器 */
ecx_APRD(// 自增式物理读(APRD) Auto increment physical read
context->port,/* 端口(port) */
aiadr, /* 从站自增地址 */
ECT_REG_EEPDAT,// EEPROM Data:EEPROM数据=0x0508
sizeof(edat32),/* 32bit EEPROM数据 */
&edat32,/* 32bit EEPROM数据 */
EC_TIMEOUTRET);/* 发送帧(tx frame)返回到接收(rx)的超时时间[单位:us(微秒)]=2000 */
}
while ((wkc/* 工作计数器 */ <= 0)
&& (cnt++/* 试行次数:最大三回 */
< EC_DEFAULTRETRIES/* 默认重试次数,如果 WKC <= 0 */));
edat64/* 64bit EEPROM数据 */
=(uint64)edat32;/* 32bit EEPROM数据 */
}
}
}
}
}
while ((nackcnt > 0) && (nackcnt < 3));/* EEprom 状态机错误应答试行次数:最大三回 */
}
return edat64;/* 64bit EEPROM数据 */
}

