master/slave.c
changeset 136 a03a684cac89
parent 135 80d493917205
child 138 7e743a61a991
equal deleted inserted replaced
135:80d493917205 136:a03a684cac89
    46     slave->sii_alias = 0;
    46     slave->sii_alias = 0;
    47     slave->sii_vendor_id = 0;
    47     slave->sii_vendor_id = 0;
    48     slave->sii_product_code = 0;
    48     slave->sii_product_code = 0;
    49     slave->sii_revision_number = 0;
    49     slave->sii_revision_number = 0;
    50     slave->sii_serial_number = 0;
    50     slave->sii_serial_number = 0;
       
    51     slave->sii_rx_mailbox_offset = 0;
       
    52     slave->sii_rx_mailbox_size = 0;
       
    53     slave->sii_tx_mailbox_offset = 0;
       
    54     slave->sii_tx_mailbox_size = 0;
    51     slave->sii_mailbox_protocols = 0;
    55     slave->sii_mailbox_protocols = 0;
    52     slave->type = NULL;
    56     slave->type = NULL;
    53     slave->registered = 0;
    57     slave->registered = 0;
    54     slave->fmmu_count = 0;
    58     slave->fmmu_count = 0;
    55     slave->eeprom_name = NULL;
    59     slave->eeprom_name = NULL;
   141     slave->base_sync_count = EC_READ_U8 (command.data + 5);
   145     slave->base_sync_count = EC_READ_U8 (command.data + 5);
   142 
   146 
   143     if (slave->base_fmmu_count > EC_MAX_FMMUS)
   147     if (slave->base_fmmu_count > EC_MAX_FMMUS)
   144         slave->base_fmmu_count = EC_MAX_FMMUS;
   148         slave->base_fmmu_count = EC_MAX_FMMUS;
   145 
   149 
   146     // Read identification from "Slave Information Interface" (SII)
   150     if (ec_slave_sii_read16(slave, 0x0004, &slave->sii_alias))
   147 
   151         return -1;
   148     if (unlikely(ec_slave_sii_read(slave, 0x0004,
   152     if (ec_slave_sii_read32(slave, 0x0008, &slave->sii_vendor_id))
   149                                    (uint32_t *) &slave->sii_alias))) {
   153         return -1;
   150         EC_ERR("Could not read SII alias!\n");
   154     if (ec_slave_sii_read32(slave, 0x000A, &slave->sii_product_code))
   151         return -1;
   155         return -1;
   152     }
   156     if (ec_slave_sii_read32(slave, 0x000C, &slave->sii_revision_number))
   153 
   157         return -1;
   154     if (unlikely(ec_slave_sii_read(slave, 0x0008, &slave->sii_vendor_id))) {
   158     if (ec_slave_sii_read32(slave, 0x000E, &slave->sii_serial_number))
   155         EC_ERR("Could not read SII vendor id!\n");
   159         return -1;
   156         return -1;
   160     if (ec_slave_sii_read16(slave, 0x0018, &slave->sii_rx_mailbox_offset))
   157     }
   161         return -1;
   158 
   162     if (ec_slave_sii_read16(slave, 0x0019, &slave->sii_rx_mailbox_size))
   159     if (unlikely(ec_slave_sii_read(slave, 0x000A, &slave->sii_product_code))) {
   163         return -1;
   160         EC_ERR("Could not read SII product code!\n");
   164     if (ec_slave_sii_read16(slave, 0x001A, &slave->sii_tx_mailbox_offset))
   161         return -1;
   165         return -1;
   162     }
   166     if (ec_slave_sii_read16(slave, 0x001B, &slave->sii_tx_mailbox_size))
   163 
   167         return -1;
   164     if (unlikely(ec_slave_sii_read(slave, 0x000C,
   168     if (ec_slave_sii_read16(slave, 0x001C, &slave->sii_mailbox_protocols))
   165                                    &slave->sii_revision_number))) {
   169         return -1;
   166         EC_ERR("Could not read SII revision number!\n");
       
   167         return -1;
       
   168     }
       
   169 
       
   170     if (unlikely(ec_slave_sii_read(slave, 0x000E,
       
   171                                    &slave->sii_serial_number))) {
       
   172         EC_ERR("Could not read SII serial number!\n");
       
   173         return -1;
       
   174     }
       
   175 
       
   176     if (unlikely(ec_slave_sii_read(slave, 0x001C,
       
   177                                    &slave->sii_mailbox_protocols))) {
       
   178         EC_ERR("Could not read SII supported mailbox protocols!\n");
       
   179         return -1;
       
   180     }
       
   181 
   170 
   182     if (unlikely(ec_slave_fetch_categories(slave))) {
   171     if (unlikely(ec_slave_fetch_categories(slave))) {
   183         EC_ERR("Could not fetch category data!\n");
   172         EC_ERR("Failed to fetch category data!\n");
   184         return -1;
   173         return -1;
   185     }
   174     }
   186 
   175 
   187     return 0;
   176     return 0;
   188 }
   177 }
   189 
   178 
   190 /*****************************************************************************/
   179 /*****************************************************************************/
   191 
   180 
   192 /**
   181 /**
   193    Liest Daten aus dem Slave-Information-Interface
   182    Liest 16 Bit aus dem Slave-Information-Interface
   194    eines EtherCAT-Slaves.
   183    eines EtherCAT-Slaves.
   195 
   184 
   196    \return 0 bei Erfolg, sonst < 0
   185    \return 0 bei Erfolg, sonst < 0
   197 */
   186 */
   198 
   187 
   199 int ec_slave_sii_read(ec_slave_t *slave,
   188 int ec_slave_sii_read16(ec_slave_t *slave,
   200                       /**< EtherCAT-Slave */
   189                         /**< EtherCAT-Slave */
   201                       uint16_t offset,
   190                         uint16_t offset,
   202                       /**< Adresse des zu lesenden SII-Registers */
   191                         /**< Adresse des zu lesenden SII-Registers */
   203                       uint32_t *target
   192                         uint16_t *target
   204                       /**< Zeiger auf einen 4 Byte großen Speicher zum Ablegen
   193                         /**< Speicher für Wert (16-Bit) */
   205                          der Daten */
   194                         )
   206                       )
       
   207 {
   195 {
   208     ec_command_t command;
   196     ec_command_t command;
   209     uint8_t data[10];
   197     uint8_t data[10];
   210     cycles_t start, end, timeout;
   198     cycles_t start, end, timeout;
   211 
   199 
   240         }
   228         }
   241 
   229 
   242         end = get_cycles();
   230         end = get_cycles();
   243 
   231 
   244         if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
   232         if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
       
   233             *target = EC_READ_U16(command.data + 6);
       
   234             return 0;
       
   235         }
       
   236 
       
   237         if (unlikely((end - start) >= timeout)) {
       
   238             EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
       
   239             return -1;
       
   240         }
       
   241     }
       
   242 }
       
   243 
       
   244 /*****************************************************************************/
       
   245 
       
   246 /**
       
   247    Liest 32 Bit aus dem Slave-Information-Interface
       
   248    eines EtherCAT-Slaves.
       
   249 
       
   250    \return 0 bei Erfolg, sonst < 0
       
   251 */
       
   252 
       
   253 int ec_slave_sii_read32(ec_slave_t *slave,
       
   254                         /**< EtherCAT-Slave */
       
   255                         uint16_t offset,
       
   256                         /**< Adresse des zu lesenden SII-Registers */
       
   257                         uint32_t *target
       
   258                         /**< Speicher für Wert (32-Bit) */
       
   259                         )
       
   260 {
       
   261     ec_command_t command;
       
   262     uint8_t data[10];
       
   263     cycles_t start, end, timeout;
       
   264 
       
   265     // Initiate read operation
       
   266 
       
   267     EC_WRITE_U8 (data,     0x00); // read-only access
       
   268     EC_WRITE_U8 (data + 1, 0x01); // request read operation
       
   269     EC_WRITE_U32(data + 2, offset);
       
   270 
       
   271     ec_command_init_npwr(&command, slave->station_address, 0x502, 6, data);
       
   272     if (unlikely(ec_master_simple_io(slave->master, &command))) {
       
   273         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
       
   274         return -1;
       
   275     }
       
   276 
       
   277     // Der Slave legt die Informationen des Slave-Information-Interface
       
   278     // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange
       
   279     // den Status auslesen, bis das Bit weg ist.
       
   280 
       
   281     start = get_cycles();
       
   282     timeout = (cycles_t) 100 * cpu_khz; // 100ms
       
   283 
       
   284     while (1)
       
   285     {
       
   286         udelay(10);
       
   287 
       
   288         ec_command_init_nprd(&command, slave->station_address, 0x502, 10);
       
   289         if (unlikely(ec_master_simple_io(slave->master, &command))) {
       
   290             EC_ERR("Getting SII-read status failed on slave %i!\n",
       
   291                    slave->ring_position);
       
   292             return -1;
       
   293         }
       
   294 
       
   295         end = get_cycles();
       
   296 
       
   297         if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
   245             *target = EC_READ_U32(command.data + 6);
   298             *target = EC_READ_U32(command.data + 6);
   246             return 0;
   299             return 0;
   247         }
   300         }
   248 
   301 
   249         if (unlikely((end - start) >= timeout)) {
   302         if (unlikely((end - start) >= timeout)) {
   254 }
   307 }
   255 
   308 
   256 /*****************************************************************************/
   309 /*****************************************************************************/
   257 
   310 
   258 /**
   311 /**
   259    Schreibt Daten in das Slave-Information-Interface
   312    Schreibt 16 Bit Daten in das Slave-Information-Interface
   260    eines EtherCAT-Slaves.
   313    eines EtherCAT-Slaves.
   261 
   314 
   262    \return 0 bei Erfolg, sonst < 0
   315    \return 0 bei Erfolg, sonst < 0
   263 */
   316 */
   264 
   317 
   265 int ec_slave_sii_write(ec_slave_t *slave,
   318 int ec_slave_sii_write16(ec_slave_t *slave,
   266                        /**< EtherCAT-Slave */
   319                          /**< EtherCAT-Slave */
   267                        uint16_t offset,
   320                          uint16_t offset,
   268                        /**< Adresse des zu lesenden SII-Registers */
   321                          /**< Adresse des zu lesenden SII-Registers */
   269                        uint16_t value
   322                          uint16_t value
   270                        /**< Zu schreibender Wert */
   323                          /**< Zu schreibender Wert */
   271                        )
   324                          )
   272 {
   325 {
   273     ec_command_t command;
   326     ec_command_t command;
   274     uint8_t data[8];
   327     uint8_t data[8];
   275     cycles_t start, end, timeout;
   328     cycles_t start, end, timeout;
   276 
   329 
   350         return -1;
   403         return -1;
   351     }
   404     }
   352 
   405 
   353     while (1) {
   406     while (1) {
   354         // read category type
   407         // read category type
   355         if (ec_slave_sii_read(slave, word_offset, &value)) {
   408         if (ec_slave_sii_read32(slave, word_offset, &value)) {
   356             EC_ERR("Unable to read category header.\n");
   409             EC_ERR("Unable to read category header.\n");
   357             goto out_free;
   410             goto out_free;
   358         }
   411         }
   359 
   412 
   360         // Last category?
   413         // Last category?
   363         cat_type = value & 0x7FFF;
   416         cat_type = value & 0x7FFF;
   364         word_count = (value >> 16) & 0xFFFF;
   417         word_count = (value >> 16) & 0xFFFF;
   365 
   418 
   366         // Fetch category data
   419         // Fetch category data
   367         for (i = 0; i < word_count; i++) {
   420         for (i = 0; i < word_count; i++) {
   368             if (ec_slave_sii_read(slave, word_offset + 2 + i, &value)) {
   421             if (ec_slave_sii_read32(slave, word_offset + 2 + i, &value)) {
   369                 EC_ERR("Unable to read category data word %i.\n", i);
   422                 EC_ERR("Unable to read category data word %i.\n", i);
   370                 goto out_free;
   423                 goto out_free;
   371             }
   424             }
   372 
   425 
   373             cat_data[i * 2]     = (value >> 0) & 0xFF;
   426             cat_data[i * 2]     = (value >> 0) & 0xFF;
   822     EC_INFO("|   Type %u, Revision %i, Build %i\n",
   875     EC_INFO("|   Type %u, Revision %i, Build %i\n",
   823             slave->base_type, slave->base_revision, slave->base_build);
   876             slave->base_type, slave->base_revision, slave->base_build);
   824     EC_INFO("|   Supported FMMUs: %i, Sync managers: %i\n",
   877     EC_INFO("|   Supported FMMUs: %i, Sync managers: %i\n",
   825             slave->base_fmmu_count, slave->base_sync_count);
   878             slave->base_fmmu_count, slave->base_sync_count);
   826 
   879 
   827     EC_INFO("| Supported mailbox protocols: ");
   880     if (slave->sii_mailbox_protocols) {
   828     if (!slave->sii_mailbox_protocols) {
   881         EC_INFO("| Mailbox communication:\n");
   829         printk("(none)");
   882         EC_INFO("|   RX mailbox: 0x%04X/%i, TX mailbox: 0x%04X/%i\n",
   830     }
   883                 slave->sii_rx_mailbox_offset, slave->sii_rx_mailbox_size,
   831     else {
   884                 slave->sii_tx_mailbox_offset, slave->sii_tx_mailbox_size);
       
   885         EC_INFO("|   Supported protocols: ");
       
   886 
   832         first = 1;
   887         first = 1;
   833         if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
   888         if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
   834             printk("AoE");
   889             printk("AoE");
   835             first = 0;
   890             first = 0;
   836         }
   891         }
   856         }
   911         }
   857         if (slave->sii_mailbox_protocols & EC_MBOX_VOE) {
   912         if (slave->sii_mailbox_protocols & EC_MBOX_VOE) {
   858             if (!first) printk(", ");
   913             if (!first) printk(", ");
   859             printk("VoE");
   914             printk("VoE");
   860         }
   915         }
   861     }
   916         printk("\n");
   862     printk("\n");
   917     }
   863 
   918 
   864     EC_INFO("| EEPROM data:\n");
   919     EC_INFO("| EEPROM data:\n");
   865 
   920 
   866     if (slave->sii_alias)
   921     if (slave->sii_alias)
   867         EC_INFO("|   Configured station alias: 0x%04X (%i)\n",
   922         EC_INFO("|   Configured station alias: 0x%04X (%i)\n",
   981                           uint8_t type, /**< Unterliegendes Protokoll */
  1036                           uint8_t type, /**< Unterliegendes Protokoll */
   982                           const uint8_t *prot_data, /**< Protokoll-Daten */
  1037                           const uint8_t *prot_data, /**< Protokoll-Daten */
   983                           size_t size /**< Datengröße */
  1038                           size_t size /**< Datengröße */
   984                           )
  1039                           )
   985 {
  1040 {
   986     uint8_t data[0xF6];
  1041     size_t total_size;
       
  1042     uint8_t *data;
   987     ec_command_t command;
  1043     ec_command_t command;
   988 
  1044 
   989     if (unlikely(size + 6 > 0xF6)) {
  1045     if (unlikely(!slave->sii_mailbox_protocols)) {
       
  1046         EC_ERR("Slave %i does not support mailbox communication!\n",
       
  1047                slave->ring_position);
       
  1048         return -1;
       
  1049     }
       
  1050 
       
  1051     total_size = size + 6;
       
  1052     if (unlikely(total_size > slave->sii_rx_mailbox_size)) {
   990         EC_ERR("Data size does not fit in mailbox!\n");
  1053         EC_ERR("Data size does not fit in mailbox!\n");
   991         return -1;
  1054         return -1;
   992     }
  1055     }
   993 
  1056 
   994     memset(data, 0x00, 0xF6);
  1057     if (!(data = kmalloc(slave->sii_rx_mailbox_size, GFP_KERNEL))) {
   995 
  1058         EC_ERR("Failed to allocate %i bytes of memory for mailbox data!\n",
       
  1059                slave->sii_rx_mailbox_size);
       
  1060         return -1;
       
  1061     }
       
  1062 
       
  1063     memset(data, 0x00, slave->sii_rx_mailbox_size);
   996     EC_WRITE_U16(data,      size); // Length of the Mailbox service data
  1064     EC_WRITE_U16(data,      size); // Length of the Mailbox service data
   997     EC_WRITE_U16(data + 2,  slave->station_address); // Station address
  1065     EC_WRITE_U16(data + 2,  slave->station_address); // Station address
   998     EC_WRITE_U8 (data + 4,  0x00); // Channel & priority
  1066     EC_WRITE_U8 (data + 4,  0x00); // Channel & priority
   999     EC_WRITE_U8 (data + 5,  type); // Underlying protocol type
  1067     EC_WRITE_U8 (data + 5,  type); // Underlying protocol type
  1000 
       
  1001     memcpy(data + 6, prot_data, size);
  1068     memcpy(data + 6, prot_data, size);
  1002 
  1069 
  1003     ec_command_init_npwr(&command, slave->station_address, 0x1800, 0xF6, data);
  1070     ec_command_init_npwr(&command, slave->station_address,
       
  1071                          slave->sii_rx_mailbox_offset,
       
  1072                          slave->sii_rx_mailbox_size, data);
  1004     if (unlikely(ec_master_simple_io(slave->master, &command))) {
  1073     if (unlikely(ec_master_simple_io(slave->master, &command))) {
  1005         EC_ERR("Mailbox sending failed on slave %i!\n", slave->ring_position);
  1074         EC_ERR("Mailbox sending failed on slave %i!\n", slave->ring_position);
  1006         return -1;
  1075         kfree(data);
  1007     }
  1076         return -1;
  1008 
  1077     }
       
  1078 
       
  1079     kfree(data);
  1009     return 0;
  1080     return 0;
  1010 }
  1081 }
  1011 
  1082 
  1012 /*****************************************************************************/
  1083 /*****************************************************************************/
  1013 
  1084 
  1030     start = get_cycles();
  1101     start = get_cycles();
  1031     timeout = (cycles_t) 100 * cpu_khz; // 100ms
  1102     timeout = (cycles_t) 100 * cpu_khz; // 100ms
  1032 
  1103 
  1033     while (1)
  1104     while (1)
  1034     {
  1105     {
       
  1106         // FIXME: Zweiter Sync-Manager nicht immer TX-Mailbox?
  1035         ec_command_init_nprd(&command, slave->station_address, 0x808, 8);
  1107         ec_command_init_nprd(&command, slave->station_address, 0x808, 8);
  1036         if (unlikely(ec_master_simple_io(slave->master, &command))) {
  1108         if (unlikely(ec_master_simple_io(slave->master, &command))) {
  1037             EC_ERR("Mailbox checking failed on slave %i!\n",
  1109             EC_ERR("Mailbox checking failed on slave %i!\n",
  1038                    slave->ring_position);
  1110                    slave->ring_position);
  1039             return -1;
  1111             return -1;
  1040         }
  1112         }
  1041 
  1113 
  1042         end = get_cycles();
  1114         end = get_cycles();
  1043 
  1115 
  1044         if (EC_READ_U8(command.data + 5) & 8) break; // Written bit is high
  1116         if (EC_READ_U8(command.data + 5) & 8)
       
  1117             break; // Proceed with received data
  1045 
  1118 
  1046         if ((end - start) >= timeout) {
  1119         if ((end - start) >= timeout) {
  1047             EC_ERR("Mailbox check - Slave %i timed out.\n",
  1120             EC_ERR("Mailbox check - Slave %i timed out.\n",
  1048                    slave->ring_position);
  1121                    slave->ring_position);
  1049             return -1;
  1122             return -1;
  1050         }
  1123         }
  1051 
  1124 
  1052         udelay(100);
  1125         udelay(100);
  1053     }
  1126     }
  1054 
  1127 
  1055     if (unlikely(slave->master->debug_level) > 1)
  1128     ec_command_init_nprd(&command, slave->station_address,
  1056         EC_DBG("SDO download took %ius.\n", ((u32) (end - start) * 1000
  1129                          slave->sii_tx_mailbox_offset,
  1057                                              / cpu_khz));
  1130                          slave->sii_tx_mailbox_size);
  1058 
       
  1059     ec_command_init_nprd(&command, slave->station_address, 0x18F6, 0xF6);
       
  1060     if (unlikely(ec_master_simple_io(slave->master, &command))) {
  1131     if (unlikely(ec_master_simple_io(slave->master, &command))) {
  1061         EC_ERR("Mailbox receiving failed on slave %i!\n",
  1132         EC_ERR("Mailbox receiving failed on slave %i!\n",
  1062                slave->ring_position);
  1133                slave->ring_position);
  1063         return -1;
  1134         return -1;
  1064     }
  1135     }
  1065 
  1136 
  1066     if (EC_READ_U8(command.data + 5) != type) { // nicht CoE
  1137     if ((EC_READ_U8(command.data + 5) & 0x0F) != type) {
  1067         EC_ERR("Invalid mailbox response (non-CoE) at slave %i!\n",
  1138         EC_ERR("Unexpected mailbox protocol 0x%02X (exp.: 0x%02X) at"
       
  1139                " slave %i!\n", EC_READ_U8(command.data + 5), type,
  1068                slave->ring_position);
  1140                slave->ring_position);
  1069         return -1;
  1141         return -1;
  1070     }
  1142     }
  1071 
  1143 
       
  1144     if (unlikely(slave->master->debug_level) > 1)
       
  1145         EC_DBG("Mailbox receive took %ius.\n", ((u32) (end - start) * 1000
       
  1146                                                 / cpu_khz));
       
  1147 
  1072     if ((data_size = EC_READ_U16(command.data)) > *size) {
  1148     if ((data_size = EC_READ_U16(command.data)) > *size) {
  1073         EC_ERR("CoE data does not fit in buffer (%i > %i).\n",
  1149         EC_ERR("Mailbox service data does not fit into buffer (%i > %i).\n",
  1074                data_size, *size);
  1150                data_size, *size);
       
  1151         return -1;
       
  1152     }
       
  1153 
       
  1154     if (data_size > slave->sii_tx_mailbox_size - 6) {
       
  1155         EC_ERR("Currupt mailbox response detected!\n");
  1075         return -1;
  1156         return -1;
  1076     }
  1157     }
  1077 
  1158 
  1078     memcpy(prot_data, command.data + 6, data_size);
  1159     memcpy(prot_data, command.data + 6, data_size);
  1079     *size = data_size;
  1160     *size = data_size;