From 6f4eae0faafa0ab847d8f3cf492a6a489178018d Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Wed, 7 Mar 2007 13:06:40 +0000 Subject: [PATCH] Layed out sync manager structures and methods into own files. --- master/Kbuild | 2 +- master/Makefile.am | 1 + master/domain.c | 1 - master/fsm_slave.c | 16 ++++--- master/slave.c | 43 +++++++++++-------- master/slave.h | 22 +--------- master/sync.c | 105 +++++++++++++++++++++++++++++++++++++++++++++ master/sync.h | 79 ++++++++++++++++++++++++++++++++++ 8 files changed, 221 insertions(+), 48 deletions(-) create mode 100644 master/sync.c create mode 100644 master/sync.h diff --git a/master/Kbuild b/master/Kbuild index 1daabc87..0799df43 100644 --- a/master/Kbuild +++ b/master/Kbuild @@ -35,7 +35,7 @@ include $(src)/../config.kbuild obj-m := ec_master.o -ec_master-objs := module.o master.o device.o device_id.o pdo.o slave.o \ +ec_master-objs := module.o master.o device.o device_id.o pdo.o sync.o slave.o \ datagram.o domain.o mailbox.o canopen.o ethernet.o fsm_sii.o fsm_change.o \ fsm_coe.o fsm_slave.o fsm_master.o xmldev.o diff --git a/master/Makefile.am b/master/Makefile.am index 83d36447..565afad0 100644 --- a/master/Makefile.am +++ b/master/Makefile.am @@ -39,6 +39,7 @@ EXTRA_DIST = \ device.c device.h \ device_id.c device_id.h \ pdo.c pdo.h \ + sync.c sync.h \ domain.c domain.h \ doxygen.c \ ethernet.c ethernet.h \ diff --git a/master/domain.c b/master/domain.c index f6c4c09a..4c5ec4cb 100644 --- a/master/domain.c +++ b/master/domain.c @@ -207,7 +207,6 @@ int ec_domain_reg_pdo_entry(ec_domain_t *domain, /**< EtherCAT domain */ pdo->index, entry->subindex); return -1; } - sync = &slave->sii_syncs[pdo->sync_index]; // Calculate offset (in sync manager) for process data pointer diff --git a/master/fsm_slave.c b/master/fsm_slave.c index c18ec80d..cbecca8b 100644 --- a/master/fsm_slave.c +++ b/master/fsm_slave.c @@ -657,9 +657,11 @@ void ec_fsm_slave_conf_state_clear_fmmus(ec_fsm_slave_t *fsm /*****************************************************************************/ /** -*/ + */ -void ec_fsm_slave_conf_enter_mbox_sync(ec_fsm_slave_t *fsm /**< slave state machine */) +void ec_fsm_slave_conf_enter_mbox_sync( + ec_fsm_slave_t *fsm /**< slave state machine */ + ) { ec_master_t *master = fsm->slave->master; ec_slave_t *slave = fsm->slave; @@ -693,7 +695,7 @@ void ec_fsm_slave_conf_enter_mbox_sync(ec_fsm_slave_t *fsm /**< slave state mach memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count); for (i = 0; i < 2; i++) { - ec_slave_sync_config(slave, &slave->sii_syncs[i], + ec_sync_config(&slave->sii_syncs[i], datagram->data + EC_SYNC_SIZE * i); } @@ -790,9 +792,11 @@ void ec_fsm_slave_conf_state_preop(ec_fsm_slave_t *fsm /**< slave state machine /*****************************************************************************/ /** -*/ + */ -void ec_fsm_slave_conf_enter_pdo_sync(ec_fsm_slave_t *fsm /**< slave state machine */) +void ec_fsm_slave_conf_enter_pdo_sync( + ec_fsm_slave_t *fsm /**< slave state machine */ + ) { ec_slave_t *slave = fsm->slave; ec_datagram_t *datagram = fsm->datagram; @@ -809,7 +813,7 @@ void ec_fsm_slave_conf_enter_pdo_sync(ec_fsm_slave_t *fsm /**< slave state machi memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count); for (i = 0; i < slave->sii_sync_count; i++) { - ec_slave_sync_config(slave, &slave->sii_syncs[i], + ec_sync_config(&slave->sii_syncs[i], datagram->data + EC_SYNC_SIZE * i); } diff --git a/master/slave.c b/master/slave.c index 00b34938..c1d26e36 100644 --- a/master/slave.c +++ b/master/slave.c @@ -255,7 +255,13 @@ void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */) } // free all sync managers - if (slave->sii_syncs) kfree(slave->sii_syncs); + if (slave->sii_syncs) { + for (i = 0; i < slave->sii_sync_count; i++) { + ec_sync_clear(&slave->sii_syncs[i]); + kfree(&slave->sii_syncs[i]); + } + kfree(slave->sii_syncs); + } // free all PDOs list_for_each_entry_safe(pdo, next_pdo, &slave->sii_pdos, list) { @@ -480,22 +486,22 @@ int ec_slave_fetch_sii_syncs( // sync manager struct is 4 words long slave->sii_sync_count = word_count / 4; - if (!(slave->sii_syncs = kmalloc(sizeof(ec_sync_t) * - slave->sii_sync_count, GFP_ATOMIC))) { - EC_ERR("Failed to allocate Sync-Manager memory.\n"); + if (!(slave->sii_syncs = + kmalloc(sizeof(ec_sync_t) * slave->sii_sync_count, + GFP_KERNEL))) { + EC_ERR("Failed to allocate memory for sync managers.\n"); + slave->sii_sync_count = 0; return -1; } for (i = 0; i < slave->sii_sync_count; i++, data += 8) { sync = &slave->sii_syncs[i]; - sync->index = i; + ec_sync_init(sync, slave, i); sync->physical_start_address = EC_READ_U16(data); - sync->length = EC_READ_U16(data + 2); - sync->control_register = EC_READ_U8 (data + 4); - sync->enable = EC_READ_U8 (data + 6); - - sync->est_length = 0; + sync->length = EC_READ_U16(data + 2); + sync->control_register = EC_READ_U8 (data + 4); + sync->enable = EC_READ_U8 (data + 6); } return 0; @@ -761,7 +767,7 @@ size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */ for (i = 0; i < slave->sii_sync_count; i++) { sync = &slave->sii_syncs[i]; - off += sprintf(buffer + off, " %i: 0x%04X, length %i," + off += sprintf(buffer + off, " %u) 0x%04X, length %i," " control 0x%02X, %s\n", sync->index, sync->physical_start_address, sync->length, sync->control_register, @@ -1051,15 +1057,14 @@ ssize_t ec_store_slave_attribute(struct kobject *kobj, /**< slave's kobject */ /*****************************************************************************/ /** - Calculates the size of a sync manager by evaluating PDO sizes. - \return sync manager size -*/ + * Calculates the size of a sync manager by evaluating PDO sizes. + * \return sync manager size + */ -uint16_t ec_slave_calc_sync_size(const ec_slave_t *slave, - /**< EtherCAT slave */ - const ec_sync_t *sync - /**< sync manager */ - ) +uint16_t ec_slave_calc_sync_size( + const ec_slave_t *slave, /**< EtherCAT slave */ + const ec_sync_t *sync /**< sync manager */ + ) { const ec_pdo_t *pdo; const ec_pdo_entry_t *pdo_entry; diff --git a/master/slave.h b/master/slave.h index bd95314c..03652098 100644 --- a/master/slave.h +++ b/master/slave.h @@ -49,6 +49,7 @@ #include "globals.h" #include "datagram.h" #include "pdo.h" +#include "sync.h" /*****************************************************************************/ @@ -102,26 +103,6 @@ enum /*****************************************************************************/ -/** - Sync manager. -*/ - -typedef struct -{ - unsigned int index; /**< sync manager index */ - uint16_t physical_start_address; /**< physical start address */ - uint16_t length; /**< data length in bytes */ - uint8_t control_register; /**< control register value */ - uint8_t enable; /**< enable bit */ - - uint16_t est_length; /**< Estimated length. This is no field of the SII, - but it is used to calculate the length via - PDO ranges */ -} -ec_sync_t; - -/*****************************************************************************/ - /** FMMU configuration. */ @@ -232,7 +213,6 @@ int ec_slave_fetch_sii_pdos(ec_slave_t *, const uint8_t *, size_t, // misc. ec_sync_t *ec_slave_get_pdo_sync(ec_slave_t *, ec_direction_t); -void ec_slave_sync_config(const ec_slave_t *, const ec_sync_t *, uint8_t *); void ec_slave_fmmu_config(const ec_slave_t *, const ec_fmmu_t *, uint8_t *); uint16_t ec_slave_calc_sync_size(const ec_slave_t *, const ec_sync_t *); diff --git a/master/sync.c b/master/sync.c new file mode 100644 index 00000000..e6583f03 --- /dev/null +++ b/master/sync.c @@ -0,0 +1,105 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * The right to use EtherCAT Technology is granted and comes free of + * charge under condition of compatibility of product made by + * Licensee. People intending to distribute/sell products based on the + * code, have to sign an agreement to guarantee that products using + * software based on IgH EtherCAT master stay compatible with the actual + * EtherCAT specification (which are released themselves as an open + * standard) as the (only) precondition to have the right to use EtherCAT + * Technology, IP and trade marks. + * + *****************************************************************************/ + +/** + \file + EtherCAT sync manager methods. +*/ + +/*****************************************************************************/ + +#include "globals.h" +#include "slave.h" +#include "master.h" +#include "sync.h" + +/*****************************************************************************/ + +/** + * Constructor. + */ + +void ec_sync_init( + ec_sync_t *sync, /**< EtherCAT sync manager */ + const ec_slave_t *slave, /**< EtherCAT slave */ + unsigned int index /**< sync manager index */ + ) +{ + sync->slave = slave; + sync->index = index; + + sync->est_length = 0; +} + +/*****************************************************************************/ + +/** + * Destructor. + */ + +void ec_sync_clear( + ec_sync_t *sync /**< EtherCAT sync manager */ + ) +{ +} + +/*****************************************************************************/ + +/** + Initializes a sync manager configuration page with EEPROM data. + The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. +*/ + +void ec_sync_config( + const ec_sync_t *sync, /**< sync manager */ + uint8_t *data /**> configuration memory */ + ) +{ + size_t sync_size; + + sync_size = ec_slave_calc_sync_size(sync->slave, sync); + + if (sync->slave->master->debug_level) { + EC_DBG("SM%i: Addr 0x%04X, Size %3i, Ctrl 0x%02X, En %i\n", + sync->index, sync->physical_start_address, + sync_size, sync->control_register, sync->enable); + } + + EC_WRITE_U16(data, sync->physical_start_address); + EC_WRITE_U16(data + 2, sync_size); + EC_WRITE_U8 (data + 4, sync->control_register); + EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) + EC_WRITE_U16(data + 6, sync->enable ? 0x0001 : 0x0000); // enable +} + +/*****************************************************************************/ diff --git a/master/sync.h b/master/sync.h new file mode 100644 index 00000000..88586774 --- /dev/null +++ b/master/sync.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * The right to use EtherCAT Technology is granted and comes free of + * charge under condition of compatibility of product made by + * Licensee. People intending to distribute/sell products based on the + * code, have to sign an agreement to guarantee that products using + * software based on IgH EtherCAT master stay compatible with the actual + * EtherCAT specification (which are released themselves as an open + * standard) as the (only) precondition to have the right to use EtherCAT + * Technology, IP and trade marks. + * + *****************************************************************************/ + +/** + \file + EtherCAT sync manager. +*/ + +/*****************************************************************************/ + +#ifndef _EC_SYNC_H_ +#define _EC_SYNC_H_ + +#include <linux/list.h> + +#include "../include/ecrt.h" +#include "globals.h" + +/*****************************************************************************/ + +/** + * Sync manager. + */ + +typedef struct +{ + const ec_slave_t *slave; /**< slave, the sync manager belongs to */ + unsigned int index; /**< sync manager index */ + uint16_t physical_start_address; /**< physical start address */ + uint16_t length; /**< data length in bytes */ + uint8_t control_register; /**< control register value */ + uint8_t enable; /**< enable bit */ + + uint16_t est_length; /**< Estimated length. This is no field of the SII, + but it is used to calculate the length via + PDO ranges */ +} +ec_sync_t; + +/*****************************************************************************/ + +void ec_sync_init(ec_sync_t *, const ec_slave_t *, unsigned int); +void ec_sync_clear(ec_sync_t *); + +void ec_sync_config(const ec_sync_t *, uint8_t *); + +/*****************************************************************************/ + +#endif -- GitLab