Serveral changes to avoid timeouts under high CPU load.
--- a/master/datagram.c Mon Oct 16 08:03:28 2006 +0000
+++ b/master/datagram.c Mon Oct 16 09:07:49 2006 +0000
@@ -78,6 +78,7 @@
datagram->working_counter = 0x00;
datagram->state = EC_DATAGRAM_INIT;
datagram->cycles_sent = 0;
+ datagram->check_once_more = 0;
}
/*****************************************************************************/
--- a/master/datagram.h Mon Oct 16 08:03:28 2006 +0000
+++ b/master/datagram.h Mon Oct 16 09:07:49 2006 +0000
@@ -119,6 +119,7 @@
uint16_t working_counter; /**< working counter */
ec_datagram_state_t state; /**< datagram state */
cycles_t cycles_sent; /**< time, the datagram was sent */
+ uint8_t check_once_more; /**< one more try in case of timeout */
}
ec_datagram_t;
--- a/master/fsm.c Mon Oct 16 08:03:28 2006 +0000
+++ b/master/fsm.c Mon Oct 16 09:07:49 2006 +0000
@@ -265,7 +265,7 @@
ec_master_t *master = fsm->master;
if (datagram->state != EC_DATAGRAM_RECEIVED) {
- EC_ERR("Failed tor receive broadcast datagram.\n");
+ EC_ERR("Failed to receive broadcast datagram.\n");
fsm->master_state = ec_fsm_error;
return;
}
@@ -1613,6 +1613,7 @@
return;
}
+ fsm->sii_check_once_more = 1;
fsm->sii_start = get_cycles();
// issue check/fetch datagram
@@ -1649,16 +1650,19 @@
if (EC_READ_U8(datagram->data + 1) & 0x81) {
// still busy... timeout?
if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) {
- EC_ERR("SII: Read timeout.\n");
- fsm->sii_state = ec_fsm_error;
+ if (!fsm->sii_check_once_more) {
+ EC_ERR("SII: Read timeout.\n");
+ fsm->sii_state = ec_fsm_error;
#if 0
- EC_DBG("SII busy: %02X %02X %02X %02X\n",
- EC_READ_U8(datagram->data + 0),
- EC_READ_U8(datagram->data + 1),
- EC_READ_U8(datagram->data + 2),
- EC_READ_U8(datagram->data + 3));
+ EC_DBG("SII busy: %02X %02X %02X %02X\n",
+ EC_READ_U8(datagram->data + 0),
+ EC_READ_U8(datagram->data + 1),
+ EC_READ_U8(datagram->data + 2),
+ EC_READ_U8(datagram->data + 3));
#endif
- return;
+ return;
+ }
+ fsm->sii_check_once_more = 0;
}
// issue check/fetch datagram again
--- a/master/fsm.h Mon Oct 16 08:03:28 2006 +0000
+++ b/master/fsm.h Mon Oct 16 09:07:49 2006 +0000
@@ -72,6 +72,7 @@
unsigned int sii_mode; /**< SII reading done by APRD (0) or NPRD (1) */
uint8_t sii_value[4]; /**< raw SII value (32bit) */
cycles_t sii_start; /**< sii start */
+ uint8_t sii_check_once_more; /**< do one more check in case of timeout */
void (*change_state)(ec_fsm_t *); /**< slave state change state function */
ec_slave_state_t change_new; /**< input: new state */
--- a/master/master.c Mon Oct 16 08:03:28 2006 +0000
+++ b/master/master.c Mon Oct 16 09:07:49 2006 +0000
@@ -356,6 +356,7 @@
datagram->state = EC_DATAGRAM_SENT;
datagram->cycles_sent = cycles_start;
+ datagram->check_once_more = 1;
datagram->index = master->datagram_index++;
if (unlikely(master->debug_level > 1))
@@ -1313,7 +1314,7 @@
ec_device_call_isr(master->device);
cycles_received = get_cycles();
- cycles_timeout = EC_IO_TIMEOUT * cpu_khz / 1000;
+ cycles_timeout = EC_IO_TIMEOUT /* us */ * cpu_khz / 1000;
// dequeue all datagrams that timed out
list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
@@ -1321,6 +1322,11 @@
case EC_DATAGRAM_SENT:
case EC_DATAGRAM_QUEUED:
if (cycles_received - datagram->cycles_sent > cycles_timeout) {
+ if (datagram->state == EC_DATAGRAM_SENT
+ && datagram->check_once_more) {
+ datagram->check_once_more = 0;
+ break;
+ }
list_del_init(&datagram->queue);
datagram->state = EC_DATAGRAM_TIMED_OUT;
master->stats.timeouts++;