182 EC_WRITE_U8 (datagram->data, 0x80); // two address octets |
182 EC_WRITE_U8 (datagram->data, 0x80); // two address octets |
183 EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation |
183 EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation |
184 EC_WRITE_U16(datagram->data + 2, fsm->word_offset); |
184 EC_WRITE_U16(datagram->data + 2, fsm->word_offset); |
185 |
185 |
186 #ifdef SII_DEBUG |
186 #ifdef SII_DEBUG |
187 EC_DBG("reading SII data:\n"); |
187 EC_SLAVE_DBG(slave, 0, "reading SII data:\n"); |
188 ec_print_data(datagram->data, 4); |
188 ec_print_data(datagram->data, 4); |
189 #endif |
189 #endif |
190 |
190 |
191 fsm->retries = EC_FSM_RETRIES; |
191 fsm->retries = EC_FSM_RETRIES; |
192 fsm->state = ec_fsm_sii_state_read_check; |
192 fsm->state = ec_fsm_sii_state_read_check; |
208 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
208 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
209 return; |
209 return; |
210 |
210 |
211 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
211 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
212 fsm->state = ec_fsm_sii_state_error; |
212 fsm->state = ec_fsm_sii_state_error; |
213 EC_ERR("Failed to receive SII read datagram from slave %u: ", |
213 EC_SLAVE_ERR(fsm->slave, "Failed to receive SII read datagram: "); |
214 fsm->slave->ring_position); |
|
215 ec_datagram_print_state(datagram); |
214 ec_datagram_print_state(datagram); |
216 return; |
215 return; |
217 } |
216 } |
218 |
217 |
219 if (datagram->working_counter != 1) { |
218 if (datagram->working_counter != 1) { |
220 fsm->state = ec_fsm_sii_state_error; |
219 fsm->state = ec_fsm_sii_state_error; |
221 EC_ERR("Reception of SII read datagram failed on slave %u: ", |
220 EC_SLAVE_ERR(fsm->slave, "Reception of SII read datagram failed: "); |
222 fsm->slave->ring_position); |
|
223 ec_datagram_print_wc_error(datagram); |
221 ec_datagram_print_wc_error(datagram); |
224 return; |
222 return; |
225 } |
223 } |
226 |
224 |
227 fsm->jiffies_start = datagram->jiffies_sent; |
225 fsm->jiffies_start = datagram->jiffies_sent; |
257 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
255 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
258 return; |
256 return; |
259 |
257 |
260 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
258 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
261 fsm->state = ec_fsm_sii_state_error; |
259 fsm->state = ec_fsm_sii_state_error; |
262 EC_ERR("Failed to receive SII check/fetch datagram from slave %u: ", |
260 EC_SLAVE_ERR(fsm->slave, |
263 fsm->slave->ring_position); |
261 "Failed to receive SII check/fetch datagram: "); |
264 ec_datagram_print_state(datagram); |
262 ec_datagram_print_state(datagram); |
265 return; |
263 return; |
266 } |
264 } |
267 |
265 |
268 if (datagram->working_counter != 1) { |
266 if (datagram->working_counter != 1) { |
269 fsm->state = ec_fsm_sii_state_error; |
267 fsm->state = ec_fsm_sii_state_error; |
270 EC_ERR("Reception of SII check/fetch datagram failed on slave %u: ", |
268 EC_SLAVE_ERR(fsm->slave, |
271 fsm->slave->ring_position); |
269 "Reception of SII check/fetch datagram failed: "); |
272 ec_datagram_print_wc_error(datagram); |
270 ec_datagram_print_wc_error(datagram); |
273 return; |
271 return; |
274 } |
272 } |
275 |
273 |
276 #ifdef SII_DEBUG |
274 #ifdef SII_DEBUG |
277 EC_DBG("checking SII read state:\n"); |
275 EC_SLAVE_DBG(fsm->slave, 0, "checking SII read state:\n"); |
278 ec_print_data(datagram->data, 10); |
276 ec_print_data(datagram->data, 10); |
279 #endif |
277 #endif |
280 |
278 |
281 if (EC_READ_U8(datagram->data + 1) & 0x20) { |
279 if (EC_READ_U8(datagram->data + 1) & 0x20) { |
282 EC_ERR("SII: Error on last SII command!\n"); |
280 EC_SLAVE_ERR(fsm->slave, "SII: Error on last SII command!\n"); |
283 fsm->state = ec_fsm_sii_state_error; |
281 fsm->state = ec_fsm_sii_state_error; |
284 return; |
282 return; |
285 } |
283 } |
286 |
284 |
287 // check "busy bit" |
285 // check "busy bit" |
292 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
290 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
293 if (diff_ms >= SII_TIMEOUT) { |
291 if (diff_ms >= SII_TIMEOUT) { |
294 if (fsm->check_once_more) { |
292 if (fsm->check_once_more) { |
295 fsm->check_once_more = 0; |
293 fsm->check_once_more = 0; |
296 } else { |
294 } else { |
297 EC_ERR("SII: Read timeout.\n"); |
295 EC_SLAVE_ERR(fsm->slave, "SII: Read timeout.\n"); |
298 fsm->state = ec_fsm_sii_state_error; |
296 fsm->state = ec_fsm_sii_state_error; |
299 return; |
297 return; |
300 } |
298 } |
301 } |
299 } |
302 |
300 |
331 EC_WRITE_U16(datagram->data + 2, fsm->word_offset); |
329 EC_WRITE_U16(datagram->data + 2, fsm->word_offset); |
332 memset(datagram->data + 4, 0x00, 2); |
330 memset(datagram->data + 4, 0x00, 2); |
333 memcpy(datagram->data + 6, fsm->value, 2); |
331 memcpy(datagram->data + 6, fsm->value, 2); |
334 |
332 |
335 #ifdef SII_DEBUG |
333 #ifdef SII_DEBUG |
336 EC_DBG("writing SII data:\n"); |
334 EC_SLAVE_DBG(fsm->slave, 0, "writing SII data:\n"); |
337 ec_print_data(datagram->data, 8); |
335 ec_print_data(datagram->data, 8); |
338 #endif |
336 #endif |
339 |
337 |
340 fsm->retries = EC_FSM_RETRIES; |
338 fsm->retries = EC_FSM_RETRIES; |
341 fsm->state = ec_fsm_sii_state_write_check; |
339 fsm->state = ec_fsm_sii_state_write_check; |
356 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
354 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
357 return; |
355 return; |
358 |
356 |
359 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
357 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
360 fsm->state = ec_fsm_sii_state_error; |
358 fsm->state = ec_fsm_sii_state_error; |
361 EC_ERR("Failed to receive SII write datagram for slave %u: ", |
359 EC_SLAVE_ERR(fsm->slave, "Failed to receive SII write datagram: "); |
362 fsm->slave->ring_position); |
|
363 ec_datagram_print_state(datagram); |
360 ec_datagram_print_state(datagram); |
364 return; |
361 return; |
365 } |
362 } |
366 |
363 |
367 if (datagram->working_counter != 1) { |
364 if (datagram->working_counter != 1) { |
368 fsm->state = ec_fsm_sii_state_error; |
365 fsm->state = ec_fsm_sii_state_error; |
369 EC_ERR("Reception of SII write datagram failed on slave %u: ", |
366 EC_SLAVE_ERR(fsm->slave, "Reception of SII write datagram failed: "); |
370 fsm->slave->ring_position); |
|
371 ec_datagram_print_wc_error(datagram); |
367 ec_datagram_print_wc_error(datagram); |
372 return; |
368 return; |
373 } |
369 } |
374 |
370 |
375 fsm->jiffies_start = datagram->jiffies_sent; |
371 fsm->jiffies_start = datagram->jiffies_sent; |
398 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
394 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
399 return; |
395 return; |
400 |
396 |
401 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
397 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
402 fsm->state = ec_fsm_sii_state_error; |
398 fsm->state = ec_fsm_sii_state_error; |
403 EC_ERR("Failed to receive SII write check datagram from slave %u: ", |
399 EC_SLAVE_ERR(fsm->slave, |
404 fsm->slave->ring_position); |
400 "Failed to receive SII write check datagram: "); |
405 ec_datagram_print_state(datagram); |
401 ec_datagram_print_state(datagram); |
406 return; |
402 return; |
407 } |
403 } |
408 |
404 |
409 if (datagram->working_counter != 1) { |
405 if (datagram->working_counter != 1) { |
410 fsm->state = ec_fsm_sii_state_error; |
406 fsm->state = ec_fsm_sii_state_error; |
411 EC_ERR("Reception of SII write check datagram failed on slave %u: ", |
407 EC_SLAVE_ERR(fsm->slave, |
412 fsm->slave->ring_position); |
408 "Reception of SII write check datagram failed: "); |
413 ec_datagram_print_wc_error(datagram); |
409 ec_datagram_print_wc_error(datagram); |
414 return; |
410 return; |
415 } |
411 } |
416 |
412 |
417 #ifdef SII_DEBUG |
413 #ifdef SII_DEBUG |
418 EC_DBG("checking SII write state:\n"); |
414 EC_SLAVE_DBG(fsm->slave, 0, "checking SII write state:\n"); |
419 ec_print_data(datagram->data, 2); |
415 ec_print_data(datagram->data, 2); |
420 #endif |
416 #endif |
421 |
417 |
422 if (EC_READ_U8(datagram->data + 1) & 0x20) { |
418 if (EC_READ_U8(datagram->data + 1) & 0x20) { |
423 EC_ERR("SII: Error on last SII command!\n"); |
419 EC_SLAVE_ERR(fsm->slave, "SII: Error on last SII command!\n"); |
424 fsm->state = ec_fsm_sii_state_error; |
420 fsm->state = ec_fsm_sii_state_error; |
425 return; |
421 return; |
426 } |
422 } |
427 |
423 |
428 /* FIXME: some slaves never answer with the busy flag set... |
424 /* FIXME: some slaves never answer with the busy flag set... |
429 * wait a few ms for the write operation to complete. */ |
425 * wait a few ms for the write operation to complete. */ |
430 diff_ms = (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
426 diff_ms = (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
431 if (diff_ms < SII_INHIBIT) { |
427 if (diff_ms < SII_INHIBIT) { |
432 #ifdef SII_DEBUG |
428 #ifdef SII_DEBUG |
433 EC_DBG("too early.\n"); |
429 EC_SLAVE_DBG(fsm->slave, 0, "too early.\n"); |
434 #endif |
430 #endif |
435 // issue check datagram again |
431 // issue check datagram again |
436 fsm->retries = EC_FSM_RETRIES; |
432 fsm->retries = EC_FSM_RETRIES; |
437 return; |
433 return; |
438 } |
434 } |
442 // still busy... timeout? |
438 // still busy... timeout? |
443 if (diff_ms >= SII_TIMEOUT) { |
439 if (diff_ms >= SII_TIMEOUT) { |
444 if (fsm->check_once_more) { |
440 if (fsm->check_once_more) { |
445 fsm->check_once_more = 0; |
441 fsm->check_once_more = 0; |
446 } else { |
442 } else { |
447 EC_ERR("SII: Write timeout.\n"); |
443 EC_SLAVE_ERR(fsm->slave, "SII: Write timeout.\n"); |
448 fsm->state = ec_fsm_sii_state_error; |
444 fsm->state = ec_fsm_sii_state_error; |
449 return; |
445 return; |
450 } |
446 } |
451 } |
447 } |
452 |
448 |