From 3fb968420f55aedcac23f7bd42da8485fc210c92 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 2 Nov 2013 15:46:01 +0200 Subject: [PATCH] Hide details of output packet lifecycle Other modules should have no need to mess with the packet state directly. --- arducontrol/motorola.c | 73 ++++++++++++++++++++---------------------- arducontrol/output.c | 31 +++++++++++++----- arducontrol/output.h | 10 ++---- 3 files changed, 61 insertions(+), 53 deletions(-) diff --git a/arducontrol/motorola.c b/arducontrol/motorola.c index 3e1a41c..ff686ca 100644 --- a/arducontrol/motorola.c +++ b/arducontrol/motorola.c @@ -12,82 +12,85 @@ static uint8_t motorola_speed_to_value(uint8_t speed) return 0; } -static void motorola_common_packet(uint8_t addr, uint8_t aux, uint8_t value) +static OutputPacket *motorola_common_packet(uint8_t addr, uint8_t aux, uint8_t value) { uint8_t i; - clear_packet(); + OutputPacket *packet = output_create_packet(); - packet.bit_duration = 2; - packet.length = 18*8; + packet->bit_duration = 2; + packet->length = 18*8; for(i=0; i<4; ++i) { uint8_t d = addr%3; addr /= 3; - packet.data[i*2] = (d==0 ? 0x01 : 0x7F); - packet.data[i*2+1] = (d==1 ? 0x7F : 0x01); + packet->data[i*2] = (d==0 ? 0x01 : 0x7F); + packet->data[i*2+1] = (d==1 ? 0x7F : 0x01); } - packet.data[8] = (aux ? 0x7F : 0x01); - packet.data[9] = packet.data[8]; + packet->data[8] = (aux ? 0x7F : 0x01); + packet->data[9] = packet->data[8]; for(i=0; i<4; ++i) { - packet.data[10+i*2] = ((value&1) ? 0x7F : 0x01); + packet->data[10+i*2] = ((value&1) ? 0x7F : 0x01); value >>= 1; } - packet.repeat_count = 2; + packet->repeat_count = 2; // Duration of three trits - packet.repeat_delay = 96; - packet.final_delay = 224; + packet->repeat_delay = 96; + packet->final_delay = 224; + + return packet; } -static void motorola_old_packet(uint8_t addr, uint8_t aux, uint8_t value) +static OutputPacket *motorola_old_packet(uint8_t addr, uint8_t aux, uint8_t value) { uint8_t i; - motorola_common_packet(addr, aux, value); + OutputPacket *packet = motorola_common_packet(addr, aux, value); for(i=0; i<4; ++i) - packet.data[11+i*2] = packet.data[10+i*2]; + packet->data[11+i*2] = packet->data[10+i*2]; + + return packet; } void motorola_locomotive_speed_packet(uint8_t addr, uint8_t aux, uint8_t speed) { motorola_old_packet(addr, aux, motorola_speed_to_value(speed)); - - packet.ready = 1; + output_send_packet(); } void motorola_locomotive_reverse_packet(uint8_t addr, uint8_t aux) { motorola_old_packet(addr, aux, 1); - - packet.ready = 1; + output_send_packet(); } void motorola_locomotive_speed_direction_packet(uint8_t addr, uint8_t aux, uint8_t speed, uint8_t dir) { - motorola_common_packet(addr, aux, motorola_speed_to_value(speed)); + OutputPacket *packet = motorola_common_packet(addr, aux, motorola_speed_to_value(speed)); - packet.data[11] = (dir ? 0x01 : 0x7F); - packet.data[13] = (dir ? 0x7F : 0x01); - packet.data[15] = (dir ? 0x01 : 0x7F); - packet.data[17] = 0x80-packet.data[16]; + packet->data[11] = (dir ? 0x01 : 0x7F); + packet->data[13] = (dir ? 0x7F : 0x01); + packet->data[15] = (dir ? 0x01 : 0x7F); + packet->data[17] = 0x80-packet->data[16]; - packet.ready = 1; + output_send_packet(); } void motorola_locomotive_speed_function_packet(uint8_t addr, uint8_t aux, uint8_t speed, uint8_t func, uint8_t state) { uint8_t i; uint8_t value; + OutputPacket *packet; value = motorola_speed_to_value(speed); - motorola_common_packet(addr, aux, value); + packet = motorola_common_packet(addr, aux, value); /* 001 -> 011 @@ -105,11 +108,11 @@ void motorola_locomotive_speed_function_packet(uint8_t addr, uint8_t aux, uint8_ for(i=0; i<4; ++i) { - packet.data[11+i*2] = ((func&1) ? 0x7F : 0x01); + packet->data[11+i*2] = ((func&1) ? 0x7F : 0x01); func >>= 1; } - packet.ready = 1; + output_send_packet(); } void motorola_solenoid_packet(uint8_t addr, uint8_t output, uint8_t state) @@ -118,11 +121,11 @@ void motorola_solenoid_packet(uint8_t addr, uint8_t output, uint8_t state) if(state) value |= 8; - motorola_old_packet(addr, 0, value); - packet.repeat_delay >>= 1; - packet.bit_duration = 1; + OutputPacket *packet = motorola_old_packet(addr, 0, value); + packet->repeat_delay >>= 1; + packet->bit_duration = 1; - packet.ready = 1; + output_send_packet(); } uint8_t motorola_command(const uint8_t *cmd_buf, uint8_t cmd_length) @@ -156,8 +159,6 @@ uint8_t motorola_command(const uint8_t *cmd_buf, uint8_t cmd_length) uint8_t dir = !(cmd_buf[3]&0x80); - while(packet.ready && !packet.done) ; - if(cmd_buf[0]==MOTOROLA_SPEED) motorola_locomotive_speed_packet(addr, aux, speed); else if(cmd_buf[0]==MOTOROLA_SPEED_DIRECTION) @@ -178,8 +179,6 @@ uint8_t motorola_command(const uint8_t *cmd_buf, uint8_t cmd_length) return INVALID_VALUE; uint8_t aux = cmd_buf[2]&0x01; - while(packet.ready && !packet.done) ; - motorola_locomotive_reverse_packet(addr, aux); } else if(cmd_buf[0]==MOTOROLA_SOLENOID) @@ -196,8 +195,6 @@ uint8_t motorola_command(const uint8_t *cmd_buf, uint8_t cmd_length) uint8_t output = (cmd_buf[2]&0x70)>>4; uint8_t state = cmd_buf[2]&1; - while(packet.ready && !packet.done) ; - motorola_solenoid_packet(addr, output, state); } else diff --git a/arducontrol/output.c b/arducontrol/output.c index 38d1045..673f232 100644 --- a/arducontrol/output.c +++ b/arducontrol/output.c @@ -7,7 +7,15 @@ #define ENABLE PORTD3 #define BIT(x) (1<<(x)) +enum State +{ + IDLE, + READY, + SENDING +}; + OutputPacket packet; +volatile uint8_t packet_state = IDLE; static uint8_t out_bit; static uint8_t out_time; static uint8_t out_data; @@ -21,11 +29,18 @@ void output_init(void) timer_start_hz(2, 80000, 1); } -void clear_packet(void) +OutputPacket *output_create_packet(void) { - packet.ready = 0; - packet.sending = 0; - packet.done = 0; + while(packet_state!=IDLE) ; + return &packet; +} + +void output_send_packet(void) +{ + if(packet_state!=IDLE) + return; + + packet_state = READY; } void output_set_power(uint8_t p) @@ -82,12 +97,12 @@ static inline void output_tick(void) if(packet.repeat_count<0xFF) --packet.repeat_count; delay_time = packet.repeat_delay; - packet.sending = 0; + packet_state = READY; } else { delay_time = packet.final_delay; - packet.done = 1; + packet_state = IDLE; } } else @@ -108,9 +123,9 @@ static inline void output_tick(void) return; } - if(packet.ready && !packet.sending) + if(packet_state==READY) { - packet.sending = 1; + packet_state = SENDING; out_bit = 0; out_time = packet.bit_duration; out_data = packet.data[0]; diff --git a/arducontrol/output.h b/arducontrol/output.h index 988c16e..162e1e0 100644 --- a/arducontrol/output.h +++ b/arducontrol/output.h @@ -5,10 +5,7 @@ typedef struct { - uint8_t bit_duration:5; - uint8_t ready:1; - uint8_t sending:1; - volatile uint8_t done:1; + uint8_t bit_duration; uint8_t length; uint8_t data[32]; uint8_t repeat_count; @@ -16,10 +13,9 @@ typedef struct uint8_t final_delay; } OutputPacket; -extern OutputPacket packet; - void output_init(void); -void clear_packet(void); +OutputPacket *output_create_packet(void); +void output_send_packet(void); void output_set_power(uint8_t); uint8_t output_is_power_on(); uint8_t output_command(const uint8_t *, uint8_t); -- 2.43.0