CANopen over EtherCAT.
This commit is contained in:
parent
842f163d28
commit
fb4b07cf52
|
|
@ -48,6 +48,11 @@ int EtherCAT_rt_domain_xio(ec_master_t *master, unsigned int domain,
|
|||
|
||||
void EtherCAT_rt_debug_level(ec_master_t *master, int level);
|
||||
|
||||
int EtherCAT_rt_canopen_sdo_write(ec_master_t *master, ec_slave_t *slave,
|
||||
unsigned int sdo_index,
|
||||
unsigned char sdo_subindex,
|
||||
unsigned int value, unsigned int size);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ ifneq ($(KERNELRELEASE),)
|
|||
|
||||
obj-m := ec_master.o
|
||||
|
||||
ec_master-objs := module.o master.o device.o slave.o command.o types.o domain.o
|
||||
ec_master-objs := module.o master.o device.o slave.o command.o types.o \
|
||||
domain.o canopen.o
|
||||
|
||||
REV = `svnversion $(src)`
|
||||
DATE = `date`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* c a n o p e n . c
|
||||
*
|
||||
* CANopen over EtherCAT
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "master.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
// Prototypen
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int EtherCAT_rt_canopen_sdo_write(ec_master_t *master, ec_slave_t *slave,
|
||||
unsigned int sdo_index,
|
||||
unsigned char sdo_subindex,
|
||||
unsigned int value, unsigned int size)
|
||||
{
|
||||
unsigned char data[0xF6];
|
||||
ec_command_t cmd;
|
||||
unsigned int tries_left, i;
|
||||
|
||||
for (i = 0; i < 0xF6; i++) data[i] = 0x00;
|
||||
|
||||
if (size == 0 || size > 4) {
|
||||
printk(KERN_ERR "EtherCAT: Illegal SDO data size: %i!\n", size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
data[0] = 0x0A; // Length of the Mailbox service data
|
||||
data[1] = 0x00;
|
||||
data[2] = slave->station_address & 0xFF; // Station address
|
||||
data[3] = (slave->station_address >> 8) & 0xFF;
|
||||
data[4] = 0x00; // Channel & priority
|
||||
data[5] = 0x03; // CANopen over EtherCAT
|
||||
data[6] = 0x00; // Number(7-0)
|
||||
data[7] = 0x2 << 4; // Number(8) & Service = SDO Request (0x02)
|
||||
data[8] = 0x01 // Size specified
|
||||
| (0x1 << 1) // Transfer type = Expedited
|
||||
| ((4 - size) << 2) // Data Set Size
|
||||
| (0x1 << 5); // Command specifier = Initiate download request (0x01)
|
||||
data[9] = sdo_index & 0xFF;
|
||||
data[10] = (sdo_index >> 8) & 0xFF;
|
||||
data[11] = sdo_subindex;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
data[12 + i] = value & 0xFF;
|
||||
value >>= 8;
|
||||
}
|
||||
|
||||
ec_command_write(&cmd, slave->station_address, 0x1800, 0xF6, data);
|
||||
|
||||
if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
|
||||
return -1;
|
||||
|
||||
if (unlikely(cmd.working_counter != 1)) {
|
||||
printk(KERN_ERR "EtherCAT: Mailbox send - Slave %i did not respond!\n",
|
||||
slave->ring_position * (-1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read "written bit" of Sync-Manager
|
||||
|
||||
tries_left = 10;
|
||||
while (tries_left)
|
||||
{
|
||||
ec_command_read(&cmd, slave->station_address, 0x808, 8);
|
||||
|
||||
if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
|
||||
return -1;
|
||||
|
||||
if (unlikely(cmd.working_counter != 1)) {
|
||||
printk(KERN_ERR "EtherCAT: Mailbox check - Slave %i did not"
|
||||
" respond!\n", slave->ring_position * (-1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmd.data[5] & 8) { // Written bit is high
|
||||
break;
|
||||
}
|
||||
|
||||
udelay(1000);
|
||||
tries_left--;
|
||||
}
|
||||
|
||||
if (!tries_left) {
|
||||
printk(KERN_ERR "EtherCAT: Mailbox check - Slave %i timed out.\n",
|
||||
slave->ring_position * (-1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ec_command_read(&cmd, slave->station_address, 0x18F6, 0xF6);
|
||||
|
||||
if (unlikely(ec_simple_send_receive(master, &cmd) < 0))
|
||||
return -1;
|
||||
|
||||
if (unlikely(cmd.working_counter != 1)) {
|
||||
printk(KERN_ERR "EtherCAT: Mailbox receive - Slave %i did not"
|
||||
" respond!\n", slave->ring_position * (-1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmd.data[5] != 0x03 // COE
|
||||
|| (cmd.data[7] >> 4) != 0x03 // SDO response
|
||||
|| (cmd.data[8] >> 5) != 0x03 // Initiate download response
|
||||
|| (cmd.data[9] != (sdo_index & 0xFF)) // Index
|
||||
|| (cmd.data[10] != ((sdo_index >> 8) & 0xFF))
|
||||
|| (cmd.data[11] != sdo_subindex)) // Subindex
|
||||
{
|
||||
printk(KERN_ERR "EtherCAT: Illegal mailbox response at slave %i!\n",
|
||||
slave->ring_position * (-1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
EXPORT_SYMBOL(EtherCAT_rt_canopen_sdo_write);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Emacs-Konfiguration
|
||||
;;; Local Variables: ***
|
||||
;;; c-basic-offset:4 ***
|
||||
;;; End: ***
|
||||
*/
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* c a n o p e n . h
|
||||
*
|
||||
* CANopen over EtherCAT
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _CANOPEN_H_
|
||||
#define _CANOPEN_H_
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
|
@ -306,7 +306,8 @@ int ec_simple_receive(ec_master_t *master, ec_command_t *cmd)
|
|||
int ret;
|
||||
unsigned char command_type, command_index;
|
||||
|
||||
if (unlikely((ret = ec_device_receive(&master->device, master->rx_data)) < 0))
|
||||
if (unlikely((ret = ec_device_receive(&master->device,
|
||||
master->rx_data)) < 0))
|
||||
return -1;
|
||||
|
||||
master->rx_data_length = (unsigned int) ret;
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@ struct ec_master
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
// Private Methods
|
||||
|
||||
// Master creation and deletion
|
||||
void ec_master_init(ec_master_t *);
|
||||
void ec_master_clear(ec_master_t *);
|
||||
|
|
@ -64,6 +62,9 @@ void ec_master_close(ec_master_t *);
|
|||
// Slave management
|
||||
int ec_scan_for_slaves(ec_master_t *);
|
||||
|
||||
// Data
|
||||
int ec_simple_send_receive(ec_master_t *, ec_command_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ int *ec_masters_reserved = NULL;
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
MODULE_AUTHOR ("Wilhelm Hagemeister <hm@igh-essen.com>,"
|
||||
"Florian Pose <fp@igh-essen.com>");
|
||||
MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>");
|
||||
MODULE_DESCRIPTION ("EtherCAT master driver module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(COMPILE_INFO);
|
||||
|
|
|
|||
18
mini/mini.c
18
mini/mini.c
|
|
@ -18,14 +18,15 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
ec_master_t *master = NULL;
|
||||
ec_slave_t *s_in, *s_out;
|
||||
ec_slave_t *s_in, *s_out, *s_ssi;
|
||||
|
||||
struct timer_list timer;
|
||||
|
||||
ec_slave_init_t slaves[] = {
|
||||
// Zeiger, Index, Herstellername, Produktname, Domäne
|
||||
{ &s_out, 9, "Beckhoff", "EL2004", 1 },
|
||||
{ &s_in, 1, "Beckhoff", "EL3102", 1 }
|
||||
{ &s_out, 2, "Beckhoff", "EL2004", 1 },
|
||||
{ &s_in, 1, "Beckhoff", "EL3102", 1 },
|
||||
{ &s_ssi, 7, "Beckhoff", "EL5001", 1 }
|
||||
};
|
||||
|
||||
#define SLAVE_COUNT (sizeof(slaves) / sizeof(ec_slave_init_t))
|
||||
|
|
@ -68,6 +69,17 @@ int __init init_mini_module(void)
|
|||
goto out_release_master;
|
||||
}
|
||||
|
||||
printk("Configuring EtherCAT slaves.\n");
|
||||
|
||||
EtherCAT_rt_debug_level(master, 2);
|
||||
|
||||
if (EtherCAT_rt_canopen_sdo_write(master, s_ssi, 0x4067, 2, 2)) {
|
||||
printk(KERN_ERR "EtherCAT: Could not set SSI baud rate!\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
EtherCAT_rt_debug_level(master, 0);
|
||||
|
||||
printk("Starting cyclic sample thread.\n");
|
||||
|
||||
init_timer(&timer);
|
||||
|
|
|
|||
Loading…
Reference in New Issue