X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=arducontrol%2Foutput.c;h=e017560c5cf6e12930f3b65003b4eae1823868b0;hb=285513c401954c5ad012ae4ae5411f72b7f73ffc;hp=c1d51488349359ae9101a9762c2837bf257aebce;hpb=b47b38e9dd282c5f8fb1ded25ade805e64d0cf1a;p=model-railway-devices.git diff --git a/arducontrol/output.c b/arducontrol/output.c index c1d5148..e017560 100644 --- a/arducontrol/output.c +++ b/arducontrol/output.c @@ -3,36 +3,70 @@ #include "output.h" #include "timer.h" -OutputPacket packet; -uint8_t out_bit; -uint8_t out_time; -uint8_t out_data; -uint8_t delay_time; +#define POLARITY PORTD2 +#define ENABLE PORTD3 +#define BIT(x) (1<<(x)) -void output_init() +enum State +{ + IDLE, + READY, + SENDING +}; + +OutputPacket packets[4]; +uint8_t chain_length; +uint8_t current_packet; +volatile uint8_t packet_state = IDLE; +static uint8_t out_bit; +static uint8_t out_time; +static uint8_t out_data; +static uint8_t delay_time; + +void output_init(void) { DDRD = (DDRD&0xF3)|0x0C; - PORTD &= ~0x08; + PORTD &= ~BIT(ENABLE); + + timer_start_hz(2, 80000, 1); +} - timer_start_hz(0, 80000, 1); +OutputPacket *output_create_packet(void) +{ + while(packet_state!=IDLE) ; + chain_length = 1; + return &packets[0]; } -void clear_packet() +OutputPacket *output_create_chained_packet(void) { - packet.ready = 0; - packet.sending = 0; - packet.done = 0; + ++chain_length; + return &packets[chain_length-1]; +} + +void output_send_packet(void) +{ + if(packet_state!=IDLE) + return; + + current_packet = 0; + packet_state = READY; } void output_set_power(uint8_t p) { if(p==POWER_ON) - PORTD |= 0x08; + PORTD |= BIT(ENABLE); else - PORTD &= ~0x08; + PORTD &= ~BIT(ENABLE); } -uint8_t output_command() +uint8_t output_is_power_on() +{ + return (PORTD&BIT(ENABLE))!=0; +} + +uint8_t output_command(const uint8_t *cmd_buf, uint8_t cmd_length) { if(cmd_buf[0]==POWER_ON || cmd_buf[0]==POWER_OFF) { @@ -41,65 +75,78 @@ uint8_t output_command() output_set_power(cmd_buf[0]==POWER_ON); } + else if(cmd_buf[0]==READ_POWER_STATE) + { + if(cmd_length!=1) + return LENGTH_ERROR; + + uint8_t reply[2]; + reply[0] = POWER_STATE; + reply[1] = output_is_power_on(); + interface_send(reply, 2); + } else return INVALID_COMMAND; return COMMAND_OK; } -static inline void output_tick() +static inline void output_tick(void) { if(delay_time && --delay_time) return; if(out_time && !--out_time) { + OutputPacket *packet = &packets[current_packet]; ++out_bit; - if(out_bit>=packet.length) + if(out_bit>=packet->length) { - PORTD &= ~0x04; - if(packet.repeat_count>1) + PORTD &= ~BIT(POLARITY); + if(--packet->repeat_count) { - if(packet.repeat_count<0xFF) - --packet.repeat_count; - delay_time = packet.repeat_delay; - packet.sending = 0; + delay_time = packet->repeat_delay; + packet_state = READY; } else { - delay_time = packet.final_delay; - packet.done = 1; + delay_time = packet->final_delay; + if(++current_packet>3]; + out_data = packet->data[out_bit>>3]; else out_data >>= 1; if(out_data&1) - PORTD |= 0x04; + PORTD |= BIT(POLARITY); else - PORTD &= ~0x04; + PORTD &= ~BIT(POLARITY); - out_time = packet.bit_duration; + out_time = packet->bit_duration; } return; } - if(packet.ready && !packet.sending) + if(packet_state==READY) { - packet.sending = 1; + OutputPacket *packet = &packets[current_packet]; + packet_state = SENDING; out_bit = 0; - out_time = packet.bit_duration; - out_data = packet.data[0]; + out_time = packet->bit_duration; + out_data = packet->data[0]; if(out_data&1) - PORTD |= 0x04; + PORTD |= BIT(POLARITY); else - PORTD &= ~0x04; + PORTD &= ~BIT(POLARITY); } } -TIMER_SET_CALLBACK(0, output_tick) +TIMER_SET_CALLBACK(2, output_tick)