master/slave.c
changeset 98 f564d0929292
parent 91 0120d6214948
child 101 b0c19892145a
equal deleted inserted replaced
97:e6264685dd7b 98:f564d0929292
    12 #include <linux/delay.h>
    12 #include <linux/delay.h>
    13 
    13 
    14 #include "../include/EtherCAT_si.h"
    14 #include "../include/EtherCAT_si.h"
    15 #include "globals.h"
    15 #include "globals.h"
    16 #include "slave.h"
    16 #include "slave.h"
    17 #include "frame.h"
    17 #include "command.h"
       
    18 #include "master.h"
    18 
    19 
    19 /*****************************************************************************/
    20 /*****************************************************************************/
    20 
    21 
    21 /**
    22 /**
    22    EtherCAT-Slave-Konstruktor.
    23    EtherCAT-Slave-Konstruktor.
    62    \return 0 wenn alles ok, < 0 bei Fehler.
    63    \return 0 wenn alles ok, < 0 bei Fehler.
    63 */
    64 */
    64 
    65 
    65 int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT-Slave */)
    66 int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT-Slave */)
    66 {
    67 {
    67     ec_frame_t frame;
    68     ec_command_t command;
    68 
    69 
    69     // Read base data
    70     // Read base data
    70     ec_frame_init_nprd(&frame, slave->master, slave->station_address,
    71     ec_command_init_nprd(&command, slave->station_address, 0x0000, 6);
    71                        0x0000, 6);
    72     if (unlikely(ec_master_simple_io(slave->master, &command))) {
    72 
       
    73     if (unlikely(ec_frame_send_receive(&frame))) {
       
    74         EC_ERR("Reading base datafrom slave %i failed!\n",
    73         EC_ERR("Reading base datafrom slave %i failed!\n",
    75                slave->ring_position);
    74                slave->ring_position);
    76         return -1;
    75         return -1;
    77     }
    76     }
    78 
    77 
    79     slave->base_type =       EC_READ_U8 (frame.data);
    78     slave->base_type =       EC_READ_U8 (command.data);
    80     slave->base_revision =   EC_READ_U8 (frame.data + 1);
    79     slave->base_revision =   EC_READ_U8 (command.data + 1);
    81     slave->base_build =      EC_READ_U16(frame.data + 2);
    80     slave->base_build =      EC_READ_U16(command.data + 2);
    82     slave->base_fmmu_count = EC_READ_U8 (frame.data + 4);
    81     slave->base_fmmu_count = EC_READ_U8 (command.data + 4);
    83     slave->base_sync_count = EC_READ_U8 (frame.data + 5);
    82     slave->base_sync_count = EC_READ_U8 (command.data + 5);
    84 
    83 
    85     if (slave->base_fmmu_count > EC_MAX_FMMUS)
    84     if (slave->base_fmmu_count > EC_MAX_FMMUS)
    86         slave->base_fmmu_count = EC_MAX_FMMUS;
    85         slave->base_fmmu_count = EC_MAX_FMMUS;
    87 
    86 
    88     // Read identification from "Slave Information Interface" (SII)
    87     // Read identification from "Slave Information Interface" (SII)
   128                       unsigned int *target
   127                       unsigned int *target
   129                       /**< Zeiger auf einen 4 Byte großen Speicher zum Ablegen
   128                       /**< Zeiger auf einen 4 Byte großen Speicher zum Ablegen
   130                          der Daten */
   129                          der Daten */
   131                       )
   130                       )
   132 {
   131 {
   133     ec_frame_t frame;
   132     ec_command_t command;
   134     unsigned char data[10];
   133     unsigned char data[10];
   135     unsigned int tries_left;
   134     cycles_t start, end, timeout;
   136 
   135 
   137     // Initiate read operation
   136     // Initiate read operation
   138 
   137 
   139     EC_WRITE_U8 (data,     0x00);
   138     EC_WRITE_U8 (data,     0x00);
   140     EC_WRITE_U8 (data + 1, 0x01);
   139     EC_WRITE_U8 (data + 1, 0x01);
   141     EC_WRITE_U16(data + 2, offset);
   140     EC_WRITE_U16(data + 2, offset);
   142     EC_WRITE_U16(data + 4, 0x0000);
   141     EC_WRITE_U16(data + 4, 0x0000);
   143 
   142 
   144     ec_frame_init_npwr(&frame, slave->master, slave->station_address,
   143     ec_command_init_npwr(&command, slave->station_address, 0x502, 6, data);
   145                        0x502, 6, data);
   144     if (unlikely(ec_master_simple_io(slave->master, &command))) {
   146 
       
   147     if (unlikely(ec_frame_send_receive(&frame))) {
       
   148         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   145         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   149         return -1;
   146         return -1;
   150     }
   147     }
   151 
   148 
   152     // Der Slave legt die Informationen des Slave-Information-Interface
   149     // Der Slave legt die Informationen des Slave-Information-Interface
   153     // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange
   150     // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange
   154     // den Status auslesen, bis das Bit weg ist.
   151     // den Status auslesen, bis das Bit weg ist.
   155 
   152 
   156     tries_left = 100;
   153     start = get_cycles();
   157     while (likely(tries_left))
   154     timeout = cpu_khz; // 1ms
       
   155 
       
   156     do
   158     {
   157     {
   159         udelay(10);
   158         ec_command_init_nprd(&command, slave->station_address, 0x502, 10);
   160 
   159         if (unlikely(ec_master_simple_io(slave->master, &command))) {
   161         ec_frame_init_nprd(&frame, slave->master, slave->station_address,
       
   162                            0x502, 10);
       
   163 
       
   164         if (unlikely(ec_frame_send_receive(&frame))) {
       
   165             EC_ERR("Getting SII-read status failed on slave %i!\n",
   160             EC_ERR("Getting SII-read status failed on slave %i!\n",
   166                    slave->ring_position);
   161                    slave->ring_position);
   167             return -1;
   162             return -1;
   168         }
   163         }
   169 
   164 
   170         if (likely((EC_READ_U8(frame.data + 1) & 0x81) == 0)) {
   165         end = get_cycles();
   171             memcpy(target, frame.data + 6, 4);
   166 
       
   167         if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
       
   168             memcpy(target, command.data + 6, 4);
   172             break;
   169             break;
   173         }
   170         }
   174 
   171     }
   175         tries_left--;
   172     while (likely((end - start) < timeout));
   176     }
   173 
   177 
   174     if (unlikely((end - start) >= timeout)) {
   178     if (unlikely(!tries_left)) {
       
   179         EC_ERR("SSI-read. Slave %i timed out!\n", slave->ring_position);
   175         EC_ERR("SSI-read. Slave %i timed out!\n", slave->ring_position);
   180         return -1;
   176         return -1;
   181     }
   177     }
   182 
   178 
   183     return 0;
   179     return 0;
   195                         /**< Slave, dessen Zustand geändert werden soll */
   191                         /**< Slave, dessen Zustand geändert werden soll */
   196                         uint8_t state
   192                         uint8_t state
   197                         /**< Alter Zustand */
   193                         /**< Alter Zustand */
   198                         )
   194                         )
   199 {
   195 {
   200     ec_frame_t frame;
   196     ec_command_t command;
   201     unsigned char data[2];
   197     unsigned char data[2];
   202     unsigned int tries_left;
   198     cycles_t start, end, timeout;
   203 
   199 
   204     EC_WRITE_U16(data, state | EC_ACK);
   200     EC_WRITE_U16(data, state | EC_ACK);
   205 
   201 
   206     ec_frame_init_npwr(&frame, slave->master, slave->station_address,
   202     ec_command_init_npwr(&command, slave->station_address, 0x0120, 2, data);
   207                        0x0120, 2, data);
   203     if (unlikely(ec_master_simple_io(slave->master, &command))) {
   208 
       
   209     if (unlikely(ec_frame_send_receive(&frame))) {
       
   210         EC_WARN("State %02X acknowledge failed on slave %i!\n",
   204         EC_WARN("State %02X acknowledge failed on slave %i!\n",
   211                 state, slave->ring_position);
   205                 state, slave->ring_position);
   212         return;
   206         return;
   213     }
   207     }
   214 
   208 
   215     tries_left = 100;
   209     start = get_cycles();
   216     while (likely(tries_left))
   210     timeout = cpu_khz; // 1ms
       
   211 
       
   212     do
   217     {
   213     {
   218         udelay(10);
   214         ec_command_init_nprd(&command, slave->station_address, 0x0130, 2);
   219 
   215         if (unlikely(ec_master_simple_io(slave->master, &command))) {
   220         ec_frame_init_nprd(&frame, slave->master, slave->station_address,
       
   221                            0x0130, 2);
       
   222 
       
   223         if (unlikely(ec_frame_send_receive(&frame))) {
       
   224             EC_WARN("State %02X acknowledge checking failed on slave %i!\n",
   216             EC_WARN("State %02X acknowledge checking failed on slave %i!\n",
   225                     state, slave->ring_position);
   217                     state, slave->ring_position);
   226             return;
   218             return;
   227         }
   219         }
   228 
   220 
   229         if (unlikely(EC_READ_U8(frame.data) != state)) {
   221         end = get_cycles();
       
   222 
       
   223         if (unlikely(EC_READ_U8(command.data) != state)) {
   230             EC_WARN("Could not acknowledge state %02X on slave %i (code"
   224             EC_WARN("Could not acknowledge state %02X on slave %i (code"
   231                     " %02X)!\n", state, slave->ring_position,
   225                     " %02X)!\n", state, slave->ring_position,
   232                     EC_READ_U8(frame.data));
   226                     EC_READ_U8(command.data));
   233             return;
   227             return;
   234         }
   228         }
   235 
   229 
   236         if (likely(EC_READ_U8(frame.data) == state)) {
   230         if (likely(EC_READ_U8(command.data) == state)) {
   237             EC_INFO("Acknowleged state %02X on slave %i.\n", state,
   231             EC_INFO("Acknowleged state %02X on slave %i.\n", state,
   238                     slave->ring_position);
   232                     slave->ring_position);
   239             return;
   233             return;
   240         }
   234         }
   241 
   235     }
   242         tries_left--;
   236     while (likely((end - start) < timeout));
   243     }
   237 
   244 
   238     if (unlikely((end - start) >= timeout)) {
   245     if (unlikely(!tries_left)) {
       
   246         EC_WARN("Could not check state acknowledgement %02X of slave %i -"
   239         EC_WARN("Could not check state acknowledgement %02X of slave %i -"
   247                 " Timeout while checking!\n", state, slave->ring_position);
   240                 " Timeout while checking!\n", state, slave->ring_position);
   248         return;
   241         return;
   249     }
   242     }
   250 }
   243 }
   261                           /**< Slave, dessen Zustand geändert werden soll */
   254                           /**< Slave, dessen Zustand geändert werden soll */
   262                           uint8_t state
   255                           uint8_t state
   263                           /**< Neuer Zustand */
   256                           /**< Neuer Zustand */
   264                           )
   257                           )
   265 {
   258 {
   266     ec_frame_t frame;
   259     ec_command_t command;
   267     unsigned char data[2];
   260     unsigned char data[2];
   268     unsigned int tries_left;
   261     cycles_t start, end, timeout;
   269 
   262 
   270     EC_WRITE_U16(data, state);
   263     EC_WRITE_U16(data, state);
   271 
   264 
   272     ec_frame_init_npwr(&frame, slave->master, slave->station_address,
   265     ec_command_init_npwr(&command, slave->station_address, 0x0120, 2, data);
   273                        0x0120, 2, data);
   266     if (unlikely(ec_master_simple_io(slave->master, &command))) {
   274 
       
   275     if (unlikely(ec_frame_send_receive(&frame))) {
       
   276         EC_ERR("Failed to set state %02X on slave %i!\n",
   267         EC_ERR("Failed to set state %02X on slave %i!\n",
   277                state, slave->ring_position);
   268                state, slave->ring_position);
   278         return -1;
   269         return -1;
   279     }
   270     }
   280 
   271 
   281     tries_left = 100;
   272     start = get_cycles();
   282     while (likely(tries_left))
   273     timeout = cpu_khz; // 1ms
       
   274 
       
   275     do
   283     {
   276     {
   284         udelay(10);
   277         udelay(100); // Dem Slave etwas Zeit lassen...
   285 
   278 
   286         ec_frame_init_nprd(&frame, slave->master, slave->station_address,
   279         ec_command_init_nprd(&command, slave->station_address, 0x0130, 2);
   287                            0x0130, 2);
   280         if (unlikely(ec_master_simple_io(slave->master, &command))) {
   288 
       
   289         if (unlikely(ec_frame_send_receive(&frame))) {
       
   290             EC_ERR("Failed to check state %02X on slave %i!\n",
   281             EC_ERR("Failed to check state %02X on slave %i!\n",
   291                    state, slave->ring_position);
   282                    state, slave->ring_position);
   292             return -1;
   283             return -1;
   293         }
   284         }
   294 
   285 
   295         if (unlikely(EC_READ_U8(frame.data) & 0x10)) { // State change error
   286         end = get_cycles();
       
   287 
       
   288         if (unlikely(EC_READ_U8(command.data) & 0x10)) { // State change error
   296             EC_ERR("Could not set state %02X - Slave %i refused state change"
   289             EC_ERR("Could not set state %02X - Slave %i refused state change"
   297                    " (code %02X)!\n", state, slave->ring_position,
   290                    " (code %02X)!\n", state, slave->ring_position,
   298                    EC_READ_U8(frame.data));
   291                    EC_READ_U8(command.data));
   299             ec_slave_state_ack(slave, EC_READ_U8(frame.data) & 0x0F);
   292             ec_slave_state_ack(slave, EC_READ_U8(command.data) & 0x0F);
   300             return -1;
   293             return -1;
   301         }
   294         }
   302 
   295 
   303         if (likely(EC_READ_U8(frame.data) == (state & 0x0F))) {
   296         if (likely(EC_READ_U8(command.data) == (state & 0x0F))) {
   304             // State change successful
   297             // State change successful
   305             break;
   298             break;
   306         }
   299         }
   307 
   300     }
   308         tries_left--;
   301     while (likely((end - start) < timeout));
   309     }
   302 
   310 
   303     if (unlikely((end - start) >= timeout)) {
   311     if (unlikely(!tries_left)) {
       
   312         EC_ERR("Could not check state %02X of slave %i - Timeout!\n", state,
   304         EC_ERR("Could not check state %02X of slave %i - Timeout!\n", state,
   313                slave->ring_position);
   305                slave->ring_position);
   314         return -1;
   306         return -1;
   315     }
   307     }
   316 
   308 
   403    \return 0 bei Erfolg, sonst < 0
   395    \return 0 bei Erfolg, sonst < 0
   404 */
   396 */
   405 
   397 
   406 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */)
   398 int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT-Slave */)
   407 {
   399 {
   408     ec_frame_t frame;
   400     ec_command_t command;
   409     uint8_t data[4];
   401     uint8_t data[4];
   410 
   402 
   411     ec_frame_init_nprd(&frame, slave->master, slave->station_address,
   403     ec_command_init_nprd(&command, slave->station_address, 0x0300, 4);
   412                        0x0300, 4);
   404     if (unlikely(ec_master_simple_io(slave->master, &command))) {
   413 
       
   414     if (unlikely(ec_frame_send_receive(&frame))) {
       
   415         EC_WARN("Reading CRC fault counters failed on slave %i!\n",
   405         EC_WARN("Reading CRC fault counters failed on slave %i!\n",
   416                 slave->ring_position);
   406                 slave->ring_position);
   417         return -1;
   407         return -1;
   418     }
   408     }
   419 
   409 
   420     // No CRC faults.
   410     // No CRC faults.
   421     if (!EC_READ_U16(frame.data) && !EC_READ_U16(frame.data + 2)) return 0;
   411     if (!EC_READ_U16(command.data) && !EC_READ_U16(command.data + 2)) return 0;
   422 
   412 
   423     EC_WARN("CRC faults on slave %i. A: %i, B: %i\n", slave->ring_position,
   413     EC_WARN("CRC faults on slave %i. A: %i, B: %i\n", slave->ring_position,
   424             EC_READ_U16(frame.data), EC_READ_U16(frame.data + 2));
   414             EC_READ_U16(command.data), EC_READ_U16(command.data + 2));
   425 
   415 
   426     // Reset CRC counters
   416     // Reset CRC counters
   427     EC_WRITE_U16(data,     0x0000);
   417     EC_WRITE_U16(data,     0x0000);
   428     EC_WRITE_U16(data + 2, 0x0000);
   418     EC_WRITE_U16(data + 2, 0x0000);
   429     ec_frame_init_npwr(&frame, slave->master, slave->station_address,
   419     ec_command_init_npwr(&command, slave->station_address, 0x0300, 4, data);
   430                        0x0300, 4, data);
   420     if (unlikely(ec_master_simple_io(slave->master, &command))) {
   431 
       
   432     if (unlikely(ec_frame_send_receive(&frame))) {
       
   433         EC_WARN("Resetting CRC fault counters failed on slave %i!\n",
   421         EC_WARN("Resetting CRC fault counters failed on slave %i!\n",
   434                 slave->ring_position);
   422                 slave->ring_position);
   435         return -1;
   423         return -1;
   436     }
   424     }
   437 
   425