master/master.c
changeset 144 fdc24bf62f80
parent 140 b09658e50d6f
child 145 11a82e4fd31b
equal deleted inserted replaced
143:f6c4f38b699f 144:fdc24bf62f80
    31 void ec_master_init(ec_master_t *master /**< EtherCAT-Master */)
    31 void ec_master_init(ec_master_t *master /**< EtherCAT-Master */)
    32 {
    32 {
    33     master->slaves = NULL;
    33     master->slaves = NULL;
    34     master->device = NULL;
    34     master->device = NULL;
    35 
    35 
    36     INIT_LIST_HEAD(&master->commands);
    36     INIT_LIST_HEAD(&master->command_queue);
    37     INIT_LIST_HEAD(&master->domains);
    37     INIT_LIST_HEAD(&master->domains);
       
    38 
       
    39     ec_command_init(&master->simple_command);
       
    40     ec_command_init(&master->watch_command);
    38 
    41 
    39     ec_master_reset(master);
    42     ec_master_reset(master);
    40 }
    43 }
    41 
    44 
    42 /*****************************************************************************/
    45 /*****************************************************************************/
    54 
    57 
    55     if (master->device) {
    58     if (master->device) {
    56         ec_device_clear(master->device);
    59         ec_device_clear(master->device);
    57         kfree(master->device);
    60         kfree(master->device);
    58     }
    61     }
       
    62 
       
    63     ec_command_clear(&master->simple_command);
       
    64     ec_command_clear(&master->watch_command);
    59 }
    65 }
    60 
    66 
    61 /*****************************************************************************/
    67 /*****************************************************************************/
    62 
    68 
    63 /**
    69 /**
    70 void ec_master_reset(ec_master_t *master
    76 void ec_master_reset(ec_master_t *master
    71                      /**< Zeiger auf den zurückzusetzenden Master */
    77                      /**< Zeiger auf den zurückzusetzenden Master */
    72                      )
    78                      )
    73 {
    79 {
    74     unsigned int i;
    80     unsigned int i;
    75     ec_command_t *command, *next_command;
    81     ec_command_t *command, *next_c;
    76     ec_domain_t *domain, *next_domain;
    82     ec_domain_t *domain, *next_d;
    77 
    83 
    78     // Alle Slaves entfernen
    84     // Alle Slaves entfernen
    79     if (master->slaves) {
    85     if (master->slaves) {
    80         for (i = 0; i < master->slave_count; i++) {
    86         for (i = 0; i < master->slave_count; i++) {
    81             ec_slave_clear(master->slaves + i);
    87             ec_slave_clear(master->slaves + i);
    84         master->slaves = NULL;
    90         master->slaves = NULL;
    85     }
    91     }
    86     master->slave_count = 0;
    92     master->slave_count = 0;
    87 
    93 
    88     // Kommando-Warteschlange leeren
    94     // Kommando-Warteschlange leeren
    89     list_for_each_entry_safe(command, next_command, &master->commands, list) {
    95     list_for_each_entry_safe(command, next_c, &master->command_queue, queue) {
    90         command->state = EC_CMD_ERROR;
    96         command->state = EC_CMD_ERROR;
    91         list_del_init(&command->list);
    97         list_del_init(&command->queue);
    92     }
    98     }
    93 
    99 
    94     // Domain-Liste leeren
   100     // Domain-Liste leeren
    95     list_for_each_entry_safe(domain, next_domain, &master->domains, list) {
   101     list_for_each_entry_safe(domain, next_d, &master->domains, list) {
    96         list_del(&domain->list);
   102         list_del(&domain->list);
    97         ec_domain_clear(domain);
   103         ec_domain_clear(domain);
    98         kfree(domain);
   104         kfree(domain);
    99     }
   105     }
   100 
   106 
   164                              )
   170                              )
   165 {
   171 {
   166     ec_command_t *queued_command;
   172     ec_command_t *queued_command;
   167 
   173 
   168     // Ist das Kommando schon in der Warteschlange?
   174     // Ist das Kommando schon in der Warteschlange?
   169     list_for_each_entry(queued_command, &master->commands, list) {
   175     list_for_each_entry(queued_command, &master->command_queue, queue) {
   170         if (queued_command == command) {
   176         if (queued_command == command) {
   171             command->state = EC_CMD_QUEUED;
   177             command->state = EC_CMD_QUEUED;
   172             if (unlikely(master->debug_level))
   178             if (unlikely(master->debug_level))
   173                 EC_WARN("command already queued.\n");
   179                 EC_WARN("command already queued.\n");
   174             return;
   180             return;
   175         }
   181         }
   176     }
   182     }
   177 
   183 
   178     list_add_tail(&command->list, &master->commands);
   184     list_add_tail(&command->queue, &master->command_queue);
   179     command->state = EC_CMD_QUEUED;
   185     command->state = EC_CMD_QUEUED;
   180 }
   186 }
   181 
   187 
   182 /*****************************************************************************/
   188 /*****************************************************************************/
   183 
   189 
   204     frame_data = ec_device_tx_data(master->device);
   210     frame_data = ec_device_tx_data(master->device);
   205     cur_data = frame_data + EC_FRAME_HEADER_SIZE;
   211     cur_data = frame_data + EC_FRAME_HEADER_SIZE;
   206     follows_word = NULL;
   212     follows_word = NULL;
   207 
   213 
   208     // Aktuellen Frame mit Kommandos füllen
   214     // Aktuellen Frame mit Kommandos füllen
   209     list_for_each_entry(command, &master->commands, list) {
   215     list_for_each_entry(command, &master->command_queue, queue) {
   210         if (command->state != EC_CMD_QUEUED) continue;
   216         if (command->state != EC_CMD_QUEUED) continue;
   211 
   217 
   212         // Passt das aktuelle Kommando noch in den aktuellen Rahmen?
   218         // Passt das aktuelle Kommando noch in den aktuellen Rahmen?
   213         command_size = EC_COMMAND_HEADER_SIZE + command->data_size
   219         command_size = EC_COMMAND_HEADER_SIZE + command->data_size
   214             + EC_COMMAND_FOOTER_SIZE;
   220             + EC_COMMAND_FOOTER_SIZE;
   236         // EtherCAT command data
   242         // EtherCAT command data
   237         memcpy(cur_data, command->data, command->data_size);
   243         memcpy(cur_data, command->data, command->data_size);
   238         cur_data += command->data_size;
   244         cur_data += command->data_size;
   239 
   245 
   240         // EtherCAT command footer
   246         // EtherCAT command footer
   241         EC_WRITE_U16(cur_data, command->working_counter);
   247         EC_WRITE_U16(cur_data, 0x0000); // Working counter
   242         cur_data += EC_COMMAND_FOOTER_SIZE;
   248         cur_data += EC_COMMAND_FOOTER_SIZE;
   243     }
   249     }
   244 
   250 
   245     if (cur_data - frame_data == EC_FRAME_HEADER_SIZE) {
   251     if (cur_data - frame_data == EC_FRAME_HEADER_SIZE) {
   246         if (unlikely(master->debug_level > 0)) EC_DBG("nothing to send.\n");
   252         if (unlikely(master->debug_level > 0)) EC_DBG("nothing to send.\n");
   321             return;
   327             return;
   322         }
   328         }
   323 
   329 
   324         // Suche passendes Kommando in der Liste
   330         // Suche passendes Kommando in der Liste
   325         matched = 0;
   331         matched = 0;
   326         list_for_each_entry(command, &master->commands, list) {
   332         list_for_each_entry(command, &master->command_queue, queue) {
   327             if (command->state == EC_CMD_SENT
   333             if (command->state == EC_CMD_SENT
   328                 && command->type == command_type
   334                 && command->type == command_type
   329                 && command->index == command_index
   335                 && command->index == command_index
   330                 && command->data_size == data_size) {
   336                 && command->data_size == data_size) {
   331                 matched = 1;
   337                 matched = 1;
   347 
   353 
   348         // Working-Counter setzen
   354         // Working-Counter setzen
   349         command->working_counter = EC_READ_U16(cur_data);
   355         command->working_counter = EC_READ_U16(cur_data);
   350         cur_data += EC_COMMAND_FOOTER_SIZE;
   356         cur_data += EC_COMMAND_FOOTER_SIZE;
   351 
   357 
   352         // Kommando aus der Liste entfernen
   358         // Kommando aus der Warteschlange entfernen
   353         command->state = EC_CMD_RECEIVED;
   359         command->state = EC_CMD_RECEIVED;
   354         list_del_init(&command->list);
   360         list_del_init(&command->queue);
   355     }
   361     }
   356 }
   362 }
   357 
   363 
   358 /*****************************************************************************/
   364 /*****************************************************************************/
   359 
   365 
   364    nochmals gesendet.
   370    nochmals gesendet.
   365 
   371 
   366    \return 0 bei Erfolg, sonst < 0
   372    \return 0 bei Erfolg, sonst < 0
   367 */
   373 */
   368 
   374 
   369 int ec_master_simple_io(ec_master_t *master, /**< EtherCAT-Master */
   375 int ec_master_simple_io(ec_master_t *master /**< EtherCAT-Master */)
   370                         ec_command_t *command /**< Kommando */
       
   371                         )
       
   372 {
   376 {
   373     unsigned int response_tries_left;
   377     unsigned int response_tries_left;
       
   378     ec_command_t *command;
   374 
   379 
   375     response_tries_left = 10;
   380     response_tries_left = 10;
       
   381     command = &master->simple_command;
   376 
   382 
   377     while (1)
   383     while (1)
   378     {
   384     {
   379         ec_master_queue_command(master, command);
   385         ec_master_queue_command(master, command);
   380         ecrt_master_sync_io(master);
   386         ecrt_master_sync_io(master);
   413    \return 0 bei Erfolg, sonst < 0
   419    \return 0 bei Erfolg, sonst < 0
   414 */
   420 */
   415 
   421 
   416 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT-Master */)
   422 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT-Master */)
   417 {
   423 {
   418     ec_command_t command;
       
   419     ec_slave_t *slave;
   424     ec_slave_t *slave;
   420     ec_slave_ident_t *ident;
   425     ec_slave_ident_t *ident;
   421     unsigned int i;
   426     unsigned int i;
   422     uint8_t data[2];
   427     ec_command_t *command;
   423 
   428 
   424     if (master->slaves || master->slave_count) {
   429     if (master->slaves || master->slave_count) {
   425         EC_ERR("Slave scan already done!\n");
   430         EC_ERR("Slave scan already done!\n");
   426         return -1;
   431         return -1;
   427     }
   432     }
   428 
   433 
       
   434     command = &master->simple_command;
       
   435 
   429     // Determine number of slaves on bus
   436     // Determine number of slaves on bus
   430     ec_command_init_brd(&command, 0x0000, 4);
   437     if (ec_command_brd(command, 0x0000, 4)) return -1;
   431     if (unlikely(ec_master_simple_io(master, &command))) return -1;
   438     if (unlikely(ec_master_simple_io(master))) return -1;
   432     master->slave_count = command.working_counter;
   439     master->slave_count = command->working_counter;
   433     EC_INFO("Found %i slaves on bus.\n", master->slave_count);
   440     EC_INFO("Found %i slaves on bus.\n", master->slave_count);
   434 
   441 
   435     if (!master->slave_count) return 0;
   442     if (!master->slave_count) return 0;
   436 
   443 
   437     if (!(master->slaves = (ec_slave_t *) kmalloc(master->slave_count
   444     if (!(master->slaves = (ec_slave_t *) kmalloc(master->slave_count
   453     for (i = 0; i < master->slave_count; i++)
   460     for (i = 0; i < master->slave_count; i++)
   454     {
   461     {
   455         slave = master->slaves + i;
   462         slave = master->slaves + i;
   456 
   463 
   457         // Write station address
   464         // Write station address
   458         EC_WRITE_U16(data, slave->station_address);
   465         if (ec_command_apwr(command, slave->ring_position,
   459         ec_command_init_apwr(&command, slave->ring_position,
   466                             0x0010, sizeof(uint16_t))) return -1;
   460                              0x0010, sizeof(uint16_t), data);
   467         EC_WRITE_U16(command->data, slave->station_address);
   461         if (unlikely(ec_master_simple_io(master, &command))) {
   468         if (unlikely(ec_master_simple_io(master))) {
   462             EC_ERR("Writing station address failed on slave %i!\n", i);
   469             EC_ERR("Writing station address failed on slave %i!\n", i);
   463             return -1;
   470             return -1;
   464         }
   471         }
   465 
   472 
   466         // Fetch all slave information
   473         // Fetch all slave information
   711                                      /**< EtherCAT-Master */
   718                                      /**< EtherCAT-Master */
   712                                      )
   719                                      )
   713 {
   720 {
   714     unsigned int first;
   721     unsigned int first;
   715 
   722 
       
   723     if (unlikely(master->watch_command.state == EC_CMD_INIT)) return;
       
   724 
   716     first = 1;
   725     first = 1;
   717 
   726 
   718     if (master->watch_command.working_counter != master->slaves_responding ||
   727     if (master->watch_command.working_counter != master->slaves_responding ||
   719         master->watch_command.data[0] != master->slave_states)
   728         master->watch_command.data[0] != master->slave_states)
   720     {
   729     {
   787 
   796 
   788 int ecrt_master_activate(ec_master_t *master /**< EtherCAT-Master */)
   797 int ecrt_master_activate(ec_master_t *master /**< EtherCAT-Master */)
   789 {
   798 {
   790     unsigned int i, j;
   799     unsigned int i, j;
   791     ec_slave_t *slave;
   800     ec_slave_t *slave;
   792     ec_command_t command;
   801     ec_command_t *command;
   793     const ec_sync_t *sync;
   802     const ec_sync_t *sync;
   794     const ec_slave_type_t *type;
   803     const ec_slave_type_t *type;
   795     const ec_fmmu_t *fmmu;
   804     const ec_fmmu_t *fmmu;
   796     uint8_t data[256];
       
   797     uint32_t domain_offset;
   805     uint32_t domain_offset;
   798     ec_domain_t *domain;
   806     ec_domain_t *domain;
   799     ec_eeprom_sync_t *eeprom_sync;
   807     ec_eeprom_sync_t *eeprom_sync;
       
   808 
       
   809     command = &master->simple_command;
       
   810 
       
   811     if (ec_command_brd(&master->watch_command, 0x130, 2)) {
       
   812         EC_ERR("Failed to allocate watchdog command!\n");
       
   813         return -1;
       
   814     }
   800 
   815 
   801     // Domains erstellen
   816     // Domains erstellen
   802     domain_offset = 0;
   817     domain_offset = 0;
   803     list_for_each_entry(domain, &master->domains, list) {
   818     list_for_each_entry(domain, &master->domains, list) {
   804         if (ec_domain_alloc(domain, domain_offset)) {
   819         if (ec_domain_alloc(domain, domain_offset)) {
   824         // Check and reset CRC fault counters
   839         // Check and reset CRC fault counters
   825         ec_slave_check_crc(slave);
   840         ec_slave_check_crc(slave);
   826 
   841 
   827         // Resetting FMMUs
   842         // Resetting FMMUs
   828         if (slave->base_fmmu_count) {
   843         if (slave->base_fmmu_count) {
   829             memset(data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
   844             if (ec_command_npwr(command, slave->station_address, 0x0600,
   830             ec_command_init_npwr(&command, slave->station_address, 0x0600,
   845                                 EC_FMMU_SIZE * slave->base_fmmu_count))
   831                                  EC_FMMU_SIZE * slave->base_fmmu_count, data);
   846                 return -1;
   832             if (unlikely(ec_master_simple_io(master, &command))) {
   847             memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
       
   848             if (unlikely(ec_master_simple_io(master))) {
   833                 EC_ERR("Resetting FMMUs failed on slave %i!\n",
   849                 EC_ERR("Resetting FMMUs failed on slave %i!\n",
   834                        slave->ring_position);
   850                        slave->ring_position);
   835                 return -1;
   851                 return -1;
   836             }
   852             }
   837         }
   853         }
   838 
   854 
   839         // Resetting Sync Manager channels
   855         // Resetting Sync Manager channels
   840         if (slave->base_sync_count) {
   856         if (slave->base_sync_count) {
   841             memset(data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
   857             if (ec_command_npwr(command, slave->station_address, 0x0800,
   842             ec_command_init_npwr(&command, slave->station_address, 0x0800,
   858                                 EC_SYNC_SIZE * slave->base_sync_count))
   843                                  EC_SYNC_SIZE * slave->base_sync_count, data);
   859                 return -1;
   844             if (unlikely(ec_master_simple_io(master, &command))) {
   860             memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count);
       
   861             if (unlikely(ec_master_simple_io(master))) {
   845                 EC_ERR("Resetting sync managers failed on slave %i!\n",
   862                 EC_ERR("Resetting sync managers failed on slave %i!\n",
   846                        slave->ring_position);
   863                        slave->ring_position);
   847                 return -1;
   864                 return -1;
   848             }
   865             }
   849         }
   866         }
   851         // Set Sync Managers
   868         // Set Sync Managers
   852         if (type) {
   869         if (type) {
   853             for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++)
   870             for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++)
   854             {
   871             {
   855                 sync = type->sync_managers[j];
   872                 sync = type->sync_managers[j];
   856                 ec_sync_config(sync, data);
   873                 if (ec_command_npwr(command, slave->station_address,
   857                 ec_command_init_npwr(&command, slave->station_address,
   874                                     0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE))
   858                                      0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE,
   875                     return -1;
   859                                      data);
   876                 ec_sync_config(sync, command->data);
   860                 if (unlikely(ec_master_simple_io(master, &command))) {
   877                 if (unlikely(ec_master_simple_io(master))) {
   861                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
   878                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
   862                            j, slave->ring_position);
   879                            j, slave->ring_position);
   863                     return -1;
   880                     return -1;
   864                 }
   881                 }
   865             }
   882             }
   866         }
   883         }
   867         else if (slave->sii_mailbox_protocols) { // Unknown slave, has mailbox
   884         else if (slave->sii_mailbox_protocols) { // Unknown slave, has mailbox
   868             list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
   885             list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
   869                 ec_eeprom_sync_config(eeprom_sync, data);
   886                 if (ec_command_npwr(command, slave->station_address,
   870                 ec_command_init_npwr(&command, slave->station_address,
   887                                     0x800 + eeprom_sync->index * EC_SYNC_SIZE,
   871                                      0x800 + eeprom_sync->index * EC_SYNC_SIZE,
   888                                     EC_SYNC_SIZE)) return -1;
   872                                      EC_SYNC_SIZE, data);
   889                 ec_eeprom_sync_config(eeprom_sync, command->data);
   873                 if (unlikely(ec_master_simple_io(master, &command))) {
   890                 if (unlikely(ec_master_simple_io(master))) {
   874                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
   891                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
   875                            eeprom_sync->index, slave->ring_position);
   892                            eeprom_sync->index, slave->ring_position);
   876                     return -1;
   893                     return -1;
   877                 }
   894                 }
   878             }
   895             }
   894 
   911 
   895         // Set FMMUs
   912         // Set FMMUs
   896         for (j = 0; j < slave->fmmu_count; j++)
   913         for (j = 0; j < slave->fmmu_count; j++)
   897         {
   914         {
   898             fmmu = &slave->fmmus[j];
   915             fmmu = &slave->fmmus[j];
   899 
   916             if (ec_command_npwr(command, slave->station_address,
   900             ec_fmmu_config(fmmu, data);
   917                                 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE))
   901             ec_command_init_npwr(&command, slave->station_address,
   918                 return -1;
   902                                  0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE,
   919             ec_fmmu_config(fmmu, command->data);
   903                                  data);
   920             if (unlikely(ec_master_simple_io(master))) {
   904             if (unlikely(ec_master_simple_io(master, &command))) {
       
   905                 EC_ERR("Setting FMMU %i failed on slave %i!\n",
   921                 EC_ERR("Setting FMMU %i failed on slave %i!\n",
   906                        j, slave->ring_position);
   922                        j, slave->ring_position);
   907                 return -1;
   923                 return -1;
   908             }
   924             }
   909         }
   925         }
   978    Sendet und empfängt Kommandos synchron.
   994    Sendet und empfängt Kommandos synchron.
   979 */
   995 */
   980 
   996 
   981 void ecrt_master_sync_io(ec_master_t *master)
   997 void ecrt_master_sync_io(ec_master_t *master)
   982 {
   998 {
   983     ec_command_t *command, *next;
   999     ec_command_t *command, *n;
   984     unsigned int commands_sent;
  1000     unsigned int commands_sent;
   985     cycles_t t_start, t_end, t_timeout;
  1001     cycles_t t_start, t_end, t_timeout;
   986 
  1002 
   987     ec_master_output_stats(master);
  1003     // Kommandos senden
   988 
  1004     ecrt_master_async_send(master);
   989     if (unlikely(!master->device->link_state)) {
       
   990         // Link DOWN, keines der Kommandos kann gesendet werden.
       
   991         list_for_each_entry_safe(command, next, &master->commands, list) {
       
   992             command->state = EC_CMD_ERROR;
       
   993             list_del_init(&command->list);
       
   994         }
       
   995 
       
   996         // Device-Zustand abfragen
       
   997         ec_device_call_isr(master->device);
       
   998         return;
       
   999     }
       
  1000 
       
  1001     // Rahmen senden
       
  1002     ec_master_send_commands(master);
       
  1003 
  1005 
  1004     t_start = get_cycles(); // Sendezeit nehmen
  1006     t_start = get_cycles(); // Sendezeit nehmen
  1005     t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
  1007     t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
  1006 
  1008 
  1007     while (1)
  1009     while (1) // Aktiv auf Empfang warten
  1008     {
  1010     {
  1009         ec_device_call_isr(master->device);
  1011         ec_device_call_isr(master->device);
  1010 
  1012 
  1011         t_end = get_cycles(); // Aktuelle Zeit nehmen
  1013         t_end = get_cycles(); // Aktuelle Zeit nehmen
  1012         if (t_end - t_start >= t_timeout) break; // Timeout
  1014         if (t_end - t_start >= t_timeout) break; // Timeout
  1013 
  1015 
  1014         commands_sent = 0;
  1016         commands_sent = 0;
  1015         list_for_each_entry_safe(command, next, &master->commands, list) {
  1017         list_for_each_entry_safe(command, n, &master->command_queue, queue) {
  1016             if (command->state == EC_CMD_RECEIVED)
  1018             if (command->state == EC_CMD_RECEIVED)
  1017                 list_del_init(&command->list);
  1019                 list_del_init(&command->queue);
  1018             else if (command->state == EC_CMD_SENT)
  1020             else if (command->state == EC_CMD_SENT)
  1019                 commands_sent++;
  1021                 commands_sent++;
  1020         }
  1022         }
  1021 
  1023 
  1022         if (!commands_sent) break;
  1024         if (!commands_sent) break;
  1023     }
  1025     }
  1024 
  1026 
  1025     // Zeit abgelaufen. Alle verbleibenden Kommandos entfernen.
  1027     // Zeit abgelaufen. Alle verbleibenden Kommandos entfernen.
  1026     list_for_each_entry_safe(command, next, &master->commands, list) {
  1028     list_for_each_entry_safe(command, n, &master->command_queue, queue) {
  1027         switch (command->state) {
  1029         switch (command->state) {
  1028             case EC_CMD_SENT:
  1030             case EC_CMD_SENT:
  1029             case EC_CMD_QUEUED:
  1031             case EC_CMD_QUEUED:
  1030                 command->state = EC_CMD_TIMEOUT;
  1032                 command->state = EC_CMD_TIMEOUT;
  1031                 master->stats.timeouts++;
  1033                 master->stats.timeouts++;
  1036                 ec_master_output_stats(master);
  1038                 ec_master_output_stats(master);
  1037                 break;
  1039                 break;
  1038             default:
  1040             default:
  1039                 break;
  1041                 break;
  1040         }
  1042         }
  1041         list_del_init(&command->list);
  1043         list_del_init(&command->queue);
  1042     }
  1044     }
  1043 }
  1045 }
  1044 
  1046 
  1045 /*****************************************************************************/
  1047 /*****************************************************************************/
  1046 
  1048 
  1048    Sendet Kommandos asynchron.
  1050    Sendet Kommandos asynchron.
  1049 */
  1051 */
  1050 
  1052 
  1051 void ecrt_master_async_send(ec_master_t *master)
  1053 void ecrt_master_async_send(ec_master_t *master)
  1052 {
  1054 {
  1053     ec_command_t *command, *next;
  1055     ec_command_t *command, *n;
  1054 
       
  1055     ec_master_output_stats(master);
       
  1056 
  1056 
  1057     if (unlikely(!master->device->link_state)) {
  1057     if (unlikely(!master->device->link_state)) {
  1058         // Link DOWN, keines der Kommandos kann gesendet werden.
  1058         // Link DOWN, keines der Kommandos kann gesendet werden.
  1059         list_for_each_entry_safe(command, next, &master->commands, list) {
  1059         list_for_each_entry_safe(command, n, &master->command_queue, queue) {
  1060             command->state = EC_CMD_ERROR;
  1060             command->state = EC_CMD_ERROR;
  1061             list_del_init(&command->list);
  1061             list_del_init(&command->queue);
  1062         }
  1062         }
  1063 
  1063 
  1064         // Device-Zustand abfragen
  1064         // Device-Zustand abfragen
  1065         ec_device_call_isr(master->device);
  1065         ec_device_call_isr(master->device);
  1066         return;
  1066         return;
  1067     }
  1067     }
  1068 
  1068 
  1069     // Watch-Kommando hinzufügen
       
  1070     ec_command_init_brd(&master->watch_command, 0x130, 2);
       
  1071     ec_master_queue_command(master, &master->watch_command);
       
  1072 
       
  1073     // Rahmen senden
  1069     // Rahmen senden
  1074     ec_master_send_commands(master);
  1070     ec_master_send_commands(master);
  1075 }
  1071 }
  1076 
  1072 
  1077 /*****************************************************************************/
  1073 /*****************************************************************************/
  1085     ec_command_t *command, *next;
  1081     ec_command_t *command, *next;
  1086 
  1082 
  1087     ec_device_call_isr(master->device);
  1083     ec_device_call_isr(master->device);
  1088 
  1084 
  1089     // Alle empfangenen Kommandos aus der Liste entfernen
  1085     // Alle empfangenen Kommandos aus der Liste entfernen
  1090     list_for_each_entry_safe(command, next, &master->commands, list)
  1086     list_for_each_entry_safe(command, next, &master->command_queue, queue)
  1091         if (command->state == EC_CMD_RECEIVED)
  1087         if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue);
  1092             list_del_init(&command->list);
       
  1093 
  1088 
  1094     // Alle verbleibenden Kommandos entfernen.
  1089     // Alle verbleibenden Kommandos entfernen.
  1095     list_for_each_entry_safe(command, next, &master->commands, list) {
  1090     list_for_each_entry_safe(command, next, &master->command_queue, queue) {
  1096         switch (command->state) {
  1091         switch (command->state) {
  1097             case EC_CMD_SENT:
  1092             case EC_CMD_SENT:
  1098             case EC_CMD_QUEUED:
  1093             case EC_CMD_QUEUED:
  1099                 command->state = EC_CMD_TIMEOUT;
  1094                 command->state = EC_CMD_TIMEOUT;
  1100                 master->stats.timeouts++;
  1095                 master->stats.timeouts++;
  1101                 ec_master_output_stats(master);
  1096                 ec_master_output_stats(master);
  1102                 break;
  1097                 break;
  1103             default:
  1098             default:
  1104                 break;
  1099                 break;
  1105         }
  1100         }
  1106         list_del_init(&command->list);
  1101         list_del_init(&command->queue);
  1107     }
  1102     }
  1108 
       
  1109     // Watch-Kommando verarbeiten
       
  1110     ec_master_process_watch_command(master);
       
  1111 
       
  1112     // Statistiken ausgeben
       
  1113     ec_master_output_stats(master);
       
  1114 }
  1103 }
  1115 
  1104 
  1116 /*****************************************************************************/
  1105 /*****************************************************************************/
  1117 
  1106 
  1118 /**
  1107 /**
  1126 void ecrt_master_prepare_async_io(ec_master_t *master)
  1115 void ecrt_master_prepare_async_io(ec_master_t *master)
  1127 {
  1116 {
  1128     ec_domain_t *domain;
  1117     ec_domain_t *domain;
  1129     cycles_t t_start, t_end, t_timeout;
  1118     cycles_t t_start, t_end, t_timeout;
  1130 
  1119 
  1131     // Alle empfangenen Kommandos aus der Liste entfernen
  1120     // Kommandos aller Domains in die Warteschlange setzen
  1132     list_for_each_entry(domain, &master->domains, list)
  1121     list_for_each_entry(domain, &master->domains, list)
  1133         ecrt_domain_queue(domain);
  1122         ecrt_domain_queue(domain);
  1134 
  1123 
  1135     ecrt_master_async_send(master);
  1124     ecrt_master_async_send(master);
  1136 
  1125 
  1140     // Aktiv warten!
  1129     // Aktiv warten!
  1141     while (1) {
  1130     while (1) {
  1142         t_end = get_cycles();
  1131         t_end = get_cycles();
  1143         if (t_end - t_start >= t_timeout) break;
  1132         if (t_end - t_start >= t_timeout) break;
  1144     }
  1133     }
       
  1134 }
       
  1135 
       
  1136 /*****************************************************************************/
       
  1137 
       
  1138 /**
       
  1139    Führt Routinen im zyklischen Betrieb aus.
       
  1140 */
       
  1141 
       
  1142 void ecrt_master_run(ec_master_t *master /**< EtherCAT-Master */)
       
  1143 {
       
  1144     // Statistiken ausgeben
       
  1145     ec_master_output_stats(master);
       
  1146 
       
  1147     // Watchdog-Kommando
       
  1148     ec_master_process_watch_command(master);
       
  1149     ec_master_queue_command(master, &master->watch_command);
  1145 }
  1150 }
  1146 
  1151 
  1147 /*****************************************************************************/
  1152 /*****************************************************************************/
  1148 
  1153 
  1149 /**
  1154 /**
  1196 EXPORT_SYMBOL(ecrt_master_fetch_sdo_lists);
  1201 EXPORT_SYMBOL(ecrt_master_fetch_sdo_lists);
  1197 EXPORT_SYMBOL(ecrt_master_prepare_async_io);
  1202 EXPORT_SYMBOL(ecrt_master_prepare_async_io);
  1198 EXPORT_SYMBOL(ecrt_master_sync_io);
  1203 EXPORT_SYMBOL(ecrt_master_sync_io);
  1199 EXPORT_SYMBOL(ecrt_master_async_send);
  1204 EXPORT_SYMBOL(ecrt_master_async_send);
  1200 EXPORT_SYMBOL(ecrt_master_async_receive);
  1205 EXPORT_SYMBOL(ecrt_master_async_receive);
       
  1206 EXPORT_SYMBOL(ecrt_master_run);
  1201 EXPORT_SYMBOL(ecrt_master_debug);
  1207 EXPORT_SYMBOL(ecrt_master_debug);
  1202 EXPORT_SYMBOL(ecrt_master_print);
  1208 EXPORT_SYMBOL(ecrt_master_print);
  1203 EXPORT_SYMBOL(ecrt_master_get_slave);
  1209 EXPORT_SYMBOL(ecrt_master_get_slave);
  1204 
  1210 
  1205 /*****************************************************************************/
  1211 /*****************************************************************************/