master/slave.c
changeset 145 11a82e4fd31b
parent 144 fdc24bf62f80
child 147 a355b587b4bc
equal deleted inserted replaced
144:fdc24bf62f80 145:11a82e4fd31b
    41     slave->base_type = 0;
    41     slave->base_type = 0;
    42     slave->base_revision = 0;
    42     slave->base_revision = 0;
    43     slave->base_build = 0;
    43     slave->base_build = 0;
    44     slave->base_fmmu_count = 0;
    44     slave->base_fmmu_count = 0;
    45     slave->base_sync_count = 0;
    45     slave->base_sync_count = 0;
    46     for (i = 0; i < 2; i++) {
       
    47         slave->dl_status_link[i] = 0;
       
    48         slave->dl_status_loop[i] = 0;
       
    49         slave->dl_status_comm[i] = 0;
       
    50     }
       
    51     slave->ring_position = 0;
    46     slave->ring_position = 0;
    52     slave->station_address = 0;
    47     slave->station_address = 0;
    53     slave->sii_alias = 0;
    48     slave->sii_alias = 0;
    54     slave->sii_vendor_id = 0;
    49     slave->sii_vendor_id = 0;
    55     slave->sii_product_code = 0;
    50     slave->sii_product_code = 0;
    64     slave->registered = 0;
    59     slave->registered = 0;
    65     slave->fmmu_count = 0;
    60     slave->fmmu_count = 0;
    66     slave->eeprom_name = NULL;
    61     slave->eeprom_name = NULL;
    67     slave->eeprom_group = NULL;
    62     slave->eeprom_group = NULL;
    68     slave->eeprom_desc = NULL;
    63     slave->eeprom_desc = NULL;
       
    64 
       
    65     ec_command_init(&slave->mbox_command);
       
    66 
    69     INIT_LIST_HEAD(&slave->eeprom_strings);
    67     INIT_LIST_HEAD(&slave->eeprom_strings);
    70     INIT_LIST_HEAD(&slave->eeprom_syncs);
    68     INIT_LIST_HEAD(&slave->eeprom_syncs);
    71     INIT_LIST_HEAD(&slave->eeprom_pdos);
    69     INIT_LIST_HEAD(&slave->eeprom_pdos);
    72     INIT_LIST_HEAD(&slave->sdo_dictionary);
    70     INIT_LIST_HEAD(&slave->sdo_dictionary);
       
    71 
       
    72     for (i = 0; i < 2; i++) {
       
    73         slave->dl_status_link[i] = 0;
       
    74         slave->dl_status_loop[i] = 0;
       
    75         slave->dl_status_comm[i] = 0;
       
    76     }
    73 }
    77 }
    74 
    78 
    75 /*****************************************************************************/
    79 /*****************************************************************************/
    76 
    80 
    77 /**
    81 /**
   127             list_del(&en->list);
   131             list_del(&en->list);
   128             kfree(en);
   132             kfree(en);
   129         }
   133         }
   130         kfree(sdo);
   134         kfree(sdo);
   131     }
   135     }
       
   136 
       
   137     ec_command_clear(&slave->mbox_command);
   132 }
   138 }
   133 
   139 
   134 /*****************************************************************************/
   140 /*****************************************************************************/
   135 
   141 
   136 /**
   142 /**
   147 
   153 
   148     command = &slave->master->simple_command;
   154     command = &slave->master->simple_command;
   149 
   155 
   150     // Read base data
   156     // Read base data
   151     if (ec_command_nprd(command, slave->station_address, 0x0000, 6)) return -1;
   157     if (ec_command_nprd(command, slave->station_address, 0x0000, 6)) return -1;
   152     if (unlikely(ec_master_simple_io(slave->master))) {
   158     if (unlikely(ec_master_simple_io(slave->master, command))) {
   153         EC_ERR("Reading base data from slave %i failed!\n",
   159         EC_ERR("Reading base data from slave %i failed!\n",
   154                slave->ring_position);
   160                slave->ring_position);
   155         return -1;
   161         return -1;
   156     }
   162     }
   157 
   163 
   164     if (slave->base_fmmu_count > EC_MAX_FMMUS)
   170     if (slave->base_fmmu_count > EC_MAX_FMMUS)
   165         slave->base_fmmu_count = EC_MAX_FMMUS;
   171         slave->base_fmmu_count = EC_MAX_FMMUS;
   166 
   172 
   167     // Read DL status
   173     // Read DL status
   168     if (ec_command_nprd(command, slave->station_address, 0x0110, 2)) return -1;
   174     if (ec_command_nprd(command, slave->station_address, 0x0110, 2)) return -1;
   169     if (unlikely(ec_master_simple_io(slave->master))) {
   175     if (unlikely(ec_master_simple_io(slave->master, command))) {
   170         EC_ERR("Reading DL status from slave %i failed!\n",
   176         EC_ERR("Reading DL status from slave %i failed!\n",
   171                slave->ring_position);
   177                slave->ring_position);
   172         return -1;
   178         return -1;
   173     }
   179     }
   174 
   180 
   234     // Initiate read operation
   240     // Initiate read operation
   235     if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
   241     if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
   236     EC_WRITE_U8 (command->data,     0x00); // read-only access
   242     EC_WRITE_U8 (command->data,     0x00); // read-only access
   237     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
   243     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
   238     EC_WRITE_U32(command->data + 2, offset);
   244     EC_WRITE_U32(command->data + 2, offset);
   239     if (unlikely(ec_master_simple_io(slave->master))) {
   245     if (unlikely(ec_master_simple_io(slave->master, command))) {
   240         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   246         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   241         return -1;
   247         return -1;
   242     }
   248     }
   243 
   249 
   244     // Der Slave legt die Informationen des Slave-Information-Interface
   250     // Der Slave legt die Informationen des Slave-Information-Interface
   252     {
   258     {
   253         udelay(10);
   259         udelay(10);
   254 
   260 
   255         if (ec_command_nprd(command, slave->station_address, 0x502, 10))
   261         if (ec_command_nprd(command, slave->station_address, 0x502, 10))
   256             return -1;
   262             return -1;
   257         if (unlikely(ec_master_simple_io(slave->master))) {
   263         if (unlikely(ec_master_simple_io(slave->master, command))) {
   258             EC_ERR("Getting SII-read status failed on slave %i!\n",
   264             EC_ERR("Getting SII-read status failed on slave %i!\n",
   259                    slave->ring_position);
   265                    slave->ring_position);
   260             return -1;
   266             return -1;
   261         }
   267         }
   262 
   268 
   299     // Initiate read operation
   305     // Initiate read operation
   300     if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
   306     if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1;
   301     EC_WRITE_U8 (command->data,     0x00); // read-only access
   307     EC_WRITE_U8 (command->data,     0x00); // read-only access
   302     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
   308     EC_WRITE_U8 (command->data + 1, 0x01); // request read operation
   303     EC_WRITE_U32(command->data + 2, offset);
   309     EC_WRITE_U32(command->data + 2, offset);
   304     if (unlikely(ec_master_simple_io(slave->master))) {
   310     if (unlikely(ec_master_simple_io(slave->master, command))) {
   305         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   311         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   306         return -1;
   312         return -1;
   307     }
   313     }
   308 
   314 
   309     // Der Slave legt die Informationen des Slave-Information-Interface
   315     // Der Slave legt die Informationen des Slave-Information-Interface
   317     {
   323     {
   318         udelay(10);
   324         udelay(10);
   319 
   325 
   320         if (ec_command_nprd(command, slave->station_address, 0x502, 10))
   326         if (ec_command_nprd(command, slave->station_address, 0x502, 10))
   321             return -1;
   327             return -1;
   322         if (unlikely(ec_master_simple_io(slave->master))) {
   328         if (unlikely(ec_master_simple_io(slave->master, command))) {
   323             EC_ERR("Getting SII-read status failed on slave %i!\n",
   329             EC_ERR("Getting SII-read status failed on slave %i!\n",
   324                    slave->ring_position);
   330                    slave->ring_position);
   325             return -1;
   331             return -1;
   326         }
   332         }
   327 
   333 
   368     if (ec_command_npwr(command, slave->station_address, 0x502, 8)) return -1;
   374     if (ec_command_npwr(command, slave->station_address, 0x502, 8)) return -1;
   369     EC_WRITE_U8 (command->data,     0x01); // enable write access
   375     EC_WRITE_U8 (command->data,     0x01); // enable write access
   370     EC_WRITE_U8 (command->data + 1, 0x02); // request write operation
   376     EC_WRITE_U8 (command->data + 1, 0x02); // request write operation
   371     EC_WRITE_U32(command->data + 2, offset);
   377     EC_WRITE_U32(command->data + 2, offset);
   372     EC_WRITE_U16(command->data + 6, value);
   378     EC_WRITE_U16(command->data + 6, value);
   373     if (unlikely(ec_master_simple_io(slave->master))) {
   379     if (unlikely(ec_master_simple_io(slave->master, command))) {
   374         EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
   380         EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
   375         return -1;
   381         return -1;
   376     }
   382     }
   377 
   383 
   378     // Der Slave legt die Informationen des Slave-Information-Interface
   384     // Der Slave legt die Informationen des Slave-Information-Interface
   386     {
   392     {
   387         udelay(10);
   393         udelay(10);
   388 
   394 
   389         if (ec_command_nprd(command, slave->station_address, 0x502, 2))
   395         if (ec_command_nprd(command, slave->station_address, 0x502, 2))
   390             return -1;
   396             return -1;
   391         if (unlikely(ec_master_simple_io(slave->master))) {
   397         if (unlikely(ec_master_simple_io(slave->master, command))) {
   392             EC_ERR("Getting SII-write status failed on slave %i!\n",
   398             EC_ERR("Getting SII-write status failed on slave %i!\n",
   393                    slave->ring_position);
   399                    slave->ring_position);
   394             return -1;
   400             return -1;
   395         }
   401         }
   396 
   402 
   724 
   730 
   725     command = &slave->master->simple_command;
   731     command = &slave->master->simple_command;
   726 
   732 
   727     if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return;
   733     if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return;
   728     EC_WRITE_U16(command->data, state | EC_ACK);
   734     EC_WRITE_U16(command->data, state | EC_ACK);
   729     if (unlikely(ec_master_simple_io(slave->master))) {
   735     if (unlikely(ec_master_simple_io(slave->master, command))) {
   730         EC_WARN("State %02X acknowledge failed on slave %i!\n",
   736         EC_WARN("State %02X acknowledge failed on slave %i!\n",
   731                 state, slave->ring_position);
   737                 state, slave->ring_position);
   732         return;
   738         return;
   733     }
   739     }
   734 
   740 
   739     {
   745     {
   740         udelay(100); // Dem Slave etwas Zeit lassen...
   746         udelay(100); // Dem Slave etwas Zeit lassen...
   741 
   747 
   742         if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
   748         if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
   743             return;
   749             return;
   744         if (unlikely(ec_master_simple_io(slave->master))) {
   750         if (unlikely(ec_master_simple_io(slave->master, command))) {
   745             EC_WARN("State %02X acknowledge checking failed on slave %i!\n",
   751             EC_WARN("State %02X acknowledge checking failed on slave %i!\n",
   746                     state, slave->ring_position);
   752                     state, slave->ring_position);
   747             return;
   753             return;
   748         }
   754         }
   749 
   755 
   789 
   795 
   790     command = &slave->master->simple_command;
   796     command = &slave->master->simple_command;
   791 
   797 
   792     if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return -1;
   798     if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return -1;
   793     EC_WRITE_U16(command->data, state);
   799     EC_WRITE_U16(command->data, state);
   794     if (unlikely(ec_master_simple_io(slave->master))) {
   800     if (unlikely(ec_master_simple_io(slave->master, command))) {
   795         EC_ERR("Failed to set state %02X on slave %i!\n",
   801         EC_ERR("Failed to set state %02X on slave %i!\n",
   796                state, slave->ring_position);
   802                state, slave->ring_position);
   797         return -1;
   803         return -1;
   798     }
   804     }
   799 
   805 
   804     {
   810     {
   805         udelay(100); // Dem Slave etwas Zeit lassen...
   811         udelay(100); // Dem Slave etwas Zeit lassen...
   806 
   812 
   807         if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
   813         if (ec_command_nprd(command, slave->station_address, 0x0130, 2))
   808             return -1;
   814             return -1;
   809         if (unlikely(ec_master_simple_io(slave->master))) {
   815         if (unlikely(ec_master_simple_io(slave->master, command))) {
   810             EC_ERR("Failed to check state %02X on slave %i!\n",
   816             EC_ERR("Failed to check state %02X on slave %i!\n",
   811                    state, slave->ring_position);
   817                    state, slave->ring_position);
   812             return -1;
   818             return -1;
   813         }
   819         }
   814 
   820 
  1047     ec_command_t *command;
  1053     ec_command_t *command;
  1048 
  1054 
  1049     command = &slave->master->simple_command;
  1055     command = &slave->master->simple_command;
  1050 
  1056 
  1051     if (ec_command_nprd(command, slave->station_address, 0x0300, 4)) return -1;
  1057     if (ec_command_nprd(command, slave->station_address, 0x0300, 4)) return -1;
  1052     if (unlikely(ec_master_simple_io(slave->master))) {
  1058     if (unlikely(ec_master_simple_io(slave->master, command))) {
  1053         EC_WARN("Reading CRC fault counters failed on slave %i!\n",
  1059         EC_WARN("Reading CRC fault counters failed on slave %i!\n",
  1054                 slave->ring_position);
  1060                 slave->ring_position);
  1055         return -1;
  1061         return -1;
  1056     }
  1062     }
  1057 
  1063 
  1080                 slave->ring_position);
  1086                 slave->ring_position);
  1081 
  1087 
  1082     // Reset CRC counters
  1088     // Reset CRC counters
  1083     if (ec_command_npwr(command, slave->station_address, 0x0300, 4)) return -1;
  1089     if (ec_command_npwr(command, slave->station_address, 0x0300, 4)) return -1;
  1084     EC_WRITE_U32(command->data, 0x00000000);
  1090     EC_WRITE_U32(command->data, 0x00000000);
  1085     if (unlikely(ec_master_simple_io(slave->master))) {
  1091     if (unlikely(ec_master_simple_io(slave->master, command))) {
  1086         EC_WARN("Resetting CRC fault counters failed on slave %i!\n",
  1092         EC_WARN("Resetting CRC fault counters failed on slave %i!\n",
  1087                 slave->ring_position);
  1093                 slave->ring_position);
  1088         return -1;
  1094         return -1;
  1089     }
  1095     }
  1090 
  1096 
  1091     return 0;
       
  1092 }
       
  1093 
       
  1094 /*****************************************************************************/
       
  1095 
       
  1096 /**
       
  1097    Bereitet ein Mailbox-Send-Kommando vor.
       
  1098  */
       
  1099 
       
  1100 uint8_t *ec_slave_prepare_mailbox_send(ec_slave_t *slave, /**< Slave */
       
  1101                                        uint8_t type, /**< Mailbox-Protokoll */
       
  1102                                        size_t size /**< Datengröße */
       
  1103                                        )
       
  1104 {
       
  1105     size_t total_size;
       
  1106     ec_command_t *command;
       
  1107 
       
  1108     if (unlikely(!slave->sii_mailbox_protocols)) {
       
  1109         EC_ERR("Slave %i does not support mailbox communication!\n",
       
  1110                slave->ring_position);
       
  1111         return NULL;
       
  1112     }
       
  1113 
       
  1114     total_size = size + 6;
       
  1115     if (unlikely(total_size > slave->sii_rx_mailbox_size)) {
       
  1116         EC_ERR("Data size does not fit in mailbox!\n");
       
  1117         return NULL;
       
  1118     }
       
  1119 
       
  1120     command = &slave->master->simple_command;
       
  1121 
       
  1122     if (ec_command_npwr(command, slave->station_address,
       
  1123                         slave->sii_rx_mailbox_offset,
       
  1124                         slave->sii_rx_mailbox_size)) return NULL;
       
  1125     EC_WRITE_U16(command->data,     size); // Mailbox service data length
       
  1126     EC_WRITE_U16(command->data + 2, slave->station_address); // Station address
       
  1127     EC_WRITE_U8 (command->data + 4, 0x00); // Channel & priority
       
  1128     EC_WRITE_U8 (command->data + 5, type); // Underlying protocol type
       
  1129 
       
  1130     return command->data + 6;
       
  1131 }
       
  1132 
       
  1133 /*****************************************************************************/
       
  1134 
       
  1135 /**
       
  1136    Empfängt ein Mailbox-Kommando.
       
  1137  */
       
  1138 
       
  1139 uint8_t *ec_slave_mailbox_receive(ec_slave_t *slave, /**< Slave */
       
  1140                                   uint8_t type, /**< Protokoll */
       
  1141                                   size_t *size /**< Größe der gelesenen
       
  1142                                                   Daten */
       
  1143                                   )
       
  1144 {
       
  1145     ec_command_t *command;
       
  1146     size_t data_size;
       
  1147     cycles_t start, end, timeout;
       
  1148 
       
  1149     command = &slave->master->simple_command;
       
  1150 
       
  1151     // Read "written bit" of Sync-Manager
       
  1152     start = get_cycles();
       
  1153     timeout = (cycles_t) 100 * cpu_khz; // 100ms
       
  1154 
       
  1155     while (1)
       
  1156     {
       
  1157         // FIXME: Zweiter Sync-Manager nicht immer TX-Mailbox?
       
  1158         if (ec_command_nprd(command, slave->station_address, 0x808, 8))
       
  1159             return NULL;
       
  1160         if (unlikely(ec_master_simple_io(slave->master))) {
       
  1161             EC_ERR("Mailbox checking failed on slave %i!\n",
       
  1162                    slave->ring_position);
       
  1163             return NULL;
       
  1164         }
       
  1165 
       
  1166         end = get_cycles();
       
  1167 
       
  1168         if (EC_READ_U8(command->data + 5) & 8)
       
  1169             break; // Proceed with received data
       
  1170 
       
  1171         if ((end - start) >= timeout) {
       
  1172             EC_ERR("Mailbox check - Slave %i timed out.\n",
       
  1173                    slave->ring_position);
       
  1174             return NULL;
       
  1175         }
       
  1176 
       
  1177         udelay(100);
       
  1178     }
       
  1179 
       
  1180     if (ec_command_nprd(command, slave->station_address,
       
  1181                         slave->sii_tx_mailbox_offset,
       
  1182                         slave->sii_tx_mailbox_size)) return NULL;
       
  1183     if (unlikely(ec_master_simple_io(slave->master))) {
       
  1184         EC_ERR("Mailbox receiving failed on slave %i!\n",
       
  1185                slave->ring_position);
       
  1186         return NULL;
       
  1187     }
       
  1188 
       
  1189     if ((EC_READ_U8(command->data + 5) & 0x0F) != type) {
       
  1190         EC_ERR("Unexpected mailbox protocol 0x%02X (exp.: 0x%02X) at"
       
  1191                " slave %i!\n", EC_READ_U8(command->data + 5), type,
       
  1192                slave->ring_position);
       
  1193         return NULL;
       
  1194     }
       
  1195 
       
  1196     if (unlikely(slave->master->debug_level) > 1)
       
  1197         EC_DBG("Mailbox receive took %ius.\n", ((u32) (end - start) * 1000
       
  1198                                                 / cpu_khz));
       
  1199 
       
  1200     if ((data_size = EC_READ_U16(command->data)) >
       
  1201         slave->sii_tx_mailbox_size - 6) {
       
  1202         EC_ERR("Currupt mailbox response detected!\n");
       
  1203         return NULL;
       
  1204     }
       
  1205 
       
  1206     *size = data_size;
       
  1207     return 0;
  1097     return 0;
  1208 }
  1098 }
  1209 
  1099 
  1210 /*****************************************************************************/
  1100 /*****************************************************************************/
  1211 
  1101