X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=arducontrol%2Finterface.c;h=a73189648669345eda9a8589bc7d56ab9e94f12d;hb=ae0ea6bd659e35ae9ea324dd010c66f6c176d6ff;hp=9d21e9cbfe1ddf874d0e41b9807aa29a2164686e;hpb=b47b38e9dd282c5f8fb1ded25ade805e64d0cf1a;p=model-railway-devices.git diff --git a/arducontrol/interface.c b/arducontrol/interface.c index 9d21e9c..a731896 100644 --- a/arducontrol/interface.c +++ b/arducontrol/interface.c @@ -1,114 +1,148 @@ +#include +#include "clock.h" #include "interface.h" +#include "mfx.h" #include "monitor.h" #include "motorola.h" #include "output.h" #include "serial.h" +#include "s88.h" -volatile uint8_t recv_buf[32]; -uint8_t recv_head = 0; -uint8_t recv_tail = 0; -volatile uint8_t recv_fill = 0; -volatile uint8_t recv_overrun = 0; -uint8_t cmd_buf[15]; -uint8_t cmd_length; +static uint8_t cmd_buffer[15]; +static uint8_t cmd_length = 0; +static uint8_t cmd_read_pos = 0; +static uint16_t baud_rate = 9600; +static uint16_t baud_change = 0; +static uint32_t baud_changed_at = 0; -void process_commands(); -uint8_t process_command(); +static uint8_t dispatch_command(const uint8_t *, uint8_t); +uint8_t interface_command(const uint8_t *, uint8_t); -void interface_init() +void interface_init(void) { + DDRB |= 0x01; DDRD = (DDRD&0xFC)|0x02; - serial_init(9600); + serial_init(baud_rate); } -void interface_check() +void interface_check(void) { - if(recv_overrun) - { - serial_write(0xFE); - serial_write(RECEIVE_OVERRUN); - recv_overrun = 0; - } - if(recv_fill>0) - process_commands(); -} + if(serial_read_overrun()) + interface_send1(RECEIVE_OVERRUN); -void process_commands() -{ - while(recv_fill>0) + uint8_t count = serial_read_available(); + if(count>0) { - uint8_t consumed; - uint8_t c = recv_buf[recv_tail]; - - cmd_length = 0; + PORTB |= 0x01; + 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(c>=0xF0) + if(cmd_read_poscmd_length) + count = cmd_length-cmd_read_pos; + for(uint8_t i=0; i=cmd_length) { - if(j>=sizeof(recv_buf)) - j = 0; - cmd_buf[i] = recv_buf[j]; + uint8_t result = dispatch_command(cmd_buffer, cmd_length); + interface_send1(result); + cmd_length = 0; } - - consumed = 1+cmd_length; } - else + PORTB &= ~0x01; + } + + if(baud_change) + { + if(!baud_changed_at) { - serial_write(0xFE); - serial_write(FRAMING_ERROR); - consumed = 1; + baud_changed_at = clock_get(); + serial_set_baud(baud_change); } - - recv_tail += consumed; - if(recv_tail>=sizeof(recv_buf)) - recv_tail -= sizeof(recv_buf); - recv_fill -= consumed; - - if(cmd_length>0) + else if(clock_get()-baud_changed_at>3*CLOCK_RATE) { - uint8_t result = process_command(); - serial_write(0xFE); - serial_write(result); + baud_change = 0; + serial_set_baud(baud_rate); + interface_send1(BAUD_CHANGE_FAILED); } } } -uint8_t process_command() +static uint8_t dispatch_command(const uint8_t *cmd, uint8_t length) { - uint8_t type = cmd_buf[0]>>4; + uint8_t type = cmd[0]>>4; if(type==0) { - uint8_t subtype = (cmd_buf[0]>>3)&1; + uint8_t subtype = (cmd[0]>>3)&1; if(subtype==0) - return output_command(); + return output_command(cmd, length); else - return monitor_command(); + return monitor_command(cmd, length); } else if(type==1) - return motorola_command(); + return motorola_command(cmd, length); + else if(type==2) + return mfx_command(cmd, length); + else if(type==3) + return s88_command(cmd, length); + else if(type==7) + return interface_command(cmd, length); else return INVALID_COMMAND; } -static inline void receive(uint8_t c) +void interface_send(const uint8_t *cmd, uint8_t length) { - if(recv_fill>=sizeof(recv_buf)) + serial_write(~length); + for(uint8_t i=0; i=sizeof(recv_buf)) - recv_head = 0; - ++recv_fill; + return COMMAND_OK; } - -SERIAL_SET_CALLBACK(receive)