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 |
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 } |
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; |