examples/rtai_rtdm/main.c
changeset 2589 2b9c78543663
parent 2059 ab0b96ac18bb
equal deleted inserted replaced
2415:af21f0bdc7c9 2589:2b9c78543663
     1 /******************************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  *  $Id$
     3  *  $Id$
     4  *
     4  *
     5  *  main.c	        Copyright (C) 2011       IgH Andreas Stewering-Bone
     5  *  Copyright (C)      2011  IgH Andreas Stewering-Bone
     6  *
     6  *                     2012  Florian Pose <fp@igh-essen.com>
     7  *  This file is part of ethercatrtdm interface to IgH EtherCAT master 
     7  *
     8  *  
     8  *  This file is part of the IgH EtherCAT master
     9  *  The IgH EtherCAT master is free software; you can
       
    10  *  redistribute it and/or modify it under the terms of the GNU Lesser General
       
    11  *  Public License as published by the Free Software Foundation; version 2.1
       
    12  *  of the License.
       
    13  *
     9  *
    14  *  The IgH EtherCAT Master is free software; you can redistribute it and/or
    10  *  The IgH EtherCAT Master is free software; you can redistribute it and/or
    15  *  modify it under the terms of the GNU General Public License version 2, as
    11  *  modify it under the terms of the GNU General Public License version 2, as
    16  *  published by the Free Software Foundation.
    12  *  published by the Free Software Foundation.
    17  *
    13  *
    18  *  The IgH EtherCAT master userspace library is distributed in the hope that
    14  *  The IgH EtherCAT master is distributed in the hope that it will be useful,
    19  *  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    20  *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
    21  *  GNU Lesser General Public License for more details.
    17  *  Public License for more details.
    22  *
    18  *
    23  *  You should have received a copy of the GNU Lesser General Public License
    19  *  You should have received a copy of the GNU General Public License along
    24  *  along with the IgH EtherCAT master userspace library. If not, see
    20  *  with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>.
    25  *  <http://www.gnu.org/licenses/>.
    21  *
    26  *  
    22  *  ---
       
    23  *
    27  *  The license mentioned above concerns the source code only. Using the
    24  *  The license mentioned above concerns the source code only. Using the
    28  *  EtherCAT technology and brand is only permitted in compliance with the
    25  *  EtherCAT technology and brand is only permitted in compliance with the
    29  *  industrial property and similar rights of Beckhoff Automation GmbH.
    26  *  industrial property and similar rights of Beckhoff Automation GmbH.
    30  *
    27  *
    31  *****************************************************************************/
    28  *****************************************************************************/
    32 
       
    33 
       
    34 
       
    35 
    29 
    36 #include <sched.h>
    30 #include <sched.h>
    37 #include <stdio.h>
    31 #include <stdio.h>
    38 #include <stdlib.h>
    32 #include <stdlib.h>
    39 #include <fcntl.h>
    33 #include <fcntl.h>
    40 #include <signal.h>
    34 #include <signal.h>
    41 
    35 
    42 #include <rtai_lxrt.h>
    36 #include <rtai_lxrt.h>
    43 #include <rtdm/rtdm.h>
    37 #include <rtdm/rtdm.h>
    44 
    38 
    45 #include "../../include/ecrt.h"
    39 #include "ecrt.h"
    46 #include "../../include/ec_rtdm.h"
    40 
    47 
    41 #define rt_printf(X, Y)
    48 
       
    49 
       
    50 #define rt_printf(X,Y) 
       
    51 
    42 
    52 #define NSEC_PER_SEC 1000000000
    43 #define NSEC_PER_SEC 1000000000
    53 
    44 
    54 RT_TASK* task;    // Stores a handle.
    45 RT_TASK *task;
    55 int priority=0;   // Highest
    46 
    56 int stack_size=0; // Use default (512)
    47 const static unsigned int cycle_us = 1000; /* 1 ms */
    57 int msg_size=0;   // Use default (256)
    48 
    58 
    49 static int run = 1;
    59 static unsigned int cycle = 1000; /* 1 ms */
       
    60 
       
    61 int rt_fd = -1;
       
    62 int run=0;
       
    63 
       
    64 unsigned int sync_ref_counter = 0;
       
    65 
       
    66 CstructMstrAttach MstrAttach;
       
    67 
       
    68 /****************************************************************************/
       
    69 
       
    70 
       
    71 
       
    72 
       
    73 // Optional features
       
    74 #define CONFIGURE_PDOS  1
       
    75 
       
    76 
    50 
    77 /****************************************************************************/
    51 /****************************************************************************/
    78 
    52 
    79 // EtherCAT
    53 // EtherCAT
    80 static ec_master_t *master = NULL;
    54 static ec_master_t *master = NULL;
    81 static ec_master_state_t master_state = {};
    55 static ec_master_state_t master_state = {};
    82 
    56 
    83 static ec_domain_t *domain1 = NULL;
    57 static ec_domain_t *domain1 = NULL;
    84 static ec_domain_state_t domain1_state = {};
    58 static ec_domain_state_t domain1_state = {};
    85 
    59 
    86 
       
    87 /****************************************************************************/
       
    88 static uint8_t *domain1_pd = NULL;
    60 static uint8_t *domain1_pd = NULL;
    89 
    61 
       
    62 static ec_slave_config_t *sc_dig_out_01 = NULL;
       
    63 
       
    64 /****************************************************************************/
       
    65 
    90 // process data
    66 // process data
    91 
    67 
    92 #define BusCoupler01_Pos    0, 0
    68 #define BusCoupler01_Pos  0, 0
    93 #define DigOutSlave01_Pos   0, 1
    69 #define DigOutSlave01_Pos 0, 1
    94 #define DigOutSlave02_Pos   0, 2
       
    95 #define DigInSlave01_Pos    0, 3
       
    96 #define AnaOutSlave01_Pos   0, 4
       
    97 #define AnaInSlave01_Pos    0, 5
       
    98 #define BusCoupler02_Pos    0, 6
       
    99 #define AnaInSlave02_Pos    0, 7
       
   100 
       
   101 
    70 
   102 #define Beckhoff_EK1100 0x00000002, 0x044c2c52
    71 #define Beckhoff_EK1100 0x00000002, 0x044c2c52
   103 #define Beckhoff_EL1014 0x00000002, 0x03f63052
       
   104 #define Beckhoff_EL2004 0x00000002, 0x07d43052
    72 #define Beckhoff_EL2004 0x00000002, 0x07d43052
   105 #define Beckhoff_EL4132 0x00000002, 0x10243052
       
   106 #define Beckhoff_EL3102 0x00000002, 0x0c1e3052
       
   107 #define Beckhoff_EL4102 0x00000002, 0x10063052
       
   108 #define Beckhoff_EL6731 0x00000002, 0x1a4b3052
       
   109 #define Beckhoff_EL6600 0x00000002, 0x19c93052
       
   110 #define Beckhoff_EL3602 0x00000002, 0x0e123052
       
   111 #define Beckhoff_EL5151 0x00000002, 0x141f3052
       
   112 
       
   113 
    73 
   114 // offsets for PDO entries
    74 // offsets for PDO entries
   115 static unsigned int off_dig_out0      = 0;
    75 static unsigned int off_dig_out0 = 0;
   116 static unsigned int off_dig_out1      = 0;
       
   117 static unsigned int off_dig_out2      = 0;
       
   118 static unsigned int off_dig_out3      = 0;
       
   119 static unsigned int off_dig_in0       = 0;
       
   120 static unsigned int off_ana_out0      = 0;
       
   121 static unsigned int off_ana_out1      = 0;
       
   122 static unsigned int off_ana_in0_status = 0;
       
   123 static unsigned int off_ana_in0_value  = 0;
       
   124 static unsigned int off_ana_in1_status = 0;
       
   125 static unsigned int off_ana_in1_value  = 0;
       
   126 
       
   127 
    76 
   128 // process data
    77 // process data
   129 unsigned int bit_position0=0; /* Pointer to a variable to store a bit */
       
   130 unsigned int bit_position1=0; /* Pointer to a variable to store a bit */
       
   131 unsigned int bit_position2=0; /* Pointer to a variable to store a bit */
       
   132 unsigned int bit_position3=0; /* Pointer to a variable to store a bit */
       
   133 
    78 
   134 const static ec_pdo_entry_reg_t domain1_regs[] = {
    79 const static ec_pdo_entry_reg_t domain1_regs[] = {
   135    {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7000, 0x01, &off_dig_out0, &bit_position0},
    80    {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7000, 0x01, &off_dig_out0, NULL},
   136    {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7010, 0x01, &off_dig_out1, &bit_position1},
       
   137    {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7020, 0x01, &off_dig_out2, &bit_position2},
       
   138    {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7030, 0x01, &off_dig_out3, &bit_position3},
       
   139    {DigInSlave01_Pos,  Beckhoff_EL1014, 0x6000, 0x01, &off_dig_in0},
       
   140    {AnaOutSlave01_Pos, Beckhoff_EL4132, 0x3001, 0x01, &off_ana_out0},
       
   141    {AnaOutSlave01_Pos, Beckhoff_EL4132, 0x3002, 0x01, &off_ana_out1},
       
   142    {AnaInSlave01_Pos,  Beckhoff_EL3102, 0x3101, 0x01, &off_ana_in0_status},
       
   143    {AnaInSlave01_Pos,  Beckhoff_EL3102, 0x3101, 0x02, &off_ana_in0_value},
       
   144    {AnaInSlave01_Pos,  Beckhoff_EL3102, 0x3102, 0x01, &off_ana_in1_status},
       
   145    {AnaInSlave01_Pos,  Beckhoff_EL3102, 0x3102, 0x02, &off_ana_in1_value},
       
   146    {}
    81    {}
   147 };
    82 };
   148 
    83 
   149 char rt_dev_file[64];
    84 /****************************************************************************/
   150 static unsigned int blink = 0;
       
   151 
       
   152 static ec_slave_config_t *sc_dig_out_01 = NULL;
       
   153 
       
   154 static ec_slave_config_t *sc_dig_out_02 = NULL;
       
   155 
       
   156 static ec_slave_config_t *sc_dig_in_01 = NULL;
       
   157 
       
   158 static ec_slave_config_t *sc_ana_out_01 = NULL;
       
   159 
       
   160 static ec_slave_config_t *sc_ana_in_01 = NULL;
       
   161 
       
   162 static ec_slave_config_t *sc_ana_in_02 = NULL;
       
   163 
       
   164 /*****************************************************************************/
       
   165 
    85 
   166 /* Slave 1, "EL2004"
    86 /* Slave 1, "EL2004"
   167  * Vendor ID:       0x00000002
    87  * Vendor ID:       0x00000002
   168  * Product code:    0x07d43052
    88  * Product code:    0x07d43052
   169  * Revision number: 0x00100000
    89  * Revision number: 0x00100000
   186 ec_sync_info_t slave_1_syncs[] = {
   106 ec_sync_info_t slave_1_syncs[] = {
   187    {0, EC_DIR_OUTPUT, 4, slave_1_pdos + 0, EC_WD_ENABLE},
   107    {0, EC_DIR_OUTPUT, 4, slave_1_pdos + 0, EC_WD_ENABLE},
   188    {0xff}
   108    {0xff}
   189 };
   109 };
   190 
   110 
   191 /* Slave 2, "EL2004"
   111 /*****************************************************************************
   192  * Vendor ID:       0x00000002
   112  * Realtime task
   193  * Product code:    0x07d43052
   113  ****************************************************************************/
   194  * Revision number: 0x00100000
       
   195  */
       
   196 
       
   197 ec_pdo_entry_info_t slave_2_pdo_entries[] = {
       
   198    {0x7000, 0x01, 1}, /* Output */
       
   199    {0x7010, 0x01, 1}, /* Output */
       
   200    {0x7020, 0x01, 1}, /* Output */
       
   201    {0x7030, 0x01, 1}, /* Output */
       
   202 };
       
   203 
       
   204 ec_pdo_info_t slave_2_pdos[] = {
       
   205    {0x1600, 1, slave_2_pdo_entries + 0}, /* Channel 1 */
       
   206    {0x1601, 1, slave_2_pdo_entries + 1}, /* Channel 2 */
       
   207    {0x1602, 1, slave_2_pdo_entries + 2}, /* Channel 3 */
       
   208    {0x1603, 1, slave_2_pdo_entries + 3}, /* Channel 4 */
       
   209 };
       
   210 
       
   211 ec_sync_info_t slave_2_syncs[] = {
       
   212    {0, EC_DIR_OUTPUT, 4, slave_2_pdos + 0, EC_WD_ENABLE},
       
   213    {0xff}
       
   214 };
       
   215 
       
   216 /* Slave 3, "EL1014"
       
   217  * Vendor ID:       0x00000002
       
   218  * Product code:    0x03f63052
       
   219  * Revision number: 0x00100000
       
   220  */
       
   221 
       
   222 ec_pdo_entry_info_t slave_3_pdo_entries[] = {
       
   223    {0x6000, 0x01, 1}, /* Input */
       
   224    {0x6010, 0x01, 1}, /* Input */
       
   225    {0x6020, 0x01, 1}, /* Input */
       
   226    {0x6030, 0x01, 1}, /* Input */
       
   227 };
       
   228 
       
   229 ec_pdo_info_t slave_3_pdos[] = {
       
   230    {0x1a00, 1, slave_3_pdo_entries + 0}, /* Channel 1 */
       
   231    {0x1a01, 1, slave_3_pdo_entries + 1}, /* Channel 2 */
       
   232    {0x1a02, 1, slave_3_pdo_entries + 2}, /* Channel 3 */
       
   233    {0x1a03, 1, slave_3_pdo_entries + 3}, /* Channel 4 */
       
   234 };
       
   235 
       
   236 ec_sync_info_t slave_3_syncs[] = {
       
   237    {0, EC_DIR_INPUT, 4, slave_3_pdos + 0, EC_WD_DISABLE},
       
   238    {0xff}
       
   239 };
       
   240 
       
   241 /* Slave 4, "EL4132"
       
   242  * Vendor ID:       0x00000002
       
   243  * Product code:    0x10243052
       
   244  * Revision number: 0x03f90000
       
   245  */
       
   246 
       
   247 ec_pdo_entry_info_t slave_4_pdo_entries[] = {
       
   248    {0x3001, 0x01, 16}, /* Output */
       
   249    {0x3002, 0x01, 16}, /* Output */
       
   250 };
       
   251 
       
   252 ec_pdo_info_t slave_4_pdos[] = {
       
   253    {0x1600, 1, slave_4_pdo_entries + 0}, /* RxPDO 01 mapping */
       
   254    {0x1601, 1, slave_4_pdo_entries + 1}, /* RxPDO 02 mapping */
       
   255 };
       
   256 
       
   257 ec_sync_info_t slave_4_syncs[] = {
       
   258    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   259    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   260    {2, EC_DIR_OUTPUT, 2, slave_4_pdos + 0, EC_WD_DISABLE},
       
   261    {3, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   262    {0xff}
       
   263 };
       
   264 
       
   265 /* Slave 5, "EL3102"
       
   266  * Vendor ID:       0x00000002
       
   267  * Product code:    0x0c1e3052
       
   268  * Revision number: 0x00000000
       
   269  */
       
   270 
       
   271 ec_pdo_entry_info_t slave_5_pdo_entries[] = {
       
   272    {0x3101, 0x01, 8}, /* Status */
       
   273    {0x3101, 0x02, 16}, /* Value */
       
   274    {0x3102, 0x01, 8}, /* Status */
       
   275    {0x3102, 0x02, 16}, /* Value */
       
   276 };
       
   277 
       
   278 ec_pdo_info_t slave_5_pdos[] = {
       
   279    {0x1a00, 2, slave_5_pdo_entries + 0}, /* TxPDO 001 mapping */
       
   280    {0x1a01, 2, slave_5_pdo_entries + 2}, /* TxPDO 002 mapping */
       
   281 };
       
   282 
       
   283 ec_sync_info_t slave_5_syncs[] = {
       
   284    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   285    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   286    {2, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   287    {3, EC_DIR_INPUT, 2, slave_5_pdos + 0, EC_WD_DISABLE},
       
   288    {0xff}
       
   289 };
       
   290 
       
   291 /* Slave 6, "EL6731-0010"
       
   292  * Vendor ID:       0x00000002
       
   293  * Product code:    0x1a4b3052
       
   294  * Revision number: 0x0011000a
       
   295  */
       
   296 
       
   297 ec_sync_info_t slave_6_syncs[] = {
       
   298    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   299    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   300    {2, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   301    {3, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   302 };
       
   303 
       
   304 
       
   305 /* Slave 7, "EL6601"
       
   306  * Vendor ID:       0x00000002
       
   307  * Product code:    0x19c93052
       
   308  * Revision number: 0x00110000
       
   309  */
       
   310 /*
       
   311 ec_sync_info_t slave_7_syncs[] = {
       
   312    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   313    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   314    {2, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   315    {3, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   316    {0xff}
       
   317 };
       
   318 */
       
   319 
       
   320 /* Master 0, Slave 7, "EL3602"
       
   321  * Vendor ID:       0x00000002
       
   322  * Product code:    0x0e123052
       
   323  * Revision number: 0x00100000
       
   324  */
       
   325 ec_pdo_entry_info_t slave_7_pdo_entries[] = {
       
   326    {0x6000, 0x01, 1}, /* Underrange */
       
   327    {0x6000, 0x02, 1}, /* Overrange */
       
   328    {0x6000, 0x03, 2}, /* Limit 1 */
       
   329    {0x6000, 0x05, 2}, /* Limit 2 */
       
   330    {0x6000, 0x07, 1}, /* Error */
       
   331    {0x0000, 0x00, 7}, /* Gap */
       
   332    {0x1800, 0x07, 1},
       
   333    {0x1800, 0x09, 1},
       
   334    {0x6000, 0x11, 32}, /* Value */
       
   335    {0x6010, 0x01, 1}, /* Underrange */
       
   336    {0x6010, 0x02, 1}, /* Overrange */
       
   337    {0x6010, 0x03, 2}, /* Limit 1 */
       
   338    {0x6010, 0x05, 2}, /* Limit 2 */
       
   339    {0x6010, 0x07, 1}, /* Error */
       
   340    {0x0000, 0x00, 7}, /* Gap */
       
   341    {0x1801, 0x07, 1},
       
   342    {0x1801, 0x09, 1},
       
   343    {0x6010, 0x11, 32}, /* Value */
       
   344 };
       
   345 
       
   346 ec_pdo_info_t slave_7_pdos[] = {
       
   347    {0x1a00, 9, slave_7_pdo_entries + 0}, /* AI TxPDO-Map Inputs Ch.1 */
       
   348    {0x1a01, 9, slave_7_pdo_entries + 9}, /* AI TxPDO-Map Inputs Ch.2 */
       
   349 };
       
   350 
       
   351 ec_sync_info_t slave_7_syncs[] = {
       
   352    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   353    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   354    {2, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   355    {3, EC_DIR_INPUT, 2, slave_7_pdos + 0, EC_WD_DISABLE},
       
   356    {0xff}
       
   357 };
       
   358 
       
   359 /* Master 0, Slave 8, "EL5151"
       
   360  * Vendor ID:       0x00000002
       
   361  * Product code:    0x141f3052
       
   362  * Revision number: 0x00130000
       
   363  */
       
   364 
       
   365 ec_pdo_entry_info_t slave_8_pdo_entries[] = {
       
   366    {0x6000, 0x01, 1},
       
   367    {0x6000, 0x02, 1},
       
   368    {0x6000, 0x03, 1},
       
   369    {0x0000, 0x00, 4}, /* Gap */
       
   370    {0x6000, 0x08, 1},
       
   371    {0x6000, 0x09, 1},
       
   372    {0x6000, 0x0a, 1},
       
   373    {0x6000, 0x0b, 1},
       
   374    {0x0000, 0x00, 1}, /* Gap */
       
   375    {0x6000, 0x0d, 1},
       
   376    {0x1c32, 0x20, 1},
       
   377    {0x0000, 0x00, 1}, /* Gap */
       
   378    {0x1800, 0x09, 1},
       
   379    {0x6000, 0x11, 32},
       
   380    {0x6000, 0x12, 32},
       
   381    {0x6000, 0x14, 32},
       
   382 };
       
   383 
       
   384 ec_pdo_info_t slave_8_pdos[] = {
       
   385    {0x0000, 0, NULL},
       
   386    {0x1a00, 15, slave_8_pdo_entries + 0},
       
   387    {0x1a02, 1, slave_8_pdo_entries + 15},
       
   388 };
       
   389 
       
   390 ec_sync_info_t slave_8_syncs[] = {
       
   391    {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
       
   392    {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
       
   393    {2, EC_DIR_OUTPUT, 1, slave_8_pdos + 0, EC_WD_DISABLE},
       
   394    {3, EC_DIR_INPUT, 2, slave_8_pdos + 1, EC_WD_DISABLE},
       
   395    {0xff}
       
   396 };
       
   397 
       
   398 
       
   399 /*****************************************************************************/
       
   400 
       
   401 
   114 
   402 void rt_check_domain_state(void)
   115 void rt_check_domain_state(void)
   403 {
   116 {
   404     ec_domain_state_t ds;
   117     ec_domain_state_t ds = {};
   405 
   118 
   406     if (rt_fd>=0)
   119     ecrt_domain_state(domain1, &ds);
   407       {
   120 
   408           ecrt_rtdm_domain_state(rt_fd,&ds);  
   121     if (ds.working_counter != domain1_state.working_counter) {
   409       }
       
   410 
       
   411     if (ds.working_counter != domain1_state.working_counter)
       
   412      {
       
   413         rt_printf("Domain1: WC %u.\n", ds.working_counter);
   122         rt_printf("Domain1: WC %u.\n", ds.working_counter);
   414      }
   123     }
   415     if (ds.wc_state != domain1_state.wc_state)
   124 
   416      {
   125     if (ds.wc_state != domain1_state.wc_state) {
   417     	rt_printf("Domain1: State %u.\n", ds.wc_state);
   126         rt_printf("Domain1: State %u.\n", ds.wc_state);
   418      }
   127     }
   419 
   128 
   420     domain1_state = ds;
   129     domain1_state = ds;
   421 }
   130 }
   422 
   131 
       
   132 /****************************************************************************/
       
   133 
   423 void rt_check_master_state(void)
   134 void rt_check_master_state(void)
   424 {
   135 {
   425     ec_master_state_t ms;
   136     ec_master_state_t ms;
   426 
   137 
   427     if (rt_fd>=0)
   138     ecrt_master_state(master, &ms);
   428       {
   139 
   429           ecrt_rtdm_master_state(rt_fd,&ms);
   140     if (ms.slaves_responding != master_state.slaves_responding) {
   430       }
       
   431 
       
   432     if (ms.slaves_responding != master_state.slaves_responding)
       
   433     {
       
   434         rt_printf("%u slave(s).\n", ms.slaves_responding);
   141         rt_printf("%u slave(s).\n", ms.slaves_responding);
   435     }
   142     }
   436     if (ms.al_states != master_state.al_states)
   143 
   437     {
   144     if (ms.al_states != master_state.al_states) {
   438         rt_printf("AL states: 0x%02X.\n", ms.al_states);
   145         rt_printf("AL states: 0x%02X.\n", ms.al_states);
   439     }
   146     }
   440     if (ms.link_up != master_state.link_up)
   147 
   441     {
   148     if (ms.link_up != master_state.link_up) {
   442         rt_printf("Link is %s.\n", ms.link_up ? "up" : "down");
   149         rt_printf("Link is %s.\n", ms.link_up ? "up" : "down");
   443     }
   150     }
       
   151 
   444     master_state = ms;
   152     master_state = ms;
   445 }
   153 }
   446 
   154 
   447 
   155 /****************************************************************************/
   448 
       
   449 
       
   450 void rt_sync(void)
       
   451 {
       
   452 
       
   453   RTIME now_ns;
       
   454   uint64_t now;
       
   455   now_ns = rt_get_cpu_time_ns();
       
   456   now = (uint64_t)now_ns;
       
   457 
       
   458   if (rt_fd>=0)
       
   459   {
       
   460       ecrt_rtdm_master_application_time(rt_fd, &now);
       
   461   }
       
   462 
       
   463   if (sync_ref_counter) {
       
   464      sync_ref_counter--;
       
   465   } else {
       
   466      sync_ref_counter = 9;
       
   467      if (rt_fd>=0)
       
   468      {
       
   469          ecrt_rtdm_master_sync_reference_clock(rt_fd);
       
   470      }
       
   471   }
       
   472   if (rt_fd>=0)
       
   473   {
       
   474       ecrt_rtdm_master_sync_slave_clocks(rt_fd) ;
       
   475   }
       
   476 }
       
   477 
       
   478 /*****************************************************************************/
       
   479 
       
   480 /**********************************************************/
       
   481 void cleanup_all(void)
       
   482 {
       
   483     run = 0;   
       
   484 }
       
   485 
       
   486 void catch_signal(int sig)
       
   487 {
       
   488     cleanup_all();    
       
   489 }
       
   490 
       
   491 
       
   492 
       
   493 
       
   494 
   156 
   495 void my_cyclic(void)
   157 void my_cyclic(void)
   496 {
   158 {
   497 
   159     int cycle_counter = 0;
   498     int counter = 0;
       
   499     int divcounter = 0;
       
   500     int divider = 10;
       
   501     int period;
   160     int period;
       
   161     unsigned int blink = 0;
   502 
   162 
   503     rt_set_periodic_mode();
   163     rt_set_periodic_mode();
   504     period = (int) nano2count((RTIME)cycle*1000);
   164     period = (int) nano2count((RTIME) cycle_us * 1000);
   505     start_rt_timer(period);
   165     start_rt_timer(period);
   506     rt_make_hard_real_time();
   166     rt_make_hard_real_time();
   507     rt_task_make_periodic(task, rt_get_time() + 10*period, period);
   167     rt_task_make_periodic(task, rt_get_time() + 10 * period, period);
   508 
   168 
   509 
   169     while (run) {
   510 
       
   511     while(1) {
       
   512  
       
   513         rt_task_wait_period();
   170         rt_task_wait_period();
   514 
   171 
   515 
   172         cycle_counter++;
   516         counter++;
   173 
   517         if (counter>60000) {
   174         // receive EtherCAT
   518             run=0;
   175         ecrt_master_receive(master);
       
   176         ecrt_domain_process(domain1);
       
   177 
       
   178         rt_check_domain_state();
       
   179 
       
   180         if (!(cycle_counter % 1000)) {
       
   181             rt_check_master_state();
   519         }
   182         }
   520 
   183 
   521         if(run ==  0) {
   184         if (!(cycle_counter % 200)) {
   522             rt_make_soft_real_time();
   185             blink = !blink;
   523             stop_rt_timer();
       
   524             return;
       
   525         }
   186         }
   526 
   187 
   527         
   188         EC_WRITE_U8(domain1_pd + off_dig_out0, blink ? 0x00 : 0x0F);
   528         // receive ethercat
   189 
   529         ecrt_rtdm_master_recieve(rt_fd);
       
   530         ecrt_rtdm_domain_process(rt_fd);
       
   531         
       
   532         rt_check_domain_state();
       
   533         
       
   534         if (divcounter ==0)
       
   535             {
       
   536                 divcounter=divider;
       
   537                 rt_check_master_state();
       
   538             }
       
   539         divcounter--;
       
   540         if ((counter % 200)==0)
       
   541             {
       
   542                 blink = !blink;
       
   543                 
       
   544             }
       
   545       
       
   546 
       
   547         EC_WRITE_U8(domain1_pd + off_dig_out0, blink ? 0x0 : 0x0F);
       
   548         EC_WRITE_U16(domain1_pd + off_ana_out0, blink ? 0x0: 0xfff);
       
   549         
       
   550         //sync DC
       
   551         rt_sync();
       
   552         
       
   553         // send process data
   190         // send process data
   554         ecrt_rtdm_domain_queque(rt_fd);
   191         ecrt_domain_queue(domain1);
   555         ecrt_rtdm_master_send(rt_fd);   
   192         ecrt_master_send(master);
   556     }
   193     }
   557     return;
   194 
   558 }
   195     rt_make_soft_real_time();
   559 
   196     stop_rt_timer();
   560 
   197 }
       
   198 
       
   199 /****************************************************************************
       
   200  * Signal handler
       
   201  ***************************************************************************/
       
   202 
       
   203 void signal_handler(int sig)
       
   204 {
       
   205     run = 0;
       
   206 }
       
   207 
       
   208 /****************************************************************************
       
   209  * Main function
       
   210  ***************************************************************************/
   561 
   211 
   562 int main(int argc, char *argv[])
   212 int main(int argc, char *argv[])
   563 {
   213 {
   564     ec_slave_config_t *sc;
   214     ec_slave_config_t *sc;
   565     int rtstatus;
   215 
   566 
   216     signal(SIGTERM, signal_handler);
   567 
   217     signal(SIGINT, signal_handler);
   568 
   218 
   569     signal(SIGTERM, catch_signal);
   219     mlockall(MCL_CURRENT | MCL_FUTURE);
   570     signal(SIGINT, catch_signal);
   220 
   571     signal(SIGHUP, catch_signal);
   221     printf("Requesting master...\n");
   572 
   222     master = ecrt_request_master(0);
   573     mlockall(MCL_CURRENT|MCL_FUTURE);
   223     if (!master) {
   574 
   224         return -1;
   575 
   225     }
   576 
   226 
   577     MstrAttach.masterindex = 0;
       
   578     
       
   579     printf("request master\n");
       
   580     master = ecrt_request_master(MstrAttach.masterindex);
       
   581     if (!master)
       
   582         return -1;
       
   583     
       
   584     
       
   585     domain1 = ecrt_master_create_domain(master);
   227     domain1 = ecrt_master_create_domain(master);
   586     if (!domain1)
   228     if (!domain1) {
   587         return -1;
   229         return -1;
   588     
   230     }
   589     
   231 
   590 #ifdef CONFIGURE_PDOS
   232     printf("Creating slave configurations...\n");
   591 
   233 
   592     printf("Configuring PDOs...\n");
   234     // Create configuration for bus coupler
   593     
   235     sc = ecrt_master_slave_config(master, BusCoupler01_Pos, Beckhoff_EK1100);
   594     printf("Get Configuring el2004...\n");
   236     if (!sc) {
   595     sc_dig_out_01 = ecrt_master_slave_config(master, DigOutSlave01_Pos, Beckhoff_EL2004);
   237         return -1;
       
   238     }
       
   239 
       
   240     sc_dig_out_01 =
       
   241         ecrt_master_slave_config(master, DigOutSlave01_Pos, Beckhoff_EL2004);
   596     if (!sc_dig_out_01) {
   242     if (!sc_dig_out_01) {
   597         fprintf(stderr, "Failed to get slave configuration.\n");
   243         fprintf(stderr, "Failed to get slave configuration.\n");
   598         return -1;
   244         return -1;
   599     }
   245     }
   600     
   246 
   601     printf("Configuring EL2004...\n");
   247     if (ecrt_slave_config_pdos(sc_dig_out_01, EC_END, slave_1_syncs)) {
   602     if (ecrt_slave_config_pdos(sc_dig_out_01, EC_END, slave_1_syncs))
       
   603         {
       
   604             fprintf(stderr, "Failed to configure PDOs.\n");
       
   605             return -1;
       
   606         }
       
   607     
       
   608     printf("Get Configuring el2004...\n");
       
   609     sc_dig_out_02 = ecrt_master_slave_config(master, DigOutSlave02_Pos, Beckhoff_EL2004);
       
   610     if (!sc_dig_out_02) {
       
   611         fprintf(stderr, "Failed to get slave configuration.\n");
       
   612         return -1;
       
   613     }
       
   614 
       
   615     printf("Configuring EL2004...\n");
       
   616     if (ecrt_slave_config_pdos(sc_dig_out_02, EC_END, slave_2_syncs)) {
       
   617         fprintf(stderr, "Failed to configure PDOs.\n");
   248         fprintf(stderr, "Failed to configure PDOs.\n");
   618         return -1;
   249         return -1;
   619     }
   250     }
   620     
   251 
   621     printf("Get Configuring el1014...\n");
       
   622     sc_dig_in_01 = ecrt_master_slave_config(master, DigInSlave01_Pos, Beckhoff_EL1014);
       
   623     if (!sc_dig_in_01) {
       
   624         fprintf(stderr, "Failed to get slave configuration.\n");
       
   625         return -1;
       
   626     }
       
   627     
       
   628     printf("Configuring EL1014...\n");
       
   629     if (ecrt_slave_config_pdos(sc_dig_in_01, EC_END, slave_3_syncs)) {
       
   630         fprintf(stderr, "Failed to configure PDOs.\n");
       
   631         return -1;
       
   632     }
       
   633 
       
   634     printf("Get Configuring EL4132...\n");
       
   635     sc_ana_out_01 = ecrt_master_slave_config(master, AnaOutSlave01_Pos, Beckhoff_EL4132);
       
   636     if (!sc_ana_out_01) {
       
   637         fprintf(stderr, "Failed to get slave configuration.\n");
       
   638         return -1;
       
   639     }
       
   640 
       
   641     printf("Configuring EL4132...\n");
       
   642     if (ecrt_slave_config_pdos(sc_ana_out_01, EC_END, slave_4_syncs)) {
       
   643         fprintf(stderr, "Failed to configure PDOs.\n");
       
   644         return -1;
       
   645     }
       
   646 
       
   647     printf("Get Configuring EL3102...\n");
       
   648     sc_ana_in_01 = ecrt_master_slave_config(master, AnaInSlave01_Pos, Beckhoff_EL3102);
       
   649     if (!sc_ana_in_01) {
       
   650         fprintf(stderr, "Failed to get slave configuration.\n");
       
   651         return -1;
       
   652     }
       
   653 
       
   654     printf("Configuring EL3102...\n");
       
   655     if (ecrt_slave_config_pdos(sc_ana_in_01, EC_END, slave_5_syncs)) {
       
   656         fprintf(stderr, "Failed to configure PDOs.\n");
       
   657         return -1;
       
   658     }
       
   659 
       
   660     printf("Get Configuring EL3602...\n");
       
   661 	sc_ana_in_02 = ecrt_master_slave_config(master, AnaInSlave02_Pos, Beckhoff_EL3602);
       
   662 	if (!sc_ana_in_02) {
       
   663         fprintf(stderr, "Failed to get slave configuration.\n");
       
   664         return -1;
       
   665 	}
       
   666     
       
   667 
       
   668 	printf("Configuring EL3602...\n");
       
   669 	if (ecrt_slave_config_pdos(sc_ana_in_02, EC_END, slave_7_syncs)) {
       
   670         fprintf(stderr, "Failed to configure PDOs.\n");
       
   671         return -1;
       
   672 	}
       
   673     
       
   674 #endif
       
   675     
       
   676     // Create configuration for bus coupler
       
   677     sc = ecrt_master_slave_config(master, BusCoupler01_Pos, Beckhoff_EK1100);
       
   678     if (!sc)
       
   679         return -1;
       
   680     
       
   681 #ifdef CONFIGURE_PDOS
       
   682     if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
   252     if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
   683         fprintf(stderr, "PDO entry registration failed!\n");
   253         fprintf(stderr, "PDO entry registration failed!\n");
   684         return -1;
   254         return -1;
   685     }
   255     }
   686 #endif
   256 
   687 
       
   688 
       
   689         
       
   690     sprintf(&rt_dev_file[0],"%s%u",EC_RTDM_DEV_FILE_NAME,0);
       
   691     
       
   692     
       
   693     rt_fd = rt_dev_open( &rt_dev_file[0], 0);
       
   694     if (rt_fd < 0) {
       
   695         printf("can't open %s\n", &rt_dev_file[0]);
       
   696         return -1;
       
   697     }
       
   698     
       
   699     MstrAttach.domainindex = ecrt_domain_index(domain1);
       
   700     
       
   701     // attach the master over rtdm driver
       
   702     rtstatus=ecrt_rtdm_master_attach(rt_fd, &MstrAttach);
       
   703     if (rtstatus < 0)
       
   704         {
       
   705             printf("cannot attach to master over rtdm\n");
       
   706             return -1;
       
   707         }
       
   708     
       
   709     printf("Activating master...\n");
   257     printf("Activating master...\n");
   710     if (ecrt_master_activate(master))
   258     if (ecrt_master_activate(master)) {
   711         return -1;
   259         return -1;
   712     
   260     }
       
   261 
   713     if (!(domain1_pd = ecrt_domain_data(domain1))) {
   262     if (!(domain1_pd = ecrt_domain_data(domain1))) {
   714         return -1;
   263         fprintf(stderr, "Failed to get domain data pointer.\n");
   715     }
   264         return -1;
   716     fprintf(stderr, "domain1_pd:  0x%.6x\n", (unsigned int)domain1_pd);
   265     }
   717     
       
   718     
       
   719     
       
   720     run=1;
       
   721 
   266 
   722     /* Create cyclic RT-thread */
   267     /* Create cyclic RT-thread */
   723     struct sched_param param;
   268     struct sched_param param;
   724     param.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
   269     param.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
   725     if( sched_setscheduler( 0, SCHED_FIFO, &param ) == -1 ) {
   270     if (sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
   726       puts("ERROR IN SETTING THE SCHEDULER");
   271         puts("ERROR IN SETTING THE SCHEDULER");
   727       perror("errno");
   272         perror("errno");
   728       exit(1);
   273         return -1;
   729     }
   274     }
   730 
   275 
   731     task = rt_task_init( nam2num("ec_rtai_rtdm_example"), priority, stack_size, msg_size);
   276     task = rt_task_init(nam2num("ec_rtai_rtdm_example"),
   732 
   277             0 /* priority */, 0 /* stack size */, 0 /* msg size */);
   733     
   278 
   734     my_cyclic();
   279     my_cyclic();
   735 
   280 
   736     rt_task_delete(task);
   281     rt_task_delete(task);
   737 
   282 
   738     if (rt_fd >= 0)
       
   739         {
       
   740             printf("closing rt device %s\n", &rt_dev_file[0]);
       
   741             
       
   742             rt_dev_close(rt_fd);
       
   743             
       
   744         }
       
   745     
       
   746     printf("End of Program\n");
   283     printf("End of Program\n");
   747     ecrt_release_master(master);
   284     ecrt_release_master(master);
   748 
   285 
   749     return 0;
   286     return 0;
   750 
   287 }
   751 }
   288 
   752 
   289 /****************************************************************************/