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 /** |
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 |
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 |
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 |
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 |
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 |
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 |