]> git.tdb.fi Git - model-railway-devices.git/blobdiff - arducontrol/output.c
Hide details of output packet lifecycle
[model-railway-devices.git] / arducontrol / output.c
index c1d51488349359ae9101a9762c2837bf257aebce..673f23242d0b93aab450ea1eb4129ad3acb531a7 100644 (file)
@@ -3,36 +3,60 @@
 #include "output.h"
 #include "timer.h"
 
+#define POLARITY PORTD2
+#define ENABLE PORTD3
+#define BIT(x) (1<<(x))
+
+enum State
+{
+       IDLE,
+       READY,
+       SENDING
+};
+
 OutputPacket packet;
-uint8_t out_bit;
-uint8_t out_time;
-uint8_t out_data;
-uint8_t delay_time;
+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 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) ;
+       return &packet;
 }
 
-void clear_packet()
+void output_send_packet(void)
 {
-       packet.ready = 0;
-       packet.sending = 0;
-       packet.done = 0;
+       if(packet_state!=IDLE)
+               return;
+
+       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,13 +65,23 @@ 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;
@@ -57,18 +91,18 @@ static inline void output_tick()
                ++out_bit;
                if(out_bit>=packet.length)
                {
-                       PORTD &= ~0x04;
+                       PORTD &= ~BIT(POLARITY);
                        if(packet.repeat_count>1)
                        {
                                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
@@ -79,9 +113,9 @@ static inline void output_tick()
                                out_data >>= 1;
 
                        if(out_data&1)
-                               PORTD |= 0x04;
+                               PORTD |= BIT(POLARITY);
                        else
-                               PORTD &= ~0x04;
+                               PORTD &= ~BIT(POLARITY);
 
                        out_time = packet.bit_duration;
                }
@@ -89,17 +123,17 @@ static inline void output_tick()
                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];
                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)