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 |