aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2013-02-27 15:53:33 +0100
committerJakob Odersky <jodersky@gmail.com>2013-02-27 15:53:33 +0100
commit793983ca31eb05fce655ed5877b6f3faa4577acd (patch)
tree94929b35094209df2964cd69068a0b9a270095dd
parent20a2350f9b33a797763413509781d0686fc38fe5 (diff)
downloadace-793983ca31eb05fce655ed5877b6f3faa4577acd.tar.gz
ace-793983ca31eb05fce655ed5877b6f3faa4577acd.tar.bz2
ace-793983ca31eb05fce655ed5877b6f3faa4577acd.zip
restructure scala implementation
-rw-r--r--scala/ace/src/main/scala/com/github/jodersky/ace/protocol/Arq.scala (renamed from scala/ace/src/main/scala/com/github/jodersky/ace/Arq.scala)10
-rw-r--r--scala/ace/src/main/scala/com/github/jodersky/ace/protocol/Framer.scala (renamed from scala/ace/src/main/scala/com/github/jodersky/ace/Framer.scala)16
-rw-r--r--scala/ace/src/main/scala/com/github/jodersky/ace/protocol/ReactiveLayer.scala (renamed from scala/ace/src/main/scala/com/github/jodersky/ace/ReactiveLayer.scala)18
-rw-r--r--scala/ace/src/main/scala/com/github/jodersky/ace/protocol/SimpleActionLayer.scala8
-rw-r--r--scala/ace/src/main/scala/com/github/jodersky/ace/serial/Serial.scala15
-rw-r--r--scala/ace/src/main/scala/com/github/jodersky/ace/serial/SerialProvider.scala7
-rw-r--r--scala/jssc/.gitignore18
-rw-r--r--scala/jssc/build.sbt11
-rw-r--r--scala/jssc/lib/jssc.jarbin0 -> 120277 bytes
-rw-r--r--scala/jssc/src/main/scala/com/github/jodersky/ace/Main.scala30
-rw-r--r--scala/jssc/src/main/scala/com/github/jodersky/ace/jssc/JSSCSerialProvider.scala48
-rw-r--r--scala/jssc/src/main/scala/com/github/jodersky/ace/jssc/package.scala7
12 files changed, 166 insertions, 22 deletions
diff --git a/scala/ace/src/main/scala/com/github/jodersky/ace/Arq.scala b/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/Arq.scala
index 3f8f84d..4a4ed8d 100644
--- a/scala/ace/src/main/scala/com/github/jodersky/ace/Arq.scala
+++ b/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/Arq.scala
@@ -1,4 +1,4 @@
-package com.github.jodersky.ace
+package com.github.jodersky.ace.protocol
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
@@ -19,7 +19,7 @@ class Arq(timeout: Int, maxResends: Int = 5, maxMessageBuffer: Int = 10) extends
// received message sequences
private val receivedSequences = Queue[Int]()
- def receive(frameData: Seq[Int]) = {
+ protected def receive(frameData: Seq[Int]) = {
val sequence = frameData(SequenceOffset)
val command = frameData(CommandOffset)
val message = frameData.drop(MessageOffset)
@@ -33,7 +33,7 @@ class Arq(timeout: Int, maxResends: Int = 5, maxMessageBuffer: Int = 10) extends
}
case Data => {
- writeToLower(ack(sequence))
+ sendToLower(ack(sequence))
if (!(receivedSequences contains sequence)) {
if (receivedSequences.size > maxMessageBuffer) receivedSequences.dequeue
@@ -45,14 +45,14 @@ class Arq(timeout: Int, maxResends: Int = 5, maxMessageBuffer: Int = 10) extends
}
}
- def write(message: Seq[Int]) = {
+ def send(message: Seq[Int]) = {
val promise = Promise[Seq[Int]]
val sequence = nextSequence()
val frameData = Seq(sequence, Data) ++ message
def send(n: Int): Future[Seq[Int]] =
- writeToLower(frameData) map { frameData =>
+ sendToLower(frameData) map { frameData =>
Await.result(promise.future, timeout.milliseconds)
} recoverWith {
case t: TimeoutException if (n < maxResends) => send(n + 1)
diff --git a/scala/ace/src/main/scala/com/github/jodersky/ace/Framer.scala b/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/Framer.scala
index 52496e4..5558db3 100644
--- a/scala/ace/src/main/scala/com/github/jodersky/ace/Framer.scala
+++ b/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/Framer.scala
@@ -1,4 +1,4 @@
-package com.github.jodersky.ace
+package com.github.jodersky.ace.protocol
import scala.collection.mutable.ArrayBuffer
import scala.concurrent.Future
@@ -14,9 +14,9 @@ class Framer extends ReactiveLayer[Seq[Int], Seq[Int]] {
private var state: State = Waiting
private val buffer = new ArrayBuffer[Int]
- def receive(bytes: Seq[Int]) = bytes foreach receive
+ protected def receive(bytes: Seq[Int]) = bytes foreach receive
- def receive(byte: Int): Unit = {
+ protected def receive(byte: Int): Unit = {
state match {
case Escaping => {
@@ -40,7 +40,7 @@ class Framer extends ReactiveLayer[Seq[Int], Seq[Int]] {
}
}
- def write(data: Seq[Int]): Future[Seq[Int]] = {
+ def send(data: Seq[Int]): Future[Seq[Int]] = {
val buffer = new ArrayBuffer[Int]
buffer += Start
@@ -62,7 +62,7 @@ class Framer extends ReactiveLayer[Seq[Int], Seq[Int]] {
case _ => buffer += c
}
buffer += Stop
- writeToLower(buffer) map (_ => data)
+ sendToLower(buffer) map (_ => data)
}
}
@@ -72,9 +72,9 @@ object Framer {
case object Receiving extends State
case object Escaping extends State
- final val Escape = 0x02
- final val Start = 0x03
- final val Stop = 0x10
+ final val Escape = 0x10
+ final val Start = 0x02
+ final val Stop = 0x03
def checksum(unsignedData: Seq[Int]) = {
unsignedData.fold(0)(_ ^ _)
diff --git a/scala/ace/src/main/scala/com/github/jodersky/ace/ReactiveLayer.scala b/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/ReactiveLayer.scala
index 663a4a7..c9531c0 100644
--- a/scala/ace/src/main/scala/com/github/jodersky/ace/ReactiveLayer.scala
+++ b/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/ReactiveLayer.scala
@@ -1,4 +1,4 @@
-package com.github.jodersky.ace
+package com.github.jodersky.ace.protocol
import scala.concurrent.Future
@@ -15,14 +15,14 @@ trait ReactiveLayer[L, T] {
case None => throw new UnsupportedOperationException("Higher layer doesn't exist.")
}
- /** Writes data to a lower layer. */
- protected def writeToLower(l: L): Future[L] = lowerLayer match {
- case Some(lower) => lower.write(l)
+ /** Sends data to a lower layer. */
+ protected def sendToLower(l: L): Future[L] = lowerLayer match {
+ case Some(lower) => lower.send(l)
case None => Future.failed(new UnsupportedOperationException("Lower layer doesn't exist."))
}
/** Connects this layer with a higher layer, effectively linking calls
- * `notifyHigher` to `higher.receive` and `higher.writeToLower` to `write`. */
+ * `notifyHigher` to `higher.receive` and `higher.sendToLower` to `send`. */
def connect[A](higher: ReactiveLayer[T, A]) = {
this.higherLayer = Some(higher)
higher.lowerLayer = Some(this)
@@ -30,9 +30,9 @@ trait ReactiveLayer[L, T] {
}
/** Called from lower layer. */
- def receive(data: L): Unit
+ protected def receive(data: L): Unit
- /** Write data to this layer.
- * @return a future value containing the data written, or an error */
- def write(data: T): Future[T]
+ /** Send data to this layer.
+ * @return a future value containing the data sent, or an error */
+ def send(data: T): Future[T]
} \ No newline at end of file
diff --git a/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/SimpleActionLayer.scala b/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/SimpleActionLayer.scala
new file mode 100644
index 0000000..81e39cb
--- /dev/null
+++ b/scala/ace/src/main/scala/com/github/jodersky/ace/protocol/SimpleActionLayer.scala
@@ -0,0 +1,8 @@
+package com.github.jodersky.ace.protocol
+
+class SimpleActionLayer[A](action: A => Unit) extends ReactiveLayer[A, A] {
+ protected def receive(data: A) = action(data)
+
+ def send(data: A) = sendToLower(data)
+
+} \ No newline at end of file
diff --git a/scala/ace/src/main/scala/com/github/jodersky/ace/serial/Serial.scala b/scala/ace/src/main/scala/com/github/jodersky/ace/serial/Serial.scala
new file mode 100644
index 0000000..b688ec8
--- /dev/null
+++ b/scala/ace/src/main/scala/com/github/jodersky/ace/serial/Serial.scala
@@ -0,0 +1,15 @@
+package com.github.jodersky.ace.serial
+
+import com.github.jodersky.ace.protocol.ReactiveLayer
+
+trait Serial extends ReactiveLayer[Nothing, Seq[Int]] {
+ protected def receive(nothing: Nothing) = throw new UnsupportedOperationException("A receive function cannot be called on the lowest layer.")
+
+ def begin(): Unit
+ def close(): Unit
+
+}
+
+object Serial {
+ def open(port: String, baudRate: Int)(implicit provider: SerialProvider) = provider.open(port, baudRate)
+} \ No newline at end of file
diff --git a/scala/ace/src/main/scala/com/github/jodersky/ace/serial/SerialProvider.scala b/scala/ace/src/main/scala/com/github/jodersky/ace/serial/SerialProvider.scala
new file mode 100644
index 0000000..9c7b95c
--- /dev/null
+++ b/scala/ace/src/main/scala/com/github/jodersky/ace/serial/SerialProvider.scala
@@ -0,0 +1,7 @@
+package com.github.jodersky.ace.serial
+
+trait SerialProvider {
+
+ def open(port: String, baudRate: Int): Serial
+
+} \ No newline at end of file
diff --git a/scala/jssc/.gitignore b/scala/jssc/.gitignore
new file mode 100644
index 0000000..94730a8
--- /dev/null
+++ b/scala/jssc/.gitignore
@@ -0,0 +1,18 @@
+*.class
+*.log
+
+# sbt specific
+dist/*
+target/
+.target/
+lib_managed/
+src_managed/
+project/boot/
+project/plugins/project/
+
+# Scala-IDE specific
+.scala_dependencies
+.project
+.classpath
+.cache
+.settings/
diff --git a/scala/jssc/build.sbt b/scala/jssc/build.sbt
new file mode 100644
index 0000000..8757f1c
--- /dev/null
+++ b/scala/jssc/build.sbt
@@ -0,0 +1,11 @@
+name := "ace-jssc"
+
+organization := "com.github.jodersky"
+
+version := "1.0-SNAPSHOT"
+
+scalaVersion := "2.10.0"
+
+scalacOptions ++= Seq("-deprecation","-feature")
+
+libraryDependencies += "com.github.jodersky" %% "ace" % "1.0-SNAPSHOT"
diff --git a/scala/jssc/lib/jssc.jar b/scala/jssc/lib/jssc.jar
new file mode 100644
index 0000000..b0d6a82
--- /dev/null
+++ b/scala/jssc/lib/jssc.jar
Binary files differ
diff --git a/scala/jssc/src/main/scala/com/github/jodersky/ace/Main.scala b/scala/jssc/src/main/scala/com/github/jodersky/ace/Main.scala
new file mode 100644
index 0000000..55c23b9
--- /dev/null
+++ b/scala/jssc/src/main/scala/com/github/jodersky/ace/Main.scala
@@ -0,0 +1,30 @@
+package com.github.jodersky.ace
+
+import com.github.jodersky.ace.protocol._
+
+import scala.concurrent.ExecutionContext.Implicits.global
+
+object Main {
+
+ def main(args: Array[String]): Unit = {
+ import com.github.jodersky.ace.jssc._
+
+ val s = serial.Serial.open("/dev/ttyACM0", 9600)
+ val framer = new Framer
+ val arq = new Arq(200)
+ val app = new SimpleActionLayer((s: Seq[Int]) => println(s))
+
+ s connect framer connect arq connect app
+ s.begin()
+
+ while (true) {
+ app.send(Console.readLine.getBytes().map(_.toInt)).map(sent => Console.println("> " + sent))
+
+ }
+
+
+ ()
+ }
+
+
+} \ No newline at end of file
diff --git a/scala/jssc/src/main/scala/com/github/jodersky/ace/jssc/JSSCSerialProvider.scala b/scala/jssc/src/main/scala/com/github/jodersky/ace/jssc/JSSCSerialProvider.scala
new file mode 100644
index 0000000..3bfd650
--- /dev/null
+++ b/scala/jssc/src/main/scala/com/github/jodersky/ace/jssc/JSSCSerialProvider.scala
@@ -0,0 +1,48 @@
+package com.github.jodersky.ace.jssc
+
+import scala.concurrent._
+import scala.concurrent.ExecutionContext.Implicits.global
+import com.github.jodersky.ace.serial._
+import com.github.jodersky.ace.serial.Serial
+import jssc.SerialPortEvent
+import jssc.SerialPort
+import jssc.SerialPortEventListener
+import java.io.IOException
+
+object JSSCSerialProvider extends SerialProvider {
+
+ def open(port: String, baudRate: Int) = new Serial {
+ val serialPort = new SerialPort(port);
+ serialPort.openPort()
+ serialPort.setParams(
+ baudRate,
+ SerialPort.DATABITS_8,
+ SerialPort.STOPBITS_1,
+ SerialPort.PARITY_NONE)
+
+ val listener = new SerialPortEventListener {
+ override def serialEvent(event: SerialPortEvent) = {
+ if (event.isRXCHAR()) {
+ val bytes = serialPort.readBytes
+ if (bytes != null) notifyHigher(bytes.map(_ & 0xff))
+ }
+ }
+ }
+
+ def send(data: Seq[Int]) = future {
+ serialPort.writeBytes(data.toArray.map(_.toByte))
+ } map { success =>
+ if (success) data
+ else throw new IOException("Could not write to serial port.")
+ }
+
+ def close() = serialPort.closePort()
+
+ def begin() = {
+ val mask = SerialPort.MASK_RXCHAR + SerialPort.MASK_CTS + SerialPort.MASK_DSR
+ serialPort.setEventsMask(mask)
+ serialPort.addEventListener(listener)
+ }
+ }
+
+} \ No newline at end of file
diff --git a/scala/jssc/src/main/scala/com/github/jodersky/ace/jssc/package.scala b/scala/jssc/src/main/scala/com/github/jodersky/ace/jssc/package.scala
new file mode 100644
index 0000000..891e588
--- /dev/null
+++ b/scala/jssc/src/main/scala/com/github/jodersky/ace/jssc/package.scala
@@ -0,0 +1,7 @@
+package com.github.jodersky.ace
+
+package object jssc {
+
+ implicit val provider = JSSCSerialProvider
+
+} \ No newline at end of file