public class EngineController { private Posix.termios newtio; private Posix.termios restoretio; private int fd=-1; private int byterate; private void setup(string device, int rate, int bits, int stopbits) { Posix.speed_t baudrate = Posix.B9600; fd = Posix.open(device, Posix.O_RDWR /*| Posix.O_NONBLOCK*/); if(fd < 0) { fd = -1; stderr.printf("Could not open device!\n"); return; } Posix.tcflush(fd, Posix.TCIOFLUSH); Posix.tcgetattr(fd, out restoretio); /* apply settings */ switch(rate) { case 300: baudrate = Posix.B300; break; case 600: baudrate = Posix.B600; break; case 1200: baudrate = Posix.B1200; break; case 2400: baudrate = Posix.B2400; break; case 4800: baudrate = Posix.B4800; break; case 9600: baudrate = Posix.B9600; break; case 19200: baudrate = Posix.B19200; break; case 38400: baudrate = Posix.B38400; break; case 57600: baudrate = Posix.B57600; break; case 115200: baudrate = Posix.B115200; break; case 230400: baudrate = Posix.B230400; break; default: /* not supported */ rate = 9600; break; } Posix.cfsetospeed(ref newtio, baudrate); Posix.cfsetispeed(ref newtio, baudrate); switch(bits) { case 5: newtio.c_cflag = (newtio.c_cflag & ~Posix.CSIZE) | Posix.CS5; break; case 6: newtio.c_cflag = (newtio.c_cflag & ~Posix.CSIZE) | Posix.CS6; break; case 7: newtio.c_cflag = (newtio.c_cflag & ~Posix.CSIZE) | Posix.CS7; break; case 8: default: newtio.c_cflag = (newtio.c_cflag & ~Posix.CSIZE) | Posix.CS8; break; } newtio.c_cflag |= Posix.CLOCAL | Posix.CREAD; newtio.c_cflag &= ~(Posix.PARENB | Posix.PARODD); /* TODO: parity */ newtio.c_cflag &= ~Linux.Termios.CRTSCTS; if(stopbits == 2) newtio.c_cflag |= Posix.CSTOPB; else newtio.c_cflag &= ~Posix.CSTOPB; newtio.c_iflag = Posix.IGNBRK; newtio.c_lflag = 0; newtio.c_oflag = 0; newtio.c_cc[Posix.VTIME]=1; newtio.c_cc[Posix.VMIN]=1; newtio.c_lflag &= ~(Posix.ECHONL|Posix.NOFLSH); int mcs=0; Posix.ioctl(fd, Linux.Termios.TIOCMGET, out mcs); mcs |= Linux.Termios.TIOCM_RTS; Posix.ioctl(fd, Linux.Termios.TIOCMSET, out mcs); Posix.tcsetattr(fd, Posix.TCSANOW, newtio); this.byterate = rate/bits; } public EngineController(string device) { setup(device, 9600, 8, 1); } private ssize_t read(void *buf, size_t count) { if(fd >= 0) return Posix.read(fd, buf, count); else stderr.printf("not connected!\n"); return 0; } private ssize_t write(void *buf, size_t count) { if(fd >= 0) { ssize_t size = Posix.write(fd, buf, count); return size; } else { stderr.printf("not connected!\n"); return 0; } } public bool disable() { uint8[4] buf = new uint8[4]; buf[0] = 0xDE; buf[1] = 0xAD; buf[2] = 0xBA; buf[3] = 0xBE; if(fd < 0) { stderr.printf("not connected!\n"); return false; } write(buf, 4); read(buf, 1); if(buf[0] == '.') return true; else return false; } public bool enable() { uint8[4] buf = new uint8[4]; buf[0] = 0xCA; buf[1] = 0xFE; buf[2] = 0xBA; buf[3] = 0xBE; if(fd < 0) { stderr.printf("not connected!\n"); return false; } write(buf, 4); read(buf, 1); if(buf[0] == '.') return true; else return false; } public bool no_operation() { uint8[1] buf = new uint8[1]; buf[0] = 0x00; if(fd < 0) { stderr.printf("not connected!\n"); return false; } write(buf, 1); read(buf, 1); if(buf[0] == '.') return true; else return false; } public bool set_speed(uint8 engine, uint8 speed) { uint8[2] buf = new uint8[2]; buf[0] = engine+1; buf[1] = speed; if(fd < 0) { stderr.printf("not connected!\n"); return false; } if(engine > 5) return false; write(buf, 2); read(buf, 2); if(buf[0] == '.') return true; else return false; } public bool set_speed_all(uint8 speed) { uint8[2] buf = new uint8[2]; buf[0] = 0xFF; buf[1] = speed; if(fd < 0) { stderr.printf("not connected!\n"); return false; } write(buf, 2); read(buf, 2); if(buf[0] == '.') return true; else return false; } }