Commit b0ae82ab authored by Marcus Greiff's avatar Marcus Greiff

Added PWM tests

parent b8734a6c
...@@ -48,7 +48,7 @@ const gpio_channels =[ ...@@ -48,7 +48,7 @@ const gpio_channels =[
] ]
# These pins are exported with the Device Tree Overlay cape-universaln (default) # These pins are exported with the Device Tree Overlay cape-universaln (default)
const validPins = Dict( const pwm_pins = Dict(
"P9.22" => ("PWM0A", "pwmchip0", "0"), "P9.22" => ("PWM0A", "pwmchip0", "0"),
"P9.21" => ("PWM0B", "pwmchip0", "1"), "P9.21" => ("PWM0B", "pwmchip0", "1"),
"P9.14" => ("PWM1A", "pwmchip2", "0"), "P9.14" => ("PWM1A", "pwmchip2", "0"),
......
...@@ -10,29 +10,25 @@ type PWM <: IO_Object ...@@ -10,29 +10,25 @@ type PWM <: IO_Object
i::Int32 i::Int32
pin::String pin::String
chip::String chip::String
basedir::String
filestreams::Array{IOStream,1} filestreams::Array{IOStream,1}
function PWM(i::Int32) function PWM(i::Int32)
pins = collect(keys(validPins))
(i < 1 || i > length(pins)) && error("Invalid PWM index: $i")
pin = pins[i]
# Configure the pin to run PWM if possible
Base.run(`config-pin $(pin) pwm`)
# Find chip and export number (i < 1 || i > length(pwm_pins)) && error("Invalid PWM index: $i")
chip = validPins[pin][2]
filename = "/sys/class/pwm/$(chip)/export"
exportNumber = validPins[pin][3]
# Export the filestructure of the corresponding chip # Export the PWM pin
write(filename, exportNumber) basedir = export_pwm(i)
# Setup filestreams # Setup filestreams
enable_filestream = open("/sys/class/pwm/$(validPins[pin][2])/pwm$(validPins[pin][3])/enable","r+") pins = collect(keys(pwm_pins))
period_filestream = open("/sys/class/pwm/$(validPins[pin][2])/pwm$(validPins[pin][3])/period","r+") pin = pins[i]
duty_cycle_filestream = open("/sys/class/pwm/$(validPins[pin][2])/pwm$(validPins[pin][3])/duty_cycle","r+") chip = pwm_pins[pin][2]
polarity_filestream = open("/sys/class/pwm/$(validPins[pin][2])/pwm$(validPins[pin][3])/polarity","r+")
return new(i, pin, chip, [enable_filestream, period_filestream, duty_cycle_filestream, polarity_filestream]) enable_filestream = open("$(basedir)/$(pwm_pins[pin][2])/pwm$(pwm_pins[pin][3])/enable","r+")
period_filestream = open("$(basedir)/$(pwm_pins[pin][2])/pwm$(pwm_pins[pin][3])/period","r+")
duty_cycle_filestream = open("$(basedir)/$(pwm_pins[pin][2])/pwm$(pwm_pins[pin][3])/duty_cycle","r+")
polarity_filestream = open("$(basedir)/$(pwm_pins[pin][2])/pwm$(pwm_pins[pin][3])/polarity","r+")
return new(i, pin, chip, basedir, [enable_filestream, period_filestream, duty_cycle_filestream, polarity_filestream])
end end
end end
...@@ -46,40 +42,114 @@ function write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false) ...@@ -46,40 +42,114 @@ function write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false)
operation, entry = args[1], args[2] operation, entry = args[1], args[2]
(operation < 1 || operation > length(pwm.filestreams)) && error("Invalid PWM operation: $operation") (operation < 1 || operation > length(pwm.filestreams)) && error("Invalid PWM operation: $operation")
#TODO: Add a list of allowed entries for error checking # Input data check
write(pwm.filestreams[operation], entry) assert_pwm_write(operation, entry)
# Write to file
seekstart(pwm.filestreams[operation]) seekstart(pwm.filestreams[operation])
write(pwm.filestreams[operation], "$entry\n")
flush(pwm.filestreams[operation])
end
"""
assert_pwm_write(operation::Int32, entry::String)
Assertsion for the PWM input data
"""
function assert_pwm_write(operation::Int32, entry::String)
if operation == "1"
entry ["0", "1"] && error("Invalid SysLED entry $(entry), valid options are 0 and 1 ::String")
else
number = try
parse(Int32, entry)
catch
error("Invalid SysLED entry $(entry), cannot parse as Int32")
end
(number < 0 || number > 100000000) && error("Invalid SysLED entry $(entry), not in the range [0,100000000]")
end
end end
""" """
l = read(pwm::PWM, operation::Int32, debug::Bool=false) l = read(pwm::PWM, operation::Int32, debug::Bool=false)
Reads the current value from an operation on a PWM. Reads the current value from an operation on a GPIO.
""" """
function read(pwm::PWM, operation::Int32, debug::Bool=false) function read(pwm::PWM, operation::Int32, debug::Bool=false)
debug && return debug && return
(operation < 1 || operation > length(pwm.filestreams)) && error("Invalid PWM operation: $operation") # Filestreams 1, 2 and 3 are readable
l = readline(pwm.filestreams[operation]) operation [1,2,3,4] && error("Invalid GPIO operation: $operation for reading")
seekstart(pwm.filestreams[operation]) seekstart(pwm.filestreams[operation])
l = readline(pwm.filestreams[operation])
return l return l
end end
""" """
teardown!(pwd::PWM) teardown!(pwd::PWM)
Closes all open streams on the PWM, and unexports it from the file system Closes all open streams on the PWM, and unexports it from the file system
""" """
function teardown!(pwm::PWM, debug::Bool=false) function teardown(pwm::PWM, debug::Bool=false)
debug && return debug && return
#Close all IOStreams #Close all IOStreams
for stream in pwm.filestreams for stream in pwm.filestreams
close(stream) close(stream)
end end
#Unexport filestructure if isdefined(:RUNNING_TESTS)
filename = "/sys/class/pwm/$(pwm.chip)/unexport" # Remove the dummy file system for testing
export_number = validPins[pwm.pin][3] try
write(filename, export_number) rm("$(pwm.basedir)/$(pwm_pins[pwm.pin][2])/pwm$(pwm_pins[pwm.pin][3])"; recursive=true)
return catch
error("Could not remove the requested GPIO testfiles for channel $(pwm_pins[pwm.pin][2])/pwm$(pwm_pins[pwm.pin][3]).")
end
else
#Unexport filestructure
filename = "/sys/class/pwm/$(pwm.chip)/unexport"
export_number = pwm_pins[pwm.pin][3]
write(filename, export_number)
end
end
"""
export_gpio(i::Int32, debug::Bool=false)
Export the GPIO file system, either for real-time or testing usecases.
"""
function export_pwm(i::Int32)
# Find chip and export number
pins = collect(keys(pwm_pins))
pin = pins[i]
chip = pwm_pins[pin][2]
if isdefined(:RUNNING_TESTS)
# Export a dummy file system for testing
basedir = "$(pwd())/testfilesystem/pwm"
complete_path = "$(basedir)/$(pwm_pins[pin][2])/pwm$(pwm_pins[pin][3])"
try
mkpath(complete_path)
catch
error("Could not export the PWM device for $(pwm_pins[pin][2]) for testing as the directory $(basedir)/$(pwm_pins[pin][2])/pwm$(pwm_pins[pin][3]) already exists.")
end
try
f = open("$(complete_path)/enable", "w"); write(f,"0"); close(f);
f = open("$(complete_path)/period", "w"); write(f,"0"); close(f);
f = open("$(complete_path)/duty_cycle", "w"); write(f,"0"); close(f);
f = open("$(complete_path)/polarity", "w"); write(f,"0"); close(f);
catch
error("Could not open the requested GPIO testfiles for $(complete_path).")
end
else
basedir = "/sys/class/pwm"
# Configure the pin to run PWM if possible
Base.run(`config-pin $(pin) pwm`)
# Export the filestructure of the corresponding chip
filename = "/sys/class/pwm/$(chip)/export"
exportNumber = pwm_pins[pin][3]
write(filename, exportNumber)
end
return basedir
end end
""" """
......
using LabConnections.BeagleBone
import LabConnections.BeagleBone: initdev, listdev, closedev, printdev, write!, read, pwm_pins
using Base.Test using Base.Test
@testset "PWM tests" begin @testset "PWM tests" begin
@testset "Inialization and termination" begin
@test 1 == 1 @testset "Inialization/Termination" begin
# Initialize three devices
initdev("pwm", Int32(1))
@test sum(listdev()) == 1
initdev("pwm", Int32(3))
@test sum(listdev()) == 2
initdev("pwm", Int32(5))
@test sum(listdev()) == 3
#printdev("gpio", 3)
# Attempt to initialize a device which has already been initialized
@test_throws ErrorException initdev("pwm", Int32(1))
@test_throws ErrorException initdev("pwm", Int32(3))
@test_throws ErrorException initdev("pwm", Int32(5))
# Attempt to initialize a device with a very high index (no matching channel)
@test_throws ErrorException initdev("pwm", Int32(1000))
# Attempt to remove devices which have not been initialized
@test_throws ErrorException closedev("pwm", Int32(2))
@test_throws ErrorException closedev("pwm", Int32(4))
@test_throws ErrorException closedev("pwm", Int32(6))
#printdev("gpio", 3)
# Remove devices from TOC
closedev("pwm", Int32(1))
@test sum(listdev()) == 2
closedev("pwm", Int32(3))
@test sum(listdev()) == 1
closedev("pwm", Int32(5))
@test sum(listdev()) == 0
end end
@testset "Read and write" begin @testset "Read/Write" begin
@test 1 == 1
# Fixture
device = initdev("pwm", Int32(1))
# Test that an exception is thrown when an invalid operation is given
# supported operations are 1,2,3,
@test_throws ErrorException write!(device, (Int32(0), "something"))
@test_throws ErrorException write!(device, (Int32(5), "something"))
# Test thet exceptions are thrown when attempting to write faulty entries
@test_throws ErrorException write!(device, (Int32(1), "-1"))
@test_throws ErrorException write!(device, (Int32(1), "bad_entry"))
@test_throws ErrorException write!(device, (Int32(2), "-1"))
@test_throws ErrorException write!(device, (Int32(2), "100000001"))
@test_throws ErrorException write!(device, (Int32(2), "bad_entry"))
@test_throws ErrorException write!(device, (Int32(3), "-1"))
@test_throws ErrorException write!(device, (Int32(3), "100000001"))
@test_throws ErrorException write!(device, (Int32(3), "bad_entry"))
@test_throws ErrorException write!(device, (Int32(4), "-1"))
@test_throws ErrorException write!(device, (Int32(4), "100000001"))
@test_throws ErrorException write!(device, (Int32(4), "bad_entry"))
# Close Gpio
closedev("pwm", Int32(1))
end
@testset "All pins" begin
# Instanciate all possible leds and perform 10 read/write commands
# with the set high/low operation ("value")
# Configure the GPIO for output usage
devices = []
for ii = 1:length(pwm_pins)
device = initdev("pwm", Int32(ii))
# Operation 2 -> in/out, set out
write!(device, (Int32(2), "100000000"))
@test read(device, Int32(2)) == "100000000"
write!(device, (Int32(3), "50000000"))
@test read(device, Int32(3)) == "50000000"
write!(device, (Int32(1), "1"))
@test read(device, Int32(1)) == "1"
# Append to list
append!(devices, [device])
end
@test sum(listdev()) == 6
sleep(1.0)
# Closes all devices
for ii = 1:length(pwm_pins)
write!(devices[ii], (Int32(1), "0"))
closedev("pwm", Int32(ii))
end
@test sum(listdev()) == 0
end end
end end
using LabConnections.BeagleBone
using Base.Test using Base.Test
# This flag is enabled if a dummy filesystem should be used for testing (for online testing) # This flag is enabled if a dummy filesystem should be used for testing (for online testing)
# disabling the flag allows the BBB to be run in the loop, in this case blinking LEDS # disabling the flag allows the BBB to be run in the loop, in this case blinking LEDS
#RUNNING_TESTS = true RUNNING_TESTS = true
# Run tests
include("BeagleBone/SYS_LED_test.jl") include("BeagleBone/SYS_LED_test.jl")
include("BeagleBone/GPIO_test.jl") include("BeagleBone/GPIO_test.jl")
include("BeagleBone/PWM_test.jl") include("BeagleBone/PWM_test.jl")
# Remove the testfilesystem
try
rm("$(pwd())/testfilesystem", recursive=true)
catch
println("Warning. Could not remove the testfilesystem.")
end
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