summaryrefslogtreecommitdiffhomepage
path: root/digital
diff options
context:
space:
mode:
Diffstat (limited to 'digital')
-rw-r--r--digital/io/src/asserv.c62
-rw-r--r--digital/io/src/asserv.h12
-rw-r--r--digital/io/src/main.c9
3 files changed, 80 insertions, 3 deletions
diff --git a/digital/io/src/asserv.c b/digital/io/src/asserv.c
index 97cd2650..66f407a8 100644
--- a/digital/io/src/asserv.c
+++ b/digital/io/src/asserv.c
@@ -73,6 +73,21 @@ typedef struct asserv_struct_s
asserv_struct_s asserv_status;
/**
+ * Retransmit counter initial value.
+ */
+#define ASSERV_RETRANSMIT_COUNT 10
+
+/**
+ * Retransmit counter.
+ */
+static uint8_t asserv_retransmit_counter;
+
+/**
+ * Length of the last transmitted command.
+ */
+static uint8_t asserv_retransmit_length;
+
+/**
* Update TWI module until request (send or receive) is finished.
* This functions is blocking.
*/
@@ -93,6 +108,20 @@ asserv_twi_update (void);
static inline uint8_t
asserv_twi_send_command (uint8_t command, uint8_t length);
+/**
+ * Send a prepared command to the asserv board using TWI module.
+ * It will reset the counter retransmission value and store the length for
+ * future retransmission.
+ * In comparison with \a asserv_twi_send_command this function is internal and
+ * used by \a asserv_twi_send_command.
+ * @param length th length of the complete command with parameters.
+ * @return
+ * - 0 if no error occurred.
+ * - 1 if TWI transmission failed.
+ */
+static inline uint8_t
+asserv_twi_send (uint8_t length);
+
/* Update TWI module until request (send or receive) is finished. */
static inline void
asserv_twi_update (void)
@@ -114,12 +143,26 @@ asserv_twi_send_command (uint8_t command, uint8_t length)
/* Put the sequence number */
asserv_twi_buffer[1] = ++asserv_twi_seq;
+ /* Send the prepared command */
+ return asserv_twi_send (length + 2);
+}
+
+/* Send a prepared command to the asserv board using TWI module. */
+static inline uint8_t
+asserv_twi_send (uint8_t length)
+{
/* Send command to the asserv */
- if (twi_ms_send (AC_ASSERV_TWI_ADDRESS, asserv_twi_buffer, length + 2) != 0)
+ if (twi_ms_send (AC_ASSERV_TWI_ADDRESS, asserv_twi_buffer, length) != 0)
return 1;
/* Update until the command is sent */
asserv_twi_update ();
+
+ /* Reset retransmit counter */
+ asserv_retransmit_counter = ASSERV_RETRANSMIT_COUNT;
+ /* Store length for retransmission */
+ asserv_retransmit_length = length;
+
return 0;
}
/** @} */
@@ -164,6 +207,23 @@ asserv_last_cmd_ack (void)
return (asserv_status.seq == asserv_twi_seq);
}
+/**
+ * Re-send command if not acknowledged.
+ */
+uint8_t
+asserv_retransmit (void)
+{
+ /* Check if we have reached the maximum number of check before
+ * retransmission */
+ if (--asserv_retransmit_counter == 0)
+ {
+ /* Retransmit! */
+ asserv_twi_send (asserv_retransmit_length);
+ return 1;
+ }
+ return 0;
+}
+
/* Is last move class command has successfully ended? */
asserv_status_e
asserv_move_cmd_status (void)
diff --git a/digital/io/src/asserv.h b/digital/io/src/asserv.h
index 6bb883d2..ab81118a 100644
--- a/digital/io/src/asserv.h
+++ b/digital/io/src/asserv.h
@@ -69,6 +69,18 @@ uint8_t
asserv_last_cmd_ack (void);
/**
+ * Re-send command if not acknowledged.
+ * This function should be called when the command has not been acknowledged
+ * by the asserv board. It will re send the last command when a certain number
+ * of cycle has been reached without any acknowledge from the asserv.
+ * @return
+ * - 0 if the command was not received.
+ * - 1 if the command was re-sent.
+ */
+uint8_t
+asserv_retransmit (void);
+
+/**
* Status of a move or arm class command.
* It is return by status functions.
*/
diff --git a/digital/io/src/main.c b/digital/io/src/main.c
index bab667e4..20eace93 100644
--- a/digital/io/src/main.c
+++ b/digital/io/src/main.c
@@ -93,8 +93,13 @@ main_loop (void)
/* Manage UART protocol */
proto_accept (uart0_getc ());
- /* Update TWI module to get new data */
- // TODO
+ /* Update TWI module to get new data from the asserv board */
+ asserv_update_status ();
+
+ /* Is last command has been acknowledged? */
+ if (asserv_last_cmd_ack () == 0)
+ /* Called function to manage retransmission */
+ asserv_retransmit ();
}
}