Neues Slave-Interface, CRC-Prüfung und mehrfaches Scannen nun ungefährlich.
This commit is contained in:
parent
4d65b22b0f
commit
b49d9be301
|
|
@ -8,64 +8,76 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define EC_PROC_DATA(SLAVE) ((unsigned char *) ((SLAVE)->process_data))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_READ_EL10XX(SLAVE, CHANNEL) \
|
||||
((EC_PROC_DATA(SLAVE)[0] >> (CHANNEL)) & 0x01)
|
||||
// Bitwise read/write macros
|
||||
|
||||
/*****************************************************************************/
|
||||
#define EC_READ_BIT(PD, CH) (*((uint8_t *) (PD)) >> (CH)) & 0x01)
|
||||
|
||||
#define EC_WRITE_EL200X(SLAVE, CHANNEL, VALUE) \
|
||||
#define EC_WRITE_BIT(PD, CH, VAL) \
|
||||
do { \
|
||||
if (VALUE) EC_PROC_DATA(SLAVE)[0] |= (1 << (CHANNEL)); \
|
||||
else EC_PROC_DATA(SLAVE)[0] &= ~(1 << (CHANNEL)); \
|
||||
if (VAL) *((uint8_t *) (PD)) |= (1 << (CH)); \
|
||||
else *((uint8_t *) (PD)) &= ~(1 << (CH)); \
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_READ_EL310X(SLAVE, CHANNEL) \
|
||||
((signed short int) ((EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 2] << 8) | \
|
||||
EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 1]))
|
||||
// Read macros
|
||||
|
||||
#define EC_READ_EL316X(SLAVE, CHANNEL) \
|
||||
((unsigned short int) ((EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 2] << 8) | \
|
||||
EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 1]))
|
||||
#define EC_READ_U8(PD) \
|
||||
(*((uint8_t *) (PD)))
|
||||
|
||||
#define EC_READ_S8(PD) \
|
||||
((int8_t) *((uint8_t *) (PD)))
|
||||
|
||||
#define EC_READ_U16(PD) \
|
||||
((uint16_t) (*((uint8_t *) (PD) + 0) << 0 | \
|
||||
*((uint8_t *) (PD) + 1) << 8))
|
||||
|
||||
#define EC_READ_S16(PD) \
|
||||
((int16_t) (*((uint8_t *) (PD) + 0) << 0 | \
|
||||
*((uint8_t *) (PD) + 1) << 8))
|
||||
|
||||
#define EC_READ_U32(PD) \
|
||||
((uint32_t) (*((uint8_t *) (PD) + 0) << 0 | \
|
||||
*((uint8_t *) (PD) + 1) << 8 | \
|
||||
*((uint8_t *) (PD) + 2) << 16 | \
|
||||
*((uint8_t *) (PD) + 3) << 24))
|
||||
|
||||
#define EC_READ_S32(PD) \
|
||||
((int32_t) (*((uint8_t *) (PD) + 0) << 0 | \
|
||||
*((uint8_t *) (PD) + 1) << 8 | \
|
||||
*((uint8_t *) (PD) + 2) << 16 | \
|
||||
*((uint8_t *) (PD) + 3) << 24))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_WRITE_EL410X(SLAVE, CHANNEL, VALUE) \
|
||||
// Write macros
|
||||
|
||||
#define EC_WRITE_U8(PD, VAL) \
|
||||
do { \
|
||||
EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 1] = ((VALUE) & 0xFF00) >> 8; \
|
||||
EC_PROC_DATA(SLAVE)[(CHANNEL) * 3 + 2] = (VALUE) & 0xFF; \
|
||||
*((uint8_t *)(PD)) = ((uint8_t) (VAL)); \
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************/
|
||||
#define EC_WRITE_S8(PD, VAL) EC_WRITE_U8(PD, VAL)
|
||||
|
||||
#define EC_CONF_EL5001_BAUD (0x4067)
|
||||
#define EC_WRITE_U16(PD, VAL) \
|
||||
do { \
|
||||
*((uint8_t *) (PD) + 0) = ((uint16_t) (VAL) >> 0) & 0xFF; \
|
||||
*((uint8_t *) (PD) + 1) = ((uint16_t) (VAL) >> 8) & 0xFF; \
|
||||
} while (0)
|
||||
|
||||
#define EC_READ_EL5001_STATE(SLAVE) \
|
||||
((unsigned char) EC_PROC_DATA(SLAVE)[0])
|
||||
#define EC_WRITE_S16(PD, VAL) EC_WRITE_U16(PD, VAL)
|
||||
|
||||
#define EC_READ_EL5001_VALUE(SLAVE) \
|
||||
((unsigned int) (EC_PROC_DATA(SLAVE)[1] | \
|
||||
(EC_PROC_DATA(SLAVE)[2] << 8) | \
|
||||
(EC_PROC_DATA(SLAVE)[3] << 16) | \
|
||||
(EC_PROC_DATA(SLAVE)[4] << 24)))
|
||||
#define EC_WRITE_U32(PD, VAL) \
|
||||
do { \
|
||||
*((uint8_t *) (PD) + 0) = ((uint32_t) (VAL) >> 0) & 0xFF; \
|
||||
*((uint8_t *) (PD) + 1) = ((uint32_t) (VAL) >> 8) & 0xFF; \
|
||||
*((uint8_t *) (PD) + 2) = ((uint32_t) (VAL) >> 16) & 0xFF; \
|
||||
*((uint8_t *) (PD) + 3) = ((uint32_t) (VAL) >> 24) & 0xFF; \
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EC_READ_EL5101_STATE(SLAVE) \
|
||||
((unsigned char) EC_PROC_DATA(SLAVE)[0])
|
||||
|
||||
#define EC_READ_EL5101_VALUE(SLAVE) \
|
||||
((unsigned int) (EC_PROC_DATA(SLAVE)[1] | \
|
||||
(EC_PROC_DATA(SLAVE)[2] << 8)))
|
||||
|
||||
#define EC_READ_EL5101_LATCH(SLAVE) \
|
||||
((unsigned int) (EC_PROC_DATA(SLAVE)[3] | \
|
||||
(EC_PROC_DATA(SLAVE)[4] << 8)))
|
||||
#define EC_WRITE_S32(PD, VAL) EC_WRITE_U32(PD, VAL)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -71,14 +71,7 @@ void ec_master_reset(ec_master_t *master
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
if (master->slaves) {
|
||||
for (i = 0; i < master->slave_count; i++) {
|
||||
ec_slave_clear(master->slaves + i);
|
||||
}
|
||||
kfree(master->slaves);
|
||||
master->slaves = NULL;
|
||||
}
|
||||
master->slave_count = 0;
|
||||
ec_master_clear_slaves(master);
|
||||
|
||||
for (i = 0; i < master->domain_count; i++) {
|
||||
ec_domain_clear(master->domains[i]);
|
||||
|
|
@ -95,6 +88,26 @@ void ec_master_reset(ec_master_t *master
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Entfernt alle Slaves.
|
||||
*/
|
||||
|
||||
void ec_master_clear_slaves(ec_master_t *master /**< EtherCAT-Master */)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (master->slaves) {
|
||||
for (i = 0; i < master->slave_count; i++) {
|
||||
ec_slave_clear(master->slaves + i);
|
||||
}
|
||||
kfree(master->slaves);
|
||||
master->slaves = NULL;
|
||||
}
|
||||
master->slave_count = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Öffnet das EtherCAT-Geraet des Masters.
|
||||
|
||||
|
|
@ -152,10 +165,9 @@ int ec_scan_for_slaves(ec_master_t *master /**< EtherCAT-Master */)
|
|||
unsigned int i;
|
||||
unsigned char data[2];
|
||||
|
||||
if (master->slaves || master->slave_count) {
|
||||
printk(KERN_ERR "EtherCAT: Slave scan already done!\n");
|
||||
return -1;
|
||||
}
|
||||
if (master->slaves || master->slave_count)
|
||||
printk(KERN_WARNING "EtherCAT: Slave scan already done!\n");
|
||||
ec_master_clear_slaves(master);
|
||||
|
||||
// Determine number of slaves on bus
|
||||
|
||||
|
|
@ -434,6 +446,8 @@ ec_domain_t *EtherCAT_rt_master_register_domain(ec_master_t *master,
|
|||
return domain;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Konfiguriert alle Slaves und setzt den Operational-Zustand.
|
||||
|
||||
|
|
@ -486,6 +500,9 @@ int EtherCAT_rt_master_activate(ec_master_t *master /**< EtherCAT-Master */)
|
|||
|
||||
type = slave->type;
|
||||
|
||||
// Check and reset CRC fault counters
|
||||
ec_slave_check_crc(slave);
|
||||
|
||||
// Resetting FMMU's
|
||||
if (slave->base_fmmu_count) {
|
||||
memset(data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
|
||||
|
|
@ -581,6 +598,9 @@ int EtherCAT_rt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */)
|
|||
{
|
||||
slave = master->slaves + i;
|
||||
|
||||
// CRC-Zählerstände ausgeben
|
||||
ec_slave_check_crc(slave);
|
||||
|
||||
if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT) != 0))
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ struct ec_master
|
|||
void ec_master_init(ec_master_t *);
|
||||
void ec_master_clear(ec_master_t *);
|
||||
void ec_master_reset(ec_master_t *);
|
||||
void ec_master_clear_slaves(ec_master_t *);
|
||||
|
||||
// Registration of devices
|
||||
int ec_master_open(ec_master_t *);
|
||||
|
|
|
|||
|
|
@ -432,6 +432,61 @@ void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Gibt die Zählerstände der CRC-Fault-Counter aus und setzt diese zurück.
|
||||
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */)
|
||||
{
|
||||
ec_frame_t frame;
|
||||
uint8_t data[4];
|
||||
uint16_t crc[2];
|
||||
|
||||
ec_frame_init_nprd(&frame, slave->master, slave->station_address, 0x0300,
|
||||
4);
|
||||
|
||||
if (unlikely(ec_frame_send_receive(&frame))) {
|
||||
printk(KERN_WARNING "EtherCAT: Reading CRC fault counters failed"
|
||||
" on slave %i - Could not send command!\n",
|
||||
slave->ring_position);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlikely(frame.working_counter != 1)) {
|
||||
printk(KERN_WARNING "EtherCAT: Reading CRC fault counters -"
|
||||
" Slave %i did not respond!\n", slave->ring_position);
|
||||
return -1;
|
||||
}
|
||||
|
||||
crc[0] = frame.data[0] | (frame.data[1] << 8);
|
||||
crc[1] = frame.data[2] | (frame.data[3] << 8);
|
||||
|
||||
// No CRC faults.
|
||||
if (!crc[0] && !crc[1]) return 0;
|
||||
|
||||
printk(KERN_INFO "EtherCAT: CRC faults on slave %i. A: %i, B: %i\n",
|
||||
slave->ring_position, crc[0], crc[1]);
|
||||
|
||||
// Reset CRC counters
|
||||
memset(data, 0x00, 4);
|
||||
ec_frame_init_npwr(&frame, slave->master, slave->station_address, 0x0300,
|
||||
4, data);
|
||||
|
||||
if (unlikely(ec_frame_send_receive(&frame))) return -1;
|
||||
|
||||
if (unlikely(frame.working_counter != 1)) {
|
||||
printk(KERN_ERR "EtherCAT: Resetting CRC fault counters - Slave"
|
||||
" %i did not respond!\n", slave->ring_position);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:4 ***
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ int ec_slave_set_fmmu(ec_slave_t *, const ec_domain_t *, const ec_sync_t *);
|
|||
|
||||
// Misc
|
||||
void ec_slave_print(const ec_slave_t *);
|
||||
int ec_slave_check_crc(ec_slave_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue