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