Added phy commands.
--- a/master/cdev.c Wed Aug 13 13:21:35 2008 +0000
+++ b/master/cdev.c Wed Aug 13 13:23:52 2008 +0000
@@ -986,6 +986,162 @@
/*****************************************************************************/
+/** Read a slave's physical memory.
+ */
+int ec_cdev_ioctl_slave_phy_read(
+ ec_master_t *master, /**< EtherCAT master. */
+ unsigned long arg /**< ioctl() argument. */
+ )
+{
+ ec_ioctl_slave_phy_t data;
+ ec_slave_t *slave;
+ uint8_t *contents;
+ ec_phy_request_t request;
+
+ if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+ return -EFAULT;
+ }
+
+ if (!data.length)
+ return 0;
+
+ if (!(contents = kmalloc(data.length, GFP_KERNEL))) {
+ EC_ERR("Failed to allocate %u bytes for phy data.\n", data.length);
+ return -ENOMEM;
+ }
+
+ if (down_interruptible(&master->master_sem))
+ return -EINTR;
+
+ if (!(slave = ec_master_find_slave(
+ master, 0, data.slave_position))) {
+ up(&master->master_sem);
+ EC_ERR("Slave %u does not exist!\n", data.slave_position);
+ return -EINVAL;
+ }
+
+ // init phy request
+ INIT_LIST_HEAD(&request.list);
+ request.slave = slave;
+ request.dir = EC_DIR_INPUT;
+ request.data = contents;
+ request.offset = data.offset;
+ request.length = data.length;
+ request.state = EC_REQUEST_QUEUED;
+
+ // schedule request.
+ list_add_tail(&request.list, &master->phy_requests);
+
+ up(&master->master_sem);
+
+ // wait for processing through FSM
+ if (wait_event_interruptible(master->phy_queue,
+ request.state != EC_REQUEST_QUEUED)) {
+ // interrupted by signal
+ down(&master->master_sem);
+ if (request.state == EC_REQUEST_QUEUED) {
+ // abort request
+ list_del(&request.list);
+ up(&master->master_sem);
+ kfree(contents);
+ return -EINTR;
+ }
+ up(&master->master_sem);
+ }
+
+ // wait until master FSM has finished processing
+ wait_event(master->phy_queue, request.state != EC_REQUEST_BUSY);
+
+ if (request.state == EC_REQUEST_SUCCESS) {
+ if (copy_to_user((void __user *) data.data, contents, data.length))
+ return -EFAULT;
+ }
+ kfree(contents);
+
+ return request.state == EC_REQUEST_SUCCESS ? 0 : -EIO;
+}
+
+/*****************************************************************************/
+
+/** Write a slave's physical memory.
+ */
+int ec_cdev_ioctl_slave_phy_write(
+ ec_master_t *master, /**< EtherCAT master. */
+ unsigned long arg /**< ioctl() argument. */
+ )
+{
+ ec_ioctl_slave_phy_t data;
+ ec_slave_t *slave;
+ uint8_t *contents;
+ ec_phy_request_t request;
+
+ if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+ return -EFAULT;
+ }
+
+ if (!data.length)
+ return 0;
+
+ if (!(contents = kmalloc(data.length, GFP_KERNEL))) {
+ EC_ERR("Failed to allocate %u bytes for phy data.\n", data.length);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(contents, (void __user *) data.data, data.length)) {
+ kfree(contents);
+ return -EFAULT;
+ }
+
+ if (down_interruptible(&master->master_sem))
+ return -EINTR;
+
+ if (!(slave = ec_master_find_slave(
+ master, 0, data.slave_position))) {
+ up(&master->master_sem);
+ EC_ERR("Slave %u does not exist!\n", data.slave_position);
+ kfree(contents);
+ return -EINVAL;
+ }
+
+ // init phy request
+ INIT_LIST_HEAD(&request.list);
+ request.slave = slave;
+ request.dir = EC_DIR_OUTPUT;
+ request.data = contents;
+ request.offset = data.offset;
+ request.length = data.length;
+ request.state = EC_REQUEST_QUEUED;
+
+ // schedule request.
+ list_add_tail(&request.list, &master->phy_requests);
+
+ up(&master->master_sem);
+
+ // wait for processing through FSM
+ if (wait_event_interruptible(master->phy_queue,
+ request.state != EC_REQUEST_QUEUED)) {
+ // interrupted by signal
+ down(&master->master_sem);
+ if (request.state == EC_REQUEST_QUEUED) {
+ // abort request
+ list_del(&request.list);
+ up(&master->master_sem);
+ kfree(contents);
+ return -EINTR;
+ }
+ up(&master->master_sem);
+ }
+
+ // wait until master FSM has finished processing
+ wait_event(master->phy_queue, request.state != EC_REQUEST_BUSY);
+
+ kfree(contents);
+
+ return request.state == EC_REQUEST_SUCCESS ? 0 : -EIO;
+}
+
+/*****************************************************************************/
+
/** Get slave configuration information.
*/
int ec_cdev_ioctl_config(
@@ -1282,6 +1438,12 @@
if (!(filp->f_mode & FMODE_WRITE))
return -EPERM;
return ec_cdev_ioctl_slave_sii_write(master, arg);
+ case EC_IOCTL_SLAVE_PHY_READ:
+ return ec_cdev_ioctl_slave_phy_read(master, arg);
+ case EC_IOCTL_SLAVE_PHY_WRITE:
+ if (!(filp->f_mode & FMODE_WRITE))
+ return -EPERM;
+ return ec_cdev_ioctl_slave_phy_write(master, arg);
case EC_IOCTL_CONFIG:
return ec_cdev_ioctl_config(master, arg);
case EC_IOCTL_CONFIG_PDO:
--- a/master/fsm_master.c Wed Aug 13 13:21:35 2008 +0000
+++ b/master/fsm_master.c Wed Aug 13 13:23:52 2008 +0000
@@ -59,6 +59,7 @@
void ec_fsm_master_state_write_sii(ec_fsm_master_t *);
void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *);
void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
+void ec_fsm_master_state_phy_request(ec_fsm_master_t *);
/*****************************************************************************/
@@ -324,6 +325,59 @@
/*****************************************************************************/
+/** Check for pending phy requests and process one.
+ *
+ * \return non-zero, if a phy request is processed.
+ */
+int ec_fsm_master_action_process_phy(
+ ec_fsm_master_t *fsm /**< Master state machine. */
+ )
+{
+ ec_master_t *master = fsm->master;
+ ec_phy_request_t *request;
+
+ // search the first request to be processed
+ while (1) {
+ if (list_empty(&master->phy_requests))
+ break;
+
+ // get first request
+ request = list_entry(master->phy_requests.next,
+ ec_phy_request_t, list);
+ list_del_init(&request->list); // dequeue
+ request->state = EC_REQUEST_BUSY;
+
+ // found pending request; process it!
+ if (master->debug_level)
+ EC_DBG("Processing phy request for slave %u...\n",
+ request->slave->ring_position);
+ fsm->phy_request = request;
+
+ if (request->dir == EC_DIR_INPUT) {
+ ec_datagram_fprd(fsm->datagram, request->slave->station_address,
+ request->offset, request->length);
+ } else {
+ if (request->length > fsm->datagram->mem_size) {
+ EC_ERR("Request length (%u) exceeds maximum datagram size (%u)!\n",
+ request->length, fsm->datagram->mem_size);
+ request->state = EC_REQUEST_FAILURE;
+ wake_up(&master->phy_queue);
+ continue;
+ }
+ ec_datagram_fpwr(fsm->datagram, request->slave->station_address,
+ request->offset, request->length);
+ memcpy(fsm->datagram->data, request->data, request->length);
+ }
+ fsm->retries = EC_FSM_RETRIES;
+ fsm->state = ec_fsm_master_state_phy_request;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+
/** Check for pending Sdo requests and process one.
*
* \return non-zero, if an Sdo request is processed.
@@ -460,6 +514,10 @@
if (ec_fsm_master_action_process_sii(fsm))
return; // SII write request found
+ // check for pending phy requests.
+ if (ec_fsm_master_action_process_phy(fsm))
+ return; // phy request processing
+
ec_fsm_master_restart(fsm);
}
@@ -862,3 +920,49 @@
}
/*****************************************************************************/
+
+/** Master state: PHY.
+ */
+void ec_fsm_master_state_phy_request(
+ ec_fsm_master_t *fsm /**< Master state machine. */
+ )
+{
+ ec_master_t *master = fsm->master;
+ ec_datagram_t *datagram = fsm->datagram;
+ ec_phy_request_t *request = fsm->phy_request;
+
+ if (datagram->state != EC_DATAGRAM_RECEIVED) {
+ EC_ERR("Failed to receive phy request datagram (state %u).\n",
+ datagram->state);
+ request->state = EC_REQUEST_FAILURE;
+ wake_up(&master->phy_queue);
+ ec_fsm_master_restart(fsm);
+ return;
+ }
+
+ if (request->dir == EC_DIR_INPUT) { // read request
+ if (request->data)
+ kfree(request->data);
+ request->data = kmalloc(request->length, GFP_KERNEL);
+ if (!request->data) {
+ EC_ERR("Failed to allocate %u bytes of memory for phy request.\n",
+ request->length);
+ request->state = EC_REQUEST_FAILURE;
+ wake_up(&master->phy_queue);
+ ec_fsm_master_restart(fsm);
+ return;
+ }
+ memcpy(request->data, datagram->data, request->length);
+ }
+
+ request->state = EC_REQUEST_SUCCESS;
+ wake_up(&master->phy_queue);
+
+ // check for another PHY request
+ if (ec_fsm_master_action_process_phy(fsm))
+ return; // processing another request
+
+ ec_fsm_master_restart(fsm);
+}
+
+/*****************************************************************************/
--- a/master/fsm_master.h Wed Aug 13 13:21:35 2008 +0000
+++ b/master/fsm_master.h Wed Aug 13 13:23:52 2008 +0000
@@ -65,6 +65,20 @@
/*****************************************************************************/
+/** Physical memory request.
+ */
+typedef struct {
+ struct list_head list; /**< List head. */
+ ec_slave_t *slave; /**< EtherCAT slave. */
+ ec_direction_t dir; /**< Direction. */
+ uint16_t offset; /**< Physical memory offset. */
+ size_t length; /**< Number of bytes. */
+ uint8_t *data;
+ ec_request_state_t state; /**< State of the request. */
+} ec_phy_request_t;
+
+/*****************************************************************************/
+
/** Slave/Sdo request record for master's Sdo request list.
*/
typedef struct {
@@ -94,6 +108,7 @@
ec_sii_write_request_t *sii_request; /**< SII write request */
off_t sii_index; /**< index to SII write request data */
ec_sdo_request_t *sdo_request; /**< Sdo request to process. */
+ ec_phy_request_t *phy_request; /**< Physical memory request to process. */
ec_fsm_coe_t fsm_coe; /**< CoE state machine */
ec_fsm_pdo_t fsm_pdo; /**< Pdo configuration state machine. */
--- a/master/ioctl.h Wed Aug 13 13:21:35 2008 +0000
+++ b/master/ioctl.h Wed Aug 13 13:23:52 2008 +0000
@@ -72,10 +72,12 @@
#define EC_IOCTL_SLAVE_SDO_DOWNLOAD EC_IOWR(0x0d, ec_ioctl_slave_sdo_download_t)
#define EC_IOCTL_SLAVE_SII_READ EC_IOWR(0x0e, ec_ioctl_slave_sii_t)
#define EC_IOCTL_SLAVE_SII_WRITE EC_IOW(0x0f, ec_ioctl_slave_sii_t)
-#define EC_IOCTL_CONFIG EC_IOWR(0x10, ec_ioctl_config_t)
-#define EC_IOCTL_CONFIG_PDO EC_IOWR(0x11, ec_ioctl_config_pdo_t)
-#define EC_IOCTL_CONFIG_PDO_ENTRY EC_IOWR(0x12, ec_ioctl_config_pdo_entry_t)
-#define EC_IOCTL_CONFIG_SDO EC_IOWR(0x13, ec_ioctl_config_sdo_t)
+#define EC_IOCTL_SLAVE_PHY_READ EC_IOWR(0x10, ec_ioctl_slave_phy_t)
+#define EC_IOCTL_SLAVE_PHY_WRITE EC_IOW(0x11, ec_ioctl_slave_phy_t)
+#define EC_IOCTL_CONFIG EC_IOWR(0x12, ec_ioctl_config_t)
+#define EC_IOCTL_CONFIG_PDO EC_IOWR(0x13, ec_ioctl_config_pdo_t)
+#define EC_IOCTL_CONFIG_PDO_ENTRY EC_IOWR(0x14, ec_ioctl_config_pdo_entry_t)
+#define EC_IOCTL_CONFIG_SDO EC_IOWR(0x15, ec_ioctl_config_sdo_t)
#define EC_IOCTL_STRING_SIZE 64
@@ -288,6 +290,16 @@
typedef struct {
// inputs
+ uint16_t slave_position;
+ uint16_t offset;
+ uint16_t length;
+ uint8_t *data;
+} ec_ioctl_slave_phy_t;
+
+/*****************************************************************************/
+
+typedef struct {
+ // inputs
uint32_t config_index;
// outputs
--- a/master/master.c Wed Aug 13 13:21:35 2008 +0000
+++ b/master/master.c Wed Aug 13 13:23:52 2008 +0000
@@ -141,6 +141,9 @@
INIT_LIST_HEAD(&master->slave_sdo_requests);
init_waitqueue_head(&master->sdo_queue);
+ INIT_LIST_HEAD(&master->phy_requests);
+ init_waitqueue_head(&master->phy_queue);
+
// init devices
if (ec_device_init(&master->main_device, master))
goto out_return;
--- a/master/master.h Wed Aug 13 13:21:35 2008 +0000
+++ b/master/master.h Wed Aug 13 13:23:52 2008 +0000
@@ -165,6 +165,9 @@
struct list_head slave_sdo_requests; /**< Sdo access requests. */
wait_queue_head_t sdo_queue; /**< Wait queue for Sdo access requests
from user space. */
+
+ struct list_head phy_requests; /**< Physical memory requests. */
+ wait_queue_head_t phy_queue; /**< Wait queue for phy requests. */
};
/*****************************************************************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool/CommandPhyRead.cpp Wed Aug 13 13:23:52 2008 +0000
@@ -0,0 +1,114 @@
+/*****************************************************************************
+ *
+ * $Id$
+ *
+ ****************************************************************************/
+
+#include <iostream>
+#include <iomanip>
+using namespace std;
+
+#include "CommandPhyRead.h"
+
+/*****************************************************************************/
+
+CommandPhyRead::CommandPhyRead():
+ Command("phy_read", "Output a slave's physical memory contents.")
+{
+}
+
+/*****************************************************************************/
+
+string CommandPhyRead::helpString() const
+{
+ stringstream str;
+
+ str << getName() << " [OPTIONS] <OFFSET> <LENGTH>" << endl
+ << endl
+ << getBriefDescription() << endl
+ << endl
+ << "This command requires a single slave to be selected." << endl
+ << endl
+ << "Arguments:" << endl
+ << " OFFSET is the physical memory address. Must" << endl
+ << " be an unsigned 16 bit number." << endl
+ << " LENGTH is the number of bytes to read and must also be" << endl
+ << " an unsigned 16 bit number. OFFSET plus LENGTH" << endl
+ << " may not exceed 64k." << endl
+ << endl
+ << "Command-specific options:" << endl
+ << " --alias -a <alias>" << endl
+ << " --position -p <pos> Slave selection. See the help of" << endl
+ << " the 'slaves' command." << endl
+ << endl
+ << numericInfo();
+
+ return str.str();
+}
+
+/****************************************************************************/
+
+void CommandPhyRead::execute(MasterDevice &m, const StringVector &args)
+{
+ SlaveList slaves;
+ ec_ioctl_slave_phy_t data;
+ stringstream strOffset, strLength, err;
+ uint16_t i;
+
+ if (args.size() != 2) {
+ err << "'" << getName() << "' takes two arguments!";
+ throwInvalidUsageException(err);
+ }
+
+ strOffset << args[0];
+ strOffset
+ >> resetiosflags(ios::basefield) // guess base from prefix
+ >> data.offset;
+ if (strOffset.fail()) {
+ err << "Invalid offset '" << args[0] << "'!";
+ throwInvalidUsageException(err);
+ }
+
+ strLength << args[1];
+ strLength
+ >> resetiosflags(ios::basefield) // guess base from prefix
+ >> data.length;
+ if (strLength.fail()) {
+ err << "Invalid length '" << args[1] << "'!";
+ throwInvalidUsageException(err);
+ }
+
+ if (!data.length) {
+ return;
+ }
+
+ if ((uint32_t) data.offset + data.length > 0xffff) {
+ err << "Offset and length exceeding 64k!";
+ throwInvalidUsageException(err);
+ }
+
+ m.open(MasterDevice::Read);
+ slaves = selectedSlaves(m);
+
+ if (slaves.size() != 1) {
+ throwSingleSlaveRequired(slaves.size());
+ }
+ data.slave_position = slaves.front().position;
+
+ data.data = new uint8_t[data.length];
+
+ try {
+ m.readPhy(&data);
+ } catch (MasterDeviceException &e) {
+ delete [] data.data;
+ throw e;
+ }
+
+ for (i = 0; i < data.length; i++) {
+ cout << data.data[i];
+ }
+
+ delete [] data.data;
+}
+
+/*****************************************************************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool/CommandPhyRead.h Wed Aug 13 13:23:52 2008 +0000
@@ -0,0 +1,26 @@
+/*****************************************************************************
+ *
+ * $Id$
+ *
+ ****************************************************************************/
+
+#ifndef __COMMANDPHYREAD_H__
+#define __COMMANDPHYREAD_H__
+
+#include "Command.h"
+
+/****************************************************************************/
+
+class CommandPhyRead:
+ public Command
+{
+ public:
+ CommandPhyRead();
+
+ string helpString() const;
+ void execute(MasterDevice &, const StringVector &);
+};
+
+/****************************************************************************/
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool/CommandPhyWrite.cpp Wed Aug 13 13:23:52 2008 +0000
@@ -0,0 +1,148 @@
+/*****************************************************************************
+ *
+ * $Id$
+ *
+ ****************************************************************************/
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+using namespace std;
+
+#include "CommandPhyWrite.h"
+#include "sii_crc.h"
+#include "byteorder.h"
+
+/*****************************************************************************/
+
+CommandPhyWrite::CommandPhyWrite():
+ Command("phy_write", "Write data to a slave's physical memory.")
+{
+}
+
+/*****************************************************************************/
+
+string CommandPhyWrite::helpString() const
+{
+ stringstream str;
+
+ str << getName() << " [OPTIONS] <OFFSET> <FILENAME>" << endl
+ << endl
+ << getBriefDescription() << endl
+ << endl
+ << "This command requires a single slave to be selected." << endl
+ << endl
+ << "Arguments:" << endl
+ << " OFFSET must be the physical memory offset to start." << endl
+ << " FILENAME must be a path to a file with data to write." << endl
+ << " If it is '-', data are read from stdin." << endl
+ << endl
+ << "Command-specific options:" << endl
+ << " --alias -a <alias>" << endl
+ << " --position -p <pos> Slave selection. See the help of" << endl
+ << " the 'slaves' command." << endl
+ << endl
+ << numericInfo();
+
+ return str.str();
+}
+
+/****************************************************************************/
+
+void CommandPhyWrite::execute(MasterDevice &m, const StringVector &args)
+{
+ stringstream strOffset, err;
+ ec_ioctl_slave_phy_t data;
+ ifstream file;
+ SlaveList slaves;
+
+ if (args.size() != 2) {
+ err << "'" << getName() << "' takes exactly one argument!";
+ throwInvalidUsageException(err);
+ }
+
+ strOffset << args[0];
+ strOffset
+ >> resetiosflags(ios::basefield) // guess base from prefix
+ >> data.offset;
+ if (strOffset.fail()) {
+ err << "Invalid offset '" << args[0] << "'!";
+ throwInvalidUsageException(err);
+ }
+
+ if (args[1] == "-") {
+ loadPhyData(&data, cin);
+ } else {
+ file.open(args[1].c_str(), ifstream::in | ifstream::binary);
+ if (file.fail()) {
+ err << "Failed to open '" << args[0] << "'!";
+ throwCommandException(err);
+ }
+ loadPhyData(&data, file);
+ file.close();
+ }
+
+ if ((uint32_t) data.offset + data.length > 0xffff) {
+ err << "Offset and length exceeding 64k!";
+ delete [] data.data;
+ throwInvalidUsageException(err);
+ }
+
+ try {
+ m.open(MasterDevice::ReadWrite);
+ } catch (MasterDeviceException &e) {
+ delete [] data.data;
+ throw e;
+ }
+
+ slaves = selectedSlaves(m);
+ if (slaves.size() != 1) {
+ delete [] data.data;
+ throwSingleSlaveRequired(slaves.size());
+ }
+ data.slave_position = slaves.front().position;
+
+ // send data to master
+ try {
+ m.writePhy(&data);
+ } catch (MasterDeviceException &e) {
+ delete [] data.data;
+ throw e;
+ }
+
+ if (getVerbosity() == Verbose) {
+ cerr << "Physical memory writing finished." << endl;
+ }
+
+ delete [] data.data;
+}
+
+/*****************************************************************************/
+
+void CommandPhyWrite::loadPhyData(
+ ec_ioctl_slave_phy_t *data,
+ const istream &in
+ )
+{
+ stringstream err;
+ ostringstream tmp;
+
+ tmp << in.rdbuf();
+ string const &contents = tmp.str();
+
+ if (getVerbosity() == Verbose) {
+ cerr << "Read " << contents.size() << " bytes of data." << endl;
+ }
+
+ if (contents.size() > 0xffff) {
+ err << "Invalid data size " << contents.size() << "!";
+ throwInvalidUsageException(err);
+ }
+ data->length = contents.size();
+
+ // allocate buffer and read file into buffer
+ data->data = new uint8_t[data->length];
+ contents.copy((char *) data->data, contents.size());
+}
+
+/*****************************************************************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool/CommandPhyWrite.h Wed Aug 13 13:23:52 2008 +0000
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ *
+ * $Id$
+ *
+ ****************************************************************************/
+
+#ifndef __COMMANDPHYWRITE_H__
+#define __COMMANDPHYWRITE_H__
+
+#include "Command.h"
+
+/****************************************************************************/
+
+class CommandPhyWrite:
+ public Command
+{
+ public:
+ CommandPhyWrite();
+
+ string helpString() const;
+ void execute(MasterDevice &, const StringVector &);
+
+ private:
+ void loadPhyData(ec_ioctl_slave_phy_t *, const istream &);
+};
+
+/****************************************************************************/
+
+#endif
--- a/tool/Makefile.am Wed Aug 13 13:21:35 2008 +0000
+++ b/tool/Makefile.am Wed Aug 13 13:23:52 2008 +0000
@@ -45,6 +45,8 @@
CommandDownload.cpp \
CommandMaster.cpp \
CommandPdos.cpp \
+ CommandPhyRead.cpp \
+ CommandPhyWrite.cpp \
CommandSdos.cpp \
CommandSiiRead.cpp \
CommandSiiWrite.cpp \
@@ -68,6 +70,8 @@
CommandDownload.h \
CommandMaster.h \
CommandPdos.h \
+ CommandPhyRead.h \
+ CommandPhyWrite.h \
CommandSdos.h \
CommandSiiRead.h \
CommandSiiWrite.h \
--- a/tool/MasterDevice.cpp Wed Aug 13 13:21:35 2008 +0000
+++ b/tool/MasterDevice.cpp Wed Aug 13 13:23:52 2008 +0000
@@ -344,6 +344,32 @@
/****************************************************************************/
+void MasterDevice::readPhy(
+ ec_ioctl_slave_phy_t *data
+ )
+{
+ if (ioctl(fd, EC_IOCTL_SLAVE_PHY_READ, data) < 0) {
+ stringstream err;
+ err << "Failed to read physical memory: " << strerror(errno);
+ throw MasterDeviceException(err);
+ }
+}
+
+/****************************************************************************/
+
+void MasterDevice::writePhy(
+ ec_ioctl_slave_phy_t *data
+ )
+{
+ if (ioctl(fd, EC_IOCTL_SLAVE_PHY_WRITE, data) < 0) {
+ stringstream err;
+ err << "Failed to write physical memory: " << strerror(errno);
+ throw MasterDeviceException(err);
+ }
+}
+
+/****************************************************************************/
+
void MasterDevice::setDebug(unsigned int debugLevel)
{
if (ioctl(fd, EC_IOCTL_MASTER_DEBUG, debugLevel) < 0) {
--- a/tool/MasterDevice.h Wed Aug 13 13:21:35 2008 +0000
+++ b/tool/MasterDevice.h Wed Aug 13 13:23:52 2008 +0000
@@ -86,6 +86,8 @@
void getSdoEntry(ec_ioctl_slave_sdo_entry_t *, uint16_t, int, uint8_t);
void readSii(ec_ioctl_slave_sii_t *);
void writeSii(ec_ioctl_slave_sii_t *);
+ void readPhy(ec_ioctl_slave_phy_t *);
+ void writePhy(ec_ioctl_slave_phy_t *);
void setDebug(unsigned int);
void sdoDownload(ec_ioctl_slave_sdo_download_t *);
void sdoUpload(ec_ioctl_slave_sdo_upload_t *);
--- a/tool/main.cpp Wed Aug 13 13:21:35 2008 +0000
+++ b/tool/main.cpp Wed Aug 13 13:23:52 2008 +0000
@@ -19,6 +19,8 @@
#include "CommandDownload.h"
#include "CommandMaster.h"
#include "CommandPdos.h"
+#include "CommandPhyRead.h"
+#include "CommandPhyWrite.h"
#include "CommandSdos.h"
#include "CommandSiiRead.h"
#include "CommandSiiWrite.h"
@@ -263,6 +265,8 @@
commandList.push_back(new CommandDownload());
commandList.push_back(new CommandMaster());
commandList.push_back(new CommandPdos());
+ commandList.push_back(new CommandPhyRead());
+ commandList.push_back(new CommandPhyWrite());
commandList.push_back(new CommandSdos());
commandList.push_back(new CommandSiiRead());
commandList.push_back(new CommandSiiWrite());