Skip to content
Snippets Groups Projects
Commit 119e3905 authored by Florian Pose's avatar Florian Pose
Browse files

EoE in Free-Run mode; Finished slave configuration state machine.

parent 3e484195
No related branches found
No related tags found
No related merge requests found
......@@ -70,17 +70,15 @@ struct net_device_stats *ec_eoedev_stats(struct net_device *);
/**
EoE constructor.
Initializes the EoE object, creates a net_device and registeres it.
Initializes the EoE handler, creates a net_device and registeres it.
*/
int ec_eoe_init(ec_eoe_t *eoe, /**< EoE object */
ec_slave_t *slave /**< assigned slave */
)
int ec_eoe_init(ec_eoe_t *eoe /**< EoE handler */)
{
ec_eoe_t **priv;
int result, i;
eoe->slave = slave;
eoe->slave = NULL;
eoe->state = ec_eoe_state_rx_start;
eoe->opened = 0;
eoe->rx_skb = NULL;
......@@ -95,7 +93,7 @@ int ec_eoe_init(ec_eoe_t *eoe, /**< EoE object */
if (!(eoe->dev =
alloc_netdev(sizeof(ec_eoe_t *), "eoe%d", ether_setup))) {
EC_ERR("Unable to allocate net_device for EoE object!\n");
EC_ERR("Unable to allocate net_device for EoE handler!\n");
goto out_return;
}
......@@ -145,7 +143,7 @@ int ec_eoe_init(ec_eoe_t *eoe, /**< EoE object */
Unregisteres the net_device and frees allocated memory.
*/
void ec_eoe_clear(ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
{
if (eoe->dev) {
unregister_netdev(eoe->dev);
......@@ -169,7 +167,7 @@ void ec_eoe_clear(ec_eoe_t *eoe /**< EoE object */)
Empties the transmit queue.
*/
void ec_eoe_flush(ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_flush(ec_eoe_t *eoe /**< EoE handler */)
{
ec_eoe_frame_t *frame, *next;
......@@ -191,7 +189,7 @@ void ec_eoe_flush(ec_eoe_t *eoe /**< EoE object */)
Sends a frame or the next fragment.
*/
int ec_eoe_send(ec_eoe_t *eoe /**< EoE object */)
int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
{
size_t remaining_size, current_size, complete_offset;
unsigned int last_fragment;
......@@ -262,7 +260,7 @@ int ec_eoe_send(ec_eoe_t *eoe /**< EoE object */)
Runs the EoE state machine.
*/
void ec_eoe_run(ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_run(ec_eoe_t *eoe /**< EoE handler */)
{
if (!eoe->opened) return;
......@@ -277,22 +275,25 @@ void ec_eoe_run(ec_eoe_t *eoe /**< EoE object */)
\return 1 if the device is "up", 0 if it is "down"
*/
unsigned int ec_eoe_active(const ec_eoe_t *eoe /**< EoE object */)
unsigned int ec_eoe_active(const ec_eoe_t *eoe /**< EoE handler */)
{
return eoe->opened;
return eoe->slave && eoe->opened;
}
/*****************************************************************************/
/**
Prints EoE object information.
Prints EoE handler information.
*/
void ec_eoe_print(const ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_print(const ec_eoe_t *eoe /**< EoE handler */)
{
EC_INFO(" EoE slave %i\n", eoe->slave->ring_position);
EC_INFO(" Assigned device: %s (%s)\n", eoe->dev->name,
eoe->opened ? "opened" : "closed");
EC_INFO(" EoE handler %s\n", eoe->dev->name);
EC_INFO(" State: %s\n", eoe->opened ? "opened" : "closed");
if (eoe->slave)
EC_INFO(" Coupled to slave %i.\n", eoe->slave->ring_position);
else
EC_INFO(" Not coupled.\n");
}
/******************************************************************************
......@@ -305,7 +306,7 @@ void ec_eoe_print(const ec_eoe_t *eoe /**< EoE object */)
slave's mailbox for a new command.
*/
void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
{
ec_slave_mbox_prepare_check(eoe->slave);
ec_master_queue_command(eoe->slave->master, &eoe->slave->mbox_command);
......@@ -320,7 +321,7 @@ void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE object */)
command, if new data is available.
*/
void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
{
if (eoe->slave->mbox_command.state != EC_CMD_RECEIVED) {
eoe->stats.rx_errors++;
......@@ -346,7 +347,7 @@ void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE object */)
EoE command.
*/
void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */)
{
size_t rec_size, data_size;
uint8_t *data, frame_type, last_fragment, time_appended;
......@@ -486,7 +487,7 @@ void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE object */)
sequence is started instead.
*/
void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE handler */)
{
#if EOE_DEBUG_LEVEL > 0
unsigned int wakeup;
......@@ -546,7 +547,7 @@ void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE object */)
fragment, if necessary.
*/
void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE object */)
void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
{
if (eoe->slave->mbox_command.state != EC_CMD_RECEIVED) {
eoe->stats.tx_errors++;
......@@ -595,7 +596,12 @@ int ec_eoedev_open(struct net_device *dev /**< EoE net_device */)
eoe->opened = 1;
netif_start_queue(dev);
eoe->tx_queue_active = 1;
EC_INFO("%s (slave %i) opened.\n", dev->name, eoe->slave->ring_position);
EC_INFO("%s opened.\n", dev->name);
if (!eoe->slave)
EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
else {
eoe->slave->requested_state = EC_SLAVE_STATE_OP;
}
return 0;
}
......@@ -612,7 +618,12 @@ int ec_eoedev_stop(struct net_device *dev /**< EoE net_device */)
eoe->tx_queue_active = 0;
eoe->opened = 0;
ec_eoe_flush(eoe);
EC_INFO("%s (slave %i) stopped.\n", dev->name, eoe->slave->ring_position);
EC_INFO("%s stopped.\n", dev->name);
if (!eoe->slave)
EC_WARN("device %s is not coupled to any EoE slave!\n", dev->name);
else {
eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
}
return 0;
}
......
......@@ -64,7 +64,7 @@ ec_eoe_frame_t;
typedef struct ec_eoe ec_eoe_t;
/**
Ethernet-over-EtherCAT (EoE) Object.
Ethernet-over-EtherCAT (EoE) handler.
The master creates one of these objects for each slave that supports the
EoE protocol.
*/
......@@ -93,7 +93,7 @@ struct ec_eoe
/*****************************************************************************/
int ec_eoe_init(ec_eoe_t *, ec_slave_t *);
int ec_eoe_init(ec_eoe_t *);
void ec_eoe_clear(ec_eoe_t *);
void ec_eoe_run(ec_eoe_t *);
unsigned int ec_eoe_active(const ec_eoe_t *);
......
This diff is collapsed.
......@@ -76,6 +76,9 @@ struct ec_fsm
void (*sii_state)(ec_fsm_t *); /**< SII state function */
uint16_t sii_offset; /**< input: offset in SII */
uint32_t sii_result; /**< output: read SII value (32bit) */
void (*change_state)(ec_fsm_t *); /**< slave state change state function */
uint8_t change_new; /**< input: new state */
};
/*****************************************************************************/
......@@ -84,7 +87,6 @@ int ec_fsm_init(ec_fsm_t *, ec_master_t *);
void ec_fsm_clear(ec_fsm_t *);
void ec_fsm_reset(ec_fsm_t *);
void ec_fsm_execute(ec_fsm_t *);
int ec_fsm_idle(const ec_fsm_t *);
/*****************************************************************************/
......
......@@ -115,6 +115,7 @@
extern void ec_print_data(const uint8_t *, size_t);
extern void ec_print_data_diff(const uint8_t *, const uint8_t *, size_t);
extern void ec_print_states(uint8_t);
/*****************************************************************************/
......
......@@ -56,7 +56,7 @@
/*****************************************************************************/
void ec_master_freerun(void *);
void ec_master_run_eoe(unsigned long);
void ec_master_eoe_run(unsigned long);
ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
void ec_master_process_watch_command(ec_master_t *);
......@@ -94,17 +94,14 @@ static struct kobj_type ktype_ec_master = {
*/
int ec_master_init(ec_master_t *master, /**< EtherCAT master */
unsigned int index /**< master index */
unsigned int index, /**< master index */
unsigned int eoe_devices /**< number of EoE devices */
)
{
EC_INFO("Initializing master %i.\n", index);
if (!(master->workqueue = create_singlethread_workqueue("EoE"))) {
EC_ERR("Failed to create master workqueue.\n");
goto out_return;
}
ec_eoe_t *eoe, *next_eoe;
unsigned int i;
if (ec_fsm_init(&master->fsm, master)) goto out_free_wq;
EC_INFO("Initializing master %i.\n", index);
master->index = index;
master->device = NULL;
......@@ -112,12 +109,36 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
INIT_LIST_HEAD(&master->slaves);
INIT_LIST_HEAD(&master->command_queue);
INIT_LIST_HEAD(&master->domains);
INIT_LIST_HEAD(&master->eoe_slaves);
INIT_LIST_HEAD(&master->eoe_handlers);
ec_command_init(&master->simple_command);
INIT_WORK(&master->freerun_work, ec_master_freerun, (void *) master);
init_timer(&master->eoe_timer);
master->eoe_timer.function = ec_master_run_eoe;
master->eoe_timer.function = ec_master_eoe_run;
master->eoe_timer.data = (unsigned long) master;
master->internal_lock = SPIN_LOCK_UNLOCKED;
master->eoe_running = 0;
// create workqueue
if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) {
EC_ERR("Failed to create master workqueue.\n");
goto out_return;
}
// create EoE handlers
for (i = 0; i < eoe_devices; i++) {
if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
EC_ERR("Failed to allocate EoE-Object.\n");
goto out_clear_eoe;
}
if (ec_eoe_init(eoe)) {
kfree(eoe);
goto out_clear_eoe;
}
list_add_tail(&eoe->list, &master->eoe_handlers);
}
// create state machine object
if (ec_fsm_init(&master->fsm, master)) goto out_clear_eoe;
// init kobject and add it to the hierarchy
memset(&master->kobj, 0x00, sizeof(struct kobject));
......@@ -132,7 +153,12 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
ec_master_reset(master);
return 0;
out_free_wq:
out_clear_eoe:
list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
list_del(&eoe->list);
ec_eoe_clear(eoe);
kfree(eoe);
}
destroy_workqueue(master->workqueue);
out_return:
return -1;
......@@ -149,6 +175,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
void ec_master_clear(struct kobject *kobj /**< kobject of the master */)
{
ec_master_t *master = container_of(kobj, ec_master_t, kobj);
ec_eoe_t *eoe, *next_eoe;
EC_INFO("Clearing master %i...\n", master->index);
......@@ -157,6 +184,13 @@ void ec_master_clear(struct kobject *kobj /**< kobject of the master */)
ec_command_clear(&master->simple_command);
destroy_workqueue(master->workqueue);
// clear EoE objects
list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
list_del(&eoe->list);
ec_eoe_clear(eoe);
kfree(eoe);
}
if (master->device) {
ec_device_clear(master->device);
kfree(master->device);
......@@ -177,14 +211,9 @@ void ec_master_reset(ec_master_t *master /**< EtherCAT master */)
{
ec_command_t *command, *next_c;
ec_domain_t *domain, *next_d;
ec_eoe_t *eoe, *next_eoe;
// stop EoE processing
del_timer_sync(&master->eoe_timer);
// stop free-run mode
ec_master_eoe_stop(master);
ec_master_freerun_stop(master);
ec_master_clear_slaves(master);
// empty command queue
......@@ -200,13 +229,6 @@ void ec_master_reset(ec_master_t *master /**< EtherCAT master */)
kobject_put(&domain->kobj);
}
// clear EoE objects
list_for_each_entry_safe(eoe, next_eoe, &master->eoe_slaves, list) {
list_del(&eoe->list);
ec_eoe_clear(eoe);
kfree(eoe);
}
master->command_index = 0;
master->debug_level = 0;
master->timeout = 500; // 500us
......@@ -674,6 +696,8 @@ void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */)
{
if (master->mode != EC_MASTER_MODE_FREERUN) return;
ec_master_eoe_stop(master);
EC_INFO("Stopping Free-Run mode.\n");
if (!cancel_delayed_work(&master->freerun_work)) {
......@@ -693,18 +717,21 @@ void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */)
void ec_master_freerun(void *data /**< master pointer */)
{
ec_master_t *master = (ec_master_t *) data;
unsigned long delay;
// aquire master lock
spin_lock_bh(&master->internal_lock);
ecrt_master_async_receive(master);
// execute freerun state machine
// execute master state machine
ec_fsm_execute(&master->fsm);
ecrt_master_async_send(master);
delay = HZ / 100;
if (ec_fsm_idle(&master->fsm)) delay = HZ;
queue_delayed_work(master->workqueue, &master->freerun_work, delay);
// release master lock
spin_unlock_bh(&master->internal_lock);
queue_delayed_work(master->workqueue, &master->freerun_work, HZ / 100);
}
/*****************************************************************************/
......@@ -798,32 +825,131 @@ ssize_t ec_show_master_attribute(struct kobject *kobj, /**< kobject */
/*****************************************************************************/
/**
Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves.
*/
void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */)
{
ec_eoe_t *eoe;
ec_slave_t *slave;
unsigned int coupled, found;
if (master->eoe_running) return;
// decouple all EoE handlers
list_for_each_entry(eoe, &master->eoe_handlers, list)
eoe->slave = NULL;
coupled = 0;
// couple a free EoE handler to every EoE-capable slave
list_for_each_entry(slave, &master->slaves, list) {
if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
found = 0;
list_for_each_entry(eoe, &master->eoe_handlers, list) {
if (eoe->slave) continue;
eoe->slave = slave;
found = 1;
coupled++;
EC_INFO("Coupling device %s to slave %i.\n",
eoe->dev->name, slave->ring_position);
if (eoe->opened)
slave->requested_state = EC_SLAVE_STATE_OP;
}
if (!found) {
EC_WARN("No EoE handler for slave %i!\n", slave->ring_position);
slave->requested_state = EC_SLAVE_STATE_INIT;
}
}
if (!coupled) {
EC_INFO("No EoE handlers coupled.\n");
return;
}
EC_INFO("Starting EoE processing.\n");
master->eoe_running = 1;
// start EoE processing
master->eoe_timer.expires = jiffies + 10;
add_timer(&master->eoe_timer);
return;
}
/*****************************************************************************/
/**
Stops the Ethernet-over-EtherCAT processing.
*/
void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */)
{
ec_eoe_t *eoe;
if (!master->eoe_running) return;
EC_INFO("Stopping EoE processing.\n");
del_timer_sync(&master->eoe_timer);
// decouple all EoE handlers
list_for_each_entry(eoe, &master->eoe_handlers, list) {
if (eoe->slave) {
eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
eoe->slave = NULL;
}
}
master->eoe_running = 0;
}
/*****************************************************************************/
/**
Does the Ethernet-over-EtherCAT processing.
*/
void ec_master_run_eoe(unsigned long data /**< master pointer */)
void ec_master_eoe_run(unsigned long data /**< master pointer */)
{
ec_master_t *master = (ec_master_t *) data;
ec_eoe_t *eoe;
unsigned int active = 0;
list_for_each_entry(eoe, &master->eoe_slaves, list) {
list_for_each_entry(eoe, &master->eoe_handlers, list) {
if (ec_eoe_active(eoe)) active++;
}
if (!active) goto queue_timer;
// request_cb must return 0, if the lock has been aquired!
if (active && !master->request_cb(master->cb_data))
{
ecrt_master_async_receive(master);
list_for_each_entry(eoe, &master->eoe_slaves, list) {
ec_eoe_run(eoe);
}
ecrt_master_async_send(master);
// aquire master lock...
if (master->mode == EC_MASTER_MODE_RUNNING) {
// request_cb must return 0, if the lock has been aquired!
if (master->request_cb(master->cb_data))
goto queue_timer;
}
else if (master->mode == EC_MASTER_MODE_FREERUN) {
spin_lock(&master->internal_lock);
}
else
goto queue_timer;
// actual EoE stuff
ecrt_master_async_receive(master);
list_for_each_entry(eoe, &master->eoe_handlers, list) {
ec_eoe_run(eoe);
}
ecrt_master_async_send(master);
// release lock...
if (master->mode == EC_MASTER_MODE_RUNNING) {
master->release_cb(master->cb_data);
}
else if (master->mode == EC_MASTER_MODE_FREERUN) {
spin_unlock(&master->internal_lock);
}
queue_timer:
master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY;
add_timer(&master->eoe_timer);
}
......@@ -1404,37 +1530,12 @@ void ecrt_master_callbacks(ec_master_t *master, /**< EtherCAT master */
int ecrt_master_start_eoe(ec_master_t *master /**< EtherCAT master */)
{
ec_eoe_t *eoe;
ec_slave_t *slave;
if (!master->request_cb || !master->release_cb) {
EC_ERR("EoE requires master callbacks to be set!\n");
return -1;
}
list_for_each_entry(slave, &master->slaves, list) {
// does the slave support EoE?
if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
EC_ERR("Failed to allocate EoE-Object.\n");
return -1;
}
if (ec_eoe_init(eoe, slave)) {
kfree(eoe);
return -1;
}
list_add_tail(&eoe->list, &master->eoe_slaves);
}
if (list_empty(&master->eoe_slaves)) {
EC_WARN("start_eoe: no EoE-capable slaves present.\n");
return 0;
}
// start EoE processing
master->eoe_timer.expires = jiffies + 10;
add_timer(&master->eoe_timer);
ec_master_eoe_start(master);
return 0;
}
......@@ -1482,9 +1583,9 @@ void ecrt_master_print(const ec_master_t *master, /**< EtherCAT master */
list_for_each_entry(slave, &master->slaves, list)
ec_slave_print(slave, verbosity);
}
if (!list_empty(&master->eoe_slaves)) {
if (!list_empty(&master->eoe_handlers)) {
EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n");
list_for_each_entry(eoe, &master->eoe_slaves, list) {
list_for_each_entry(eoe, &master->eoe_handlers, list) {
ec_eoe_print(eoe);
}
}
......
......@@ -116,7 +116,9 @@ struct ec_master
ec_master_mode_t mode; /**< master mode */
struct timer_list eoe_timer; /** EoE timer object */
struct list_head eoe_slaves; /**< Ethernet-over-EtherCAT slaves */
unsigned int eoe_running; /**< non-zero, if EoE processing is active. */
struct list_head eoe_handlers; /**< Ethernet-over-EtherCAT handlers */
spinlock_t internal_lock; /**< spinlock used in freerun mode */
int (*request_cb)(void *); /**< lock request callback */
void (*release_cb)(void *); /**< lock release callback */
void *cb_data; /**< data parameter of locking callbacks */
......@@ -125,7 +127,7 @@ struct ec_master
/*****************************************************************************/
// master creation and deletion
int ec_master_init(ec_master_t *, unsigned int);
int ec_master_init(ec_master_t *, unsigned int, unsigned int);
void ec_master_clear(struct kobject *);
void ec_master_reset(ec_master_t *);
......@@ -133,6 +135,10 @@ void ec_master_reset(ec_master_t *);
void ec_master_freerun_start(ec_master_t *);
void ec_master_freerun_stop(ec_master_t *);
// EoE
void ec_master_eoe_start(ec_master_t *);
void ec_master_eoe_stop(ec_master_t *);
// IO
void ec_master_receive(ec_master_t *, const uint8_t *, size_t);
void ec_master_queue_command(ec_master_t *, ec_command_t *);
......@@ -143,6 +149,9 @@ int ec_master_bus_scan(ec_master_t *);
// misc.
void ec_master_clear_slaves(ec_master_t *);
void ec_sync_config(const ec_sync_t *, uint8_t *);
void ec_eeprom_sync_config(const ec_eeprom_sync_t *, uint8_t *);
void ec_fmmu_config(const ec_fmmu_t *, uint8_t *);
void ec_master_output_stats(ec_master_t *);
/*****************************************************************************/
......
......@@ -67,19 +67,22 @@ void __exit ec_cleanup_module(void);
/*****************************************************************************/
static int ec_master_count = 1;
static int ec_eoe_devices = 0;
static struct list_head ec_masters;
/*****************************************************************************/
/** \cond */
MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION ("EtherCAT master driver module");
module_param(ec_master_count, int, S_IRUGO);
module_param(ec_eoe_devices, int, S_IRUGO);
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION("EtherCAT master driver module");
MODULE_LICENSE("GPL");
MODULE_VERSION(COMPILE_INFO);
module_param(ec_master_count, int, 1);
MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize");
MODULE_PARM_DESC(ec_eoe_devices, "number of EoE devices per master");
/** \endcond */
......@@ -114,7 +117,7 @@ int __init ec_init_module(void)
goto out_free;
}
if (ec_master_init(master, i)) // kobject_put is done inside...
if (ec_master_init(master, i, ec_eoe_devices))
goto out_free;
if (kobject_add(&master->kobj)) {
......@@ -228,6 +231,41 @@ void ec_print_data_diff(const uint8_t *d1, /**< first data */
printk("\n");
}
/*****************************************************************************/
/**
Prints slave states in clear text.
*/
void ec_print_states(const uint8_t states /**< slave states */)
{
unsigned int first = 1;
if (!states) {
printk("(unknown)");
return;
}
if (states & EC_SLAVE_STATE_INIT) {
printk("INIT");
first = 0;
}
if (states & EC_SLAVE_STATE_PREOP) {
if (!first) printk(", ");
printk("PREOP");
first = 0;
}
if (states & EC_SLAVE_STATE_SAVEOP) {
if (!first) printk(", ");
printk("SAVEOP");
first = 0;
}
if (states & EC_SLAVE_STATE_OP) {
if (!first) printk(", ");
printk("OP");
}
}
/******************************************************************************
* Device interface
*****************************************************************************/
......
......@@ -48,6 +48,10 @@
/*****************************************************************************/
extern const ec_code_msg_t al_status_messages[];
/*****************************************************************************/
int ec_slave_fetch_categories(ec_slave_t *);
ssize_t ec_show_slave_attribute(struct kobject *, struct attribute *, char *);
......@@ -89,10 +93,6 @@ static struct kobj_type ktype_ec_slave = {
/*****************************************************************************/
const ec_code_msg_t al_status_messages[];
/*****************************************************************************/
/**
Slave constructor.
\return 0 in case of success, else < 0
......@@ -144,6 +144,9 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
slave->eeprom_name = NULL;
slave->eeprom_group = NULL;
slave->eeprom_desc = NULL;
slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
slave->current_state = EC_SLAVE_STATE_UNKNOWN;
slave->state_error = 0;
ec_command_init(&slave->mbox_command);
......@@ -1261,32 +1264,6 @@ ssize_t ec_show_slave_attribute(struct kobject *kobj, /**< slave's kobject */
return 0;
}
/*****************************************************************************/
/**
Application layer status messages.
*/
const ec_code_msg_t al_status_messages[] = {
{0x0001, "Unspecified error"},
{0x0011, "Invalud requested state change"},
{0x0012, "Unknown requested state"},
{0x0013, "Bootstrap not supported"},
{0x0014, "No valid firmware"},
{0x0015, "Invalid mailbox configuration"},
{0x0016, "Invalid mailbox configuration"},
{0x0017, "Invalid sync manager configuration"},
{0x0018, "No valid inputs available"},
{0x0019, "No valid outputs"},
{0x001A, "Synchronisation error"},
{0x001B, "Sync manager watchdog"},
{0x0020, "Slave needs cold start"},
{0x0021, "Slave needs INIT"},
{0x0022, "Slave needs PREOP"},
{0x0023, "Slave needs SAVEOP"},
{}
};
/******************************************************************************
* Realtime interface
*****************************************************************************/
......
......@@ -272,6 +272,10 @@ struct ec_slave
struct list_head sdo_dictionary; /**< SDO directory list */
ec_command_t mbox_command; /**< mailbox command */
ec_slave_state_t requested_state; /**< requested slave state */
ec_slave_state_t current_state; /**< current slave state */
unsigned int state_error; /**< a state error has happened */
};
/*****************************************************************************/
......
......@@ -73,6 +73,10 @@ case "$1" in
rc_exit
fi
if [ ! $EOE_DEVICES ]; then
EOE_DEVICES=0
fi
for mod in 8139too 8139cp; do
if lsmod | grep "^$mod " > /dev/null; then
if ! rmmod $mod; then
......@@ -83,7 +87,17 @@ case "$1" in
fi
done
modprobe ec_8139too ec_device_index=$DEVICE_INDEX
if ! modprobe ec_master ec_eoe_devices=$EOE_DEVICES; then
/bin/false
rc_status -v
rc_exit
fi
if ! modprobe ec_8139too ec_device_index=$DEVICE_INDEX; then
/bin/false
rc_status -v
rc_exit
fi
rc_status -v
;;
......
......@@ -13,7 +13,7 @@
#DEVICE_INDEX=99
#
# Number of Ethernet-over-EtherCAT devices the master shall create
# Number of Ethernet-over-EtherCAT devices every master shall create
# on startup. Default is 0.
#
#EOE_DEVICES=0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment