]> git.tdb.fi Git - model-railway-devices.git/blobdiff - arducontrol/arducontrol.c
Organize arducontrol code by functionality
[model-railway-devices.git] / arducontrol / arducontrol.c
index d09fc09c3766e3dca9d41dbbd0125e250dae8c28..882f280b9e432b3dd3399f0230a011b4404d34d4 100644 (file)
@@ -34,361 +34,24 @@ blocks until the operation completes.  The command returns as soon as sending
 its data to the track can start.
 */
 #include <avr/io.h>
-#include "adc.h"
-#include "commands.h"
-#include "motorola.h"
-#include "packet.h"
-#include "serial.h"
-#include "timer.h"
-
-Packet packet;
-uint8_t out_bit;
-uint8_t out_time;
-uint8_t out_data;
-uint8_t delay_time;
-
-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;
-
-uint16_t track_current_samples[16] = { 0 };
-uint8_t track_current_head = 0;
-volatile uint16_t track_current_sum = 0;
-uint16_t overcurrent_limit = 1000<<4;
-uint8_t overcurrent_sent = 0;
-
-uint16_t input_voltage_samples[16] = { 0 };
-uint8_t input_voltage_head = 0;
-volatile uint16_t input_voltage_sum = 0;
-
-volatile uint8_t adc_state = 0;
-
-void process_commands();
-uint8_t process_command();
+#include <avr/interrupt.h>
+#include "interface.h"
+#include "monitor.h"
+#include "output.h"
 
 int main()
 {
-       DDRD = 0x0E;
-       PORTD = 0;
-
-       serial_init(9600);
-       timer_start_hz(0, 80000, 1);
-       adc_init();
+       output_init();
+       interface_init();
+       monitor_init();
 
        sei();
 
        while(1)
        {
-               if(recv_overrun)
-               {
-                       serial_write(0xFE);
-                       serial_write(RECEIVE_OVERRUN);
-                       recv_overrun = 0;
-               }
-               if(recv_fill>0)
-                       process_commands();
-               if(!(adc_state&1))
-               {
-                       ++adc_state;
-                       adc_read_async(adc_state>>1);
-               }
-               if(track_current_sum>overcurrent_limit)
-               {
-                       PORTD &= ~0x08;
-                       if(!overcurrent_sent)
-                       {
-                               overcurrent_sent = 1;
-                               serial_write(0xFE);
-                               serial_write(OVERCURRENT);
-                       }
-               }
-               else
-                       overcurrent_sent = 0;
+               interface_check();
+               monitor_check();
        }
 
        return 0;
 }
-
-static inline void receive(uint8_t c)
-{
-       if(recv_fill>=sizeof(recv_buf))
-       {
-               recv_overrun = 1;
-               return;
-       }
-
-       recv_buf[recv_head++] = c;
-       if(recv_head>=sizeof(recv_buf))
-               recv_head = 0;
-       ++recv_fill;
-}
-
-SERIAL_SET_CALLBACK(receive)
-
-void process_commands()
-{
-       while(recv_fill>0)
-       {
-               uint8_t consumed;
-               uint8_t c = recv_buf[recv_tail];
-
-               cmd_length = 0;
-
-               if(c>=0xF0)
-               {
-                       cmd_length = ~c;
-                       if(recv_fill<=cmd_length)
-                               break;
-
-                       uint8_t i, j;
-                       for(i=0, j=recv_tail+1; i<cmd_length; ++i, ++j)
-                       {
-                               if(j>=sizeof(recv_buf))
-                                       j = 0;
-                               cmd_buf[i] = recv_buf[j];
-                       }
-
-                       consumed = 1+cmd_length;
-               }
-               else
-               {
-                       serial_write(0xFE);
-                       serial_write(FRAMING_ERROR);
-                       consumed = 1;
-               }
-
-               recv_tail += consumed;
-               if(recv_tail>=sizeof(recv_buf))
-                       recv_tail -= sizeof(recv_buf);
-               recv_fill -= consumed;
-
-               if(cmd_length>0)
-               {
-                       uint8_t result = process_command();
-                       serial_write(0xFE);
-                       serial_write(result);
-               }
-       }
-}
-
-uint8_t process_command()
-{
-       if(cmd_buf[0]==POWER_ON || cmd_buf[0]==POWER_OFF)
-       {
-               if(cmd_length!=1)
-                       return LENGTH_ERROR;
-
-               if(cmd_buf[0]==POWER_ON)
-                       PORTD |= 0x08;
-               else
-                       PORTD &= ~0x08;
-       }
-       else if(cmd_buf[0]==READ_TRACK_CURRENT)
-       {
-               if(cmd_length!=1)
-                       return LENGTH_ERROR;
-
-               serial_write(0xFC);
-               serial_write(TRACK_CURRENT);
-               uint16_t value = track_current_sum>>4;
-               serial_write(value>>8);
-               serial_write(value);
-       }
-       else if(cmd_buf[0]==SET_OVERCURRENT_LIMIT)
-       {
-               if(cmd_length!=3)
-                       return LENGTH_ERROR;
-
-               if(cmd_buf[1]&0xF0)
-                       return INVALID_VALUE;
-
-               overcurrent_limit = (cmd_buf[1]<<12) | (cmd_buf[2]<<4);
-       }
-       else if(cmd_buf[0]==READ_INPUT_VOLTAGE)
-       {
-               if(cmd_length!=1)
-                       return LENGTH_ERROR;
-
-               serial_write(0xFC);
-               serial_write(INPUT_VOLTAGE);
-               uint16_t value = (input_voltage_sum>>3)*5;
-               serial_write(value>>8);
-               serial_write(value);
-       }
-       else if(cmd_buf[0]==MOTOROLA_SPEED || cmd_buf[0]==MOTOROLA_SPEED_DIRECTION || cmd_buf[0]==MOTOROLA_SPEED_FUNCTION)
-       {
-               if(cmd_length!=4)
-                       return LENGTH_ERROR;
-
-               uint8_t addr = cmd_buf[1];
-               if(addr>80)
-                       return INVALID_VALUE;
-
-               if(cmd_buf[2]&0x0E)
-                       return INVALID_VALUE;
-               uint8_t aux = cmd_buf[2]&0x01;
-
-               uint8_t func = (cmd_buf[2]&0xF0)>>4;
-               if(cmd_buf[0]==MOTOROLA_SPEED_FUNCTION)
-               {
-                       if(func<1 || func>4)
-                               return INVALID_VALUE;
-               }
-               else if(cmd_buf[2]&0xFE)
-                       return INVALID_VALUE;
-               uint8_t state = cmd_buf[2]&0x02;
-
-               uint8_t speed = cmd_buf[3]&0x7F;
-               if(speed>14)
-                       return INVALID_VALUE;
-
-               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)
-                       motorola_locomotive_speed_direction_packet(addr, aux, speed, dir);
-               else if(cmd_buf[0]==MOTOROLA_SPEED_FUNCTION)
-                       motorola_locomotive_speed_function_packet(addr, aux, speed, func, state);
-       }
-       else if(cmd_buf[0]==MOTOROLA_REVERSE)
-       {
-               if(cmd_length!=3)
-                       return LENGTH_ERROR;
-
-               uint8_t addr = cmd_buf[1];
-               if(addr>80)
-                       return INVALID_VALUE;
-
-               if(cmd_buf[2]&0xFE)
-                       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)
-       {
-               if(cmd_length!=3)
-                       return LENGTH_ERROR;
-
-               uint8_t addr = cmd_buf[1];
-               if(addr>80)
-                       return INVALID_VALUE;
-
-               if(cmd_buf[2]&0x8E)
-                       return INVALID_VALUE;
-               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
-               return INVALID_COMMAND;
-
-       return COMMAND_OK;
-}
-
-static inline void tick()
-{
-       if(delay_time && --delay_time)
-               return;
-
-       if(out_time && !--out_time)
-       {
-               ++out_bit;
-               if(out_bit>=packet.length)
-               {
-                       PORTD &= ~0x04;
-                       if(packet.repeat_count>1)
-                       {
-                               if(packet.repeat_count<0xFF)
-                                       --packet.repeat_count;
-                               delay_time = packet.repeat_delay;
-                               packet.sending = 0;
-                       }
-                       else
-                       {
-                               delay_time = packet.final_delay;
-                               packet.done = 1;
-                       }
-               }
-               else
-               {
-                       if((out_bit&7)==0)
-                               out_data = packet.data[out_bit>>3];
-                       else
-                               out_data >>= 1;
-
-                       if(out_data&1)
-                               PORTD |= 0x04;
-                       else
-                               PORTD &= ~0x04;
-
-                       out_time = packet.bit_duration;
-               }
-
-               return;
-       }
-
-       if(packet.ready && !packet.sending)
-       {
-               packet.sending = 1;
-               out_bit = 0;
-               out_time = packet.bit_duration;
-               out_data = packet.data[0];
-               if(out_data&1)
-                       PORTD |= 0x04;
-               else
-                       PORTD &= ~0x04;
-       }
-}
-
-TIMER_SET_CALLBACK(0, tick)
-
-static inline void adc_complete(uint16_t value)
-{
-       if(adc_state==1)
-       {
-               // Convert to milliamps: (v*5/1024-2.5)*1000/0.185
-               if(value<512)  // Ignore negative current readings
-                       value = 0;
-               else if(value>663)  // Limit range so averaging won't overflow
-                       value = 4000;
-               else
-                       value = (value-512)*132/5;
-
-               uint8_t i = track_current_head;
-               track_current_sum -= track_current_samples[i];
-               track_current_samples[i] = value;
-               track_current_sum += value;
-               track_current_head = (i+1)&15;
-       }
-       else if(adc_state==3)
-       {
-               // Convert to centivolts: (v*5/1024)*100*11
-               if(value>744) // Limit range so averaging won't overflow
-                       value = 4000;
-               else
-                       value = value*43/8;
-
-               uint8_t i = input_voltage_head;
-               input_voltage_sum -= input_voltage_samples[i];
-               input_voltage_samples[i] = value;
-               input_voltage_sum += value;
-               input_voltage_head = (i+1)&15;
-       }
-
-       ++adc_state;
-}
-
-ADC_SET_CALLBACK(adc_complete)