Commit 22ff84d6 authored by Marcus Greiff's avatar Marcus Greiff

Include PWM manipulation

TODO: Write better tests (currently just experiments)
TODO: Test a combinatino of universaln and universala
TODO: Test after merge..
parent 3b2febb3
......@@ -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)
......
# 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
"""
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
"""
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
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)
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)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment