summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/Makefile9
-rw-r--r--client/enginecontroller.vala237
-rw-r--r--client/main.vala58
3 files changed, 304 insertions, 0 deletions
diff --git a/client/Makefile b/client/Makefile
new file mode 100644
index 0000000..d274276
--- /dev/null
+++ b/client/Makefile
@@ -0,0 +1,9 @@
+all: engine
+
+engine: enginecontroller.vala main.vala
+ valac -o $@ --pkg posix --pkg linux $^
+
+clean:
+ rm -f engine
+
+.PHONY: all clean
diff --git a/client/enginecontroller.vala b/client/enginecontroller.vala
new file mode 100644
index 0000000..23bd572
--- /dev/null
+++ b/client/enginecontroller.vala
@@ -0,0 +1,237 @@
+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;
+ }
+}
diff --git a/client/main.vala b/client/main.vala
new file mode 100644
index 0000000..2c676a5
--- /dev/null
+++ b/client/main.vala
@@ -0,0 +1,58 @@
+public static void main(string[] args) {
+ var engines = new EngineController("/dev/ttyAMA0");
+
+ if(args.length < 2) {
+ stderr.printf("%s <cmd>\n", args[0]);
+ stderr.printf("cmds: engine, enable, disable, nop\n");
+ return;
+ }
+
+ switch(args[1]) {
+ case "engine":
+ if(args.length < 4) {
+ stderr.printf("%s engine <engine> <speed>\n", args[0]);
+ return;
+ }
+
+ uint8 engine = (uint8) int.parse(args[2]);
+ if("%u".printf(engine) != args[2])
+ error("engine must be an integer");
+
+ uint8 speed = (uint8) int.parse(args[3]);
+ if("%u".printf(speed) != args[3])
+ error("speed must be an integer");
+
+ if(engine == 6)
+ if(engines.set_speed_all(speed))
+ stdout.printf("set speed of all engines to %u: ok\n", speed);
+ else
+ stdout.printf("set speed of all engines to %u: fail\n", speed);
+ if(engine <= 5)
+ if(engines.set_speed(engine, speed))
+ stdout.printf("set speed of engine %u to %u: ok\n", engine, speed);
+ else
+ stdout.printf("set speed of engine %u to %u: fail\n", engine, speed);
+ break;
+ case "enable":
+ if(engines.enable())
+ stdout.printf("enable motors: ok\n");
+ else
+ stdout.printf("enable motors: fail\n");
+ break;
+ case "disable":
+ if(engines.disable())
+ stdout.printf("disable motors: ok\n");
+ else
+ stdout.printf("disable motors: fail\n");
+ break;
+ case "nop":
+ if(engines.no_operation())
+ stdout.printf("no operation: ok\n");
+ else
+ stdout.printf("no operation: fail\n");
+ break;
+ default:
+ stderr.printf("cmd not supported!\n");
+ break;
+ }
+}