diff options
Diffstat (limited to 'arduino/ace_old/transport.c')
-rw-r--r-- | arduino/ace_old/transport.c | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/arduino/ace_old/transport.c b/arduino/ace_old/transport.c deleted file mode 100644 index 986165e..0000000 --- a/arduino/ace_old/transport.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "transport.h" -#include "link.h" - -#include <stdlib.h> -#include <stdbool.h> -#include <avr/interrupt.h> - -//ms -#define EXTRA_TIME 200 -#define MAX_RESENDS 5 -#define MAX_SEQ 255 - -#define next_seq(k) if (k < MAX_SEQ) k = k + 1; else k = 0 - -#define DATA 0x05 -#define ACK 0x06 - - -static void start_sending(message* msg, bool resend); -static void stop_sending(); - - -typedef enum { - RECEIVED_PACKET, - TIMEOUT -} event_kind; - -typedef struct { - event_kind kind; - packet* payload; -} event; - -static void disassemble_packet(packet* p, uint8_t* seq, uint8_t* command, uint8_t** msg, uint16_t* message_length) { - if (seq != NULL) *seq = p->data[0]; - if (command != NULL) *command = p->data[1]; - if (msg != NULL) *msg = &(p->data[2]); - if (message_length != NULL) *message_length = p->length - 2; -} - -static void assemble_packet(packet* p, uint8_t seq, uint8_t command, uint8_t* msg, uint16_t message_length) { - p->data[0] = seq; - p->data[1] = command; - int i; - for (i = 0; i < message_length; ++i) { - p->data[i+2] = msg[i]; - } - p->length = message_length + 2; -} - -static packet* ack(uint8_t seq) { - static uint8_t ack_buffer[] = {0, ACK}; - static packet ack_packet = {ack_buffer, 2}; - ack_buffer[0] = seq; - return &ack_packet; -} - -static volatile bool awaiting_ack = false; -static volatile uint8_t last_sent_seq = 0; -static volatile uint8_t resends = 0; -static volatile uint8_t last_sent_buffer[MAX_PACKET_SIZE]; -static volatile packet last_sent = {last_sent_buffer, 0}; - -static void process_event(event* e) { - static uint8_t last_received_seq = 0; - - switch(e->kind) { - case RECEIVED_PACKET: { - uint8_t seq; - uint8_t cmd; - static message msg; - disassemble_packet(e->payload, &seq, &cmd, &msg.data, &msg.length); - - if (!awaiting_ack) { - if (cmd == DATA) { - if (last_received_seq != seq) { - last_received_seq = seq; - from_transport_layer(RECEIVED, &msg); - } - to_link_layer(ack(seq)); - } - //ignore case in which an ack is received even though none is awaited - - } else { //waiting for an ack - stop_sending(); - disassemble_packet(&last_sent, NULL, NULL, &msg.data, &msg.length); - if (cmd == ACK && seq == last_sent_seq) { - from_transport_layer(SEND_SUCCESS, &msg); - } else { - from_transport_layer(BAD_ACK, &msg); - } - } - } break; - case TIMEOUT: - if (resends > MAX_RESENDS) { - message msg; - disassemble_packet(&last_sent, NULL, NULL, &msg.data, &msg.length); - stop_sending(); - from_transport_layer(NO_ACK, &msg); - } else { - start_sending(NULL, true); - } - break; - } -} - -static void start_sending(message* msg, bool resend) { - if (resend) { - resends = resends + 1; - } else { - next_seq(last_sent_seq); - assemble_packet(&last_sent, last_sent_seq, DATA, msg->data, msg->length); - resends = 0; - TIMSK1 |= (1 << OCIE1A); - } - - awaiting_ack = true; - to_link_layer(&last_sent); -} - -static void stop_sending() { - TIMSK1 &= ~(1 << OCIE1A); - awaiting_ack = false; -} - -static volatile uint32_t ticks; -static volatile uint32_t max_ticks; - -void init_transport_layer(uint32_t timeout_millis) { - cli(); - TCCR1A = 0; // set entire TCCR1A register to 0 - TCCR1B = 0; // same for TCCR1B - // turn on CTC mode: - TCCR1B |= (1 << WGM12); - // set CS31 for 64 prescaler - TCCR1B |= (1 << CS11); - // set compare match register to desired timer count: - OCR1A = F_CPU / 1000 / 64; // should be 250 for F_CPU=16Mhz and f = 1000Hz - sei(); - - //the timer should now interrupt every ms - max_ticks = timeout_millis; -} - -ISR(TIMER1_COMPA_vect) { - static event e = {TIMEOUT, NULL}; - - ticks = ticks + 1; - if (ticks > max_ticks) { - process_event(&e); - ticks = 0; - } -} - -void from_link_layer(packet* r) { - static event e = {RECEIVED_PACKET, NULL}; - e.payload = r; - process_event(&e); -} - -void to_transport_layer(message* s) { - if (!awaiting_ack) - start_sending(s, false); - else - from_transport_layer(BUSY, s); -} - |