master/master.c
changeset 98 f564d0929292
parent 95 0066de7a456d
child 101 b0c19892145a
equal deleted inserted replaced
97:e6264685dd7b 98:f564d0929292
    19 #include "globals.h"
    19 #include "globals.h"
    20 #include "master.h"
    20 #include "master.h"
    21 #include "slave.h"
    21 #include "slave.h"
    22 #include "types.h"
    22 #include "types.h"
    23 #include "device.h"
    23 #include "device.h"
    24 #include "frame.h"
    24 #include "command.h"
    25 
    25 
    26 /*****************************************************************************/
    26 /*****************************************************************************/
    27 
    27 
    28 /**
    28 /**
    29    Konstruktor des EtherCAT-Masters.
    29    Konstruktor des EtherCAT-Masters.
    30 */
    30 */
    31 
    31 
    32 void ec_master_init(ec_master_t *master /**< EtherCAT-Master */)
    32 void ec_master_init(ec_master_t *master /**< EtherCAT-Master */)
    33 {
    33 {
    34     master->slaves = NULL;
    34     master->slaves = NULL;
    35     master->slave_count = 0;
    35     master->device = NULL;
    36     master->device_registered = 0;
    36 
    37     master->command_index = 0x00;
    37     INIT_LIST_HEAD(&master->commands);
    38     master->debug_level = 0;
       
    39     master->bus_time = 0;
       
    40     master->frames_lost = 0;
       
    41     master->frames_delayed = 0;
       
    42     master->t_last_cyclic_output = 0;
       
    43 
       
    44     INIT_LIST_HEAD(&master->domains);
    38     INIT_LIST_HEAD(&master->domains);
       
    39 
       
    40     ec_master_reset(master);
    45 }
    41 }
    46 
    42 
    47 /*****************************************************************************/
    43 /*****************************************************************************/
    48 
    44 
    49 /**
    45 /**
    54 */
    50 */
    55 
    51 
    56 void ec_master_clear(ec_master_t *master /**< EtherCAT-Master */)
    52 void ec_master_clear(ec_master_t *master /**< EtherCAT-Master */)
    57 {
    53 {
    58     ec_master_reset(master);
    54     ec_master_reset(master);
    59     ec_device_clear(&master->device);
    55 
       
    56     if (master->device) {
       
    57         ec_device_clear(master->device);
       
    58         kfree(master->device);
       
    59     }
    60 }
    60 }
    61 
    61 
    62 /*****************************************************************************/
    62 /*****************************************************************************/
    63 
    63 
    64 /**
    64 /**
    70 
    70 
    71 void ec_master_reset(ec_master_t *master
    71 void ec_master_reset(ec_master_t *master
    72                      /**< Zeiger auf den zurückzusetzenden Master */
    72                      /**< Zeiger auf den zurückzusetzenden Master */
    73                      )
    73                      )
    74 {
    74 {
    75     ec_domain_t *domain, *next;
       
    76 
       
    77     ec_master_clear_slaves(master);
       
    78 
       
    79     // Domain-Liste leeren
       
    80     list_for_each_entry_safe(domain, next, &master->domains, list) {
       
    81         ec_domain_clear(domain);
       
    82         kfree(domain);
       
    83     }
       
    84     INIT_LIST_HEAD(&master->domains);
       
    85 
       
    86     master->command_index = 0;
       
    87     master->debug_level = 0;
       
    88     master->bus_time = 0;
       
    89     master->frames_lost = 0;
       
    90     master->frames_delayed = 0;
       
    91     master->t_last_cyclic_output = 0;
       
    92 }
       
    93 
       
    94 /*****************************************************************************/
       
    95 
       
    96 /**
       
    97    Entfernt alle Slaves.
       
    98 */
       
    99 
       
   100 void ec_master_clear_slaves(ec_master_t *master /**< EtherCAT-Master */)
       
   101 {
       
   102     unsigned int i;
    75     unsigned int i;
   103 
    76     ec_command_t *command, *next_command;
       
    77     ec_domain_t *domain, *next_domain;
       
    78 
       
    79     // Alle Slaves entfernen
   104     if (master->slaves) {
    80     if (master->slaves) {
   105         for (i = 0; i < master->slave_count; i++) {
    81         for (i = 0; i < master->slave_count; i++) {
   106             ec_slave_clear(master->slaves + i);
    82             ec_slave_clear(master->slaves + i);
   107         }
    83         }
   108         kfree(master->slaves);
    84         kfree(master->slaves);
   109         master->slaves = NULL;
    85         master->slaves = NULL;
   110     }
    86     }
   111     master->slave_count = 0;
    87     master->slave_count = 0;
       
    88 
       
    89     // Kommando-Warteschlange leeren
       
    90     list_for_each_entry_safe(command, next_command, &master->commands, list) {
       
    91         command->state = EC_CMD_ERROR;
       
    92         list_del_init(&command->list);
       
    93     }
       
    94 
       
    95     // Domain-Liste leeren
       
    96     list_for_each_entry_safe(domain, next_domain, &master->domains, list) {
       
    97         list_del(&domain->list);
       
    98         ec_domain_clear(domain);
       
    99         kfree(domain);
       
   100     }
       
   101 
       
   102     master->command_index = 0;
       
   103     master->debug_level = 0;
       
   104     master->stats.timeouts = 0;
       
   105     master->stats.delayed = 0;
       
   106     master->stats.corrupted = 0;
       
   107     master->stats.unmatched = 0;
       
   108     master->stats.t_last = 0;
   112 }
   109 }
   113 
   110 
   114 /*****************************************************************************/
   111 /*****************************************************************************/
   115 
   112 
   116 /**
   113 /**
   120            es nicht geoeffnet werden konnte.
   117            es nicht geoeffnet werden konnte.
   121 */
   118 */
   122 
   119 
   123 int ec_master_open(ec_master_t *master /**< Der EtherCAT-Master */)
   120 int ec_master_open(ec_master_t *master /**< Der EtherCAT-Master */)
   124 {
   121 {
   125     if (!master->device_registered) {
   122     if (!master->device) {
   126         EC_ERR("No device registered!\n");
   123         EC_ERR("No device registered!\n");
   127         return -1;
   124         return -1;
   128     }
   125     }
   129 
   126 
   130     if (ec_device_open(&master->device) < 0) {
   127     if (ec_device_open(master->device)) {
   131         EC_ERR("Could not open device!\n");
   128         EC_ERR("Could not open device!\n");
   132         return -1;
   129         return -1;
   133     }
   130     }
   134 
   131 
   135     return 0;
   132     return 0;
   141    Schliesst das EtherCAT-Geraet, auf dem der Master arbeitet.
   138    Schliesst das EtherCAT-Geraet, auf dem der Master arbeitet.
   142 */
   139 */
   143 
   140 
   144 void ec_master_close(ec_master_t *master /**< EtherCAT-Master */)
   141 void ec_master_close(ec_master_t *master /**< EtherCAT-Master */)
   145 {
   142 {
   146     if (!master->device_registered) {
   143     if (!master->device) {
   147         EC_WARN("Warning - Trying to close an unregistered device!\n");
   144         EC_WARN("Warning - Trying to close an unregistered device!\n");
   148         return;
   145         return;
   149     }
   146     }
   150 
   147 
   151     if (ec_device_close(&master->device) < 0)
   148     if (ec_device_close(master->device))
   152         EC_WARN("Warning - Could not close device!\n");
   149         EC_WARN("Warning - Could not close device!\n");
       
   150 }
       
   151 
       
   152 /*****************************************************************************/
       
   153 
       
   154 /**
       
   155    Stellt ein Kommando in die Warteschlange.
       
   156 */
       
   157 
       
   158 void ec_master_queue_command(ec_master_t *master, /**< EtherCAT-Master */
       
   159                              ec_command_t *command /**< Kommando */
       
   160                              )
       
   161 {
       
   162     ec_command_t *queued_command;
       
   163 
       
   164     // Ist das Kommando schon in der Warteschlange?
       
   165     list_for_each_entry(queued_command, &master->commands, list) {
       
   166         if (queued_command == command) {
       
   167             command->state = EC_CMD_QUEUED;
       
   168             if (unlikely(master->debug_level))
       
   169                 EC_WARN("command already queued.\n");
       
   170             return;
       
   171         }
       
   172     }
       
   173 
       
   174     list_add_tail(&command->list, &master->commands);
       
   175     command->state = EC_CMD_QUEUED;
       
   176 }
       
   177 
       
   178 /*****************************************************************************/
       
   179 
       
   180 /**
       
   181    Sendet die Kommandos in der Warteschlange.
       
   182 
       
   183    \return 0 bei Erfolg, sonst < 0
       
   184 */
       
   185 
       
   186 void ec_master_send_commands(ec_master_t *master /**< EtherCAT-Master */)
       
   187 {
       
   188     ec_command_t *command;
       
   189     size_t command_size;
       
   190     uint8_t *frame_data, *cur_data;
       
   191     void *follows_word;
       
   192     cycles_t start = 0, end;
       
   193 
       
   194     if (unlikely(master->debug_level > 0)) {
       
   195         EC_DBG("ec_master_send\n");
       
   196         start = get_cycles();
       
   197     }
       
   198 
       
   199     // Zeiger auf Socket-Buffer holen
       
   200     frame_data = ec_device_tx_data(master->device);
       
   201     cur_data = frame_data + EC_FRAME_HEADER_SIZE;
       
   202     follows_word = NULL;
       
   203 
       
   204     // Aktuellen Frame mit Kommandos füllen
       
   205     list_for_each_entry(command, &master->commands, list) {
       
   206         if (command->state != EC_CMD_QUEUED) continue;
       
   207 
       
   208         // Passt das aktuelle Kommando noch in den aktuellen Rahmen?
       
   209         command_size = EC_COMMAND_HEADER_SIZE + command->data_size
       
   210             + EC_COMMAND_FOOTER_SIZE;
       
   211         if (cur_data - frame_data + command_size > EC_MAX_FRAME_SIZE) break;
       
   212 
       
   213         command->state = EC_CMD_SENT;
       
   214         command->index = master->command_index++;
       
   215 
       
   216         if (unlikely(master->debug_level > 0))
       
   217             EC_DBG("adding command 0x%02X\n", command->index);
       
   218 
       
   219         // Command-Following-Flag im letzten Kommando setzen
       
   220         if (follows_word)
       
   221             EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000);
       
   222 
       
   223         // EtherCAT command header
       
   224         EC_WRITE_U8 (cur_data,     command->type);
       
   225         EC_WRITE_U8 (cur_data + 1, command->index);
       
   226         EC_WRITE_U32(cur_data + 2, command->address.logical);
       
   227         EC_WRITE_U16(cur_data + 6, command->data_size & 0x7FF);
       
   228         EC_WRITE_U16(cur_data + 8, 0x0000);
       
   229         follows_word = cur_data + 6;
       
   230         cur_data += EC_COMMAND_HEADER_SIZE;
       
   231 
       
   232         // EtherCAT command data
       
   233         memcpy(cur_data, command->data, command->data_size);
       
   234         cur_data += command->data_size;
       
   235 
       
   236         // EtherCAT command footer
       
   237         EC_WRITE_U16(cur_data, command->working_counter);
       
   238         cur_data += EC_COMMAND_FOOTER_SIZE;
       
   239     }
       
   240 
       
   241     if (cur_data - frame_data == EC_FRAME_HEADER_SIZE) {
       
   242         if (unlikely(master->debug_level > 0)) EC_DBG("nothing to send.\n");
       
   243         return;
       
   244     }
       
   245 
       
   246     // EtherCAT frame header
       
   247     EC_WRITE_U16(frame_data, ((cur_data - frame_data
       
   248                                - EC_FRAME_HEADER_SIZE) & 0x7FF) | 0x1000);
       
   249 
       
   250     // Rahmen auffüllen
       
   251     while (cur_data - frame_data < EC_MIN_FRAME_SIZE)
       
   252         EC_WRITE_U8(cur_data++, 0x00);
       
   253 
       
   254     if (unlikely(master->debug_level > 0))
       
   255         EC_DBG("Frame size: %i\n", cur_data - frame_data);
       
   256 
       
   257     // Send frame
       
   258     ec_device_send(master->device, cur_data - frame_data);
       
   259 
       
   260     if (unlikely(master->debug_level > 0)) {
       
   261         end = get_cycles();
       
   262         EC_DBG("ec_master_send finished in %ius.\n",
       
   263                (u32) (end - start) * 1000 / cpu_khz);
       
   264     }
       
   265 }
       
   266 
       
   267 /*****************************************************************************/
       
   268 
       
   269 /**
       
   270    Wertet einen empfangenen Rahmen aus.
       
   271 
       
   272    \return 0 bei Erfolg, sonst < 0
       
   273 */
       
   274 
       
   275 void ec_master_receive(ec_master_t *master, /**< EtherCAT-Master */
       
   276                       const uint8_t *frame_data, /**< Empfangene Daten */
       
   277                       size_t size /**< Anzahl empfangene Datenbytes */
       
   278                       )
       
   279 {
       
   280     size_t frame_size, data_size;
       
   281     uint8_t command_type, command_index;
       
   282     unsigned int cmd_follows, matched;
       
   283     const uint8_t *cur_data;
       
   284     ec_command_t *command;
       
   285 
       
   286     if (unlikely(size < EC_FRAME_HEADER_SIZE)) {
       
   287         master->stats.corrupted++;
       
   288         ec_master_output_stats(master);
       
   289         return;
       
   290     }
       
   291 
       
   292     cur_data = frame_data;
       
   293 
       
   294     // Länge des gesamten Frames prüfen
       
   295     frame_size = EC_READ_U16(cur_data) & 0x07FF;
       
   296     cur_data += EC_FRAME_HEADER_SIZE;
       
   297 
       
   298     if (unlikely(frame_size > size)) {
       
   299         master->stats.corrupted++;
       
   300         ec_master_output_stats(master);
       
   301         return;
       
   302     }
       
   303 
       
   304     cmd_follows = 1;
       
   305     while (cmd_follows) {
       
   306         // Kommando-Header auswerten
       
   307         command_type  = EC_READ_U8 (cur_data);
       
   308         command_index = EC_READ_U8 (cur_data + 1);
       
   309         data_size     = EC_READ_U16(cur_data + 6) & 0x07FF;
       
   310         cmd_follows   = EC_READ_U16(cur_data + 6) & 0x8000;
       
   311         cur_data += EC_COMMAND_HEADER_SIZE;
       
   312 
       
   313         if (unlikely(cur_data - frame_data
       
   314                      + data_size + EC_COMMAND_FOOTER_SIZE > size)) {
       
   315             master->stats.corrupted++;
       
   316             ec_master_output_stats(master);
       
   317             return;
       
   318         }
       
   319 
       
   320         // Suche passendes Kommando in der Liste
       
   321         matched = 0;
       
   322         list_for_each_entry(command, &master->commands, list) {
       
   323             if (command->state == EC_CMD_SENT
       
   324                 && command->type == command_type
       
   325                 && command->index == command_index
       
   326                 && command->data_size == data_size) {
       
   327                 matched = 1;
       
   328                 break;
       
   329             }
       
   330         }
       
   331 
       
   332         // Kein passendes Kommando in der Liste gefunden
       
   333         if (!matched) {
       
   334             master->stats.unmatched++;
       
   335             ec_master_output_stats(master);
       
   336             cur_data += data_size + EC_COMMAND_FOOTER_SIZE;
       
   337             continue;
       
   338         }
       
   339 
       
   340         // Empfangene Daten in Kommando-Datenspeicher kopieren
       
   341         memcpy(command->data, cur_data, data_size);
       
   342         cur_data += data_size;
       
   343 
       
   344         // Working-Counter setzen
       
   345         command->working_counter = EC_READ_U16(cur_data);
       
   346         cur_data += EC_COMMAND_FOOTER_SIZE;
       
   347 
       
   348         // Kommando aus der Liste entfernen
       
   349         command->state = EC_CMD_RECEIVED;
       
   350         list_del_init(&command->list);
       
   351     }
       
   352 }
       
   353 
       
   354 /*****************************************************************************/
       
   355 
       
   356 /**
       
   357    Sendet ein einzelnes Kommando und wartet auf den Empfang.
       
   358 
       
   359    Wenn der Slave nicht antwortet, wird das Kommando
       
   360    nochmals gesendet.
       
   361 
       
   362    \return 0 bei Erfolg, sonst < 0
       
   363 */
       
   364 
       
   365 int ec_master_simple_io(ec_master_t *master, /**< EtherCAT-Master */
       
   366                         ec_command_t *command /**< Kommando */
       
   367                         )
       
   368 {
       
   369     unsigned int response_tries_left;
       
   370 
       
   371     response_tries_left = 10;
       
   372     do
       
   373     {
       
   374         ec_master_queue_command(master, command);
       
   375         EtherCAT_rt_master_xio(master);
       
   376 
       
   377         if (command->state == EC_CMD_RECEIVED) {
       
   378             break;
       
   379         }
       
   380         else if (command->state == EC_CMD_TIMEOUT) {
       
   381             EC_ERR("Simple IO TIMED OUT!\n");
       
   382             return -1;
       
   383         }
       
   384         else if (command->state == EC_CMD_ERROR) {
       
   385             EC_ERR("Simple IO command error!\n");
       
   386             return -1;
       
   387         }
       
   388     }
       
   389     while (unlikely(!command->working_counter && --response_tries_left));
       
   390 
       
   391     if (unlikely(!response_tries_left)) {
       
   392         EC_ERR("No response in simple IO!\n");
       
   393         return -1;
       
   394     }
       
   395 
       
   396     return 0;
   153 }
   397 }
   154 
   398 
   155 /*****************************************************************************/
   399 /*****************************************************************************/
   156 
   400 
   157 /**
   401 /**
   161    weiteren Betrieb notwendig sind.
   405    weiteren Betrieb notwendig sind.
   162 
   406 
   163    \return 0 bei Erfolg, sonst < 0
   407    \return 0 bei Erfolg, sonst < 0
   164 */
   408 */
   165 
   409 
   166 int ec_scan_for_slaves(ec_master_t *master /**< EtherCAT-Master */)
   410 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT-Master */)
   167 {
   411 {
   168     ec_frame_t frame;
   412     ec_command_t command;
   169     ec_slave_t *slave;
   413     ec_slave_t *slave;
   170     ec_slave_ident_t *ident;
   414     ec_slave_ident_t *ident;
   171     unsigned int i;
   415     unsigned int i;
   172     unsigned char data[2];
   416     unsigned char data[2];
   173 
   417 
   175         EC_ERR("Slave scan already done!\n");
   419         EC_ERR("Slave scan already done!\n");
   176         return -1;
   420         return -1;
   177     }
   421     }
   178 
   422 
   179     // Determine number of slaves on bus
   423     // Determine number of slaves on bus
   180     ec_frame_init_brd(&frame, master, 0x0000, 4);
   424     ec_command_init_brd(&command, 0x0000, 4);
   181     if (unlikely(ec_frame_send_receive(&frame))) return -1;
   425     if (unlikely(ec_master_simple_io(master, &command))) return -1;
   182     master->slave_count = frame.working_counter;
   426     master->slave_count = command.working_counter;
   183     EC_INFO("Found %i slaves on bus.\n", master->slave_count);
   427     EC_INFO("Found %i slaves on bus.\n", master->slave_count);
   184 
   428 
   185     if (!master->slave_count) return 0;
   429     if (!master->slave_count) return 0;
   186 
   430 
   187     if (!(master->slaves = (ec_slave_t *) kmalloc(master->slave_count
   431     if (!(master->slaves = (ec_slave_t *) kmalloc(master->slave_count
   204     {
   448     {
   205         slave = master->slaves + i;
   449         slave = master->slaves + i;
   206 
   450 
   207         // Write station address
   451         // Write station address
   208         EC_WRITE_U16(data, slave->station_address);
   452         EC_WRITE_U16(data, slave->station_address);
   209 
   453         ec_command_init_apwr(&command, slave->ring_position,
   210         ec_frame_init_apwr(&frame, master, slave->ring_position, 0x0010,
   454                              0x0010, sizeof(uint16_t), data);
   211                            sizeof(uint16_t), data);
   455         if (unlikely(ec_master_simple_io(master, &command))) {
   212 
       
   213         if (unlikely(ec_frame_send_receive(&frame))) {
       
   214             EC_ERR("Writing station address failed on slave %i!\n", i);
   456             EC_ERR("Writing station address failed on slave %i!\n", i);
   215             return -1;
   457             return -1;
   216         }
   458         }
   217 
   459 
   218         // Fetch all slave information
   460         // Fetch all slave information
   239 }
   481 }
   240 
   482 
   241 /*****************************************************************************/
   483 /*****************************************************************************/
   242 
   484 
   243 /**
   485 /**
   244    Ausgaben während des zyklischen Betriebs.
   486    Statistik-Ausgaben während des zyklischen Betriebs.
   245 
   487 
   246    Diese Funktion sorgt dafür, dass Ausgaben (Zählerstände) während
   488    Diese Funktion sorgt dafür, dass Statistiken während des zyklischen
   247    des zyklischen Betriebs nicht zu oft getätigt werden.
   489    Betriebs bei Bedarf, aber nicht zu oft ausgegeben werden.
   248 
   490 
   249    Die Ausgabe erfolgt gesammelt höchstens einmal pro Sekunde.
   491    Die Ausgabe erfolgt gesammelt höchstens einmal pro Sekunde.
   250 */
   492 */
   251 
   493 
   252 void ec_cyclic_output(ec_master_t *master /**< EtherCAT-Master */)
   494 void ec_master_output_stats(ec_master_t *master /**< EtherCAT-Master */)
   253 {
   495 {
   254     unsigned long int t;
   496     cycles_t t_now = get_cycles();
   255 
   497 
   256     rdtscl(t);
   498     if (unlikely((u32) (t_now - master->stats.t_last) / cpu_khz > 1000)) {
   257 
   499         if (master->stats.timeouts) {
   258     if ((t - master->t_last_cyclic_output) / cpu_khz > 1000) {
   500             EC_WARN("%i commands TIMED OUT!\n", master->stats.timeouts);
   259         if (master->frames_lost) {
   501             master->stats.timeouts = 0;
   260             EC_WARN("%u frame(s) LOST!\n", master->frames_lost);
   502         }
   261             master->frames_lost = 0;
   503         if (master->stats.delayed) {
   262         }
   504             EC_WARN("%i frame(s) DELAYED!\n", master->stats.delayed);
   263         if (master->frames_delayed) {
   505             master->stats.delayed = 0;
   264             EC_WARN("%u frame(s) DELAYED!\n", master->frames_delayed);
   506         }
   265             master->frames_delayed = 0;
   507         if (master->stats.corrupted) {
   266         }
   508             EC_WARN("%i frame(s) CORRUPTED!\n", master->stats.corrupted);
   267         master->t_last_cyclic_output = t;
   509             master->stats.corrupted = 0;
       
   510         }
       
   511         if (master->stats.unmatched) {
       
   512             EC_WARN("%i command(s) UNMATCHED!\n", master->stats.unmatched);
       
   513             master->stats.unmatched = 0;
       
   514         }
       
   515         master->stats.t_last = t_now;
   268     }
   516     }
   269 }
   517 }
   270 
   518 
   271 /*****************************************************************************/
   519 /*****************************************************************************/
   272 
   520 
   281    - \a "#X:Y" = der Y. Slave hinter dem Buskoppler mit der SSID X.
   529    - \a "#X:Y" = der Y. Slave hinter dem Buskoppler mit der SSID X.
   282 
   530 
   283    \return Zeiger auf Slave bei Erfolg, sonst NULL
   531    \return Zeiger auf Slave bei Erfolg, sonst NULL
   284 */
   532 */
   285 
   533 
   286 ec_slave_t *ec_address(const ec_master_t *master,
   534 ec_slave_t *ec_master_slave_address(const ec_master_t *master,
   287                        /**< EtherCAT-Master */
   535                                     /**< EtherCAT-Master */
   288                        const char *address
   536                                     const char *address
   289                        /**< Address-String */
   537                                     /**< Address-String */
   290                        )
   538                                     )
   291 {
   539 {
   292     unsigned long first, second;
   540     unsigned long first, second;
   293     char *remainder, *remainder2;
   541     char *remainder, *remainder2;
   294     unsigned int i;
   542     unsigned int i;
   295     int coupler_idx, slave_idx;
   543     int coupler_idx, slave_idx;
   446 
   694 
   447 int EtherCAT_rt_master_activate(ec_master_t *master /**< EtherCAT-Master */)
   695 int EtherCAT_rt_master_activate(ec_master_t *master /**< EtherCAT-Master */)
   448 {
   696 {
   449     unsigned int i, j;
   697     unsigned int i, j;
   450     ec_slave_t *slave;
   698     ec_slave_t *slave;
   451     ec_frame_t frame;
   699     ec_command_t command;
   452     const ec_sync_t *sync;
   700     const ec_sync_t *sync;
   453     const ec_slave_type_t *type;
   701     const ec_slave_type_t *type;
   454     const ec_fmmu_t *fmmu;
   702     const ec_fmmu_t *fmmu;
   455     uint8_t data[256];
   703     uint8_t data[256];
   456     uint32_t domain_offset;
   704     uint32_t domain_offset;
   457     unsigned int frame_count;
       
   458     ec_domain_t *domain;
   705     ec_domain_t *domain;
   459 
   706 
   460     // Domains erstellen
   707     // Domains erstellen
   461     domain_offset = 0;
   708     domain_offset = 0;
   462     list_for_each_entry(domain, &master->domains, list) {
   709     list_for_each_entry(domain, &master->domains, list) {
   463         if (ec_domain_alloc(domain, domain_offset)) {
   710         if (ec_domain_alloc(domain, domain_offset)) {
   464             EC_ERR("Failed to allocate domain %X!\n", (u32) domain);
   711             EC_ERR("Failed to allocate domain %X!\n", (u32) domain);
   465             return -1;
   712             return -1;
   466         }
   713         }
   467         frame_count = domain->data_size / EC_MAX_FRAME_SIZE + 1;
       
   468         if (!domain->data_size) frame_count = 0;
       
   469         EC_INFO("Domain %X - Allocated %i bytes (%i Frame(s))\n",
       
   470                 (u32) domain, domain->data_size, frame_count);
       
   471         domain_offset += domain->data_size;
   714         domain_offset += domain->data_size;
   472     }
   715     }
   473 
   716 
   474     // Slaves aktivieren
   717     // Slaves aktivieren
   475     for (i = 0; i < master->slave_count; i++)
   718     for (i = 0; i < master->slave_count; i++)
   492         ec_slave_check_crc(slave);
   735         ec_slave_check_crc(slave);
   493 
   736 
   494         // Resetting FMMUs
   737         // Resetting FMMUs
   495         if (slave->base_fmmu_count) {
   738         if (slave->base_fmmu_count) {
   496             memset(data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
   739             memset(data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
   497             ec_frame_init_npwr(&frame, master, slave->station_address, 0x0600,
   740             ec_command_init_npwr(&command, slave->station_address, 0x0600,
   498                                EC_FMMU_SIZE * slave->base_fmmu_count, data);
   741                                  EC_FMMU_SIZE * slave->base_fmmu_count, data);
   499             if (unlikely(ec_frame_send_receive(&frame))) {
   742             if (unlikely(ec_master_simple_io(master, &command))) {
   500                 EC_ERR("Resetting FMMUs failed on slave %i!\n",
   743                 EC_ERR("Resetting FMMUs failed on slave %i!\n",
   501                        slave->ring_position);
   744                        slave->ring_position);
   502                 return -1;
   745                 return -1;
   503             }
   746             }
   504         }
   747         }
   505 
   748 
   506         // Resetting Sync Manager channels
   749         // Resetting Sync Manager channels
   507         if (slave->base_sync_count) {
   750         if (slave->base_sync_count) {
   508             memset(data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
   751             memset(data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
   509             ec_frame_init_npwr(&frame, master, slave->station_address, 0x0800,
   752             ec_command_init_npwr(&command, slave->station_address, 0x0800,
   510                                EC_SYNC_SIZE * slave->base_sync_count, data);
   753                                  EC_SYNC_SIZE * slave->base_sync_count, data);
   511             if (unlikely(ec_frame_send_receive(&frame))) {
   754             if (unlikely(ec_master_simple_io(master, &command))) {
   512                 EC_ERR("Resetting sync managers failed on slave %i!\n",
   755                 EC_ERR("Resetting sync managers failed on slave %i!\n",
   513                        slave->ring_position);
   756                        slave->ring_position);
   514                 return -1;
   757                 return -1;
   515             }
   758             }
   516         }
   759         }
   519         for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++)
   762         for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++)
   520         {
   763         {
   521             sync = type->sync_managers[j];
   764             sync = type->sync_managers[j];
   522 
   765 
   523             ec_sync_config(sync, data);
   766             ec_sync_config(sync, data);
   524             ec_frame_init_npwr(&frame, master, slave->station_address,
   767             ec_command_init_npwr(&command, slave->station_address,
   525                                0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE, data);
   768                                  0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE,
   526 
   769                                  data);
   527             if (unlikely(ec_frame_send_receive(&frame))) {
   770             if (unlikely(ec_master_simple_io(master, &command))) {
   528                 EC_ERR("Setting sync manager %i failed on slave %i!\n",
   771                 EC_ERR("Setting sync manager %i failed on slave %i!\n",
   529                        j, slave->ring_position);
   772                        j, slave->ring_position);
   530                 return -1;
   773                 return -1;
   531             }
   774             }
   532         }
   775         }
   546         for (j = 0; j < slave->fmmu_count; j++)
   789         for (j = 0; j < slave->fmmu_count; j++)
   547         {
   790         {
   548             fmmu = &slave->fmmus[j];
   791             fmmu = &slave->fmmus[j];
   549 
   792 
   550             ec_fmmu_config(fmmu, data);
   793             ec_fmmu_config(fmmu, data);
   551             ec_frame_init_npwr(&frame, master, slave->station_address,
   794             ec_command_init_npwr(&command, slave->station_address,
   552                                0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE, data);
   795                                  0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE,
   553 
   796                                  data);
   554             if (unlikely(ec_frame_send_receive(&frame))) {
   797             if (unlikely(ec_master_simple_io(master, &command))) {
   555                 EC_ERR("Setting FMMU %i failed on slave %i!\n",
   798                 EC_ERR("Setting FMMU %i failed on slave %i!\n",
   556                        j, slave->ring_position);
   799                        j, slave->ring_position);
   557                 return -1;
   800                 return -1;
   558             }
   801             }
   559         }
   802         }
   598 }
   841 }
   599 
   842 
   600 /*****************************************************************************/
   843 /*****************************************************************************/
   601 
   844 
   602 /**
   845 /**
       
   846    Sendet und empfängt Kommandos.
       
   847 
       
   848    \return 0 bei Erfolg, sonst < 0
       
   849 */
       
   850 
       
   851 void EtherCAT_rt_master_xio(ec_master_t *master)
       
   852 {
       
   853     ec_command_t *command, *next;
       
   854     unsigned int commands_sent;
       
   855     cycles_t t_start, t_end, t_timeout;
       
   856 
       
   857     ec_master_output_stats(master);
       
   858 
       
   859     if (unlikely(!master->device->link_state)) {
       
   860         // Link DOWN, keines der Kommandos kann gesendet werden.
       
   861         list_for_each_entry_safe(command, next, &master->commands, list) {
       
   862             command->state = EC_CMD_ERROR;
       
   863             list_del_init(&command->list);
       
   864         }
       
   865 
       
   866         // Device-Zustand abfragen
       
   867         ec_device_call_isr(master->device);
       
   868         return;
       
   869     }
       
   870 
       
   871     // Rahmen senden
       
   872     ec_master_send_commands(master);
       
   873 
       
   874     t_start = get_cycles(); // Sendezeit nehmen
       
   875     t_timeout = 100 * cpu_khz / 1000; // 100us
       
   876 
       
   877     do {
       
   878         ec_device_call_isr(master->device);
       
   879 
       
   880         t_end = get_cycles(); // Aktuelle Zeit nehmen
       
   881         if (t_end - t_start >= t_timeout) break; // Timeout
       
   882 
       
   883         commands_sent = 0;
       
   884         list_for_each_entry_safe(command, next, &master->commands, list) {
       
   885             if (command->state == EC_CMD_RECEIVED)
       
   886                 list_del_init(&command->list);
       
   887             else if (command->state == EC_CMD_SENT)
       
   888                 commands_sent++;
       
   889         }
       
   890     } while (commands_sent);
       
   891 
       
   892     // Zeit abgelaufen. Alle verbleibenden Kommandos entfernen.
       
   893     list_for_each_entry_safe(command, next, &master->commands, list) {
       
   894         switch (command->state) {
       
   895             case EC_CMD_SENT:
       
   896             case EC_CMD_QUEUED:
       
   897                 command->state = EC_CMD_TIMEOUT;
       
   898                 master->stats.timeouts++;
       
   899                 ec_master_output_stats(master);
       
   900                 break;
       
   901             case EC_CMD_RECEIVED:
       
   902                 master->stats.delayed++;
       
   903                 ec_master_output_stats(master);
       
   904                 break;
       
   905             default:
       
   906                 break;
       
   907         }
       
   908         list_del_init(&command->list);
       
   909     }
       
   910 }
       
   911 
       
   912 /*****************************************************************************/
       
   913 
       
   914 /**
   603    Setzt die Debug-Ebene des Masters.
   915    Setzt die Debug-Ebene des Masters.
   604 
   916 
   605    Folgende Debug-level sind definiert:
   917    Folgende Debug-Level sind definiert:
   606 
   918 
   607    - 1: Nur Positionsmarken in bestimmten Funktionen
   919    - 1: Nur Positionsmarken in bestimmten Funktionen
   608    - 2: Komplette Frame-Inhalte
   920    - 2: Komplette Frame-Inhalte
   609 */
   921 */
   610 
   922 
   612                               /**< EtherCAT-Master */
   924                               /**< EtherCAT-Master */
   613                               int level
   925                               int level
   614                               /**< Debug-Level */
   926                               /**< Debug-Level */
   615                               )
   927                               )
   616 {
   928 {
   617     master->debug_level = level;
   929     if (level != master->debug_level) {
   618 
   930         master->debug_level = level;
   619     EC_INFO("Master debug level set to %i.\n", level);
   931         EC_INFO("Master debug level set to %i.\n", level);
       
   932     }
   620 }
   933 }
   621 
   934 
   622 /*****************************************************************************/
   935 /*****************************************************************************/
   623 
   936 
   624 /**
   937 /**
   630                               )
   943                               )
   631 {
   944 {
   632     unsigned int i;
   945     unsigned int i;
   633 
   946 
   634     EC_INFO("*** Begin master information ***\n");
   947     EC_INFO("*** Begin master information ***\n");
   635 
   948     for (i = 0; i < master->slave_count; i++)
   636     for (i = 0; i < master->slave_count; i++) {
       
   637         ec_slave_print(&master->slaves[i]);
   949         ec_slave_print(&master->slaves[i]);
   638     }
       
   639 
       
   640     EC_INFO("*** End master information ***\n");
   950     EC_INFO("*** End master information ***\n");
   641 }
   951 }
   642 
   952 
   643 /*****************************************************************************/
   953 /*****************************************************************************/
   644 
   954 
   645 EXPORT_SYMBOL(EtherCAT_rt_master_register_domain);
   955 EXPORT_SYMBOL(EtherCAT_rt_master_register_domain);
   646 EXPORT_SYMBOL(EtherCAT_rt_master_activate);
   956 EXPORT_SYMBOL(EtherCAT_rt_master_activate);
   647 EXPORT_SYMBOL(EtherCAT_rt_master_deactivate);
   957 EXPORT_SYMBOL(EtherCAT_rt_master_deactivate);
       
   958 EXPORT_SYMBOL(EtherCAT_rt_master_xio);
   648 EXPORT_SYMBOL(EtherCAT_rt_master_debug);
   959 EXPORT_SYMBOL(EtherCAT_rt_master_debug);
   649 EXPORT_SYMBOL(EtherCAT_rt_master_print);
   960 EXPORT_SYMBOL(EtherCAT_rt_master_print);
   650 
   961 
   651 /*****************************************************************************/
   962 /*****************************************************************************/
   652 
   963