From 1a358bbf883e896f659023cc76ae23f1f6216bb6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?=
 <marcus.thelander_andren@control.lth.se>
Date: Fri, 25 Aug 2017 15:36:43 +0200
Subject: [PATCH] Added read method, tests and String-arguments to GPIO

---
 src/BeagleBone/GPIO.jl       | 55 +++++++++++++++++++++++-------------
 src/BeagleBone/precompile.jl |  2 +-
 test/BeagleBone/GPIO_test.jl | 27 ++++++++++--------
 3 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/src/BeagleBone/GPIO.jl b/src/BeagleBone/GPIO.jl
index 4670fc1..57e8020 100644
--- a/src/BeagleBone/GPIO.jl
+++ b/src/BeagleBone/GPIO.jl
@@ -1,25 +1,32 @@
 """
-Lowest form of communication woth the GPIO pins. The available pins are
+Lowest form of communication with the GPIO pins. The available pins are
 listed in the "channel" parameter, and appear as directories in /sys/class.
+
 Any of these GPIOs can be run in various ways, with any operation specified
 by a sequence of three entries
 
-  (channel, operation, entry) = (int32, int32, String)
+  (channel, (operation, entry)) = (int32, (String, String))
 
 For instance, if the GPIO "gpio30" is to be configured as a output pin and set
-to high, the following two writes aould be done.
+to high, the following two writes would be done.
+
+  write!(GPIO, 14, ("direction", "out"))
+  write!(GPIO, 14, ("value", "1"))
+
+The operation of reading the current cofiguration of the GPIO is specified by
 
-  write!(GPIO, 14, 2, "out")
-  write!(GPIO, 14, 1, "1")
+  (channel, operation) = (int32, String)
+
+For instance, to read the current value of the GPIO "gpio30" the following read
+would be done
+
+  read(GPIO, 14, "value")
 
 """
 struct GPIO
 end
 
-writeOperations = [
-    Dict("dir" => "value",     "entries"=>["1", "0"])
-    Dict("dir" => "direction", "entries"=>["in", "out"])
-]
+writeOperations = Dict("value" => ["1", "0"], "direction" => ["in", "out"])
 
 readOperations = [
     "value"
@@ -63,14 +70,14 @@ channels =[
     "gpio7"
 ]
 
-function write!(::GPIO, index::Int32, args::Tuple{Int32,String}, debug::Bool=false)
+function write!(::GPIO, index::Int32, args::Tuple{String,String}, debug::Bool=false)
     debug && return
     operation, entry = args[1], args[2]
     (index <= 0 || index > length(channels)) && error("Invalid GPIO index: $index")
-    (operation <= 0 || operation > length(writeOperations)) && error("Invalid GPIO operation: $operation")
-    filename = "/sys/class/gpio/$(channels[index])/$(writeOperations[operation]["dir"])"
+    !haskey(writeOperations,operation) && error("Invalid GPIO operation: $operation")
+    filename = "/sys/class/gpio/$(channels[index])/$operation"
 
-    if entry in writeOperations[operation]["entries"]
+    if entry in writeOperations[operation]
         file = open(filename, "r+")
         write(file, "$(entry)")
         close(file)
@@ -80,10 +87,18 @@ function write!(::GPIO, index::Int32, args::Tuple{Int32,String}, debug::Bool=fal
     return
 end
 
-#function Base.read(::SysLED, ind::Int32, debug::Bool=false)
-#    debug && return
-#    (ind < 0 || ind > length(channels)) && error("Invalid SysLEND ind: $ind")
-#    println("not yet supported")
-#    l = 0
-#    return l == "1"
-#end
+function read(::GPIO, index::Int32, operation::String, debug::Bool=false)
+    debug && return
+    (index <= 0 || index > length(channels)) && error("Invalid GPIO index: $index")
+
+    if operation in readOperations
+      filename = "/sys/class/gpio/$(channels[index])/$operation"
+      file = open(filename, "r")
+      l = readline(file)
+      close(file)
+      l ∉ readOperations[operation] && error("Invalid entry read : $l")
+      return l
+    else
+      error("Cannot read from: $operation")
+    end
+end
diff --git a/src/BeagleBone/precompile.jl b/src/BeagleBone/precompile.jl
index 9b7de32..eb9b76e 100644
--- a/src/BeagleBone/precompile.jl
+++ b/src/BeagleBone/precompile.jl
@@ -25,7 +25,7 @@ function precompile_bb()
 
     # Precompile GPIO
     gpio = GPIO()
-    write!(gpio, Int32(1), (Int32(2), "1"), debug)
+    write!(gpio, Int32(1), ("value", "1"), debug)
     #read(gpio, ind, args, debug)
 
     try getdev("nonexistent")       catch end
diff --git a/test/BeagleBone/GPIO_test.jl b/test/BeagleBone/GPIO_test.jl
index bd3fabd..fff3f10 100644
--- a/test/BeagleBone/GPIO_test.jl
+++ b/test/BeagleBone/GPIO_test.jl
@@ -7,7 +7,7 @@ using Base.Test
 #Fixture
 device = getdev("gpio")
 gpio_state = true
-write!(device, 31, (2, "out"))
+write!(device, 1, ("direction", "out"))
 
 device = getdev("gpio")
 
@@ -16,26 +16,29 @@ device = getdev("gpio")
         # Attempt to initialize faulty device
         @test_throws ErrorException  getdev("wrong_device_name")
 
-        # Test that an exception is thrown when a faulty channel is given
-        @test_throws ErrorException write!(device, 100, (1, "0"))
+        # Test that an exception is thrown when a too high pin-index is given
+        @test_throws ErrorException write!(device, Int32(100), ("value", "0"))
+        @test_throws ErrorException read(device, Int32(100),"value")
 
-        # Test that an exception is thrown when a faulty channel is given
-        @test_throws ErrorException write!(device, 0, (1, "1"))
+        # Test that an exception is thrown when a too low pin-index is given
+        @test_throws ErrorException write!(device, Int32(0), ("value", "1"))
+        @test_throws ErrorException read(device, Int32(0), "value")
 
-        # Test that an exepition is thrown when requiring bad entry
-        @test_throws ErrorException write!(device, 0, (123, "0"))
+        # Test that an exception is thrown when requesting a bad operation
+        @test_throws ErrorException write!(device, Int32(1), ("bad_operation", "0"))
+        @test_throws ErrorException read(device, Int32(1),"bad_operation")
 
-        # Test that an exepition is thrown when requiring bad entry
-        @test_throws ErrorException write!(device, 0, (1, "bad_entry"))
+        # Test that an exception is thrown when writing a bad entry
+        @test_throws ErrorException write!(device, Int32(1), ("value", "bad_entry"))
     end
     @testset "IO Communication" begin
         # Instanciate all possible leds and perform 10 read/write commands
-        # with the set high/low operation (1)
-        operation = 1
+        # with the set high/low operation ("value")
+        operation = "value"
         for i = 1:10
             state = "$(i%2)"
             for index = 1:length(channels)
-                write!(device, index, (operation, state))
+                write!(device, Int32(index), (operation, state))
             end
             sleep(0.1)
         end
-- 
GitLab