]> git.tdb.fi Git - model-railway-devices.git/commitdiff
Make arducontrol interface asynchronous again
authorMikko Rasa <tdb@tdb.fi>
Wed, 30 Oct 2013 21:50:00 +0000 (23:50 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 30 Oct 2013 21:50:00 +0000 (23:50 +0200)
Blocking the main loop for extended periods of time (as could previously
happen with an incomplete packet) is bad, because it prevents the monitor
from triggering overcurrent shutdown.

arducontrol/interface.c

index 1cc4b15fa77a1af3c9f3eae71a2a49dbf5144f89..c5a7262d4c12199b217f0430f5ffe288c399afe6 100644 (file)
@@ -6,6 +6,10 @@
 #include "serial.h"
 #include "s88.h"
 
+static uint8_t cmd_buffer[15];
+static uint8_t cmd_length = 0;
+static uint8_t cmd_read_pos = 0;
+
 uint8_t dispatch_command(const uint8_t *, uint8_t);
 
 void interface_init(void)
@@ -17,27 +21,42 @@ void interface_init(void)
 
 void interface_check(void)
 {
+       uint8_t count;
        if(serial_read_overrun())
                interface_send1(RECEIVE_OVERRUN);
 
-       while(serial_read_available())
+       count = serial_read_available();
+       if(count>0)
        {
-               uint8_t length = ~serial_read();
+               if(cmd_length==0)
+               {
+                       uint8_t l = ~serial_read();
+                       if(l==0)
+                               serial_write(0xFF);
+                       else if(l>=0x10)
+                               interface_send1(FRAMING_ERROR);
+                       else
+                       {
+                               cmd_length = l;
+                               --count;
+                               cmd_read_pos = 0;
+                       }
+               }
 
-               if(length==0)
-                       serial_write(0xFF);
-               else if(length>=0x10)
-                       interface_send1(FRAMING_ERROR);
-               else
+               if(cmd_read_pos<cmd_length)
                {
-                       uint8_t cmd[15];
                        uint8_t i;
+                       if(cmd_read_pos+count>cmd_length)
+                               count = cmd_length-cmd_read_pos;
+                       for(i=0; i<count; ++i)
+                               cmd_buffer[cmd_read_pos++] = serial_read();
 
-                       for(i=0; i<length; ++i)
-                               cmd[i] = serial_read();
-
-                       uint8_t result = dispatch_command(cmd, length);
-                       interface_send1(result);
+                       if(cmd_read_pos>=cmd_length)
+                       {
+                               uint8_t result = dispatch_command(cmd_buffer, cmd_length);
+                               interface_send1(result);
+                               cmd_length = 0;
+                       }
                }
        }
 }