diff --git a/include/libethercat/slave.h b/include/libethercat/slave.h index 3d8749c2..94c60972 100644 --- a/include/libethercat/slave.h +++ b/include/libethercat/slave.h @@ -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 diff --git a/src/coe.c b/src/coe.c index 626a9908..a85eed77 100644 --- a/src/coe.c +++ b/src/coe.c @@ -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 @@ -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; @@ -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; } } } diff --git a/src/ec.c b/src/ec.c index 4161aa68..21594043 100644 --- a/src/ec.c +++ b/src/ec.c @@ -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 @@ -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; @@ -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 @@ -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; diff --git a/src/eeprom.c b/src/eeprom.c index ec2185fb..69d6ab9b 100644 --- a/src/eeprom.c +++ b/src/eeprom.c @@ -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, diff --git a/src/slave.c b/src/slave.c index 6a0eda9e..e0bc833b 100644 --- a/src/slave.c +++ b/src/slave.c @@ -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) && @@ -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); @@ -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);