Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 44 additions & 17 deletions include/libethercat/slave.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,50 @@ typedef osal_uint16_t ec_state_transition_t;

//! slave sync manager settings
typedef struct PACKED ec_slave_sm {
osal_uint16_t adr; //!< sync manager address
/*!<
* This field specifies the physical address
* where the sync manager starts.
*/

osal_uint16_t len; //!< sync manager length
/*!>
* This field specifies the length of the sync
* manager
*/

osal_uint32_t flags; //!< sync manager flags
/*!<
* Sync manager flags according to EtherCAT
* specifications
*/
osal_uint16_t adr; //!< sync manager address
/*!<
* This field specifies the physical address
* where the sync manager starts.
*/

osal_uint16_t len; //!< sync manager length
/*!<
* This field specifies the length of the sync
* manager
*/
osal_uint8_t control_register; //!< control register
/*!<
* Defines Mode of Operation
*/
osal_uint8_t status_regsiter; //!< status register
/*!<
* don’t care
*/
osal_uint8_t enable_sm; //!< enable sync manager
/*!<
* Bit 0: enable
* Bit 1: fixed content
* Bit 2: virtual SyncManager
* Bit 3: opOnly
* Bit 7:4: reserved
*/
osal_uint8_t sm_type; //!< sync manager type
/*!<
* 0x00 = not used or unknown
* 0x01 = used for mailbox out
* 0x02 = used for mailbox in
* 0x03 = used for process data outputs
* 0x04 = used for process data inputs
* 0x05 = used for dynamic process data outputs
* 0x06 = used for dynamic process data inputs
*/


// osal_uint32_t flags; //!< sync manager flags
// /*!<
// * Sync manager flags according to EtherCAT
// * specifications
// */
} PACKED ec_slave_sm_t;

//! slave fielbus memory management unit (fmmu) settings
Expand Down
51 changes: 48 additions & 3 deletions src/coe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1129,14 +1129,31 @@ int ec_coe_generate_mapping(ec_t *pec, osal_uint16_t slave) {
start_adr = slv->sm[1].adr + slv->sm[1].len;
}

for (osal_uint32_t sm_idx = 2u; sm_idx <= 3u; ++sm_idx) {
for (osal_uint32_t sm_idx = 2u; sm_idx < LEC_MAX_SLAVE_SM; ++sm_idx) {
if (slv->sm[sm_idx].adr == 0) {
// We break the loop when we found a zero address because this means end of the list.
break;
}
osal_uint32_t bit_len = 0u;
osal_uint32_t idx = 0x1c10u + sm_idx;
osal_uint8_t entry_cnt = 0u;
osal_uint8_t entry_cnt_2 = 0u;
osal_size_t entry_cnt_size = sizeof(entry_cnt);
osal_uint8_t sm_type = 0u;
osal_uint32_t abort_code = 0u;

// read sm type
buf = (osal_uint8_t *)&sm_type;
ret = ec_coe_sdo_read(pec, slave, 0x1C00, sm_idx, 0, buf, &entry_cnt_size, &abort_code);
if (ret != 0 || abort_code != 0) {
ec_log(5, "COE_MAPPING", "slave %2d: sm%u reading "
"sm type failed, error code 0x%X/0x%X\n", slave, sm_idx, ret,abort_code);
sm_type = 0;
} else {
ec_log(100, "COE_MAPPING", "slave %2d: sm%u reading "
"sm type 0x%X\n", slave, sm_idx, sm_type);
}

// read count of mapping entries, stored in subindex 0
// mapped entreis are stored at 0x1c12 and 0x1c13 and should usually be
// written in state preop with an init command
Expand All @@ -1146,7 +1163,10 @@ int ec_coe_generate_mapping(ec_t *pec, osal_uint16_t slave) {
if (abort_code == 0x06020000) { // object does not exist in the object dictionary
if (slv->sm_ch > sm_idx) {
slv->sm[sm_idx].len = 0u;
slv->sm[sm_idx].flags = 0u;
slv->sm[sm_idx].control_register = 0u;
slv->sm[sm_idx].status_regsiter = 0u;
slv->sm[sm_idx].enable_sm = 0u;
slv->sm[sm_idx].sm_type = 0u;
}

ret = 0u;
Expand Down Expand Up @@ -1240,7 +1260,32 @@ int ec_coe_generate_mapping(ec_t *pec, osal_uint16_t slave) {
start_adr += slv->sm[sm_idx].len * 3u;
}

slv->sm[sm_idx].flags = (sm_idx == 2u) ? 0x10064u : 0x10020u;
switch (sm_type) {
case 0x00:
slv->sm[sm_idx].control_register = 0u;
break;
case 0x01:
slv->sm[sm_idx].control_register = 0x26u;
break;
case 0x02:
slv->sm[sm_idx].control_register = 0x22u;
break;
case 0x03:
slv->sm[sm_idx].control_register = 0x64u; // TODO: Is this right?
break;
case 0x04:
slv->sm[sm_idx].control_register = 0x20;
break;
case 0x05:
slv->sm[sm_idx].control_register = 0u; // TODO: What to write here?
break;
case 0x06:
slv->sm[sm_idx].control_register = 0u; // TODO: What to write here?
break;
}

slv->sm[sm_idx].enable_sm = 1u;
slv->sm[sm_idx].sm_type = sm_type;
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ static void ec_create_logical_mapping_overlapping(ec_t *pec, osal_uint32_t group
osal_size_t slv_pdout_len = 0u;

for (k = start_sm; k < slv->sm_ch; ++k) {
if ((slv->sm[k].flags & 0x00000004u) != 0u) {
if ((slv->sm[k].control_register & 0x04u) != 0u) {
slv_pdout_len += slv->sm[k].len; // outputs
} else {
slv_pdin_len += slv->sm[k].len; // inputs
Expand Down Expand Up @@ -325,7 +325,7 @@ static void ec_create_logical_mapping_overlapping(ec_t *pec, osal_uint32_t group
continue; // empty
}

if ((slv->sm[k].flags & 0x00000004u) != 0u) {
if ((slv->sm[k].control_register & 0x04u) != 0u) {
if (fmmu_next < slv->fmmu_ch) {
slv->fmmu[fmmu_next].log = log_base_out;
slv->fmmu[fmmu_next].log_len = slv->sm[k].len;
Expand Down Expand Up @@ -447,7 +447,7 @@ static void ec_create_logical_mapping(ec_t *pec, osal_uint32_t group) {
}

for (k = start_sm; k < slv->sm_ch; ++k) {
if ((slv->sm[k].flags & 0x00000004u) != 0u) {
if ((slv->sm[k].control_register & 0x04u) != 0u) {
pd->pdout_len += slv->sm[k].len; // outputs
} else {
pd->pdin_len += slv->sm[k].len; // inputs
Expand Down Expand Up @@ -487,7 +487,7 @@ static void ec_create_logical_mapping(ec_t *pec, osal_uint32_t group) {
continue; // empty
}

if ((slv->sm[k].flags & 0x00000004u) != 0u) {
if ((slv->sm[k].control_register & 0x04u) != 0u) {
if (fmmu_next < slv->fmmu_ch) {
slv->fmmu[fmmu_next].log = log_base_out;
slv->fmmu[fmmu_next].log_len = slv->sm[k].len;
Expand Down
9 changes: 5 additions & 4 deletions src/eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,12 +640,13 @@ void ec_eeprom_dump(ec_t *pec, osal_uint16_t slave) {
if (slv->sm[j].adr == 0u) {
slv->sm[j].adr = tmp_sms.adr;
slv->sm[j].len = tmp_sms.len;
slv->sm[j].flags = (tmp_sms.activate << 16) | tmp_sms.ctrl_reg;
slv->sm[j].enable_sm = tmp_sms.activate;
slv->sm[j].control_register = tmp_sms.ctrl_reg;

do_eeprom_log(10, "EEPROM_SM",
" sm%d adr 0x%X, len %d, flags "
"0x%X\n", j, slv->sm[j].adr, slv->sm[j].len,
slv->sm[j].flags);
" sm%d adr 0x%X, len %d, enable_sm "
"0x%X, control_register 0x%X\n", j, slv->sm[j].adr, slv->sm[j].len,
slv->sm[j].enable_sm, slv->sm[j].control_register);
} else {
do_eeprom_log(10, "EEPROM_SM", " sm%d adr "
"0x%X, len %d, flags 0x%X\n", j,
Expand Down
18 changes: 12 additions & 6 deletions src/slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,8 @@ int ec_slave_state_transition(ec_t *pec, osal_uint16_t slave, ec_state_t state)
slv->sm[MAILBOX_READ].adr = slv->eeprom.mbx_send_offset;
slv->sm[MAILBOX_READ].len = slv->eeprom.mbx_send_size;
}
slv->sm[MAILBOX_READ].flags = 0x00010022;
slv->sm[MAILBOX_READ].enable_sm = 0x01;
slv->sm[MAILBOX_READ].control_register = 0x22;

// write mailbox
if ((transition == INIT_2_BOOT) &&
Expand All @@ -969,15 +970,18 @@ int ec_slave_state_transition(ec_t *pec, osal_uint16_t slave, ec_state_t state)
slv->sm[MAILBOX_WRITE].len = slv->eeprom.mbx_receive_size;
}

slv->sm[MAILBOX_WRITE].flags = 0x00010026;
slv->sm[MAILBOX_WRITE].enable_sm = 0x01;
slv->sm[MAILBOX_WRITE].control_register = 0x26;

ec_mbx_init(pec, slave);

for (osal_uint32_t sm_idx = 0u; sm_idx < 2u; ++sm_idx) {
ec_log(10, get_transition_string(transition), "slave %2d: "
"sm%u, adr 0x%04X, len %3d, flags 0x%08X\n",
"sm%u, adr 0x%04X, len %3d, enable_sm "
"0x%X, control_register 0x%X\n",
slave, sm_idx, slv->sm[sm_idx].adr,
slv->sm[sm_idx].len, slv->sm[sm_idx].flags);
slv->sm[sm_idx].len, slv->sm[sm_idx].enable_sm,
slv->sm[sm_idx].control_register);

(void)ec_fpwr(pec, slv->fixed_address, 0x800u + (sm_idx * 8u),
&slv->sm[sm_idx], sizeof(ec_slave_sm_t), &wkc);
Expand Down Expand Up @@ -1073,9 +1077,11 @@ int ec_slave_state_transition(ec_t *pec, osal_uint16_t slave, ec_state_t state)
}

ec_log(10, get_transition_string(transition), "slave %2d: "
"sm%d, adr 0x%04X, len %3d, flags 0x%08X\n",
"sm%d, adr 0x%04X, len %3d, enable_sm "
"0x%X, control_register 0x%X\n",
slave, sm_idx, slv->sm[sm_idx].adr,
slv->sm[sm_idx].len, slv->sm[sm_idx].flags);
slv->sm[sm_idx].len, slv->sm[sm_idx].enable_sm,
slv->sm[sm_idx].control_register);

(void)ec_fpwr(pec, slv->fixed_address, 0x800u + (sm_idx * 8u),
&slv->sm[sm_idx], sizeof(ec_slave_sm_t), &wkc);
Expand Down