From 507e3a235ca5e7e62e105fd46df7186e8559ac98 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Tue, 21 May 2013 13:41:49 +0200 Subject: initial commit --- src/main/scala/com/github/jodersky/flow/Main.scala | 26 +++++++++ .../scala/com/github/jodersky/flow/Serial.scala | 63 ++++++++++++++++++++++ .../com/github/jodersky/flow/exceptions.scala | 7 +++ 3 files changed, 96 insertions(+) create mode 100644 src/main/scala/com/github/jodersky/flow/Main.scala create mode 100644 src/main/scala/com/github/jodersky/flow/Serial.scala create mode 100644 src/main/scala/com/github/jodersky/flow/exceptions.scala (limited to 'src/main/scala') diff --git a/src/main/scala/com/github/jodersky/flow/Main.scala b/src/main/scala/com/github/jodersky/flow/Main.scala new file mode 100644 index 0000000..feea51b --- /dev/null +++ b/src/main/scala/com/github/jodersky/flow/Main.scala @@ -0,0 +1,26 @@ +package com.github.jodersky.flow + +import scala.concurrent._ +import scala.concurrent.ExecutionContext.Implicits.global + +object Main { + + def main(args: Array[String]): Unit = { + println("opening") + + Serial.debug(true) + val s = Serial.open("/dev/ttyACM0", 115200){ data => + println(data.mkString("[",",","]")) + } + println("press enter to write a loooooooooong array of data") + Console.readLine() + + val data: Array[Byte] = Array.fill(1000000)(42) + s.write(data).map(d => println("sent: " + d.mkString("[",",","]"))).recover{case t => println("write error")} + + println("press enter to exit") + Console.readLine() + println("exiting") + Console.flush() + } +} \ No newline at end of file diff --git a/src/main/scala/com/github/jodersky/flow/Serial.scala b/src/main/scala/com/github/jodersky/flow/Serial.scala new file mode 100644 index 0000000..7565cbd --- /dev/null +++ b/src/main/scala/com/github/jodersky/flow/Serial.scala @@ -0,0 +1,63 @@ +package com.github.jodersky.flow + +import scala.concurrent._ +import scala.concurrent.ExecutionContext.Implicits._ +import java.io.IOException + +class Serial private (val port: String, private val pointer: Long, reader: Array[Byte] => Unit) { + future { + var n = 0 + val buffer = new Array[Byte](100) + while (n >= 0) { + n = NativeSerial.read(pointer, buffer) + import NativeSerial._ + n match { + case E_POINTER => throw new NullPointerException("pointer to native serial") + case E_POLL => throw new IOException(port + ": polling") + case E_IO => throw new IOException(port + ": reading") + case E_CLOSE => println("close request") + case x if x > 0 => reader(buffer.take(n)) + } + } + } + + private def writeBlock(data: Array[Byte]) = synchronized { + import NativeSerial._ + NativeSerial.write(pointer, data) match { + case E_POINTER => throw new NullPointerException("pointer to native serial") + case E_IO => throw new IOException(port + ": writing") + case r => data.take(r) + } + } + + def write(data: Array[Byte]) = future { writeBlock(data) } + + def close() = synchronized { + NativeSerial.close(pointer) + } + +} + +object Serial { + + def open(port: String, baud: Int)(reader: Array[Byte] => Unit) = synchronized { + val pointer = new Array[Long](1) + val result = NativeSerial.open(port, baud, pointer) + + import NativeSerial._ + result match { + case E_PERMISSION => throw new AccessDeniedException(port) + case E_OPEN => throw new NoSuchPortException(port) + case E_BUSY => throw new PortInUseException(port) + case E_BAUD => throw new IllegalArgumentException( + s"invalid baudrate ${baud}, use standard unix values") + case E_PIPE => throw new IOException("cannot create pipe") + case E_MALLOC => throw new IOException("cannot allocate memory") + case 0 => new Serial(port, pointer(0), reader) + case _ => throw new Exception("cannot open port") + } + } + + def debug(value: Boolean) = NativeSerial.debug(value) + +} \ No newline at end of file diff --git a/src/main/scala/com/github/jodersky/flow/exceptions.scala b/src/main/scala/com/github/jodersky/flow/exceptions.scala new file mode 100644 index 0000000..a360079 --- /dev/null +++ b/src/main/scala/com/github/jodersky/flow/exceptions.scala @@ -0,0 +1,7 @@ +package com.github.jodersky.flow + +import java.io.IOException + +class NoSuchPortException(message: String) extends IOException(message) +class PortInUseException(message: String) extends IOException(message) +class AccessDeniedException(message: String) extends IOException(message) \ No newline at end of file -- cgit v1.2.3