From 22ff84d6b0d7a0c8021dc5dfa38406765d63f35b Mon Sep 17 00:00:00 2001 From: mgreiff <marcusgreiff.93@hotmail.com> Date: Fri, 25 Aug 2017 03:02:11 +0200 Subject: [PATCH] Include PWM manipulation TODO: Write better tests (currently just experiments) TODO: Test a combinatino of universaln and universala TODO: Test after merge.. --- src/BeagleBone/BeagleBone.jl | 3 +- src/BeagleBone/BeagleBone.jl~ | 86 +++++++++++++++++++++++++++++++++ src/BeagleBone/PWM.jl | 91 +++++++++++++++++++++++++++++++++++ src/BeagleBone/PWM.jl~ | 91 +++++++++++++++++++++++++++++++++++ test/BeagleBone/PWM_test.jl | 40 +++++++++++++++ test/BeagleBone/PWM_test.jl~ | 40 +++++++++++++++ 6 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 src/BeagleBone/BeagleBone.jl~ create mode 100644 src/BeagleBone/PWM.jl create mode 100644 src/BeagleBone/PWM.jl~ create mode 100644 test/BeagleBone/PWM_test.jl create mode 100644 test/BeagleBone/PWM_test.jl~ diff --git a/src/BeagleBone/BeagleBone.jl b/src/BeagleBone/BeagleBone.jl index 934bf47..0799a05 100644 --- a/src/BeagleBone/BeagleBone.jl +++ b/src/BeagleBone/BeagleBone.jl @@ -5,9 +5,10 @@ include("Debug.jl") include("SysLED.jl") include("GPIO.jl") +include("PWM.jl") #List of available devices and their constructors -const DEVICES = Dict("debug" => Debug(), "sysled" => SysLED(), "gpio" => GPIO()) +const DEVICES = Dict("debug" => Debug(), "sysled" => SysLED(), "gpio" => GPIO(), "pwm" => PWM()) """ dev = getdev(devname) diff --git a/src/BeagleBone/BeagleBone.jl~ b/src/BeagleBone/BeagleBone.jl~ new file mode 100644 index 0000000..934bf47 --- /dev/null +++ b/src/BeagleBone/BeagleBone.jl~ @@ -0,0 +1,86 @@ +# Devices should define a type `T` with methods: +# write!(::T, identifier, val) +# read(::T, identifier) + +include("Debug.jl") +include("SysLED.jl") +include("GPIO.jl") + +#List of available devices and their constructors +const DEVICES = Dict("debug" => Debug(), "sysled" => SysLED(), "gpio" => GPIO()) + +""" + dev = getdev(devname) + Gets the device corresponding to the name `devname` +""" +function getdev(devname) + dev = try + DEVICES[devname] + catch + error("Device $devname does not exist") + end + return dev +end + +""" + bbparse(cmd) +Parse and execute the command `cmd` +""" +bbparse(any) = error("Unexpected input: $any") + +""" + bbparse(l::Tuple) +Parse input on the form `l=(iswrite, ndev, cmd1, cmd2, ..., cmdn)`` +where if `iswrite` + `cmdi = (devname, id, val)` + and if not `iswrite` + `cmdi = (devname, id)` +""" +function bbparse(l::Tuple) + iswrite = l[1]::Bool #True if write command, false if read + ndev = l[2]::Int32 #Number of devices/commands + for i = 1:ndev + command = l[2+i]::Tuple + dev = getdev(command[1]) + if iswrite + write!(dev, command[2], command[3]) + else + val = read(dev, command[2]) + println("$val") + #TODO return somewhere + end + end +end + +""" + run_server(port=2001) +Run a server on `port` that listens for commands from computer +""" +function run_server(port=2001) + server = listen(port) + @async while isopen(server) + try + sock = accept(server) + @async while isopen(sock) + try + l = deserialize(sock); + println("deserialize: $l") + bbparse(l) + catch err + if !isopen(sock) && isa(err, Base.EOFError) + println("Connection to server closed") + else + throw(err) + end + end + end + catch err + if isa(err,Base.UVError) && err.prefix == "accept" + println("Server closed successfully") + else + throw(err) + end + end + end + return server +end diff --git a/src/BeagleBone/PWM.jl b/src/BeagleBone/PWM.jl new file mode 100644 index 0000000..54a0bdc --- /dev/null +++ b/src/BeagleBone/PWM.jl @@ -0,0 +1,91 @@ +""" +This script allows for low level PWM control of selected pins +The valid pins dictionary relates to memory adresses in of the +AM3359 chip, see p.182 in + + www.ti.com/product/AM3359/technicaldocuments +""" + +struct PWM +end + +# These pins are exported with the Device Tree Overlay cape-universaln (default) +validPins = Dict( + "P9.22" => ("PWM0A", "pwmchip0", "0"), + "P9.21" => ("PWM0B", "pwmchip0", "1"), + "P9.14" => ("PWM1A", "pwmchip2", "0"), + "P9.16" => ("PWM1B", "pwmchip2", "1"), + "P8.19" => ("PWM2A", "pwmchip4", "0"), + "P8.13" => ("PWM2B", "pwmchip4", "1"), +) + +# These pins are exported with the Device Tree Overlay cape-universala +# "P8.36" => ("PWM1A", "pwmchip1", "0"), +# "P9.29" => ("PWM0B", "pwmchip0", "1"), +# "P8.46" => ("PWM2B", "pwmchip2", "1") +# "P8.45" => ("PWM2A", "pwmchip2", "0"), +# "P8.34" => ("PWM1B", "pwmchip1", "1"), +# "P9.31" => ("PWM0A", "pwmchip0", "0"), + +function setup(::PWM, pin::String) + if pin in keys(validPins) + + # Configure the pin to run PWM if possible + Base.run(`config-pin $(pin) pwm`) + + # Find chip and export number + chip = validPins[pin][2] + filename = "/sys/class/pwm/$(chip)/export" + exportNumber = validPins[pin][3] + + # Export the filestructure of the corresponding chip + write(filename, exportNumber) + else + error("The pin write $(pin) does not support PWM") + end + return +end + +function teardown(::PWM, pin::String) + if pin in keys(validPins) + # Find chip and export number + chip = validPins[pin][2] + filename = "/sys/class/pwm/$(chip)/unexport" + exportNumber = validPins[pin][3] + + # Export the filestructure of the corresponding chip + write(filename, exportNumber) + else + error("The pin write $(pin) does not support PWM") + end + return +end + +function write!(::PWM, pin::String, operation::Int32, entry::String) + !(pin in keys(validPins)) && error("Invalid PWM pin: $(pin))") + (operation <= 0 || operation > 4) && error("Invalid GPIO operation: $operation") + + # TODO: Error checks + if operation == 1 + directory = "enable" + + end + if operation == 2 + directory = "period" + + end + if operation == 3 + directory = "duty_cycle" + + end + if operation == 4 + directory = "polarity" + + end + + filename = "/sys/class/pwm/$(validPins[pin][2])/pwm$(validPins[pin][3])/$(directory)" + file = open(filename, "r+") + write(file, "$(entry)") + close(file) + return +end diff --git a/src/BeagleBone/PWM.jl~ b/src/BeagleBone/PWM.jl~ new file mode 100644 index 0000000..54a0bdc --- /dev/null +++ b/src/BeagleBone/PWM.jl~ @@ -0,0 +1,91 @@ +""" +This script allows for low level PWM control of selected pins +The valid pins dictionary relates to memory adresses in of the +AM3359 chip, see p.182 in + + www.ti.com/product/AM3359/technicaldocuments +""" + +struct PWM +end + +# These pins are exported with the Device Tree Overlay cape-universaln (default) +validPins = Dict( + "P9.22" => ("PWM0A", "pwmchip0", "0"), + "P9.21" => ("PWM0B", "pwmchip0", "1"), + "P9.14" => ("PWM1A", "pwmchip2", "0"), + "P9.16" => ("PWM1B", "pwmchip2", "1"), + "P8.19" => ("PWM2A", "pwmchip4", "0"), + "P8.13" => ("PWM2B", "pwmchip4", "1"), +) + +# These pins are exported with the Device Tree Overlay cape-universala +# "P8.36" => ("PWM1A", "pwmchip1", "0"), +# "P9.29" => ("PWM0B", "pwmchip0", "1"), +# "P8.46" => ("PWM2B", "pwmchip2", "1") +# "P8.45" => ("PWM2A", "pwmchip2", "0"), +# "P8.34" => ("PWM1B", "pwmchip1", "1"), +# "P9.31" => ("PWM0A", "pwmchip0", "0"), + +function setup(::PWM, pin::String) + if pin in keys(validPins) + + # Configure the pin to run PWM if possible + Base.run(`config-pin $(pin) pwm`) + + # Find chip and export number + chip = validPins[pin][2] + filename = "/sys/class/pwm/$(chip)/export" + exportNumber = validPins[pin][3] + + # Export the filestructure of the corresponding chip + write(filename, exportNumber) + else + error("The pin write $(pin) does not support PWM") + end + return +end + +function teardown(::PWM, pin::String) + if pin in keys(validPins) + # Find chip and export number + chip = validPins[pin][2] + filename = "/sys/class/pwm/$(chip)/unexport" + exportNumber = validPins[pin][3] + + # Export the filestructure of the corresponding chip + write(filename, exportNumber) + else + error("The pin write $(pin) does not support PWM") + end + return +end + +function write!(::PWM, pin::String, operation::Int32, entry::String) + !(pin in keys(validPins)) && error("Invalid PWM pin: $(pin))") + (operation <= 0 || operation > 4) && error("Invalid GPIO operation: $operation") + + # TODO: Error checks + if operation == 1 + directory = "enable" + + end + if operation == 2 + directory = "period" + + end + if operation == 3 + directory = "duty_cycle" + + end + if operation == 4 + directory = "polarity" + + end + + filename = "/sys/class/pwm/$(validPins[pin][2])/pwm$(validPins[pin][3])/$(directory)" + file = open(filename, "r+") + write(file, "$(entry)") + close(file) + return +end diff --git a/test/BeagleBone/PWM_test.jl b/test/BeagleBone/PWM_test.jl new file mode 100644 index 0000000..2f9a2b1 --- /dev/null +++ b/test/BeagleBone/PWM_test.jl @@ -0,0 +1,40 @@ +include("../../src/LabConnection.jl") +using LabConnection.BeagleBone +import LabConnection.BeagleBone: getdev, write!, setup, teardown + +pins = Dict( + "P9.22" => ("PWM0A", "pwmchip0", "0"), + "P9.21" => ("PWM0B", "pwmchip0", "1"), + "P9.14" => ("PWM1A", "pwmchip0", "0"), + "P9.16" => ("PWM1B", "pwmchip0", "1"), + "P8.19" => ("PWM2A", "pwmchip0", "0"), + "P8.13" => ("PWM2B", "pwmchip0", "1"), +) + +dev = getdev("pwm") + +println("Running first experiment on selected pins...") +for pin in keys(pins) + println("Testing pin $(pin)") + setup(dev, pin) + write!(dev, pin, 2, "100000000") + write!(dev, pin, 3, "50000000") + write!(dev, pin, 1, "1") + sleep(1) + write!(dev, pin, 1, "0") + teardown(dev, pin) +end + + +println("Running second experiment on pin $(pin)...") +pin = "P9.22" +setup(dev, pin) +write!(dev, pin, 2, "1000000000") +write!(dev, pin, 3, "250000000") +write!(dev, pin, 1, "1") +sleep(5.0) +write!(dev, pin, 3, "500000000") +sleep(5.0) +write!(dev, pin, 3, "750000000") +write!(dev, pin, 1, "0") +teardown(dev, pin) diff --git a/test/BeagleBone/PWM_test.jl~ b/test/BeagleBone/PWM_test.jl~ new file mode 100644 index 0000000..2f9a2b1 --- /dev/null +++ b/test/BeagleBone/PWM_test.jl~ @@ -0,0 +1,40 @@ +include("../../src/LabConnection.jl") +using LabConnection.BeagleBone +import LabConnection.BeagleBone: getdev, write!, setup, teardown + +pins = Dict( + "P9.22" => ("PWM0A", "pwmchip0", "0"), + "P9.21" => ("PWM0B", "pwmchip0", "1"), + "P9.14" => ("PWM1A", "pwmchip0", "0"), + "P9.16" => ("PWM1B", "pwmchip0", "1"), + "P8.19" => ("PWM2A", "pwmchip0", "0"), + "P8.13" => ("PWM2B", "pwmchip0", "1"), +) + +dev = getdev("pwm") + +println("Running first experiment on selected pins...") +for pin in keys(pins) + println("Testing pin $(pin)") + setup(dev, pin) + write!(dev, pin, 2, "100000000") + write!(dev, pin, 3, "50000000") + write!(dev, pin, 1, "1") + sleep(1) + write!(dev, pin, 1, "0") + teardown(dev, pin) +end + + +println("Running second experiment on pin $(pin)...") +pin = "P9.22" +setup(dev, pin) +write!(dev, pin, 2, "1000000000") +write!(dev, pin, 3, "250000000") +write!(dev, pin, 1, "1") +sleep(5.0) +write!(dev, pin, 3, "500000000") +sleep(5.0) +write!(dev, pin, 3, "750000000") +write!(dev, pin, 1, "0") +teardown(dev, pin) -- GitLab