lib/master.c
branchstable-1.5
changeset 2433 3bdd7a747fae
parent 2427 17ada1c77acc
child 2443 2c3ccdde3919
equal deleted inserted replaced
2432:f4313f5aba88 2433:3bdd7a747fae
     1 /*****************************************************************************
     1 /*****************************************************************************
     2  *
     2  *
     3  *  $Id$
     3  *  $Id$
     4  *
     4  *
     5  *  Copyright (C) 2006-2009  Florian Pose, Ingenieurgemeinschaft IgH
     5  *  Copyright (C) 2006-2012  Florian Pose, Ingenieurgemeinschaft IgH
     6  *
     6  *
     7  *  This file is part of the IgH EtherCAT master userspace library.
     7  *  This file is part of the IgH EtherCAT master userspace library.
     8  *
     8  *
     9  *  The IgH EtherCAT master userspace library is free software; you can
     9  *  The IgH EtherCAT master userspace library is free software; you can
    10  *  redistribute it and/or modify it under the terms of the GNU Lesser General
    10  *  redistribute it and/or modify it under the terms of the GNU Lesser General
    28  *
    28  *
    29  ****************************************************************************/
    29  ****************************************************************************/
    30 
    30 
    31 #include <unistd.h> /* close() */
    31 #include <unistd.h> /* close() */
    32 #include <stdlib.h>
    32 #include <stdlib.h>
    33 #include <sys/ioctl.h>
       
    34 #include <stdio.h>
    33 #include <stdio.h>
    35 #include <errno.h>
    34 #include <errno.h>
    36 #include <string.h>
    35 #include <string.h>
    37 #include <sys/mman.h>
    36 #include <sys/mman.h>
    38 
    37 
       
    38 #include "ioctl.h"
    39 #include "master.h"
    39 #include "master.h"
    40 #include "domain.h"
    40 #include "domain.h"
    41 #include "slave_config.h"
    41 #include "slave_config.h"
    42 #include "master/ioctl.h"
       
    43 
    42 
    44 /****************************************************************************/
    43 /****************************************************************************/
    45 
    44 
    46 int ecrt_master_reserve(ec_master_t *master)
    45 int ecrt_master_reserve(ec_master_t *master)
    47 {
    46 {
    48     if (ioctl(master->fd, EC_IOCTL_REQUEST, NULL) == -1) {
    47     int ret = ioctl(master->fd, EC_IOCTL_REQUEST, NULL);
       
    48     if (EC_IOCTL_IS_ERROR(ret)) {
    49         fprintf(stderr, "Failed to reserve master: %s\n",
    49         fprintf(stderr, "Failed to reserve master: %s\n",
    50                 strerror(errno));
    50                 strerror(EC_IOCTL_ERRNO(ret)));
    51         return -1;
    51         return -EC_IOCTL_ERRNO(ret);
    52     }
    52     }
    53     return 0;
    53     return 0;
    54 }
    54 }
    55 
    55 
    56 /****************************************************************************/
    56 /****************************************************************************/
    86     }
    86     }
    87 
    87 
    88     ec_master_clear_config(master);
    88     ec_master_clear_config(master);
    89 
    89 
    90     if (master->fd != -1) {
    90     if (master->fd != -1) {
       
    91 #if USE_RTDM
       
    92         rt_dev_close(master->fd);
       
    93 #else
    91         close(master->fd);
    94         close(master->fd);
       
    95 #endif
    92     }
    96     }
    93 }
    97 }
    94 
    98 
    95 /****************************************************************************/
    99 /****************************************************************************/
    96 
   100 
   119         fprintf(stderr, "Failed to allocate memory.\n");
   123         fprintf(stderr, "Failed to allocate memory.\n");
   120         return 0;
   124         return 0;
   121     }
   125     }
   122 
   126 
   123     index = ioctl(master->fd, EC_IOCTL_CREATE_DOMAIN, NULL);
   127     index = ioctl(master->fd, EC_IOCTL_CREATE_DOMAIN, NULL);
   124     if (index == -1) {
   128     if (EC_IOCTL_IS_ERROR(index)) {
   125         fprintf(stderr, "Failed to create domain: %s\n", strerror(errno));
   129         fprintf(stderr, "Failed to create domain: %s\n",
       
   130                 strerror(EC_IOCTL_ERRNO(index)));
   126         free(domain);
   131         free(domain);
   127         return 0;
   132         return 0;
   128     }
   133     }
   129 
   134 
   130     domain->next = NULL;
   135     domain->next = NULL;
   158         uint16_t alias, uint16_t position, uint32_t vendor_id,
   163         uint16_t alias, uint16_t position, uint32_t vendor_id,
   159         uint32_t product_code)
   164         uint32_t product_code)
   160 {
   165 {
   161     ec_ioctl_config_t data;
   166     ec_ioctl_config_t data;
   162     ec_slave_config_t *sc;
   167     ec_slave_config_t *sc;
       
   168     int ret;
   163 
   169 
   164     sc = malloc(sizeof(ec_slave_config_t));
   170     sc = malloc(sizeof(ec_slave_config_t));
   165     if (!sc) {
   171     if (!sc) {
   166         fprintf(stderr, "Failed to allocate memory.\n");
   172         fprintf(stderr, "Failed to allocate memory.\n");
   167         return 0;
   173         return 0;
   170     data.alias = alias;
   176     data.alias = alias;
   171     data.position = position;
   177     data.position = position;
   172     data.vendor_id = vendor_id;
   178     data.vendor_id = vendor_id;
   173     data.product_code = product_code;
   179     data.product_code = product_code;
   174 
   180 
   175     if (ioctl(master->fd, EC_IOCTL_CREATE_SLAVE_CONFIG, &data) == -1) {
   181     ret = ioctl(master->fd, EC_IOCTL_CREATE_SLAVE_CONFIG, &data);
       
   182     if (EC_IOCTL_IS_ERROR(ret)) {
   176         fprintf(stderr, "Failed to create slave config: %s\n",
   183         fprintf(stderr, "Failed to create slave config: %s\n",
   177                 strerror(errno));
   184                 strerror(EC_IOCTL_ERRNO(ret)));
   178         free(sc);
   185         free(sc);
   179         return 0;
   186         return 0;
   180     }
   187     }
   181 
   188 
   182     sc->next = NULL;
   189     sc->next = NULL;
   192     return sc;
   199     return sc;
   193 }
   200 }
   194 
   201 
   195 /****************************************************************************/
   202 /****************************************************************************/
   196 
   203 
   197 int ecrt_master(ec_master_t* master, ec_master_info_t *master_info)
   204 int ecrt_master(ec_master_t *master, ec_master_info_t *master_info)
   198 {
   205 {
   199     ec_ioctl_master_t data;
   206     ec_ioctl_master_t data;
   200 
   207     int ret;
   201     if (ioctl(master->fd, EC_IOCTL_MASTER, &data) < 0) {
   208 
   202         fprintf(stderr, "Failed to get master info: %s\n", strerror(errno));
   209     ret = ioctl(master->fd, EC_IOCTL_MASTER, &data);
   203         return -1;
   210     if (EC_IOCTL_IS_ERROR(ret)) {
       
   211         fprintf(stderr, "Failed to get master info: %s\n",
       
   212                 strerror(EC_IOCTL_ERRNO(ret)));
       
   213         return -EC_IOCTL_ERRNO(ret);
   204     }
   214     }
   205 
   215 
   206     master_info->slave_count = data.slave_count;
   216     master_info->slave_count = data.slave_count;
   207     master_info->link_up = data.devices[0].link_state;
   217     master_info->link_up = data.devices[0].link_state;
   208     master_info->scan_busy = data.scan_busy;
   218     master_info->scan_busy = data.scan_busy;
   214 
   224 
   215 int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position,
   225 int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position,
   216         ec_slave_info_t *slave_info)
   226         ec_slave_info_t *slave_info)
   217 {
   227 {
   218     ec_ioctl_slave_t data;
   228     ec_ioctl_slave_t data;
   219     int i;
   229     int ret, i;
   220 
   230 
   221     data.position = slave_position;
   231     data.position = slave_position;
   222 
   232 
   223     if (ioctl(master->fd, EC_IOCTL_SLAVE, &data) == -1) {
   233     ret = ioctl(master->fd, EC_IOCTL_SLAVE, &data);
   224         fprintf(stderr, "Failed to get slave info: %s\n", strerror(errno));
   234     if (EC_IOCTL_IS_ERROR(ret)) {
   225         return -1;
   235         fprintf(stderr, "Failed to get slave info: %s\n",
       
   236                 strerror(EC_IOCTL_ERRNO(ret)));
       
   237         return -EC_IOCTL_ERRNO(ret);
   226     }
   238     }
   227 
   239 
   228     slave_info->position = data.position;
   240     slave_info->position = data.position;
   229     slave_info->vendor_id = data.vendor_id;
   241     slave_info->vendor_id = data.vendor_id;
   230     slave_info->product_code = data.product_code;
   242     slave_info->product_code = data.product_code;
   231     slave_info->revision_number = data.revision_number;
   243     slave_info->revision_number = data.revision_number;
   232     slave_info->serial_number = data.serial_number;
   244     slave_info->serial_number = data.serial_number;
   233     slave_info->alias = data.alias;
   245     slave_info->alias = data.alias;
   234     slave_info->current_on_ebus = data.current_on_ebus;
   246     slave_info->current_on_ebus = data.current_on_ebus;
   235     for ( i = 0; i < EC_MAX_PORTS; i++ ) {
   247     for (i = 0; i < EC_MAX_PORTS; i++) {
   236         slave_info->ports[i].desc = data.ports[i].desc;
   248         slave_info->ports[i].desc = data.ports[i].desc;
   237         slave_info->ports[i].link.link_up = data.ports[i].link.link_up;
   249         slave_info->ports[i].link.link_up = data.ports[i].link.link_up;
   238         slave_info->ports[i].link.loop_closed =
   250         slave_info->ports[i].link.loop_closed =
   239             data.ports[i].link.loop_closed;
   251             data.ports[i].link.loop_closed;
   240         slave_info->ports[i].link.signal_detected =
   252         slave_info->ports[i].link.signal_detected =
   256 
   268 
   257 int ecrt_master_get_sync_manager(ec_master_t *master, uint16_t slave_position,
   269 int ecrt_master_get_sync_manager(ec_master_t *master, uint16_t slave_position,
   258         uint8_t sync_index, ec_sync_info_t *sync)
   270         uint8_t sync_index, ec_sync_info_t *sync)
   259 {
   271 {
   260     ec_ioctl_slave_sync_t data;
   272     ec_ioctl_slave_sync_t data;
       
   273     int ret;
   261 
   274 
   262     if (sync_index >= EC_MAX_SYNC_MANAGERS) {
   275     if (sync_index >= EC_MAX_SYNC_MANAGERS) {
   263         return -ENOENT;
   276         return -ENOENT;
   264     }
   277     }
   265 
   278 
   266     memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_t));
   279     memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_t));
   267     data.slave_position = slave_position;
   280     data.slave_position = slave_position;
   268     data.sync_index = sync_index;
   281     data.sync_index = sync_index;
   269 
   282 
   270     if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC, &data) == -1) {
   283     ret = ioctl(master->fd, EC_IOCTL_SLAVE_SYNC, &data);
       
   284     if (EC_IOCTL_IS_ERROR(ret)) {
   271         fprintf(stderr, "Failed to get sync manager information: %s\n",
   285         fprintf(stderr, "Failed to get sync manager information: %s\n",
   272                 strerror(errno));
   286                 strerror(EC_IOCTL_ERRNO(ret)));
   273         return -1; // FIXME
   287         return -EC_IOCTL_ERRNO(ret);
   274     }
   288     }
   275 
   289 
   276     sync->index = sync_index;
   290     sync->index = sync_index;
   277     sync->dir = EC_READ_BIT(&data.control_register, 2) ?
   291     sync->dir = EC_READ_BIT(&data.control_register, 2) ?
   278         EC_DIR_OUTPUT : EC_DIR_INPUT;
   292         EC_DIR_OUTPUT : EC_DIR_INPUT;
   288 
   302 
   289 int ecrt_master_get_pdo(ec_master_t *master, uint16_t slave_position,
   303 int ecrt_master_get_pdo(ec_master_t *master, uint16_t slave_position,
   290         uint8_t sync_index, uint16_t pos, ec_pdo_info_t *pdo)
   304         uint8_t sync_index, uint16_t pos, ec_pdo_info_t *pdo)
   291 {
   305 {
   292     ec_ioctl_slave_sync_pdo_t data;
   306     ec_ioctl_slave_sync_pdo_t data;
       
   307     int ret;
   293 
   308 
   294     if (sync_index >= EC_MAX_SYNC_MANAGERS)
   309     if (sync_index >= EC_MAX_SYNC_MANAGERS)
   295         return -ENOENT;
   310         return -ENOENT;
   296 
   311 
   297     memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_pdo_t));
   312     memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_pdo_t));
   298     data.slave_position = slave_position;
   313     data.slave_position = slave_position;
   299     data.sync_index = sync_index;
   314     data.sync_index = sync_index;
   300     data.pdo_pos = pos;
   315     data.pdo_pos = pos;
   301 
   316 
   302     if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC_PDO, &data) == -1) {
   317     ret = ioctl(master->fd, EC_IOCTL_SLAVE_SYNC_PDO, &data);
       
   318     if (EC_IOCTL_IS_ERROR(ret)) {
   303         fprintf(stderr, "Failed to get pdo information: %s\n",
   319         fprintf(stderr, "Failed to get pdo information: %s\n",
   304                 strerror(errno));
   320                 strerror(EC_IOCTL_ERRNO(ret)));
   305         return -1; // FIXME
   321         return -EC_IOCTL_ERRNO(ret);
   306     }
   322     }
   307 
   323 
   308     pdo->index = data.index;
   324     pdo->index = data.index;
   309     pdo->n_entries = data.entry_count;
   325     pdo->n_entries = data.entry_count;
   310     pdo->entries = NULL;
   326     pdo->entries = NULL;
   317 int ecrt_master_get_pdo_entry(ec_master_t *master, uint16_t slave_position,
   333 int ecrt_master_get_pdo_entry(ec_master_t *master, uint16_t slave_position,
   318         uint8_t sync_index, uint16_t pdo_pos, uint16_t entry_pos,
   334         uint8_t sync_index, uint16_t pdo_pos, uint16_t entry_pos,
   319         ec_pdo_entry_info_t *entry)
   335         ec_pdo_entry_info_t *entry)
   320 {
   336 {
   321     ec_ioctl_slave_sync_pdo_entry_t data;
   337     ec_ioctl_slave_sync_pdo_entry_t data;
       
   338     int ret;
   322 
   339 
   323     if (sync_index >= EC_MAX_SYNC_MANAGERS)
   340     if (sync_index >= EC_MAX_SYNC_MANAGERS)
   324         return -ENOENT;
   341         return -ENOENT;
   325 
   342 
   326     memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_pdo_entry_t));
   343     memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_pdo_entry_t));
   327     data.slave_position = slave_position;
   344     data.slave_position = slave_position;
   328     data.sync_index = sync_index;
   345     data.sync_index = sync_index;
   329     data.pdo_pos = pdo_pos;
   346     data.pdo_pos = pdo_pos;
   330     data.entry_pos = entry_pos;
   347     data.entry_pos = entry_pos;
   331 
   348 
   332     if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC_PDO_ENTRY, &data) == -1) {
   349     ret = ioctl(master->fd, EC_IOCTL_SLAVE_SYNC_PDO_ENTRY, &data);
       
   350     if (EC_IOCTL_IS_ERROR(ret)) {
   333         fprintf(stderr, "Failed to get pdo entry information: %s\n",
   351         fprintf(stderr, "Failed to get pdo entry information: %s\n",
   334                 strerror(errno));
   352                 strerror(EC_IOCTL_ERRNO(ret)));
   335         return -1; // FIXME
   353         return -EC_IOCTL_ERRNO(ret);
   336     }
   354     }
   337 
   355 
   338     entry->index = data.index;
   356     entry->index = data.index;
   339     entry->subindex = data.subindex;
   357     entry->subindex = data.subindex;
   340     entry->bit_length = data.bit_length;
   358     entry->bit_length = data.bit_length;
   347 int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
   365 int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
   348         uint16_t index, uint8_t subindex, uint8_t *data,
   366         uint16_t index, uint8_t subindex, uint8_t *data,
   349         size_t data_size, uint32_t *abort_code)
   367         size_t data_size, uint32_t *abort_code)
   350 {
   368 {
   351     ec_ioctl_slave_sdo_download_t download;
   369     ec_ioctl_slave_sdo_download_t download;
       
   370     int ret;
   352 
   371 
   353     download.slave_position = slave_position;
   372     download.slave_position = slave_position;
   354     download.sdo_index = index;
   373     download.sdo_index = index;
   355     download.sdo_entry_subindex = subindex;
   374     download.sdo_entry_subindex = subindex;
   356     download.complete_access = 0;
   375     download.complete_access = 0;
   357     download.data_size = data_size;
   376     download.data_size = data_size;
   358     download.data = data;
   377     download.data = data;
   359 
   378 
   360     if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download) == -1) {
   379     ret = ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download);
   361         if (errno == EIO && abort_code) {
   380     if (EC_IOCTL_IS_ERROR(ret)) {
       
   381         if (EC_IOCTL_ERRNO(ret) == EIO && abort_code) {
   362             *abort_code = download.abort_code;
   382             *abort_code = download.abort_code;
   363         }
   383         }
   364         fprintf(stderr, "Failed to execute SDO download: %s\n",
   384         fprintf(stderr, "Failed to execute SDO download: %s\n",
   365             strerror(errno));
   385             strerror(EC_IOCTL_ERRNO(ret)));
   366         return -1;
   386         return -EC_IOCTL_ERRNO(ret);
   367     }
   387     }
   368 
   388 
   369     return 0;
   389     return 0;
   370 }
   390 }
   371 
   391 
   374 int ecrt_master_sdo_download_complete(ec_master_t *master,
   394 int ecrt_master_sdo_download_complete(ec_master_t *master,
   375         uint16_t slave_position, uint16_t index, uint8_t *data,
   395         uint16_t slave_position, uint16_t index, uint8_t *data,
   376         size_t data_size, uint32_t *abort_code)
   396         size_t data_size, uint32_t *abort_code)
   377 {
   397 {
   378     ec_ioctl_slave_sdo_download_t download;
   398     ec_ioctl_slave_sdo_download_t download;
       
   399     int ret;
   379 
   400 
   380     download.slave_position = slave_position;
   401     download.slave_position = slave_position;
   381     download.sdo_index = index;
   402     download.sdo_index = index;
   382     download.sdo_entry_subindex = 0;
   403     download.sdo_entry_subindex = 0;
   383     download.complete_access = 1;
   404     download.complete_access = 1;
   384     download.data_size = data_size;
   405     download.data_size = data_size;
   385     download.data = data;
   406     download.data = data;
   386 
   407 
   387     if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download) == -1) {
   408     ret = ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download);
   388         if (errno == EIO && abort_code) {
   409     if (EC_IOCTL_IS_ERROR(ret)) {
       
   410         if (EC_IOCTL_ERRNO(ret) == EIO && abort_code) {
   389             *abort_code = download.abort_code;
   411             *abort_code = download.abort_code;
   390         }
   412         }
   391         fprintf(stderr, "Failed to execute SDO download: %s\n",
   413         fprintf(stderr, "Failed to execute SDO download: %s\n",
   392             strerror(errno));
   414             strerror(EC_IOCTL_ERRNO(ret)));
   393         return -1;
   415         return -EC_IOCTL_ERRNO(ret);
   394     }
   416     }
   395 
   417 
   396     return 0;
   418     return 0;
   397 }
   419 }
   398 
   420 
   401 int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
   423 int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
   402         uint16_t index, uint8_t subindex, uint8_t *target,
   424         uint16_t index, uint8_t subindex, uint8_t *target,
   403         size_t target_size, size_t *result_size, uint32_t *abort_code)
   425         size_t target_size, size_t *result_size, uint32_t *abort_code)
   404 {
   426 {
   405     ec_ioctl_slave_sdo_upload_t upload;
   427     ec_ioctl_slave_sdo_upload_t upload;
       
   428     int ret;
   406 
   429 
   407     upload.slave_position = slave_position;
   430     upload.slave_position = slave_position;
   408     upload.sdo_index = index;
   431     upload.sdo_index = index;
   409     upload.sdo_entry_subindex = subindex;
   432     upload.sdo_entry_subindex = subindex;
   410     upload.target_size = target_size;
   433     upload.target_size = target_size;
   411     upload.target = target;
   434     upload.target = target;
   412 
   435 
   413     if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_UPLOAD, &upload) == -1) {
   436     ret = ioctl(master->fd, EC_IOCTL_SLAVE_SDO_UPLOAD, &upload);
   414         if (errno == EIO && abort_code) {
   437     if (EC_IOCTL_IS_ERROR(ret)) {
       
   438         if (EC_IOCTL_ERRNO(ret) == EIO && abort_code) {
   415             *abort_code = upload.abort_code;
   439             *abort_code = upload.abort_code;
   416         }
   440         }
   417         fprintf(stderr, "Failed to execute SDO upload: %s\n",
   441         fprintf(stderr, "Failed to execute SDO upload: %s\n",
   418                 strerror(errno));
   442                 strerror(EC_IOCTL_ERRNO(ret)));
   419         return -1;
   443         return -EC_IOCTL_ERRNO(ret);
   420     }
   444     }
   421 
   445 
   422     *result_size = upload.data_size;
   446     *result_size = upload.data_size;
   423     return 0;
   447     return 0;
   424 }
   448 }
   428 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
   452 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
   429         uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
   453         uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
   430         uint16_t *error_code)
   454         uint16_t *error_code)
   431 {
   455 {
   432     ec_ioctl_slave_soe_write_t io;
   456     ec_ioctl_slave_soe_write_t io;
       
   457     int ret;
   433 
   458 
   434     io.slave_position = slave_position;
   459     io.slave_position = slave_position;
   435     io.drive_no = drive_no;
   460     io.drive_no = drive_no;
   436     io.idn = idn;
   461     io.idn = idn;
   437     io.data_size = data_size;
   462     io.data_size = data_size;
   438     io.data = data;
   463     io.data = data;
   439 
   464 
   440     if (ioctl(master->fd, EC_IOCTL_SLAVE_SOE_WRITE, &io) == -1) {
   465     ret = ioctl(master->fd, EC_IOCTL_SLAVE_SOE_WRITE, &io);
   441         if (errno == EIO && error_code) {
   466     if (EC_IOCTL_IS_ERROR(ret)) {
       
   467         if (EC_IOCTL_ERRNO(ret) == EIO && error_code) {
   442             *error_code = io.error_code;
   468             *error_code = io.error_code;
   443         }
   469         }
   444         fprintf(stderr, "Failed to write IDN: %s\n", strerror(errno));
   470         fprintf(stderr, "Failed to write IDN: %s\n",
   445         return -1;
   471                 strerror(EC_IOCTL_ERRNO(ret)));
       
   472         return -EC_IOCTL_ERRNO(ret);
   446     }
   473     }
   447 
   474 
   448     return 0;
   475     return 0;
   449 }
   476 }
   450 
   477 
   453 int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
   480 int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
   454         uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size,
   481         uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size,
   455         size_t *result_size, uint16_t *error_code)
   482         size_t *result_size, uint16_t *error_code)
   456 {
   483 {
   457     ec_ioctl_slave_soe_read_t io;
   484     ec_ioctl_slave_soe_read_t io;
       
   485     int ret;
   458 
   486 
   459     io.slave_position = slave_position;
   487     io.slave_position = slave_position;
   460     io.drive_no = drive_no;
   488     io.drive_no = drive_no;
   461     io.idn = idn;
   489     io.idn = idn;
   462     io.mem_size = target_size;
   490     io.mem_size = target_size;
   463     io.data = target;
   491     io.data = target;
   464 
   492 
   465     if (ioctl(master->fd, EC_IOCTL_SLAVE_SOE_READ, &io) == -1) {
   493     ret = ioctl(master->fd, EC_IOCTL_SLAVE_SOE_READ, &io);
   466         if (errno == EIO && error_code) {
   494     if (EC_IOCTL_IS_ERROR(ret)) {
       
   495         if (EC_IOCTL_ERRNO(ret) == EIO && error_code) {
   467             *error_code = io.error_code;
   496             *error_code = io.error_code;
   468         }
   497         }
   469         fprintf(stderr, "Failed to read IDN: %s\n", strerror(errno));
   498         fprintf(stderr, "Failed to read IDN: %s\n",
   470         return -1;
   499                 strerror(EC_IOCTL_ERRNO(ret)));
       
   500         return -EC_IOCTL_ERRNO(ret);
   471     }
   501     }
   472 
   502 
   473     *result_size = io.data_size;
   503     *result_size = io.data_size;
   474     return 0;
   504     return 0;
   475 }
   505 }
   476 
   506 
   477 /****************************************************************************/
   507 /****************************************************************************/
   478 
   508 
   479 int ecrt_master_activate(ec_master_t *master)
   509 int ecrt_master_activate(ec_master_t *master)
   480 {
   510 {
   481     if (ioctl(master->fd, EC_IOCTL_ACTIVATE,
   511     ec_ioctl_master_activate_t io;
   482                 &master->process_data_size) == -1) {
   512     int ret;
       
   513 
       
   514     ret = ioctl(master->fd, EC_IOCTL_ACTIVATE, &io);
       
   515     if (EC_IOCTL_IS_ERROR(ret)) {
   483         fprintf(stderr, "Failed to activate master: %s\n",
   516         fprintf(stderr, "Failed to activate master: %s\n",
   484                 strerror(errno));
   517                 strerror(EC_IOCTL_ERRNO(ret)));
   485         return -1; // FIXME
   518         return -EC_IOCTL_ERRNO(ret);
   486     }
   519     }
       
   520 
       
   521     master->process_data_size = io.process_data_size;
   487 
   522 
   488     if (master->process_data_size) {
   523     if (master->process_data_size) {
       
   524 #ifdef USE_RTDM
       
   525         /* memory-mapping was already done in kernel. The user-space addess is
       
   526          * provided in the ioctl data.
       
   527          */
       
   528         master->process_data = io.process_data;
       
   529 #else
   489         master->process_data = mmap(0, master->process_data_size,
   530         master->process_data = mmap(0, master->process_data_size,
   490                 PROT_READ | PROT_WRITE, MAP_SHARED, master->fd, 0);
   531                 PROT_READ | PROT_WRITE, MAP_SHARED, master->fd, 0);
   491         if (master->process_data == MAP_FAILED) {
   532         if (master->process_data == MAP_FAILED) {
   492             fprintf(stderr, "Failed to map process data: %s",
   533             fprintf(stderr, "Failed to map process data: %s\n",
   493                     strerror(errno));
   534                     strerror(errno));
   494             master->process_data = NULL;
   535             master->process_data = NULL;
   495             master->process_data_size = 0;
   536             master->process_data_size = 0;
   496             return -1; // FIXME
   537             return -errno;
   497         }
   538         }
       
   539 #endif
   498 
   540 
   499         // Access the mapped region to cause the initial page fault
   541         // Access the mapped region to cause the initial page fault
   500         master->process_data[0] = 0x00;
   542         master->process_data[0] = 0x00;
   501     }
   543     }
   502 
   544 
   505 
   547 
   506 /****************************************************************************/
   548 /****************************************************************************/
   507 
   549 
   508 void ecrt_master_deactivate(ec_master_t *master)
   550 void ecrt_master_deactivate(ec_master_t *master)
   509 {
   551 {
   510     if (ioctl(master->fd, EC_IOCTL_DEACTIVATE, NULL) == -1) {
   552     int ret;
   511         fprintf(stderr, "Failed to deactivate master: %s\n", strerror(errno));
   553 
       
   554     ret = ioctl(master->fd, EC_IOCTL_DEACTIVATE, NULL);
       
   555     if (EC_IOCTL_IS_ERROR(ret)) {
       
   556         fprintf(stderr, "Failed to deactivate master: %s\n",
       
   557                 strerror(EC_IOCTL_ERRNO(ret)));
   512         return;
   558         return;
   513     }
   559     }
   514 
   560 
   515     ec_master_clear_config(master);
   561     ec_master_clear_config(master);
   516 }
   562 }
   518 /****************************************************************************/
   564 /****************************************************************************/
   519 
   565 
   520 int ecrt_master_set_send_interval(ec_master_t *master,
   566 int ecrt_master_set_send_interval(ec_master_t *master,
   521         size_t send_interval_us)
   567         size_t send_interval_us)
   522 {
   568 {
   523     if (ioctl(master->fd, EC_IOCTL_SET_SEND_INTERVAL,
   569     int ret;
   524                 &send_interval_us) == -1) {
   570 
       
   571     ret = ioctl(master->fd, EC_IOCTL_SET_SEND_INTERVAL, &send_interval_us);
       
   572     if (EC_IOCTL_IS_ERROR(ret)) {
   525         fprintf(stderr, "Failed to set send interval: %s\n",
   573         fprintf(stderr, "Failed to set send interval: %s\n",
   526                 strerror(errno));
   574                 strerror(EC_IOCTL_ERRNO(ret)));
   527         return -1; // FIXME
   575         return -EC_IOCTL_ERRNO(ret);
   528     }
   576     }
       
   577 
   529     return 0;
   578     return 0;
   530 }
   579 }
   531 
   580 
   532 /****************************************************************************/
   581 /****************************************************************************/
   533 
   582 
   534 void ecrt_master_send(ec_master_t *master)
   583 void ecrt_master_send(ec_master_t *master)
   535 {
   584 {
   536     if (ioctl(master->fd, EC_IOCTL_SEND, NULL) == -1) {
   585     int ret;
   537         fprintf(stderr, "Failed to send: %s\n", strerror(errno));
   586 
       
   587     ret = ioctl(master->fd, EC_IOCTL_SEND, NULL);
       
   588     if (EC_IOCTL_IS_ERROR(ret)) {
       
   589         fprintf(stderr, "Failed to send: %s\n",
       
   590                 strerror(EC_IOCTL_ERRNO(ret)));
   538     }
   591     }
   539 }
   592 }
   540 
   593 
   541 /****************************************************************************/
   594 /****************************************************************************/
   542 
   595 
   543 void ecrt_master_receive(ec_master_t *master)
   596 void ecrt_master_receive(ec_master_t *master)
   544 {
   597 {
   545     if (ioctl(master->fd, EC_IOCTL_RECEIVE, NULL) == -1) {
   598     int ret;
   546         fprintf(stderr, "Failed to receive: %s\n", strerror(errno));
   599 
       
   600     ret = ioctl(master->fd, EC_IOCTL_RECEIVE, NULL);
       
   601     if (EC_IOCTL_IS_ERROR(ret)) {
       
   602         fprintf(stderr, "Failed to receive: %s\n",
       
   603                 strerror(EC_IOCTL_ERRNO(ret)));
   547     }
   604     }
   548 }
   605 }
   549 
   606 
   550 /****************************************************************************/
   607 /****************************************************************************/
   551 
   608 
   552 void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
   609 void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
   553 {
   610 {
   554     if (ioctl(master->fd, EC_IOCTL_MASTER_STATE, state) == -1) {
   611     int ret;
   555         fprintf(stderr, "Failed to get master state: %s\n", strerror(errno));
   612 
       
   613     ret = ioctl(master->fd, EC_IOCTL_MASTER_STATE, state);
       
   614     if (EC_IOCTL_IS_ERROR(ret)) {
       
   615         fprintf(stderr, "Failed to get master state: %s\n",
       
   616                 strerror(EC_IOCTL_ERRNO(ret)));
   556     }
   617     }
   557 }
   618 }
   558 
   619 
   559 /****************************************************************************/
   620 /****************************************************************************/
   560 
   621 
   561 int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx,
   622 int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx,
   562         ec_master_link_state_t *state)
   623         ec_master_link_state_t *state)
   563 {
   624 {
   564     ec_ioctl_link_state_t io;
   625     ec_ioctl_link_state_t io;
       
   626     int ret;
   565 
   627 
   566     io.dev_idx = dev_idx;
   628     io.dev_idx = dev_idx;
   567     io.state = state;
   629     io.state = state;
   568     if (ioctl(master->fd, EC_IOCTL_MASTER_LINK_STATE, &io) == -1) {
   630 
   569         fprintf(stderr, "Failed to get link state: %s\n", strerror(errno));
   631     ret = ioctl(master->fd, EC_IOCTL_MASTER_LINK_STATE, &io);
   570         return -errno;
   632     if (EC_IOCTL_IS_ERROR(ret)) {
       
   633         fprintf(stderr, "Failed to get link state: %s\n",
       
   634                 strerror(EC_IOCTL_ERRNO(ret)));
       
   635         return -EC_IOCTL_ERRNO(ret);
   571     }
   636     }
   572 
   637 
   573     return 0;
   638     return 0;
   574 }
   639 }
   575 
   640 
   576 /****************************************************************************/
   641 /****************************************************************************/
   577 
   642 
   578 void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
   643 void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
   579 {
   644 {
   580     ec_ioctl_app_time_t data;
   645     ec_ioctl_app_time_t data;
       
   646     int ret;
   581 
   647 
   582     data.app_time = app_time;
   648     data.app_time = app_time;
   583 
   649 
   584     if (ioctl(master->fd, EC_IOCTL_APP_TIME, &data) == -1) {
   650     ret = ioctl(master->fd, EC_IOCTL_APP_TIME, &data);
       
   651     if (EC_IOCTL_IS_ERROR(ret)) {
   585         fprintf(stderr, "Failed to set application time: %s\n",
   652         fprintf(stderr, "Failed to set application time: %s\n",
   586                 strerror(errno));
   653                 strerror(EC_IOCTL_ERRNO(ret)));
   587     }
   654     }
   588 }
   655 }
   589 
   656 
   590 /****************************************************************************/
   657 /****************************************************************************/
   591 
   658 
   592 void ecrt_master_sync_reference_clock(ec_master_t *master)
   659 void ecrt_master_sync_reference_clock(ec_master_t *master)
   593 {
   660 {
   594     if (ioctl(master->fd, EC_IOCTL_SYNC_REF, NULL) == -1) {
   661     int ret;
       
   662 
       
   663     ret = ioctl(master->fd, EC_IOCTL_SYNC_REF, NULL);
       
   664     if (EC_IOCTL_IS_ERROR(ret)) {
   595         fprintf(stderr, "Failed to sync reference clock: %s\n",
   665         fprintf(stderr, "Failed to sync reference clock: %s\n",
   596                 strerror(errno));
   666                 strerror(EC_IOCTL_ERRNO(ret)));
   597     }
   667     }
   598 }
   668 }
   599 
   669 
   600 /****************************************************************************/
   670 /****************************************************************************/
   601 
   671 
   602 void ecrt_master_sync_slave_clocks(ec_master_t *master)
   672 void ecrt_master_sync_slave_clocks(ec_master_t *master)
   603 {
   673 {
   604     if (ioctl(master->fd, EC_IOCTL_SYNC_SLAVES, NULL) == -1) {
   674     int ret;
   605         fprintf(stderr, "Failed to sync slave clocks: %s\n", strerror(errno));
   675 
       
   676     ret = ioctl(master->fd, EC_IOCTL_SYNC_SLAVES, NULL);
       
   677     if (EC_IOCTL_IS_ERROR(ret)) {
       
   678         fprintf(stderr, "Failed to sync slave clocks: %s\n",
       
   679                 strerror(EC_IOCTL_ERRNO(ret)));
   606     }
   680     }
   607 }
   681 }
   608 
   682 
   609 /****************************************************************************/
   683 /****************************************************************************/
   610 
   684 
   611 void ecrt_master_sync_monitor_queue(ec_master_t *master)
   685 void ecrt_master_sync_monitor_queue(ec_master_t *master)
   612 {
   686 {
   613     if (ioctl(master->fd, EC_IOCTL_SYNC_MON_QUEUE, NULL) == -1) {
   687     int ret;
       
   688 
       
   689     ret = ioctl(master->fd, EC_IOCTL_SYNC_MON_QUEUE, NULL);
       
   690     if (EC_IOCTL_IS_ERROR(ret)) {
   614         fprintf(stderr, "Failed to queue sync monitor datagram: %s\n",
   691         fprintf(stderr, "Failed to queue sync monitor datagram: %s\n",
   615                 strerror(errno));
   692                 strerror(EC_IOCTL_ERRNO(ret)));
   616     }
   693     }
   617 }
   694 }
   618 
   695 
   619 /****************************************************************************/
   696 /****************************************************************************/
   620 
   697 
   621 uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
   698 uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
   622 {
   699 {
   623     uint32_t time_diff;
   700     uint32_t time_diff;
   624 
   701     int ret;
   625     if (ioctl(master->fd, EC_IOCTL_SYNC_MON_PROCESS, &time_diff) == -1) {
   702 
       
   703     ret = ioctl(master->fd, EC_IOCTL_SYNC_MON_PROCESS, &time_diff);
       
   704     if (EC_IOCTL_IS_ERROR(ret)) {
   626         time_diff = 0xffffffff;
   705         time_diff = 0xffffffff;
   627         fprintf(stderr, "Failed to process sync monitor datagram: %s\n",
   706         fprintf(stderr, "Failed to process sync monitor datagram: %s\n",
   628                 strerror(errno));
   707                 strerror(EC_IOCTL_ERRNO(ret)));
   629     }
   708     }
   630 
   709 
   631     return time_diff;
   710     return time_diff;
   632 }
   711 }
   633 
   712 
   634 /****************************************************************************/
   713 /****************************************************************************/
   635 
   714 
   636 void ecrt_master_reset(ec_master_t *master)
   715 void ecrt_master_reset(ec_master_t *master)
   637 {
   716 {
   638     if (ioctl(master->fd, EC_IOCTL_RESET, NULL) == -1) {
   717     int ret;
   639         fprintf(stderr, "Failed to reset master: %s\n", strerror(errno));
   718 
   640     }
   719     ret = ioctl(master->fd, EC_IOCTL_RESET, NULL);
   641 }
   720     if (EC_IOCTL_IS_ERROR(ret)) {
   642 
   721         fprintf(stderr, "Failed to reset master: %s\n",
   643 /****************************************************************************/
   722                 strerror(EC_IOCTL_ERRNO(ret)));
       
   723     }
       
   724 }
       
   725 
       
   726 /****************************************************************************/