examples/user/main.c
branchstable-1.5
changeset 2556 674fcdccc0f3
parent 2555 18c226b66533
child 2565 f7b06b264646
equal deleted inserted replaced
2540:fca12d7035d1 2556:674fcdccc0f3
    42 
    42 
    43 /****************************************************************************/
    43 /****************************************************************************/
    44 
    44 
    45 // Application parameters
    45 // Application parameters
    46 #define FREQUENCY 100
    46 #define FREQUENCY 100
    47 #define PRIORITY 1
    47 #define PRIORITY 0
    48 
       
    49 // Optional features
       
    50 #define CONFIGURE_PDOS  1
       
    51 #define SDO_ACCESS      0
       
    52 
    48 
    53 /****************************************************************************/
    49 /****************************************************************************/
    54 
    50 
    55 // EtherCAT
    51 // EtherCAT
    56 static ec_master_t *master = NULL;
    52 static ec_master_t *master = NULL;
    69 /****************************************************************************/
    65 /****************************************************************************/
    70 
    66 
    71 // process data
    67 // process data
    72 static uint8_t *domain1_pd = NULL;
    68 static uint8_t *domain1_pd = NULL;
    73 
    69 
    74 #define BusCouplerPos  0, 0
    70 #define BusCouplerPos  0, 3
    75 #define DigOutSlavePos 0, 2
    71 #define DigOutSlavePos 0, 0
    76 #define AnaInSlavePos  0, 3
    72 
    77 #define AnaOutSlavePos 0, 4
    73 //#define Beckhoff_EK1100 0x00000002, 0x044c2c52
    78 
    74 #define Beckhoff_EK1100 0x00000002, 0x04562c52
    79 #define Beckhoff_EK1100 0x00000002, 0x044c2c52
    75 #define Beckhoff_EL1008 0x00000002, 0x03f03052
    80 #define Beckhoff_EL2004 0x00000002, 0x07d43052
    76 #define Beckhoff_EL2004 0x00000002, 0x07d43052
       
    77 #define Beckhoff_EL2008 0x00000002, 0x07d83052
    81 #define Beckhoff_EL2032 0x00000002, 0x07f03052
    78 #define Beckhoff_EL2032 0x00000002, 0x07f03052
    82 #define Beckhoff_EL3152 0x00000002, 0x0c503052
    79 #define Beckhoff_EL3152 0x00000002, 0x0c503052
    83 #define Beckhoff_EL3102 0x00000002, 0x0c1e3052
    80 #define Beckhoff_EL3102 0x00000002, 0x0c1e3052
    84 #define Beckhoff_EL4102 0x00000002, 0x10063052
    81 #define Beckhoff_EL4102 0x00000002, 0x10063052
    85 
    82 
    86 // offsets for PDO entries
    83 // offsets for PDO entries
    87 static unsigned int off_ana_in_status;
    84 static unsigned int off_dig_in[1];
    88 static unsigned int off_ana_in_value;
    85 static unsigned int off_dig_out[2];
    89 static unsigned int off_ana_out;
    86 
    90 static unsigned int off_dig_out;
       
    91 
       
    92 const static ec_pdo_entry_reg_t domain1_regs[] = {
       
    93     {AnaInSlavePos,  Beckhoff_EL3102, 0x3101, 1, &off_ana_in_status},
       
    94     {AnaInSlavePos,  Beckhoff_EL3102, 0x3101, 2, &off_ana_in_value},
       
    95     {AnaOutSlavePos, Beckhoff_EL4102, 0x3001, 1, &off_ana_out},
       
    96     {DigOutSlavePos, Beckhoff_EL2032, 0x3001, 1, &off_dig_out},
       
    97     {}
       
    98 };
       
    99 
       
   100 static unsigned int counter = 0;
       
   101 static unsigned int blink = 0;
       
   102 
    87 
   103 /*****************************************************************************/
    88 /*****************************************************************************/
   104 
    89 // Digital in ------------------------
   105 #if CONFIGURE_PDOS
    90 static ec_pdo_entry_info_t el1008_channels[] = {
   106 
    91     {0x6000, 1, 1},
   107 // Analog in --------------------------
    92     {0x6010, 1, 1},
   108 
    93     {0x6020, 1, 1},
   109 static ec_pdo_entry_info_t el3102_pdo_entries[] = {
    94     {0x6030, 1, 1},
   110     {0x3101, 1,  8}, // channel 1 status
    95     {0x6040, 1, 1},
   111     {0x3101, 2, 16}, // channel 1 value
    96     {0x6050, 1, 1},
   112     {0x3102, 1,  8}, // channel 2 status
    97     {0x6060, 1, 1},
   113     {0x3102, 2, 16}, // channel 2 value
    98     {0x6070, 1, 1},
   114     {0x6401, 1, 16}, // channel 1 value (alt.)
    99 };
   115     {0x6401, 2, 16}  // channel 2 value (alt.)
   100 
   116 };
   101 static ec_pdo_info_t el1008_pdos[] = {
   117 
   102     {0x1a00, 1, &el1008_channels[0]},
   118 static ec_pdo_info_t el3102_pdos[] = {
   103     {0x1a01, 1, &el1008_channels[1]},
   119     {0x1A00, 2, el3102_pdo_entries},
   104     {0x1a02, 1, &el1008_channels[2]},
   120     {0x1A01, 2, el3102_pdo_entries + 2}
   105     {0x1a03, 1, &el1008_channels[3]},
   121 };
   106     {0x1a04, 1, &el1008_channels[4]},
   122 
   107     {0x1a05, 1, &el1008_channels[5]},
   123 static ec_sync_info_t el3102_syncs[] = {
   108     {0x1a06, 1, &el1008_channels[6]},
       
   109     {0x1a07, 1, &el1008_channels[7]}
       
   110 };
       
   111 
       
   112 static ec_sync_info_t el1008_syncs[] = {
   124     {2, EC_DIR_OUTPUT},
   113     {2, EC_DIR_OUTPUT},
   125     {3, EC_DIR_INPUT, 2, el3102_pdos},
   114     {3, EC_DIR_INPUT, 8, el1008_pdos},
   126     {0xff}
   115     {0xff}
   127 };
   116 };
   128 
   117 
   129 // Analog out -------------------------
       
   130 
       
   131 static ec_pdo_entry_info_t el4102_pdo_entries[] = {
       
   132     {0x3001, 1, 16}, // channel 1 value
       
   133     {0x3002, 1, 16}, // channel 2 value
       
   134 };
       
   135 
       
   136 static ec_pdo_info_t el4102_pdos[] = {
       
   137     {0x1600, 1, el4102_pdo_entries},
       
   138     {0x1601, 1, el4102_pdo_entries + 1}
       
   139 };
       
   140 
       
   141 static ec_sync_info_t el4102_syncs[] = {
       
   142     {2, EC_DIR_OUTPUT, 2, el4102_pdos},
       
   143     {3, EC_DIR_INPUT},
       
   144     {0xff}
       
   145 };
       
   146 
       
   147 // Digital out ------------------------
   118 // Digital out ------------------------
   148 
   119 static ec_pdo_entry_info_t el2008_channels[] = {
   149 static ec_pdo_entry_info_t el2004_channels[] = {
   120     {0x7000, 1, 1},
   150     {0x3001, 1, 1}, // Value 1
   121     {0x7010, 1, 1},
   151     {0x3001, 2, 1}, // Value 2
   122     {0x7020, 1, 1},
   152     {0x3001, 3, 1}, // Value 3
   123     {0x7030, 1, 1},
   153     {0x3001, 4, 1}  // Value 4
   124     {0x7040, 1, 1},
   154 };
   125     {0x7050, 1, 1},
   155 
   126     {0x7060, 1, 1},
   156 static ec_pdo_info_t el2004_pdos[] = {
   127     {0x7070, 1, 1},
   157     {0x1600, 1, &el2004_channels[0]},
   128 };
   158     {0x1601, 1, &el2004_channels[1]},
   129 
   159     {0x1602, 1, &el2004_channels[2]},
   130 static ec_pdo_info_t el2008_pdos[] = {
   160     {0x1603, 1, &el2004_channels[3]}
   131     {0x1600, 1, &el2008_channels[0]},
   161 };
   132     {0x1601, 1, &el2008_channels[1]},
   162 
   133     {0x1602, 1, &el2008_channels[2]},
   163 static ec_sync_info_t el2004_syncs[] = {
   134     {0x1603, 1, &el2008_channels[3]},
   164     {0, EC_DIR_OUTPUT, 4, el2004_pdos},
   135     {0x1604, 1, &el2008_channels[4]},
       
   136     {0x1605, 1, &el2008_channels[5]},
       
   137     {0x1606, 1, &el2008_channels[6]},
       
   138     {0x1607, 1, &el2008_channels[7]}
       
   139 };
       
   140 
       
   141 static ec_sync_info_t el2008_syncs[] = {
       
   142     {0, EC_DIR_OUTPUT, 8, el2008_pdos},
   165     {1, EC_DIR_INPUT},
   143     {1, EC_DIR_INPUT},
   166     {0xff}
   144     {0xff}
   167 };
   145 };
   168 #endif
       
   169 
       
   170 /*****************************************************************************/
       
   171 
       
   172 #if SDO_ACCESS
       
   173 static ec_sdo_request_t *sdo;
       
   174 #endif
       
   175 
   146 
   176 /*****************************************************************************/
   147 /*****************************************************************************/
   177 
   148 
   178 void check_domain1_state(void)
   149 void check_domain1_state(void)
   179 {
   150 {
   224                 s.operational ? "" : "Not ");
   195                 s.operational ? "" : "Not ");
   225 
   196 
   226     sc_ana_in_state = s;
   197     sc_ana_in_state = s;
   227 }
   198 }
   228 
   199 
   229 /*****************************************************************************/
       
   230 
       
   231 #if SDO_ACCESS
       
   232 void read_sdo(void)
       
   233 {
       
   234     switch (ecrt_sdo_request_state(sdo)) {
       
   235         case EC_REQUEST_UNUSED: // request was not used yet
       
   236             ecrt_sdo_request_read(sdo); // trigger first read
       
   237             break;
       
   238         case EC_REQUEST_BUSY:
       
   239             fprintf(stderr, "Still busy...\n");
       
   240             break;
       
   241         case EC_REQUEST_SUCCESS:
       
   242             fprintf(stderr, "SDO value: 0x%04X\n",
       
   243                     EC_READ_U16(ecrt_sdo_request_data(sdo)));
       
   244             ecrt_sdo_request_read(sdo); // trigger next read
       
   245             break;
       
   246         case EC_REQUEST_ERROR:
       
   247             fprintf(stderr, "Failed to read SDO!\n");
       
   248             ecrt_sdo_request_read(sdo); // retry reading
       
   249             break;
       
   250     }
       
   251 }
       
   252 #endif
       
   253 
       
   254 /****************************************************************************/
   200 /****************************************************************************/
   255 
   201 
   256 void cyclic_task()
   202 void cyclic_task()
   257 {
   203 {
       
   204     static unsigned int counter = 10;
       
   205     static uint8_t outputValue = 0;
       
   206     static int numAsyncCycles = 0;
       
   207     uint8_t inputValue = 0;
       
   208     static uint8_t error = 0;
       
   209 
   258     // receive process data
   210     // receive process data
   259     ecrt_master_receive(master);
   211     ecrt_master_receive(master);
   260     ecrt_domain_process(domain1);
   212     ecrt_domain_process(domain1);
   261 
   213 
   262     // check process data state (optional)
   214     // check process data state (optional)
   263     check_domain1_state();
   215     check_domain1_state();
   264 
   216     
       
   217 
       
   218 	inputValue = EC_READ_U8(domain1_pd + off_dig_in[0]);
       
   219 	
       
   220 	if(inputValue != outputValue) {
       
   221 		numAsyncCycles++;
       
   222 	} else {
       
   223 		numAsyncCycles = 0;
       
   224 	}
       
   225 	
       
   226 	if(numAsyncCycles > 2) {
       
   227 		if(error != 0xff) {
       
   228 			error++;
       
   229 		}
       
   230 	}
       
   231 	
       
   232 	
   265     if (counter) {
   233     if (counter) {
   266         counter--;
   234         counter--;
   267     } else { // do this at 1 Hz
   235     } else {
   268         counter = FREQUENCY;
   236         counter = 5; //update delay
       
   237         
       
   238         
   269 
   239 
   270         // calculate new process data
   240         // calculate new process data
   271         blink = !blink;
   241         outputValue++;
   272 
   242 
   273         // check for master state (optional)
   243         // check for master state (optional)
   274         check_master_state();
   244         check_master_state();
   275 
   245 
   276         // check for islave configuration state(s) (optional)
   246         // check for islave configuration state(s) (optional)
   277         check_slave_config_states();
   247         check_slave_config_states();
   278 
   248     }
   279 #if SDO_ACCESS
   249 
   280         // read process data SDO
       
   281         read_sdo();
       
   282 #endif
       
   283 
       
   284     }
       
   285 
       
   286 #if 0
       
   287     // read process data
       
   288     printf("AnaIn: state %u value %u\n",
       
   289             EC_READ_U8(domain1_pd + off_ana_in_status),
       
   290             EC_READ_U16(domain1_pd + off_ana_in_value));
       
   291 #endif
       
   292 
       
   293 #if 1
       
   294     // write process data
   250     // write process data
   295     EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);
   251     EC_WRITE_U8(domain1_pd + off_dig_out[1], outputValue);
   296 #endif
   252     EC_WRITE_U8(domain1_pd + off_dig_out[0], error);
   297 
   253 
   298     // send process data
   254     // send process data
   299     ecrt_domain_queue(domain1);
   255     ecrt_domain_queue(domain1);
   300     ecrt_master_send(master);
   256     ecrt_master_send(master);
   301 }
   257 }
   310     }
   266     }
   311 }
   267 }
   312 
   268 
   313 /****************************************************************************/
   269 /****************************************************************************/
   314 
   270 
       
   271 int Init_EL2008(uint16_t position)
       
   272 {
       
   273     ec_slave_config_t *sc;
       
   274     if (!(sc = ecrt_master_slave_config(master, 0, position, Beckhoff_EL2008))) {
       
   275         fprintf(stderr, "Failed to get EL2008 configuration #%u.\n", position);
       
   276         return -1;
       
   277     }
       
   278     if (ecrt_slave_config_pdos(sc, EC_END, el2008_syncs)) {
       
   279         fprintf(stderr, "Failed to configure PDOs #%u.\n", position);
       
   280         return -1;
       
   281     }
       
   282     if (0 > (off_dig_out[position] = ecrt_slave_config_reg_pdo_entry(sc, 0x7000, 1, domain1, NULL))) {
       
   283 		fprintf(stderr, "Failed to configure reg PDOs #%u.\n", position);
       
   284 		return -1;
       
   285 	}
       
   286     fprintf(stderr, "EL2008 #%u configured offset: %d.\n", position, off_dig_out[position]);
       
   287     return 0;
       
   288 }
       
   289 
   315 int main(int argc, char **argv)
   290 int main(int argc, char **argv)
   316 {
   291 {
   317     ec_slave_config_t *sc;
   292     ec_slave_config_t *sc;
   318     struct sigaction sa;
   293     struct sigaction sa;
   319     struct itimerval tv;
   294     struct itimerval tv;
       
   295     uint16_t i;
   320 
   296 
   321     master = ecrt_request_master(0);
   297     master = ecrt_request_master(0);
   322     if (!master)
   298     if (!master)
   323         return -1;
   299         return -1;
   324 
   300 
   325     domain1 = ecrt_master_create_domain(master);
   301     domain1 = ecrt_master_create_domain(master);
   326     if (!domain1)
   302     if (!domain1)
   327         return -1;
   303         return -1;
   328 
   304 
   329     if (!(sc_ana_in = ecrt_master_slave_config(
       
   330                     master, AnaInSlavePos, Beckhoff_EL3102))) {
       
   331         fprintf(stderr, "Failed to get slave configuration.\n");
       
   332         return -1;
       
   333     }
       
   334 
       
   335 #if SDO_ACCESS
       
   336     fprintf(stderr, "Creating SDO requests...\n");
       
   337     if (!(sdo = ecrt_slave_config_create_sdo_request(sc_ana_in, 0x3102, 2, 2))) {
       
   338         fprintf(stderr, "Failed to create SDO request.\n");
       
   339         return -1;
       
   340     }
       
   341     ecrt_sdo_request_timeout(sdo, 500); // ms
       
   342 #endif
       
   343 
       
   344 #if CONFIGURE_PDOS
       
   345     printf("Configuring PDOs...\n");
   305     printf("Configuring PDOs...\n");
   346     if (ecrt_slave_config_pdos(sc_ana_in, EC_END, el3102_syncs)) {
   306     if (!(sc_ana_in = ecrt_master_slave_config(master, 0, 2, Beckhoff_EL1008))) {
       
   307         fprintf(stderr, "Failed to get digital in configuration.\n");
       
   308         return -1;
       
   309     }
       
   310     if (ecrt_slave_config_pdos(sc_ana_in, EC_END, el1008_syncs)) {
   347         fprintf(stderr, "Failed to configure PDOs.\n");
   311         fprintf(stderr, "Failed to configure PDOs.\n");
   348         return -1;
   312         return -1;
   349     }
   313     }
   350 
   314     if (0 > (off_dig_in[0] = ecrt_slave_config_reg_pdo_entry(sc_ana_in, 0x6000, 1, domain1, NULL))) {
   351     if (!(sc = ecrt_master_slave_config(
   315 		fprintf(stderr, "Failed to configure reg PDOs.\n");
   352                     master, AnaOutSlavePos, Beckhoff_EL4102))) {
   316 		return -1;
   353         fprintf(stderr, "Failed to get slave configuration.\n");
   317 	}
   354         return -1;
   318     printf("EL1008 configured.\n");
   355     }
   319 
   356 
   320     for(i = 0; i < 2; ++i) {
   357     if (ecrt_slave_config_pdos(sc, EC_END, el4102_syncs)) {
   321         if(Init_EL2008(i)) {
   358         fprintf(stderr, "Failed to configure PDOs.\n");
   322             fprintf(stderr, "Failed to initialize EL2008 #%u.\n", i);
   359         return -1;
   323             return -1;
   360     }
   324         }
   361 
   325     }
   362     if (!(sc = ecrt_master_slave_config(
       
   363                     master, DigOutSlavePos, Beckhoff_EL2032))) {
       
   364         fprintf(stderr, "Failed to get slave configuration.\n");
       
   365         return -1;
       
   366     }
       
   367 
       
   368     if (ecrt_slave_config_pdos(sc, EC_END, el2004_syncs)) {
       
   369         fprintf(stderr, "Failed to configure PDOs.\n");
       
   370         return -1;
       
   371     }
       
   372 #endif
       
   373 
   326 
   374     // Create configuration for bus coupler
   327     // Create configuration for bus coupler
   375     sc = ecrt_master_slave_config(master, BusCouplerPos, Beckhoff_EK1100);
   328     sc = ecrt_master_slave_config(master, BusCouplerPos, Beckhoff_EK1100);
   376     if (!sc)
   329     if (!sc)
   377         return -1;
   330         return -1;
   378 
   331     fprintf(stderr, "EK1100 configured.\n");
   379     if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
       
   380         fprintf(stderr, "PDO entry registration failed!\n");
       
   381         return -1;
       
   382     }
       
   383 
   332 
   384     printf("Activating master...\n");
   333     printf("Activating master...\n");
   385     if (ecrt_master_activate(master))
   334     if (ecrt_master_activate(master))
   386         return -1;
   335         return -1;
   387 
   336