From 79cc424fe0e55f4b50d3ea1586f9ba8fc7d92150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20F=C3=A4lt?= Date: Wed, 5 Dec 2018 14:29:06 +0100 Subject: [PATCH 01/47] Almost working julia1.0 version --- Examples/testLED.jl | 6 ++++-- Manifest.toml | 5 +++++ Project.toml | 14 ++++++++++++++ REQUIRE | 2 +- src/BeagleBone/BeagleBone.jl | 10 +++++----- src/BeagleBone/Debug.jl | 2 +- src/BeagleBone/GPIO.jl | 8 +++++--- src/BeagleBone/PWM.jl | 8 +++++--- src/BeagleBone/SysLED.jl | 8 +++++--- src/BeagleBone/config/config_library.jl | 8 ++++---- src/Computer/10V.jl | 2 +- src/LabConnections.jl | 10 +++++++++- test/BeagleBone/GPIO_test.jl | 2 +- test/BeagleBone/PWM_test.jl | 2 +- test/BeagleBone/SYS_LED_test.jl | 2 +- test/runtests.jl | 4 ++-- test/testBB.jl | 2 +- test/testConenction.jl | 1 + 18 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 Manifest.toml create mode 100644 Project.toml diff --git a/Examples/testLED.jl b/Examples/testLED.jl index 66d634d..d61d0e7 100644 --- a/Examples/testLED.jl +++ b/Examples/testLED.jl @@ -1,9 +1,10 @@ #On beaglebone, run: # include("LabConnections/src/LabConnections.jl") -# using LabConnections.BeagleBone -# run_server() +# using Main.LabConnections.BeagleBone +# srv = run_server() using LabConnections.Computer +using Sockets stream = BeagleBoneStream(ip"192.168.7.2") led1 = SysLED(1) @@ -16,6 +17,7 @@ led4 = SysLED(4) init_devices!(stream, led1, led2, led3, led4) ledon = true for i = 1:100 + global ledon put!(led1, ledon) put!(led2, !ledon) put!(led3, ledon) diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000..7d0d0bf --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,5 @@ +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..221164a --- /dev/null +++ b/Project.toml @@ -0,0 +1,14 @@ +name = "LabConnections" +uuid = "e9ebaa62-f26d-11e8-0a59-692f6511a9a1" +authors = ["Mattias Fält ", "Marcus Greiff", "Marcus Thelander Andrén"] +version = "0.1.0" + +[deps] +Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" + +[extras] +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] diff --git a/REQUIRE b/REQUIRE index 137767a..05b5ab4 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1 +1 @@ -julia 0.6 +julia 1.0 diff --git a/src/BeagleBone/BeagleBone.jl b/src/BeagleBone/BeagleBone.jl index 9aa402b..aca8a1c 100644 --- a/src/BeagleBone/BeagleBone.jl +++ b/src/BeagleBone/BeagleBone.jl @@ -125,8 +125,8 @@ function bbparse(l::Tuple, sock) return else #TODO fix to have at least partial type stability - vals = Array{Any,1}(ndev) - timestamps = Array{UInt64,1}(ndev) + vals = Array{Any,1}(undef,ndev) + timestamps = Array{UInt64,1}(undef,ndev) for i = 1:ndev command = l[2+i]::Tuple dev = getdev(command[1], command[2]) @@ -146,7 +146,7 @@ Optional debug keyword disables blinking system leds. """ function run_server(port=2001; debug=false) global __waiting_first_connection__ = true - server = listen(port) + server = listen(IPv4(0), port) # IPv4(0) means listen from any ip @async while isopen(server) try @async while __waiting_first_connection__ && !debug @@ -173,7 +173,7 @@ function run_server(port=2001; debug=false) println("Connection to server closed") else println("error: $(typeof(err))") - throw(err) + rethrow() end end end @@ -181,7 +181,7 @@ function run_server(port=2001; debug=false) if isa(err,Base.UVError) && err.prefix == "accept" println("Server closed successfully") else - throw(err) + rethrow() end end end diff --git a/src/BeagleBone/Debug.jl b/src/BeagleBone/Debug.jl index e2fd369..5c7f84b 100644 --- a/src/BeagleBone/Debug.jl +++ b/src/BeagleBone/Debug.jl @@ -2,7 +2,7 @@ Debug(i::Int32) Type for debugging and precompile. """ -type Debug <: IO_Object +struct Debug <: IO_Object i::Int32 end write!(::Debug, val, debug::Bool=false) = nothing diff --git a/src/BeagleBone/GPIO.jl b/src/BeagleBone/GPIO.jl index cc03657..88a1879 100644 --- a/src/BeagleBone/GPIO.jl +++ b/src/BeagleBone/GPIO.jl @@ -15,7 +15,7 @@ The operation of reading the current output value of the GPIO is done by See the test/BeagleBone/GPIO_test.jl for more examples. """ -type GPIO <: IO_Object +struct GPIO <: IO_Object i::Int32 basedir::String filestreams::Array{IOStream,1} @@ -79,7 +79,8 @@ function teardown(gpio::GPIO, debug::Bool=false) end #Unexport filestructure - if isdefined(:RUNNING_TESTS) + global RUNNING_TESTS + if RUNNING_TESTS # Remove the dummy file system for testing basedir = "$(pwd())/testfilesystem/gpio" try @@ -100,7 +101,8 @@ end Export the GPIO file system, either for real-time or testing usecases. """ function export_gpio(i::Int32) - if isdefined(:RUNNING_TESTS) + global RUNNING_TESTS + if RUNNING_TESTS # Export a dummy file system for testing basedir = "$(pwd())/testfilesystem/gpio" try diff --git a/src/BeagleBone/PWM.jl b/src/BeagleBone/PWM.jl index 33fa9c4..c554de5 100644 --- a/src/BeagleBone/PWM.jl +++ b/src/BeagleBone/PWM.jl @@ -5,7 +5,7 @@ dictionary pwm_pins relates to memory adresses in of the AM3359 chip, see p.182 in www.ti.com/product/AM3359/technicaldocuments. """ -type PWM <: IO_Object +struct PWM <: IO_Object i::Int32 pin::String chip::String @@ -95,7 +95,8 @@ function teardown(pwm::PWM, debug::Bool=false) close(stream) end - if isdefined(:RUNNING_TESTS) + global RUNNING_TESTS + if RUNNING_TESTS # Remove the dummy file system for testing try rm("$(pwm.basedir)/$(pwm_pins[pwm.pin][2])/pwm$(pwm_pins[pwm.pin][3])"; recursive=true) @@ -120,7 +121,8 @@ function export_pwm(i::Int32) pin = pins[i] chip = pwm_pins[pin][2] - if isdefined(:RUNNING_TESTS) + global RUNNING_TESTS + if 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])" diff --git a/src/BeagleBone/SysLED.jl b/src/BeagleBone/SysLED.jl index 03cca51..71680bc 100644 --- a/src/BeagleBone/SysLED.jl +++ b/src/BeagleBone/SysLED.jl @@ -3,7 +3,7 @@ Type representing the system LEDs on the BeagleBone. The LEDs are indexed by i ∈ [1,2,3,4]. """ -type SysLED <: IO_Object +struct SysLED <: IO_Object i::Int32 basedir::String filestream::IOStream @@ -49,7 +49,8 @@ function teardown(led::SysLED, debug::Bool=false) debug && return close(led.filestream) - if isdefined(:RUNNING_TESTS) + global RUNNING_TESTS + if RUNNING_TESTS # Remove the dummy file system for testing try #println("$(led.basedir)/beaglebone:green:usr$(led.i-1)") @@ -67,7 +68,8 @@ Exports a dummy filesystem for testing the LED implementation function export_led(i::Int32, debug::Bool=false) debug && return - if isdefined(:RUNNING_TESTS) + global RUNNING_TESTS + if RUNNING_TESTS # Export a dummy file system for testing basedir = "$(pwd())/testfilesystem/leds" try diff --git a/src/BeagleBone/config/config_library.jl b/src/BeagleBone/config/config_library.jl index 72fac56..55842b4 100644 --- a/src/BeagleBone/config/config_library.jl +++ b/src/BeagleBone/config/config_library.jl @@ -2,7 +2,7 @@ import YAML abstract type IO_Object end -type GPIO <: IO_Object +struct GPIO <: IO_Object ID::Int32 pins::Array{String, 1} InOut::String @@ -11,7 +11,7 @@ end GPIO(ID, pins, InOut; file_handles=[])=GPIO(ID, pins, InOut, file_handles) # The PWM type -type PWM <: IO_Object +struct PWM <: IO_Object ID::Int32 pins::Array{String, 1} file_handles::Array{IOStream} @@ -19,7 +19,7 @@ end PWM(ID, pins; file_handles=[])=PWM(ID, pins, file_handles) # The analog to digital converter type -type ADC <: IO_Object +struct ADC <: IO_Object ID::Int32 pins::Array{String, 1} channel::String @@ -28,7 +28,7 @@ end ADC(ID, pins, channel; file_handles=[])=ADC(ID, pins, channel, file_handles) # The quadrature encoder type -type QEP <: IO_Object +struct QEP <: IO_Object ID::Int32 pins::Array{String, 1} file_handles::Array{IOStream} diff --git a/src/Computer/10V.jl b/src/Computer/10V.jl index 4c84a49..ae2e982 100644 --- a/src/Computer/10V.jl +++ b/src/Computer/10V.jl @@ -17,7 +17,7 @@ initialize(::AnalogInput10V) = nothing initialize(::AnalogOutput10V) = nothing close(::AnalogInput10V) = nothing -close(input::AnalogOutput10V) = ccall((:comedi_write_zero, comedipath), Void, (Int32, Int32, Int32), Int32(0), Int32(1), input.i) +close(input::AnalogOutput10V) = ccall((:comedi_write_zero, comedipath), Cvoid, (Int32, Int32, Int32), Int32(0), Int32(1), input.i) getwritecommand(stream::LabStream, input::AnalogInput10V, val) = error("Can't write to device $input") getreadcommand(stream::LabStream, output::AnalogOutput10V, val) = error("Can't read from device $output") diff --git a/src/LabConnections.jl b/src/LabConnections.jl index 0b63148..10e9c6b 100644 --- a/src/LabConnections.jl +++ b/src/LabConnections.jl @@ -2,6 +2,11 @@ __precompile__() module LabConnections module BeagleBone + RUNNING_TESTS = false # TODO Can we make this constant? + function running_test(val) + global RUNNING_TESTS = val + end + using Sockets, Serialization export run_server import Base: read println("Initializing BB") @@ -13,7 +18,10 @@ module LabConnections end module Computer - import Base: read, send, close, get, put!, serialize + using Sockets, Serialization + import Base: read, close, get, put! + import Sockets: send + import Serialization: serialize println("Initializing Computer") include(joinpath("Computer","Computer.jl")) end diff --git a/test/BeagleBone/GPIO_test.jl b/test/BeagleBone/GPIO_test.jl index 07ca2d5..ad0d118 100644 --- a/test/BeagleBone/GPIO_test.jl +++ b/test/BeagleBone/GPIO_test.jl @@ -1,7 +1,7 @@ using LabConnections.BeagleBone import LabConnections.BeagleBone: initdev, listdev, closedev, printdev, write!, read, gpio_channels -using Base.Test +using Test @testset "GPIO tests" begin diff --git a/test/BeagleBone/PWM_test.jl b/test/BeagleBone/PWM_test.jl index 7a61d00..dcd6fa9 100644 --- a/test/BeagleBone/PWM_test.jl +++ b/test/BeagleBone/PWM_test.jl @@ -1,7 +1,7 @@ using LabConnections.BeagleBone import LabConnections.BeagleBone: initdev, listdev, closedev, printdev, write!, read, pwm_pins -using Base.Test +using Test @testset "PWM tests" begin diff --git a/test/BeagleBone/SYS_LED_test.jl b/test/BeagleBone/SYS_LED_test.jl index d513ddf..fb3ed90 100644 --- a/test/BeagleBone/SYS_LED_test.jl +++ b/test/BeagleBone/SYS_LED_test.jl @@ -1,7 +1,7 @@ using LabConnections.BeagleBone import LabConnections.BeagleBone: getdev, write!, closedev, read, initdev, printdev, listdev -using Base.Test +using Test @testset "SYS LED Tests" begin diff --git a/test/runtests.jl b/test/runtests.jl index 66269cc..cdeb529 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,10 +1,10 @@ using LabConnections.BeagleBone -using Base.Test +using Test # 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 -RUNNING_TESTS = true +BeagleBone.running_test(true) # Run tests include("BeagleBone/SYS_LED_test.jl") diff --git a/test/testBB.jl b/test/testBB.jl index f0499b3..078ae46 100644 --- a/test/testBB.jl +++ b/test/testBB.jl @@ -1,5 +1,5 @@ using LabConnections -using Base.Test +using Test # 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 diff --git a/test/testConenction.jl b/test/testConenction.jl index 9344e0b..47c46e3 100644 --- a/test/testConenction.jl +++ b/test/testConenction.jl @@ -1,3 +1,4 @@ +using Sockets, Serialization #BB side function startbb() @async begin From 33d60f3be50242ad3b3c83599d5041e5a678c459 Mon Sep 17 00:00:00 2001 From: Fredrik Bagge Carlson Date: Fri, 7 Dec 2018 16:06:29 +0100 Subject: [PATCH 02/47] Update README.md with link to usage examples --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0350b2b..0c43bdc 100644 --- a/README.md +++ b/README.md @@ -109,4 +109,4 @@ Similarly we can read from several devices at the same time by using `get` There are several examples found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/master/docs/build/examples/examples.md#examples) which let's you test out the functionality of `LabConnections.jl`. - +Examples of real-world usage are available in [ball-and-beam](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_implementations/ballandbeam.jl) From 59537eea807ef6d6ebe2d4c9955c49b65973c119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Fri, 7 Dec 2018 16:44:49 +0100 Subject: [PATCH 03/47] Add new directory --- util/device/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 util/device/.gitkeep diff --git a/util/device/.gitkeep b/util/device/.gitkeep new file mode 100644 index 0000000..e69de29 From 96e726fcafe98258ba287937468c74642a430cf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Fri, 7 Dec 2018 16:49:07 +0100 Subject: [PATCH 04/47] Added device tree overlay for BB, which avoids conflict with HDMI/audio port --- util/{device => device_tree_overlay}/.gitkeep | 0 .../cape-universallc-00A0.dts | 1688 +++++++++++++++++ 2 files changed, 1688 insertions(+) rename util/{device => device_tree_overlay}/.gitkeep (100%) create mode 100644 util/device_tree_overlay/cape-universallc-00A0.dts diff --git a/util/device/.gitkeep b/util/device_tree_overlay/.gitkeep similarity index 100% rename from util/device/.gitkeep rename to util/device_tree_overlay/.gitkeep diff --git a/util/device_tree_overlay/cape-universallc-00A0.dts b/util/device_tree_overlay/cape-universallc-00A0.dts new file mode 100644 index 0000000..3cc5c53 --- /dev/null +++ b/util/device_tree_overlay/cape-universallc-00A0.dts @@ -0,0 +1,1688 @@ +// Copyright 2013 +// Charles Steinkuehler +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +/dts-v1/; +/plugin/; + +/ { + compatible = "ti,beaglebone", "ti,beaglebone-black"; + + /* identification */ + part-number = "cape-bone-universaln"; + version = "00A0"; + + /* state the resources this cape uses */ + exclusive-use = + +/* "P8.1", GND */ +/* "P8.2", GND */ +/* "P8.3", emmc */ +/* "P8.4", emmc */ +/* "P8.5", emmc */ +/* "P8.6", emmc */ + "P8.7", + "P8.8", + "P8.9", + "P8.10", + "P8.11", + "P8.12", + "P8.13", + "P8.14", + "P8.15", + "P8.16", + "P8.17", + "P8.18", + "P8.19", +/* "P8.20", emmc */ +/* "P8.21", emmc */ +/* "P8.22", emmc */ +/* "P8.23", emmc */ +/* "P8.24", emmc */ +/* "P8.25", emmc */ + "P8.26", +/* "P8.27", hdmi */ +/* "P8.28", hdmi */ +/* "P8.29", hdmi */ +/* "P8.30", hdmi */ +/* "P8.31", hdmi */ +/* "P8.32", hdmi */ +/* "P8.33", hdmi */ +/* "P8.34", hdmi */ +/* "P8.35", hdmi */ +/* "P8.36", hdmi */ +/* "P8.37", hdmi */ +/* "P8.38", hdmi */ +/* "P8.39", hdmi */ +/* "P8.40", hdmi */ +/* "P8.41", hdmi */ +/* "P8.42", hdmi */ +/* "P8.43", hdmi */ +/* "P8.44", hdmi */ +/* "P8.45", hdmi */ +/* "P8.46", hdmi */ + +/* "P9.1", GND */ +/* "P9.2", GND */ +/* "P9.3", 3.3V */ +/* "P9.4", 3.3V */ +/* "P9.5", VDD_5V */ +/* "P9.6", VDD_5V */ +/* "P9.7", SYS_5V */ +/* "P9.8", SYS_5V */ +/* "P9.9", PWR_BUT */ +/* "P9.10", RESETn */ + "P9.11", + "P9.12", + "P9.13", + "P9.14", + "P9.15", + "P9.16", + "P9.17", + "P9.18", +/* "P9.19", I2C */ +/* "P9.20", I2C */ + "P9.21", + "P9.22", + "P9.23", + "P9.24", +/* "P9.25", Audio */ + "P9.26", + "P9.27", +/* "P9.28", Audio */ +/* "P9.29", Audio */ + "P9.30", +/* "P9.31", Audio */ +/* "P9.32", VADC */ +/* "P9.33", AIN4 */ +/* "P9.34", AGND */ +/* "P9.35", AIN6 */ +/* "P9.36", AIN5 */ +/* "P9.37", AIN2 */ +/* "P9.38", AIN3 */ +/* "P9.39", AIN0 */ +/* "P9.40", AIN1 */ + "P9.41", + "P9.41.1", + "P9.42", + "P9.42.1", +/* "P9.43", GND */ +/* "P9.44", GND */ +/* "P9.45", GND */ +/* "P9.46", GND */ + + "uart1", + "uart2", + "uart4", +// "uart5", /* Conflicts with HDMI */ + + "ehrpwm0A", + "ehrpwm0B", + "ehrpwm1A", + "ehrpwm1B", + "ehrpwm2A", + "ehrpwm2B", + +// "epwmss0", +// "ehrpwm0", +// "ecap0", +// "epwmss1", +// "ehrpwm1", +// "epwmss2", +// "ehrpwm2", +// "ecap2", + + "i2c1", + "spi1", + "spi0", + "dcan0", + "dcan1", + + "pru0", + "pru1", + "pruss"; + + fragment@0 { + target = <&am33xx_pinmux>; + __overlay__ { + + /************************/ + /* P8 Header */ + /************************/ + + /* P8_01 GND */ + /* P8_02 GND */ + /* P8_03 (ZCZ ball R9 ) emmc */ + /* P8_04 (ZCZ ball T9 ) emmc */ + /* P8_05 (ZCZ ball R8 ) emmc */ + /* P8_06 (ZCZ ball T8 ) emmc */ + + /* P8_07 (ZCZ ball R7 ) */ + P8_07_default_pin: pinmux_P8_07_default_pin { + pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_07_gpio_pin: pinmux_P8_07_gpio_pin { + pinctrl-single,pins = <0x090 0x2F>; }; /* Mode 7, RxActive */ + P8_07_gpio_pu_pin: pinmux_P8_07_gpio_pu_pin { + pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_07_gpio_pd_pin: pinmux_P8_07_gpio_pd_pin { + pinctrl-single,pins = <0x090 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_07_timer_pin: pinmux_P8_07_timer_pin { + pinctrl-single,pins = <0x090 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + + /* P8_08 (ZCZ ball T7 ) */ + P8_08_default_pin: pinmux_P8_08_default_pin { + pinctrl-single,pins = <0x094 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_08_gpio_pin: pinmux_P8_08_gpio_pin { + pinctrl-single,pins = <0x094 0x2F>; }; /* Mode 7, RxActive */ + P8_08_gpio_pu_pin: pinmux_P8_08_gpio_pu_pin { + pinctrl-single,pins = <0x094 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_08_gpio_pd_pin: pinmux_P8_08_gpio_pd_pin { + pinctrl-single,pins = <0x094 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_08_timer_pin: pinmux_P8_08_timer_pin { + pinctrl-single,pins = <0x094 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + + /* P8_09 (ZCZ ball T6 ) */ + P8_09_default_pin: pinmux_P8_09_default_pin { + pinctrl-single,pins = <0x09c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_09_gpio_pin: pinmux_P8_09_gpio_pin { + pinctrl-single,pins = <0x09c 0x2F>; }; /* Mode 7, RxActive */ + P8_09_gpio_pu_pin: pinmux_P8_09_gpio_pu_pin { + pinctrl-single,pins = <0x09c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_09_gpio_pd_pin: pinmux_P8_09_gpio_pd_pin { + pinctrl-single,pins = <0x09c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_09_timer_pin: pinmux_P8_09_timer_pin { + pinctrl-single,pins = <0x09c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + + /* P8_10 (ZCZ ball U6 ) */ + P8_10_default_pin: pinmux_P8_10_default_pin { + pinctrl-single,pins = <0x098 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_10_gpio_pin: pinmux_P8_10_gpio_pin { + pinctrl-single,pins = <0x098 0x2F>; }; /* Mode 7, RxActive */ + P8_10_gpio_pu_pin: pinmux_P8_10_gpio_pu_pin { + pinctrl-single,pins = <0x098 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_10_gpio_pd_pin: pinmux_P8_10_gpio_pd_pin { + pinctrl-single,pins = <0x098 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_10_timer_pin: pinmux_P8_10_timer_pin { + pinctrl-single,pins = <0x098 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + + /* P8_11 (ZCZ ball R12) */ + P8_11_default_pin: pinmux_P8_11_default_pin { + pinctrl-single,pins = <0x034 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_11_gpio_pin: pinmux_P8_11_gpio_pin { + pinctrl-single,pins = <0x034 0x2F>; }; /* Mode 7, RxActive */ + P8_11_gpio_pu_pin: pinmux_P8_11_gpio_pu_pin { + pinctrl-single,pins = <0x034 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_11_gpio_pd_pin: pinmux_P8_11_gpio_pd_pin { + pinctrl-single,pins = <0x034 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_11_pruout_pin: pinmux_P8_11_pruout_pin { + pinctrl-single,pins = <0x034 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + P8_11_qep_pin: pinmux_P8_11_qep_pin { + pinctrl-single,pins = <0x034 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P8_12 (ZCZ ball T12) */ + P8_12_default_pin: pinmux_P8_12_default_pin { + pinctrl-single,pins = <0x030 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_12_gpio_pin: pinmux_P8_12_gpio_pin { + pinctrl-single,pins = <0x030 0x2F>; }; /* Mode 7, RxActive */ + P8_12_gpio_pu_pin: pinmux_P8_12_gpio_pu_pin { + pinctrl-single,pins = <0x030 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_12_gpio_pd_pin: pinmux_P8_12_gpio_pd_pin { + pinctrl-single,pins = <0x030 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_12_pruout_pin: pinmux_P8_12_pruout_pin { + pinctrl-single,pins = <0x030 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + P8_12_qep_pin: pinmux_P8_12_qep_pin { + pinctrl-single,pins = <0x030 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P8_13 (ZCZ ball T10) */ + P8_13_default_pin: pinmux_P8_13_default_pin { + pinctrl-single,pins = <0x024 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_13_gpio_pin: pinmux_P8_13_gpio_pin { + pinctrl-single,pins = <0x024 0x2F>; }; /* Mode 7, RxActive */ + P8_13_gpio_pu_pin: pinmux_P8_13_gpio_pu_pin { + pinctrl-single,pins = <0x024 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_13_gpio_pd_pin: pinmux_P8_13_gpio_pd_pin { + pinctrl-single,pins = <0x024 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_13_pwm_pin: pinmux_P8_13_pwm_pin { + pinctrl-single,pins = <0x024 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P8_14 (ZCZ ball T11) */ + P8_14_default_pin: pinmux_P8_14_default_pin { + pinctrl-single,pins = <0x028 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_14_gpio_pin: pinmux_P8_14_gpio_pin { + pinctrl-single,pins = <0x028 0x2F>; }; /* Mode 7, RxActive */ + P8_14_gpio_pu_pin: pinmux_P8_14_gpio_pu_pin { + pinctrl-single,pins = <0x028 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_14_gpio_pd_pin: pinmux_P8_14_gpio_pd_pin { + pinctrl-single,pins = <0x028 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_14_pwm_pin: pinmux_P8_14_pwm_pin { + pinctrl-single,pins = <0x028 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P8_15 (ZCZ ball U13) */ + P8_15_default_pin: pinmux_P8_15_default_pin { + pinctrl-single,pins = <0x03c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_15_gpio_pin: pinmux_P8_15_gpio_pin { + pinctrl-single,pins = <0x03c 0x2F>; }; /* Mode 7, RxActive */ + P8_15_gpio_pu_pin: pinmux_P8_15_gpio_pu_pin { + pinctrl-single,pins = <0x03c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_15_gpio_pd_pin: pinmux_P8_15_gpio_pd_pin { + pinctrl-single,pins = <0x03c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_15_pruin_pin: pinmux_P8_15_pruin_pin { + pinctrl-single,pins = <0x03c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + P8_15_pru_ecap_pin: pinmux_P8_15_pru_ecap_pin { + pinctrl-single,pins = <0x03c 0x25>; }; /* Mode 5, Pull-Down, RxActive */ + P8_15_qep_pin: pinmux_P8_15_qep_pin { + pinctrl-single,pins = <0x03c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P8_16 (ZCZ ball V13) */ + P8_16_default_pin: pinmux_P8_16_default_pin { + pinctrl-single,pins = <0x038 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_16_gpio_pin: pinmux_P8_16_gpio_pin { + pinctrl-single,pins = <0x038 0x2F>; }; /* Mode 7, RxActive */ + P8_16_gpio_pu_pin: pinmux_P8_16_gpio_pu_pin { + pinctrl-single,pins = <0x038 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_16_gpio_pd_pin: pinmux_P8_16_gpio_pd_pin { + pinctrl-single,pins = <0x038 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_16_pruin_pin: pinmux_P8_16_pruin_pin { + pinctrl-single,pins = <0x038 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + P8_16_qep_pin: pinmux_P8_16_qep_pin { + pinctrl-single,pins = <0x038 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P8_17 (ZCZ ball U12) */ + P8_17_default_pin: pinmux_P8_17_default_pin { + pinctrl-single,pins = <0x02c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_17_gpio_pin: pinmux_P8_17_gpio_pin { + pinctrl-single,pins = <0x02c 0x2F>; }; /* Mode 7, RxActive */ + P8_17_gpio_pu_pin: pinmux_P8_17_gpio_pu_pin { + pinctrl-single,pins = <0x02c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_17_gpio_pd_pin: pinmux_P8_17_gpio_pd_pin { + pinctrl-single,pins = <0x02c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_17_pwm_pin: pinmux_P8_17_pwm_pin { + pinctrl-single,pins = <0x02c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P8_18 (ZCZ ball V12) */ + P8_18_default_pin: pinmux_P8_18_default_pin { + pinctrl-single,pins = <0x08c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_18_gpio_pin: pinmux_P8_18_gpio_pin { + pinctrl-single,pins = <0x08c 0x2F>; }; /* Mode 7, RxActive */ + P8_18_gpio_pu_pin: pinmux_P8_18_gpio_pu_pin { + pinctrl-single,pins = <0x08c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_18_gpio_pd_pin: pinmux_P8_18_gpio_pd_pin { + pinctrl-single,pins = <0x08c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + + /* P8_19 (ZCZ ball U10) */ + P8_19_default_pin: pinmux_P8_19_default_pin { + pinctrl-single,pins = <0x020 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_19_gpio_pin: pinmux_P8_19_gpio_pin { + pinctrl-single,pins = <0x020 0x2F>; }; /* Mode 7, RxActive */ + P8_19_gpio_pu_pin: pinmux_P8_19_gpio_pu_pin { + pinctrl-single,pins = <0x020 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_19_gpio_pd_pin: pinmux_P8_19_gpio_pd_pin { + pinctrl-single,pins = <0x020 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P8_19_pwm_pin: pinmux_P8_19_pwm_pin { + pinctrl-single,pins = <0x020 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P8_20 (ZCZ ball V9 ) emmc */ + /* P8_21 (ZCZ ball U9 ) emmc */ + /* P8_22 (ZCZ ball V8 ) emmc */ + /* P8_23 (ZCZ ball U8 ) emmc */ + /* P8_24 (ZCZ ball V7 ) emmc */ + /* P8_25 (ZCZ ball U7 ) emmc */ + + /* P8_26 (ZCZ ball V6 ) */ + P8_26_default_pin: pinmux_P8_26_default_pin { + pinctrl-single,pins = <0x07c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_26_gpio_pin: pinmux_P8_26_gpio_pin { + pinctrl-single,pins = <0x07c 0x2F>; }; /* Mode 7, RxActive */ + P8_26_gpio_pu_pin: pinmux_P8_26_gpio_pu_pin { + pinctrl-single,pins = <0x07c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P8_26_gpio_pd_pin: pinmux_P8_26_gpio_pd_pin { + pinctrl-single,pins = <0x07c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + + /* P8_27 (ZCZ ball U5 ) hdmi */ + /* P8_28 (ZCZ ball V5 ) hdmi */ + /* P8_29 (ZCZ ball R5 ) hdmi */ + /* P8_30 (ZCZ ball R6 ) hdmi */ + /* P8_31 (ZCZ ball V4 ) hdmi */ + /* P8_32 (ZCZ ball T5 ) hdmi */ + /* P8_33 (ZCZ ball V3 ) hdmi */ + /* P8_34 (ZCZ ball U4 ) hdmi */ + /* P8_35 (ZCZ ball V2 ) hdmi */ + /* P8_36 (ZCZ ball U3 ) hdmi */ + /* P8_37 (ZCZ ball U1 ) hdmi */ + /* P8_38 (ZCZ ball U2 ) hdmi */ + /* P8_39 (ZCZ ball T3 ) hdmi */ + /* P8_40 (ZCZ ball T4 ) hdmi */ + /* P8_41 (ZCZ ball T1 ) hdmi */ + /* P8_42 (ZCZ ball T2 ) hdmi */ + /* P8_43 (ZCZ ball R3 ) hdmi */ + /* P8_44 (ZCZ ball R4 ) hdmi */ + /* P8_45 (ZCZ ball R1 ) hdmi */ + /* P8_46 (ZCZ ball R2 ) hdmi */ + + + /************************/ + /* P9 Header */ + /************************/ + + /* P9_01 GND */ + /* P9_02 GND */ + /* P9_03 3.3V */ + /* P9_04 3.3V */ + /* P9_05 VDD_5V */ + /* P9_06 VDD_5V */ + /* P9_07 SYS_5V */ + /* P9_08 SYS_5V */ + /* P9_09 PWR_BUT */ + /* P9_10 (ZCZ ball A10) RESETn */ + + /* P9_11 (ZCZ ball T17) */ + P9_11_default_pin: pinmux_P9_11_default_pin { + pinctrl-single,pins = <0x070 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_11_gpio_pin: pinmux_P9_11_gpio_pin { + pinctrl-single,pins = <0x070 0x2F>; }; /* Mode 7, RxActive */ + P9_11_gpio_pu_pin: pinmux_P9_11_gpio_pu_pin { + pinctrl-single,pins = <0x070 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_11_gpio_pd_pin: pinmux_P9_11_gpio_pd_pin { + pinctrl-single,pins = <0x070 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_11_uart_pin: pinmux_P9_11_uart_pin { + pinctrl-single,pins = <0x070 0x36>; }; /* Mode 6, Pull-Up, RxActive */ + + /* P9_12 (ZCZ ball U18) */ + P9_12_default_pin: pinmux_P9_12_default_pin { + pinctrl-single,pins = <0x078 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_12_gpio_pin: pinmux_P9_12_gpio_pin { + pinctrl-single,pins = <0x078 0x2F>; }; /* Mode 7, RxActive */ + P9_12_gpio_pu_pin: pinmux_P9_12_gpio_pu_pin { + pinctrl-single,pins = <0x078 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_12_gpio_pd_pin: pinmux_P9_12_gpio_pd_pin { + pinctrl-single,pins = <0x078 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + + /* P9_13 (ZCZ ball U17) */ + P9_13_default_pin: pinmux_P9_13_default_pin { + pinctrl-single,pins = <0x074 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_13_gpio_pin: pinmux_P9_13_gpio_pin { + pinctrl-single,pins = <0x074 0x2F>; }; /* Mode 7, RxActive */ + P9_13_gpio_pu_pin: pinmux_P9_13_gpio_pu_pin { + pinctrl-single,pins = <0x074 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_13_gpio_pd_pin: pinmux_P9_13_gpio_pd_pin { + pinctrl-single,pins = <0x074 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_13_uart_pin: pinmux_P9_13_uart_pin { + pinctrl-single,pins = <0x074 0x36>; }; /* Mode 6, Pull-Up, RxActive */ + + /* P9_14 (ZCZ ball U14) */ + P9_14_default_pin: pinmux_P9_14_default_pin { + pinctrl-single,pins = <0x048 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_14_gpio_pin: pinmux_P9_14_gpio_pin { + pinctrl-single,pins = <0x048 0x2F>; }; /* Mode 7, RxActive */ + P9_14_gpio_pu_pin: pinmux_P9_14_gpio_pu_pin { + pinctrl-single,pins = <0x048 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_14_gpio_pd_pin: pinmux_P9_14_gpio_pd_pin { + pinctrl-single,pins = <0x048 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_14_pwm_pin: pinmux_P9_14_pwm_pin { + pinctrl-single,pins = <0x048 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + + /* P9_15 (ZCZ ball R13) */ + P9_15_default_pin: pinmux_P9_15_default_pin { + pinctrl-single,pins = <0x040 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_15_gpio_pin: pinmux_P9_15_gpio_pin { + pinctrl-single,pins = <0x040 0x2F>; }; /* Mode 7, RxActive */ + P9_15_gpio_pu_pin: pinmux_P9_15_gpio_pu_pin { + pinctrl-single,pins = <0x040 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_15_gpio_pd_pin: pinmux_P9_15_gpio_pd_pin { + pinctrl-single,pins = <0x040 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_15_pwm_pin: pinmux_P9_15_pwm_pin { + pinctrl-single,pins = <0x040 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + + /* P9_16 (ZCZ ball T14) */ + P9_16_default_pin: pinmux_P9_16_default_pin { + pinctrl-single,pins = <0x04c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_16_gpio_pin: pinmux_P9_16_gpio_pin { + pinctrl-single,pins = <0x04c 0x2F>; }; /* Mode 7, RxActive */ + P9_16_gpio_pu_pin: pinmux_P9_16_gpio_pu_pin { + pinctrl-single,pins = <0x04c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_16_gpio_pd_pin: pinmux_P9_16_gpio_pd_pin { + pinctrl-single,pins = <0x04c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_16_pwm_pin: pinmux_P9_16_pwm_pin { + pinctrl-single,pins = <0x04c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + + /* P9_17 (ZCZ ball A16) */ + P9_17_default_pin: pinmux_P9_17_default_pin { + pinctrl-single,pins = <0x15c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_17_gpio_pin: pinmux_P9_17_gpio_pin { + pinctrl-single,pins = <0x15c 0x2F>; }; /* Mode 7, RxActive */ + P9_17_gpio_pu_pin: pinmux_P9_17_gpio_pu_pin { + pinctrl-single,pins = <0x15c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_17_gpio_pd_pin: pinmux_P9_17_gpio_pd_pin { + pinctrl-single,pins = <0x15c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_17_spi_pin: pinmux_P9_17_spi_pin { + pinctrl-single,pins = <0x15c 0x30>; }; /* Mode 0, Pull-Up, RxActive */ + P9_17_i2c_pin: pinmux_P9_17_i2c_pin { + pinctrl-single,pins = <0x15c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + P9_17_pwm_pin: pinmux_P9_17_pwm_pin { + pinctrl-single,pins = <0x15c 0x33>; }; /* Mode 3, Pull-Up, RxActive */ + P9_17_pru_uart_pin: pinmux_P9_17_pru_uart_pin { + pinctrl-single,pins = <0x15c 0x34>; }; /* Mode 4, Pull-Up, RxActive */ + + /* P9_18 (ZCZ ball B16) */ + P9_18_default_pin: pinmux_P9_18_default_pin { + pinctrl-single,pins = <0x158 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_18_gpio_pin: pinmux_P9_18_gpio_pin { + pinctrl-single,pins = <0x158 0x2F>; }; /* Mode 7, RxActive */ + P9_18_gpio_pu_pin: pinmux_P9_18_gpio_pu_pin { + pinctrl-single,pins = <0x158 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_18_gpio_pd_pin: pinmux_P9_18_gpio_pd_pin { + pinctrl-single,pins = <0x158 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_18_spi_pin: pinmux_P9_18_spi_pin { + pinctrl-single,pins = <0x158 0x30>; }; /* Mode 0, Pull-Up, RxActive */ + P9_18_i2c_pin: pinmux_P9_18_i2c_pin { + pinctrl-single,pins = <0x158 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + P9_18_pwm_pin: pinmux_P9_18_pwm_pin { + pinctrl-single,pins = <0x158 0x33>; }; /* Mode 3, Pull-Up, RxActive */ + P9_18_pru_uart_pin: pinmux_P9_18_pru_uart_pin { + pinctrl-single,pins = <0x158 0x34>; }; /* Mode 4, Pull-Up, RxActive */ + + // Leave the cape I2C EEPROM bus alone + /* P9_19 (ZCZ ball D17) I2C */ + /* P9_20 (ZCZ ball D18) I2C */ + + /* P9_21 (ZCZ ball B17) */ + P9_21_default_pin: pinmux_P9_21_default_pin { + pinctrl-single,pins = <0x154 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_21_gpio_pin: pinmux_P9_21_gpio_pin { + pinctrl-single,pins = <0x154 0x2F>; }; /* Mode 7, RxActive */ + P9_21_gpio_pu_pin: pinmux_P9_21_gpio_pu_pin { + pinctrl-single,pins = <0x154 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_21_gpio_pd_pin: pinmux_P9_21_gpio_pd_pin { + pinctrl-single,pins = <0x154 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_21_spi_pin: pinmux_P9_21_spi_pin { + pinctrl-single,pins = <0x154 0x30>; }; /* Mode 0, Pull-Up, RxActive */ + P9_21_uart_pin: pinmux_P9_21_uart_pin { + pinctrl-single,pins = <0x154 0x31>; }; /* Mode 1, Pull-Up, RxActive */ + P9_21_i2c_pin: pinmux_P9_21_i2c_pin { + pinctrl-single,pins = <0x154 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + P9_21_pwm_pin: pinmux_P9_21_pwm_pin { + pinctrl-single,pins = <0x154 0x33>; }; /* Mode 3, Pull-Up, RxActive */ + P9_21_pru_uart_pin: pinmux_P9_21_pru_uart_pin { + pinctrl-single,pins = <0x154 0x34>; }; /* Mode 4, Pull-Up, RxActive */ + + /* P9_22 (ZCZ ball A17) */ + P9_22_default_pin: pinmux_P9_22_default_pin { + pinctrl-single,pins = <0x150 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_22_gpio_pin: pinmux_P9_22_gpio_pin { + pinctrl-single,pins = <0x150 0x2F>; }; /* Mode 7, RxActive */ + P9_22_gpio_pu_pin: pinmux_P9_22_gpio_pu_pin { + pinctrl-single,pins = <0x150 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_22_gpio_pd_pin: pinmux_P9_22_gpio_pd_pin { + pinctrl-single,pins = <0x150 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_22_spi_pin: pinmux_P9_22_spi_pin { + pinctrl-single,pins = <0x150 0x30>; }; /* Mode 0, Pull-Up, RxActive */ + P9_22_uart_pin: pinmux_P9_22_uart_pin { + pinctrl-single,pins = <0x150 0x31>; }; /* Mode 1, Pull-Up, RxActive */ + P9_22_i2c_pin: pinmux_P9_22_i2c_pin { + pinctrl-single,pins = <0x150 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + P9_22_pwm_pin: pinmux_P9_22_pwm_pin { + pinctrl-single,pins = <0x150 0x33>; }; /* Mode 3, Pull-Up, RxActive */ + P9_22_pru_uart_pin: pinmux_P9_22_pru_uart_pin { + pinctrl-single,pins = <0x150 0x34>; }; /* Mode 4, Pull-Up, RxActive */ + + /* P9_23 (ZCZ ball V14) */ + P9_23_default_pin: pinmux_P9_23_default_pin { + pinctrl-single,pins = <0x044 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_23_gpio_pin: pinmux_P9_23_gpio_pin { + pinctrl-single,pins = <0x044 0x2F>; }; /* Mode 7, RxActive */ + P9_23_gpio_pu_pin: pinmux_P9_23_gpio_pu_pin { + pinctrl-single,pins = <0x044 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_23_gpio_pd_pin: pinmux_P9_23_gpio_pd_pin { + pinctrl-single,pins = <0x044 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_23_pwm_pin: pinmux_P9_23_pwm_pin { + pinctrl-single,pins = <0x044 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + + /* P9_24 (ZCZ ball D15) */ + P9_24_default_pin: pinmux_P9_24_default_pin { + pinctrl-single,pins = <0x184 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_24_gpio_pin: pinmux_P9_24_gpio_pin { + pinctrl-single,pins = <0x184 0x2F>; }; /* Mode 7, RxActive */ + P9_24_gpio_pu_pin: pinmux_P9_24_gpio_pu_pin { + pinctrl-single,pins = <0x184 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_24_gpio_pd_pin: pinmux_P9_24_gpio_pd_pin { + pinctrl-single,pins = <0x184 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_24_uart_pin: pinmux_P9_24_uart_pin { + pinctrl-single,pins = <0x184 0x30>; }; /* Mode 0, Pull-Up, RxActive */ + P9_24_can_pin: pinmux_P9_24_can_pin { + pinctrl-single,pins = <0x184 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + P9_24_i2c_pin: pinmux_P9_24_i2c_pin { + pinctrl-single,pins = <0x184 0x33>; }; /* Mode 3, Pull-Up, RxActive */ + P9_24_pru_uart_pin: pinmux_P9_24_pru_uart_pin { + pinctrl-single,pins = <0x184 0x35>; }; /* Mode 5, Pull-Up, RxActive */ + P9_24_pruin_pin: pinmux_P9_24_pruin_pin { + pinctrl-single,pins = <0x184 0x36>; }; /* Mode 6, Pull-Up, RxActive */ + + /* P9_25 (ZCZ ball A14) Audio */ + + /* P9_26 (ZCZ ball D16) */ + P9_26_default_pin: pinmux_P9_26_default_pin { + pinctrl-single,pins = <0x180 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_26_gpio_pin: pinmux_P9_26_gpio_pin { + pinctrl-single,pins = <0x180 0x2F>; }; /* Mode 7, RxActive */ + P9_26_gpio_pu_pin: pinmux_P9_26_gpio_pu_pin { + pinctrl-single,pins = <0x180 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_26_gpio_pd_pin: pinmux_P9_26_gpio_pd_pin { + pinctrl-single,pins = <0x180 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_26_uart_pin: pinmux_P9_26_uart_pin { + pinctrl-single,pins = <0x180 0x30>; }; /* Mode 0, Pull-Up, RxActive */ + P9_26_can_pin: pinmux_P9_26_can_pin { + pinctrl-single,pins = <0x180 0x32>; }; /* Mode 2, Pull-Up, RxActive */ + P9_26_i2c_pin: pinmux_P9_26_i2c_pin { + pinctrl-single,pins = <0x180 0x33>; }; /* Mode 3, Pull-Up, RxActive */ + P9_26_pru_uart_pin: pinmux_P9_26_pru_uart_pin { + pinctrl-single,pins = <0x180 0x35>; }; /* Mode 5, Pull-Up, RxActive */ + P9_26_pruin_pin: pinmux_P9_26_pruin_pin { + pinctrl-single,pins = <0x180 0x36>; }; /* Mode 6, Pull-Up, RxActive */ + + /* P9_27 (ZCZ ball C13) */ + P9_27_default_pin: pinmux_P9_27_default_pin { + pinctrl-single,pins = <0x1a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_27_gpio_pin: pinmux_P9_27_gpio_pin { + pinctrl-single,pins = <0x1a4 0x2F>; }; /* Mode 7, RxActive */ + P9_27_gpio_pu_pin: pinmux_P9_27_gpio_pu_pin { + pinctrl-single,pins = <0x1a4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_27_gpio_pd_pin: pinmux_P9_27_gpio_pd_pin { + pinctrl-single,pins = <0x1a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_27_qep_pin: pinmux_P9_27_qep_pin { + pinctrl-single,pins = <0x1a4 0x21>; }; /* Mode 1, Pull-Down, RxActive */ + P9_27_pruout_pin: pinmux_P9_27_pruout_pin { + pinctrl-single,pins = <0x1a4 0x25>; }; /* Mode 5, Pull-Down, RxActive */ + P9_27_pruin_pin: pinmux_P9_27_pruin_pin { + pinctrl-single,pins = <0x1a4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + + /* P9_28 (ZCZ ball C12) Audio */ + /* P9_29 (ZCZ ball B13) Audio */ + + /* P9_30 (ZCZ ball D12) */ + P9_30_default_pin: pinmux_P9_30_default_pin { + pinctrl-single,pins = <0x198 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_30_gpio_pin: pinmux_P9_30_gpio_pin { + pinctrl-single,pins = <0x198 0x2F>; }; /* Mode 7, RxActive */ + P9_30_gpio_pu_pin: pinmux_P9_30_gpio_pu_pin { + pinctrl-single,pins = <0x198 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_30_gpio_pd_pin: pinmux_P9_30_gpio_pd_pin { + pinctrl-single,pins = <0x198 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_30_pwm_pin: pinmux_P9_30_pwm_pin { + pinctrl-single,pins = <0x198 0x21>; }; /* Mode 1, Pull-Down, RxActive */ + P9_30_spi_pin: pinmux_P9_30_spi_pin { + pinctrl-single,pins = <0x198 0x23>; }; /* Mode 3, Pull-Down, RxActive */ + P9_30_pruout_pin: pinmux_P9_30_pruout_pin { + pinctrl-single,pins = <0x198 0x25>; }; /* Mode 5, Pull-Down, RxActive */ + P9_30_pruin_pin: pinmux_P9_30_pruin_pin { + pinctrl-single,pins = <0x198 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + + /* P9_31 (ZCZ ball A13) Audio */ + + /* P9_32 VADC */ + /* P9_33 (ZCZ ball C8 ) AIN4 */ + /* P9_34 AGND */ + /* P9_35 (ZCZ ball A8 ) AIN6 */ + /* P9_36 (ZCZ ball B8 ) AIN5 */ + /* P9_37 (ZCZ ball B7 ) AIN2 */ + /* P9_38 (ZCZ ball A7 ) AIN3 */ + /* P9_39 (ZCZ ball B6 ) AIN0 */ + /* P9_40 (ZCZ ball C7 ) AIN1 */ + + /* P9_41 (ZCZ ball D14) */ + P9_41_default_pin: pinmux_P9_41_default_pin { + pinctrl-single,pins = <0x1b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_41_gpio_pin: pinmux_P9_41_gpio_pin { + pinctrl-single,pins = <0x1b4 0x2F>; }; /* Mode 7, RxActive */ + P9_41_gpio_pu_pin: pinmux_P9_41_gpio_pu_pin { + pinctrl-single,pins = <0x1b4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_41_gpio_pd_pin: pinmux_P9_41_gpio_pd_pin { + pinctrl-single,pins = <0x1b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_41_timer_pin: pinmux_P9_41_timer_pin { + pinctrl-single,pins = <0x1b4 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + P9_41_pruin_pin: pinmux_P9_41_pruin_pin { + pinctrl-single,pins = <0x1b4 0x25>; }; /* Mode 5, Pull-Down, RxActive */ + + /* P9_41.1 */ + /* P9_91 (ZCZ ball D13) */ + P9_91_default_pin: pinmux_P9_91_default_pin { + pinctrl-single,pins = <0x1a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_91_gpio_pin: pinmux_P9_91_gpio_pin { + pinctrl-single,pins = <0x1a8 0x2F>; }; /* Mode 7, RxActive */ + P9_91_gpio_pu_pin: pinmux_P9_91_gpio_pu_pin { + pinctrl-single,pins = <0x1a8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_91_gpio_pd_pin: pinmux_P9_91_gpio_pd_pin { + pinctrl-single,pins = <0x1a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_91_qep_pin: pinmux_P9_91_qep_pin { + pinctrl-single,pins = <0x1a8 0x21>; }; /* Mode 1, Pull-Down, RxActive */ + P9_91_pruout_pin: pinmux_P9_91_pruout_pin { + pinctrl-single,pins = <0x1a8 0x25>; }; /* Mode 5, Pull-Down, RxActive */ + P9_91_pruin_pin: pinmux_P9_91_pruin_pin { + pinctrl-single,pins = <0x1a8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + + /* P9_42 (ZCZ ball C18) */ + P9_42_default_pin: pinmux_P9_42_default_pin { + pinctrl-single,pins = <0x164 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_42_gpio_pin: pinmux_P9_42_gpio_pin { + pinctrl-single,pins = <0x164 0x2F>; }; /* Mode 7, RxActive */ + P9_42_gpio_pu_pin: pinmux_P9_42_gpio_pu_pin { + pinctrl-single,pins = <0x164 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_42_gpio_pd_pin: pinmux_P9_42_gpio_pd_pin { + pinctrl-single,pins = <0x164 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_42_pwm_pin: pinmux_P9_42_pwm_pin { + pinctrl-single,pins = <0x164 0x20>; }; /* Mode 0, Pull-Down, RxActive */ + P9_42_uart_pin: pinmux_P9_42_uart_pin { + pinctrl-single,pins = <0x164 0x21>; }; /* Mode 1, Pull-Down, RxActive */ + P9_42_spics_pin: pinmux_P9_42_spics_pin { + pinctrl-single,pins = <0x164 0x22>; }; /* Mode 2, Pull-Down, RxActive */ + P9_42_pru_ecap_pin: pinmux_P9_42_pru_ecap_pin { + pinctrl-single,pins = <0x164 0x23>; }; /* Mode 3, Pull-Down, RxActive */ + P9_42_spiclk_pin: pinmux_P9_42_spiclk_pin { + pinctrl-single,pins = <0x164 0x24>; }; /* Mode 4, Pull-Down, RxActive */ + + /* P9_42.1 */ + /* P9_92 (ZCZ ball B12) */ + P9_92_default_pin: pinmux_P9_92_default_pin { + pinctrl-single,pins = <0x1a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_92_gpio_pin: pinmux_P9_92_gpio_pin { + pinctrl-single,pins = <0x1a0 0x2F>; }; /* Mode 7, RxActive */ + P9_92_gpio_pu_pin: pinmux_P9_92_gpio_pu_pin { + pinctrl-single,pins = <0x1a0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ + P9_92_gpio_pd_pin: pinmux_P9_92_gpio_pd_pin { + pinctrl-single,pins = <0x1a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ + P9_92_qep_pin: pinmux_P9_92_qep_pin { + pinctrl-single,pins = <0x1a0 0x21>; }; /* Mode 1, Pull-Down, RxActive */ + P9_92_pruout_pin: pinmux_P9_92_pruout_pin { + pinctrl-single,pins = <0x1a0 0x25>; }; /* Mode 5, Pull-Down, RxActive */ + P9_92_pruin_pin: pinmux_P9_92_pruin_pin { + pinctrl-single,pins = <0x1a0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ + + /* P9_43 GND */ + /* P9_44 GND */ + /* P9_45 GND */ + /* P9_46 GND */ + + }; + }; + + + /************************/ + /* Pin Multiplexing */ + /************************/ + + fragment@1 { + target = <&ocp>; + __overlay__ { + + /************************/ + /* P8 Header */ + /************************/ + + P8_07_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; + pinctrl-0 = <&P8_07_default_pin>; + pinctrl-1 = <&P8_07_gpio_pin>; + pinctrl-2 = <&P8_07_gpio_pu_pin>; + pinctrl-3 = <&P8_07_gpio_pd_pin>; + pinctrl-4 = <&P8_07_timer_pin>; + }; + + P8_08_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; + pinctrl-0 = <&P8_08_default_pin>; + pinctrl-1 = <&P8_08_gpio_pin>; + pinctrl-2 = <&P8_08_gpio_pu_pin>; + pinctrl-3 = <&P8_08_gpio_pd_pin>; + pinctrl-4 = <&P8_08_timer_pin>; + }; + + P8_09_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; + pinctrl-0 = <&P8_09_default_pin>; + pinctrl-1 = <&P8_09_gpio_pin>; + pinctrl-2 = <&P8_09_gpio_pu_pin>; + pinctrl-3 = <&P8_09_gpio_pd_pin>; + pinctrl-4 = <&P8_09_timer_pin>; + }; + + P8_10_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; + pinctrl-0 = <&P8_10_default_pin>; + pinctrl-1 = <&P8_10_gpio_pin>; + pinctrl-2 = <&P8_10_gpio_pu_pin>; + pinctrl-3 = <&P8_10_gpio_pd_pin>; + pinctrl-4 = <&P8_10_timer_pin>; + }; + + P8_11_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "qep"; + pinctrl-0 = <&P8_11_default_pin>; + pinctrl-1 = <&P8_11_gpio_pin>; + pinctrl-2 = <&P8_11_gpio_pu_pin>; + pinctrl-3 = <&P8_11_gpio_pd_pin>; + pinctrl-4 = <&P8_11_pruout_pin>; + pinctrl-5 = <&P8_11_qep_pin>; + }; + + P8_12_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "qep"; + pinctrl-0 = <&P8_12_default_pin>; + pinctrl-1 = <&P8_12_gpio_pin>; + pinctrl-2 = <&P8_12_gpio_pu_pin>; + pinctrl-3 = <&P8_12_gpio_pd_pin>; + pinctrl-4 = <&P8_12_pruout_pin>; + pinctrl-5 = <&P8_12_qep_pin>; + }; + + P8_13_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; + pinctrl-0 = <&P8_13_default_pin>; + pinctrl-1 = <&P8_13_gpio_pin>; + pinctrl-2 = <&P8_13_gpio_pu_pin>; + pinctrl-3 = <&P8_13_gpio_pd_pin>; + pinctrl-4 = <&P8_13_pwm_pin>; + }; + + P8_14_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; + pinctrl-0 = <&P8_14_default_pin>; + pinctrl-1 = <&P8_14_gpio_pin>; + pinctrl-2 = <&P8_14_gpio_pu_pin>; + pinctrl-3 = <&P8_14_gpio_pd_pin>; + pinctrl-4 = <&P8_14_pwm_pin>; + }; + + P8_15_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruin", "pru_ecap", "qep"; + pinctrl-0 = <&P8_15_default_pin>; + pinctrl-1 = <&P8_15_gpio_pin>; + pinctrl-2 = <&P8_15_gpio_pu_pin>; + pinctrl-3 = <&P8_15_gpio_pd_pin>; + pinctrl-4 = <&P8_15_pruin_pin>; + pinctrl-5 = <&P8_15_pru_ecap_pin>; + pinctrl-6 = <&P8_15_qep_pin>; + }; + + P8_16_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruin", "qep"; + pinctrl-0 = <&P8_16_default_pin>; + pinctrl-1 = <&P8_16_gpio_pin>; + pinctrl-2 = <&P8_16_gpio_pu_pin>; + pinctrl-3 = <&P8_16_gpio_pd_pin>; + pinctrl-4 = <&P8_16_pruin_pin>; + pinctrl-5 = <&P8_16_qep_pin>; + }; + + P8_17_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; + pinctrl-0 = <&P8_17_default_pin>; + pinctrl-1 = <&P8_17_gpio_pin>; + pinctrl-2 = <&P8_17_gpio_pu_pin>; + pinctrl-3 = <&P8_17_gpio_pd_pin>; + pinctrl-4 = <&P8_17_pwm_pin>; + }; + + P8_18_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; + pinctrl-0 = <&P8_18_default_pin>; + pinctrl-1 = <&P8_18_gpio_pin>; + pinctrl-2 = <&P8_18_gpio_pu_pin>; + pinctrl-3 = <&P8_18_gpio_pd_pin>; + }; + + P8_19_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; + pinctrl-0 = <&P8_19_default_pin>; + pinctrl-1 = <&P8_19_gpio_pin>; + pinctrl-2 = <&P8_19_gpio_pu_pin>; + pinctrl-3 = <&P8_19_gpio_pd_pin>; + pinctrl-4 = <&P8_19_pwm_pin>; + }; + + P8_26_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; + pinctrl-0 = <&P8_26_default_pin>; + pinctrl-1 = <&P8_26_gpio_pin>; + pinctrl-2 = <&P8_26_gpio_pu_pin>; + pinctrl-3 = <&P8_26_gpio_pd_pin>; + }; + + + /************************/ + /* P9 Header */ + /************************/ + + P9_11_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart"; + pinctrl-0 = <&P9_11_default_pin>; + pinctrl-1 = <&P9_11_gpio_pin>; + pinctrl-2 = <&P9_11_gpio_pu_pin>; + pinctrl-3 = <&P9_11_gpio_pd_pin>; + pinctrl-4 = <&P9_11_uart_pin>; + }; + + P9_12_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; + pinctrl-0 = <&P9_12_default_pin>; + pinctrl-1 = <&P9_12_gpio_pin>; + pinctrl-2 = <&P9_12_gpio_pu_pin>; + pinctrl-3 = <&P9_12_gpio_pd_pin>; + }; + + P9_13_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart"; + pinctrl-0 = <&P9_13_default_pin>; + pinctrl-1 = <&P9_13_gpio_pin>; + pinctrl-2 = <&P9_13_gpio_pu_pin>; + pinctrl-3 = <&P9_13_gpio_pd_pin>; + pinctrl-4 = <&P9_13_uart_pin>; + }; + + P9_14_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; + pinctrl-0 = <&P9_14_default_pin>; + pinctrl-1 = <&P9_14_gpio_pin>; + pinctrl-2 = <&P9_14_gpio_pu_pin>; + pinctrl-3 = <&P9_14_gpio_pd_pin>; + pinctrl-4 = <&P9_14_pwm_pin>; + }; + + P9_15_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; + pinctrl-0 = <&P9_15_default_pin>; + pinctrl-1 = <&P9_15_gpio_pin>; + pinctrl-2 = <&P9_15_gpio_pu_pin>; + pinctrl-3 = <&P9_15_gpio_pd_pin>; + pinctrl-4 = <&P9_15_pwm_pin>; + }; + + P9_16_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; + pinctrl-0 = <&P9_16_default_pin>; + pinctrl-1 = <&P9_16_gpio_pin>; + pinctrl-2 = <&P9_16_gpio_pu_pin>; + pinctrl-3 = <&P9_16_gpio_pd_pin>; + pinctrl-4 = <&P9_16_pwm_pin>; + }; + + P9_17_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm", "pru_uart"; + pinctrl-0 = <&P9_17_default_pin>; + pinctrl-1 = <&P9_17_gpio_pin>; + pinctrl-2 = <&P9_17_gpio_pu_pin>; + pinctrl-3 = <&P9_17_gpio_pd_pin>; + pinctrl-4 = <&P9_17_spi_pin>; + pinctrl-5 = <&P9_17_i2c_pin>; + pinctrl-6 = <&P9_17_pwm_pin>; + pinctrl-7 = <&P9_17_pru_uart_pin>; + }; + + P9_18_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm", "pru_uart"; + pinctrl-0 = <&P9_18_default_pin>; + pinctrl-1 = <&P9_18_gpio_pin>; + pinctrl-2 = <&P9_18_gpio_pu_pin>; + pinctrl-3 = <&P9_18_gpio_pd_pin>; + pinctrl-4 = <&P9_18_spi_pin>; + pinctrl-5 = <&P9_18_i2c_pin>; + pinctrl-6 = <&P9_18_pwm_pin>; + pinctrl-7 = <&P9_18_pru_uart_pin>; + }; + + // I2C Pins + // P9_19_pinmux + // P9_20_pinmux + + P9_21_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm", "pru_uart"; + pinctrl-0 = <&P9_21_default_pin>; + pinctrl-1 = <&P9_21_gpio_pin>; + pinctrl-2 = <&P9_21_gpio_pu_pin>; + pinctrl-3 = <&P9_21_gpio_pd_pin>; + pinctrl-4 = <&P9_21_spi_pin>; + pinctrl-5 = <&P9_21_uart_pin>; + pinctrl-6 = <&P9_21_i2c_pin>; + pinctrl-7 = <&P9_21_pwm_pin>; + pinctrl-8 = <&P9_21_pru_uart_pin>; + }; + + P9_22_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm", "pru_uart"; + pinctrl-0 = <&P9_22_default_pin>; + pinctrl-1 = <&P9_22_gpio_pin>; + pinctrl-2 = <&P9_22_gpio_pu_pin>; + pinctrl-3 = <&P9_22_gpio_pd_pin>; + pinctrl-4 = <&P9_22_spi_pin>; + pinctrl-5 = <&P9_22_uart_pin>; + pinctrl-6 = <&P9_22_i2c_pin>; + pinctrl-7 = <&P9_22_pwm_pin>; + pinctrl-8 = <&P9_22_pru_uart_pin>; + }; + + P9_23_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; + pinctrl-0 = <&P9_23_default_pin>; + pinctrl-1 = <&P9_23_gpio_pin>; + pinctrl-2 = <&P9_23_gpio_pu_pin>; + pinctrl-3 = <&P9_23_gpio_pd_pin>; + pinctrl-4 = <&P9_23_pwm_pin>; + }; + + P9_24_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pru_uart", "pruin"; + pinctrl-0 = <&P9_24_default_pin>; + pinctrl-1 = <&P9_24_gpio_pin>; + pinctrl-2 = <&P9_24_gpio_pu_pin>; + pinctrl-3 = <&P9_24_gpio_pd_pin>; + pinctrl-4 = <&P9_24_uart_pin>; + pinctrl-5 = <&P9_24_can_pin>; + pinctrl-6 = <&P9_24_i2c_pin>; + pinctrl-7 = <&P9_24_pru_uart_pin>; + pinctrl-8 = <&P9_24_pruin_pin>; + }; + + + // Audio pin + // P9_25_pinmux + + P9_26_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pru_uart", "pruin"; + pinctrl-0 = <&P9_26_default_pin>; + pinctrl-1 = <&P9_26_gpio_pin>; + pinctrl-2 = <&P9_26_gpio_pu_pin>; + pinctrl-3 = <&P9_26_gpio_pd_pin>; + pinctrl-4 = <&P9_26_uart_pin>; + pinctrl-5 = <&P9_26_can_pin>; + pinctrl-6 = <&P9_26_i2c_pin>; + pinctrl-7 = <&P9_26_pru_uart_pin>; + pinctrl-8 = <&P9_26_pruin_pin>; + }; + + P9_27_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; + pinctrl-0 = <&P9_27_default_pin>; + pinctrl-1 = <&P9_27_gpio_pin>; + pinctrl-2 = <&P9_27_gpio_pu_pin>; + pinctrl-3 = <&P9_27_gpio_pd_pin>; + pinctrl-4 = <&P9_27_qep_pin>; + pinctrl-5 = <&P9_27_pruout_pin>; + pinctrl-6 = <&P9_27_pruin_pin>; + }; + + // Audio pins + // P9_28_pinmux + // P9_29_pinmux + + P9_30_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; + pinctrl-0 = <&P9_30_default_pin>; + pinctrl-1 = <&P9_30_gpio_pin>; + pinctrl-2 = <&P9_30_gpio_pu_pin>; + pinctrl-3 = <&P9_30_gpio_pd_pin>; + pinctrl-4 = <&P9_30_pwm_pin>; + pinctrl-5 = <&P9_30_spi_pin>; + pinctrl-6 = <&P9_30_pruout_pin>; + pinctrl-7 = <&P9_30_pruin_pin>; + }; + + // Audio pin + // P9_31_pinmux + + P9_41_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer", "pruin"; + pinctrl-0 = <&P9_41_default_pin>; + pinctrl-1 = <&P9_41_gpio_pin>; + pinctrl-2 = <&P9_41_gpio_pu_pin>; + pinctrl-3 = <&P9_41_gpio_pd_pin>; + pinctrl-4 = <&P9_41_timer_pin>; + pinctrl-5 = <&P9_41_pruin_pin>; + }; + + P9_91_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; + pinctrl-0 = <&P9_91_default_pin>; + pinctrl-1 = <&P9_91_gpio_pin>; + pinctrl-2 = <&P9_91_gpio_pu_pin>; + pinctrl-3 = <&P9_91_gpio_pd_pin>; + pinctrl-4 = <&P9_91_qep_pin>; + pinctrl-5 = <&P9_91_pruout_pin>; + pinctrl-6 = <&P9_91_pruin_pin>; + }; + + P9_42_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "uart", "spics", "pru_ecap", "spiclk"; + pinctrl-0 = <&P9_42_default_pin>; + pinctrl-1 = <&P9_42_gpio_pin>; + pinctrl-2 = <&P9_42_gpio_pu_pin>; + pinctrl-3 = <&P9_42_gpio_pd_pin>; + pinctrl-4 = <&P9_42_pwm_pin>; + pinctrl-5 = <&P9_42_uart_pin>; + pinctrl-6 = <&P9_42_spics_pin>; + pinctrl-7 = <&P9_42_pru_ecap_pin>; + pinctrl-8 = <&P9_42_spiclk_pin>; + }; + + P9_92_pinmux { + compatible = "bone-pinmux-helper"; + status = "okay"; + pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; + pinctrl-0 = <&P9_92_default_pin>; + pinctrl-1 = <&P9_92_gpio_pin>; + pinctrl-2 = <&P9_92_gpio_pu_pin>; + pinctrl-3 = <&P9_92_gpio_pd_pin>; + pinctrl-4 = <&P9_92_qep_pin>; + pinctrl-5 = <&P9_92_pruout_pin>; + pinctrl-6 = <&P9_92_pruin_pin>; + }; + }; + }; + + fragment@2 { + target = <&ocp>; + __overlay__ { + + // !!!WARNING!!! + // gpio-of-helper &gpio pointers are off-by-one vs. the hardware: + // hardware GPIO bank 0 = &gpio1 + cape-universal { + compatible = "gpio-of-helper"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + + P8_07 { + gpio-name = "P8_07"; + gpio = <&gpio3 2 0>; + input; + dir-changeable; + }; + P8_08 { + gpio-name = "P8_08"; + gpio = <&gpio3 3 0>; + input; + dir-changeable; + }; + P8_09 { + gpio-name = "P8_09"; + gpio = <&gpio3 5 0>; + input; + dir-changeable; + }; + P8_10 { + gpio-name = "P8_10"; + gpio = <&gpio3 4 0>; + input; + dir-changeable; + }; + P8_11 { + gpio-name = "P8_11"; + gpio = <&gpio2 13 0>; + input; + dir-changeable; + }; + P8_12 { + gpio-name = "P8_12"; + gpio = <&gpio2 12 0>; + input; + dir-changeable; + }; + P8_13 { + gpio-name = "P8_13"; + gpio = <&gpio1 23 0>; + input; + dir-changeable; + }; + P8_14 { + gpio-name = "P8_14"; + gpio = <&gpio1 26 0>; + input; + dir-changeable; + }; + P8_15 { + gpio-name = "P8_15"; + gpio = <&gpio2 15 0>; + input; + dir-changeable; + }; + P8_16 { + gpio-name = "P8_16"; + gpio = <&gpio2 14 0>; + input; + dir-changeable; + }; + P8_17 { + gpio-name = "P8_17"; + gpio = <&gpio1 27 0>; + input; + dir-changeable; + }; + P8_18 { + gpio-name = "P8_18"; + gpio = <&gpio3 1 0>; + input; + dir-changeable; + }; + P8_19 { + gpio-name = "P8_19"; + gpio = <&gpio1 22 0>; + input; + dir-changeable; + }; + P8_26 { + gpio-name = "P8_26"; + gpio = <&gpio2 29 0>; + input; + dir-changeable; + }; + + + P9_11 { + gpio-name = "P9_11"; + gpio = <&gpio1 30 0>; + input; + dir-changeable; + }; + P9_12 { + gpio-name = "P9_12"; + gpio = <&gpio2 28 0>; + input; + dir-changeable; + }; + P9_13 { + gpio-name = "P9_13"; + gpio = <&gpio1 31 0>; + input; + dir-changeable; + }; + P9_14 { + gpio-name = "P9_14"; + gpio = <&gpio2 18 0>; + input; + dir-changeable; + }; + P9_15 { + gpio-name = "P9_15"; + gpio = <&gpio2 16 0>; + input; + dir-changeable; + }; + P9_16 { + gpio-name = "P9_16"; + gpio = <&gpio2 19 0>; + input; + dir-changeable; + }; + P9_17 { + gpio-name = "P9_17"; + gpio = <&gpio1 5 0>; + input; + dir-changeable; + }; + P9_18 { + gpio-name = "P9_18"; + gpio = <&gpio1 4 0>; + input; + dir-changeable; + }; + + // I2C pins + // P9_19 + // P9_20 + + P9_21 { + gpio-name = "P9_21"; + gpio = <&gpio1 3 0>; + input; + dir-changeable; + }; + P9_22 { + gpio-name = "P9_22"; + gpio = <&gpio1 2 0>; + input; + dir-changeable; + }; + P9_23 { + gpio-name = "P9_23"; + gpio = <&gpio2 17 0>; + input; + dir-changeable; + }; + P9_24 { + gpio-name = "P9_24"; + gpio = <&gpio1 15 0>; + input; + dir-changeable; + }; + + // Audio pin + // P9_25 + + P9_26 { + gpio-name = "P9_26"; + gpio = <&gpio1 14 0>; + input; + dir-changeable; + }; + P9_27 { + gpio-name = "P9_27"; + gpio = <&gpio4 19 0>; + input; + dir-changeable; + }; + + // Audio pins + // P9_28 + // P9_29 + + P9_30 { + gpio-name = "P9_30"; + gpio = <&gpio4 16 0>; + input; + dir-changeable; + }; + + // Audio pin + // P9_31 + + P9_41 { + gpio-name = "P9_41"; + gpio = <&gpio1 20 0>; + input; + dir-changeable; + }; + P9_91 { + gpio-name = "P9_91"; + gpio = <&gpio4 20 0>; + input; + dir-changeable; + }; + P9_42 { + gpio-name = "P9_42"; + gpio = <&gpio1 7 0>; + input; + dir-changeable; + }; + P9_92 { + gpio-name = "P9_92"; + gpio = <&gpio4 18 0>; + input; + dir-changeable; + }; + }; + }; + }; + + + + /************************/ + /* UARTs */ + /************************/ + + fragment@10 { + target = <&uart2>; /* really uart1 */ + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + fragment@11 { + target = <&uart3>; /* really uart2 */ + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + fragment@12 { + target = <&uart5>; /* really uart4 */ + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + +// /* UART 5 only available on LCD/HDMI pins */ +// fragment@13 { +// target = <&uart6>; /* really uart5 */ +// __overlay__ { +// status = "okay"; +// pinctrl-names = "default"; +// pinctrl-0 = <>; +// }; +// }; + + /************************/ + /* Timers / PWM */ + /************************/ + + fragment@20 { + target = <&epwmss0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@21 { + target = <&ehrpwm0>; + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + fragment@22 { + target = <&ecap0>; + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + fragment@23 { + target = <&epwmss1>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@24 { + target = <&ehrpwm1>; + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + fragment@25 { + target = <&epwmss2>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@26 { + target = <&ehrpwm2>; + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + fragment@27 { + target = <&ecap2>; + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + /************************/ + /* I2C / SPI */ + /************************/ + + + fragment@30 { + target = <&i2c1>; /* i2c1 is numbered correctly */ + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + + /* this is the configuration part */ + clock-frequency = <100000>; + + #address-cells = <1>; + #size-cells = <0>; + + /* add any i2c devices on the bus here */ + + // commented out example of a touchscreen (taken from BB-BONE-LCD7-01-00A4) */ + // maxtouch@4a { + // compatible = "mXT224"; + // reg = <0x4a>; + // interrupt-parent = <&gpio4>; + // interrupts = <19 0x0>; + // atmel,irq-gpio = <&gpio4 19 0>; + // }; + }; + }; + + fragment@31 { + target = <&spi0>; /* spi0 is numbered correctly */ + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + + spi0channel@0 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "spidev"; + + reg = <0>; + spi-max-frequency = <16000000>; + spi-cpha; + }; + + + spi0channel@1 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "spidev"; + + reg = <1>; + spi-max-frequency = <16000000>; + }; + }; + }; + + fragment@32 { + target = <&spi1>; /* spi1 is numbered correctly */ + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + + #address-cells = <1>; + #size-cells = <0>; + + spi1channel@0 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "spidev"; + + reg = <0>; + spi-max-frequency = <16000000>; + spi-cpha; + }; + + spi1channel@1 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "spidev"; + + reg = <1>; + spi-max-frequency = <16000000>; + }; + }; + }; + + fragment@33 { + target = <&dcan0>; + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + fragment@34 { + target = <&dcan1>; + __overlay__ { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + }; + + + /************************/ + /* PRUSS */ + /************************/ + + fragment@40 { + target = <&pruss>; + __overlay__ { + status = "okay"; + }; + }; + + + /************************/ + /* eQEP */ + /************************/ + + fragment@50 { + target = <&eqep0>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <>; + + count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ + swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ + invert_qa = <1>; /* Should we invert the channel A input? */ + invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ + invert_qi = <0>; /* Should we invert the index input? */ + invert_qs = <0>; /* Should we invert the strobe input? */ + + status = "okay"; + }; + }; + + fragment@51 { + target = <&eqep1>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <>; + + count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ + swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ + invert_qa = <1>; /* Should we invert the channel A input? */ + invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ + invert_qi = <0>; /* Should we invert the index input? */ + invert_qs = <0>; /* Should we invert the strobe input? */ + + status = "okay"; + }; + }; + + fragment@52 { + target = <&eqep2>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <>; + + count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ + swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ + invert_qa = <1>; /* Should we invert the channel A input? */ + invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ + invert_qi = <0>; /* Should we invert the index input? */ + invert_qs = <0>; /* Should we invert the strobe input? */ + + status = "okay"; + }; + }; +}; From 4448a3e5231e81d7f48ef2af778b91abffdc8306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Tue, 11 Dec 2018 10:43:53 +0100 Subject: [PATCH 05/47] Added a readme file for setting up the device tree overlay. --- util/device_tree_overlay/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 util/device_tree_overlay/README.md diff --git a/util/device_tree_overlay/README.md b/util/device_tree_overlay/README.md new file mode 100644 index 0000000..e69de29 From cbb9e0b3f9559eddf0d08867910f93dc982d9974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Tue, 11 Dec 2018 11:33:12 +0100 Subject: [PATCH 06/47] Added instructions on how to load a device tree overlay --- util/device_tree_overlay/README.md | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/util/device_tree_overlay/README.md b/util/device_tree_overlay/README.md index e69de29..ffdde3e 100644 --- a/util/device_tree_overlay/README.md +++ b/util/device_tree_overlay/README.md @@ -0,0 +1,48 @@ +# Instructions on compiling and loading a device tree overlay +The BeagleBone Black (BBB) uses device tree overlays (DTOs) to specify the operation and +default settings of the pins. You can read more about using DTOs +for the BBB [here](https://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/overview). +Here we give instructions on how to compile and load the overlay `cape-universallc` +found in this folder. All commands in the instructions are performed on the BBB. + +First, make sure to have a copy of the file `cape-universallc-00A0.dts` in the folder `/lib/firmware` +on the BBB: +```shell +cp cape-universallc-00A0.dts /lib/firmware +``` +Then we use the device tree compiler (dtc) to compile the human readable +`.dts`-file into a `.dtbo`-file usable by the Linux kernel: +```shell +cd /lib/firmware +dtc -0 dtb -o cape-universallc-00A0.dtbo -b 0 -@ cape-universallc-00A0.dts +``` +Now we have a new file `cape-universallc-00A0.dtbo` in `/lib/firmware/`. To load +the new DTO, we send it to the slots-file of the BBB: +```shell +echo cape-universallc > /sys/devices/bone_capemgr.*/slots +``` +Note that the extension `-00A0.dtbo` is omitted in the command above. To check +that the overlay has been loaded properly we can check the slots file: +```shell +cat /sys/devices/bone_capemgr.*/slots +``` +which should give the following printout: +```shell + 0: 54:PF--- + 1: 55:PF--- + 2: 56:PF--- + 3: 57:PF--- + 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G + 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI + 8: ff:P-O-L Override Board Name,00A0,Override Manuf,cape-universallc +``` +Here the overlays in slots 4 and 5 are related to the eMMC and HDMI, while the +new overlay `cape-universallc` is loaded to slot 8. Now the behaviour of the BBBs +pins is properly defined, and you can start using the framework of `LabConnections.BeagleBone`. + +### Note about `cape-universallc` +The DTO `cape-universallc` is essentially identical to the standard DTO +`cape-universaln` found [here](https://github.com/cdsteinkuehler/beaglebone-universal-io) +which exports all pins except for those used by the HDMI and eMMC. However, there +is a bug in the default version of `cape-universaln` found on the BBB (described [here](https://github.com/cdsteinkuehler/beaglebone-universal-io/issues/21)), +which prevents it from loading properly. This bug has been taken care of in `cape-universallc`. \ No newline at end of file From cb6179173ee61b4ff57c8e5f6e19b33dc8b42ea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20F=C3=A4lt?= Date: Thu, 20 Dec 2018 14:50:17 +0100 Subject: [PATCH 07/47] Fixed sysled bug --- Examples/testLED.jl | 15 ++++++++------- src/BeagleBone/BeagleBone.jl | 25 ++++++++++++++++++------- src/BeagleBone/SysLED.jl | 5 +++++ src/Computer/BeagleBoneStream.jl | 14 ++++++++++---- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/Examples/testLED.jl b/Examples/testLED.jl index d61d0e7..116f15b 100644 --- a/Examples/testLED.jl +++ b/Examples/testLED.jl @@ -27,24 +27,25 @@ for i = 1:100 get(led1) get(led2) get(led3) - #sleep(0.1) - v1,v2,v3 = read(stream) #Sends request to read, reads all inputs for which get! was called - v1 == !v2 == v3 == ledon ? nothing : println("ledon is $ledon, but read v1, v2, v3 = $v1, $v2, $v3") + sleep(0.1) + v1,v2,v3 = .==(read(stream), "1") #Sends request to read, reads all inputs for which get! was called + v1 == !v2 == v3 == ledon ? nothing : println("ledon is $ledon, but read v1, v2, v3 = $v1, $v2, $v3") ledon = !ledon end for i = 1:40 + global ledon send(led1, ledon) #sleep(0.03) - v1 = read(led1) + v1 = read(led1) == "1" send(led2, ledon) #sleep(0.03) - v2 = read(led2) + v2 = read(led2) == "1" send(led3, ledon) #sleep(0.03) - v3 = read(led3) + v3 = read(led3) == "1" send(led4, ledon) #sleep(0.03) - v4 = read(led4) + v4 = read(led4) == "1" v1 == v2 == v3 == v4 == ledon ? nothing : println("ledon is $ledon, but read v1, v2, v3, v4 = $v1, $v2, $v3, $v4") ledon = !ledon end diff --git a/src/BeagleBone/BeagleBone.jl b/src/BeagleBone/BeagleBone.jl index aca8a1c..1d888ac 100644 --- a/src/BeagleBone/BeagleBone.jl +++ b/src/BeagleBone/BeagleBone.jl @@ -106,24 +106,26 @@ end """ bbparse(l::Tuple, sock) -Parse input on the form `l=(iswrite, ndev, cmd1, cmd2, ..., cmdn)` -where if `iswrite` +Parse input on the form `l=(operation, ndev, cmd1, cmd2, ..., cmdn)` +where if `operation==1` (write) `cmdi = (devname, id, val)` - and if not `iswrite` + and if `operation==0` (read) + `cmdi = (devname, id)` + and if `operation==2` (initialize) `cmdi = (devname, id)` and send back on socket (vals, timestamps). """ function bbparse(l::Tuple, sock) - iswrite = l[1]::Bool #True if write command, false if read + operation = l[1]::Int32 #1 if write command, 0 if read, 2 if init ndev = l[2]::Int32 #Number of devices/commands - if iswrite + if operation == 1 for i = 1:ndev command = l[2+i]::Tuple dev = getdev(command[1], command[2]) write!(dev, command[3]) end return - else + elseif operation == 0 #TODO fix to have at least partial type stability vals = Array{Any,1}(undef,ndev) timestamps = Array{UInt64,1}(undef,ndev) @@ -135,6 +137,14 @@ function bbparse(l::Tuple, sock) end bbsend(sock, (vals, timestamps)) return + elseif operation == 2 + for i = 1:ndev + command = l[2+i]::Tuple + dev = initdev(command[1], command[2]) + end + return + else + error("Unknown operation $operation, cmd: $l") end end @@ -173,7 +183,8 @@ function run_server(port=2001; debug=false) println("Connection to server closed") else println("error: $(typeof(err))") - rethrow() + println("err: $err") + rethrow(err) end end end diff --git a/src/BeagleBone/SysLED.jl b/src/BeagleBone/SysLED.jl index 71680bc..5f06999 100644 --- a/src/BeagleBone/SysLED.jl +++ b/src/BeagleBone/SysLED.jl @@ -31,6 +31,11 @@ function write!(led::SysLED, entry::String, debug::Bool=false) flush(led.filestream) end +# Catch Boolean writes +write!(led::SysLED, entry::Bool, debug::Bool=false) = + write!(led::SysLED, entry ? "1" : "0", debug) + + """ l = read(led::SysLED, debug::Bool=false) Reads the current brightness value from the LED 'SysLED'. diff --git a/src/Computer/BeagleBoneStream.jl b/src/Computer/BeagleBoneStream.jl index d046000..844d721 100644 --- a/src/Computer/BeagleBoneStream.jl +++ b/src/Computer/BeagleBoneStream.jl @@ -21,6 +21,12 @@ function init_devices!(bbstream::BeagleBoneStream, devs::AbstractDevice...) setstream!(dev, bbstream) push!(bbstream.devices, dev) initialize(dev) + # Send to beaglebone 2: initialize, 1 device, (name, index) + # TODO create proper functionality to initialize + readcmd = getreadcommand(bbstream, dev) + name = readcmd[1]::String + idx = readcmd[2]::Integer + serialize(bbstream.stream, (Int32(2), Int32(1), (name, Int32(idx)))) else warn("Device $dev already added to a stream") end @@ -30,14 +36,14 @@ end function send(bbstream::BeagleBoneStream) ncmds = length(bbstream.sendbuffer) - serialize(bbstream.stream, (true, Int32(ncmds), bbstream.sendbuffer...)) + serialize(bbstream.stream, (Int32(1), Int32(ncmds), bbstream.sendbuffer...)) empty!(bbstream.sendbuffer) return end #TODO know the types of outputs some way function read(bbstream::BeagleBoneStream) ncmds = length(bbstream.readbuffer) - serialize(bbstream.stream, (false, Int32(ncmds), bbstream.readbuffer...)) + serialize(bbstream.stream, (Int32(0), Int32(ncmds), bbstream.readbuffer...)) empty!(bbstream.readbuffer) vals, timestamps = deserialize(bbstream.stream) length(vals) == ncmds || error("Wrong number of return values in $vals on request $(bbstream.readbuffer)") @@ -47,13 +53,13 @@ end #The following are for interal use only function send(bbstream::BeagleBoneStream, cmd) - allcmds = (true, Int32(1), cmd) + allcmds = (Int32(1), Int32(1), cmd) println("Sending single command: $allcmds") serialize(bbstream.stream, allcmds) return end function read(bbstream::BeagleBoneStream, cmd) - allcmds = (false, Int32(1), cmd) + allcmds = (Int32(0), Int32(1), cmd) println("Sending single command: $allcmds") serialize(bbstream.stream, allcmds) vals, timestamps = deserialize(bbstream.stream) From db5618e08291f0b16fd44ab1ecdb15d50022dd7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Wed, 10 Apr 2019 18:15:35 +0200 Subject: [PATCH 08/47] Updated flashing instructions in installation.md --- docs/src/man/installation.md | 123 +++++++++++++++++++++++------------ 1 file changed, 80 insertions(+), 43 deletions(-) diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 58798a2..ef4248b 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -1,86 +1,123 @@ + + # Installation Instructions +In these instructions we explain how to set up a working environment on a host computer and +a BeagleBone Black. If you already have a prepared micro-SD card for flashing a BeagleBone, +then you can safely skip the first section of these instructions. -## On the BBB -On the BeagleBone, first flash it with a Debian image for 32 bit ARM processors -(BeagleBoard.org Debian Image 2017-03-19) using a micro-SD by following [this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/). -You may also include a Julia v0.6 tarball, alternatively transferring it -using after an installation. -If using the provided SD card, flash the BB by holding down S2 for about 5 -seconds while connecting the BB to 5V power. Keep the button pressed until the -four system LEDs (D2/D3/D4/D5) start blinking in a periodical sequence. Leave -the BB alone for 15-20 minutes while flashing, until all four lights are turned -off (or on). Power off the BB, remove the SD card, and power it on again. + -Log on to the BB via SSH by +## Preparing a micro-SD card +First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BeagleBone. Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). +Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. +Make sure that the Julia folder has the correct name by typing +``` +`mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' +``` +The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, +you now have a prepared micro-SD card ready for flashing BeagleBones. - `ssh debian@192.168.7.2' +## Flashing a BeagleBone from a prepared micro-SD card +Insert the micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug +in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should +start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, +indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again). -an unpack the tarball. Julia should now be operational by running +## Trying out the BeagleBone +Now your BeagleBone is ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing +``` +`ssh debian@192.168.7.2' +``` +The default password is `temppwd`. You are now logged in to the BeagleBone running Debian. The Julia binary should be located at `/home/debian/julia-/bin/julia`. +You can now start a Julia REPL on the BeagleBone by typing +``` +`/home/debian/julia-/bin/julia' +``` +If this works correctly, then you have a functioning BeagleBone ready for use with the LabConnections.jl package. - `/home/debian/julia-/bin/julia' + -and before leaving the BB, remove the distibution specific tag by renaming +## Setting up the host computer - `mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' -## On the HOST -To get started, first install Julia v0.6.X on the PC running a Linux -distribution by following the instructions specified -[here](https://github.com/JuliaLang/julia/blob/master/README.md). So far, the -system has only been tested on Ubuntu 14.04 and 16.04. +To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified [here](https://github.com/JuliaLang/julia/blob/master/README.md). Once Julia is installed, run +``` +using Pkg +`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)' +``` +in the Julia REPL to install all dependencies on the host computer. The source code is then located in `./julia/v1.0/LabConnections'. -Once Julia is installed, run - `Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)' +If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus' repository which wraps the`linux/spi/spidev'. Simply -in the Julia prompt to install all dependencies on the HOST, the source code -is then located in `./julia/v0.6/LabCOnnections'. -If you plan on working with the SPI devices to debug the ADC/DAC, then you will -need a forked `serbus' repository which wraps the `linux/spi/spidev'. Simply +``` +`cd && cd .julia/v0.6' +`git clone https://github.com/mgreiff/serbus' +``` - `cd && cd .julia/v0.6' - `git clone https://github.com/mgreiff/serbus' to get the latest revision of the serbus fork. + To update the BB with the latest revision of the code, - `cd && cd .julia/v0.6/LabConnection/util' - `./flash_BB.sh' -This scripts bundles the current code in LabCOnnections and serbus on the host -computer and transfers it to the /home/debian/juliapackages directory on the BB. +``` +`cd && cd .julia/v0.6/LabConnection/util' +`./flash_BB.sh' +``` + + +This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB. + + + ## Setting up automatic communication -To setup automatic start of Julia server on the BB, make sure to have completed -all prior installation instructions, and that the lates revision of the -LabConnections package is located on the BB. SSH to the BeagleBone and copy the -julilaserver.service to the systemd/system - `ssh debian@192.168.7.2' - `sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) + +To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system + + +``` +`ssh debian@192.168.7.2' +`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) +``` + Then execute the commands -`sudo systemctl enable juliaserver` (on the BeagleBone) -`sudo systemctl start juliaserver` (on the BeagleBone) + +`sudo systemctl enable juliaserver` (on the BeagleBone) `sudo systemctl start juliaserver` (on the BeagleBone) + After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. + ```@systemConfiguration + ``` + + ## Debugging -No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. -Start julia as root: + +No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root: + + ``` sudo /home/debian/julia/bin/julia ``` + + and run the startup script: + + ``` include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl") ``` + From d93d27afa45567b97d1a4f8c00753c83f6eee5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Wed, 10 Apr 2019 18:16:59 +0200 Subject: [PATCH 09/47] Update installation.md --- docs/src/man/installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index ef4248b..fa8216a 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -18,8 +18,8 @@ Make sure that the Julia folder has the correct name by typing The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing BeagleBones. -## Flashing a BeagleBone from a prepared micro-SD card -Insert the micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug +## Flashing the BeagleBone +Insert a prepared micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again). From 37f5cf7abb1f185f43c12a04283322b943b19b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 12:59:51 +0200 Subject: [PATCH 10/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c43bdc..a3a3e86 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ With this package, the user is able to setup a connection between the host computer and the IO-device, and send and receive control signals and measurements from the lab process. -The full documentation of the package is available [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/master/docs/build/index.md). +The full documentation of the package is available [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/index.md). ## Package Overview The `LabConnections.jl` package is subdivided into two main modules; `Computer` From 8bf1d0dde4750bb0e959b49e09759a1639bb0347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 13:01:36 +0200 Subject: [PATCH 11/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a3a3e86..59b74af 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ information can be found [here](https://gitlab.control.lth.se/labdev/LabConnecti ## Getting Started ### Installation Instructions on installing the required software and setting up a connection between -the host computer and the BBB are found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/master/docs/build/man/installation.md#installation-instructions). +the host computer and the BBB are found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/man/installation.md#installation-instructions). ### A Simple Example We will here go through a simple example of using the host computer interface to communicate with the BBB and control the onboard system LEDs. From f0f9153fe2fd335f9b2447ab8cbe2995e5c00857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 13:32:02 +0200 Subject: [PATCH 12/47] Updated build of docs --- docs/build/assets/Documenter.css | 18 - docs/build/assets/arrow.svg | 63 +++ docs/build/assets/documenter.css | 601 ++++++++++++++++++++++++ docs/build/assets/documenter.js | 132 ++++++ docs/build/assets/mathjaxhelper.js | 25 - docs/build/assets/search.js | 250 ++++++++++ docs/build/examples/examples.md | 117 ----- docs/build/examples/examples/index.html | 2 + docs/build/examples/testing.md | 27 -- docs/build/examples/testing/index.html | 2 + docs/build/index.html | 2 + docs/build/index.md | 66 --- docs/build/lib/functions.md | 294 ------------ docs/build/lib/functions/index.html | 2 + docs/build/lib/io_devices.md | 76 --- docs/build/lib/io_devices/index.html | 4 + docs/build/man/installation.md | 132 ------ docs/build/man/installation/index.html | 6 + docs/build/man/introduction.md | 10 - docs/build/man/introduction/index.html | 2 + docs/build/search/index.html | 2 + docs/build/search_index.js | 3 + docs/make.jl | 2 +- 23 files changed, 1072 insertions(+), 766 deletions(-) delete mode 100644 docs/build/assets/Documenter.css create mode 100644 docs/build/assets/arrow.svg create mode 100644 docs/build/assets/documenter.css create mode 100644 docs/build/assets/documenter.js delete mode 100644 docs/build/assets/mathjaxhelper.js create mode 100644 docs/build/assets/search.js delete mode 100644 docs/build/examples/examples.md create mode 100644 docs/build/examples/examples/index.html delete mode 100644 docs/build/examples/testing.md create mode 100644 docs/build/examples/testing/index.html create mode 100644 docs/build/index.html delete mode 100644 docs/build/index.md delete mode 100644 docs/build/lib/functions.md create mode 100644 docs/build/lib/functions/index.html delete mode 100644 docs/build/lib/io_devices.md create mode 100644 docs/build/lib/io_devices/index.html delete mode 100644 docs/build/man/installation.md create mode 100644 docs/build/man/installation/index.html delete mode 100644 docs/build/man/introduction.md create mode 100644 docs/build/man/introduction/index.html create mode 100644 docs/build/search/index.html create mode 100644 docs/build/search_index.js diff --git a/docs/build/assets/Documenter.css b/docs/build/assets/Documenter.css deleted file mode 100644 index f7ae84a..0000000 --- a/docs/build/assets/Documenter.css +++ /dev/null @@ -1,18 +0,0 @@ -div.wy-menu-vertical ul.current li.toctree-l3 a { - font-weight: bold; -} - -a.documenter-source { - float: right; -} - -.documenter-methodtable pre { - margin-left: 0px; - margin-right: 0px; - margin-top: 0px; - padding: 0px; -} - -.documenter-methodtable pre.documenter-inline { - display: inline; -} diff --git a/docs/build/assets/arrow.svg b/docs/build/assets/arrow.svg new file mode 100644 index 0000000..ee2798d --- /dev/null +++ b/docs/build/assets/arrow.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/docs/build/assets/documenter.css b/docs/build/assets/documenter.css new file mode 100644 index 0000000..7cd2662 --- /dev/null +++ b/docs/build/assets/documenter.css @@ -0,0 +1,601 @@ +/* + * The default CSS style for Documenter.jl generated sites + * + * Heavily inspired by the Julia Sphinx theme + * https://github.com/JuliaLang/JuliaDoc + * which extends the sphinx_rtd_theme + * https://github.com/snide/sphinx_rtd_theme + * + * Part of Documenter.jl + * https://github.com/JuliaDocs/Documenter.jl + * + * License: MIT + */ + +/* fonts */ +body, input { + font-family: 'Lato', 'Helvetica Neue', Arial, sans-serif; + font-size: 16px; + color: #222; + text-rendering: optimizeLegibility; +} + +pre, code, kbd { + font-family: 'Roboto Mono', Monaco, courier, monospace; + font-size: 0.90em; +} + +pre code { + font-size: 1em; +} + +a { + color: #2980b9; + text-decoration: none; +} + +a:hover { + color: #3091d1; +} + +a:visited { + color: #9b59b6; +} + +body { + line-height: 1.5; +} + +h1 { + font-size: 1.75em; +} + +/* Unless the

the is very first thing on the page (i.e. the second element + * in the
, * after the
, we add some additional styling to it + * to make it stand out a bit more. This way we get a reasonable fallback if CSS3 + * selectors are not supported in the browser. + */ +article > h1:not(:nth-child(2)) { + margin: 2.5em 0 0; + padding-bottom: 0.30em; + border-bottom: 1px solid #e5e5e5; +} +h2 { + font-size: 1.50em; + margin: 2.3em 0 0; + padding-bottom: 0.25em; + border-bottom: 1px solid #e5e5e5; +} +h3 { + font-size: 1.25em; + margin: 2.0em 0 0; +} +h4 { font-size: 1.15em; } +h5 { font-size: 1.10em; } +h6 { font-size: 1em; } + +h4, h5, h6 { + margin-top: 1.5em; + margin-bottom: 1em; +} + +img { + max-width: 100%; +} + +table { + border-collapse: collapse; + margin: 1em 0; +} + +th, td { + border: 1px solid #e1e4e5; + padding: 0.5em 1em; +} + +th { + border-bottom-width: 2px; +} + +tr:nth-child(even) { + background-color: #f3f6f6; +} + +hr { + border: 0; + border-top: 1px solid #e5e5e5; +} + +/* Inline code and code blocks */ + +code { + padding: 0.1em; + background-color: rgba(0,0,0,.04); + border-radius: 3px; +} + +pre { + background-color: #f5f5f5; + border: 1px solid #dddddd; + border-radius: 3px; + padding: 0.5em; + overflow: auto; +} + +pre code { + padding: 0; + background-color: initial; +} + +kbd { + font-size: 0.70em; + display: inline-block; + padding: 0.1em 0.5em 0.4em 0.5em; + line-height: 1.0em; + color: #444d56; + vertical-align: middle; + background-color: #fafbfc; + border: solid 1px #c6cbd1; + border-bottom-color: #959da5; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #959da5; +} + +/* Headers in admonitions and docstrings */ +.admonition h1, +article section.docstring h1 { + font-size: 1.25em; +} + +.admonition h2, +article section.docstring h2 { + font-size: 1.10em; +} + +.admonition h3, +.admonition h4, +.admonition h5, +.admonition h6, +article section.docstring h3, +article section.docstring h4, +article section.docstring h5, +article section.docstring h6 { + font-size: 1em; +} + +/* Navigation */ +nav.toc { + position: fixed; + top: 0; + left: 0; + bottom: 0; + width: 20em; + display: flex; + flex-flow: column nowrap; + overflow-y: auto; + padding: 1em 0 0 0; + background-color: #fcfcfc; + box-shadow: inset -14px 0px 5px -12px rgb(210,210,210); +} + +nav.toc .logo { + margin: 0 auto; + display: block; + max-height: 6em; + max-width: 18em; +} + +nav.toc h1 { + text-align: center; + margin-top: .57em; + margin-bottom: 0; +} + +nav.toc select { + display: block; + height: 2em; + flex-shrink: 0; + padding: 0 1.6em 0 1em; + min-width: 7em; + max-width: 90%; + max-width: calc(100% - 5em); + margin: 0 auto; + font-size: .83em; + border: 1px solid #c9c9c9; + border-radius: 1em; + + /* TODO: doesn't seem to be centered on Safari */ + text-align: center; + text-align-last: center; + + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + + background: white url("arrow.svg"); + background-size: 1.155em; + background-repeat: no-repeat; + background-position: right; +} + +nav.toc select:hover { + border: 1px solid #a0a0a0; +} + +nav.toc select option { + text-align: center; +} + +nav.toc input { + display: block; + height: 2em; + width: 90%; + width: calc(100% - 5em); + margin: 1.2em auto; + padding: 0 1em; + border: 1px solid #c9c9c9; + border-radius: 1em; + font-size: .83em; +} + +nav.toc > ul * { + margin: 0; +} + +nav.toc > ul { + min-height: 2em; + overflow-y: auto; + margin: 0; +} + +nav.toc > ul > li:last-child { + padding-bottom: 1em; +} + +nav.toc ul { + color: #404040; + padding: 0; + list-style: none; +} + +nav.toc ul .toctext { + color: inherit; + display: block; +} + +nav.toc ul a:hover { + color: #fcfcfc; + background-color: #4e4a4a; +} + +nav.toc ul.internal a { + color: inherit; + display: block; +} + +nav.toc ul.internal a:hover { + background-color: #d6d6d6; +} + +nav.toc ul.internal { + background-color: #e3e3e3; + box-shadow: inset -14px 0px 5px -12px rgb(210,210,210); + list-style: none; +} + +nav.toc ul.internal li.toplevel { + border-top: 1px solid #909090; + font-weight: bold; +} + +nav.toc ul.internal li.toplevel:first-child { + border-top: none; +} + +nav.toc .toctext { + padding-top: 0.3em; + padding-bottom: 0.3em; + padding-right: 1em; +} + +nav.toc ul .toctext { + padding-left: 1em; +} + +nav.toc ul ul .toctext { + padding-left: 2em; +} + +nav.toc ul ul ul .toctext { + padding-left: 3em; +} + +nav.toc li.current > .toctext { + border-top: 1px solid #c9c9c9; + border-bottom: 1px solid #c9c9c9; + color: #404040; + font-weight: bold; + background-color: white; +} + +nav.toc ul::-webkit-scrollbar { + width: .4em; + background: none; +} + +nav.toc ul::-webkit-scrollbar-thumb { + border-radius: 5px; + background: #c9c9c9; +} + +nav.toc ul::-webkit-scrollbar-thumb:hover { + border-radius: 5px; + background: #aaaaaa; +} + +article { + margin-left: 20em; + min-width: 20em; + max-width: 48em; + padding: 2em; +} + +article > header {} + +article > header div#topbar { + display: none; +} + +article > header nav ul { + display: inline-block; + list-style: none; + margin: 0; + padding: 0; +} + +article > header nav li { + display: inline-block; + padding-right: 0.2em; +} + +article > header nav li:before { + content: "»"; + padding-right: 0.2em; +} + +article > header .edit-page { + float: right; +} + +article > footer {} + +article > footer a.prev { + float: left; +} +article > footer a.next { + float: right; +} + +article > footer a .direction:after { + content: ": "; +} + +article hr { + margin: 1em 0; +} + +article section.docstring { + border: 1px solid #ddd; + margin: 0.5em 0; + padding: 0.5em; + border-radius: 3px; +} + +article section.docstring .docstring-header { + margin-bottom: 1em; +} + +article section.docstring .docstring-binding { + color: #333; + font-weight: bold; +} + +article section.docstring .docstring-category { + font-style: italic; +} + +article section.docstring a.source-link { + display: block; + font-weight: bold; +} + +.nav-anchor, +.nav-anchor:hover, +.nav-anchor:visited { + color: #333; +} + +/* + * Admonitions + * + * Colors (title, body) + * warning: #f0b37e #ffedcc (orange) + * note: #6ab0de #e7f2fa (blue) + * tip: #1abc9c #dbfaf4 (green) +*/ +.admonition { + border-radius: 3px; + background-color: #eeeeee; + margin: 1em 0; +} + +.admonition-title { + border-radius: 3px 3px 0 0; + background-color: #9b9b9b; + padding: 0.15em 0.5em; +} + +.admonition-text { + padding: 0.5em; +} + +.admonition-text > :first-child { + margin-top: 0; +} + +.admonition-text > :last-child { + margin-bottom: 0; +} + +.admonition > .admonition-title:before { + font-family: "FontAwesome"; + margin-right: 5px; + content: "\f06a"; +} + +.admonition.warning > .admonition-title { + background-color: #f0b37e; +} + +.admonition.warning { + background-color: #ffedcc; +} + +.admonition.note > .admonition-title { + background-color: #6ab0de; +} + +.admonition.note { + background-color: #e7f2fa; +} + +.admonition.tip > .admonition-title { + background-color: #1abc9c; +} + +.admonition.tip { + background-color: #dbfaf4; +} + + +/* footnotes */ +.footnote { + padding-left: 0.8em; + border-left: 2px solid #ccc; +} + +/* Search page */ +#search-results .category { + font-size: smaller; +} + +/* Overriding the block style of highligh.js. + * We have to override the padding and the background-color, since we style this + * part ourselves. Specifically, we style the
 surrounding the , while
+ * highlight.js applies the .hljs style directly to the  tag.
+ */
+.hljs {
+    background-color: transparent;
+    padding: 0;
+}
+
+@media only screen and (max-width: 768px) {
+    nav.toc {
+        position: fixed;
+        width: 16em;
+        left: -16em;
+        -webkit-overflow-scrolling: touch;
+        -webkit-transition-property: left; /* Safari */
+        -webkit-transition-duration: 0.3s; /* Safari */
+        transition-property: left;
+        transition-duration: 0.3s;
+        -webkit-transition-timing-function: ease-out; /* Safari */
+        transition-timing-function: ease-out;
+        z-index: 2;
+        box-shadow: 5px 0px 5px 0px rgb(210,210,210);
+    }
+
+    nav.toc.show {
+        left: 0;
+    }
+
+    article {
+        margin-left: 0;
+        padding: 3em 0.9em 0 0.9em; /* top right bottom left */
+        overflow-wrap: break-word;
+    }
+
+    article > header {
+        position: fixed;
+        left: 0;
+        z-index: 1;
+    }
+
+    article > header nav, hr {
+        display: none;
+    }
+
+    article > header div#topbar {
+        display: block; /* is mobile */
+        position: fixed;
+        width: 100%;
+        height: 1.5em;
+        padding-top: 1em;
+        padding-bottom: 1em;
+        background-color: #fcfcfc;
+        box-shadow: 0 1px 3px rgba(0,0,0,.26);
+        top: 0;
+        -webkit-transition-property: top; /* Safari */
+        -webkit-transition-duration: 0.3s; /* Safari */
+        transition-property: top;
+        transition-duration: 0.3s;
+    }
+
+    article > header div#topbar.headroom--unpinned.headroom--not-top.headroom--not-bottom {
+        top: -4em;
+        -webkit-transition-property: top; /* Safari */
+        -webkit-transition-duration: 0.7s; /* Safari */
+        transition-property: top;
+        transition-duration: 0.7s;
+    }
+
+    article > header div#topbar span {
+        width: 80%;
+        height: 1.5em;
+        margin-top: -0.1em;
+        margin-left: 0.9em;
+        font-size: 1.2em;
+        overflow: hidden;
+    }
+
+    article > header div#topbar a.fa-bars {
+        float: right;
+        padding: 0.6em;
+        margin-top: -0.6em;
+        margin-right: 0.3em;
+        font-size: 1.5em;
+    }
+
+    article > header div#topbar a.fa-bars:visited {
+        color: #3091d1;
+    }
+
+    article table {
+        overflow-x: auto;
+        display: block;
+    }
+
+    article div.MathJax_Display {
+        overflow: scroll;
+    }
+
+    article span.MathJax {
+        overflow: hidden;
+    }
+}
+
+@media only screen and (max-width: 320px) {
+    body {
+        font-size: 15px;
+    }
+}
diff --git a/docs/build/assets/documenter.js b/docs/build/assets/documenter.js
new file mode 100644
index 0000000..761ae29
--- /dev/null
+++ b/docs/build/assets/documenter.js
@@ -0,0 +1,132 @@
+/*
+ * Part of Documenter.jl
+ *     https://github.com/JuliaDocs/Documenter.jl
+ *
+ * License: MIT
+ */
+
+requirejs.config({
+    paths: {
+        'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min',
+        'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min',
+        'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.3/headroom.min',
+        'mathjax': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML',
+        'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min',
+        'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/julia.min',
+        'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/julia-repl.min',
+    },
+    shim: {
+        'mathjax' : {
+            exports: "MathJax"
+        },
+        'highlight-julia': ['highlight'],
+        'highlight-julia-repl': ['highlight'],
+    }
+});
+
+// Load MathJax
+require(['mathjax'], function(MathJax) {
+    MathJax.Hub.Config({
+      "tex2jax": {
+        inlineMath: [['$','$'], ['\\(','\\)']],
+        processEscapes: true
+      }
+    });
+    MathJax.Hub.Config({
+      config: ["MMLorHTML.js"],
+      jax: [
+        "input/TeX",
+        "output/HTML-CSS",
+        "output/NativeMML"
+      ],
+      extensions: [
+        "MathMenu.js",
+        "MathZoom.js",
+        "TeX/AMSmath.js",
+        "TeX/AMSsymbols.js",
+        "TeX/autobold.js",
+        "TeX/autoload-all.js"
+      ]
+    });
+    MathJax.Hub.Config({
+      TeX: { equationNumbers: { autoNumber: "AMS" } }
+    });
+})
+
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
+    $(document).ready(function() {
+        hljs.initHighlighting();
+    })
+
+})
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+require(['jquery'], function($) {
+    $(document).ready(function() {
+        var version_selector = $("#version-selector");
+
+        // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+        if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
+            var option = $("");
+            version_selector.append(option);
+        }
+
+        if (typeof DOC_VERSIONS !== 'undefined') {
+            var existing_versions = $('#version-selector > option');
+            var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
+            DOC_VERSIONS.forEach(function(each) {
+                var version_url = documenterBaseURL + "/../" + each;
+                var existing_id = $.inArray(each, existing_versions_texts);
+                // if not already in the version selector, add it as a new option,
+                // otherwise update the old option with the URL and enable it
+                if (existing_id == -1) {
+                    var option = $("");
+                    version_selector.append(option);
+                } else {
+                    var option = existing_versions[existing_id];
+                    option.value = version_url;
+                    option.disabled = false;
+                }
+            });
+        }
+
+        // only show the version selector if the selector has been populated
+        if ($('#version-selector > option').length > 0) {
+            version_selector.css("visibility", "visible");
+        }
+
+        // Scroll the navigation bar to the currently selected menu item
+        $("nav.toc > ul").get(0).scrollTop = $(".current").get(0).offsetTop - $("nav.toc > ul").get(0).offsetTop;
+    })
+
+})
+
+// mobile
+require(['jquery', 'headroom'], function($, Headroom) {
+    $(document).ready(function() {
+        var navtoc = $("nav.toc");
+        $("nav.toc li.current a.toctext").click(function() {
+            navtoc.toggleClass('show');
+        });
+        $("article > header div#topbar a.fa-bars").click(function(ev) {
+            ev.preventDefault();
+            navtoc.toggleClass('show');
+            if (navtoc.hasClass('show')) {
+                var title = $("article > header div#topbar span").text();
+                $("nav.toc ul li a:contains('" + title + "')").focus();
+            }
+        });
+        $("article#docs").bind('click', function(ev) {
+            if ($(ev.target).is('div#topbar a.fa-bars')) {
+                return;
+            }
+            if (navtoc.hasClass('show')) {
+                navtoc.removeClass('show');
+            }
+        });
+        if ($("article > header div#topbar").css('display') == 'block') {
+            var headroom = new Headroom(document.querySelector("article > header div#topbar"), {"tolerance": {"up": 10, "down": 10}});
+            headroom.init();
+        }
+    })
+})
diff --git a/docs/build/assets/mathjaxhelper.js b/docs/build/assets/mathjaxhelper.js
deleted file mode 100644
index 3561b10..0000000
--- a/docs/build/assets/mathjaxhelper.js
+++ /dev/null
@@ -1,25 +0,0 @@
-MathJax.Hub.Config({
-  "tex2jax": {
-    inlineMath: [['$','$'], ['\\(','\\)']],
-    processEscapes: true
-  }
-});
-MathJax.Hub.Config({
-  config: ["MMLorHTML.js"],
-  jax: [
-    "input/TeX",
-    "output/HTML-CSS",
-    "output/NativeMML"
-  ],
-  extensions: [
-    "MathMenu.js",
-    "MathZoom.js",
-    "TeX/AMSmath.js",
-    "TeX/AMSsymbols.js",
-    "TeX/autobold.js",
-    "TeX/autoload-all.js"
-  ]
-});
-MathJax.Hub.Config({
-  TeX: { equationNumbers: { autoNumber: "AMS" } }
-});
diff --git a/docs/build/assets/search.js b/docs/build/assets/search.js
new file mode 100644
index 0000000..5d32c3a
--- /dev/null
+++ b/docs/build/assets/search.js
@@ -0,0 +1,250 @@
+/*
+ * Part of Documenter.jl
+ *     https://github.com/JuliaDocs/Documenter.jl
+ *
+ * License: MIT
+ */
+
+// parseUri 1.2.2
+// (c) Steven Levithan 
+// MIT License
+function parseUri (str) {
+	var	o   = parseUri.options,
+		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+		uri = {},
+		i   = 14;
+
+	while (i--) uri[o.key[i]] = m[i] || "";
+
+	uri[o.q.name] = {};
+	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+		if ($1) uri[o.q.name][$1] = $2;
+	});
+
+	return uri;
+};
+parseUri.options = {
+	strictMode: false,
+	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+	q:   {
+		name:   "queryKey",
+		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+	},
+	parser: {
+		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+	}
+};
+
+requirejs.config({
+    paths: {
+        'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min',
+        'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.5/lunr.min',
+        'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min',
+    }
+});
+
+var currentScript = document.currentScript;
+
+require(["jquery", "lunr", "lodash"], function($, lunr, _) {
+    $("#search-form").submit(function(e) {
+        e.preventDefault()
+    })
+
+    // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+    // (all, any, get, in, is, which) and (do, else, for, let, where, while, with)
+    // ideally we'd just filter the original list but it's not available as a variable
+    lunr.stopWordFilter = lunr.generateStopWordFilter([
+        'a',
+        'able',
+        'about',
+        'across',
+        'after',
+        'almost',
+        'also',
+        'am',
+        'among',
+        'an',
+        'and',
+        'are',
+        'as',
+        'at',
+        'be',
+        'because',
+        'been',
+        'but',
+        'by',
+        'can',
+        'cannot',
+        'could',
+        'dear',
+        'did',
+        'does',
+        'either',
+        'ever',
+        'every',
+        'from',
+        'got',
+        'had',
+        'has',
+        'have',
+        'he',
+        'her',
+        'hers',
+        'him',
+        'his',
+        'how',
+        'however',
+        'i',
+        'if',
+        'into',
+        'it',
+        'its',
+        'just',
+        'least',
+        'like',
+        'likely',
+        'may',
+        'me',
+        'might',
+        'most',
+        'must',
+        'my',
+        'neither',
+        'no',
+        'nor',
+        'not',
+        'of',
+        'off',
+        'often',
+        'on',
+        'only',
+        'or',
+        'other',
+        'our',
+        'own',
+        'rather',
+        'said',
+        'say',
+        'says',
+        'she',
+        'should',
+        'since',
+        'so',
+        'some',
+        'than',
+        'that',
+        'the',
+        'their',
+        'them',
+        'then',
+        'there',
+        'these',
+        'they',
+        'this',
+        'tis',
+        'to',
+        'too',
+        'twas',
+        'us',
+        'wants',
+        'was',
+        'we',
+        'were',
+        'what',
+        'when',
+        'who',
+        'whom',
+        'why',
+        'will',
+        'would',
+        'yet',
+        'you',
+        'your'
+        ])
+
+    // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
+    // would not find anything if searching for "add!", only for the entire qualification
+    lunr.tokenizer.separator = /[\s\-\.]+/
+
+    // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+    lunr.trimmer = function (token) {
+        return token.update(function (s) {
+            return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
+        })
+    }
+
+    lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
+    lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
+
+    var index = lunr(function () {
+        this.ref('location')
+        this.field('title')
+        this.field('text')
+        documenterSearchIndex['docs'].forEach(function(e) {
+            this.add(e)
+        }, this)
+    })
+    var store = {}
+
+    documenterSearchIndex['docs'].forEach(function(e) {
+        store[e.location] = {title: e.title, category: e.category}
+    })
+
+    $(function(){
+        function update_search(querystring) {
+            tokens = lunr.tokenizer(querystring)
+            results = index.query(function (q) {
+                tokens.forEach(function (t) {
+                    q.term(t.toString(), {
+                        fields: ["title"],
+                        boost: 100,
+                        usePipeline: false,
+                        editDistance: 0,
+                        wildcard: lunr.Query.wildcard.NONE
+                    })
+                    q.term(t.toString(), {
+                        fields: ["title"],
+                        boost: 10,
+                        usePipeline: false,
+                        editDistance: 2,
+                        wildcard: lunr.Query.wildcard.NONE
+                    })
+                    q.term(t.toString(), {
+                        fields: ["text"],
+                        boost: 1,
+                        usePipeline: true,
+                        editDistance: 0,
+                        wildcard: lunr.Query.wildcard.NONE
+                    })
+                })
+            })
+            $('#search-info').text("Number of results: " + results.length)
+            $('#search-results').empty()
+            results.forEach(function(result) {
+                data = store[result.ref]
+                link = $('')
+                link.text(data.title)
+                link.attr('href', documenterBaseURL+'/'+result.ref)
+                cat = $('('+data.category+')')
+                li = $('
  • ').append(link).append(" ").append(cat) + $('#search-results').append(li) + }) + } + + function update_search_box() { + querystring = $('#search-query').val() + update_search(querystring) + } + + $('#search-query').keyup(_.debounce(update_search_box, 250)) + $('#search-query').change(update_search_box) + + search_query_uri = parseUri(window.location).queryKey["q"] + if(search_query_uri !== undefined) { + search_query = decodeURIComponent(search_query_uri.replace(/\+/g, '%20')) + $("#search-query").val(search_query) + } + update_search_box(); + }) +}) diff --git a/docs/build/examples/examples.md b/docs/build/examples/examples.md deleted file mode 100644 index eca81f5..0000000 --- a/docs/build/examples/examples.md +++ /dev/null @@ -1,117 +0,0 @@ - - - -# Examples - - -The following examples may be run from the BB, and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the following line in the Julia prompt - - -``` -push!(LOAD_PATH, "/home/debian/juliapackages") -``` - - -When running the examples with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in parallel. See the configuration page for information on which functionality specific pins support. - - - - -## Example with LEDs (BB) - - -To test the system LED functionality of the Julia code from the BBB, open a Julia prompt and run the SYS_LED_test.jl file - - -``` -include("/home/debian/juliapackages/LabConnections/test/BeagleBone/SYS_LED_test.jl") -``` - - -This example runs a test with hardware in the loop, exporting and unexporting the SYS_LED devices and blinking led D2-D5 in a sequence over 1 second, alternating with D2/D4 and D3/D5 on/off. - - - - -## Example with GPIOs (BB) - - -To test the GPIO functionality of the Julia code from the BBB, open a Julia prompt and run the GPIO_test.jl file - - -``` -include("/home/debian/juliapackages/LabConnections/test/BeagleBone/GPIO_test.jl") -``` - - -This again runs the tests with the BBB in the loop, testing exception handling exporting of the file system and also runs all the GPIOs on the board high/low at a 0.1 period time over 1 second to demonstrate the IO communication visually. - - - - -## Example with PWM (BB) - - -To test the PWM functionality of the Julia code from the BBB, open a Julia prompt and run the PWM_test.jl file - - -``` -include("/home/debian/juliapackages/LabConnections/test/BeagleBone/PWM_test.jl") -``` - - -This runs the PWM tests with the BBB in the loop, testing exception handling exporting of the file system. In addition, it runs all the PWM pins on the board with a duty cycle of 0.5 over a period time over 1 second to demonstrate the IO communication visually. - - - - -## Example with SPI (BB) - - -All development on the SPI is currently done in C in a for of the serbus package. Consequently, this example is currently run completely separate from the LabConnections. - - -Make sure that the serbus package exists in the /juliapackages/ directory, where it is automatically placed when transferring code to the BB using the ./flash_BB shell script. Then simply run - - -``` -cp /home/debian/juliapackages/serbus/bb_spi.sh /home/debian -``` - - -and execute - - -``` -./bb_spi.sh -``` - - -in the /home/debian/ directory. The program then - - -1. Compiles a device tree overlay (should SPI1 be used) -2. Creates the binaries for the SPI driver and example -3. Runs the MCP3903 example script located in spi_MCP3903.c - - -The purpose of the program is to configure the ADC to operate in the continuous mode and then read the registers, outputting the measurements in the terminal. - - - - -## Example with LEDs (HOST) - - -To operate the LEDs from the host computer, simply connect the BBB to the HOST via USB and run the "testLED.jl" on the HOST - - -``` -cd && cd .julia/v0.6/LabConnections/Examples/ && julia testLED.jl -``` - - -```@systemConfiguration - -``` - diff --git a/docs/build/examples/examples/index.html b/docs/build/examples/examples/index.html new file mode 100644 index 0000000..4bb0407 --- /dev/null +++ b/docs/build/examples/examples/index.html @@ -0,0 +1,2 @@ + +Examples · LabConnections

    Examples

    Examples

    The following examples may be run from the BB, and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the following line in the Julia prompt

    push!(LOAD_PATH, "/home/debian/juliapackages")

    When running the examples with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in parallel. See the configuration page for information on which functionality specific pins support.

    Example with LEDs (BB)

    To test the system LED functionality of the Julia code from the BBB, open a Julia prompt and run the SYSLEDtest.jl file

    include("/home/debian/juliapackages/LabConnections/test/BeagleBone/SYS_LED_test.jl")

    This example runs a test with hardware in the loop, exporting and unexporting the SYS_LED devices and blinking led D2-D5 in a sequence over 1 second, alternating with D2/D4 and D3/D5 on/off.

    Example with GPIOs (BB)

    To test the GPIO functionality of the Julia code from the BBB, open a Julia prompt and run the GPIO_test.jl file

    include("/home/debian/juliapackages/LabConnections/test/BeagleBone/GPIO_test.jl")

    This again runs the tests with the BBB in the loop, testing exception handling exporting of the file system and also runs all the GPIOs on the board high/low at a 0.1 period time over 1 second to demonstrate the IO communication visually.

    Example with PWM (BB)

    To test the PWM functionality of the Julia code from the BBB, open a Julia prompt and run the PWM_test.jl file

    include("/home/debian/juliapackages/LabConnections/test/BeagleBone/PWM_test.jl")

    This runs the PWM tests with the BBB in the loop, testing exception handling exporting of the file system. In addition, it runs all the PWM pins on the board with a duty cycle of 0.5 over a period time over 1 second to demonstrate the IO communication visually.

    Example with SPI (BB)

    All development on the SPI is currently done in C in a for of the serbus package. Consequently, this example is currently run completely separate from the LabConnections.

    Make sure that the serbus package exists in the /juliapackages/ directory, where it is automatically placed when transferring code to the BB using the ./flash_BB shell script. Then simply run

    cp /home/debian/juliapackages/serbus/bb_spi.sh /home/debian

    and execute

    ./bb_spi.sh

    in the /home/debian/ directory. The program then

    1. Compiles a device tree overlay (should SPI1 be used)
    2. Creates the binaries for the SPI driver and example
    3. Runs the MCP3903 example script located in spi_MCP3903.c

    The purpose of the program is to configure the ADC to operate in the continuous mode and then read the registers, outputting the measurements in the terminal.

    Example with LEDs (HOST)

    To operate the LEDs from the host computer, simply connect the BBB to the HOST via USB and run the "testLED.jl" on the HOST

    cd && cd .julia/v0.6/LabConnections/Examples/ && julia testLED.jl
    diff --git a/docs/build/examples/testing.md b/docs/build/examples/testing.md deleted file mode 100644 index d6c3c74..0000000 --- a/docs/build/examples/testing.md +++ /dev/null @@ -1,27 +0,0 @@ - - - -# Tests - - -The BeagleBone tests can be run on any computer, regrdless of their file-syste. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis. - - -To run the tests, simply enter the /test/ directory and run - - -``` -julia run_tests.jl -``` - - -If the tests are to be run on the BB with hardware in the loop, run - - -``` -julia run_tests.jl -``` - - -on the BB, to run examples separately, see - diff --git a/docs/build/examples/testing/index.html b/docs/build/examples/testing/index.html new file mode 100644 index 0000000..b798a0e --- /dev/null +++ b/docs/build/examples/testing/index.html @@ -0,0 +1,2 @@ + +Tests · LabConnections

    Tests

    Tests

    The BeagleBone tests can be run on any computer, regrdless of their file-syste. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis.

    To run the tests, simply enter the /test/ directory and run

    julia run_tests.jl

    If the tests are to be run on the BB with hardware in the loop, run

    julia run_tests.jl

    on the BB, to run examples separately, see

    diff --git a/docs/build/index.html b/docs/build/index.html new file mode 100644 index 0000000..42d9b36 --- /dev/null +++ b/docs/build/index.html @@ -0,0 +1,2 @@ + +LabConnections.jl Manual · LabConnections

    LabConnections.jl Manual

    LabConnections.jl Manual

    Examples

    Guide

    Functions

    Documentation Index

    diff --git a/docs/build/index.md b/docs/build/index.md deleted file mode 100644 index 7a600d2..0000000 --- a/docs/build/index.md +++ /dev/null @@ -1,66 +0,0 @@ - - - -# LabConnections.jl Manual - - - - - - -## Examples - -- [Examples](examples/examples.md#Examples-1) -- [Tests](examples/testing.md#Tests-1) - - - - -## Guide - -- [Introduction](man/introduction.md#Introduction-1) -- [Installation Instructions](man/installation.md#Installation-Instructions-1) - - - - -## Functions - -- [Available devices](lib/io_devices.md#Available-devices-1) -- [Available functions](lib/functions.md#Available-functions-1) - - - - -## Documentation Index - -- [`LabConnections.BeagleBone.Debug`](lib/io_devices.md#LabConnections.BeagleBone.Debug) -- [`LabConnections.BeagleBone.GPIO`](lib/io_devices.md#LabConnections.BeagleBone.GPIO) -- [`LabConnections.BeagleBone.IO_Object`](lib/io_devices.md#LabConnections.BeagleBone.IO_Object) -- [`LabConnections.BeagleBone.PWM`](lib/io_devices.md#LabConnections.BeagleBone.PWM) -- [`LabConnections.BeagleBone.SysLED`](lib/io_devices.md#LabConnections.BeagleBone.SysLED) -- [`Base.read`](lib/functions.md#Base.read) -- [`Base.read`](lib/functions.md#Base.read) -- [`Base.read`](lib/functions.md#Base.read) -- [`LabConnections.BeagleBone.assert_pwm_write`](lib/functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) -- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) -- [`LabConnections.BeagleBone.closedev`](lib/functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) -- [`LabConnections.BeagleBone.export_gpio`](lib/functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) -- [`LabConnections.BeagleBone.export_led`](lib/functions.md#LabConnections.BeagleBone.export_led) -- [`LabConnections.BeagleBone.export_pwm`](lib/functions.md#LabConnections.BeagleBone.export_pwm-Tuple{Int32}) -- [`LabConnections.BeagleBone.getdev`](lib/functions.md#LabConnections.BeagleBone.getdev-Tuple{String,Int32}) -- [`LabConnections.BeagleBone.initdev`](lib/functions.md#LabConnections.BeagleBone.initdev-Tuple{String,Int32}) -- [`LabConnections.BeagleBone.listdev`](lib/functions.md#LabConnections.BeagleBone.listdev-Tuple{}) -- [`LabConnections.BeagleBone.printdev`](lib/functions.md#LabConnections.BeagleBone.printdev-Tuple{String,Int32}) -- [`LabConnections.BeagleBone.run_server`](lib/functions.md#LabConnections.BeagleBone.run_server) -- [`LabConnections.BeagleBone.teardown`](lib/functions.md#LabConnections.BeagleBone.teardown) -- [`LabConnections.BeagleBone.teardown`](lib/functions.md#LabConnections.BeagleBone.teardown) -- [`LabConnections.BeagleBone.teardown`](lib/functions.md#LabConnections.BeagleBone.teardown) -- [`LabConnections.BeagleBone.to_string`](lib/functions.md#LabConnections.BeagleBone.to_string) -- [`LabConnections.BeagleBone.to_string`](lib/functions.md#LabConnections.BeagleBone.to_string) -- [`LabConnections.BeagleBone.to_string`](lib/functions.md#LabConnections.BeagleBone.to_string) -- [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) -- [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) -- [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) - diff --git a/docs/build/lib/functions.md b/docs/build/lib/functions.md deleted file mode 100644 index 07f1f3f..0000000 --- a/docs/build/lib/functions.md +++ /dev/null @@ -1,294 +0,0 @@ -- [`Base.read`](functions.md#Base.read) -- [`Base.read`](functions.md#Base.read) -- [`Base.read`](functions.md#Base.read) -- [`LabConnections.BeagleBone.assert_pwm_write`](functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) -- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) -- [`LabConnections.BeagleBone.closedev`](functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) -- [`LabConnections.BeagleBone.export_gpio`](functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) -- [`LabConnections.BeagleBone.export_led`](functions.md#LabConnections.BeagleBone.export_led) -- [`LabConnections.BeagleBone.export_pwm`](functions.md#LabConnections.BeagleBone.export_pwm-Tuple{Int32}) -- [`LabConnections.BeagleBone.getdev`](functions.md#LabConnections.BeagleBone.getdev-Tuple{String,Int32}) -- [`LabConnections.BeagleBone.initdev`](functions.md#LabConnections.BeagleBone.initdev-Tuple{String,Int32}) -- [`LabConnections.BeagleBone.listdev`](functions.md#LabConnections.BeagleBone.listdev-Tuple{}) -- [`LabConnections.BeagleBone.printdev`](functions.md#LabConnections.BeagleBone.printdev-Tuple{String,Int32}) -- [`LabConnections.BeagleBone.run_server`](functions.md#LabConnections.BeagleBone.run_server) -- [`LabConnections.BeagleBone.teardown`](functions.md#LabConnections.BeagleBone.teardown) -- [`LabConnections.BeagleBone.teardown`](functions.md#LabConnections.BeagleBone.teardown) -- [`LabConnections.BeagleBone.teardown`](functions.md#LabConnections.BeagleBone.teardown) -- [`LabConnections.BeagleBone.to_string`](functions.md#LabConnections.BeagleBone.to_string) -- [`LabConnections.BeagleBone.to_string`](functions.md#LabConnections.BeagleBone.to_string) -- [`LabConnections.BeagleBone.to_string`](functions.md#LabConnections.BeagleBone.to_string) -- [`LabConnections.BeagleBone.write!`](functions.md#LabConnections.BeagleBone.write!) -- [`LabConnections.BeagleBone.write!`](functions.md#LabConnections.BeagleBone.write!) -- [`LabConnections.BeagleBone.write!`](functions.md#LabConnections.BeagleBone.write!) - - - - -# Available functions - -# -**`LabConnections.BeagleBone.run_server`** — *Function*. - - - -``` -run_server(port=2001; debug=false) -``` - -Run a server on `port` that listens for commands from computer Optional debug keyword disables blinking system leds. - -# -**`Base.read`** — *Function*. - - - -``` -l = read(gpio::GPIO, operation::Int32, debug::Bool=false) -``` - -Reads the current value from an operation on a GPIO. - -# -**`Base.read`** — *Function*. - - - -``` -l = read(led::SysLED, debug::Bool=false) -``` - -Reads the current brightness value from the LED 'SysLED'. - -# -**`Base.read`** — *Function*. - - - -``` -l = read(pwm::PWM, operation::Int32, debug::Bool=false) -``` - -Reads the current value from an operation on a GPIO. - -# -**`LabConnections.BeagleBone.assert_pwm_write`** — *Method*. - - - -``` -assert_pwm_write(operation::Int32, entry::String) -``` - -Assertsion for the PWM input data. - -# -**`LabConnections.BeagleBone.bbparse`** — *Method*. - - - -``` -bbparse(cmd) -``` - -Parse and execute the command `cmd`. - -# -**`LabConnections.BeagleBone.bbparse`** — *Method*. - - - -``` -bbparse(l::Tuple, sock) -``` - -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)` and send back on socket (vals, timestamps). - -# -**`LabConnections.BeagleBone.closedev`** — *Method*. - - - -``` -closedev(dev_name::String, i::Int32) -``` - -Closes down a currently active device of type 'dev_name' at index 'i' on the BeagleBone, and removes it from the dict of currently active devices. - -# -**`LabConnections.BeagleBone.export_gpio`** — *Method*. - - - -``` -export_gpio(i::Int32, debug::Bool=false) -``` - -Export the GPIO file system, either for real-time or testing usecases. - -# -**`LabConnections.BeagleBone.export_led`** — *Function*. - - - -``` -export_led(i::Int32, debug::Bool=false) -``` - -Exports a dummy filesystem for testing the LED implementation - -# -**`LabConnections.BeagleBone.export_pwm`** — *Method*. - - - -``` -export_gpio(i::Int32, debug::Bool=false) -``` - -Export the GPIO file system, either for real-time or testing usecases. - -# -**`LabConnections.BeagleBone.getdev`** — *Method*. - - - -``` -dev = getdev(dev_name::String, i::Int32) -``` - -Retrieves the active device of type `dev_name` at index 'i'. - -# -**`LabConnections.BeagleBone.initdev`** — *Method*. - - - -``` -active_device = initdev(dev_name::String, i:Int32) -``` - -Initializes a new device of type 'dev_name' at index 'i' on the BeagleBone, and adds it to the dict of currently active devices. Returns the initialized device 'active_device'. - -# -**`LabConnections.BeagleBone.listdev`** — *Method*. - - - -``` -message = listdev() -``` - -Lists all the active devices as an insidence array for testing. - -# -**`LabConnections.BeagleBone.printdev`** — *Method*. - - - -``` -message = printdev() -``` - -Prints all the active devices and writes out specifics of a single devices. - -# -**`LabConnections.BeagleBone.teardown`** — *Function*. - - - -``` -teardown(led::SysLED, debug::Bool=false) -``` - -Closes all open filestreams for the SysLED 'led'. - -# -**`LabConnections.BeagleBone.teardown`** — *Function*. - - - -``` -teardown!(pwd::PWM) -``` - -Closes all open streams on the PWM, and unexports it from the file system - -# -**`LabConnections.BeagleBone.teardown`** — *Function*. - - - -``` -teardown(gpio::GPIO, debug::Bool=false) -``` - -Closes all open streams on the GPIO, and unexports it from the file system. - -# -**`LabConnections.BeagleBone.to_string`** — *Function*. - - - -``` -to_string(led::SysLED, debug::Bool=false) -``` - -Generates a string representation of the GPIO device. - -# -**`LabConnections.BeagleBone.to_string`** — *Function*. - - - -``` -to_string(pwm::PWM,, debug::Bool=false) -``` - -Generates a string representation of the GPIO device. - -# -**`LabConnections.BeagleBone.to_string`** — *Function*. - - - -``` -to_string(gpio::GPIO, debug::Bool=false) -``` - -Generates a string representation of the GPIO device. - -# -**`LabConnections.BeagleBone.write!`** — *Function*. - - - -``` -write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false) -``` - -Writes an entry to an operation on a GPIO, of the form args = (operation, entry). - -# -**`LabConnections.BeagleBone.write!`** — *Function*. - - - -``` -write!(led::SysLED, val::Bool, debug::Bool=false) -``` - -Turns the LED 'SysLed' on/off for val = true/false respectively. - -# -**`LabConnections.BeagleBone.write!`** — *Function*. - - - -``` -write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false) -``` - -Writes an entry to an operation on the PWM, of the form args = (operation, entry). - diff --git a/docs/build/lib/functions/index.html b/docs/build/lib/functions/index.html new file mode 100644 index 0000000..aa3a00c --- /dev/null +++ b/docs/build/lib/functions/index.html @@ -0,0 +1,2 @@ + +Available functions · LabConnections

    Available functions

    Available functions

    run_server(port=2001; debug=false)

    Run a server on port that listens for commands from computer Optional debug keyword disables blinking system leds.

    Base.readFunction.
    l = read(led::SysLED, debug::Bool=false)

    Reads the current brightness value from the LED 'SysLED'.

    Base.readFunction.
    l = read(pwm::PWM, operation::Int32, debug::Bool=false)

    Reads the current value from an operation on a GPIO.

    Base.readFunction.
    l = read(gpio::GPIO, operation::Int32, debug::Bool=false)

    Reads the current value from an operation on a GPIO.

    assert_pwm_write(operation::Int32, entry::String)

    Assertsion for the PWM input data.

    bbparse(cmd)

    Parse and execute the command cmd.

    bbparse(l::Tuple, sock)

    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) and send back on socket (vals, timestamps).

    closedev(dev_name::String, i::Int32)

    Closes down a currently active device of type 'dev_name' at index 'i' on the BeagleBone, and removes it from the dict of currently active devices.

    export_gpio(i::Int32, debug::Bool=false)

    Export the GPIO file system, either for real-time or testing usecases.

    export_led(i::Int32, debug::Bool=false)

    Exports a dummy filesystem for testing the LED implementation

    export_gpio(i::Int32, debug::Bool=false)

    Export the GPIO file system, either for real-time or testing usecases.

    dev = getdev(dev_name::String, i::Int32)

    Retrieves the active device of type dev_name at index 'i'.

    active_device = initdev(dev_name::String, i:Int32)

    Initializes a new device of type 'devname' at index 'i' on the BeagleBone, and adds it to the dict of currently active devices. Returns the initialized device 'activedevice'.

    message = listdev()

    Lists all the active devices as an insidence array for testing.

    message = printdev()

    Prints all the active devices and writes out specifics of a single devices.

    teardown(led::SysLED, debug::Bool=false)

    Closes all open filestreams for the SysLED 'led'.

    teardown(gpio::GPIO, debug::Bool=false)

    Closes all open streams on the GPIO, and unexports it from the file system.

    teardown!(pwd::PWM)

    Closes all open streams on the PWM, and unexports it from the file system

    to_string(led::SysLED, debug::Bool=false)

    Generates a string representation of the GPIO device.

    to_string(gpio::GPIO, debug::Bool=false)

    Generates a string representation of the GPIO device.

    to_string(pwm::PWM,, debug::Bool=false)

    Generates a string representation of the GPIO device.

    write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false)

    Writes an entry to an operation on a GPIO, of the form args = (operation, entry).

    write!(led::SysLED, val::Bool, debug::Bool=false)

    Turns the LED 'SysLed' on/off for val = true/false respectively.

    write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false)

    Writes an entry to an operation on the PWM, of the form args = (operation, entry).

    diff --git a/docs/build/lib/io_devices.md b/docs/build/lib/io_devices.md deleted file mode 100644 index f01fba9..0000000 --- a/docs/build/lib/io_devices.md +++ /dev/null @@ -1,76 +0,0 @@ -- [`LabConnections.BeagleBone.Debug`](io_devices.md#LabConnections.BeagleBone.Debug) -- [`LabConnections.BeagleBone.GPIO`](io_devices.md#LabConnections.BeagleBone.GPIO) -- [`LabConnections.BeagleBone.IO_Object`](io_devices.md#LabConnections.BeagleBone.IO_Object) -- [`LabConnections.BeagleBone.PWM`](io_devices.md#LabConnections.BeagleBone.PWM) -- [`LabConnections.BeagleBone.SysLED`](io_devices.md#LabConnections.BeagleBone.SysLED) - - - - -# Available devices - -# -**`LabConnections.BeagleBone.Debug`** — *Type*. - - - -``` -Debug(i::Int32) -``` - -Type for debugging and precompile. - -# -**`LabConnections.BeagleBone.GPIO`** — *Type*. - - - -``` -GPIO(i::Int32) -``` - -Lowest form of communication with the GPIO pins. The available pins are listed in the "channel" parameter, and appear as directories in /sys/class/gpio after being exported. For instance, to setup a GPIO on "gpio112", configure it as an output pin and set it to high, the following code would be used. - -``` -`gpio = GPIO(1)` -`write!(gpio, (2,"out"))` -`write!(gpio, (1, "1"))` -``` - -The operation of reading the current output value of the GPIO is done by - -``` -`read(gpio, 1)` -``` - -See the test/BeagleBone/GPIO_test.jl for more examples. - -# -**`LabConnections.BeagleBone.IO_Object`** — *Type*. - - - -Define abstract type for pins/LEDS on the BeagleBone - -# -**`LabConnections.BeagleBone.PWM`** — *Type*. - - - -``` -PWM(i::Int32) -``` - -This device allows for low level PWM control of selected pins. The valid pins dictionary pwm_pins relates to memory adresses in of the AM3359 chip, see p.182 in www.ti.com/product/AM3359/technicaldocuments. - -# -**`LabConnections.BeagleBone.SysLED`** — *Type*. - - - -``` -SysLED(i::Int32) -``` - -Type representing the system LEDs on the BeagleBone. The LEDs are indexed by i ∈ [1,2,3,4]. - diff --git a/docs/build/lib/io_devices/index.html b/docs/build/lib/io_devices/index.html new file mode 100644 index 0000000..11289fb --- /dev/null +++ b/docs/build/lib/io_devices/index.html @@ -0,0 +1,4 @@ + +Available devices · LabConnections

    Available devices

    Available devices

    Debug(i::Int32)

    Type for debugging and precompile.

    GPIO(i::Int32)

    Lowest form of communication with the GPIO pins. The available pins are listed in the "channel" parameter, and appear as directories in /sys/class/gpio after being exported. For instance, to setup a GPIO on "gpio112", configure it as an output pin and set it to high, the following code would be used.

    `gpio = GPIO(1)`
    +`write!(gpio, (2,"out"))`
    +`write!(gpio, (1, "1"))`

    The operation of reading the current output value of the GPIO is done by

    `read(gpio, 1)`

    See the test/BeagleBone/GPIO_test.jl for more examples.

    Define abstract type for pins/LEDS on the BeagleBone

    SysLED(i::Int32)

    Type representing the system LEDs on the BeagleBone. The LEDs are indexed by i ∈ [1,2,3,4].

    diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md deleted file mode 100644 index a4c478b..0000000 --- a/docs/build/man/installation.md +++ /dev/null @@ -1,132 +0,0 @@ - - - -# Installation Instructions - - - - -## On the BBB - - -On the BeagleBone, first flash it with a Debian image for 32 bit ARM processors (BeagleBoard.org Debian Image 2017-03-19) using a micro-SD by following [this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/). You may also include a Julia v0.6 tarball, alternatively transferring it using after an installation. - - -If using the provided SD card, flash the BB by holding down S2 for about 5 seconds while connecting the BB to 5V power. Keep the button pressed until the four system LEDs (D2/D3/D4/D5) start blinking in a periodical sequence. Leave the BB alone for 15-20 minutes while flashing, until all four lights are turned off (or on). Power off the BB, remove the SD card, and power it on again. - - -Log on to the BB via SSH by - - -``` -`ssh debian@192.168.7.2' -``` - - -an unpack the tarball. Julia should now be operational by running - - -``` -`/home/debian/julia-/bin/julia' -``` - - -and before leaving the BB, remove the distibution specific tag by renaming - - -``` -`mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' -``` - - - - -## On the HOST - - -To get started, first install Julia v0.6.X on the PC running a Linux distribution by following the instructions specified [here](https://github.com/JuliaLang/julia/blob/master/README.md). So far, the system has only been tested on Ubuntu 14.04 and 16.04. - - -Once Julia is installed, run - - -``` -`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)' -``` - - -in the Julia prompt to install all dependencies on the HOST, the source code is then located in `./julia/v0.6/LabCOnnections'. - - -If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus' repository which wraps the`linux/spi/spidev'. Simply - - -``` -`cd && cd .julia/v0.6' -`git clone https://github.com/mgreiff/serbus' -``` - - -to get the latest revision of the serbus fork. - - -To update the BB with the latest revision of the code, - - -``` -`cd && cd .julia/v0.6/LabConnection/util' -`./flash_BB.sh' -``` - - -This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB. - - - - -## Setting up automatic communication - - -To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system - - -``` -`ssh debian@192.168.7.2' -`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) -``` - - -Then execute the commands - - -`sudo systemctl enable juliaserver` (on the BeagleBone) `sudo systemctl start juliaserver` (on the BeagleBone) - - -After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. - - -```@systemConfiguration - -``` - - - - -## Debugging - - -No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root: - - -``` -sudo /home/debian/julia/bin/julia -``` - - -and run the startup script: - - -``` -include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl") -``` - diff --git a/docs/build/man/installation/index.html b/docs/build/man/installation/index.html new file mode 100644 index 0000000..64d2ca5 --- /dev/null +++ b/docs/build/man/installation/index.html @@ -0,0 +1,6 @@ + +Installation Instructions · LabConnections

    Installation Instructions

    <a id='Installation-Instructions-1'></a>

    Installation Instructions

    In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black. If you already have a prepared micro-SD card for flashing a BeagleBone, then you can safely skip the first section of these instructions.

    <a id='On-the-BBB-1'></a>

    Preparing a micro-SD card

    First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BeagleBone. Start by downloading the Debian image here (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card (this guide is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found here. Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under /home/debian, and unzip it. Make sure that the Julia folder has the correct name by typing

    `mv /home/debian/julia-<distro specific tag>/bin/julia /home/debian/julia/bin/julia'

    The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found here. Congratulations, you now have a prepared micro-SD card ready for flashing BeagleBones.

    Flashing the BeagleBone

    Insert a prepared micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again).

    Trying out the BeagleBone

    Now your BeagleBone is ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing

    `ssh debian@192.168.7.2'

    The default password is temppwd. You are now logged in to the BeagleBone running Debian. The Julia binary should be located at /home/debian/julia-/bin/julia. You can now start a Julia REPL on the BeagleBone by typing

    `/home/debian/julia-<distro specific tag>/bin/julia'

    If this works correctly, then you have a functioning BeagleBone ready for use with the LabConnections.jl package.

    <a id='On-the-HOST-1'></a>

    Setting up the host computer

    To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified here. Once Julia is installed, run

    using Pkg
    +`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)'

    in the Julia REPL to install all dependencies on the host computer. The source code is then located in `./julia/v1.0/LabConnections'.

    If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked serbus' repository which wraps thelinux/spi/spidev'. Simply

    `cd && cd .julia/v0.6'
    +`git clone https://github.com/mgreiff/serbus'

    to get the latest revision of the serbus fork.

    To update the BB with the latest revision of the code,

    `cd && cd .julia/v0.6/LabConnection/util'
    +`./flash_BB.sh'

    This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB.

    <a id='Setting-up-automatic-communication-1'></a>

    Setting up automatic communication

    To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system

    `ssh debian@192.168.7.2'
    +`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone)

    Then execute the commands

    sudo systemctl enable juliaserver (on the BeagleBone) sudo systemctl start juliaserver (on the BeagleBone)

    After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer.

    <a id='Debugging-1'></a>

    Debugging

    No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root:

    sudo /home/debian/julia/bin/julia

    and run the startup script:

    include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl")
    diff --git a/docs/build/man/introduction.md b/docs/build/man/introduction.md deleted file mode 100644 index 6d7027e..0000000 --- a/docs/build/man/introduction.md +++ /dev/null @@ -1,10 +0,0 @@ - - - -# Introduction - - - - -## Installation - diff --git a/docs/build/man/introduction/index.html b/docs/build/man/introduction/index.html new file mode 100644 index 0000000..1410692 --- /dev/null +++ b/docs/build/man/introduction/index.html @@ -0,0 +1,2 @@ + +Introduction · LabConnections diff --git a/docs/build/search/index.html b/docs/build/search/index.html new file mode 100644 index 0000000..be304c7 --- /dev/null +++ b/docs/build/search/index.html @@ -0,0 +1,2 @@ + +Search · LabConnections

    Search

    Search

    Number of results: loading...

      diff --git a/docs/build/search_index.js b/docs/build/search_index.js new file mode 100644 index 0000000..f70efb2 --- /dev/null +++ b/docs/build/search_index.js @@ -0,0 +1,3 @@ +var documenterSearchIndex = {"docs": +[{"location":"examples/examples/#Examples-1","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"The following examples may be run from the BB, and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the following line in the Julia prompt","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"push!(LOAD_PATH, \"/home/debian/juliapackages\")","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"When running the examples with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in parallel. See the configuration page for information on which functionality specific pins support.","category":"page"},{"location":"examples/examples/#Example-with-LEDs-(BB)-1","page":"Examples","title":"Example with LEDs (BB)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"To test the system LED functionality of the Julia code from the BBB, open a Julia prompt and run the SYSLEDtest.jl file","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"include(\"/home/debian/juliapackages/LabConnections/test/BeagleBone/SYS_LED_test.jl\")","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"This example runs a test with hardware in the loop, exporting and unexporting the SYS_LED devices and blinking led D2-D5 in a sequence over 1 second, alternating with D2/D4 and D3/D5 on/off.","category":"page"},{"location":"examples/examples/#Example-with-GPIOs-(BB)-1","page":"Examples","title":"Example with GPIOs (BB)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"To test the GPIO functionality of the Julia code from the BBB, open a Julia prompt and run the GPIO_test.jl file","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"include(\"/home/debian/juliapackages/LabConnections/test/BeagleBone/GPIO_test.jl\")","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"This again runs the tests with the BBB in the loop, testing exception handling exporting of the file system and also runs all the GPIOs on the board high/low at a 0.1 period time over 1 second to demonstrate the IO communication visually.","category":"page"},{"location":"examples/examples/#Example-with-PWM-(BB)-1","page":"Examples","title":"Example with PWM (BB)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"To test the PWM functionality of the Julia code from the BBB, open a Julia prompt and run the PWM_test.jl file","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"include(\"/home/debian/juliapackages/LabConnections/test/BeagleBone/PWM_test.jl\")","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"This runs the PWM tests with the BBB in the loop, testing exception handling exporting of the file system. In addition, it runs all the PWM pins on the board with a duty cycle of 0.5 over a period time over 1 second to demonstrate the IO communication visually.","category":"page"},{"location":"examples/examples/#Example-with-SPI-(BB)-1","page":"Examples","title":"Example with SPI (BB)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"All development on the SPI is currently done in C in a for of the serbus package. Consequently, this example is currently run completely separate from the LabConnections.","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"Make sure that the serbus package exists in the /juliapackages/ directory, where it is automatically placed when transferring code to the BB using the ./flash_BB shell script. Then simply run","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"cp /home/debian/juliapackages/serbus/bb_spi.sh /home/debian","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"and execute","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"./bb_spi.sh","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"in the /home/debian/ directory. The program then","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"Compiles a device tree overlay (should SPI1 be used)\nCreates the binaries for the SPI driver and example\nRuns the MCP3903 example script located in spi_MCP3903.c","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"The purpose of the program is to configure the ADC to operate in the continuous mode and then read the registers, outputting the measurements in the terminal.","category":"page"},{"location":"examples/examples/#Example-with-LEDs-(HOST)-1","page":"Examples","title":"Example with LEDs (HOST)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"To operate the LEDs from the host computer, simply connect the BBB to the HOST via USB and run the \"testLED.jl\" on the HOST","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"cd && cd .julia/v0.6/LabConnections/Examples/ && julia testLED.jl","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"","category":"page"},{"location":"examples/testing/#Tests-1","page":"Tests","title":"Tests","text":"","category":"section"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"The BeagleBone tests can be run on any computer, regrdless of their file-syste. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis.","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"To run the tests, simply enter the /test/ directory and run","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"julia run_tests.jl","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"If the tests are to be run on the BB with hardware in the loop, run","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"julia run_tests.jl","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"on the BB, to run examples separately, see","category":"page"},{"location":"#LabConnections.jl-Manual-1","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"CurrentModule = LabConnections","category":"page"},{"location":"#Examples-1","page":"LabConnections.jl Manual","title":"Examples","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"Pages = [\"examples/examples.md\", \"examples/testing.md\"]\nDepth = 1","category":"page"},{"location":"#Guide-1","page":"LabConnections.jl Manual","title":"Guide","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"Pages = [\"man/introduction.md\", \"man/installation.md\"]\nDepth = 1","category":"page"},{"location":"#Functions-1","page":"LabConnections.jl Manual","title":"Functions","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"Pages = [\"lib/io_devices.md\", \"lib/functions.md\"]","category":"page"},{"location":"#Documentation-Index-1","page":"LabConnections.jl Manual","title":"Documentation Index","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"Pages = [\"lib/io_devices.md\", \"lib/functions.md\"]\nDepth = 1","category":"page"},{"location":"lib/functions/#","page":"Available functions","title":"Available functions","text":"Pages = [\"functions.md\"]","category":"page"},{"location":"lib/functions/#Available-functions-1","page":"Available functions","title":"Available functions","text":"","category":"section"},{"location":"lib/functions/#","page":"Available functions","title":"Available functions","text":"Modules = [LabConnections.BeagleBone]\nOrder = [:function]","category":"page"},{"location":"lib/functions/#LabConnections.BeagleBone.run_server","page":"Available functions","title":"LabConnections.BeagleBone.run_server","text":"run_server(port=2001; debug=false)\n\nRun a server on port that listens for commands from computer Optional debug keyword disables blinking system leds.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#Base.read","page":"Available functions","title":"Base.read","text":"l = read(led::SysLED, debug::Bool=false)\n\nReads the current brightness value from the LED 'SysLED'.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#Base.read","page":"Available functions","title":"Base.read","text":"l = read(pwm::PWM, operation::Int32, debug::Bool=false)\n\nReads the current value from an operation on a GPIO.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#Base.read","page":"Available functions","title":"Base.read","text":"l = read(gpio::GPIO, operation::Int32, debug::Bool=false)\n\nReads the current value from an operation on a GPIO.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}","page":"Available functions","title":"LabConnections.BeagleBone.assert_pwm_write","text":"assert_pwm_write(operation::Int32, entry::String)\n\nAssertsion for the PWM input data.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.bbparse-Tuple{Any}","page":"Available functions","title":"LabConnections.BeagleBone.bbparse","text":"bbparse(cmd)\n\nParse and execute the command cmd.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}","page":"Available functions","title":"LabConnections.BeagleBone.bbparse","text":"bbparse(l::Tuple, sock)\n\nParse input on the form l=(iswrite, ndev, cmd1, cmd2, ..., cmdn) where if iswrite cmdi = (devname, id, val) and if not iswrite cmdi = (devname, id) and send back on socket (vals, timestamps).\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.closedev-Tuple{String,Int32}","page":"Available functions","title":"LabConnections.BeagleBone.closedev","text":"closedev(dev_name::String, i::Int32)\n\nCloses down a currently active device of type 'dev_name' at index 'i' on the BeagleBone, and removes it from the dict of currently active devices.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.export_gpio-Tuple{Int32}","page":"Available functions","title":"LabConnections.BeagleBone.export_gpio","text":"export_gpio(i::Int32, debug::Bool=false)\n\nExport the GPIO file system, either for real-time or testing usecases.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.export_led","page":"Available functions","title":"LabConnections.BeagleBone.export_led","text":"export_led(i::Int32, debug::Bool=false)\n\nExports a dummy filesystem for testing the LED implementation\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.export_pwm-Tuple{Int32}","page":"Available functions","title":"LabConnections.BeagleBone.export_pwm","text":"export_gpio(i::Int32, debug::Bool=false)\n\nExport the GPIO file system, either for real-time or testing usecases.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.getdev-Tuple{String,Int32}","page":"Available functions","title":"LabConnections.BeagleBone.getdev","text":"dev = getdev(dev_name::String, i::Int32)\n\nRetrieves the active device of type dev_name at index 'i'.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.initdev-Tuple{String,Int32}","page":"Available functions","title":"LabConnections.BeagleBone.initdev","text":"active_device = initdev(dev_name::String, i:Int32)\n\nInitializes a new device of type 'devname' at index 'i' on the BeagleBone, and adds it to the dict of currently active devices. Returns the initialized device 'activedevice'.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.listdev-Tuple{}","page":"Available functions","title":"LabConnections.BeagleBone.listdev","text":"message = listdev()\n\nLists all the active devices as an insidence array for testing.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.printdev-Tuple{String,Int32}","page":"Available functions","title":"LabConnections.BeagleBone.printdev","text":"message = printdev()\n\nPrints all the active devices and writes out specifics of a single devices.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.teardown","page":"Available functions","title":"LabConnections.BeagleBone.teardown","text":"teardown(led::SysLED, debug::Bool=false)\n\nCloses all open filestreams for the SysLED 'led'.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.teardown","page":"Available functions","title":"LabConnections.BeagleBone.teardown","text":"teardown(gpio::GPIO, debug::Bool=false)\n\nCloses all open streams on the GPIO, and unexports it from the file system.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.teardown","page":"Available functions","title":"LabConnections.BeagleBone.teardown","text":"teardown!(pwd::PWM)\n\nCloses all open streams on the PWM, and unexports it from the file system\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.to_string","page":"Available functions","title":"LabConnections.BeagleBone.to_string","text":"to_string(led::SysLED, debug::Bool=false)\n\nGenerates a string representation of the GPIO device.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.to_string","page":"Available functions","title":"LabConnections.BeagleBone.to_string","text":"to_string(gpio::GPIO, debug::Bool=false)\n\nGenerates a string representation of the GPIO device.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.to_string","page":"Available functions","title":"LabConnections.BeagleBone.to_string","text":"to_string(pwm::PWM,, debug::Bool=false)\n\nGenerates a string representation of the GPIO device.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.write!","page":"Available functions","title":"LabConnections.BeagleBone.write!","text":"write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false)\n\nWrites an entry to an operation on a GPIO, of the form args = (operation, entry).\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.write!","page":"Available functions","title":"LabConnections.BeagleBone.write!","text":"write!(led::SysLED, val::Bool, debug::Bool=false)\n\nTurns the LED 'SysLed' on/off for val = true/false respectively.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.write!","page":"Available functions","title":"LabConnections.BeagleBone.write!","text":"write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false)\n\nWrites an entry to an operation on the PWM, of the form args = (operation, entry).\n\n\n\n\n\n","category":"function"},{"location":"lib/io_devices/#","page":"Available devices","title":"Available devices","text":"Pages = [\"io_devices.md\"]","category":"page"},{"location":"lib/io_devices/#Available-devices-1","page":"Available devices","title":"Available devices","text":"","category":"section"},{"location":"lib/io_devices/#","page":"Available devices","title":"Available devices","text":"Modules = [LabConnections.BeagleBone]\nOrder = [:type]","category":"page"},{"location":"lib/io_devices/#LabConnections.BeagleBone.Debug","page":"Available devices","title":"LabConnections.BeagleBone.Debug","text":"Debug(i::Int32)\n\nType for debugging and precompile.\n\n\n\n\n\n","category":"type"},{"location":"lib/io_devices/#LabConnections.BeagleBone.GPIO","page":"Available devices","title":"LabConnections.BeagleBone.GPIO","text":"GPIO(i::Int32)\n\nLowest form of communication with the GPIO pins. The available pins are listed in the \"channel\" parameter, and appear as directories in /sys/class/gpio after being exported. For instance, to setup a GPIO on \"gpio112\", configure it as an output pin and set it to high, the following code would be used.\n\n`gpio = GPIO(1)`\n`write!(gpio, (2,\"out\"))`\n`write!(gpio, (1, \"1\"))`\n\nThe operation of reading the current output value of the GPIO is done by\n\n`read(gpio, 1)`\n\nSee the test/BeagleBone/GPIO_test.jl for more examples.\n\n\n\n\n\n","category":"type"},{"location":"lib/io_devices/#LabConnections.BeagleBone.IO_Object","page":"Available devices","title":"LabConnections.BeagleBone.IO_Object","text":"Define abstract type for pins/LEDS on the BeagleBone\n\n\n\n\n\n","category":"type"},{"location":"lib/io_devices/#LabConnections.BeagleBone.SysLED","page":"Available devices","title":"LabConnections.BeagleBone.SysLED","text":"SysLED(i::Int32)\n\nType representing the system LEDs on the BeagleBone. The LEDs are indexed by i ∈ [1,2,3,4].\n\n\n\n\n\n","category":"type"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Installation-Instructions-1","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black. If you already have a prepared micro-SD card for flashing a BeagleBone, then you can safely skip the first section of these instructions.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Preparing-a-micro-SD-card-1","page":"Installation Instructions","title":"Preparing a micro-SD card","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BeagleBone. Start by downloading the Debian image here (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card (this guide is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found here. Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under /home/debian, and unzip it. Make sure that the Julia folder has the correct name by typing","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found here. Congratulations, you now have a prepared micro-SD card ready for flashing BeagleBones.","category":"page"},{"location":"man/installation/#Flashing-the-BeagleBone-1","page":"Installation Instructions","title":"Flashing the BeagleBone","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"Insert a prepared micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again).","category":"page"},{"location":"man/installation/#Trying-out-the-BeagleBone-1","page":"Installation Instructions","title":"Trying out the BeagleBone","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"Now your BeagleBone is ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`ssh debian@192.168.7.2'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"The default password is temppwd. You are now logged in to the BeagleBone running Debian. The Julia binary should be located at /home/debian/julia-/bin/julia. You can now start a Julia REPL on the BeagleBone by typing","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`/home/debian/julia-/bin/julia'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"If this works correctly, then you have a functioning BeagleBone ready for use with the LabConnections.jl package.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Setting-up-the-host-computer-1","page":"Installation Instructions","title":"Setting up the host computer","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified here. Once Julia is installed, run","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"using Pkg\n`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"in the Julia REPL to install all dependencies on the host computer. The source code is then located in `./julia/v1.0/LabConnections'.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked serbus' repository which wraps thelinux/spi/spidev'. Simply","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`cd && cd .julia/v0.6'\n`git clone https://github.com/mgreiff/serbus'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"to get the latest revision of the serbus fork.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"To update the BB with the latest revision of the code, ","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`cd && cd .julia/v0.6/LabConnection/util'\n`./flash_BB.sh'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Setting-up-automatic-communication-1","page":"Installation Instructions","title":"Setting up automatic communication","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`ssh debian@192.168.7.2'\n`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone)","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"Then execute the commands","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"sudo systemctl enable juliaserver (on the BeagleBone) sudo systemctl start juliaserver (on the BeagleBone)","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Debugging-1","page":"Installation Instructions","title":"Debugging","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root:","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"sudo /home/debian/julia/bin/julia","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"and run the startup script:","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"include(\"/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl\")","category":"page"},{"location":"man/introduction/#Introduction-1","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"man/introduction/#Installation-1","page":"Introduction","title":"Installation","text":"","category":"section"}] +} diff --git a/docs/make.jl b/docs/make.jl index 56a17c7..7dcc9d1 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -10,7 +10,7 @@ using Documenter, LabConnections # osname = "linux" # ) -makedocs(modules=[LabConnections]) +makedocs(modules=[LabConnections],format=Documenter.HTML(),sitename="LabConnections") #makedocs( # format = :html, From 4ab5fd4878de48896e305d9fb2d75b5718d41eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 13:44:02 +0200 Subject: [PATCH 13/47] Changed from html to md format --- docs/build/assets/Documenter.css | 18 + docs/build/assets/arrow.svg | 63 --- docs/build/assets/documenter.css | 601 ------------------------ docs/build/assets/documenter.js | 132 ------ docs/build/assets/mathjaxhelper.js | 25 + docs/build/assets/search.js | 250 ---------- docs/build/examples/examples.md | 117 +++++ docs/build/examples/examples/index.html | 2 - docs/build/examples/testing.md | 27 ++ docs/build/examples/testing/index.html | 2 - docs/build/index.html | 2 - docs/build/index.md | 65 +++ docs/build/lib/functions.md | 294 ++++++++++++ docs/build/lib/functions/index.html | 2 - docs/build/lib/io_devices.md | 64 +++ docs/build/lib/io_devices/index.html | 4 - docs/build/man/installation.md | 161 +++++++ docs/build/man/installation/index.html | 6 - docs/build/man/introduction.md | 10 + docs/build/man/introduction/index.html | 2 - docs/build/search/index.html | 2 - docs/build/search_index.js | 3 - docs/make.jl | 31 +- 23 files changed, 783 insertions(+), 1100 deletions(-) create mode 100644 docs/build/assets/Documenter.css delete mode 100644 docs/build/assets/arrow.svg delete mode 100644 docs/build/assets/documenter.css delete mode 100644 docs/build/assets/documenter.js create mode 100644 docs/build/assets/mathjaxhelper.js delete mode 100644 docs/build/assets/search.js create mode 100644 docs/build/examples/examples.md delete mode 100644 docs/build/examples/examples/index.html create mode 100644 docs/build/examples/testing.md delete mode 100644 docs/build/examples/testing/index.html delete mode 100644 docs/build/index.html create mode 100644 docs/build/index.md create mode 100644 docs/build/lib/functions.md delete mode 100644 docs/build/lib/functions/index.html create mode 100644 docs/build/lib/io_devices.md delete mode 100644 docs/build/lib/io_devices/index.html create mode 100644 docs/build/man/installation.md delete mode 100644 docs/build/man/installation/index.html create mode 100644 docs/build/man/introduction.md delete mode 100644 docs/build/man/introduction/index.html delete mode 100644 docs/build/search/index.html delete mode 100644 docs/build/search_index.js diff --git a/docs/build/assets/Documenter.css b/docs/build/assets/Documenter.css new file mode 100644 index 0000000..f7ae84a --- /dev/null +++ b/docs/build/assets/Documenter.css @@ -0,0 +1,18 @@ +div.wy-menu-vertical ul.current li.toctree-l3 a { + font-weight: bold; +} + +a.documenter-source { + float: right; +} + +.documenter-methodtable pre { + margin-left: 0px; + margin-right: 0px; + margin-top: 0px; + padding: 0px; +} + +.documenter-methodtable pre.documenter-inline { + display: inline; +} diff --git a/docs/build/assets/arrow.svg b/docs/build/assets/arrow.svg deleted file mode 100644 index ee2798d..0000000 --- a/docs/build/assets/arrow.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/docs/build/assets/documenter.css b/docs/build/assets/documenter.css deleted file mode 100644 index 7cd2662..0000000 --- a/docs/build/assets/documenter.css +++ /dev/null @@ -1,601 +0,0 @@ -/* - * The default CSS style for Documenter.jl generated sites - * - * Heavily inspired by the Julia Sphinx theme - * https://github.com/JuliaLang/JuliaDoc - * which extends the sphinx_rtd_theme - * https://github.com/snide/sphinx_rtd_theme - * - * Part of Documenter.jl - * https://github.com/JuliaDocs/Documenter.jl - * - * License: MIT - */ - -/* fonts */ -body, input { - font-family: 'Lato', 'Helvetica Neue', Arial, sans-serif; - font-size: 16px; - color: #222; - text-rendering: optimizeLegibility; -} - -pre, code, kbd { - font-family: 'Roboto Mono', Monaco, courier, monospace; - font-size: 0.90em; -} - -pre code { - font-size: 1em; -} - -a { - color: #2980b9; - text-decoration: none; -} - -a:hover { - color: #3091d1; -} - -a:visited { - color: #9b59b6; -} - -body { - line-height: 1.5; -} - -h1 { - font-size: 1.75em; -} - -/* Unless the

      the is very first thing on the page (i.e. the second element - * in the
      , * after the
      , we add some additional styling to it - * to make it stand out a bit more. This way we get a reasonable fallback if CSS3 - * selectors are not supported in the browser. - */ -article > h1:not(:nth-child(2)) { - margin: 2.5em 0 0; - padding-bottom: 0.30em; - border-bottom: 1px solid #e5e5e5; -} -h2 { - font-size: 1.50em; - margin: 2.3em 0 0; - padding-bottom: 0.25em; - border-bottom: 1px solid #e5e5e5; -} -h3 { - font-size: 1.25em; - margin: 2.0em 0 0; -} -h4 { font-size: 1.15em; } -h5 { font-size: 1.10em; } -h6 { font-size: 1em; } - -h4, h5, h6 { - margin-top: 1.5em; - margin-bottom: 1em; -} - -img { - max-width: 100%; -} - -table { - border-collapse: collapse; - margin: 1em 0; -} - -th, td { - border: 1px solid #e1e4e5; - padding: 0.5em 1em; -} - -th { - border-bottom-width: 2px; -} - -tr:nth-child(even) { - background-color: #f3f6f6; -} - -hr { - border: 0; - border-top: 1px solid #e5e5e5; -} - -/* Inline code and code blocks */ - -code { - padding: 0.1em; - background-color: rgba(0,0,0,.04); - border-radius: 3px; -} - -pre { - background-color: #f5f5f5; - border: 1px solid #dddddd; - border-radius: 3px; - padding: 0.5em; - overflow: auto; -} - -pre code { - padding: 0; - background-color: initial; -} - -kbd { - font-size: 0.70em; - display: inline-block; - padding: 0.1em 0.5em 0.4em 0.5em; - line-height: 1.0em; - color: #444d56; - vertical-align: middle; - background-color: #fafbfc; - border: solid 1px #c6cbd1; - border-bottom-color: #959da5; - border-radius: 3px; - box-shadow: inset 0 -1px 0 #959da5; -} - -/* Headers in admonitions and docstrings */ -.admonition h1, -article section.docstring h1 { - font-size: 1.25em; -} - -.admonition h2, -article section.docstring h2 { - font-size: 1.10em; -} - -.admonition h3, -.admonition h4, -.admonition h5, -.admonition h6, -article section.docstring h3, -article section.docstring h4, -article section.docstring h5, -article section.docstring h6 { - font-size: 1em; -} - -/* Navigation */ -nav.toc { - position: fixed; - top: 0; - left: 0; - bottom: 0; - width: 20em; - display: flex; - flex-flow: column nowrap; - overflow-y: auto; - padding: 1em 0 0 0; - background-color: #fcfcfc; - box-shadow: inset -14px 0px 5px -12px rgb(210,210,210); -} - -nav.toc .logo { - margin: 0 auto; - display: block; - max-height: 6em; - max-width: 18em; -} - -nav.toc h1 { - text-align: center; - margin-top: .57em; - margin-bottom: 0; -} - -nav.toc select { - display: block; - height: 2em; - flex-shrink: 0; - padding: 0 1.6em 0 1em; - min-width: 7em; - max-width: 90%; - max-width: calc(100% - 5em); - margin: 0 auto; - font-size: .83em; - border: 1px solid #c9c9c9; - border-radius: 1em; - - /* TODO: doesn't seem to be centered on Safari */ - text-align: center; - text-align-last: center; - - appearance: none; - -moz-appearance: none; - -webkit-appearance: none; - - background: white url("arrow.svg"); - background-size: 1.155em; - background-repeat: no-repeat; - background-position: right; -} - -nav.toc select:hover { - border: 1px solid #a0a0a0; -} - -nav.toc select option { - text-align: center; -} - -nav.toc input { - display: block; - height: 2em; - width: 90%; - width: calc(100% - 5em); - margin: 1.2em auto; - padding: 0 1em; - border: 1px solid #c9c9c9; - border-radius: 1em; - font-size: .83em; -} - -nav.toc > ul * { - margin: 0; -} - -nav.toc > ul { - min-height: 2em; - overflow-y: auto; - margin: 0; -} - -nav.toc > ul > li:last-child { - padding-bottom: 1em; -} - -nav.toc ul { - color: #404040; - padding: 0; - list-style: none; -} - -nav.toc ul .toctext { - color: inherit; - display: block; -} - -nav.toc ul a:hover { - color: #fcfcfc; - background-color: #4e4a4a; -} - -nav.toc ul.internal a { - color: inherit; - display: block; -} - -nav.toc ul.internal a:hover { - background-color: #d6d6d6; -} - -nav.toc ul.internal { - background-color: #e3e3e3; - box-shadow: inset -14px 0px 5px -12px rgb(210,210,210); - list-style: none; -} - -nav.toc ul.internal li.toplevel { - border-top: 1px solid #909090; - font-weight: bold; -} - -nav.toc ul.internal li.toplevel:first-child { - border-top: none; -} - -nav.toc .toctext { - padding-top: 0.3em; - padding-bottom: 0.3em; - padding-right: 1em; -} - -nav.toc ul .toctext { - padding-left: 1em; -} - -nav.toc ul ul .toctext { - padding-left: 2em; -} - -nav.toc ul ul ul .toctext { - padding-left: 3em; -} - -nav.toc li.current > .toctext { - border-top: 1px solid #c9c9c9; - border-bottom: 1px solid #c9c9c9; - color: #404040; - font-weight: bold; - background-color: white; -} - -nav.toc ul::-webkit-scrollbar { - width: .4em; - background: none; -} - -nav.toc ul::-webkit-scrollbar-thumb { - border-radius: 5px; - background: #c9c9c9; -} - -nav.toc ul::-webkit-scrollbar-thumb:hover { - border-radius: 5px; - background: #aaaaaa; -} - -article { - margin-left: 20em; - min-width: 20em; - max-width: 48em; - padding: 2em; -} - -article > header {} - -article > header div#topbar { - display: none; -} - -article > header nav ul { - display: inline-block; - list-style: none; - margin: 0; - padding: 0; -} - -article > header nav li { - display: inline-block; - padding-right: 0.2em; -} - -article > header nav li:before { - content: "»"; - padding-right: 0.2em; -} - -article > header .edit-page { - float: right; -} - -article > footer {} - -article > footer a.prev { - float: left; -} -article > footer a.next { - float: right; -} - -article > footer a .direction:after { - content: ": "; -} - -article hr { - margin: 1em 0; -} - -article section.docstring { - border: 1px solid #ddd; - margin: 0.5em 0; - padding: 0.5em; - border-radius: 3px; -} - -article section.docstring .docstring-header { - margin-bottom: 1em; -} - -article section.docstring .docstring-binding { - color: #333; - font-weight: bold; -} - -article section.docstring .docstring-category { - font-style: italic; -} - -article section.docstring a.source-link { - display: block; - font-weight: bold; -} - -.nav-anchor, -.nav-anchor:hover, -.nav-anchor:visited { - color: #333; -} - -/* - * Admonitions - * - * Colors (title, body) - * warning: #f0b37e #ffedcc (orange) - * note: #6ab0de #e7f2fa (blue) - * tip: #1abc9c #dbfaf4 (green) -*/ -.admonition { - border-radius: 3px; - background-color: #eeeeee; - margin: 1em 0; -} - -.admonition-title { - border-radius: 3px 3px 0 0; - background-color: #9b9b9b; - padding: 0.15em 0.5em; -} - -.admonition-text { - padding: 0.5em; -} - -.admonition-text > :first-child { - margin-top: 0; -} - -.admonition-text > :last-child { - margin-bottom: 0; -} - -.admonition > .admonition-title:before { - font-family: "FontAwesome"; - margin-right: 5px; - content: "\f06a"; -} - -.admonition.warning > .admonition-title { - background-color: #f0b37e; -} - -.admonition.warning { - background-color: #ffedcc; -} - -.admonition.note > .admonition-title { - background-color: #6ab0de; -} - -.admonition.note { - background-color: #e7f2fa; -} - -.admonition.tip > .admonition-title { - background-color: #1abc9c; -} - -.admonition.tip { - background-color: #dbfaf4; -} - - -/* footnotes */ -.footnote { - padding-left: 0.8em; - border-left: 2px solid #ccc; -} - -/* Search page */ -#search-results .category { - font-size: smaller; -} - -/* Overriding the block style of highligh.js. - * We have to override the padding and the background-color, since we style this - * part ourselves. Specifically, we style the
       surrounding the , while
      - * highlight.js applies the .hljs style directly to the  tag.
      - */
      -.hljs {
      -    background-color: transparent;
      -    padding: 0;
      -}
      -
      -@media only screen and (max-width: 768px) {
      -    nav.toc {
      -        position: fixed;
      -        width: 16em;
      -        left: -16em;
      -        -webkit-overflow-scrolling: touch;
      -        -webkit-transition-property: left; /* Safari */
      -        -webkit-transition-duration: 0.3s; /* Safari */
      -        transition-property: left;
      -        transition-duration: 0.3s;
      -        -webkit-transition-timing-function: ease-out; /* Safari */
      -        transition-timing-function: ease-out;
      -        z-index: 2;
      -        box-shadow: 5px 0px 5px 0px rgb(210,210,210);
      -    }
      -
      -    nav.toc.show {
      -        left: 0;
      -    }
      -
      -    article {
      -        margin-left: 0;
      -        padding: 3em 0.9em 0 0.9em; /* top right bottom left */
      -        overflow-wrap: break-word;
      -    }
      -
      -    article > header {
      -        position: fixed;
      -        left: 0;
      -        z-index: 1;
      -    }
      -
      -    article > header nav, hr {
      -        display: none;
      -    }
      -
      -    article > header div#topbar {
      -        display: block; /* is mobile */
      -        position: fixed;
      -        width: 100%;
      -        height: 1.5em;
      -        padding-top: 1em;
      -        padding-bottom: 1em;
      -        background-color: #fcfcfc;
      -        box-shadow: 0 1px 3px rgba(0,0,0,.26);
      -        top: 0;
      -        -webkit-transition-property: top; /* Safari */
      -        -webkit-transition-duration: 0.3s; /* Safari */
      -        transition-property: top;
      -        transition-duration: 0.3s;
      -    }
      -
      -    article > header div#topbar.headroom--unpinned.headroom--not-top.headroom--not-bottom {
      -        top: -4em;
      -        -webkit-transition-property: top; /* Safari */
      -        -webkit-transition-duration: 0.7s; /* Safari */
      -        transition-property: top;
      -        transition-duration: 0.7s;
      -    }
      -
      -    article > header div#topbar span {
      -        width: 80%;
      -        height: 1.5em;
      -        margin-top: -0.1em;
      -        margin-left: 0.9em;
      -        font-size: 1.2em;
      -        overflow: hidden;
      -    }
      -
      -    article > header div#topbar a.fa-bars {
      -        float: right;
      -        padding: 0.6em;
      -        margin-top: -0.6em;
      -        margin-right: 0.3em;
      -        font-size: 1.5em;
      -    }
      -
      -    article > header div#topbar a.fa-bars:visited {
      -        color: #3091d1;
      -    }
      -
      -    article table {
      -        overflow-x: auto;
      -        display: block;
      -    }
      -
      -    article div.MathJax_Display {
      -        overflow: scroll;
      -    }
      -
      -    article span.MathJax {
      -        overflow: hidden;
      -    }
      -}
      -
      -@media only screen and (max-width: 320px) {
      -    body {
      -        font-size: 15px;
      -    }
      -}
      diff --git a/docs/build/assets/documenter.js b/docs/build/assets/documenter.js
      deleted file mode 100644
      index 761ae29..0000000
      --- a/docs/build/assets/documenter.js
      +++ /dev/null
      @@ -1,132 +0,0 @@
      -/*
      - * Part of Documenter.jl
      - *     https://github.com/JuliaDocs/Documenter.jl
      - *
      - * License: MIT
      - */
      -
      -requirejs.config({
      -    paths: {
      -        'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min',
      -        'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min',
      -        'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.9.3/headroom.min',
      -        'mathjax': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML',
      -        'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min',
      -        'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/julia.min',
      -        'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/julia-repl.min',
      -    },
      -    shim: {
      -        'mathjax' : {
      -            exports: "MathJax"
      -        },
      -        'highlight-julia': ['highlight'],
      -        'highlight-julia-repl': ['highlight'],
      -    }
      -});
      -
      -// Load MathJax
      -require(['mathjax'], function(MathJax) {
      -    MathJax.Hub.Config({
      -      "tex2jax": {
      -        inlineMath: [['$','$'], ['\\(','\\)']],
      -        processEscapes: true
      -      }
      -    });
      -    MathJax.Hub.Config({
      -      config: ["MMLorHTML.js"],
      -      jax: [
      -        "input/TeX",
      -        "output/HTML-CSS",
      -        "output/NativeMML"
      -      ],
      -      extensions: [
      -        "MathMenu.js",
      -        "MathZoom.js",
      -        "TeX/AMSmath.js",
      -        "TeX/AMSsymbols.js",
      -        "TeX/autobold.js",
      -        "TeX/autoload-all.js"
      -      ]
      -    });
      -    MathJax.Hub.Config({
      -      TeX: { equationNumbers: { autoNumber: "AMS" } }
      -    });
      -})
      -
      -require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
      -    $(document).ready(function() {
      -        hljs.initHighlighting();
      -    })
      -
      -})
      -
      -// update the version selector with info from the siteinfo.js and ../versions.js files
      -require(['jquery'], function($) {
      -    $(document).ready(function() {
      -        var version_selector = $("#version-selector");
      -
      -        // add the current version to the selector based on siteinfo.js, but only if the selector is empty
      -        if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
      -            var option = $("");
      -            version_selector.append(option);
      -        }
      -
      -        if (typeof DOC_VERSIONS !== 'undefined') {
      -            var existing_versions = $('#version-selector > option');
      -            var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
      -            DOC_VERSIONS.forEach(function(each) {
      -                var version_url = documenterBaseURL + "/../" + each;
      -                var existing_id = $.inArray(each, existing_versions_texts);
      -                // if not already in the version selector, add it as a new option,
      -                // otherwise update the old option with the URL and enable it
      -                if (existing_id == -1) {
      -                    var option = $("");
      -                    version_selector.append(option);
      -                } else {
      -                    var option = existing_versions[existing_id];
      -                    option.value = version_url;
      -                    option.disabled = false;
      -                }
      -            });
      -        }
      -
      -        // only show the version selector if the selector has been populated
      -        if ($('#version-selector > option').length > 0) {
      -            version_selector.css("visibility", "visible");
      -        }
      -
      -        // Scroll the navigation bar to the currently selected menu item
      -        $("nav.toc > ul").get(0).scrollTop = $(".current").get(0).offsetTop - $("nav.toc > ul").get(0).offsetTop;
      -    })
      -
      -})
      -
      -// mobile
      -require(['jquery', 'headroom'], function($, Headroom) {
      -    $(document).ready(function() {
      -        var navtoc = $("nav.toc");
      -        $("nav.toc li.current a.toctext").click(function() {
      -            navtoc.toggleClass('show');
      -        });
      -        $("article > header div#topbar a.fa-bars").click(function(ev) {
      -            ev.preventDefault();
      -            navtoc.toggleClass('show');
      -            if (navtoc.hasClass('show')) {
      -                var title = $("article > header div#topbar span").text();
      -                $("nav.toc ul li a:contains('" + title + "')").focus();
      -            }
      -        });
      -        $("article#docs").bind('click', function(ev) {
      -            if ($(ev.target).is('div#topbar a.fa-bars')) {
      -                return;
      -            }
      -            if (navtoc.hasClass('show')) {
      -                navtoc.removeClass('show');
      -            }
      -        });
      -        if ($("article > header div#topbar").css('display') == 'block') {
      -            var headroom = new Headroom(document.querySelector("article > header div#topbar"), {"tolerance": {"up": 10, "down": 10}});
      -            headroom.init();
      -        }
      -    })
      -})
      diff --git a/docs/build/assets/mathjaxhelper.js b/docs/build/assets/mathjaxhelper.js
      new file mode 100644
      index 0000000..3561b10
      --- /dev/null
      +++ b/docs/build/assets/mathjaxhelper.js
      @@ -0,0 +1,25 @@
      +MathJax.Hub.Config({
      +  "tex2jax": {
      +    inlineMath: [['$','$'], ['\\(','\\)']],
      +    processEscapes: true
      +  }
      +});
      +MathJax.Hub.Config({
      +  config: ["MMLorHTML.js"],
      +  jax: [
      +    "input/TeX",
      +    "output/HTML-CSS",
      +    "output/NativeMML"
      +  ],
      +  extensions: [
      +    "MathMenu.js",
      +    "MathZoom.js",
      +    "TeX/AMSmath.js",
      +    "TeX/AMSsymbols.js",
      +    "TeX/autobold.js",
      +    "TeX/autoload-all.js"
      +  ]
      +});
      +MathJax.Hub.Config({
      +  TeX: { equationNumbers: { autoNumber: "AMS" } }
      +});
      diff --git a/docs/build/assets/search.js b/docs/build/assets/search.js
      deleted file mode 100644
      index 5d32c3a..0000000
      --- a/docs/build/assets/search.js
      +++ /dev/null
      @@ -1,250 +0,0 @@
      -/*
      - * Part of Documenter.jl
      - *     https://github.com/JuliaDocs/Documenter.jl
      - *
      - * License: MIT
      - */
      -
      -// parseUri 1.2.2
      -// (c) Steven Levithan 
      -// MIT License
      -function parseUri (str) {
      -	var	o   = parseUri.options,
      -		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
      -		uri = {},
      -		i   = 14;
      -
      -	while (i--) uri[o.key[i]] = m[i] || "";
      -
      -	uri[o.q.name] = {};
      -	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
      -		if ($1) uri[o.q.name][$1] = $2;
      -	});
      -
      -	return uri;
      -};
      -parseUri.options = {
      -	strictMode: false,
      -	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
      -	q:   {
      -		name:   "queryKey",
      -		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
      -	},
      -	parser: {
      -		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
      -		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
      -	}
      -};
      -
      -requirejs.config({
      -    paths: {
      -        'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min',
      -        'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.5/lunr.min',
      -        'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min',
      -    }
      -});
      -
      -var currentScript = document.currentScript;
      -
      -require(["jquery", "lunr", "lodash"], function($, lunr, _) {
      -    $("#search-form").submit(function(e) {
      -        e.preventDefault()
      -    })
      -
      -    // list below is the lunr 2.1.3 list minus the intersect with names(Base)
      -    // (all, any, get, in, is, which) and (do, else, for, let, where, while, with)
      -    // ideally we'd just filter the original list but it's not available as a variable
      -    lunr.stopWordFilter = lunr.generateStopWordFilter([
      -        'a',
      -        'able',
      -        'about',
      -        'across',
      -        'after',
      -        'almost',
      -        'also',
      -        'am',
      -        'among',
      -        'an',
      -        'and',
      -        'are',
      -        'as',
      -        'at',
      -        'be',
      -        'because',
      -        'been',
      -        'but',
      -        'by',
      -        'can',
      -        'cannot',
      -        'could',
      -        'dear',
      -        'did',
      -        'does',
      -        'either',
      -        'ever',
      -        'every',
      -        'from',
      -        'got',
      -        'had',
      -        'has',
      -        'have',
      -        'he',
      -        'her',
      -        'hers',
      -        'him',
      -        'his',
      -        'how',
      -        'however',
      -        'i',
      -        'if',
      -        'into',
      -        'it',
      -        'its',
      -        'just',
      -        'least',
      -        'like',
      -        'likely',
      -        'may',
      -        'me',
      -        'might',
      -        'most',
      -        'must',
      -        'my',
      -        'neither',
      -        'no',
      -        'nor',
      -        'not',
      -        'of',
      -        'off',
      -        'often',
      -        'on',
      -        'only',
      -        'or',
      -        'other',
      -        'our',
      -        'own',
      -        'rather',
      -        'said',
      -        'say',
      -        'says',
      -        'she',
      -        'should',
      -        'since',
      -        'so',
      -        'some',
      -        'than',
      -        'that',
      -        'the',
      -        'their',
      -        'them',
      -        'then',
      -        'there',
      -        'these',
      -        'they',
      -        'this',
      -        'tis',
      -        'to',
      -        'too',
      -        'twas',
      -        'us',
      -        'wants',
      -        'was',
      -        'we',
      -        'were',
      -        'what',
      -        'when',
      -        'who',
      -        'whom',
      -        'why',
      -        'will',
      -        'would',
      -        'yet',
      -        'you',
      -        'your'
      -        ])
      -
      -    // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
      -    // would not find anything if searching for "add!", only for the entire qualification
      -    lunr.tokenizer.separator = /[\s\-\.]+/
      -
      -    // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
      -    lunr.trimmer = function (token) {
      -        return token.update(function (s) {
      -            return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
      -        })
      -    }
      -
      -    lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
      -    lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
      -
      -    var index = lunr(function () {
      -        this.ref('location')
      -        this.field('title')
      -        this.field('text')
      -        documenterSearchIndex['docs'].forEach(function(e) {
      -            this.add(e)
      -        }, this)
      -    })
      -    var store = {}
      -
      -    documenterSearchIndex['docs'].forEach(function(e) {
      -        store[e.location] = {title: e.title, category: e.category}
      -    })
      -
      -    $(function(){
      -        function update_search(querystring) {
      -            tokens = lunr.tokenizer(querystring)
      -            results = index.query(function (q) {
      -                tokens.forEach(function (t) {
      -                    q.term(t.toString(), {
      -                        fields: ["title"],
      -                        boost: 100,
      -                        usePipeline: false,
      -                        editDistance: 0,
      -                        wildcard: lunr.Query.wildcard.NONE
      -                    })
      -                    q.term(t.toString(), {
      -                        fields: ["title"],
      -                        boost: 10,
      -                        usePipeline: false,
      -                        editDistance: 2,
      -                        wildcard: lunr.Query.wildcard.NONE
      -                    })
      -                    q.term(t.toString(), {
      -                        fields: ["text"],
      -                        boost: 1,
      -                        usePipeline: true,
      -                        editDistance: 0,
      -                        wildcard: lunr.Query.wildcard.NONE
      -                    })
      -                })
      -            })
      -            $('#search-info').text("Number of results: " + results.length)
      -            $('#search-results').empty()
      -            results.forEach(function(result) {
      -                data = store[result.ref]
      -                link = $('')
      -                link.text(data.title)
      -                link.attr('href', documenterBaseURL+'/'+result.ref)
      -                cat = $('('+data.category+')')
      -                li = $('
    • ').append(link).append(" ").append(cat) - $('#search-results').append(li) - }) - } - - function update_search_box() { - querystring = $('#search-query').val() - update_search(querystring) - } - - $('#search-query').keyup(_.debounce(update_search_box, 250)) - $('#search-query').change(update_search_box) - - search_query_uri = parseUri(window.location).queryKey["q"] - if(search_query_uri !== undefined) { - search_query = decodeURIComponent(search_query_uri.replace(/\+/g, '%20')) - $("#search-query").val(search_query) - } - update_search_box(); - }) -}) diff --git a/docs/build/examples/examples.md b/docs/build/examples/examples.md new file mode 100644 index 0000000..7a6fece --- /dev/null +++ b/docs/build/examples/examples.md @@ -0,0 +1,117 @@ + + + +# Examples + + +The following examples may be run from the BB, and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the following line in the Julia prompt + + +``` +push!(LOAD_PATH, "/home/debian/juliapackages") +``` + + +When running the examples with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in parallel. See the configuration page for information on which functionality specific pins support. + + + + +## Example with LEDs (BB) + + +To test the system LED functionality of the Julia code from the BBB, open a Julia prompt and run the SYS*LED*test.jl file + + +``` +include("/home/debian/juliapackages/LabConnections/test/BeagleBone/SYS_LED_test.jl") +``` + + +This example runs a test with hardware in the loop, exporting and unexporting the SYS_LED devices and blinking led D2-D5 in a sequence over 1 second, alternating with D2/D4 and D3/D5 on/off. + + + + +## Example with GPIOs (BB) + + +To test the GPIO functionality of the Julia code from the BBB, open a Julia prompt and run the GPIO_test.jl file + + +``` +include("/home/debian/juliapackages/LabConnections/test/BeagleBone/GPIO_test.jl") +``` + + +This again runs the tests with the BBB in the loop, testing exception handling exporting of the file system and also runs all the GPIOs on the board high/low at a 0.1 period time over 1 second to demonstrate the IO communication visually. + + + + +## Example with PWM (BB) + + +To test the PWM functionality of the Julia code from the BBB, open a Julia prompt and run the PWM_test.jl file + + +``` +include("/home/debian/juliapackages/LabConnections/test/BeagleBone/PWM_test.jl") +``` + + +This runs the PWM tests with the BBB in the loop, testing exception handling exporting of the file system. In addition, it runs all the PWM pins on the board with a duty cycle of 0.5 over a period time over 1 second to demonstrate the IO communication visually. + + + + +## Example with SPI (BB) + + +All development on the SPI is currently done in C in a for of the serbus package. Consequently, this example is currently run completely separate from the LabConnections. + + +Make sure that the serbus package exists in the /juliapackages/ directory, where it is automatically placed when transferring code to the BB using the ./flash_BB shell script. Then simply run + + +``` +cp /home/debian/juliapackages/serbus/bb_spi.sh /home/debian +``` + + +and execute + + +``` +./bb_spi.sh +``` + + +in the /home/debian/ directory. The program then + + +1. Compiles a device tree overlay (should SPI1 be used) +2. Creates the binaries for the SPI driver and example +3. Runs the MCP3903 example script located in spi_MCP3903.c + + +The purpose of the program is to configure the ADC to operate in the continuous mode and then read the registers, outputting the measurements in the terminal. + + + + +## Example with LEDs (HOST) + + +To operate the LEDs from the host computer, simply connect the BBB to the HOST via USB and run the "testLED.jl" on the HOST + + +``` +cd && cd .julia/v0.6/LabConnections/Examples/ && julia testLED.jl +``` + + +```@systemConfiguration + +``` + diff --git a/docs/build/examples/examples/index.html b/docs/build/examples/examples/index.html deleted file mode 100644 index 4bb0407..0000000 --- a/docs/build/examples/examples/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Examples · LabConnections

      Examples

      Examples

      The following examples may be run from the BB, and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the following line in the Julia prompt

      push!(LOAD_PATH, "/home/debian/juliapackages")

      When running the examples with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in parallel. See the configuration page for information on which functionality specific pins support.

      Example with LEDs (BB)

      To test the system LED functionality of the Julia code from the BBB, open a Julia prompt and run the SYSLEDtest.jl file

      include("/home/debian/juliapackages/LabConnections/test/BeagleBone/SYS_LED_test.jl")

      This example runs a test with hardware in the loop, exporting and unexporting the SYS_LED devices and blinking led D2-D5 in a sequence over 1 second, alternating with D2/D4 and D3/D5 on/off.

      Example with GPIOs (BB)

      To test the GPIO functionality of the Julia code from the BBB, open a Julia prompt and run the GPIO_test.jl file

      include("/home/debian/juliapackages/LabConnections/test/BeagleBone/GPIO_test.jl")

      This again runs the tests with the BBB in the loop, testing exception handling exporting of the file system and also runs all the GPIOs on the board high/low at a 0.1 period time over 1 second to demonstrate the IO communication visually.

      Example with PWM (BB)

      To test the PWM functionality of the Julia code from the BBB, open a Julia prompt and run the PWM_test.jl file

      include("/home/debian/juliapackages/LabConnections/test/BeagleBone/PWM_test.jl")

      This runs the PWM tests with the BBB in the loop, testing exception handling exporting of the file system. In addition, it runs all the PWM pins on the board with a duty cycle of 0.5 over a period time over 1 second to demonstrate the IO communication visually.

      Example with SPI (BB)

      All development on the SPI is currently done in C in a for of the serbus package. Consequently, this example is currently run completely separate from the LabConnections.

      Make sure that the serbus package exists in the /juliapackages/ directory, where it is automatically placed when transferring code to the BB using the ./flash_BB shell script. Then simply run

      cp /home/debian/juliapackages/serbus/bb_spi.sh /home/debian

      and execute

      ./bb_spi.sh

      in the /home/debian/ directory. The program then

      1. Compiles a device tree overlay (should SPI1 be used)
      2. Creates the binaries for the SPI driver and example
      3. Runs the MCP3903 example script located in spi_MCP3903.c

      The purpose of the program is to configure the ADC to operate in the continuous mode and then read the registers, outputting the measurements in the terminal.

      Example with LEDs (HOST)

      To operate the LEDs from the host computer, simply connect the BBB to the HOST via USB and run the "testLED.jl" on the HOST

      cd && cd .julia/v0.6/LabConnections/Examples/ && julia testLED.jl
      diff --git a/docs/build/examples/testing.md b/docs/build/examples/testing.md new file mode 100644 index 0000000..d6c3c74 --- /dev/null +++ b/docs/build/examples/testing.md @@ -0,0 +1,27 @@ + + + +# Tests + + +The BeagleBone tests can be run on any computer, regrdless of their file-syste. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis. + + +To run the tests, simply enter the /test/ directory and run + + +``` +julia run_tests.jl +``` + + +If the tests are to be run on the BB with hardware in the loop, run + + +``` +julia run_tests.jl +``` + + +on the BB, to run examples separately, see + diff --git a/docs/build/examples/testing/index.html b/docs/build/examples/testing/index.html deleted file mode 100644 index b798a0e..0000000 --- a/docs/build/examples/testing/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Tests · LabConnections

      Tests

      Tests

      The BeagleBone tests can be run on any computer, regrdless of their file-syste. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis.

      To run the tests, simply enter the /test/ directory and run

      julia run_tests.jl

      If the tests are to be run on the BB with hardware in the loop, run

      julia run_tests.jl

      on the BB, to run examples separately, see

      diff --git a/docs/build/index.html b/docs/build/index.html deleted file mode 100644 index 42d9b36..0000000 --- a/docs/build/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -LabConnections.jl Manual · LabConnections

      LabConnections.jl Manual

      LabConnections.jl Manual

      Examples

      Guide

      Functions

      Documentation Index

      diff --git a/docs/build/index.md b/docs/build/index.md new file mode 100644 index 0000000..1f15185 --- /dev/null +++ b/docs/build/index.md @@ -0,0 +1,65 @@ + + + +# LabConnections.jl Manual + + + + + + +## Examples + +- [Examples](examples/examples.md#Examples-1) +- [Tests](examples/testing.md#Tests-1) + + + + +## Guide + +- [Introduction](man/introduction.md#Introduction-1) +- [Installation Instructions](man/installation.md#Installation-Instructions-1) + + + + +## Functions + +- [Available devices](lib/io_devices.md#Available-devices-1) +- [Available functions](lib/functions.md#Available-functions-1) + + + + +## Documentation Index + +- [`LabConnections.BeagleBone.Debug`](lib/io_devices.md#LabConnections.BeagleBone.Debug) +- [`LabConnections.BeagleBone.GPIO`](lib/io_devices.md#LabConnections.BeagleBone.GPIO) +- [`LabConnections.BeagleBone.IO_Object`](lib/io_devices.md#LabConnections.BeagleBone.IO_Object) +- [`LabConnections.BeagleBone.SysLED`](lib/io_devices.md#LabConnections.BeagleBone.SysLED) +- [`Base.read`](lib/functions.md#Base.read) +- [`Base.read`](lib/functions.md#Base.read) +- [`Base.read`](lib/functions.md#Base.read) +- [`LabConnections.BeagleBone.assert_pwm_write`](lib/functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) +- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) +- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) +- [`LabConnections.BeagleBone.closedev`](lib/functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) +- [`LabConnections.BeagleBone.export_gpio`](lib/functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) +- [`LabConnections.BeagleBone.export_led`](lib/functions.md#LabConnections.BeagleBone.export_led) +- [`LabConnections.BeagleBone.export_pwm`](lib/functions.md#LabConnections.BeagleBone.export_pwm-Tuple{Int32}) +- [`LabConnections.BeagleBone.getdev`](lib/functions.md#LabConnections.BeagleBone.getdev-Tuple{String,Int32}) +- [`LabConnections.BeagleBone.initdev`](lib/functions.md#LabConnections.BeagleBone.initdev-Tuple{String,Int32}) +- [`LabConnections.BeagleBone.listdev`](lib/functions.md#LabConnections.BeagleBone.listdev-Tuple{}) +- [`LabConnections.BeagleBone.printdev`](lib/functions.md#LabConnections.BeagleBone.printdev-Tuple{String,Int32}) +- [`LabConnections.BeagleBone.run_server`](lib/functions.md#LabConnections.BeagleBone.run_server) +- [`LabConnections.BeagleBone.teardown`](lib/functions.md#LabConnections.BeagleBone.teardown) +- [`LabConnections.BeagleBone.teardown`](lib/functions.md#LabConnections.BeagleBone.teardown) +- [`LabConnections.BeagleBone.teardown`](lib/functions.md#LabConnections.BeagleBone.teardown) +- [`LabConnections.BeagleBone.to_string`](lib/functions.md#LabConnections.BeagleBone.to_string) +- [`LabConnections.BeagleBone.to_string`](lib/functions.md#LabConnections.BeagleBone.to_string) +- [`LabConnections.BeagleBone.to_string`](lib/functions.md#LabConnections.BeagleBone.to_string) +- [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) +- [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) +- [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) + diff --git a/docs/build/lib/functions.md b/docs/build/lib/functions.md new file mode 100644 index 0000000..36fff70 --- /dev/null +++ b/docs/build/lib/functions.md @@ -0,0 +1,294 @@ +- [`Base.read`](functions.md#Base.read) +- [`Base.read`](functions.md#Base.read) +- [`Base.read`](functions.md#Base.read) +- [`LabConnections.BeagleBone.assert_pwm_write`](functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) +- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) +- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) +- [`LabConnections.BeagleBone.closedev`](functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) +- [`LabConnections.BeagleBone.export_gpio`](functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) +- [`LabConnections.BeagleBone.export_led`](functions.md#LabConnections.BeagleBone.export_led) +- [`LabConnections.BeagleBone.export_pwm`](functions.md#LabConnections.BeagleBone.export_pwm-Tuple{Int32}) +- [`LabConnections.BeagleBone.getdev`](functions.md#LabConnections.BeagleBone.getdev-Tuple{String,Int32}) +- [`LabConnections.BeagleBone.initdev`](functions.md#LabConnections.BeagleBone.initdev-Tuple{String,Int32}) +- [`LabConnections.BeagleBone.listdev`](functions.md#LabConnections.BeagleBone.listdev-Tuple{}) +- [`LabConnections.BeagleBone.printdev`](functions.md#LabConnections.BeagleBone.printdev-Tuple{String,Int32}) +- [`LabConnections.BeagleBone.run_server`](functions.md#LabConnections.BeagleBone.run_server) +- [`LabConnections.BeagleBone.teardown`](functions.md#LabConnections.BeagleBone.teardown) +- [`LabConnections.BeagleBone.teardown`](functions.md#LabConnections.BeagleBone.teardown) +- [`LabConnections.BeagleBone.teardown`](functions.md#LabConnections.BeagleBone.teardown) +- [`LabConnections.BeagleBone.to_string`](functions.md#LabConnections.BeagleBone.to_string) +- [`LabConnections.BeagleBone.to_string`](functions.md#LabConnections.BeagleBone.to_string) +- [`LabConnections.BeagleBone.to_string`](functions.md#LabConnections.BeagleBone.to_string) +- [`LabConnections.BeagleBone.write!`](functions.md#LabConnections.BeagleBone.write!) +- [`LabConnections.BeagleBone.write!`](functions.md#LabConnections.BeagleBone.write!) +- [`LabConnections.BeagleBone.write!`](functions.md#LabConnections.BeagleBone.write!) + + + + +# Available functions + +# +**`LabConnections.BeagleBone.run_server`** — *Function*. + + + +```julia +run_server(port=2001; debug=false) +``` + +Run a server on `port` that listens for commands from computer Optional debug keyword disables blinking system leds. + +# +**`Base.read`** — *Function*. + + + +```julia +l = read(led::SysLED, debug::Bool=false) +``` + +Reads the current brightness value from the LED 'SysLED'. + +# +**`Base.read`** — *Function*. + + + +```julia +l = read(pwm::PWM, operation::Int32, debug::Bool=false) +``` + +Reads the current value from an operation on a GPIO. + +# +**`Base.read`** — *Function*. + + + +```julia +l = read(gpio::GPIO, operation::Int32, debug::Bool=false) +``` + +Reads the current value from an operation on a GPIO. + +# +**`LabConnections.BeagleBone.assert_pwm_write`** — *Method*. + + + +```julia +assert_pwm_write(operation::Int32, entry::String) +``` + +Assertsion for the PWM input data. + +# +**`LabConnections.BeagleBone.bbparse`** — *Method*. + + + +```julia +bbparse(cmd) +``` + +Parse and execute the command `cmd`. + +# +**`LabConnections.BeagleBone.bbparse`** — *Method*. + + + +```julia +bbparse(l::Tuple, sock) +``` + +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)` and send back on socket (vals, timestamps). + +# +**`LabConnections.BeagleBone.closedev`** — *Method*. + + + +```julia +closedev(dev_name::String, i::Int32) +``` + +Closes down a currently active device of type 'dev_name' at index 'i' on the BeagleBone, and removes it from the dict of currently active devices. + +# +**`LabConnections.BeagleBone.export_gpio`** — *Method*. + + + +```julia +export_gpio(i::Int32, debug::Bool=false) +``` + +Export the GPIO file system, either for real-time or testing usecases. + +# +**`LabConnections.BeagleBone.export_led`** — *Function*. + + + +```julia +export_led(i::Int32, debug::Bool=false) +``` + +Exports a dummy filesystem for testing the LED implementation + +# +**`LabConnections.BeagleBone.export_pwm`** — *Method*. + + + +```julia +export_gpio(i::Int32, debug::Bool=false) +``` + +Export the GPIO file system, either for real-time or testing usecases. + +# +**`LabConnections.BeagleBone.getdev`** — *Method*. + + + +```julia +dev = getdev(dev_name::String, i::Int32) +``` + +Retrieves the active device of type `dev_name` at index 'i'. + +# +**`LabConnections.BeagleBone.initdev`** — *Method*. + + + +```julia +active_device = initdev(dev_name::String, i:Int32) +``` + +Initializes a new device of type 'dev*name' at index 'i' on the BeagleBone, and adds it to the dict of currently active devices. Returns the initialized device 'active*device'. + +# +**`LabConnections.BeagleBone.listdev`** — *Method*. + + + +```julia +message = listdev() +``` + +Lists all the active devices as an insidence array for testing. + +# +**`LabConnections.BeagleBone.printdev`** — *Method*. + + + +```julia +message = printdev() +``` + +Prints all the active devices and writes out specifics of a single devices. + +# +**`LabConnections.BeagleBone.teardown`** — *Function*. + + + +```julia +teardown(led::SysLED, debug::Bool=false) +``` + +Closes all open filestreams for the SysLED 'led'. + +# +**`LabConnections.BeagleBone.teardown`** — *Function*. + + + +```julia +teardown(gpio::GPIO, debug::Bool=false) +``` + +Closes all open streams on the GPIO, and unexports it from the file system. + +# +**`LabConnections.BeagleBone.teardown`** — *Function*. + + + +```julia +teardown!(pwd::PWM) +``` + +Closes all open streams on the PWM, and unexports it from the file system + +# +**`LabConnections.BeagleBone.to_string`** — *Function*. + + + +```julia +to_string(led::SysLED, debug::Bool=false) +``` + +Generates a string representation of the GPIO device. + +# +**`LabConnections.BeagleBone.to_string`** — *Function*. + + + +```julia +to_string(gpio::GPIO, debug::Bool=false) +``` + +Generates a string representation of the GPIO device. + +# +**`LabConnections.BeagleBone.to_string`** — *Function*. + + + +```julia +to_string(pwm::PWM,, debug::Bool=false) +``` + +Generates a string representation of the GPIO device. + +# +**`LabConnections.BeagleBone.write!`** — *Function*. + + + +```julia +write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false) +``` + +Writes an entry to an operation on a GPIO, of the form args = (operation, entry). + +# +**`LabConnections.BeagleBone.write!`** — *Function*. + + + +```julia +write!(led::SysLED, val::Bool, debug::Bool=false) +``` + +Turns the LED 'SysLed' on/off for val = true/false respectively. + +# +**`LabConnections.BeagleBone.write!`** — *Function*. + + + +```julia +write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false) +``` + +Writes an entry to an operation on the PWM, of the form args = (operation, entry). + diff --git a/docs/build/lib/functions/index.html b/docs/build/lib/functions/index.html deleted file mode 100644 index aa3a00c..0000000 --- a/docs/build/lib/functions/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Available functions · LabConnections

      Available functions

      Available functions

      run_server(port=2001; debug=false)

      Run a server on port that listens for commands from computer Optional debug keyword disables blinking system leds.

      Base.readFunction.
      l = read(led::SysLED, debug::Bool=false)

      Reads the current brightness value from the LED 'SysLED'.

      Base.readFunction.
      l = read(pwm::PWM, operation::Int32, debug::Bool=false)

      Reads the current value from an operation on a GPIO.

      Base.readFunction.
      l = read(gpio::GPIO, operation::Int32, debug::Bool=false)

      Reads the current value from an operation on a GPIO.

      assert_pwm_write(operation::Int32, entry::String)

      Assertsion for the PWM input data.

      bbparse(cmd)

      Parse and execute the command cmd.

      bbparse(l::Tuple, sock)

      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) and send back on socket (vals, timestamps).

      closedev(dev_name::String, i::Int32)

      Closes down a currently active device of type 'dev_name' at index 'i' on the BeagleBone, and removes it from the dict of currently active devices.

      export_gpio(i::Int32, debug::Bool=false)

      Export the GPIO file system, either for real-time or testing usecases.

      export_led(i::Int32, debug::Bool=false)

      Exports a dummy filesystem for testing the LED implementation

      export_gpio(i::Int32, debug::Bool=false)

      Export the GPIO file system, either for real-time or testing usecases.

      dev = getdev(dev_name::String, i::Int32)

      Retrieves the active device of type dev_name at index 'i'.

      active_device = initdev(dev_name::String, i:Int32)

      Initializes a new device of type 'devname' at index 'i' on the BeagleBone, and adds it to the dict of currently active devices. Returns the initialized device 'activedevice'.

      message = listdev()

      Lists all the active devices as an insidence array for testing.

      message = printdev()

      Prints all the active devices and writes out specifics of a single devices.

      teardown(led::SysLED, debug::Bool=false)

      Closes all open filestreams for the SysLED 'led'.

      teardown(gpio::GPIO, debug::Bool=false)

      Closes all open streams on the GPIO, and unexports it from the file system.

      teardown!(pwd::PWM)

      Closes all open streams on the PWM, and unexports it from the file system

      to_string(led::SysLED, debug::Bool=false)

      Generates a string representation of the GPIO device.

      to_string(gpio::GPIO, debug::Bool=false)

      Generates a string representation of the GPIO device.

      to_string(pwm::PWM,, debug::Bool=false)

      Generates a string representation of the GPIO device.

      write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false)

      Writes an entry to an operation on a GPIO, of the form args = (operation, entry).

      write!(led::SysLED, val::Bool, debug::Bool=false)

      Turns the LED 'SysLed' on/off for val = true/false respectively.

      write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false)

      Writes an entry to an operation on the PWM, of the form args = (operation, entry).

      diff --git a/docs/build/lib/io_devices.md b/docs/build/lib/io_devices.md new file mode 100644 index 0000000..f559bd2 --- /dev/null +++ b/docs/build/lib/io_devices.md @@ -0,0 +1,64 @@ +- [`LabConnections.BeagleBone.Debug`](io_devices.md#LabConnections.BeagleBone.Debug) +- [`LabConnections.BeagleBone.GPIO`](io_devices.md#LabConnections.BeagleBone.GPIO) +- [`LabConnections.BeagleBone.IO_Object`](io_devices.md#LabConnections.BeagleBone.IO_Object) +- [`LabConnections.BeagleBone.SysLED`](io_devices.md#LabConnections.BeagleBone.SysLED) + + + + +# Available devices + +# +**`LabConnections.BeagleBone.Debug`** — *Type*. + + + +```julia +Debug(i::Int32) +``` + +Type for debugging and precompile. + +# +**`LabConnections.BeagleBone.GPIO`** — *Type*. + + + +```julia +GPIO(i::Int32) +``` + +Lowest form of communication with the GPIO pins. The available pins are listed in the "channel" parameter, and appear as directories in /sys/class/gpio after being exported. For instance, to setup a GPIO on "gpio112", configure it as an output pin and set it to high, the following code would be used. + +``` +`gpio = GPIO(1)` +`write!(gpio, (2,"out"))` +`write!(gpio, (1, "1"))` +``` + +The operation of reading the current output value of the GPIO is done by + +``` +`read(gpio, 1)` +``` + +See the test/BeagleBone/GPIO_test.jl for more examples. + +# +**`LabConnections.BeagleBone.IO_Object`** — *Type*. + + + +Define abstract type for pins/LEDS on the BeagleBone + +# +**`LabConnections.BeagleBone.SysLED`** — *Type*. + + + +```julia +SysLED(i::Int32) +``` + +Type representing the system LEDs on the BeagleBone. The LEDs are indexed by i ∈ [1,2,3,4]. + diff --git a/docs/build/lib/io_devices/index.html b/docs/build/lib/io_devices/index.html deleted file mode 100644 index 11289fb..0000000 --- a/docs/build/lib/io_devices/index.html +++ /dev/null @@ -1,4 +0,0 @@ - -Available devices · LabConnections

      Available devices

      Available devices

      Debug(i::Int32)

      Type for debugging and precompile.

      GPIO(i::Int32)

      Lowest form of communication with the GPIO pins. The available pins are listed in the "channel" parameter, and appear as directories in /sys/class/gpio after being exported. For instance, to setup a GPIO on "gpio112", configure it as an output pin and set it to high, the following code would be used.

      `gpio = GPIO(1)`
      -`write!(gpio, (2,"out"))`
      -`write!(gpio, (1, "1"))`

      The operation of reading the current output value of the GPIO is done by

      `read(gpio, 1)`

      See the test/BeagleBone/GPIO_test.jl for more examples.

      Define abstract type for pins/LEDS on the BeagleBone

      SysLED(i::Int32)

      Type representing the system LEDs on the BeagleBone. The LEDs are indexed by i ∈ [1,2,3,4].

      diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md new file mode 100644 index 0000000..dfc060a --- /dev/null +++ b/docs/build/man/installation.md @@ -0,0 +1,161 @@ + + + + + + +# Installation Instructions + + +In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black. If you already have a prepared micro-SD card for flashing a BeagleBone, then you can safely skip the first section of these instructions. + + + + + + + +## Preparing a micro-SD card + + +First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BeagleBone. Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. Make sure that the Julia folder has the correct name by typing + + +``` +`mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' +``` + + +The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing BeagleBones. + + + + +## Flashing the BeagleBone + + +Insert a prepared micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again). + + + + +## Trying out the BeagleBone + + +Now your BeagleBone is ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing + + +``` +`ssh debian@192.168.7.2' +``` + + +The default password is `temppwd`. You are now logged in to the BeagleBone running Debian. The Julia binary should be located at `/home/debian/julia-/bin/julia`. You can now start a Julia REPL on the BeagleBone by typing + + +``` +`/home/debian/julia-/bin/julia' +``` + + +If this works correctly, then you have a functioning BeagleBone ready for use with the LabConnections.jl package. + + + + + + + +## Setting up the host computer + + +To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified [here](https://github.com/JuliaLang/julia/blob/master/README.md). Once Julia is installed, run + + +``` +using Pkg +`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)' +``` + + +in the Julia REPL to install all dependencies on the host computer. The source code is then located in `./julia/v1.0/LabConnections'. + + +If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus' repository which wraps the`linux/spi/spidev'. Simply + + +``` +`cd && cd .julia/v0.6' +`git clone https://github.com/mgreiff/serbus' +``` + + +to get the latest revision of the serbus fork. + + +To update the BB with the latest revision of the code, + + +``` +`cd && cd .julia/v0.6/LabConnection/util' +`./flash_BB.sh' +``` + + +This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB. + + + + + + + +## Setting up automatic communication + + +To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system + + +``` +`ssh debian@192.168.7.2' +`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) +``` + + +Then execute the commands + + +`sudo systemctl enable juliaserver` (on the BeagleBone) `sudo systemctl start juliaserver` (on the BeagleBone) + + +After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. + + +```@systemConfiguration + +``` + + + + + + + +## Debugging + + +No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root: + + +``` +sudo /home/debian/julia/bin/julia +``` + + +and run the startup script: + + +``` +include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl") +``` + diff --git a/docs/build/man/installation/index.html b/docs/build/man/installation/index.html deleted file mode 100644 index 64d2ca5..0000000 --- a/docs/build/man/installation/index.html +++ /dev/null @@ -1,6 +0,0 @@ - -Installation Instructions · LabConnections

      Installation Instructions

      <a id='Installation-Instructions-1'></a>

      Installation Instructions

      In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black. If you already have a prepared micro-SD card for flashing a BeagleBone, then you can safely skip the first section of these instructions.

      <a id='On-the-BBB-1'></a>

      Preparing a micro-SD card

      First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BeagleBone. Start by downloading the Debian image here (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card (this guide is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found here. Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under /home/debian, and unzip it. Make sure that the Julia folder has the correct name by typing

      `mv /home/debian/julia-<distro specific tag>/bin/julia /home/debian/julia/bin/julia'

      The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found here. Congratulations, you now have a prepared micro-SD card ready for flashing BeagleBones.

      Flashing the BeagleBone

      Insert a prepared micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again).

      Trying out the BeagleBone

      Now your BeagleBone is ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing

      `ssh debian@192.168.7.2'

      The default password is temppwd. You are now logged in to the BeagleBone running Debian. The Julia binary should be located at /home/debian/julia-/bin/julia. You can now start a Julia REPL on the BeagleBone by typing

      `/home/debian/julia-<distro specific tag>/bin/julia'

      If this works correctly, then you have a functioning BeagleBone ready for use with the LabConnections.jl package.

      <a id='On-the-HOST-1'></a>

      Setting up the host computer

      To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified here. Once Julia is installed, run

      using Pkg
      -`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)'

      in the Julia REPL to install all dependencies on the host computer. The source code is then located in `./julia/v1.0/LabConnections'.

      If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked serbus' repository which wraps thelinux/spi/spidev'. Simply

      `cd && cd .julia/v0.6'
      -`git clone https://github.com/mgreiff/serbus'

      to get the latest revision of the serbus fork.

      To update the BB with the latest revision of the code,

      `cd && cd .julia/v0.6/LabConnection/util'
      -`./flash_BB.sh'

      This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB.

      <a id='Setting-up-automatic-communication-1'></a>

      Setting up automatic communication

      To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system

      `ssh debian@192.168.7.2'
      -`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone)

      Then execute the commands

      sudo systemctl enable juliaserver (on the BeagleBone) sudo systemctl start juliaserver (on the BeagleBone)

      After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer.

      <a id='Debugging-1'></a>

      Debugging

      No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root:

      sudo /home/debian/julia/bin/julia

      and run the startup script:

      include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl")
      diff --git a/docs/build/man/introduction.md b/docs/build/man/introduction.md new file mode 100644 index 0000000..6d7027e --- /dev/null +++ b/docs/build/man/introduction.md @@ -0,0 +1,10 @@ + + + +# Introduction + + + + +## Installation + diff --git a/docs/build/man/introduction/index.html b/docs/build/man/introduction/index.html deleted file mode 100644 index 1410692..0000000 --- a/docs/build/man/introduction/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Introduction · LabConnections diff --git a/docs/build/search/index.html b/docs/build/search/index.html deleted file mode 100644 index be304c7..0000000 --- a/docs/build/search/index.html +++ /dev/null @@ -1,2 +0,0 @@ - -Search · LabConnections

      Search

      Search

      Number of results: loading...

        diff --git a/docs/build/search_index.js b/docs/build/search_index.js deleted file mode 100644 index f70efb2..0000000 --- a/docs/build/search_index.js +++ /dev/null @@ -1,3 +0,0 @@ -var documenterSearchIndex = {"docs": -[{"location":"examples/examples/#Examples-1","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"The following examples may be run from the BB, and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the following line in the Julia prompt","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"push!(LOAD_PATH, \"/home/debian/juliapackages\")","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"When running the examples with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in parallel. See the configuration page for information on which functionality specific pins support.","category":"page"},{"location":"examples/examples/#Example-with-LEDs-(BB)-1","page":"Examples","title":"Example with LEDs (BB)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"To test the system LED functionality of the Julia code from the BBB, open a Julia prompt and run the SYSLEDtest.jl file","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"include(\"/home/debian/juliapackages/LabConnections/test/BeagleBone/SYS_LED_test.jl\")","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"This example runs a test with hardware in the loop, exporting and unexporting the SYS_LED devices and blinking led D2-D5 in a sequence over 1 second, alternating with D2/D4 and D3/D5 on/off.","category":"page"},{"location":"examples/examples/#Example-with-GPIOs-(BB)-1","page":"Examples","title":"Example with GPIOs (BB)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"To test the GPIO functionality of the Julia code from the BBB, open a Julia prompt and run the GPIO_test.jl file","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"include(\"/home/debian/juliapackages/LabConnections/test/BeagleBone/GPIO_test.jl\")","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"This again runs the tests with the BBB in the loop, testing exception handling exporting of the file system and also runs all the GPIOs on the board high/low at a 0.1 period time over 1 second to demonstrate the IO communication visually.","category":"page"},{"location":"examples/examples/#Example-with-PWM-(BB)-1","page":"Examples","title":"Example with PWM (BB)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"To test the PWM functionality of the Julia code from the BBB, open a Julia prompt and run the PWM_test.jl file","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"include(\"/home/debian/juliapackages/LabConnections/test/BeagleBone/PWM_test.jl\")","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"This runs the PWM tests with the BBB in the loop, testing exception handling exporting of the file system. In addition, it runs all the PWM pins on the board with a duty cycle of 0.5 over a period time over 1 second to demonstrate the IO communication visually.","category":"page"},{"location":"examples/examples/#Example-with-SPI-(BB)-1","page":"Examples","title":"Example with SPI (BB)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"All development on the SPI is currently done in C in a for of the serbus package. Consequently, this example is currently run completely separate from the LabConnections.","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"Make sure that the serbus package exists in the /juliapackages/ directory, where it is automatically placed when transferring code to the BB using the ./flash_BB shell script. Then simply run","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"cp /home/debian/juliapackages/serbus/bb_spi.sh /home/debian","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"and execute","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"./bb_spi.sh","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"in the /home/debian/ directory. The program then","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"Compiles a device tree overlay (should SPI1 be used)\nCreates the binaries for the SPI driver and example\nRuns the MCP3903 example script located in spi_MCP3903.c","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"The purpose of the program is to configure the ADC to operate in the continuous mode and then read the registers, outputting the measurements in the terminal.","category":"page"},{"location":"examples/examples/#Example-with-LEDs-(HOST)-1","page":"Examples","title":"Example with LEDs (HOST)","text":"","category":"section"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"To operate the LEDs from the host computer, simply connect the BBB to the HOST via USB and run the \"testLED.jl\" on the HOST","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"cd && cd .julia/v0.6/LabConnections/Examples/ && julia testLED.jl","category":"page"},{"location":"examples/examples/#","page":"Examples","title":"Examples","text":"","category":"page"},{"location":"examples/testing/#Tests-1","page":"Tests","title":"Tests","text":"","category":"section"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"The BeagleBone tests can be run on any computer, regrdless of their file-syste. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis.","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"To run the tests, simply enter the /test/ directory and run","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"julia run_tests.jl","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"If the tests are to be run on the BB with hardware in the loop, run","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"julia run_tests.jl","category":"page"},{"location":"examples/testing/#","page":"Tests","title":"Tests","text":"on the BB, to run examples separately, see","category":"page"},{"location":"#LabConnections.jl-Manual-1","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"CurrentModule = LabConnections","category":"page"},{"location":"#Examples-1","page":"LabConnections.jl Manual","title":"Examples","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"Pages = [\"examples/examples.md\", \"examples/testing.md\"]\nDepth = 1","category":"page"},{"location":"#Guide-1","page":"LabConnections.jl Manual","title":"Guide","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"Pages = [\"man/introduction.md\", \"man/installation.md\"]\nDepth = 1","category":"page"},{"location":"#Functions-1","page":"LabConnections.jl Manual","title":"Functions","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"Pages = [\"lib/io_devices.md\", \"lib/functions.md\"]","category":"page"},{"location":"#Documentation-Index-1","page":"LabConnections.jl Manual","title":"Documentation Index","text":"","category":"section"},{"location":"#","page":"LabConnections.jl Manual","title":"LabConnections.jl Manual","text":"Pages = [\"lib/io_devices.md\", \"lib/functions.md\"]\nDepth = 1","category":"page"},{"location":"lib/functions/#","page":"Available functions","title":"Available functions","text":"Pages = [\"functions.md\"]","category":"page"},{"location":"lib/functions/#Available-functions-1","page":"Available functions","title":"Available functions","text":"","category":"section"},{"location":"lib/functions/#","page":"Available functions","title":"Available functions","text":"Modules = [LabConnections.BeagleBone]\nOrder = [:function]","category":"page"},{"location":"lib/functions/#LabConnections.BeagleBone.run_server","page":"Available functions","title":"LabConnections.BeagleBone.run_server","text":"run_server(port=2001; debug=false)\n\nRun a server on port that listens for commands from computer Optional debug keyword disables blinking system leds.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#Base.read","page":"Available functions","title":"Base.read","text":"l = read(led::SysLED, debug::Bool=false)\n\nReads the current brightness value from the LED 'SysLED'.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#Base.read","page":"Available functions","title":"Base.read","text":"l = read(pwm::PWM, operation::Int32, debug::Bool=false)\n\nReads the current value from an operation on a GPIO.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#Base.read","page":"Available functions","title":"Base.read","text":"l = read(gpio::GPIO, operation::Int32, debug::Bool=false)\n\nReads the current value from an operation on a GPIO.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}","page":"Available functions","title":"LabConnections.BeagleBone.assert_pwm_write","text":"assert_pwm_write(operation::Int32, entry::String)\n\nAssertsion for the PWM input data.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.bbparse-Tuple{Any}","page":"Available functions","title":"LabConnections.BeagleBone.bbparse","text":"bbparse(cmd)\n\nParse and execute the command cmd.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}","page":"Available functions","title":"LabConnections.BeagleBone.bbparse","text":"bbparse(l::Tuple, sock)\n\nParse input on the form l=(iswrite, ndev, cmd1, cmd2, ..., cmdn) where if iswrite cmdi = (devname, id, val) and if not iswrite cmdi = (devname, id) and send back on socket (vals, timestamps).\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.closedev-Tuple{String,Int32}","page":"Available functions","title":"LabConnections.BeagleBone.closedev","text":"closedev(dev_name::String, i::Int32)\n\nCloses down a currently active device of type 'dev_name' at index 'i' on the BeagleBone, and removes it from the dict of currently active devices.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.export_gpio-Tuple{Int32}","page":"Available functions","title":"LabConnections.BeagleBone.export_gpio","text":"export_gpio(i::Int32, debug::Bool=false)\n\nExport the GPIO file system, either for real-time or testing usecases.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.export_led","page":"Available functions","title":"LabConnections.BeagleBone.export_led","text":"export_led(i::Int32, debug::Bool=false)\n\nExports a dummy filesystem for testing the LED implementation\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.export_pwm-Tuple{Int32}","page":"Available functions","title":"LabConnections.BeagleBone.export_pwm","text":"export_gpio(i::Int32, debug::Bool=false)\n\nExport the GPIO file system, either for real-time or testing usecases.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.getdev-Tuple{String,Int32}","page":"Available functions","title":"LabConnections.BeagleBone.getdev","text":"dev = getdev(dev_name::String, i::Int32)\n\nRetrieves the active device of type dev_name at index 'i'.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.initdev-Tuple{String,Int32}","page":"Available functions","title":"LabConnections.BeagleBone.initdev","text":"active_device = initdev(dev_name::String, i:Int32)\n\nInitializes a new device of type 'devname' at index 'i' on the BeagleBone, and adds it to the dict of currently active devices. Returns the initialized device 'activedevice'.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.listdev-Tuple{}","page":"Available functions","title":"LabConnections.BeagleBone.listdev","text":"message = listdev()\n\nLists all the active devices as an insidence array for testing.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.printdev-Tuple{String,Int32}","page":"Available functions","title":"LabConnections.BeagleBone.printdev","text":"message = printdev()\n\nPrints all the active devices and writes out specifics of a single devices.\n\n\n\n\n\n","category":"method"},{"location":"lib/functions/#LabConnections.BeagleBone.teardown","page":"Available functions","title":"LabConnections.BeagleBone.teardown","text":"teardown(led::SysLED, debug::Bool=false)\n\nCloses all open filestreams for the SysLED 'led'.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.teardown","page":"Available functions","title":"LabConnections.BeagleBone.teardown","text":"teardown(gpio::GPIO, debug::Bool=false)\n\nCloses all open streams on the GPIO, and unexports it from the file system.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.teardown","page":"Available functions","title":"LabConnections.BeagleBone.teardown","text":"teardown!(pwd::PWM)\n\nCloses all open streams on the PWM, and unexports it from the file system\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.to_string","page":"Available functions","title":"LabConnections.BeagleBone.to_string","text":"to_string(led::SysLED, debug::Bool=false)\n\nGenerates a string representation of the GPIO device.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.to_string","page":"Available functions","title":"LabConnections.BeagleBone.to_string","text":"to_string(gpio::GPIO, debug::Bool=false)\n\nGenerates a string representation of the GPIO device.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.to_string","page":"Available functions","title":"LabConnections.BeagleBone.to_string","text":"to_string(pwm::PWM,, debug::Bool=false)\n\nGenerates a string representation of the GPIO device.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.write!","page":"Available functions","title":"LabConnections.BeagleBone.write!","text":"write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false)\n\nWrites an entry to an operation on a GPIO, of the form args = (operation, entry).\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.write!","page":"Available functions","title":"LabConnections.BeagleBone.write!","text":"write!(led::SysLED, val::Bool, debug::Bool=false)\n\nTurns the LED 'SysLed' on/off for val = true/false respectively.\n\n\n\n\n\n","category":"function"},{"location":"lib/functions/#LabConnections.BeagleBone.write!","page":"Available functions","title":"LabConnections.BeagleBone.write!","text":"write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false)\n\nWrites an entry to an operation on the PWM, of the form args = (operation, entry).\n\n\n\n\n\n","category":"function"},{"location":"lib/io_devices/#","page":"Available devices","title":"Available devices","text":"Pages = [\"io_devices.md\"]","category":"page"},{"location":"lib/io_devices/#Available-devices-1","page":"Available devices","title":"Available devices","text":"","category":"section"},{"location":"lib/io_devices/#","page":"Available devices","title":"Available devices","text":"Modules = [LabConnections.BeagleBone]\nOrder = [:type]","category":"page"},{"location":"lib/io_devices/#LabConnections.BeagleBone.Debug","page":"Available devices","title":"LabConnections.BeagleBone.Debug","text":"Debug(i::Int32)\n\nType for debugging and precompile.\n\n\n\n\n\n","category":"type"},{"location":"lib/io_devices/#LabConnections.BeagleBone.GPIO","page":"Available devices","title":"LabConnections.BeagleBone.GPIO","text":"GPIO(i::Int32)\n\nLowest form of communication with the GPIO pins. The available pins are listed in the \"channel\" parameter, and appear as directories in /sys/class/gpio after being exported. For instance, to setup a GPIO on \"gpio112\", configure it as an output pin and set it to high, the following code would be used.\n\n`gpio = GPIO(1)`\n`write!(gpio, (2,\"out\"))`\n`write!(gpio, (1, \"1\"))`\n\nThe operation of reading the current output value of the GPIO is done by\n\n`read(gpio, 1)`\n\nSee the test/BeagleBone/GPIO_test.jl for more examples.\n\n\n\n\n\n","category":"type"},{"location":"lib/io_devices/#LabConnections.BeagleBone.IO_Object","page":"Available devices","title":"LabConnections.BeagleBone.IO_Object","text":"Define abstract type for pins/LEDS on the BeagleBone\n\n\n\n\n\n","category":"type"},{"location":"lib/io_devices/#LabConnections.BeagleBone.SysLED","page":"Available devices","title":"LabConnections.BeagleBone.SysLED","text":"SysLED(i::Int32)\n\nType representing the system LEDs on the BeagleBone. The LEDs are indexed by i ∈ [1,2,3,4].\n\n\n\n\n\n","category":"type"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Installation-Instructions-1","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black. If you already have a prepared micro-SD card for flashing a BeagleBone, then you can safely skip the first section of these instructions.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Preparing-a-micro-SD-card-1","page":"Installation Instructions","title":"Preparing a micro-SD card","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BeagleBone. Start by downloading the Debian image here (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card (this guide is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found here. Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under /home/debian, and unzip it. Make sure that the Julia folder has the correct name by typing","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found here. Congratulations, you now have a prepared micro-SD card ready for flashing BeagleBones.","category":"page"},{"location":"man/installation/#Flashing-the-BeagleBone-1","page":"Installation Instructions","title":"Flashing the BeagleBone","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"Insert a prepared micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again).","category":"page"},{"location":"man/installation/#Trying-out-the-BeagleBone-1","page":"Installation Instructions","title":"Trying out the BeagleBone","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"Now your BeagleBone is ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`ssh debian@192.168.7.2'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"The default password is temppwd. You are now logged in to the BeagleBone running Debian. The Julia binary should be located at /home/debian/julia-/bin/julia. You can now start a Julia REPL on the BeagleBone by typing","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`/home/debian/julia-/bin/julia'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"If this works correctly, then you have a functioning BeagleBone ready for use with the LabConnections.jl package.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Setting-up-the-host-computer-1","page":"Installation Instructions","title":"Setting up the host computer","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified here. Once Julia is installed, run","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"using Pkg\n`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"in the Julia REPL to install all dependencies on the host computer. The source code is then located in `./julia/v1.0/LabConnections'.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked serbus' repository which wraps thelinux/spi/spidev'. Simply","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`cd && cd .julia/v0.6'\n`git clone https://github.com/mgreiff/serbus'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"to get the latest revision of the serbus fork.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"To update the BB with the latest revision of the code, ","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`cd && cd .julia/v0.6/LabConnection/util'\n`./flash_BB.sh'","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Setting-up-automatic-communication-1","page":"Installation Instructions","title":"Setting up automatic communication","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"`ssh debian@192.168.7.2'\n`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone)","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"Then execute the commands","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"sudo systemctl enable juliaserver (on the BeagleBone) sudo systemctl start juliaserver (on the BeagleBone)","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer.","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"","category":"page"},{"location":"man/installation/#Debugging-1","page":"Installation Instructions","title":"Debugging","text":"","category":"section"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root:","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"sudo /home/debian/julia/bin/julia","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"and run the startup script:","category":"page"},{"location":"man/installation/#","page":"Installation Instructions","title":"Installation Instructions","text":"include(\"/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl\")","category":"page"},{"location":"man/introduction/#Introduction-1","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"man/introduction/#Installation-1","page":"Introduction","title":"Installation","text":"","category":"section"}] -} diff --git a/docs/make.jl b/docs/make.jl index 7dcc9d1..6c510eb 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,32 +1,5 @@ push!(LOAD_PATH,"../src/") println(LOAD_PATH) -using Documenter, LabConnections -# makedocs() -# deploydocs( -# deps = Deps.pip("pygments", "mkdocs", "python-markdown-math", "mkdocs-cinder"), -# repo = "gitlab.control.lth.se/processes/LabProcesses.jl", -# branch = "gh-pages", -# julia = "0.6", -# osname = "linux" -# ) +using Documenter, LabConnections, DocumenterMarkdown -makedocs(modules=[LabConnections],format=Documenter.HTML(),sitename="LabConnections") - -#makedocs( -# format = :html, -# sitename = "LabConnections", -# pages = [ -# "index.md", -# "installation.md", -# "systemConfiguration.md", -# "testing.md", -# "examples.md", -# ] -#) - -#deploydocs( -# repo = "gitlab.control.lth.se/labdev/LabConnections.jl.git", -# target = "build", -# deps = nothing, -# make = nothing -#) +makedocs(modules=[LabConnections],format=Markdown(),sitename="LabConnections") From 9ba3ac36b043fbc7d76d3c1c531c582d22edefda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 14:07:39 +0200 Subject: [PATCH 14/47] Minor changes to the installation instruction. --- docs/build/index.md | 16 ++++++------- docs/build/man/installation.md | 39 +++++++++++++++---------------- docs/build/man/introduction.md | 8 +++++-- docs/src/index.md | 12 ++++------ docs/src/man/installation.md | 42 ++++++++++++++-------------------- docs/src/man/introduction.md | 10 +++++++- 6 files changed, 62 insertions(+), 65 deletions(-) diff --git a/docs/build/index.md b/docs/build/index.md index 1f15185..9ff9ffc 100644 --- a/docs/build/index.md +++ b/docs/build/index.md @@ -6,20 +6,20 @@ - + -## Examples +## Getting Started -- [Examples](examples/examples.md#Examples-1) -- [Tests](examples/testing.md#Tests-1) +- [Introduction](man/introduction.md#Introduction-1) +- [Installation instructions](man/installation.md#Installation-instructions-1) - + -## Guide +## Examples -- [Introduction](man/introduction.md#Introduction-1) -- [Installation Instructions](man/installation.md#Installation-Instructions-1) +- [Examples](examples/examples.md#Examples-1) +- [Tests](examples/testing.md#Tests-1) diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index dfc060a..3ba1d5f 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -1,16 +1,10 @@ - + +# Installation instructions - -# Installation Instructions - - -In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black. If you already have a prepared micro-SD card for flashing a BeagleBone, then you can safely skip the first section of these instructions. - - - +In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black (BBB). If you already have a prepared micro-SD card for flashing a BBB, then you can safely skip the first section of these instructions. @@ -18,15 +12,21 @@ In these instructions we explain how to set up a working environment on a host c ## Preparing a micro-SD card -First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BeagleBone. Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. Make sure that the Julia folder has the correct name by typing +First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BBB. + + +Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. Make sure that the Julia folder has the correct name by typing ``` -`mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' +mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' ``` -The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing BeagleBones. +The file structure on the micro-SD now has the correct structure. + + +The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BBB when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing a BBB. @@ -34,7 +34,7 @@ The file structure on the micro-SD now has the correct structure. The final step ## Flashing the BeagleBone -Insert a prepared micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again). +Insert a prepared micro-SD card in the slot on the BBB, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BBB. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to blink in a wave pattern, indicating that the BBB is being flashed. After a while (can vary between 5-45 minutes) the BBB will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BBB again (otherwise it will start to flash the BBB again). @@ -42,26 +42,23 @@ Insert a prepared micro-SD card in the slot on the BeagleBone, and press down th ## Trying out the BeagleBone -Now your BeagleBone is ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing +Now your BBB should be ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing ``` -`ssh debian@192.168.7.2' +ssh debian@192.168.7.2 ``` -The default password is `temppwd`. You are now logged in to the BeagleBone running Debian. The Julia binary should be located at `/home/debian/julia-/bin/julia`. You can now start a Julia REPL on the BeagleBone by typing +The default password is `temppwd`. You are now logged in to the BBB running Debian. If the micro-SD was prepared correctly, the Julia binary should be located at `/home/debian/julia/bin/julia`. You can now start a Julia REPL on the BBB by typing ``` -`/home/debian/julia-/bin/julia' +/home/debian/julia/bin/julia ``` -If this works correctly, then you have a functioning BeagleBone ready for use with the LabConnections.jl package. - - - +If the Julia REPL starts up correctly, then you have a functioning BBB ready for use with the LabConnections.jl package. diff --git a/docs/build/man/introduction.md b/docs/build/man/introduction.md index 6d7027e..5ed1fc4 100644 --- a/docs/build/man/introduction.md +++ b/docs/build/man/introduction.md @@ -4,7 +4,11 @@ # Introduction - + -## Installation + +This project is developing a software package in [Julia](https://julialang.org/) for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BBB) with custom [IO-board cape](https://gitlab.control.lth.se/labdev/ioboards), or the old IO-boxes in the labs using Comedi. With this package, the user is able to setup a connection between the host computer and the IO-device, and send and receive control signals and measurements from the lab process. + + +To get started, first follow the installation instruction found [here](installation.md). diff --git a/docs/src/index.md b/docs/src/index.md index 6532b2d..02d150e 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -3,24 +3,20 @@ ```@meta CurrentModule = LabConnections ``` - -## Examples +## Getting Started ```@contents -Pages = ["examples/examples.md", "examples/testing.md"] +Pages = ["man/introduction.md", "man/installation.md"] Depth = 1 ``` - -## Guide +## Examples ```@contents -Pages = ["man/introduction.md", "man/installation.md"] +Pages = ["examples/examples.md", "examples/testing.md"] Depth = 1 ``` - ## Functions ```@contents Pages = ["lib/io_devices.md", "lib/functions.md"] ``` - ## Documentation Index ```@index Pages = ["lib/io_devices.md", "lib/functions.md"] diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index fa8216a..29ccd14 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -1,42 +1,35 @@ - - -# Installation Instructions +# Installation instructions In these instructions we explain how to set up a working environment on a host computer and -a BeagleBone Black. If you already have a prepared micro-SD card for flashing a BeagleBone, +a BeagleBone Black (BBB). If you already have a prepared micro-SD card for flashing a BBB, then you can safely skip the first section of these instructions. - - - ## Preparing a micro-SD card -First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BeagleBone. Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). -Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. +First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BBB. + +Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). +Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. Make sure that the Julia folder has the correct name by typing ``` -`mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' +mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' ``` -The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BeagleBone when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, -you now have a prepared micro-SD card ready for flashing BeagleBones. +The file structure on the micro-SD now has the correct structure. + +The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BBB when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing a BBB. ## Flashing the BeagleBone -Insert a prepared micro-SD card in the slot on the BeagleBone, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug -in the USB-cable to the BeagleBone. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should -start to flash in a wave pattern, indicating that the BeagleBone is being flashed. After a while (can vary between 5-45 minutes) the BeagleBone will be turn off automatically, -indicating that the flashing is complete. Remove the micro-SD before powering on the BeagleBone again (otherwise it will start to flash the BeagleBone again). +Insert a prepared micro-SD card in the slot on the BBB, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BBB. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to blink in a wave pattern, indicating that the BBB is being flashed. After a while (can vary between 5-45 minutes) the BBB will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BBB again (otherwise it will start to flash the BBB again). ## Trying out the BeagleBone -Now your BeagleBone is ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing +Now your BBB should be ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing ``` -`ssh debian@192.168.7.2' +ssh debian@192.168.7.2 ``` -The default password is `temppwd`. You are now logged in to the BeagleBone running Debian. The Julia binary should be located at `/home/debian/julia-/bin/julia`. -You can now start a Julia REPL on the BeagleBone by typing +The default password is `temppwd`. You are now logged in to the BBB running Debian. If the micro-SD was prepared correctly, the Julia binary should be located at `/home/debian/julia/bin/julia`. +You can now start a Julia REPL on the BBB by typing ``` -`/home/debian/julia-/bin/julia' +/home/debian/julia/bin/julia ``` -If this works correctly, then you have a functioning BeagleBone ready for use with the LabConnections.jl package. - - +If the Julia REPL starts up correctly, then you have a functioning BBB ready for use with the LabConnections.jl package. ## Setting up the host computer @@ -120,4 +113,3 @@ and run the startup script: ``` include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl") ``` - diff --git a/docs/src/man/introduction.md b/docs/src/man/introduction.md index c35df1d..3fbddbb 100644 --- a/docs/src/man/introduction.md +++ b/docs/src/man/introduction.md @@ -1,3 +1,11 @@ # Introduction -## Installation + +This project is developing a software package in [Julia](https://julialang.org/) +for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BBB) +with custom [IO-board cape](https://gitlab.control.lth.se/labdev/ioboards), or the old IO-boxes in the labs using Comedi. +With this package, the user is able to setup a connection between the +host computer and the IO-device, and send and +receive control signals and measurements from the lab process. + +To get started, first follow the installation instruction found [here](installation.md). From bded7b7923f798b31a6829c0733d7408a476445c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 14:21:53 +0200 Subject: [PATCH 15/47] Added figures in docs --- README.md | 38 +++++++++--------- .../{images => build/fig}/beaglebonetypes.png | Bin docs/{images => build/fig}/computertypes.png | Bin docs/{images => build/fig}/labio_overview.png | Bin docs/src/fig/beaglebonetypes.png | Bin 0 -> 31694 bytes docs/src/fig/computertypes.png | Bin 0 -> 28182 bytes docs/src/fig/labio_overview.png | Bin 0 -> 137129 bytes docs/src/man/introduction.md | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) rename docs/{images => build/fig}/beaglebonetypes.png (100%) rename docs/{images => build/fig}/computertypes.png (100%) rename docs/{images => build/fig}/labio_overview.png (100%) create mode 100644 docs/src/fig/beaglebonetypes.png create mode 100644 docs/src/fig/computertypes.png create mode 100644 docs/src/fig/labio_overview.png diff --git a/README.md b/README.md index 59b74af..c6da30d 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,29 @@ [![coverage report](https://gitlab.control.lth.se/labdev/LabConnections.jl/badges/master/coverage.svg)](https://gitlab.control.lth.se/labdev/LabConnections.jl/commits/master) # Welcome to LabConnections.jl - the IO-software part of the LabDev project - + -The goal of this project is to develop a software package in [Julia](https://julialang.org/) +The goal of this project is to develop a software package in [Julia](https://julialang.org/) for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BBB) with custom [IO-board cape](https://gitlab.control.lth.se/labdev/ioboards), or the old IO-boxes in the labs using Comedi. -With this package, the user is able to setup a connection between the -host computer and the IO-device, and send and +With this package, the user is able to setup a connection between the +host computer and the IO-device, and send and receive control signals and measurements from the lab process. The full documentation of the package is available [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/index.md). ## Package Overview -The `LabConnections.jl` package is subdivided into two main modules; `Computer` +The `LabConnections.jl` package is subdivided into two main modules; `Computer` and `BeagleBone`. `Computer` defines the user interface on the host computer side, while `BeagleBone` defines low-level types and functions meant to be used locally on the BBB. ### Computer - + -This module contains the user interface on the host computer side, and defines -types for devices/connections to the lab process, and filestreams between the -host computer and different IO-devices (BBB or Comedi). There are currently 3 +This module contains the user interface on the host computer side, and defines +types for devices/connections to the lab process, and filestreams between the +host computer and different IO-devices (BBB or Comedi). There are currently 3 different device/connection types (each has the abstract super type `AbstractDevice`): * `AnalogInput10V` : Represents ±10V connections from the lab process to the IO-device. Each instance will correspond to a physical ±10V measurement signal from the lab process, whose value can be read. * `AnalogOutput10V` : Represents ±10V connections from the IO-device to the lab process. Each instance will correspond to a physical ±10V input signal to the lab process, whose value can be set. @@ -32,23 +32,23 @@ different device/connection types (each has the abstract super type `AbstractDev There are 2 different filestream types (each has the abstract super type `LabStream`): * `BeagleBoneStream` : Represents the data stream between the host computer and the BBB. -* `ComediStream` : Represent the data stream between the host computer and the old IO-boxes using Comedi. +* `ComediStream` : Represent the data stream between the host computer and the old IO-boxes using Comedi. ### BeagleBone - + This module defines types representing different pins and LEDs on the BBB, and functions to change their status and behaviour. There are currently 4 different types defined (each has the abstract super type `IO_Object`): -* `GPIO` : Represents the BBB's General Purpose Input Output (GPIO) pins. -Each instance will correspond to a physical GPIO pin on the board, and can be +* `GPIO` : Represents the BBB's General Purpose Input Output (GPIO) pins. +Each instance will correspond to a physical GPIO pin on the board, and can be set as an input or output pin, and to output high (1) or low (0). -* `PWM` : Represents the BBB's Pulse Width Modulation (PWM) pins. +* `PWM` : Represents the BBB's Pulse Width Modulation (PWM) pins. Each instance will correspond to a physical PWM pin on the board, which can be turned on/off, and whose period, duty cycle and polarity can be specified. * `SysLED` : Represents the 4 system LEDs on the BBB, and can be turned on/off. Used to perform simple tests and debugging on the BBB. -* `Debug` : Used for debugging and pre-compilation on the BBB. It does +* `Debug` : Used for debugging and pre-compilation on the BBB. It does not represent any physical pin or LED on the board. **Note:** In addition to GPIO and PWM, the BBB also has pins dedicated for [Serial Peripheral @@ -58,7 +58,7 @@ information can be found [here](https://gitlab.control.lth.se/labdev/LabConnecti ## Getting Started ### Installation -Instructions on installing the required software and setting up a connection between +Instructions on installing the required software and setting up a connection between the host computer and the BBB are found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/man/installation.md#installation-instructions). ### A Simple Example @@ -71,7 +71,7 @@ Then, start the Julia REPL and input to load the host computer interface. Then define a file stream `stream` and connect to the server running on the BBB by inputting stream = BeagleBoneStream(ip"192.168.7.2") -Now, we continue by defining the LED we want to control +Now, we continue by defining the LED we want to control led = SysLED(1) @@ -83,14 +83,14 @@ Now we can start controlling the LED on the BBB. Let's begin by turning it on send(led, true) You should now see the first system LED on the BBB being lit. -The function `send` puts a new command (`true`) to a device (`led`) to the file stream buffer and +The function `send` puts a new command (`true`) to a device (`led`) to the file stream buffer and sends it immediately to the BBB. We can read the current status of the LED by calling `read` v = read(led) You should now see a printout saying that the LED is turned on. -We can also stack several commands to the buffer before sending them to the BBB. +We can also stack several commands to the buffer before sending them to the BBB. We do this with the command `put!`. To turn on 2 LEDS at the same time, we can call led2 = SysLED(2) diff --git a/docs/images/beaglebonetypes.png b/docs/build/fig/beaglebonetypes.png similarity index 100% rename from docs/images/beaglebonetypes.png rename to docs/build/fig/beaglebonetypes.png diff --git a/docs/images/computertypes.png b/docs/build/fig/computertypes.png similarity index 100% rename from docs/images/computertypes.png rename to docs/build/fig/computertypes.png diff --git a/docs/images/labio_overview.png b/docs/build/fig/labio_overview.png similarity index 100% rename from docs/images/labio_overview.png rename to docs/build/fig/labio_overview.png diff --git a/docs/src/fig/beaglebonetypes.png b/docs/src/fig/beaglebonetypes.png new file mode 100644 index 0000000000000000000000000000000000000000..d6174c5b519aa20644fa7fa8080c8608485a9a3e GIT binary patch literal 31694 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 literal 0 HcmV?d00001 diff --git a/docs/src/fig/labio_overview.png b/docs/src/fig/labio_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e7cf63f6a0c3e8bdc8a1a52976494ee0ef21f0 GIT binary patch literal 137129 zcmc$FbyOVR)@5*aN#g+;cN!1w?(Wb?aF^gt1C6^Af(Iu+2o8;Ff;&Njy9Ay5-Z$@k z->mt6rq-=mRrjt_x7Mm%`<%1ysTg%tIV^Ni^fzzbU@6E;Yrc7d*z))M5Ec3FvDN`f4rkb=9 zhk$Yd2u)gy`N5U+=@*V$7$Tmfm81|lKH_Bb8}C-~_Zn~L8q$Wn<203utx}2wa1s;G z)_q*CY!~}SqqSUUsARHtu4qf25n@}N^R@Pmg<20qPrViljkI-`Vv8C7yS0*dd_hqs zl+pO_Rwsw%Nc2BDT$JeQb^d!?Mx%o*y+`+dSjb$oXu})*Pm_Ta&HqO?Y2$wkF}v@3 zd*5vK*v$V}|M%%)CiCA9m5bgmsTPU`eu>s39LU|g3x2)(v$pZPW+VbFX6%Z;>wbNH zx^;QwiyPR|#VKX%vaQx-5xs~}JKyC9{_{^ytjl(5&{6CCQsMK`!gGLzP9VWhf8EPr zU1MwO5XVy=M@M!vTkMv~b&Og-*v8Yu#*S^!o~`qZdTg;T!PD==7e=wyE3qjQ(eqFv zk+fn)(}B9D(YkY#;B%CK^Khz;IVq;tGZM4sL%lz3g^z+kXLmto|C(3tqHQWLVJct` z6!0)p7_>IzI|FKYbNc;=z3cU{`_+d0J7X+=@A~?B4W*<8p-UsxeJItYT+oi3^9|?U zxrykszA!q+w>XWheq~(mGxhz2Bzl!S)$s|OM*08g9sOTu*>S#k^XBEp>+S3Lm+ngr zPy)qS$C2~;bM52DyY`KVHJ^)Thb&)uv>*Len3<7H!yhiJ=rr$5JQPnkWbcXbzHnO3W@n?-6`|{^LFEpcS!yd!FBh8aE6JWt$6xSN~YOP2IfK zpPe&P&ichmZe=~{0)Z4ocZ`T5FE{~X42em)5j1NzAR>0pak24=(>er)$1?;KN;X0$DOkhO3WllTuiq#Mj~1nRIk-dvvka^5$1;Y+F( zseRn&hqn6jS>Bm{4v2M=Uq%p8#3G#%mV7|mp`zp$Kar*=eAcEeE^>BDX;t&HJPvmh zCH;5eWIL3gKWJ#QMW;(mI?$46CrMyB5DJCHo<(GmMEUPhH7G!STD!rc6!Y7~ z3pv(p(Fz(})bHUwERv`Iv1d;#gev6B_b@u;Nnk?>Cua_XDEbG2?2^o}L7tW6 z+=dX}5x9CS5F}Pr=Q@U9bmo615^ynw6D;@WcXqK3%4KuDtT65VjGa(G?t4AL5Xw-u z(jwdiySz`DyM*js;*af8AI+s~Z__?FD@?|u;S17f#+C%!bXBe2N7PvYkgKZv2+R!r z?E?pV>L@Ud5Sx+hIUv%y{*TA|bWB!z7zp}}(NzskOILlDrC{um-CPcOzAtc%KaUGa z#*&991*hc1ToarzwTq?CDwX@nmAR2!gaZ|M=HL~`ppiW6T+Ksq5=7O_)A1E}nyN{k z3g#fF{haT%xKKagXsZnPW!L(vp^dffUbk)*qOUK~7-(JQ6p1KEO z9xu_+U zHF8A;Jvn7sw1)?OF~`}^fx?Ax2f*?DoSS{P;@fLxJ1S_x{&B;f%IxW~U;E}s7iYI@WogaU*5|dX(6-6c?N=YtX~)%M zZcy!iVyiP`6$Bb0EVyRuk>q?|sD7^=GMD6bdCJ%QM6BSK8s4`VXcXAzR~dOkT7s8= zY~FgF^VQy{_mh)&6Ts}oWT;ESGF;4HuUogx0*j@HT&Md_Ys*-kt0+!H$K7|f%w}*I zT&RKud1w&St{PlK?FPO#x1$c+vRteU3p>I9+MVhh@&gZ=HVPoSUH+y%ep69TAKAk@ zZP_H|dPAm-fQIc^k)o>K7&yO9AA(d*)<;S$%;iJVK<}>}^=DZ!SUx=T9K4_6?3(7H zbUc4V@M;ftQFZlPwW#LgVE|l0CQyL9i{4RZiA&M~`t+w_GnQ4H>B@sSUh5Wm@L-)E zWnidkogS2W7rmL1!qjq|2O8KzigJ{C4{FD(r9mE$OZc1ZlXjhH-U^== z)Fxi%;f~BhYs#tH14#LrHEjVEHx2zFUv-?f3~t7h&IcQSYlf^WfXQAZRHQk3tOiIi z2=gBsbL^lg4PD4fMS=v4`0<}$1dy_$D-ESXw0)du_WD+Z&Gs?Qg!_t)I0I(Ed67F}X)hPQH3*@t;_w!>Pon zMfZ|uooUdB_&xSEg=NGjJo=HweRntS<+u`=ZY~@zvTYGRkp*f6UbUB}LYr^U$mt}d z1~qU%LG~-SNu}Bl#bQWhPEd-f0t@y5Fp%OwKPZohH=&4`3_$6K6KLwymzpF2W9F2- z8E;M()f+{fN$Ukci4{Jg+yAP_OQ{O1MkcgKWgg^7ua;S|fF_rWa!Oa@M}e2JHEO?MjS@5=?rUWl)`= zEEmutg_W3Z2uh-jnL^{U+8muA@~%S1(QsxZl+d4t72pw4^+}hrP0ACvJB|xqglQqo zJe7s``E53y#!S-ZVhdyg+@`qiaBtERvWzsLT8V5rFjQovLOtM2>QY7wz6K4AWGot< z1k_?pL}3;^mH(c+0&pILa%AL6v{UKHbxXnL1+1)a6xZo7jB*^A|23=8F20R#&sHmn zq%Vz?t0O)Wl1YgtrJPKCqpw9xGuzBCNMy=AC@BxOg#=Bw9!Z*kWRY?qZ;M!B!bL-H zztfHI&Dt&6)S)esq7Lu!>#i0#AHFRU1*jo|W!Y4fOHoJ^>kx9yS`WsdEh z`r6uIzuMs8z1%0hX5j>#hqwAM{wM!&!I%t1)uz!qr?* zS7dj&teFuWiO8MI*%^E*^Wmw+(hd?5-<->S<3WE+=WcSvjYxg5e>Y0v%4mW?`xt$N-O#s~IIA*Y)7A?J&wtOVI7%|1m+14ynH}4%eZ_Z0%uB&RH@lp49eX6$12r}sjLf@Af@O#&V$ z6EFENl^wOhAh=di-=|72koi4Z$9>A>>+{H4^WaRJygwK(w_;arxYUWX3Komd`xct` zQ2W+B_p<4%^bdQpdr4X5w3HmYrhKq8PSg}V2;f2BX9V5IL<4;7>A@g{v4C`5(&rT5 zcD}^*8>mcZH5Pp}$rGAz<{KFe%XQ?gOWu>)c&V#dmocF@l_6Bc^LD^m(gZm{fmEqA z0Hi~d?9~5~S6(QiDMwBafv5Gz)Mw8|Pbb?9VH|0JkVfHZ7*?NDtU_<B% z&v_cuF_Er#PX=Mk^5OT;Q9<`%)L5cVDZ`}`@>+DH3n?&e%oqk74%gSV_6mDCIjP@5 zgb4G+OmG=D=Gl5=^}H!48P9nGte@$B%<~GWELq68m5^=tPF=a|XP~sOw_j1*nI4Rr zb+`pz%LT(+o(5h1kI$bCf@+DCLv&`2NdiXFBVl$>pAZgo{Ih%&8U!-^XgWT6`OS6} zIi523MIp+eY#9YbX^&wK7-~`n{m7gzbda7^K3BapaR^^nv2TgmMX-f z*`nZ*hB^#4*fy<(++pSxa7h~8CgCe!&XZO*kyF)H9LE05LmbFI1;@NSoYC&5MI@3g zJLW*zQcB#^ph3>mWvmxe1cDU=J%o?zH)>tGb~hvU>*FXA_($D$0lFJoCT9W@>`JBq z7sA`-F;kST^~%RWpX%-)KSACbTXmhUtaqJPeCr?Y42-wy)9G9?^Le~uF(6H=9t&ne zJj71kt_>0=;)=WqYc$}H9ADOoAhaYT-K%Z7SzFdu# zREYVE6S}E}_btza*AkYD7y-2$Mh9yiG8cO%axuUJmA3`IWB?1QMFc&+`9(9vkaGht zf+q8%IEl1C-!k$eY3YaO3H}-$G=Abu=yb@;>_A)R4y`H6=DMbs@Xj7_prE3d_Bt}+ ztm5x)am#h2-Ci;C*6YqZ>I!atF5_qnG%jn@2N7N9&aq@7KOftQ`D>X@TwHJ^3SXiY z-oqH~pZ3M3)LyUEu9Uj3l>&~zRAA9UP~nu@Dce;G^S`r|`-I~YLrLQA?7vvTog&g& zue=e)uwORHWeWmMecJ~&VZ*Z?qx<7;U=}bvPEKo;c!5b)Lv~7^@s?dEI7$WIyVIQz z(YEZJ9sn6%k}{nKSgk;A9bSi+Ni&AptfoH!I<4H~~y0#T+&~WY&*Q7Q| z_1Fj)+T;2QyRSQAR+)6kB_W%{WeYgg-v>~}vAz0`4- z72jki9SwIs)IF2?bl(MGKPcag%M6DujZml-IxQLtZT*ZKs&wC*efGI59h$s~FE`z) z#d!tzY`8`Fta*jiJyk0I(U|A93HQnH$;&5r5N`#e;@4wleeKB#ai9^B<*}6}Qb5}$ z4{S6~aO2tpQd=Huk;{)`%C8sw4E2KcBWoEzZ7kQNX6POO4b4)LePig_LmU)ojY&8k{T!NPEQtD4!SYr$dAJ|Lq_{h@NaYjyFoo#!+-Q6>eIykqJTc_!}_jj_X zgX_?erfwLQDDRUT&&1r(t!&D==;PAV<%n8P3JO&~Qh9;j;pnyw@3za!@KD=b*PYwm z@kzkWP;heM(>(|L`CN43{pG^z+l(>VjG^ef;9pDyeoq=*H;YpI!b900+rP1nf7|QJ z%grYSKw%0{kAMH zW@=Zz$Anhhdg6Jrlu9aylhUU1JHj9H75#iiDu5od3`j94 zs&?hF&>?C1DKwNxDYkby!?xa68~?P5W2*YqH81$Vj-6aof|8VdfN2JE^Ibf7$Gx!6 z(EbS1)gQ4(;$T000`OLJ@D_>oYdG>(Ik0g;L~qD!>hp=y~eVlxrgXnE7W(fIrX zYC;&@*R(|(3Ut*xGo};2Eh9+I%1;srLciXIBq4x6jjH9Lcyr2%Fun z?++P91h1y0a4w>Q@1vh4&z`WOqoeg&PL5AK9>ysGcA|r0->R11Xr*X{zS#IBPQU0Tg3?&D9zUW~V>UepSIZEnIR25gTBzbx|WvvV{U zn--t()d_4k@@;QZy$Vo0E)LzFM~jXBqZ3m2th&+l*Zf=7-nwbjb=5_cq9;LMq-Nas zmh@*&!b$|DC(Hl`F=tLJi6HIo;07{OhjTm2vJ3mf43b1;$_%71r+@%bPUUl`U|q~U z8Wd!$1|yP`Ff6=Ea!}7lskg0x1&GXP%raZvPlL+*nKUh2-*{@4Ge1w$eW=-DiA!c0 zk=D@sjeAsyS(K4A|20UpC6pRDZvtXN+0BW6EE-Rd?BrTA$i21mwg+PVen30zyrL8hcqO5H+C%zY0SK)pK^6Q} ziUc>2Eg#;5u3YdV4>2i=i!%g9T!GcTV zOmPFypl0nHT)!Czt>J28C>Q2ERU?@oaq+Xv`DL%hN#tz2Jud$fdBfL!f247UG(5Ec zLLJ$&NT#{G?R!O@BhgepNz3uePO`spAS!*$q5yxs*>Mokq-gneLPXWSQHa|EO3%qg z?N@DBoezRx6CRe)Cx&@xwJ}vOZYq2Tgs;Ze9BhltqM1Zj(MkQ8V@CnQOF!tesi9r6 z@w+1BPp8|9unMgT71(O&Tz{bcF)j=JQfC8P1G;4QWN<~jE%1+Bne4nGTFJXwp<^=J ze&_OIb4DewOPRzeQ;E24q%s~~Y)V3pq_$7|>7CKmSPVS~)(#smLL z^Tt3L#O(p2A7h{6a>7NVpFpk9mR$C)960t@K`+1mE87!hj`5oX)jFJ+8Kb=p z*-}{oy5tv}?w9pm^Xh_crUYO6Ky`pG%^7zc`y#^E)A69;f4gPIHyzpBs>_NHG#k^8 z$20+_2jivhpj_Qsf_AZNTzBy6Kj!=wJ7Bz6f{y1j*VIl3MrauCX0AH$s(k=O7}@h^ zQei6NT1l1O@{`}jw2ITp1kHybfNC3LaOKGLyoD!ooYG28>H0@+-ca6qr%gxOl@&kx zGM&jWm)oPxxz;3zZJ z=~Dn#(kV~%HsyX{P{BU`=+)auk7jotr*B76M98H=zA0B~Ya^X!K{#U9KklxY8D0^o z@wkl@v!xTu2NK&o+xiE1t73KiVaN3!`_YGLLndfVpjP>f$3PZSxnh%4%Xl4XuKpaQ zZ{JQ*)6K_4mc9xMR$AeRQ)J`e^|nc4Cs%A9^W5p`n%EYi-wCJ(WU&Ow!bxRj-f$HZ3P@1hx zB#qCOv)$@1gm?pHlH4)M!n2Y)Xa-Gs%mf-)T9wT)HnVLhx21xgqs=b9 zc{zW_UKn%^+UgE#7kwEGH}>yL)9ViM^Pr8=LpkSeC=8mejIIy+wzTdiPk|{n)3PWb z(Dgl7UxJbv%k`WWP@c}qi3|S5o`2J5_WD>Dpk+1@53k&lcKC;R;m_{PkdAc)^He)A z=zo58xa z2^saHqvota^oF*-!8Wap)lz*z;X2mxTJ@D`(*ofuqM~KW++k}rOZo`ReIcdPpGb1j z0M%gCK7nk~aI$cfm{Fi+logiLbft@~ZWQY*c8Z-{pt*7=5JZ~V5}IL$)YEaoF+a{~ zk`?9`IG)!%tyQ`2fFlw&ZX591d#ciV(1yZb7)}ApqFSLpr1kB`p%bDz?WjCLJgEf+ z?2POn<&yj+;itE1?zgo*S6ac3VB>&mu9u-H5v*Ft1BinB`_T9!PN_cKC;=dZR`)$r z*82eR@lc}^l-sc6xe}z;XAa*mrY}Sory%F~Q(Yma*pSHr=!C%|frt2)A2Z8e4Bb+3 z!DXzRBN3wJol-F~#Rx#{^1VBHxiFEK!3fjSbl}VuLZ;4XRvKB3#RNUSmKnbTswK&6 z(MR(ckvQJ7PmLK84yrkH>-ix(MIV6*Savds3G9GFzfcV%W@$|1fozh`hIw_k4#U*A zvp<*RhohDa6Lhh+$?@gf4=ZzHojWZ6ewvHwF}An^S;={jgRqeW}UAaL5EaLO;;y(9RHiyw)|HB)I+dhJQ!fm>YhQ(@tdotdNa{H`WGVo zY(HC*Tvj}trMcvFQe_1BHsl+6JgwGHE>p6FF4{b4A3)HQp7`wi=?Q0oF&!r-KL>jB@4om9sCLs;1XE{YIUq=NO0yp8PO<`p_m$~b17oOFB74iTTvP8yyD za(mpAgQl{+E!U)Rc54~u4QJCN?t|MQ%AS$3(7R<3m^c8TtM1oQ$-ip>T8?W9#J_;; z&A4_BM>_)Lc|Qy;dqnt#&|q%kAChDu53Qmwd%%Zy1@~k>@K_MyQ@r<*vy4v2h#juB z2c&$$VX+rusN8gq<}XNND~@4ARzWk4jHd{n*WX7at)#;PtML_-6!a@aALn;qfvy+n zT?4*JYl%aLgwzr!TI}UNm0z-L<4S-m33U>qurG*6;qQ@>>~hC2NLR^SDhH+4_I_ef zwazzcPNmaPA?k~A$sqHF4xXK7m~OBQEp$EWp=ah#eTDL zXR@Geu_v|r2Ap+O>&QVU@O^(N5fdisC0*6(ObHR_I}2U9Yy>&2oJ}SmJ-fD&S;E?0 zbm|*yH(?sZQg>EBQ~p~A%`m(UWbUA{Ro4e^B&L!so!dqZ01xI@zS2}F;o(i?pHJfb z5nUPcvdCgJ9VD}G9Ady(g8qhrJtayC$Q7?Zz62#RP9FjM_hH zRke45lQu!g@N8sUp6PQ)DzwNKPud>2Mjg?mtZ{rm*aeK7VF-`^-WVNXW?sfmU$pr0 zCaH30iMx12& zdE0DzX#8!RX#K~%QO$JzAv5mwBQLt}&PmM1KNJhBom@y+wHz{phkNN?l)5q&MkoE6 zWzYZQgv{Ku=`AdTnXaGc5PYpQ>AYN~G+H<<)=T_zg5Rmlk?22)$`V@h?}e7Ge6g2@ z9$bI!K8;1!uh`e~?k&wg1P0})<5}{F(Zem$Z$iN%;A&(TBDP7v12ymgFw+ zvh4<>7KGf#t+Kf*I@(t&L}}63Ie@l^6%?lFS&^fRT-JVEFjNIhX8_=cbRUsL-GA)D z4;Cw)GfKn~6Tu20=m^aoVa)Jrc{hOVfRv7`E{)Pdy~5p|Md;uljdJ-SnrmxjMTEJA zI?pn%dSYgX!lcTgXkQR!V7D^FTyEFs^VpUn_VJn~Q7l>TqvhmD>q%;JX=607j+}Dp zel*fC03l%uX=AG}N1@mJl%#UxZA z2AmsZ|GvgXie=&=-UP`^r#!r}PPi4OqF91{t~lb+F`pfHRFwb^ zl|`Gi#ZCbXQ+%@$GCMwGTg0c2KoY%7Y?ruQG%TZ)(E^MwFnro79ucv;xSkNhYPP>qStU8v+H{tU#__3yEF8)E+ z1dAEX?_*^6!Bt--Wk6D$=(Sh1MeLJ%Teq%^&fM|oiR)>LN8Wp%_x}F=`~cj{w|8%9 z3HeQ%`getHzdVky+-8TFGnL{m{v)+@F;vpyhIbrq4E@F0)}ZL!BEGg=&Gc?1=J`%g zoNhwf$_t-UtCKss>QtNeEx*l&leBEYltv>X8z-5KcvgQo<*1fy&EhbwEW|AeXlNSY zSsEvE7qd5(Pycw~x~gN6Y4vwrA0IiD~(S_l<}2FstW1GY0YEwW1E0bPs8` zGpLbIAxl9PX5ol{2@~FoPm$&XAf7if+`;{TJE9m-?rmX=dfUf-w-0vz&K-%+qfd>xxCm?)~pWgQoHPp zhZ61+ePn|Z_-Cw>Mw*ZkTzQge0%QCrfuFOyOZq(6_bv3L5h)EHt*jDP_yo>c=nYscz3Vn zc~%Z0<_&Mv3U+p0&{Xq92LigxMGKo2m)b6$94I&zQ2(pmF2E&w6gb|h=ED9LjkTYv ze6w{~s;zQZ3)fxRjLE@>d3ZLHoUMIAOu3$3^Qlo0`4~)UUnpwvd7MY54--wLHRdHa zNz$B1EETnoGl`HJO3;lH0HE|6!Pik@(4<+Qu}%X#6BEb<7d&im&}i{1Z7CqLW59sk&#fKtd!&R>4N7p`^{3W~b9%!eI92(C={z~VLKN4jWjY6B0C5|%{Plzv%F%ABO8xBP#>j}K3)gG(YT2kwh)roI}v>Nc| z4wfKk2dJVUB1rlRv7C4ZZuA>;UCfVAL^vFng>)0Qy`;6oxCk?zq!J%U`FljQ=_c#| zQWaS*I|BW&wTqh^8?}^k`GZh&M$J5 z5=@HcwvsZAs$5#VbiAd`!(zalploeUNSCNYC?`*Gv&A0e*5jMFbwMA_JQpBw!uH85 znMY#)>xYg$rbhW2pf(J*SI4Td)dFE4mcfRTK1CtREr39*vhF$q!_i~`@p%*+qCbdu z(kwF6wcRs+bVG~B)Yc+6ctkvwrefy|b=vhvOqbXzp(uj@cOXvXq}h4zC1LB zMdLap!Xfsrl9d1-jfs`+ER5H+;OD}tO|d{i686jX*YjZ6rjYCxihtnd?C7Ekj_TpI zWu}FMfo9I;s8#1A)3X&ZO|*LbzNJ)J$^4ewiV&|0;nF$-yJQvSUDT9wxb9aXXL3)f zfGVrjYl|78vIwKM;yE3JWbJCo7rp z2PIpOZ4rM+tJklmXweTKBIhAFqyhYuqqwAT0kZwY4fms(Ith`y`nmc8M@_EPZ=pn* zby-ePxy2u%IBf!WZ=!-0oH9@fg?75M-V6J<#@v-C=OgQ`rGOYzL4&An=5t5|9~=4? zFz}4ONem(p=Xe>%pF3$l1 zE}0L3r@sd3G%BM356Qlo!S$`OqJ5NACOKon$`HlY9t1^ph&SQ$2ano`^l4M&5Tm;C zf)ij82V3kyl;8;-TVA_JqPQkr0}*iSwf!e_@$f3#HSu)TW-U$JszLm#uoB$VaywRP zl#X1BKCZ((z=`}RVTN6)EHANoUN+bRr-eSUM*v&@@@p)3w|;`Xs5)ACh61m3S6gaa zYp}?w`XZ@p6Y9kV<6Tm*{;p%1YJxE6Il z-b^kj|C86mwX~jjBc7}q_mv~gFK`}Ci8TjD{_A(tmo0i5WNf?vyU#~=owb$kr+p~; zIgJS_{Mz)KeQN@1D}_2Vb9^5u&US8BHa@O_UVhKK9(l#@>3zZe%lH4(3I{9@yu*0f z+IW87vHgN`c};-hF%)>V55{={zTVHgLR!|^H8cbMN)`=X8~N`e(*8WOV&j^tTMOEF zGl#cE{T6Y{dI>Re$sKIfT?Eoq;(MVB^TL}%MUIdgj7^SvJUwx_e@D`RHtWB)HZn1V zj#Z@05I!CFmwH77r3%;~gu9#oc7p%VJmLuJcDHf`=57-J_u z&yz(cLJrN)kIm2cHQcvh@eUa`>`uxbv@YT~f@1Do;;G&Vjkz6OR8s#ukB_F>+A*Qp zGHI223BFwyHf;IIdiB(~Q6CKvaGRvK+{@z!!GRRSlT^i}73II?$d+o1;Wf{;WRzOB zS5Z_c9n6s3zawp9_*N*$;l%%TsR4Yp__zvL+-NGi`v?lkZl*kVwuYQ?&ch^qI01WBhdi_g zzOKF538spgc}cv}ZDR(unQOHcR_Ht^__*#gK2oNJx(MilMm#`2tVLAOUFu+Ec#~>W zX>{;`reOwcm_;Z>4Z(6qRU>bE!XqgSDIKCW&{(F5}fw?3R5L^ElBWykoFePy5| zVGg02Zq{$;D%nF7&2H=m=2>FaM%!aHgQ9cZwza`5NHV(ThfpRPWqEi~Mt8Yf)|T@{ za$Fsr@g7WeQI|+|bhOgi1xOJ5d_!kD78A|97KFM4dlW10ddC_$nH1-lT~js2S=o-e zlQGaRd@-E&LxMT$PbabXvsESO#pT7UV>F|;X*BFegj`X4eGfC#jt8G1Dr!qen_8?{ zY*SJuSc1C#s;#?!mKOzvZBJi#$WXAw4mA7YCdZbFyPrvn-Z-uNY+gHG958(p44bFT z%baq{$E7v!nv&tm<%i)GsP8St60zu3>tB3~v?1KBOl4Nr}9M^N)Q>A zV&H2#9(DLLdG-MJa^cgJu+sH#q#>A^*JwHL*Y>t)hVIzim`hF3BBHr3DV}anI-RB$ zbGvAuA}l{c#xMh(*)y=u&c>NM-G=bjdC4Zsrbvy%A&PsTIu;q=pw=@@7Tqk_Kv$EzB4mc_mU=Z2%D@}!jej0@B6K`F5s^aQ9{JJJWwt&g4Q{4&<^~F=Vzj& ze}nMhSL~UOs0z5y=Vts0WDSduo|c|h zK2iKmSYL)hl)|VR8M$IjIDf9Rpfi}f5>iIoP!PT?I3+UezF;dlw%2I{3tw=rH{GPe z+k)WQB7*3mDe)F#cr6jnER2{HotSu7TU{8d5&Y0EN(hTs&TUk^DN~2OHuR58e_$&U z%z{6{#@E83w@i_6REVXpCua-OkK$I{X9|${DQy6R^6DE&`KJKU;*}V3zhbVtNJ+ZF zYu0`e+>HOEB>9Ux&=J>G1K!fg^+ZFg=4?$#a#5&WboT{CRh@XZK-?n;7y;o-%*&*H z(f@U!7MgYaA$O4jBI2|Vop=tP@yLR~Squ>rGf@JLlf zHVG~RmzuhwzV)&dsq&A*fDOsvk848w6WAm^tRw&sWG=1^sr0J#8~%dn)zB(}>S5i* zHeg9Zm8!dNU-<4%z->XdOpNf^AC8^hSp4p14Tq6HU=FpBlHye50DB5G zvvw)nv^XIRWdM6 zLl(vdq~anPeU%-@VQTYE+S}0Y*8=h5mL101|Z-mJG9Ys%ENo+P}~B@ry;+rDjdchr8{;F#Ll#>NPG*2bd!s$vCG5 zXsIT7>-3#-%;rE*PQB#;uVqM|ewa-$Hn$}iLTLl6`l}EsK5@k(S~BL(?Fw;_3N~R` z&k#j|EB~bSYCv--dzu>MBN?`FFogKy(W#CtsnZ24YS*>Q+Qvdq%b`+#Y95Z41| z%Pj@(;Na#REzbPy^%cce0NAPT128w72hUzFnJa=7;Fe}N%vcpuf=r9--eW-h9UWtF z@yFos2QXA$3G==0e*GABp7%#ejYN5PyBO3ey3(fb-+BU;*t3yl=;4$y6&Rlm3fD)! z{e@zz8%jtc=?P2a`+iL;ynahxvBF);gc=b1@J93Wb=pfl<#u`c{O6SwX zCc>Tj72E5?KE3gYVB;hkmPqc9m-ipj!Hh%P5J-Vm?6=o%?2W%0=6#R7Zl6gl$wigD ze2b1~xsXR2J6zlU;ljUI+^2q|ee>Nrlj`M1;nuIVZ4lK12f0{KUOWOyec7gx+3jw} zUBb%8sgtu$N5sNsf>YEy@83O+s{fZYWi4%@(wLp1Y>55ik@eaDz|qv0gQz98 z<7$l=i{IypVD^YDSEd*Kq4@06RKh5k@_58CE&?<18AT*fF*-eqjDh82k0fF$w@Tw| zdh~2l7RsoGf(DLdVS{?S9JG2GxpV>#%qAQ06SL364y#1jgw%3esy1En7prYGvg~Hm zXSp83g5b3XhjIdJN@LqVl>@I{-)F`N$LLy?3y0_rd+1&^B^VE@DWU9E)l`aGLii+{ z>lQkYKW{o)lq_nBXQY`j2=~KR*yZfqJcR_lYJ*Dk{kT;q5oftA`M?el5q1=BJc6KLCfh7I@6q=?>Q>;ooCRkh)lLwTijZ>~hkE^&gT(c+v&{M@2LEDk5~T zUNNl16G{2B%@o$W)W6~LK3{4HMU0{{v1ky;60&3z;n60`Q!0MYsP;5hTo$#weD`Dx z5-#un+J@^})JKa18sqoPgPgx5s0CaiTALKo=H(HYAxo60b9}qlpj}_!J_QxSjaJ0u_Un$+`bXSXXs}K9ZcxnQ>g`?gpaRls) z8yn9H6jpMbJ<4OUSUCLSNp%B$6^)T8bl*614{xlt4um2QxZ4XpZDn4bu56494oa9_ zjIP|@M{kV9IR`SGwLhB}`%Gx4Iu*c_WN)5?Xa42K;p&@a8d`Mmi|d=;L*5zcW2<4z zE`3sn2JqNY2DsXueUyE7^zL{u?|iVRiZHU&$qy()EdG`NWkE^%)0m`F)TWOPBf3(Z ztIhoxmM;kE?)|xbk5C3;D`z8ccHUO5M-AZrRs^FKG|&HxMq)<1Q#)WZw8&&KlM)!} ziRCLbnJr6Q9>K;&qE1^xX=WXut$7HkElN}7NT}G<7ta+0=bI*sqdcCskj&C``O`Wd(!0kxcote5Kx#Ig>l(W|V=OowR zLHu~r^Z+t1k%CBi?o6q)HHFIC#r(5r`#p7&?W)+X`nXb|hvWkCvrr;xW2rxS8hfS z+Yu_r^~$<7Xk8+T!=KHQN&o`_-_u744lZ~Oa(iLBfpccnWy@20G^Xj3%+M)CTDnJj(ZxvD5r2-VhKCz1HXaRA-0&PH7OB0p(y7LS=|7MU z=QI$0IIZ7`vRw>Iqah{GF~F51mzJxt-s zX#9j-3;?Yf2PlGCM5kcY&v|Z+aFJ+lh1R460v~=|_1$w&zP#M886^T8^BJTMHW$CE z*9&FJd6=4b=F9PpVZ9D=M%?7PCEo<5=aXp2*1W+6uWnTSC3`nXy z`H{qUh{xeSpm))G*PYn<^yAE9 zuC}d!tiTO~l4v~S8p>t76!&BIx#H?ON8LZ%`j#cp&V8T+czr~ipP8ZLh-c}JMKkf>3dQ&6KB zEAB@GEg6weAy)q7E#9NN^b&TImzZ#CS$VJeZo#~sfUVo#g?dgcHHl&<#$Ij7D4R-% zBzL5aw~&nW__rmAz?g6FCgbKjz04mD8|F8WYyxe#jLbVEkZib`=EqUzAYSo#_v7K@ z75I0aBHr3;LwR9DV;wm9U$PoQ$VV(fM}8<3WwpS+?k^C|BI}XjHuwL~yuNEt9($^KbKj?4w zth&2Ay`6sC6^yoCYpU;OOi~q(4aJZfdaD_OKb2QZP(v%-+GtnM;@I6}8hX$p5Upds z!s98mESRHZtu~|!$5IbQq$(>Ry8*bF$hsMXvW!*fV8tTUYS)&JlH9=jD6VdttPe;H%cj8j2#SU}TMhZY$*ZjX|7e`Vui zsvnOXio=iZkCl+&VoIem=kyFLYD7|q6vY}M%x9QVmExix1qjFgLz!L+CRjaK{Hva~ zeRhASUNQZt%O5dK3UljkJmU<4-#+RamLNhyM_F&bgO9t9g}p8pX;F>#C(V?rg=}Bk zP>miF1qP*8ZiOXt=0A1|j|wFgK}8zP%OdK#3Ef;>Z$26Q2e5B;PrIK5T<%8-e?{4@ zj_05G^G^kyVtjn1Xx+}+?tYD`+t#9b<(vvSWg~At6UDAg#QU7LjE&0a;x}kLp)&QV znb#oTBFM?)rYq3AavJ#2&&7AWsdleC=+^e*-ULS%=e_4Y)Z8V$w3wA5hveOAO(tJe zB7+faPaFu0lID|)&8BU3|4vYiNe9vB#W=o>sZ5-m!MiKW;Q)I@DOa{&!0aNYvTK!g z5X)Q%4I0FuiiA?u)MR7MBE2z5HlX4g0X*YFc|hY8E_|G0*77F-jgE3O^BU_fI?PlM zS%?Di+eA2)?EFneC(AOVL8C@`(rs5=H}+HyG}N{O3D!283d~(ACTaY4Oig>}VPu0l z1h$LGVP70KOB#d&+;e$yxH~N+@uLYKZE~eW5Rdhj+Qf66x&XAm4+@$zi0BH{CLbw+ zFKTfvJ2*OH#>y8`Qa&)&?6ob-1O=rf?VI0ev7|O=3~6d zr?9X4+BO)04J#IW*J=I9BZ64x18q`z*U7;fNx5-0HzOvT1!J#2bF4X2A+qy>VA)8^ zez_%ke6xV78)yz2b5p++56upGLzF5%s$H~!;pY@=cQtlJV}cAp(~KmEKD0a|DeJd! zG~XpMK9SkF7nmcRn0FNXe(T|AKsz5cdtC_^`IEjrGu6F>Gn?;Lzgq$yiC}tFBRjSS z@h#~&5f=)NY~F-+2J=F_st82ErKEXk4QtH(>f1wBXnwM(aT?V8uuwxlp1rihknvJ@$3(z zcjS7B?)Qn!lcr3T%Kb+MUG#VsqAR`2<*j8t{|W-CeZNl&uTDQS1V4n2gL@H%`2Ng_ zoNdm=q~@*XxE;lH=gs7n`;JjPbKR}_;OLRJ<=NSNkm`9$#AJ(!D>>x}mK+Z?sukS`?Cw*$G(@}TzBAy4|49m+HefDOEYa+~bc1{qBhT)# z3BUaxEg&+wREmyvo%X9fUL!M(i?_Be7Y%^LDpI4v|K#@HwE%XD%;*ob{TyQW;gT!Y z#uiu#>7qE>Z*Bkn{Pfd{kXr%-1Xp4}xMsXJm84=7H5lUi-*%-?@O{HfcEDpT> zlF+?pLiNJhk_cn{R$Nk%rd4iR0%+TB6^ms%h3U|ik&zAG7R?^17@$xhc&lgLC zSFgo1e}ZA4Z+qAw?(52OR6;Ip}jJ(tDwmS(SL$oT8Rm75fcF z_GV$h=z%sZd}6)rYA&2>jM*Zt{AQO=;pA0@FB9F59;bhlrtX67l<<01#_Zf9CrH@5 z>$w`qX!LRl$R(a7^3?LyO*SD`NW26c4HZJ9vZ$O5NRcFAE8!Gck5OH06-sgZ^|?5W zlkBA?pE1~|k$@*##tJ{t%5st{m7tO*tThR^gxewttXwk8{P6fr!^VL-exB=i%Yr4! zEp+$rGi>t6)6oA#(>HKO`UgvIvau(&HL-2mww-Kj?1mHD+9Vs>+1R#iZfqxS{`cPZ z3(Prl&QrhcuBxtPg6TB)TIVS3pFNUNkFi<}rb8Phw=C%W7roBqzOFyluP&|9iO>BDLhI9Txfbi$HNSEN^1B5a7DJpFn z&&js}INiRRrGQrtmbDFIOUumjY=WldW-CmWmk;uP3siIoS-~@bAt!qP|WoWr20R2w6H0uXAE#uKW9`Q ziZgz|ZGKK}9YHdBQ4slV5hRKC*jK;E)JecGRwz;>6^c6d9UkJNh}eZyE14=MWqTn@ zgEq3zkoksR;u-TReF(j;{0-jgj;^k!E}Wg)c0!svGO9hFWxuwgKDKTbyWSvv_-x*K zP1rN;8h-A6h6t2KmjBmgx45pXUpRtWGzf35Qk2gEgR{AfSu6^I(|(uH$#_2b&%*!jn}V}Sp@kyQ)iO?02 z_olQEX{?p7#)^7RY8-X`7PP2jr-qJO%28D?FJD2uU==t>Xc9ZG+P_RftWSqCrbLu# z#OQX$^Np=93*fd{WGsf!e5}tc1*;9RaO{`HoeY?S?XQ`O)#hx&XZl$+15LtWLE6@0 zBQxir$6WPPHU=l~Gy+|^Sbca=`5J%UZC}kdN6z$H0fN6BVhRzFa?#r9Ut& zo82y(|Ki##dSo@Jyvky$iSU_tvg6w4`k+ik#`;GDu&(j%$jMys^6I*o%PkwD_f9?Y z;DwtwI^Zh?#HlCe|Hv`fhrhCRQzY)81sXvQ%S_0Jr6c3wXge*9cLNcB4W^z8Fc z^^9Z|VQ!1%{1|Hnyb7K0>mNV&HE;E-<#@n*`0tzc-9}w-xBSOz?85)5K&coSB)p_c z`0}Ef1g~6VE%PGD$+U8q{8IU?{=m{u#eg`_1EBKoj;c2!2s{{a8_9>YdmIG-oI?dH zZA`;_O)#7x%9U1)zp+JPns)C;)%QK{>Ixy;y)#{~m`tNzYrtq@FQs%^OLdy<=UIE} z=$bf_-{I`xlfV};xAc-#k-EXF5Dvw@M7E;22j$^zDd+7lpdw+V#tjyT{v+ zC1GG78c4WmRVX{d87(nU#@*s(=w?(TC0IE{naAiz{xYFvZYnx%236%V+K20) zunUEjt`!=Oi+O1650@y(!HNCaU|?;G*MO%%o@#OKt(|MLyNqdh7u!y;)E^5!B(L^4 zVEucVhTdWA9lTUppU5Obd|=}enBIL!&k`9c^Ul0Td04fl zGutF9Y_9lsiDQEi0wjhus~_jkYu=9GY*d`I-jVnH>3QJemcYQtfMGWakz9Ia&ZqX@YF@VGj|YL9w0k=SByKVHOgd0x4RBc+vd+L+TWb^5tm0}2AkwL!<)+GFzhj;=ax_`CX5IRWI|*8agf<`G<^*dcsg_k{D;rW#T`pM|8U ztkD+eCT{NuC{j^#+3{Ba>PnJRrCBX((RwK^#(AW99amr|aorMrMMJs-!Ed#Y;%MuY zWCI|@G^i(9B3QexU0Um?)U>anxy9UT*9aP*BBz#MWs#mw<9Log12M_ed-MHszx?<$ z4-N`1ZaS~X>>uWt6!P8JMJP(^PtIvw<4rd?f_*-auX4yejZuFM0of^L21Mg8Iu!O= zf*!oE#29h(MZGC&{h>k}Q%%!_1efU8UwRL&ED{J1Mc7R+Y}3$UxbqH5rwk#=QK7*nP`prT z=yh9Tpox$SQw)Ij&OL$_{j_-A4bojqovwaLWXMyGK3g>~UT7;Uug_Q@`Z_hp3=Uix zi_J?W4-824JA75#f_X<@8j01;DNcaHH8WF=u`TQ57yHY^Uf-grb%woI zUIRw$+5i@r8f%D1DlQ)qy-Yi6{|0?s^$3tZ(Bf*|>FdKUOE*Q{h{bm4aZ4Z_zY&hx zdrc7tt+_YrFB~;=M@_Ah(Qt1R+1KHjVB2HLI$r8r&tMIt>wcC?!D_D`anHoK_WB z+#-Xg&jn|x_ox78o94oTV6MnpyN$M;TQ>tHh8NCKNrO*u-6qrNzd!fN7 zr$^CeU>IU&(4mj*#4O3Nr6jRTB25v9(SI}cX&!(C z?pZM-M~kLvGKPt0MzW+!KwH5O1#vl^C);uf_7thQb`lrEt|&15HI<}7;ZH+~24F-w zO+!(Og@@EgDXoD!wy;41Vg44g)nxx>5y6DUWilz1@5LR~VR=X~KqX@_31zNKsHG%v z5Hn^q#_7IHi~pATD_=qs+6$~GA4}Bi7Zu4W*_e~Lco@MCrG2^b`)yFZ&@BEB{z?rk zYbG%}yIKjRN!4%?qZ1eGx&_QfmeFt{gr!)8UF6thd$^WeOb(8w+C9WYQ?sM_Eg>)L zBiX@oBpXUlP#T6Sd?Ff&kfb6SWq+Jgh)@Pvf$^AU`)LhW;N=y6l$un6lliX*k|8M| zl`<=-WF$R)#%oV40a?c#mu^rgu|vT?(s~Z1t+b|wRtWl0(m|TZ?lDJ5)fCrvWC72N z@3!oD>G5m&aE9^y)0}Odsy{76WTd#oqoxak*^!h%5XX3!J!D#TXC$IgikBh16clzL zam%ZG;oP79q#%^dbC3g9sO%01_hGfRb1Ss&J>zdVoO-sdfJz-@LDRXLYyJv=_?xpy zhzhqO-;x~d&MprV87FE*F3Ek|esV+fSlZ0fx2q?g%Xd1%SGO&v3#W@QzgXsJHv+${ z84r5DEtf6P;-@vmts!6LVr@Dty2E}~gV2l|dU^DR3FM-Nyyl;P&g;xhw@X;k-VwAR z?f=9;3|a=i;HCC|g?xJ}jAoX%5Vm`6F`JGA>wZLdr>E-=Wtz9SAA8k~@AWxTwWdQQ zrx6p0#n6_EENK)+QOt1(;IOA~84S(~(Nnv3K^`veGnURrl7hnKJz88%D>u^*jvlk?=B*nB0kMgR?j8$ISR#e5I65C z1{>`+xhm64%x1Jwl9wFz-bezFeY?2tW*QPsaGx0ii24SK>q&`8FttkuGB<%BidZZ; z7k)x7i8c}A?4bvt(8U=i1w%A&D`$d$^xSt4>>wbDEv&V|npjaHEQ#A4w=&4cmvHm| z4!No4031W|5^i)kZ*uw`RuhbRg{vRK3dRV|QT3%pbZ2P4MN~<&m;!CBr%uvP4y+b4 z5u8R;x@eF)xzUwdRYvh2CU&*h9#Ae{QHd+;0p1SE6k#RW5j7q=Ed-cKq%}OJG7$r%1{0$5feA1u zlGsEeE8EfEHEYL&ZBRvG_n}PrCkc!;q3o37cQF^MlwX*Ew40uzJhKv#2opDLf@m*t zqkv0Pc_oRtj4Ymt+y3QQc2>vGIvuixNRqWVbdV5S_`Kw3E!mLJj^sW%EVHskjyN6= zPV$&YQs5v({HO}j(H&*JMkIPQWaa3mRFlq zm0O#NPg^^n8QkY5y|V73{#_U3CYx(4l2sL0`XjJ@KGXl`{EhC!vF6>t|G%m@#wUiB z{|SS>PO&22@YMU|XNu_3`uKTsS6CCyMTKdS=4W&DK@d@E;+Eg-4<~1r!Gl|Z!#3TL zpSn$(9HhZ)>+cHM*PFACIL;7Ge0M88o;$Y=``-iZfd=noskeE^e!&|XkbXp-=cfh( z?cwcv=K(z<=P5s4A1-&VdPLiA`H6Nrh@Qaw_a3(f1z#qA>^5~hQu^d-6AXr zuyjgE8%aIlkmS;~9K)AHiwXtJi<|P4d7fHcP>o3&#~H_x>)1OK?=5sx0uwvK&Un)( z8X^0mH*j%*+*X^8M@Biu4jsY=L&9CV9BH-~l9gL*aZk!>Mh(%2BL^RxSglCn792xL zff&0EeK`#zQ7Rt(cOVm%#7ClFn2y2GB)uiWNS6hw2UR7X1#(8rPD4*EAEUjtWfs*` ztfH@+%(cykfAyTW2!}^#FcG_1n1B-iZnFdy`zNskVbAQEB7`PVPkF_iNz%%QlgLPq zocu0HTpA57iY|?U+E*L|wr8V~g(h~jSPzI5WoUVE9H{O(@tD3J`+MS5-HjE_yXg{9 z?V~<182^f$8n&E8v3Q!%x>8v9N7^5BJ`;n;x|dW{pzTyhR%$ed;HKJ6E+aS~ZK2B_ zhK|1mbBcmhf+u`Y!+;E)vAACo`FI*!RZu}mjz0*a9Za5+EneizZ_eF2o!C!e4{cI% z3MgF(O*=t}SXYI!(ne!vL}YP5c~h&c`nk@OkyPT;($L;BXvDRmFE&VsB5Hp7A8Gn0 zxDuPRSb=b>oJs)tm+A==)1^S0-3M$M-z{@f8J4C7VeH_Y=eqMz(hh&jeJ)e%mBZSwYjJsw>~cd3U61!8JNH)R%gs=Op>7g0sKUrneL*+TJh z@5QtD`~%CF-WDV;4+(yJiW)raGFmpZ^=Wn;shpQ_&-5+rV>5xTpmqrzCgd7OI~gpzV|ZTJT!MjBX=HUzuk2`;rQPm3Xb6U zUqrv%RKLOfc(3PG!s!gtH0=4}n4Wx1Z7qLcvTNX*@zRifP9HiT@R{;8c4p1L&>LyQ267dJ5+Q4u3hEW?grq2Y z@-mXY!AsyHDOzH~G2%AVg%Sk&XF%uBP73WHgcN!iV> z04e!Oq~=#@u`9~~<#2UL6B%RUe1b|imZ>0a&;;0hBYxJ# zMD?M7M&kPso=tgNTg7}3U}tbtjuq#OfFu&j z({|}TCIG|7(_Z#nd{NC0qFBp!zq!55NAaev09*q8BR#VT5MY1&nI*Km`Y#yZYu5m! zwS)MXe=YMYQ!7H;XY8BH;sk}zQlpRCsLxnx9;j>#U08j!sPMG4=kLOUtG(n}c6RIg zT)G?K^>zIz-wj8~sVhJ5K-gBV6H^=be>!jiX`-?i$sOX>d-hgeF;T|#SCL2(^cymC z-tD&*c&LrN9_{*E!0$YB_WykJj}23V{t9_5uye4l=gl;Z5;uFQ!s_M;qPykj$2K|s z`wYoQZZl{-)bnXS@H;f}ZGx_0x2M{z-`4eg zaOctJShbicskym}Wn}JWh~cg(kr$ERl6x8R;H@)5SryJAr8(i%z%ELI|^i!8L zfxoK)H-DSC^A7Mtp6af81wB%n z9zd9Z(lwJtA?Kl58SVQ=If7NcDS``M~uySGH{g5L=)grN%w;XWAIZ~RtMP0ZPWIl;(w-y#5bWxFRSz{ zN;ypL>ZmvXZ(*~{vJk2()Wg7)5$(^?LWJzmR|(wP0NElrKN2P&fRxyC)8#{WqV7t; zq3MER92f;mlCCjKmio;z4)CY^_8jYi9(q1|ZtI@M!~r)sZF#&Qx92wjpjie~Ua!D{ zKJFeZk`fAcoKyPb22lp}%#->c=S)Q0c0A@wTD1`Abg6~Lv=^2awYW1d8MNWQ5-(rT zu~BAhoWYK$%KAL7EXu*?J}+s~i}Cq&8jF9bhOo!{hhk`HA!Ns8GJVSGh(o3DSl1#U zn#l1KQ%Ql7Kr!iBQGMY9f<2-2RUDL45)q12(Fz;+b5HXMH z?mg!i!$dKv&v(nCe>&GPlBZ4o;aqh8Oh1ZMRW82j^yH;p^~>+=W?3YubyQ0j@W)MM z)Q7TT;eGdi3XfB19*o2e^5$En@4M|Mm}Ir!sHDJ^Lyp@VeXsxtl)-JIp{&b4FeE~r z{>CMPzMa0)yLZQ0?Ih8nkmbC$X>Qpi=-^>5_e>_(O3=_Q-Z|zNOy^{={l6@5C zzTw1dy26Js^7anC2&*Xg9)5&*y>t4Lb={nH{nuCokVRGRets+%?s5h^+DGx>`&=1Q zTJ%JIi5DMRTTkjNELyYwL;BtZH>Gu3_3G#|Ij4*h+rUmU3>{cPO^G{3u|mT~jDkhbG|_{$)z`*J5lObb znD6w?lTz~Y1IKU?lJu&Rhc8O-OUQ_bV?{3v!`5QrvUAoD^8uxdDpIE<$cdBKav2(# z5u||=nm{Hct^7hXf|$Ux>kgk@BMI(cfRh*iu_VjArwKGxyhdb^HPS9$p?S0Jiy)eg zBckWkQ)tlXM33C_u;@recyq<@x&B*Y4+GdlI0&ot6h(z1ndiwf6r=blzh`eIz{r>j(&Q)`vRJFLQxO~!U@>ZZ)N!`VhlrpHd0o2)BBIbY? z8bPNXY$H^~HYm54id~A?kdsHo9pjI2W`lj1kfDt#KX2KSaC5q%)9xrFU>x zn3e29OGD#xp!c!V@ImNLlbo!Fx^*4tXkbH`_Q0ULZrTd#Snuezt%(d-hAie7!F0c} zXI?oi%5c5!jE`;nvJN$mid}6TN15}9g!fO;MPY`aSep9n#YQ7Y_bVRa!Rh&h;ijqXYb#N4OeUz^^q>W3zu<3o2u4bXF`{U#1)rE{j7kG zqvbYBMzlm#EqHQaoFEB+s;JS|9vt(w{suxzS;l=PhszMX;CB900FvnLEN#_J;H}_* zYVNgfRPCQ6Y=k4Odt>CCY@!$PW_^Dkvfz<*R;M}rQotva0`D!|Zc*kB z0rw$q*F+zLC4p4Ax2^`yyGP7^$0O~p8v#S7 z2A?#YZv*gN8$|EypI2XbSUs8yy8aYgT46MWGq--}3t-Un-2eUI>+asrh;1??Fl93u zm7zft0VG>B+P*MQ9aJVC3HY^;c^Pu}KAFO=nFxd)AS5{y19LX533|Jt*#&!l z17_64g+(TaVeK)55g5c1Xp{!XOSAg+Q&7A;PvX-TT2^Q1+4{;zG3jB9>cOhyj9B8l zu5jX}32n_ToVLe8oE);sT|iaoqJ9Qa2WqXsgI-89Uk?6EtrdDOWoz zEHnu!l?b^(udG}M=J~u>Y}s>u?Ue7_GWg7k5WwLEdliC~L3BZ=us=cxnA*Jg;YM|o zfeJVvLg^emI?70h+#rC73U)a$r7r<a<;o5~G1yztlq4CN>%h}KFDzL~r(5qqfNU8c+ zt0lCXzUq>CpF}K7uEY#^0oEUL5)iyD2`Tx%R=X6eJ{0YuO&uj$dQJOUL#rJrZS|O5 zC`ppwgAemjA4b*a(Ij~DvY=FL7;!zTDXm)e|3y~-mCB9K*Rs%F6Q1WAT2A)}GIvn5 z-W5&^_k(8zbA?VvhNa-^3jSYfxR9Frnm%s3G0dCw{6=x>Ili@I(lO_#uL#cR^d76o z$Q;YJf7LEW^qelE*OD{2M5y^kiklCVInP;!zaS<#zel!PC3?5DoIVh&H~B$p>ba6s z`_JXhrfW@z9|d3%k)|5DbLW2Uho#%;z7!TvuR;)|W#$$F=)^Yf4m})ild-OvwgNB= zKXwPCEF-pj4&a~9Q@bLX+n=r*D2rO$EJuJ;*}cCxC1v81G!?(iNa&P|!HuW|xj z&_C~DI7JXD#^qT52V!$QHC3f*lT2bVN7$haY3I|0VvL6cr4NJa{1i%uLKLIKE!gSH9T@0sfCo7mDRz@GrAqb^D(0-S-MSFWtA{f zJ+PA|-WzePHF-uk$y!lLWSc#85e24IegV<2DWequm-uibQ+yKG+??PxxM3s^ih?>7 z3k}KO%1`s)`axEX^a(NZs57mx;VFOk#d^FV$EZr(6i~$-it$JXU8$${oxTk~Xz;PD zhapnvSkq+Zi2=fH3*v#Gt&nB>WGrk9Yv%qi29m?1B6$*=JbZAtLj0DEPD@#n{$(2Y%V_r$sU2>8|fJVLoi*hV-opqLP}qLh?(QB==BWa1IY(vIL#&U z++p_PBx+X?S`slPpiy)lcIgEnH6I9FSGL|$mh!l6R~{CDVC=XBf-Z6ae*z>>W8eNb z;4=`rP()Nf#@UJ_Q!8b09?)Li<%1K;eX5r-OIVe~h@k~QLqZ&Btnm{jJJ6HQ!H6_V zq5E{eWWi!co1~IBynfAHKz0i-Txs<=nXW21A{NISX$v`w=5P96JU#sgmYQ4e{)grt zlc?~i&9b)J%lO7CV5a9kLV@r17QV01vfT@RH913sq|M4NAHXD(BoR&uP$u0Mmxzip z5z!4&V4BM;#Mj9B3`ceuZUwrZ5nioZ3MMQ1{^Q$xdFZms+0!weAxDkKz-vA~$g|vk z+xlz|O>IAn?$>p{+K^=|f(wt%xE$p0+k=_;F(BG?*T{Tlje^ z-Tu}X;M9HpysFtXZYl7p?S6h<@79Oj^~_s+#A*1}<#p7y8DcH}*3eb;Rl4^+kEEKq zpCYX2X4pvr)7kb^b5Sc>!}cfqHp(oP^T=y|e0qPYX8#L=mRHpn@$f^Bb}O zBMCgSl5J5zCy!#+Y`>I!bYTHmL^f869hF(k^+t&&N~f$K;#(*Rst$b5kc9bn>Pkmx zVi8FnH5r6~{5d`lMMSR|*gu8@R5$i8=7??n!gA$GhQCSkZioX=zWn|Bfnq^TtvK#b zB!4j@go-2^)FQ~)#VceQMuw#z^odD!=i;o2Q1(U^$Vb$%?WH=!8Y#hGU=wnFG6iEx zOP5?xJ5h)J`3)=-G6&4kF=MEeetFe*H!Ze~hp|;g$P;8l;QE>RsmAVE`RD&(VwRk! zmNB#~K+wQ?0D%1fXb)CuS|v2l3CcWO`I2Or5_3|N?JHVC{=v?v4Wa)NuEQ$-)ITnx z+Z5B5^F!X1ItxTw%A)Y1Fg3Vn3Yvi$Op!WQ7ex?KGO7K^%>A#tbCv!;9`XDjx=gB4 z22y?J5$V$YG4ylN1U(}1T~*RWQ5~<$G;j%65;ZO$41-aH2t~>Iw|o<(AKhvd=~8iC zWjw!X(SJrF**f!;K08DgR-lDoh(yizk?4r#q*IE}QI5~sg!(+1s1ln)@<0_WI<#yB zRF7T%CTT+2Y7Jj==z{--QwUnlO+Z2K%qvTcTOSpH-V^<3>w^hU%k-bG*zZ}*)go=W zld>y(SfYac5^3NFeHK+y)Msl1XkkeIHcJqCJ_P}EX)|*{Ko#|c8!|eA7vdplXkV?r zj*R8VI+VeMO8tjmOqBm0UMFN6E@SiRBWOgA5II+Wif^llK6D9RlPqV6?zqhMB))!r z#ctD?8cYAmi^G1kx9QwNse!bwPQ;cURR#WUBf0sNK!PPsP!9^hb{tu((Na~L=N;Ol z@nKFT*Z$Sqb9r-n(h&bOR*eMUd)hcEts?PmIcnmOn%`9MWEbdC&z+L@VH`E_YUH-7 z|KEb`NfZ2HWv<0gjD42(Dy-hidAZlIXsqSqnL!g_Q_9-Ky8K~b4DH&~&a;F0yjlR) z`@X5x768uHvoE(Z5v%K%({trEcl6}w4V6g&>c4{a=1N>82LF`yn?0Oh(wKrBE)^nZ zkvwrW$|VWa&R7|I96@6~@#m_j=5Li&Sg`MK^~7Q*Vw{~4n~>y`he1ZC5^m;EMl2ze zBr?pZeXdZI01pg_k0EBU-ra33W>xrdR_X>ORf?i|i<%}O8(~%px{kpjsXF>34fJG7 zZ|}e){K8lJXr?NIvyxKba+-72Ggqq zd%wWgghjiBWX9pw@gr2Mw^z=UCLczRb!W2TtcLJv zLu=2`lQqY=@={-D`P&d3{87na`VpULc`XgLaz|zs<3sE}>T;{W>h?)>=q!>W5aqm3 z#*F6d;`ziy_@)Hsc7eu9*cjKa2{w7C4H1|m2=R6pXsuz$6hShk>X9roJWyH8f1E)o z-%ad<5zx=umHi-*sYgd=M&_X=e?KS3hPS0*cfR?A`Zz6pD!=ExkNkP<=(-~tF8hQteCS(M+vxmbHi!7D zUgU)1W%+c1;YNCl@f5Dk=DOoKY4)a$A^$nTPY$ zL4aiLM45WI*T&kWxYTT%ByeVpbEu5He5J#M$}LI?*GN95oPgK;yufh5ZoLH%(rabB z7rLMqFy@}~loob)mG3@892k6k>6u z2+fYCf%ZehfNst%Z-A!n5pS0JtOViXGMaW9}IJ{r~0 z-x^=FZTO#@u}ZhBXs{ZgbK(`VvZS~qq_2$>{Wnv@xe*c>P(haIDlU{eLE-|E2&!xO z?<#yC2Sgld&~K$Xrm~=d?+!!~82!ss3m84F(sjs%2;o^4aVJuJa3k!cP|Bj+%9ers z9Iba&9g$|mLT)7D`SjB>iCIuk69aemyH5(mV$SSo@s@Se!3jwa;}Qr zmSk5}(!dPA@mb4#!;4J2EdA`fAS0b>9JbFn)C}^7=x;)aCt}d3Mp$d%|CSWF8wfr zqcCzP=2CLFOP6Sc;^jDo&kgty}monqZf2TrHFhNq_ z@aXTu=#RRS_145zcZ4kH z;A1jtw!D;tUH*W3EHkgjV5Q4!^NBn3skda!X&pBhP5&e3_Hxg~+Yio#b>tSGCH#69 zcEgT+{iHrrzz#sNa!>jwOCE!iN^sZdPulU6!x1Z%fA(j~HlM)V=HpdHYDeJG+or6R zPya~VyfCHE(0}jL1<`zyXiR|uckLNjz9TH#gzNzh{TxC?!yEIGI>1#C=94julTbJnS-d}Ey`@t$o1x7`He~&_@Ud5qy4tRYx!Cl>UVeRFAI=#$=chv? z-BtY}uE53YwU%AzdNq4-j`gsqrNsI~L!T4)mWPb7k)?{Acq;q-hZTmt9tI?CXSgYJ z|7}36St*oFf(pWFdHO873>8bMQ>!?Dwk89cy%Zm{o!~W%Z=U1DYDw3C_`tlL+DBzO| z(Z&REN6+~p_90hx{|iZGf4HX`tf@U0EQ8UPiJ_}xM#Fx6-X@pV7#yYeT(5c4zjv92 zd;gugs`q(NB5B~Y7h{tUCgA&1lt?|R)#puAqk;A>LzT#%a_i+^s^{)pZr?$wZ?-6> z!}crZ`l! zDr_Y}z+Fl+Db3AO{gm<1I9>Y0w8SlZu|0X^X20OaDb@*k#?#0p8o+u^Ax?mCD)^;qP} zBmf6CAueseGo4Xy&io}4H)&1ltP2!V(lY6?W94&oatXo-AW0LkxxERD8MqEQ!#G)` zwX>#(qY+iS+IKJ_Qc7E9*BFhI=mu=?{P>EFeG)_|gE*S7W>~F|UBaZ8{xV8j(K3P& z1yURE;qK<+G$|0`LF!rF{vN}iePD+(5Vi_dTbf@W%#=WP1f zx@NuG97E?-W#+Q);*|21AAysJv+~c`C}XtR8`pXPqmw7XkV+{^s!}8%Lbwg)$P(#l zK1E#dploHHLE(tI)f$3rnjJ3)XEURVOcmvnpUFB2#+TXUQcj@b z!TmId4Tms;YQ+dAY3*uM)pTQzyDz`XkFP7TuOag!&OIS()3f7w9+XS9USsj=UQ>MJ zLu4G)yH9fp`>LN#I7{!_x^@C)^p<@4VpT0qe4FpT6zfgbIDD^KM&q&2-tM74q6?68 z$E>TL{63~m{Zlo&4q}My>cJpR8Mz2Cjd14ZTK5YE|4fsxRz}2^fmMcQ zCNvW&&V)&5_70s`N@~@4``Xfb=;INjLhrPFY>GDMCmD{8F2=$Zpx**kH-y?)M_fB2u#dQ0&X(iRzN^rf^yq>0d6BCN{Ya~8fyuU<~q20an(1L5{Fanz}IT^{C-2F;OnjX-6 zH)#E}0!msTFaDZa|MjDBRrnmCf<-=z`$$||XfqpNKW@l$glvqO`7m~4>}ryp?Qr0A zl+;E5=qcD09#9%Y`rk!5=#2f78=Lfp#AwuFpjYoUX))D-i`Ua??uKW$vWdKBARB_} zvyrol{-1XB`X^~&e^vIH*SqdVR`|W-b;#|MrG*97#svgv?~0-qE|$Kh0MX|#^xxNu zHf|GtP`NFXPCQ=ZW1iQCG;xtw6u_2E8Gy9^m1cD#&{UD@ zS99lKazjxO9#QHtU)XDqmyVb4n%3dbQOk2m=9f8a4%8AcQU501bxqp)#vpJrqj)u6 zEExMk&wFIoED@C?bXp7lk61)Bm2^4N-Qiq`V4M`W|HW6yK0M?t@e|UX&}8UL^I7gD z`W*S(;SYE;!Fj4bXb7MEWPA5jrgfJT3|T$Kwb>(JE!) zmqIs?Ge?OCkXA*Zz9bh6BL?~664>Z)poCJKYYhH&mTPj>2`QSJz>MDYBbbKM`D?-j z5e_KKv-ri-;iPK%a*cFMj2R2>zlHt z-;XPa+M^yrNv)iy+xMpownRTGRdD>RVB0by2s_(k8;kyt`BecaLAnav%|`j!8l(mrFC>AStVjY(I7%6JO}k9pPZv(i zuuBEkflLw$W%!A@d*$GN>vRw7RyxO!4g!Q7y z?b`$p$Zkv_FKDZ4YXZF7ZgsS{pSgxPVp9U7sCVB7%cEkLZ)?AU+T6>T*A1__cpRr1 zo;rnC=&7qyR6%3b#RK2^8!8lbgiPSIX9MU}^9s#ns*_UAyLMq{@iJ9(RDui5?X}3u z&E~TT{jlWEQ<3;?Y7`^;Qx<9Gj{d*;?k6q>knY7ZxVM$F;|kx4UFls|+UzeNy0v2H zxLeaQ^?Xa5Iw-R392qI*OIrKU8IOp!SnqPgPn>bgr@&@&cc;#FvZ+sh=j|7z{I;mO zHMnN*y4Ju;-|05v^){}pNWAFxF~s;z6L8-oNS>=D4uX{i0Mc@|!eU{M4u#nyfTXYm z-60^6yc>i-$3f}L5l(@e6|3j&RdD(%|IlbrNFN7dZ!;A6@FW&=~_ygC4RF* zTS%tEhAwYu9#IfEVCR#M|m!2BykEE)YC!<^^;djX=4jnIJw^r+vhWGkQ|wGnmi zQATu>Tv6;xJII2C#;{cow)x{J(-@xNYNI16QJNiZsMjb%d}>C}ZZVmm@@bU)iNYD; zt)(dPNoA13lZi=GKz-#1cX4XE`OerIgBmerq?_NQoeo1uB*!0~rU^pp)=YA3>b+Fz zM?5VK-DhbzSXg-n5ZwtNUCeOsn^*JmsX)d*l+HSNokoA}f)?0EXwl=FZb4QFTk?xJ z+exg1;t7|I_a0pl3gP!dxxG7*1kyRdajVoqz2E4OlGLRZmPnvVVGAY~ZvQoVHUyN|)3&}E(O z7dJdi(SIo~z=`5^eKx*DXA?=jaeuJ+*c}(Q+>t7X4n{`$QzW@8#4LqINZ7oDpKwicWM5AGwH>5h^K+04;pc*y$4#suk+oT z3Kpz4qWIMW6p{H-jD5vQO?sTo{CcPIEINtARikJrrMkCV_|EVCj6o*< zrJN1lC%=Fo>}ce8U5AdK6@4O6yFtUx9U_if--4suujm^{gO{7FZ9~CN^#_Np#MMPe4>{tLpeC_`I>y5zp^( z`$Z~U{y(1Hf-SCS+1d>Rm*DR1?rx1kaJL|hy99^eP2=v?xVr{-2_D=b!3pkm*?WKI z{)PFhIoGHfquvTQmswP46|mS4EGdmU7_Y1WR%o#c@r~G5KP1>V6zyrdt?uP2I63l_X5TcD_iwB@Zs(9a!v|b+RX(hFzE76LaajJ>YkEc#h0&aq z(D6@fNmtdFMM*&krlr(Z)mOFU4sXc(6^rQ|L%W%RX&7xWh4uMQI|R&4aM~oUP`3PF z7KwbAexZ;AsB4K-oh@85z`=yrCs8ah17)~NE_V{Y!()-~C_`%SsY(_oDR&L zz)B2;*qxp+OKJF=c5)nZCzJL1%BJ?pf7kw)_Oi=V-M3LwSJsP0`{iJXB5Ko+VzRaz>WkkIf!ee&i{GvSil%|*1DT#a5E zlrmB205Dt*AH{WM7YJdKE}7pwHvv-Uj*;W~frCSd3{DPRh4cH}bOJpq1<_IRz+oGw zdi6nTHEfMwIsu<75%&+?z!0_8nED{iof?1dkju@F4zlgGsPiPF1Mllq5?3yLr$|-K z>ZCX#W{FL1M#tbK{SE^>Ls&9W`ODd|abeWZxqZQNG83j+ipy);G&TAfufVyQm>}8z zNIF|nVvZAHE62p7>g9)?%yalVbOdRJiA5%aBe)itSLWu>yQaFJDnhrIp0*@?gU_Nv zWV^=qZpMfw2t&%Z5Ee)WZquv**U_Z0puM`7; zrpE;L>JP>UZDbxVD}e+H{uh%ZKTkf*`>(u*Fk{Fzkc~A}jY7T5BiU7jpc}BO`xXOD zBN~*TQd92?Y6uO~!&vNwI7=!xij5Y#6Fe7#>o*%@NT};v{!b>myhASg75w(i$^Oip zZ}lBn2}hqBx#7qXyK%d935Z``ABd)Ov}Wzai3Oc`u222>jorw_h2V2@h-ror6DWr; zSk_B_Tp>v`Foxz!t>gb}mwo-a^zzIpASdnZiS2SWE>BiV=qV;KsL1d%h1_ z?f0#4eGS4uR}&pAy_Kan3=1JQao`K$%SzrmPu^Qv+!a@x4>PY_LCQtFN&r~J?`0mq z()o1jbU;DpxRXw$@(29hiR3ruQH|*?q=Tygzxz8w(YgXNa?FmJ#eDnbhR;UEOPXKtvit_PBi<& zS`JZS78MNG4=wcGEsWjET3Vmn>Ul!*UY!<8Y?s*mfF57)kv%epH0;j|#O=@LJ@jgdXga5)w>aEc>InNWM!*5=PymR&^(J7q0=YVywF=xI^h) zWt(iophh>^1X-Ay^kRh4BA-)IdWi3(3m;Yo#HmRd!L8<4g1Vi>8Zjf0R}Pyj`vKvJ z6m8N#ZJa(!*rWh)8=)9gfb~o3cxLXB`y~uUG!OP!Fgr0PL+l}O(phlTPb7A9lr!C3 zkFQre3Q{%PEoBV8NY&z2L8`pdVGWFktoiy_g?9YvlqZ(1)Y413{Lu07+IXL|+|z1) zezHW`6_)9xD=^Pb6KrF~JV7bNq5SO5f^EY$V2@ONJQQl$rveR?BrGi=RZUy27iO)3 z@R|BddPQp1HuaFvo+O=@y|#n`xJ^FqW&ua*kropHPfF|HR}~~ux1qM-f;RFX!0cPL zE9mO0!lkzmS>%UVO7DXZVf~w zAebOkAc9LN%^^4zRMkcEphjo{^GY2sTxhCcd`U$=4;T!IU9K1hSH4}Vw~)GUJCkoU zu92V}&lThNig~|#*>2=L)4}_`d)w%#NV*_doCLm@-*rO;EGg_Ckz2l!tZ&*; zM6;174L6%OIY0Jn2J4?}gR6nyO5kx74)qeJN)-*JeUsXq(_X(Q)p<1#W(jOP4@A}F z)K+4e3jF`?a3FbcDCK3gl~`KmhoIT&N!|E)PMe>8*d(y`tMTEVC+kk7N#~C>$BqOK zBEDHh*QZws`k}cbW|r$fd&`WRO7udBz6Bj)8Oh6H&z_8x%M)C z2sW|czo|0%84I)C<;$l}pu}Xp%ycQ}^7r1+d@ncCEntUO^szp$U_J-HAYDfC0n@3y zUaR%Ts&+)KW?5_5l8+{337*URTGM_Ko3-Mz3|G_s4|nw}y8+346;3|0qhbZ?j)RMD zy)Htv96>YaK_)G3&M$4#cJ-eB&SmEamcD_0Lq1~HrCGffxqDZ z@-Cn=FpuNw^vkf)mqQ7)fW48DBM3jnQR^N3AXw}aq#E?WD!MpXK}px~JTg~~*p%9l z1;G68@pdY}th$~eE_(%Z;m;eA>iwupn89P5O2Mq8S$a*ia#I?MnO|vdIwgog#!GEZ zM(Y}W$Yy{*#SXpli=i}MaApagSQAjQm=m<=+_m$SsbJ@*5}c@G2D=gYARX!`AYS}P z{)5r#0to7yMMM(63KuUo2={5zR5KDW(t?VXmfFV_=v>}AEIvah5g$KlhGxag0hg_W z9!=|c{ks5WYz)Mo0k5A=i@ssLXzl6)QXXuODN;ts)Mrfm%%}P5?tW(g<|J-Qf$qfh zthL5+Y163JgZi8ygE~x9FB+YyI7?cKLdd#;8IBslfC`5EgQQNLT0Gm3rl4rRq5HLCI65O%jq}ibz>F0Ad*B zzdis;8R(pKbWHpd1bM3AZ_yMBQqlO?Q!@-Tqt1`w+kLY33p_eTE)3INi?!TL7MEzy zzclH7FjKVz=vyrKuZT_dU1YHfkMcI+{<4iHHbYylh6i^9{C@u-Zm`u1P-3AfBYkzV zYAgdMzIqa2$ih>p$TAq{gub(!M^9k7q|A+v<3*N-g|MRAM!}>p-)ES}XcyBYGO^sh z>3_9kaf4P=bkMtNDY{A=mazZ7yL*{LS&RVrxTD=;VtyC%!Y{vM-Bw!J4i5KJD2>p7 zdanPta+OD@E8gVo*S-rG#EHZ{b~WC>B_vaVX}$dKiV@oQ^CN4W$!1@%GyO~DW!#f{@N&g=IWg^x>v^^= zEpmuan4hv^XY$C&=J&>>7x;U?>$TEkEaL6xbGF+*jg>YRstreEvGLF*A6szWH#wd% z3<8mm6tj`oGr#Sw_rZ6czUzl&vA}St#i|{fX>T|uujjRT=|u}kh#E0yE(Q;;|91s% zdyRn0iGJ=?k(>9l@0RS~PGP}e6FofGb%tuf)$;C?;t4@v)FbvR_&zo+@Jz5}>(!%b zOb(hYV3jJvur-Ly$Xn*K4-?3)yO})ZrWnO$vW_@>uq=oN?R6dSB?3&Ax%n~u6 ziZC&pA?zu#pRy1kIDN2Y!3FeJY8#0L>cI^+*kJ`qgytW1N+AFXJ$hkqF2OcV*3?ze zl6!oiOgo53`(c$2>vdx|PJV^AC36H;c`o()2f#>;_EWG$ZbvS8nt(bgkXJ(c{&JiX zAxMdsF%PhG4aj7FO3qhJVB`&m4oEh%*8}rmN?wtUp-?ak(jUX5LdjriB_{||6lla; zBf;VusV=$wQKwktM2XL$*u?dM0b;XUhH7Uq!cg1n)_s#n`*pr9@8rm~=Cr1KIPGGG zRuM4dtn2Do8^Iv*m5#Fq(McS~Uodg`fXV?#Ur3i|jbr4O%H=((OdZr$^RsT@d-U`n z18e{p$Dmoz;_86QEG6xzFha)yS4v$ zLK?f;lu!eZq+d?+&`t4(389c!L=XXkD3>khDMz;%Kp^r9@xMEb?Vm{?%QFaQe<-0T4~LME zAe4QEHlGnGLaC)CR~0G}k5ztVE&SSlt-rIWkWfpst2uRw5t*uJUNW>hYtCxl_YCOS z+M>k7k(fsJQ%=S0EtO5lMd#*+;6b*B0j*A?E9d$mgc(ul0#v3wFZt{ zWq>Tz*2_J50Gibm6LHA#a!=Q5kIR>Gy@FMDwME{*-K1O}h2h0aGh2sAAJG>}I2&cN z=8`kR>Dfe&-Q&<>Fx|<|-KV+8==no&j+(C4tkbYU2MdQR<&vRE!Kz7FBe6vrPF@T5 z8oMyW|AaCA^S9bU+wq=m#~guqzTcP>^M9fGtu=Y`3+3mOaGKQf`CdibE6e@IZm-iD zW`ovW^&M>>>#kgR8p=WR@*F2i4s!sY-uaZB%WW-730g)n@ZX4flbpee8&k&E=U)QtPwf6Ii6E2IAW z4gR4L?Tx29)_N@&BaVWX&zvGZnNpz$7?xG@3hlPm>N-;0deKi7z#Vvfl-2h7@3YtW z*cG;kfgg%Bw)anI0sMH&Oj9*;d&wS@(6Tzc{;0g~u-)^23-dORDO6SVU*4QvX`laf zdc-7-79ZFXoizRD2;pJ7;?0IAkf_h&!=YHu5>d4of;a)Tlz;1JCt0Ku^E(T_ z1ZyEt{yxL)lTB0;*X9IEdr~B>fUeQej~O8z`83@WeO395*yki1!IX)>a7|&_X%{W! z+)vQ3nH5#D5VX8pUjLFLl#64J25-b=Di4Tp6mWUV%-d@FbByPq8bnIY{vlM8`)M=T4HMfHW|G zkZ;0aH4`N5QX_bzcWmrb0+-EzxAgZS7oWOBneU%aeEt1q&4Dzk&q!2oHpMUtGIKJ$ zGwLyr$q}eT<@^cp=vaEB5W2xcB~OAjX<`Ni6qaI+L`lbZ`rqG!S{yZWqHdIsr6e$f z=rOABi)u2IM9x&_-9(B+#Ul&wh&!rO7iZC;w%ziTF~v_|#&5HTf1!^ii{qfrmc=(7 z$0ZyxXyYk%-=x&Ktx%B-6sL)W6Wwi&{o|V6*F9~J_DMfvI2NtoiJ?$WAy`D(lzjpg zq2PGu#%F{I%QM(gD04ywQ}&I1%9+Y{`8~@?Pl(B*T=Zyo82ZmA*K z4U7}c6IX?qCy41}GBeUhL^p~nqm8UkbIhW*h9aY4!BUftCAyQqmdPr)`YQ#BAgkBX zLCtzWWuy|M&3buw|D{w7U-%m0_a(!4(BZ8v8kg+xkj{Cd*+l#VYwNhJyE?lrZ?e=K zT8oD=@(=gmVh4^((Z5wyB?rpc#aPe86lWGTJM)}u3j>RsHhsD+UIStk{*@RmTwePm z^P$E6-P0}R-4YZ~%8+^IX<9%MGTXDGW7i{Yi{sjG{}obB?2d2uIs6K5YZwvcME~Vp zHbb~sUH|SbWm$<7Ho1)1IyUixg1Azu{-hAQ8W0<7U!!}NzkkE=+;S1p%e^?Y5{o+MdH^z$3iRiGm}2M8 zZ;2+}e-)3umuBRxZT<KPogx*TqQ1|cZGIAC_)A5CxPX7!BbyBfMpHlJo@f7_pp+wVB38L*9M7U&Zi zub_N_I{O|m?mgb{jq^-(A@;k_-Y*f~WnaJ1OaITHi_nSb0|FhD|xwjVBme zP^6-PlX%{baiTRDC`3XS|FMjnFd~`Ah zqdWqb7|BMXt47L~e_@(YOUE#d@GahbLmfb;;0+1Tfweu0$Cqm!M%Iml$(ke6{D|*M z@KBscVy#!>bTF3%OVWfxYUJ#Z`b_6S4{f8hHPy;eWSY=nDj)zlM71Ea5(4S4AE|_B zH?P>M+Bb$%`Bi1OvGsm0{K)<)7>quOpK;+}DSE%z^jdi0F0`U3%j@ByOeC7tE7ew9 zk|ukB)lDHov`E!!*p6ZB73*cil8RswX0;Ndrnxrjc=CtEFZwol0D@#d#kO^dl%MFt zOtq?F`0#ENAx;E8HXtt2A$a`gCq+Cuhc$+FL==4z7KWk7AT5E%jT~pl9HO@zgI`hE z8g=<@ zh$b07Z+-)-x(Wlmj0Cy6r-W4Cw*+^hcn|Xsd$@^ zuCWxvJc$U5+~-$NR`V^(={uIo+<(ZA?Bhw{loF>2pF<=KODqA28{z(WgaPVB58s3{ z@@twg_{YrLTu%883fWgGet1OXCloe`L3S1Na1IDxI;|~cMoNxA@Tz4R_BLp&qydB4 zJQd;Ou5**}QiW~H6n>3-tY}8=oknIOFefw?fb)P%RTSLqR(u37W{`Ctqw#vV+`Y)NG30*3+q46 zNw1g>AhL#%J*~p(RuU*wLSc@K8ayC;^P}pT_0xfJpRrdJgQn1Lh|U zzhABh?;VMa_U(1Nsx8Cy8zw-BRyizkq}U(iUb83O zh6)UZMpO!X6?)>ys=vXhy!3ujG_K|zXyE%ppG#WQD2^||Mycf~xbx9O{^ zg_6}mcF1Z}uTCt+U=j$z@wtt!*?>l1<=(k7<5VhDJR~bpa5H2coBz^C`THvu@!f?f z{H$QbZ%&G!GC?KA0r0&N0=8b3qjDnT(TiRLSK-XdOkvA15h(6t@#Ra9fgP ztVBe6FbzD2mF-_gF(B=VU}DYM?tdgX{f9u4*^LhZtHK8(6C3DLYsU7=8fuxVPfVJ0 z<-VVL27dO4pgm15eoF&Sus*QOj9!xm@I6iXHx)D8H8&bSy9;S(Y5 z7R426`UOeJ>pq&9T*SC-pIFpDyy&LvrwLXL{m#uh$aBd`r6^IP3Z>M^zne!YDqaioPgieo-$cAGYo$%xHO1m%KlF73`EUD;tYV}$@+`o-L6Y~YK zTOkD~2|}LaIgqs(3bDY;CxezVYB==BCiRIre0A{dg=Ai&wv66l%my1EyVk~|b+^mh zV}~B^G?!W{0Xy_vdA@FL-Q>~iV{9uZt^D)M0ccIpYp!vjYXXQZ6dkF?P%9b`A zFk{9SwiE*BtNal=X?Xnm2K#K)<j*U<{(q| zzc7+zV^`6ews9k(N6#NYFcV9&?Y7(f+QzoJUX9#4^UjA6gU;(?w%sU-YVLsr(qh!U z|J1F`T%Bl|#a3%~HnjSweBC=Sr(H*Ijz7)G$b1gSu21p0qkG;e@7=UL@WgH=oFpRQ ze@T%l2z?x-pRaf;r~9I01SY29nr0hgJQN6W5%lR#O%W$8=&pKqdOW4wpF$6!iqXO>jxf@w@l(4cK1b5IAId1if<4Xqj2 zR9;B2OcG$Dh%IHbSmX`n6DX({tCl!MGFd9BI5JR}r_`oNERu`%JF6)a{vLpLeb(zb zN}l@QngQVEAuOiU*GCTngpOOKt8ROQX~&u!ssaGEjHMic#X6<#RdB-BjU-Pv>FM+L z1S}_ri&O*I<8)=~+u8fp^?(^GtQgd`buAO z`}Blb>#CsF_7BqYn$o}GnH8D%Gyu4mNxHwFR0O-~@-49gnlQ7kLE6fQ@(WdXQqJo++;UE>s5-`245#CKV^xJdpzj4!pH1+9UAlXJ6s zzl-;Rqgc%!I}8xuaJ4&rDHT)C#(!nJBQb%9ESpx*nNuPKKTEvv>eFkY`nCLvvm%h)5$ayVe7}%-O zd800k;bLe%u`h^BCcUc(D~(kIq9ucWd&qZ0USfR&(nn&+c78RoZ3Ao;EnPtgfI9C0 z^UBG^?&is_G%a7jr~0iZGP~BTbePGd=(<^i7|m_}mj(E^#*5V$W+z7mL`+}#8&SKK zOLQ8imU!&$PFDv0r=!jNs1PKh6VQ6zN&L2*-ZG?QV=oqJ4HW~Mr`KC@+QthshHgz> zxXIqOH=3?+4GuiFC8gcr)Piw0mXVg8G-&9H(XlL#uVZ`Uei31YGmAACtZ3G6in?dL3is z^_u5ix$n20Lkm-QQAhWmQ=J6e&fLUt3@2m?#wsi$&-wzeBb!gt^A2Wq1`xoX?>9z( zX-4BaAtTnnr1guGEU!hCS8UG>Z#un1E@IZgJ~d_Sm(5-Enz8PvzI! z?j0Q;R*e7)f5$%*{8F|rFJHhduc*glb3XU5trAn=lEKiUxGmO{h%epG11qmhWaD3N zS+%C;I!^uI{i^FJ;L-Nd z&;YaZE%Zl>0&?>;6nWH3htSK-sXO+SQsljC`+q(&*ltc#sg4}X-h4c|t<=j{b>Z5USwDAr*70-k*!&(f6GD4}7h4&kf z+fF-;s^%cfA{$n>Wv?*$ddXkqI_budmi#ZIyznv{SmxzR5wym7OHd|0%ia98%%uMP zFemBA5b-VXhdfG1U%XOnd;*pdcwEDl4uIIC?U4X+2MCuoI9RocTNy!Jshn0!}NIB@E_)$mV=5EVh6ABKibn@FRg?$|z3w+y zLnr>s&_o5t~fjEAGy8@?cX939a;0>hV4rqPCEk~Pmc1HF=k+&`VjtbZ}m zj7L#T-jEcLM^+kuLR?%L#3DY)+gXUjF+TuJhr=~^wwXjWLzjCI8LJ(iQ@lY?kqO@& z>Fs2lR10IirITU@4lO3 zCIQ=Qk1KdR$pJ=gYmCjJtv4 z8j_Z^9E(~oFQJa6SM}^Fx<9OVy*j(VJa$>8oQFA+3eP~$NC~(D>2UCyWInzR^ta}1 zqrqo!1au9l3Gd*ANvGC0%@n!`)G^R+Od1%nnZc5AW1b?(Bv3!1S12=InPC1&qUjlX zB!vSIP^{M7k1GP<{1e%~g6$WkL!eE>4W$JKUfwNSA}(b`ZprgT#KK~cdT@@Vy+YN^iQl!F8RK|u?{CQB%6NKX|mIw5Dt0G+ny^bi{#nm)Y z(rl~J&wv+G3G~G&Il-&&WCe`2>_}LYp>mYLA+%*C5+qdZ2&^)539hZN7*w1UvcKpt z#p$Jb!Kx!5oW9TB8-w-8;UV;#X9$7>47FJfooE198{5d)-SCib_C^Nj)gb{Dpt|M_ zJBNf2K;J=5Ijy4tF;Tnh;VIdpsNU_lO>I6gZmCwsM$h|Z433M&tE9l>j_f!+ z!A21lkVT@h{ZA=Hi_FiBrjSW6D=(MHiFW@!dlq6jmIFD_nj=E@V#>D@g_=pC@zt88 zIHp3f03nt| zqdWUG<9MKJr>l2lY7d?xJ+Kv@O`ajdkRHd(HaES+=ek~toNDw9fGeizGM!A=tHdu{ z7Mur~dZ*06w@glA23vUpM;9{?ZO`?L2t4u%$|3mK<`AJFvA2P(Yp&@>#DIs4>D|Kw zDtx<@4hNwr9xb#kvLQiGRg%6PV>LQ7XJ)gpi3(Riu?*&?1L0NcWcn7TEty<{nwMFo zN0Yoa;rFv86KOU0Dbai8JHs3Ln)f+n;`Revdow-5qsx@#KP(j z7^4stF{XkM^g~P8IS_@~7|S1~u#T#Kf-pu`n*P;i6@m;^sHx!iW3S{z{8olITbR3x37$HT13!HI*I$WT}cta5ingiQw9TN3ugN45y?*^!R zR%&sSwLrk_k(TV(#QO!$)&zH8-ncO(Whf?!*{*3pUr^hAv<6@1RFilTzA8b5=$JuI z!#?MRe|EP`#vlj#a+BE7-$9LgflbAL$aKEt!~)0lxFtd3?k9mAV4dIme^a+8Kk)l~ zjxO;0Z+EF6>E%!a^eeWF`mf!8A7HO&FWwaJ1C-b?zHC`8hA@h%TDCXaG1J+je7tLeF71@gpmpV24Q-xJC^F*PH;(|L+N(xrq>s}TO2b!lOc2u z`;O=Xze$K!dZ;632Fyk{_XBjT1(l%d%Rl|KD=DE>L+XB(SJ@Uh_hEDLx;F5h7TW6H zRgh2~sYtZ)EOX;22XcvIVf|R6k zHKt-b8RY-G+~QB9((aXuJS`G2!6pzP<~=~>@{ISMfIO8;=PA3~<&kM&$@l)UQtNX0 zH|-+P#EYiqe!tc2W?RDe{<$Y&Qs{KmgO+b=&AiSXG{1%VA0y4&@48Mwj+r0t;&%AF zgcAwKO%YtG2D|b*Utd6>Pd_JqRl3UakNyQ!1GS7ULmy$-V(>kN4tz9DB7ma`dce$L z)-7o2m~)u$xB{{;Mg&x|WgylJp-_M^=jk9do5MCrTUIrdjA;@|FT=lslhfLU7l~e| zO3j5_{idhwU~wgpZ=$pfaVQlBgi%!u_s$g*{wf0>rCJUF>1mXlj=o_|YO2qhoXwlC z3Ve4Lufdk+#aCXO92H`a2`x&g`uW3fEuLPQgo;!yS(2`V0C_*WDhDEq#0cdVO<&B8 z#V{@#jjZZDXstwmE;MJ>ULpn$5=BR9)pH0UxOHRXeXat7U3Gb1O@-@w(6?^(94*|6 z%F4zGOPTeVN(PX$v@~QUdnHIhA!QfP@@7OlCehf^VcNlQlkk*-7;3oCqAgyJjRE0A zHILA>fscwV0Y4OwHM{cMy3or zJg(Bbayd@0Xn4g7Aq&RjgY4=ZuSD?i&6*WStg`z4+3=Z}QaA7%+IN++3 zozQQ#^EKS|G8SvnrjVxoSZQmLOiaarn;P0t=x9k1(LwS)fFwKvK!a%z!Q zydWwXs@6k@fjzHbG(LWvlV&oN^>*m#y))gF?)z^eV$yXL%P83GVaCEXjD5TXo0qfM z?;ExoGWSCJA{@~PD27pCxlqUU2MyH2iHeB?-`eI^Qk*7pYA(* ziqFTeLsZ-0oUF^n!uj54!v`4elEL^2V&&@mUTt_ACbaDTCf#}X$hMs!_KYcdnSkcD z_R&h-u==1o=%wyRZiAUfCpU%AqO}bEqfS~wt8&om@Yi6Xi8jh=KXGzZ2(ryw6D7SX zR5O@S$eAY~Lq_dk@DOB@WK@h0r{JU2e%Cx!PsdQe$kK6X_L)a-(+SCe{+ww`H39JN z!s$13$L58L85Jg$1qq98~Onk_`y+!07CVt zg=Oui*bq(caGSKI*4~$vYGM<{8T{{)7Q_Y>he}O0OcK)0RBL2E&iMdwaK{p1q=+mH zL8VARzX^{qT(H3%8P*IWqT)I9nn#fwiS%LDL2dfE7n=_OVG1a>b&ib6H4L>ffkx5z z)#QL<^g4x|Y$*n1Na(7yItfG00DcHkcfB2)Yz4IF*vzbkCQoFnZccusXtPbdeTQzQ z?+<>)3rKVSZyFg&ky?2dYCUDGBK-No;l;=XbOeez^AXm6%g-JiZU@ePE+`O`ZzuX4 zfs~rbTJn_}R;tyBu~)0;s@mp-wyyo48^rulmu9-8&~e|v(|-CmBpS89*rcvhMXOMR z=Zs2;36l&tzdTh!Q4fE}rVa22Q;d0H&WuE&qA&XP(f#ixGJu`K!P@IZ|H)7DCW zvNDfZiOTM06-qfiI^FuOU#h3~-tU7gUuo@jGFK-Sa;ZjAm!_Teyy!3u zM(}(QM84Z+ZG0>JDy&G&t3DF5m**3ZRoDUu9U9sz^(XnC%Jq9D54Q}ag?0)YICuRf z;5?jh(Ad<}8}u38+Ot$w-}o;qn-9a1-`zE_U{hX|kYeRLaK-=#^nk6#fiN?EqNJ8r zFw#Pp88;Z*))NjOChM0&Jd^z%FdZ}y1)|@#q$|%Zq*o~EAi+(Aw>ZN^WT&sBRgs3N z4qII?^m@xU?RjSxyIs%QAB%han)~#sVy-K2>^i!>u5Ddj3Z%v$Lzn z1~lE_uYCRoVUAGFuXCtxdiXS-v=&MAcm2QbU?7Zqm2=@%!VgJB0P5A;xD44dLiNCmrhEcink>&#)kA_CQJefXEbF9;!UvCY zJ1X(e_PF1ircT{aqH%O~NR)5G%Tr_FGL|N~Sq?!N^paUT6CvXbd-DBzyjmdBNfJG9 zBpyXLQXN3HI7a`844N>EKCBwr7-nAns1_y5uV%JI8l?zw0jG3!S>B&oP;SAmZZ7~8 zQpHpsjo|UYXeiVy{M5L}PS41>hHfPzOscF3Hz(s#455SRBM7Oqg-l-ZLn34<@kTMD zkiox+t#l{zPZ={ZN~&OpI6J*iaGK}ki1W3=mr&d9P68kFadmvKW$&)T4gQ(oll8*L z?J-Jah#M53B%uH^Bg=GCvK?U#cs|~nFKW1S0=#h9adO(|W{c~AASi5Fui&`{bm!Ul zmDw)UGW^tBYNz>}4AXYiq9LT$Au0Pl>_*SYdICk@cATTFOg$rhP!P zc1;Q}*m{pV`;e|YL}7~>ez);37Ab@iQ;zb-E?@QBG7rsQLwXQKm$jCiU&yc3fL?5t|-AUmiJgUtcs z7hRam`e^}XvsMp77N_wGsopmimy9Sf7ly$1%Sx|XJL8EUA*T<{q9txUt_n<~($}Vy zZhtGR3Z_YW?;~Lals?%8=DnF&>5d%UO`(=k;i#UU{}5EV+~HkD3LiJmSLLZypMrnh zZA@QX4zzU+0DemEX#5j!j)sJvICex?i5<|jU8Z*Z`sMg{G3(y-R_lG#s`d@$e#4(m zXli+^-duL2*_;UKqlxryzAFof`bAh}+fb~nD0?K# z<;PRk32ygr{e6~(;JVk~B6Hlc-sehr)INdH3- zP6#GLWl!Qi4I||>bE2!P@k+}CYdow&Dv+Esg75ijXa1s-QOYM$7GBQhe+L9LI3v_k zq%_bpStr*0XbvyK#wcK9Qm_f7tND&C&4r;6DvpyC8Hb=rC1!~M9o-OXP(YCfo{1Kl znBDTx*xc(C@Qb$Yt;S8C_2L}{MJ2!#AV8VGN=B!1s>VJwH~Ux2ylkine6X(@m`U_t zaRy9RUaCKaPUy`G7m@5l=Mb6|KO*)vKG zEoIU0P6ZN%ET+QTuU*3^e7^FvLG~(c0% zFX*C9-99I9Q}2`T-KC0gt!Q01PmEgShNxEkZD7OPai1+)FX)$G*FIxzexknlk6px{ z0vYRxSgTY-3LQK{$(THtIx*PVREeiE3B?}LORFwR(+a$s)3>)L3d}pB^}rIkwIZ9j zUod%3W?y}PbjIMAt;YKQp`iBGunIHw5Y#A59)4*V-ez?9jo@qz1iiwyJ+}Nz|0qeP zgwFq11-{`uj;Gc9?U)XXB`1kxWzG-TTfUU0mWk#;&tlY8SU`2*9xorCOWr1#4xCkN zdn?KEe(^K{J9<7;>vSbnueG?ozrnLF*45R`C<)sP6`Ml7f%hHb+&Pb)Z9;0B?Q+Y1cVle42ut8*BhN=1y;Uvxz-;_KdeIQfr*? zHhNo(tW#hAobKK94K=zp3ivaYhB41-^M%cCY@zeO=zQl&Ry6nS5BBxXyKT{T2K2TU zFw>!u(v0Jz>$(3uM=Q_Hxu}~^pqHde#(%wv)>0i3>DpL9tMDgq6@hhk903-Y{1Q;pVtMYUr~! zhA|C@z#i#-Bv~}JYZX4fM8)qaoISpoX9w94wRYnOjP;-ud^ZLg=pEET6JxTOLZqJ* zG8W5+?$}j2RMFf?Om-DD?$qPXRMI-c4vNvb#e@bsnHwB3P3mR%<&uS~m}CjIps!c^ zuazXj*4a)7OjwMa3h5283;7t(cfNQqWvW zJ$8qn1lkGK1D70bCtTa8oha4x1;2r zE>*aKBqCcji^%@MgpT|804FkSa5c9>XIWgpx~CJ8gie{-*HC(j3D@BCh!pkXEZg_m zvporGCzL|xdyN!FB7UAa<=w-2@1$D~mw6;!dypL?)7QqDDlhY=Q#fo-|J}_s3jL3SHpfvZmei3u|3n+i3qB zCZ35aM&5Ho&tE6eD-K!%mVjrp&C$Ns=k{$3yxH?xRRumITNbZ_@{i82OV~3S3E9RT z_krKPm9<&Mt5-2En(2W3xa+Dsua90#=f^a6To>cZ`pPYRS=Ni5MVgR0lTcwN!8o8R#Q-~PQ%oq3*G1vq{=haTup0H)H3 z9U+y_t!CHzr!tXx5ZHMlemn+=MFf=Kg@C*x#|U9%{`+h$frHLQuSurd$v?ljZEr=5 zuak2ge88nfW)Iiz&#tkxZ~>>~Y4hh=)=7;i=9<+aHx}U5u5*o>&jGy<{DsS^GoPsLx=sO6f705W?zX{8d6Fw$xBbH~^4Y{K|M;^JwVeIsgO>1wK|& zIH`mIJ8_@ELk~*|fTnHz2u+5q_ld&+w9UAr^z~CQa?>?T5^yF+RRo}oq|$HZjzmO7A=;F3GIR{@bOFc9tKIk^OA97Er~U1IgQs= z=+C&}uv*#&xT(tL0Nr;H(j@)|}0j%+LmMqlizL2;Q~MByXw zzR;gB^V1UoKiLH^=HK^~kE7B2le*$I`X3o)-?Ej^FS9vH*td1y`IMhJm6L;kr@AZbLM_{4MWa*LOuw zv&xvq$x1T4_#AJ zZm29`pKLr_9n6W{MWZfUV@R=_eJJu-jPb`dJ||KH(7Z@3^?1 zH|mV>7%;u2>T>q`f3T^CI|*Hrjp|Xu}VbsAz!! z43@M8%&g2Ge#@oMy8E6-=c!hYk{U`zb}sExxazfCXsS9uuTeTY2C)cVO${{8tw&!l zHjV&2D+}Ogp!H$pe>a5df>JZsyjyI&es=QV`dCu`S=->d<63{8l%ghUom)U+6su@N zSmA`B^Cqe2O?~C#PN`_nh{!(XM>y)cPnRgyyhd`dmCYr8L@e>%{rfgrx((vT2hY~n z^s@2t5C%Ix#>^n;8IaJSZn1h%CGzZbe}LO=Z^mbgo!4;$b(cc6J3#gb-*PUP#x*4v zHFiYc_;Tejc$kryZLvh)o1VGaf9CnIXd(5Z2_1Fz^RBM$HyuX|Sa>|dE$Tnp4g8+_ z1Z7nvFA@OxbIQD$2+Fy$sVlfb2Wx-yK?-t7aw4IElKZyF(6!heq10aCpV2b<@M1fG z^e1w*unvSY%kR^hStDy&3kUD#Jf}O^Zl%AlxDq~5h+E)V*&%~LQaDZ67|2M)l*?d* zCyg0F@)pJ~P3i{CUwarAk(w5RHPNY~DU*WY;|2KI_XMoYyGqW|@JT8AkbEgxr|Ym$)xqowGB5V9rGKX#Ba7WZ~9 zv3dJ8A&yiOXUmAje{d=Js-t z$&y2tV%uZ%t1ePC$%`$dc>~f6O-yffMS;qjh-4b$zC)e~I>wM|9ZA+&wVmb-oV7^Z zrKOwod$xk$aYEs$QD#h^LD?-ZRv^$M!r;(IB}s%sBrOsd@IqsYHm%-1x?T~I9PLV~ zpg_d*!$eAqE3qbF!uCMQ31wlRC)u%@s%IpzrIlj+`Zdg(zbmk9=R}|rjVqfV$DVBW z?ePpEpLXQ_S+-RHwRM-+vzt3_LA_u?o*yQ)O<~(@x5GrL;)FrGpG;2_g2@qJAtMP^ zRhE&_cCE~M0^;f^NUUuMHL-OCf|x2XxMhr)(|hZ<R z%dft8Q<%aOrZ9zP2_%8QMejbF)tf7J-DLsazx@_w&6>lil@Fs-!U?ZGk#cw~)&+Li zbvM>)jS801+UOZEY0y-G6(|+WSEUFDsc_Cy6diu}z3*|+$3D%Mueh8|>(}#d|NnRR z^k@E#m8({B=g)qEl8P+N7#SHQO*FG-&tiCJ6l*J@(R=J*huR}@VA@>1_=Qh%)>-f3 zzWeW`)9o;4_8h7zsYu0W=IYGD6 zCT~sWqo25tGv9d*#rO!bX3wH1O4h93g4CM*cG-obS*P7N!=vjr^Sa|+!hhd*H_tzG zUn=W~qg;|KhuwCW!}`seX~=Q1#$0-*&*Dw{k1;);kMb3b#yCm^bW>nT2U78t7tH2= zetr`)_oJg)eEnNLV64+&!{F_#d2}TQ9dsDp83K~cn>Mj(%~~kNn7`K|o_FLSR5<*$0(n(3)Oh~-POF`Dqc;m1|Bt3+bh~SZl zLfJ@OD6L7;s79(}Opi~JtxqTy0zoK52=r)+51LUMXf-o}4>;>+Ny%7I#muENMFoK` zyGW%FPM{hJ>nw>aFj*7f9Zn`uQ!Ao(SCS=hki%IJGFCAR(RWeiEehx9(I9n#Q2neK ze3aL}^lZAN#U_9c(c4N#f(jw9m5nx9)?p{o1j{P6Nj{)bO(G=Ldx8z%A;_3nl!SOa z5~9+}xvkG_rzFY;60InT60H?gWdKQl}yo6)Sg-rQ&}=BWlftz5>D49_#R|Fx!l`v zr0bFHm+yEg59?1U`A*ZUAF+_hTq@>ziEKK;r=@y zhAfXA+6k6_Tg;okAkIvBVZo#%>#5?IpZDa>&X;ZzYeiA z@n`eUIQ{)Cw3;BZwhcLcGS)FR-rerJ?e>n%<(Ckd@bdll;_auMMz`v6^b1}>-cW2A9*r*qznO`|vQm>)nqyyeJZGNvXB_|P*D~JeU`@%uz%+`YQxji-iORvl8b|+=G8+onz+{Oobn!TKL?uY2f zG;cfYWbR)6LxkJFNq@AM(rU`_SZ3S{kMBnE?L`O7W^D!ESk~siLk?rK-R0K*y^d+q zX0c)8DxUx1KSD^wgAcA?aNQ%&)8eQj4nxT3OM?$=+_(;JqY3g9wKat)OyTK5gn;xu zDw8S;0(w)8uZxh_L?bFg(Y1(Fk>(OxSQ&dc6Ud>VX%r=?3;0ZvCK6x9iiHhf@E#B;s*#Ym3e{@V-in%TDbWI~kfg3e z<#AotdIT`dj4>LbA-r)=x%ixHNbo_RQ;owT!YG?J592FCrUVV8sdN4)3CIxmjypQcw0PQ`6b&%G6IyHe9Dhpasmer)! zRwGMeTj(v7@u)PRstf{XrGnBcUiqi5;*s5EG54^eF(Hr&fwT_q11{BsM3G5}D%-S6 zsOnV3yjx;>oA~;j7r>S!LMN1E^is1b1?Qu0mv!I`j)ZO78t(&nq3Jee5UfKpj!^wL zYsd{)@6o9u_<*l9NK=rjYM@CqR!VU&a}$ONHNTse-)Gn^-qr7A`HE{2Rug9(DFECI{Vh$RR~*Lw0s zwnKlr&q!j65ZJJOU2T54ZHip{Gh99w#O>Sfv$M&nolJJ6DRmXZZAqi}XYrDyTT=}m zXH_L0$8l}9|6{zZCcUw?vR4d`cD6b1ucy*_viT zpxlOB6F_HtirAXM6s9nRKO{&Y(5YnKefI;eSiNQquQ=f~DCt=Kpk(j8_QpHU3m4Br zD2d5?$pN0cfavf&Uw#8eElo`gtZ)-Jt5s=CRnmDfQaCr$FVdSXUpbL|iuEK+*r&6~-ik8YsZOjx;k z9jCwLG&T;8@V*PqXScaCupzK|-5>&Z`O6OH2iN|DTkpJ&&0B^!=-|byT{lQ?PYW9? zILGxj+=h^PyM9Zk$+slS*>#s)=#F>z?B~DC>yFxuJ^D3YyY4~WeC**Evj%TL1jqPz zz{|il{&yp{K71#$X3yd3fBy~#AAUHMtx!5a1j&jO4|C^Ff6Sk}?#)ncX7PbbV+x3k zl_Bwh!F8*d)2HM2p28HSFomayRL1NSOEf^2T2onv50EMWiN+-f-dU7!coEIvD-XVk zs$VJEbSsb4l00uPURC7M(`ag}6O0ENeW;M=M3X3mA&{DqR42$((VeK2i$mraB55LR zMVcnjw=qp()j(54#ZKk18jN!!TH(D%I!huIS(-5HGV&x=@a>8O0!UXn zUAq2elm_~;59%};#K@u!RB?#wHO2)KHV?j#1 zZPP%~l_@%eNu`?ip5PsAZOELaB;aMMe*d;el@c&iMj(SD@tV?Xp)DbE8CiFTR{Iys zowYxmjjQOC9+!E_(4dFF7Mn4nWl4Mr0bDgqmQBO?9wzz&xmHxpk!c;jn{y;upwb3i z=SaE*9>{!x7lz*Hv&b7cwk*&Rs74~endNxz2;QT#CIrDy+tZUua1J3eyvi|UiBcMm z0NceU8Wo@l9*F|mMI|{p&7m?#5is5E4*l&uBU}GXgIid+@}b9>po`i>eym*j>@$G> z4ZlN@Mfyhy5zS)j6bB&$2Of0D_7}J|a^Kn`jc)N_V#3#zlqRN$(w-B$Z#8-MenQQ) zz4<$jouAzAvBvRFFwc{3gAjDPhLO<@!y|1*$GVfF0gs&!VoI?!g(*y73V%SD7-VTR za&6&%8QW=(6b=bV0&6l7^av)M#S z4LYMN4U3oT%cuY0N~|5nIk!#Q7;t!cduCy)4l5tLmx2Bk2OqSAH=S}8@B7flK}FAv z(a}+qQhf5m7qRq^Lr4?J=Rf~>?z-b=eEd_NWn_4mfr0*LRBSCFSfo^S$@JLRJ4B3G z$Y>-L1g>tcCkF$Ch#pfyvS7h{ED9|pd+#})qA0oOz3=0?8-K?4zVmIIwX9gPk(FyV z;$7f{FF2I{`q51+m_3a*zwVVhx^{@`e|!_IW{whY%TMp(mOJi`9x~V%!{oKE$*m9& zB9J#TX3v|$RX=%%Rh^6@4_wT*|8p7ZhXvL-#>WDQ@?7wpHQ0fLEIssv3=VE)?yh^V z_R+O0T(~z!Jn#AJzRwcYtyx3=%z3D4i~|ln1m`_vSy1yzzviCVDWx`APCMu5G0Khhak;UtaC^u5mr(b6~1H0rNUR1Mo$Z=B$fAACurM1+gM5)+ahl& ze7C}NG;x7~yMQ`w}%zp)(N-uau>z?5u12d`u?wiaoIY((!jme6tSbYC5XiC=mozXQoO2{e z^!%DIm=_{i4rEyZA)xT!wi?FAAPN9HIfc_?opLLw)h>`y(y9VV2ds+k*rxJSWl0Dc zXDotbvWSbR#!zggrDmb^G}7)k-3@EVIuEkjt}__ivH?{}B%^3Eh{O?$q*M-P#z~a} zA<=3S+b+@GAfzO#{mC_tL{)dvL)GojNEKQJG8NENR4ymWV&9>yda)jCG96zN5>hIZ zj*2uP0u9wc3W*C~eZboinJB#N#Q&UTA0jBU9U%#xR0bMphJct(DjZ4+Y}m2X(=(IU z+BnF=%O9u-tw_+wiE4jRQ2BXO6Xg+}iYWSZh@=0@{=bc5?4bRVjIF*KHK8?ey$(G1 z5WKfcRyf?Q+TnJt@!NcSf^F-?kFRhjCe>n3G|4Af{$ym-Q*Xnsv3%=%XNuUGLXCCn z*75%Lzn|5sSMTglrmzF?m9Kn-uYdjPlb%CU_`}4^fqq=wrcIwdgGCE>W6pxz$#Q}6 z72`$4s*PiGDu-5*X?+>H&dOQ5XFn1_p66s)hABF{=Yt=h+o`zf%YVzRyX-;mzOKj{ z2;TADvrp#mBcIF0wX5lD-ppq&`xqC${~{i||1O3%F6S+8J(W%C*Pyh*TF*N#_z0Uf z4)WjEUd<&Je~=q*{9jTebLP&as!EKl0MJUKbqX?;B6rSAcDB8DgkbT(A$%OIbuPv; z;l~w1VC}k%>^gTkW8(#@)~x5NU;Z*b{^_mwYLLp7*jR#!C5!f8uRRxFsxB{n{^2ZL zvWS~*y^|!>bPB_cob2u7Gtj|q^VgkaV#yYk(emvilH z4>4_8A2;8>iXY#-j(nh(GrzHp+4E*|?X_34dHr$*rq4o4MV_ZD*mX~?yY?F9&zVmD zv}qjsieqW^_EVJ=MNwj$VQgd+?+n&dcoR784QC<4HWmj{*de(2=9~H0$3DjRlq&vN zi}CSsKJt-|aK{~Y?Cel}=SZX=)so-?qN<|WNC~8l9*Yybi>^)xQjn(-Zv#aTB&noZ z#fr4nc+yNV-s&aMf^Nsr=@_H}Av~t2NHUGI6+Q%tcEPB%2qg$g;FX|}E2?gXGWs`ETK0`=&4itdh+P2WqfQmdZa)T(<%$yr1XJGYMN5e)Pg)w zq{0)BgrJcEg4XDUB-3?TCh+Q$PUX#i^&ZYR=Wj@Bat9x9MHxppte^CZQ9+Oe5XQy0 ztpgL)S@`HNrldqB8gx_vCrR`iBS0`VUT-Pz))SmZDv1MFrM8ZA;Bgy$tghuyo0`;CdTwJ-t7>AVqoq7MrgXmFkW;ijKPUL0fBZMP@3@yAmHly zIz7oaKD4j_lx>qyLNyHD<4p9yGEP$2=+TBu@j3?~QMQB9Iar6#O~6C9jq?tl3{a{j zg#{NN(ea)tEL2W{Y43=i>?EF%#MXuln|NsX{WYQWSk+b}F1jVp3Z>O=x_=O`X)`?X zD3gTFR@K%73$0o8$U~FLtFU!us|QB_@t87*TW9O->V;28Ch;Wmk0Gm=RAl{{(^G8w z>l|xJu{DM9@o_G?=pqg}=perO)vxmX?|*-1hcty9hzl>gkV`JPgd>kUlIyR(erJa> zg`I?Xb7!K22Pv?|pp~Mb!B(D;@dBk4T@%``*X!rVVTw7OYymmcG6o(p2-8XP*W_@X62qGbf*NGL60g3K^?s-TU*q`NZFT z7^{1E;DKNAcb9*Tm%r?#2qD=J)*%U$odVM- zaRl1d(k&~T6ftd0)ufw@)go~oX<{nm#1mPjD!!}M@1U+SIOn3Fdll3DOs&?^HL2vB zi$tCTTr}R<`FNnekmPn7I6tB+LGCh5VK3bbtFy~i1g zp(Z4WWR8W&G=B&2MO&+wJ_$&ra4NowsxXQc(LbvyDsm4VMZ5AiJY+=??wvJ|l@OYc0b=Tegxjazgnd zC#Okb>-St~^;nW>ybBu!;h~jq_kD2t&+F;#INf?@!VR|`%zxhaXIypt-|~(BzKS2- zehqg#a?N81t!=iG1J)C$p7)~o5HgN-g~aR@=6vhTEs&SJ;btQ%Q)tkV|I2}Q}`X= z>Z`BjoO90Mlv7UOwXc0G%a9Sv$thm#=5WjA?x1U%$m$-hL)WzT{7M;DHDD#r@0q;0G_HG6i$z z&gP0M{)IVnXVWc8UjMq+5rigqUpJM}+v7j~;~Gvo<8*Gk`BrYd`DQ--hB?MS3bmj_dSG?pb;E$(Ei+b^Bwf{_VV0=pTkRE zb{Na~VFq$SG3mw~gW9Vcz}jcXPxMM{vLa2XNng_c4F|{GA=v6m~Fn z*<}~*zyE&r+;dNsE?vrn7hd=Wq0(#HfT=7&3R_AlqQa^; z=#Z;G-cWcOu%TAH7)!S-QA&|#twQ59=m6vGX!1Te$YR~35xfJG_gDcVrNjHE zcyc}xU}>7f(VK~qwiAk9A+W|qWBGcO4N*~r5NILD>rtP|2sU@S^feRKj+G1zwW*w} z2ZBk^gFedte)$4tT@77-S(XGs+ zc%(`c4G(Fs@$313N)mLc@j*}yZ2@AX$NpvuJ$*Kb1dyavhZ((=wi!p&DX}6rwD8Dk zD5}t^l4g=mS`Zi$q9>fvcxUl-?CnCL!zkz;#u-2akIe;21gsH^C9^?D43W%|I*9{T z0gMqf?_q~x001BWNklJ+s?;_M=Uw(LqOD{1>2r$3V)cm z_S$Q?;DQV2@9*b(-}@ei9(w4`4rvO%LkJ-_>7W(MKQ6i6@@OMHgMf z%$YNHc6d|x9bk`z3kd{PtbCZ@;ZL8x8$Z}GMA_=4-ELD>CXO7XD;Kb|NKv!`nI>zY-ALjf-~Ro z7hL+O%Ml2?2z7RzBM8aEzr2?fkE~|djW;lR_FT^U%QHCl10TYAM@k^gQV5>W@q&SY zf!ecb+fk-i<%*iv3c=TD6AD2fc#roILZGMBz*~!#ik?=^>eU;0)hl1kl0y#ReeZn_ z1JnDFLO~K(xYt}BcxVl`-hMYH9QR_3G2F837u@#qU)Gfuqk`LeS6dLo{+JLF7d#Rl zm083=1WBab02H;Qy$Fo9+f=m=Oyw=R%$~#S1-o+py}zI{_8^_kD37jN%bt7gg-}gy zy6GmyMn~DaX(dM?C7BY)Mv8V8sbc{xS2;SJ z4nn0Qq9W<(Lr6i=jL+*-`5l=Jwir0ZlfEB65<12%vck{qb&HbDy!wNFZtIZv~hP&o(AlggN`=Z!tfOts_5c7hVR|;AfrYxylDf?o<8*bgU-|jvNw!kzImol1r#u zKxv5xB}v{QR6}%q4+ia$9)(o<03#AQ6t+A=%zOk7c+5(<}q9ix@^PPd}#db|k9WZ752xcKh`K81Ej% zXmK=^+l|UDz=y_mC)Qfi)6+{&Zy#xzk)|25X9{NXRD8^nlU9>!pJH9C4j8tMWQJ|n zD?;?eAUy6I6N0F15B=mM*0#jcwlO^gvGurZpJIL+b=G8_Gg}$;XsD~Fh^;?h+>PL>+p)qr?zrPltn)Nw#X$>a^TXR#)0gH*AsHGOr6@`o%_i0=+U+s+Te6t{ zx%xji?~RAjNCcg-U4<3&|iI}?Ky+cZg4}k|(tVITowT8uu_F?XV-C4EbK@MJe2)8Y}6`f|h=*2I^ z_yAP&4m^(s?^(uCM;^sK`|QJ-!8TP@V9bPiEZ|+BTU2Zw9HiUnu+P9|mK^+=dgOYl z-T!UjyWjmTfAcqg!@`9N`O%Ml#Qyv5zq3P{!cN4zdGq+vm%hXucih3b=bp>umtW2& zKl#aLr4qi=tx%bc{#J#f?F6a!NCH-A`c?D~>dz$*Fdk&t!>AcUdyi^p1Obs}1T#+X zB~|6fa}@_beDqP2N)coe%oy5B($b=O`Y5cgr34z2K!2j>SWo3VsZ>aB5lT}Cg-8^M zl62dKMpm~H*3nWPBQ*j+CLBc>n6Re~0h~_g35G!-NPu2p=%|D|6y#cfnu$&nRo9T| zlyUD#iwYyaX+>fjuBk`^*vgV7(a$URKq_PUUr`uxC84e^=&d6af~qovo+edkkj@cw z9zD1qDvf*qC2_Sf3WzEx5z`1w84c=)NY(nCvcVtV2z(ez~&sU^dO zqX7uN0>l2KtsY#}Ay5Gb4?SDp|A2n`CHsZct_RwXKnUSLu>EIESl`W_y^%bZN< z$TpagG|7;7N*9nqqD7!evK{){eP$C|LTv4#h^?I!Aq8c{6R<7+Hy8_570Ifh;U`j5 zfpN1iZZ6}+5sVf`W9^*B5I>S6NlDX;{=R;C`}^sgCg^=kU{B1mJk`3m@M#lWV*3@H z&Uoanw)=vQ`B0Nwp*CK9ob|FGKBy=Ct+odLbQD?J&TmhQJ@NVgk0Z21s1qyelnC*d zxTf%jf%WUxbMeI&^PTT}hx5-rpLe|D9aF@`6eclq=1eZX{Bq7d`)n?_-~ztzg)eaN z#TWC&H@@+4&&nzMenUvO;M}wL_ErCh&T?kYoJFhIAP7w^Est&*jU87hD2swLO_?=k zK5u&KDSZCZpGFJCrC+;|_x<@%7;AZC-6%i(|GfbN~n=PBxBogb&f#pOPYp&tE^UmYaOE2XUpZEkz zmoDAeq5am-pDC;qbgMujAx}UfDV?CHqBDfoQiQrXV`)7}@B}UBT8Spa0UhJf+T-jn-uK{)K?;XedjdZd&X9}t^Y zkp@YT<}{_FU25he9V(ZT2!VDLqLJW6$EecjXaY_sgekGD=>))fkCu|s27;E5wUB-c zowe}NP>m1K*V9XPcq747XqDiqk}700RD~1rXIajK?>5dv<(q266iJ;^l_ge1 z?@gUHC}c+NOH?QkK_c@e%1-D5cMP7<#FiA|2?+`%W4XyEQf!U4Ve=Lk8w2O!G>Q5! zBc10n+xvdb>x)KgF8zWeTr={!@I!V_TMefQ-%-}w&LUw=L4o_j8T|M!2- zr#|&5jy&?nogLZ~ena@+@y;=OdLIKb=TnvyFM8223~pG%`pxV32?eHdsE2bz~XQRhg-4BRqBZB$Udzn6eK6n58{&-#oy{#sTmMj4wIPl;@xpmpk z*lm}E%$_@oT^H<$OfqK7nu#$LGiUU($L@Rbo(n!ew=<3ift4#B!H1{-GlgNS-DUH} zbrhB7%+p>$t2LcBzxAB$d{L(G^ss8xD$YOue181nA9L}=7xR|4yd{#DQ<%aN;Mil2 z<>fDbIage91;-q7496XJ9G6^j$+IF=)d@jWT6_`>;~OEM6Nwj4I>@ERmL7$quobNY zWRf9*rQ_=Ae@Y=lO<*;0R8`?fs9cvK8c(56B&H(GQ>>GuxuiGM*s_aG8+cZ2cWly+Dcjt$d?l?uP2xHTDd_qJy^Uyi58#DH zdWVpb(&zLv1l`UU&L=2UfD%;J)clMBS5SEku0z%6L!`YpDM-B`*}-kfGmh9AnAXSe z&?vy9AsTE?9!V9;f!=l(lxBAdvp3yxG2`WPF?P;&#}h)3=M5UoCaq=K^(%#?3eUh*Qt_E2hnu zPotqJi-JcUxC?JRD^@&;@Q%SP4V*Q!J8iN&$5e)&-*E$-;WmS#1$Ljsti1moHuv^$ z%AdWKZ+`1Pc=wx*V0g5RvxcJZocCu(^Ra)qfuhsq)0cdJ{(+fX{OQj!ZPqTl`~`>d znNNR&|7tc_uBxD~Axmqol&)2^Lb7@ZVQ|kEMqk#*!ubaQ+8B&K|oj;GL(R z#^wzhIqj@>@$Iku3(iroi(dhqmvX% zG|!z>PytG5mff?QNQX_N9oA~BNpDk8ch3EG{+xkO3#4OJM2HHm5CSvj&gG7~@4*L+ zHC^^zxG(EgujR%cU(foD>)B(s-AT1%VA?!}HxF|69rxm0!Cuc<#9@alp{LQq>F+$3 zqE?uD0&7>V!~{=S8M@Nk8E0_C6<5&H)3dX~n!@h^wAP$?=9!#)^2vPcV;|$7gAU@1GtS^W?|IMf^*y9Q zpqWSl4yzNK4A_n(Z)nQW;RJ+`lh7bf#%St;?pGXjiZ!@r)z3=FOflNo>jOJhryZFIu!e8wZy$W5!G} zsmOr-9Y#p)1hVQWg8lW@J@NVww(-yskszAjw?Z9{2qDH5wzrxWOe_xD6I;KEta=g^ z)??ESw}vgY@zAQPHwI$Gr#fCS8S{i%Ya+*TirD%?z=YZ+%QC+4jc-h;ZKm+FAf@Ew zlTYULuYWz4U3M8q9B~Avo_Z=5UU=b@>hJdf6N4Th@PfmaGGo>Z-tdxr=u?JHX?Wx7 zjzxRRTR(C&i*?j;d+!7R2kpBX zV#_MdeCr#y>>t0$X~!K%S+u$Or^{KhxuDhRWqiDi5CW|w|MUH8_{j}F-MepOw zU;G?@@mGJ%zh3!8Dq~18HJO$n>OmhNqRPq(&{A>O^IyoT{^VsGfBdVNGkX?7>e!JD z5M5-wHa+-Y;+LYEg9T6h-yt^<*i@kv{PTppPh0xS(eAxpP2=|pYgEPa>W%_aPh?# z^NLrzg1hg&`&ps3nZoZLy}i9$a>*r}e){R0fByL_TD0i*TJ>k7B$FDi0=aj1FK9G1 zHb8Gv)hUG*7(>XEQbZ49DFd1q7r@NWg@Ig!FQ9$}Uq@`Ta5b zln_ww1+KyGd0ww1JG0iTSu=ajtXa=`KF_C~1Sk0>VOKY1)99w!=gWvls zY0HlERWyZ2(pRgZd`M*pzZ9U2ASg(ZT8b=%_(3r@>aXSBOW=73FT|JxBYo1ij`Biu zEy2V+`F(0LJTJh+H9Qd_Ri5cNlwhp_r;$Mk=QKEhPA#4cQPRVt-5?aG0w^D04N)LT zvJ}sx7#Sgz!HY_7>%F_hJ#9vh&NEhx965T3>^@J~DTP2vfslfcBS)i@*C>;llnw4D z{*E&F24&*!D3fncCjLg5$Wv1P)v`^?r5t(=f2&MxRt5} Q-xuXUeTokU9q1>t8l;=cneG0x;yH)aU*3O0gY^g6Y#eJC z|2$Zmg}y&jx<$I`Q5Ej#VGAM4kw zW6j$2OxS89UF+BK%ECqLxWi0lop~~6o^cW;O$nm{k3YMRXI|L|p5%x__Ty`J{DE)% zd;v3eKag4Hp2_83`5MQ4=1h!^F`4Gq_y3FuQ>HWbx^J-cv}rv5?9FZrj z66e1~*H4N$gL4*734AH|*rRsb<;AwODKEcgr*;!#RsF8P;l?GgzyK z5LgYe>^0-&&~d*}4agTA^N>W#q;aG9<5SOKjKwPy7(IFv8d$!31-IYwAH2M9K49q5C{O6@C^e0f0c}Sp&JX*>jL8M4*u0oRe+7A($ zEHk93&a?S7BA0yW;Y>#0Kv_#>3~}bL5(@NUY=(1=0yQ-G{z;ZAl0p)kR4C=hT!EY} z11mjJ8{$bQxOGTB#KQmrtrXJB!(CG+=#34D@QHjyuzE3GZ3SJ04ti2WR~<|yFs?#Y zO~BN^DGEg&>l`MjA#o@v(Tyo|i{DE|0l&~enp6;IT-t}{<@O9VGZ^Plr;RX>NafMg z(wQsHb&ZXEb(X*UGA};2fX5$sng{QGf*;)W1HL)uPHw#Rm;B+8ClM|q5E^GC_0(dt zM#~~D?Iq0w)!P4KiY=#ewbtmd<8n#-7Nw&4zf)LkzKeL>GUpsCmcPoQ5C4uEubac# zHLC~eg@uTgmJasZ`ykGn{Y3_{9=^_j1|6(kbDYh>5(gDqn}!;)nF?#O&#$Z48X9Jp z_b^|GA0*TIiMXMJml&$(qF>tSh8*LKzvp4Rv#@^sdM>-{GVZ$TE-tv>0`9!?&S7Kt zVZ7xSGiD4o-EaX#NX)`pgTskGq+6001BW zNklHmwrd0zyEZ**o{U8r9y) zXHPkmU;plpJoCgOASFWNrt%Iu;I}*Uy1B+iDf19UA#>y0{%}Gm`@oT!j2}0ik)y{_uhdw%Y8f4E z?F2GqyX|Lk!Nr%ca?KjLH>_pExG_Yf4otNUQgHSer?LB9yK~p~?%-cf|1hZyIQxtX z8BpO5kMaLwJoC&mTzKJytXQ#vYp%J5!w*0FAKj&4{1alg-FD-_2Os3#d++6}v(94L zv}s&>?X~Zi%$h=#C`yfRF_{Pn0*wefjFdPRkft%hIpQiPFDJX|u^Ldd_G&>SEKN-X zl+(nCLCM^}y}hMKwOS)kKHx}g)9NIQxjH3mpCk7Q1NsYxSpGaEPi4fl; ztY1^Z!=Moe>oCHR2#IHMf~+nCGSl>Gi9jMlflC~j6R4WO0v?u1>IghVVjMUNLJ$iN zXC2mBa?Z}-IY%lKnKO`CoG(a(%0tuRl;VgMlv4R@*2I*JWshB^^ZWb9vo!PQ?Y5Ln z4~LGA`RVeI-i`3``j`pRn-M^7>cB##HJQ$+WGTuR>P}Mh9I*^gF2!08Ur4evMS7Cd z>D+5A2#7O{O)ZJvk}Jt{ijfkX6SHSkY%!JksDzXEsbxw@>Azt9&Y>h0flBEG* z7?4ISUSk@Dx)Ec~?hb4)jy(__X_t0BiPfynd;?$AU)}VVURMMDgT@aEH z$rApEG00G%aYUXECdQR4txY~7wkqI9MMAn+*R`I`k&{4V2wYB}T8$GC9tM-v-srY_ zOR&WeTVuzJ23}&!nDGet+P9WBLuj#ul2(76(8{umuirSA`+j~8%a*-@&IYpyOq{$8 z`|fu*ZS5l{mYO*Jv;Wp8aafxmoF+HV*p&2Pr~<3OTMg~SrsuV3sNkS^e1F}|Kfji^ zdZW(+gq9eHB!q?>vp>_4bE4lxYk>S3RBiQd%l$rvt~L)7Tkm|NY03>Z+`ybUb2#?c zV|n3)7wGKld{b?>q9$B z7!`TXVMp-v;}7$|Zy(~gW8TkKFPp{etF9$ZVv=>M5l#*)8#(8&sphnkPULI{`B$r{Kbizrb~0{}usNGGoZI9zs5tHq2}L zG@Vm?+|k;F+cdWAOsvMXolK0zMq@jTZKHA0*lKLswrzjY^PO|CFJ^voGqeA*vEH?w zH%Sx0q;AQ&9_w3ys;;jc{6sGn2Z3ak-$8&vOG}#cU;hB2-vz{1e0dIGIiGtHZ=-EU zzw?d2+r8V}gqaO`j4xVF<)h!aB&axCt4|qtm`sg%h*=ki(V#?bM2c03%I}{%Wc}ZxlF*8w1RU5fCLC!hR4XCSh@I$7z$No4kckB^kk2>q zliLw5h!aVp%fa{)+8Qivn+0qOnE_KeDF8ilf1gLG#9{6)_?g#5F%vbX%1WBfLWf#4 zZls3_rbK9jwpbT53~8q<0u%|g{3!9A$zrpGo4-Vm)C7a2b54lBe4ETKa_%MO`@Hz3 zO_uc4`IIcEaIas*`RgR$XrRHBovaSAw2U*inv{5)wTCMcIj}Ljl-5#Ia$l(yGNb@i z`>jAeSIVHgw|B6RnvXU|!s$$ygl?w22#%31{=SmD0*_tAusXn!oPtHwm=lbeY-L3l zOpo*jiq!%d=BRmR(!muuY)9WMS$cYg`88{*{nJb=SJ(tl$D7PqUG$VYH?&$;bhv6; z;ye{dNv_@vr*)MCNI>;y)yM{qBw7q(!x_1yYG_1tt>{6%a#5IQ;xx1xOP&5Ao7Q?S z=(egYr-p#p?j1O1x?iQ-Xnaljare}__P)8f+hUf3Pj%0mbB$KS>^(4H-MOm^3OnP! zPuKZZXmHK}Pet3$(gyZ0Q2`udHrHA)11wv>e1o-yEtc@F zz?%IO+2}TI{JPK12%?8MR|wksD$e&Ff~yq=5zvw9$DP4nk*&<#e>gi((bWW09@zu= z^h{1GntWtdI?ifGmq17Ujrhjk8WTfMpQ1#-aYC2z#{*5%P_oSXTYi>SdlPIUPJA=`DX4>8J8)_ z0sS{^Rjsi}(mqBQ8%*}$?XT6&i6{GAdp}D0dCRdSB?6UG>dx0*M{Aa!v=^`A@4T;v zLHIs>xx81Sn~GKHEp87GZ?9||SG|{;!{0jJ2||cmkUux&nx@tkCK5}PHJ@f=`lQlB z;-O<4WDejU)oP4r9sqyUgUd!;A#n0NJ3HO&MLpgYw)_!)ODJ(_DvFW3!VtVG6#%dT)EWdEfUIY(FTAv%LAO)H|eo z2m1WIXodY)QWr~dAW(6)Ul>&C6TKeYi1ND5Z=wBN&>(lk`N~!-QBNgMf)j| zD>Zt3p#Fw%vWV-mcgOEnp$@XStU59-RB8=6PV$M>sO$x~`xcTP0?55yK$IrycT)Ik_{o3`yat3oB53M`oytdlPN09v(S`i z`rQerDW;)agK+5gD#};r8X|uXU?n2E7z5EWyQRfSAhDDLe}nlqfMwxC+6O|!#E(d# z$sxZ)(%|T<1R|@_sEU{p2%FajXO54^&C`RGkEwQ2h(UaXgdqjR?i;`+4Qsei_5iV9 z;dEuWswgBzUAYwygiXrb1JSA)cWBy!4 zbx$Ldcj%=k=5Jp=N8`(r`_&eC+7YWYm>SHpb?0D@)8+<$Cib zGJ6ZOpep3t3*F@cjjz=d1L@ef;(_9itfaPjA+jFl-B9S7zk;hXoQ4r9ZgGEA$PHC> z6F?@Zz@Jg}>GSwT^sU^zV&C=R9trm%bm)1rv36ZG1Y(7DdqaYo{VKqGXS}OA9{s+- z<#tvx`1E!tpb!sOa~P$^2gM0&EnYh=9mkjk{}$RH?&e?trTK5uChb5UbU1HVtbM&` zbG#X*bo_WeM8X^U)a(8#Tzk2}bJKz3lUn@ohLxS&6iTMR9W`3{H+0lgZ}=%J!QG{s zG~07n#EdZ@UN*atfMfH)nb7TX`Y9U_b&CJFjP^W1-}K$+^~cfqvY?|(oJmz>enW#O zHLRQcy@$9}jQ8V;KhgW$A%68|hen0F#k65%^O09z95Fu`K$M22BIvW}4$Eq!6ZC7S1h1>a-K2mkh30mbdzC;hqb1c}5c%AT7D z%7o0Rv*v2<(v#XoB#!L~mrCa&n^cT2+58nNCJ=&p$)=2gPD$NtHvlLdoOAHtE0B`C!5u<~J@X@NX!%h0Yp*8K=O9Qe|F@?c7p6FX_LM77 zO`~JK;4KgaEjaAM;BDR9#%BMYN9b-=;V@o?;UD~I|7Mi&@M$+@a|ix_W5KYXO0t}o zyo+oAE0#Ox@DJ;&zMY%jr8cj?V`zBZmoj=`%L3S`6*7C=q&-nJYX}2AF<2yedY_|j zTyYqS%3cbnL4=yUWHt1P0K`9{AQNTrkv6>P>oRL+? z?)vaW*KZu9R#bU_0qhw-Z;aQQpip}CZX%*jiyfb|+tOSfFOn6Vb8)CKSt9ZgQW(@P zSYe>iwI~7gFC9MvCo&SvN=(NIk^&Kpuq)E?${iH_@-OfVqsXLREV^kj8=NeVI}{u( z;|Q^pC5TI(NIF1QEXAhk1m(ahC7 z?Zpvkz$Gg+s6|)#(&{%K5w;t+61;!rJ++NqUbHqX?bsrz+>&G{kv6AAy1(m$kN|C( z&d;k#W{(1NGnQg3r0QX7B55E7it&o0;YB&43|I?NSjYofOksV}4jRF-Y#{2><+WD* z*r>U!prADAa~Ciak2QPCXw}H9vsxQKw_K^P1`?oo{F1>eg2pB?Y#2HWLm62Bs!txu zuz0$OWVfsF1c;q>|W|Aja(7gWgY09U! z321F3%a&sPG`Mcl86dyZzb)Vp=h`d|%c{j$!_$!R9%Uo@{nW`}t*(eULP`Ca-{1l<%z}bB0!$pXwE6U;bIanJX>eGDE9}2iRbh(m z2+`-0#J~L&q?|U>Ux=Aue_rP4Fdzk9{!@TK5;wc8Cg)gVwK^=`Q{;6 z4&SdF-^*1&Ld@zrj?eK>B=2-vuX7;(YgGzLQbroHqk84v7ubvEZi2s`Ln0cT9t5u! zO^h)g9|qxtp`I6S{Ei1+VQh?(hc$;OS0N#vU5V5QnjMA^_J5dGYHLMIsj=DtoExpRgA{sXLjR?v-5RArx1N^ zvQD`k=9V*`u8|x^G;!JfyJl9_CYrDFmzI9)9}DnJ z+?dE{w7i+PtocB)G_Hn4bl9=Uq*MqFGL6&Qh#JtM)l$r`ZmS~+i2Su@^7Yzr=l5Rw zdiQW|*RQ&19=Ut+`9k>=J@5^Qx9j;ZM?ppg&K2YZvx`qMuvSWCHi30rvmfjdKDb}h zn_O#g+`I`I1B@Bv-1Tzpj^D z?QkzF+!+zAWR%8g3dkRjGY-5Edah91l&m%7(~iLzeKWy38bxRR5mV1JVU?$Lo?li} zI`3I6oo^K``E+-L+u9a`*(seTytDKrS-3O`C}flsB2R!QhCLVOBPhWVN!74}m2N?g zlZh=>q^>`MUBOeb0Ai`#TOXAw-orO=cHg-<)xS77)sse`E&q{1k%ud>%WVg z7vHJHw&KmSl|qrEr%uYa7R5@tAZ7{%jEByGo3$<}V(5F=)ygU}^)0+Wlg6;tB&ILM z-LvPbAi>H+r0mS&3)OUgYlc5ONi>P0V|xPiG3hpjMM;eHAS+>V+kG%OOJ#cU`SK@n z+#{B>m+NXKa-$XWw20b{U%41Yc#~b?Go@En-aENOua%!w{VDtSS!+3a^R~QmbfPu6 z8^b@w1`0u7jHVzYdin^K&h>4)cBFvzQaocGDEvDmM9!o9Z_XDV9|)k*&W7nb0gnrv zqwQZba1gM-Tp#1kHdk+%^=cBYpI@| z^J^}vHkqCmEncVEn=6Ke$GzACsZ2)A_Y2w}7mQi+QC>vzaZ$$8O-kq3>*nW&uhZhk zFtHtUG|x#p{zsVdl6^+S^Q@!qK|9ptXw2p7x5DZ^1InyXP$WDAUU-7{)p}tLtQGSO zS0Ge_>yv5WqMc(@yl8YfY@G8|7P6@KK{LV}2eRa2#`nS_j4I(9C2D>WpYtv@%*AB{t0lqT3uN+_7pro>5_G4*C=b z`*dINNBA%Kot9)yeM6sb4_T}h=s;TyYvz+7wl?p>hNmr|_np$edWby#v+=)6-9KB? zPZY@8cCBet$xJFgIXew4II(KgKLhz^+H|ni?8xEbhGAeK_R#=&rIE=)Pa4vSVsv37 z5_I+(7<+818ewFburG!NrB>f4^a4X=JGx@cf1!d=#tkCU! zM~X=(k~jvk8pKVh07cTIF5HkWFJh03^s*oy6JmC9#+VmpnbULs;fvpBmTzx^ zvRMEgpBT!TrIj-i;RIT1Jea+F>}a$dQDZ0Km+Y>G+kPE&h<4=bb(N&g#a(+~m?K5FG|1C%3~ZGhUc!s`0BjsizVm zl>yfbWg&)B48`X@?ri~+UbHtrc|+ZwAnixt*-nv|nwtrrK`(ij7esd;H_+;bjj_~= z0;2EXU*ap{web;h)ZR(g{^zlG~ z!(t!~gHo1{UbTevJoEleCJ~+AQWzCOGTZ6;d@h9mbiBlb?!bcQsN@+IP5ghI2Ggz3+tR6 zny^jRoHukgn`oTauFksPkioCtcssdlf)4kOlL)%Se=lOWzb)E^rptC6P3M0uh+z*1 ze6dJ(xE<%X?Pv6fL-M)$HI~6)8^M7_F!24Q1|;9weZD_Bg2uo9$Uj-+U?L0j?%7Su z#R?DZv*QL>IL>U-z_1^LUQ6;LVKe3A$1#pPw=HJz&rgPn&yOa}&Lgq()d42=6UmPI zDBJ60wCFsONiwdBl1KZY4^L$AbGnR2$I7-7IB0mYEN2=<{%Z;Tml`AYdq%kB!>(W0 zTt7(-zI48=E6>d&(v{VDJxf0b?7hD&E_M!_l`)uoM95qRO62Mo&nzg1wds*ZD@Qi8 zNT?ZkjVL$$65hdr^&_RiY<{l%+({tfN_RL?q6sd)sEp;xvE6i`oq5C)Nfm+)b9`Th zCZ|{GoA5jvnNe3qDcFLFKZu|7-E^jGJ8#8P_dbru{Csxgd|rcl-ac=NH^uS4+|LaG z3p95#B*EPdi7F4-BWZjuQ0x2*5n)%^)<_Y~KsS23IVB1EUIdQ+#NYp2=s_N>?u;YypEBHoe$W*sDFlrX^%41Ms`*HlMO0*-20lALG0|67zy|JtlR2bi0 zKynbewB$=X{3gIn2}MC#7y?zq5JDIGV1&L)Q-%a~3NsV-JFalto_ECnr+^?OPJdoZ z4u$!C0**fsSQy19x?F*1Hi@$$I!2~mFK&o5dn}0*P{uWLdSk)A%+=`c7qelx{fdE< zuVE~1!aFiS6E7u0Uye~xF>)>O6m|VE;B1w$9*wSMABZA5^(vedT4?|YZT4ga)b(l7Z!1bu1IVC?l>~qBV6)?vnnl)fPjiT zHY>}VmdQA>0n&uk+XKEJ(9{^)>GNcX(1|*2ek^H!4pD~S!hopw!Mi)g41<=5U ziUv1AZZiX6IZvTUa~!aDWl@5JX})Fml#>2wmzA(r52%KCL)EoF2U2?}Y?TA*_|*pc z_}T-53@ecrF@U?(3_^cU2e^SY$Rmo-0H7r^9&tj{e@suP+Vhr4#W^04y&I4IB-;H& zIl+H#%QZe|CIuc@H{T~XIAD+xM~v={DpEVnC(deDKd9z=3?#CL3bY(LOIZc2!#<{3zsk)N_04o`UO4xuiA;DW zB#rrWSfN?WTUE`P+J}n#L9E}N4sblvq0 z$r`215p*8=gbX2Y!Gc}kEjGDvm21kGLt zfY}=!>2}7;nB@$16LBIgH-w8#@^-^9GVE_w@}_FrcBEAxx+7gz5gnLydS~0N-*EkG z|A~n9$eVd9&yRRcw?0op^f?5jahH<9_0pHnd=N1Ev`AZ7yik`+)fFJ@MeNKLhd9e+|jmOCg)r zUeQ-zfo2i!%q=0ebyL>)Mff`Vn%aUr`Ih0C=9?yc$Tf#j)nXctD+7pnvfqcMVB8%5 z(YxW>>n1@84F&>__rp+TcBOROkvFdXqOyge>?}rVdDj<^ zTuXKZ@S!NZpZ^j%qD1I$7kM%8OxR5iQxNj{W$%G ze#l^(3FYU1rdEK$U;}^rVLT1-rJTyy;m5M!m?N5csLNGrju+e0@w#}82`(O+g{m+-X(l?kZ#jZz2FqSU3`6%+O zT8wtsUu%1hn9&9!yOIZ)^8iP>b>JC&PLKWA;C$X}<&h=xCm;jZRPl5>hKh1rYeF+I zU@kyd#y^1as1#tmG!-?0`p3Jfwo*ObscNtY$NP_DT%5`pZhDUzd!>$4?euhUieedb zpx<-RNO2ht-yLq*`)d^*)w#se*L%Xx6vOoLej1_v%?e&XVo(fzuy0N5wTi7gn zqLV&qdH}*4D##$BQYtA2CtVvX!yAc?9v_%plJ*DAjuWU&5gA@mB;RvzU2=e#9&V)A zk7=i%j*npkne=i=uqJO&PbG@18N||1r6^VzZsmKGegy6rRP{?P? zBV&RV!!@gz^CjQSa|=t$m9uWDz^z|IT+hxi@8Wx^0yPcK>~2T?M4j6$qDrhKOSnDM z_sTl9f!#N9Nm>j7XMWk1%JEj!A4QBIQRfIrv-*3Ygj$?;8V_tEHMwO)@BC_2GS+cs zE-Pc`8;Bkz`+>0rrhlZtp!D z(|4g1|9aywuVAl5&zEQy-z?h^vF);*vDo`y7TZeWX-5X%ea>LbdsmEAZX;_jTU*do zFA0SH4(b5M%qel0vhhuwrJsF8}B_njGH z2S_zoa$fxLuLPOKZnGlLstwx4GQ`cyDF3a5|789EIEJmFjGu-RnOy&3Hm?HS40AKO zV2tXG18MnOBZ5zf-(pxHg~RGl1@1u9q9R2_28B0D2%q#==$P>Dl3xeZQ)Pc4Qzf8c zlIaxU{fepKr@0yegj!;dkZ0e8jiBUK-IV6%m~|xirKH$D+vD80=Qpk=C$$o(Hk2ik55=N zkr84^6hFwpco^jWUBw zgXEOG&c5tUo1MxT&!2BW%c1n(LG8}p4-7pN&wW!XSQJM0pb{XCMDIZUJ>sSzTNGAK z!Gfczq;EYJg)SGF#*MZwwNS1j<2ecIlKFdR<|k$+kep3MBa+w>wOo5Tq8izZ8sn7e z1Xhc-btma>qT11ErP8I0ebUcA_I@|7l7IY`B~=4CmHG-)rT3BdF{q$0Pr+af#vt2p zGZv(T!_dg{?6V?iE(57qS@QCulx$26GToWjI$@RK8o!g3b(c7#jp6Q0o1}XO5kYH3 z?4*h?B*7X` zlH0K}#p!P7DoNSRvH*C0OEF9^JD3&!Dy#n<{$d2KS^4-d^-rG^Zx@7{psU`4mT^16W|v2Wc(pFl7* zvkYW=D651_Qm@SU#4Vq+I)NwOVqfMzYMZxZ-kfGK1QlA#msUutt(TciC$q=@vDQ@8 zfAkj%ydVEFtG>M%Io&#NP0k4>gB{i3b<8^0SP;IpLvaTx@{uVxFKg2TyT3xqdV zal{^>a(Lget5ufGuHfICXLRBR3huu!3^|w}X%X9v0J3n1}e)nY3OmYyq zvc>w*jkqdr`VmoewHEL^=4nr2miZvnVgD|N4fb*SaOtp(L#Z59=H%3PTL@~dl#=5e zXjwSHzWQ^rbw5I*p*3RNB~{o{22EZAY;tf1I?-_Oyr|al2Ns;JZd}Ogw#Lnlqt{LB z`EcgJa#Fm-?y8%^hL$|nz6v7$6Q9?Uh{Uev*D^JR!AD-T3Jv+**Q_`+itDi)LX(li z(sGU3&>yZ#U;Xu$Z!i+`p!ebU@2`!xKI$m#AIxHmn%W zsM3g&ke0p*jD8KFFRR&$5C>94&TCl3k*dp7RB9(C4iW1YXSo=@2S=%tsq$_XYtR78 zRF*w+yfqf*`**~A4epNYkIE-N-t{guBZ=$W7{bXq1>T7j=Q5?*u{lr|x_N~Qla=V# znOXVvJFye5+gUkuIrL@2hv9oHdcJolBStACs|*d* z`OUXeB!)XesF46FK_R86hL+DNtQYf&IPTsAu@fa0VKd2n6!lYdI0#rJrpNvpKnJo4 zP_7hNv4WgRZ!11>A{rA^4^)$Vr4r#~AM^W}GcZ6QU7O!$RNX1~QTDBTNH@syF&WR(G}J>C#5g9)Ivbv1 z1PY`-M|gsKsTEZ*L6e_B&UosEmcg>ZHB{Ifrm&>ec`A3uY{X+Uf!0O93d4p#2U^nF zdR95Wtkv;3Ubp!IS_$Hd2aD4I6&5`icVoV@N*Hjt7gM?(o!kOUl@TD5OAJacu`rj0zUlOy#QmBe$RzoYq&#{rG zDPBj&5^5V;#*{I-}w=S~+V>G7KZwYc&eTvnYw{k&{g_*pDFTJR_>NtFv;C>ciz zO{JR7il@OqB`OR>4O^lw^moxtNmL9O1-VprM4bsJ#!W&3bDSp2XS3L_@EF6wk_NNC zad~M5uY2I$ZaTq#de*+k?Rk*d{#ciN_*`F4tooi^cI4iNi+jT#7T4Dpc<1G`^a~Sl z23Lo&OF1^RHFyK%wu|86TiPG3duYyHEo%ukLy}zM= z@UIcOZN%^6FU#I~x;8nU4^p7Aook2tfa&rld5TWYnGF=Oc2}ZBoktk`l1da??Af0L z#T^@)ii(QMl}&v^E9JW%c0XrY!;oq|OP5LpPKt}zYjDFKfA>M&&*ofhyw-Q@x~^k( zX}r4_%G}v(77yX-OPw{KBmU9nyh6ZJ?(DiCtJDYiiD7HLo;NC>EIeA~B*l6B94gwy zC2efPr%8fU2l+ribRh-K_q$n8$D{7p02AoXQzrWz(Vs2*nAyG`?*Aw+|AalzSRo18 z`TQc>MeF+t2i8CMuoR6XmrSR_oE-A;MmKZavU{<~2;b$@ptC^Ve&q*h z0TC2FjtyKk4;8uDtp%z3`(P5xPpPg?;1p`dGuJg*?wlXqhIGA7hRD*so6s)M=|!@_ zxC;z2v|S7s#Rv!)JLq`ci`^x%sJ*=#AaXe=$iMe+!CMiqZCwf!%z1EtiphbXO2zG( ze2wnB*s{A z$gG8-SPdLvC!J1PCYX-9Zb%h0nXMoy@|qs8ysGa7=e74_^M=ph(acoZ{0)<`^ouTfx&CcS?OhggdiW~Iy|q`zCz zL3D;)UqtUYxC3B1W<^q|#Wje(SuqRKq7(_E7lO{b)-3Whg48DzhhlqcVXV>S{lwP} za@bt>`;f*1hCQ$iV}jq|B@(GqK!obHqa&(aNkNP&W;su;A|1S+mM39@Q!52K6+p0~WsKmud!`f@^4#%aN6X$)?R|FdxT@^F7J?&lx8+bk(E> z3rDlEJ!Pc1d+4ER_iA(4ig*2!yo#egZ-@;?Z%_6$p=fG1(xw7F$}7Iwbb_j08x5Tf zEw$5?i;KkszklI!A~PN3+U`dMCKBkgp?~XH-^8R6(5L*?Lc>&TpP=hu^Ccs1a-CCh ze4+ERd-T0vPVgS%TMkmA)Ph;*x&BUB3i_#X>ixdieaHmd3CmOlvi2{j;g_M{p54#q zq1s3YI83|!B=wu?7~f1RJumxEef%CMM3C!)EQap^+jZR;3sfV(6nN@Jdb)7!9A#g% zt}6_A=m=`SBq!GplAzyhX##KfE-W2%=n=RNYqjAK6>PAZDqu^P^RdHgj2vqMnIHyF z#FCCNsw<+=`%p(I+`WC@NW-OWP+@T1IuC92v@Q~3ze&)!v*S3in-4|cw~MjtQvAc+ z>RCIrSWhrDv`}WVKyj?*Gnt?1s;D;y zc^sg~(4qaCABV25|H3vIHoG;rErVv@>5B$^wNx0=c_S_8_lMZm3X=G^LT)>MG^m$L zYkM4Qeth6bZ9bR(YquJ6d4I>&mQyS2NOF^|u1w8z@3o^WE>p5bBXSgW z|DFvm^C?-rb0Blf0)udKU=pqc>JET_$uUce>f> zy5#g#VF^z%IU%I=QVM1^W{KH6@F*W??G6}$p*R_~IJ)>kjJ06QT4^jP5f+OM903$? zBY2+4m2hdT{zbMchu`EyT4YKLf7%9)-Vgi&R!*GDH?J_2%%?Pi6_eSEQ3f9svnjCI zql-|YSQ}Vpm)3gb{*sOh8pKLT)8Xr=Bljmy#c5>47od{U$tM##iyyo;D~ZyOlgfq# z_L0Ue08ziXlj=Yr@}4_7G57@C(=JSRY|A?xOvgH!TRVm2VS8caD&u-dktd;pK~aM< z;3i5WJvS-18D5T< zS7qqJz5>>}_H`H(8nlk{v!F`qJ$#otz$^Uck)c))U;l>S(Nbv{ow)z-er5dyLtk$4 zqNe>A<4WxMs4Lw{^0uo~s`5{v0X?+fkL#|Rib>5RUR(Ac^7K`hf>!`&X{!bi4IDt& zSjUT&!=J|n?TjRW`fV+q`n8w0XO4`dLBH5xTDlJVl;sT$L4g=|GcSM3MUQBKce+5o z(%DAC{Sgy%og4!M_vA{;L(t!|%U9Q%eucL`u%hW;2W0hZ68J#uF3}w8eDWe}-o-)> ziP;S$Lo#_^Nutxf<(1jg0jX){Lz~&2s5az8>y8YX=y_4OWyQf|=<5Vo8aB|dU-|ZF zq@{EwyB`Tgl5n}hp7;FQYAuH|u*sI(SHtS(nOjFN4)pBE+b%l39cHq{z)kRl5EE@- z@y=v35Vjs?G)L!6De52Z^vkY#P}tVnZuP6{ZiBwr{sIIXHp`!+Ux=Kcn;W0dtCP#g zWJoVm{iTje9;X&w+sz8M4QTvht{vV8W?9dwyo-lCDSCa=#Xi|QK8;@tAhL_UXbR*2 z1#BPVv=(5iVT5TwS%ZnC>s_~_j?LR`z6aBNZQJP??&K^`w@za9t)xzY@jmKV%_d8X zSE6PCDeRm3XRI2pd5_u>VeH2(njGN4brjr0!JLtW&%5f!+mo`_@hw!X@vydzYj4%7 zc(vH)=EkMlP8cQUPAJ(wpt~DrS86l|%_zKq3|Y#kJ!l4RS|+`tLD_&r%{o(i(1h0w z5_-P%zSjPMu|X}cW6~m)l&s|q@(N!FK)U418rlqIYN2V-2l!)=$VN7biTdz1%vc5# z1djzFYe^TPYMG-}*rA1msl}_RqhV#Bz>Baq0>_-UTk_-lW9)E|X#__}qw`DDWag~H zs&SQ1%%Mi+lK0|#B5gOjCJ(=Z($eCt2zb8*h8 zYq!&J##fmwn-zZUfrG{6YH8W|W0Z~VN!vKJKR{0M-ZG!kVu;6JE1*Xizn*)6*6&kS zULPKLyy56sao}{dgLe`uoAuF247}c(s>$0j-zdnUF`}47?lA>#S>%={6M}I@ zTrFTnRVqY^AaJGpicC$i;H81W=pFNZ25ZeyybV|O1>xT*3^WpA;=$sP<6MQf?g}t* z(2+&kwJ^o#XYOetf&LBXu*nbcxv7tmvS4%T-`UGiY}|0!9BlJUrI5wkFe5RIQJplp z*|E$c2Dgi-xn<&7C}e>mg)js3@g__?!@q`yUKxN#+{MHvAvDa+AEGc3icwUna*3GT z3q#L@_F&u(S9m{mYRTteI+C`i9Q^x>KCfaaEg+-wpL~aB zPs%zd{a!EI5wK;gD|A}oXFI%@zO;F}O$?lS>JdqrFZ-WVG#U5>mbn%-wLn0j>e|{~ zc$*{$x?%s#7s`TrIbr_^NcSLmDI@J*sUd%XG^cm*E3dU(^#|ANlrGa7nwM}u090CE zdJ?WJCwY>~{_gf0cg%#5Nl6{CGhGLIzdz=ez0DTFEZ3Nw0T`38)ltDW5h93>B zQMRzg5mzY9pqovl+aGg0WN}zSFJi;ix4m&%(+^HuI|OPI_nP$WT?Sdq5#;nS*)k??&Pm{ANhI&EQ% z3TDq&0=M@h^`qmHygDPkUCIG3VR@mf>tn9pM6i20p=Vgh z!}C1ehD>XB4|rpviKXaUh((t1wF(NPM(XW*Vdk(^7Q}R{`b=RkD2eSdYKj8#7Y&`F zFJuj^qNo6^Q$bTCGcey5e&5bcEg%nok^Sgvy-&mst2Gf;B^_Ov>gfeQlFfuN5$I?s+ zh{u{~t7bORsK~NFgHT`$YkufxvMbO(8M9fsRn9Tkdt!>bh8>a~(&me2^L5Yi%+Y`s zR5DRv4rANm1WPkHA{NAr!bIH<^+?hsCoWT{l%&($Qat}j))*f=@Fo3rFRJ^5U`z1f ze_jAK)*%@E0W#j83<^M_&pF_)Nazl{9<-s=bx;?!2nD$2AI-;%9OdJSE}9f_^yd@R z&EniGgB|o!?ofajRhZq}K=^>BH0BeyePBZ}ETRRY7->UMWJEq)B!VlZJcs@7o6;VWJ!b>V_;$q?gx$eWgwYe&bav?A*tu*?I}IflwC zBSbcynXIS5*5J8i_!0?ab)8I1-v9*PvktDbh zQKfLLbjqN?BxO_uw>=m-raKDpX92_j&PUe0%zV{ zhwMjn0NgBulikQV2GimABx3MIJy#Nr4Yyt5S6zY9JNd?5*P+!Dk(~1>#Fqvb@t$Xs(P?UTWhc8i!DI&pzrKQI|q7RVSp~Cw~C;4CLI5xdlK-($ZzbnE& z2@8!pts^0grD>=CFh@u_1ZG#9$!LbE z#{nj=%MrgmsPX|p!^)frJv1*6AjgF1WC~JFIHhZ?_d&v9Nd9lk5HI5tF5b@t4@;EQdQ$}lx=ZD7q#iI?z=^}(8_Az z7>Wk%@Mz)^jgCQBQbbSeZ|HK0`f%|y!wTYBFmk%Eq~?)a&AvMTVksH&z!v8{vP&UL zJrJ8rky-H61q@0&(i*H)2-;yLb_aL`PFlIW4;J}#pXN^kdMUcF6tB&xgq|dj9(iSI zOPX}uleY4Ys7-_gwLHK%qlUdemJGolO-Xrx%+Vb=eo9hShcstWIYPN0N5U9In5KOC z-lz)DgHT->k<8B?7Mo36OgGOd@=R||5LXCtSzwk=r_zx~Log#F^9%t+$RULHoP3%4+@Cr*m>0o-3!FmO{`QM9$1A>Wf;)mUx&`F! zUoy+_ZoG@#_^iH{O2w&j*`9F^KE-^?hC9#`#t-5B9O0J#d{JL^S#S~`k*~~jWfo|C z=HUJ4OTd48u0s8zI)9zASY`kJ^}lhd z$@XO1wocY$+itQk87JGCtjU;c+pejZI9d1ZcisO7`$>;F*FNWi^yzVl3oclo3 zF89;j!@(B@qhnYExSS@qj!fPuG^0Exfhgp2sKd@q#l7Rlpgm}UVF~A8aBy4=n<{)U z`pU$fO!<-+g6QXpIHwddEm!iS&yx)Pl}Xy{W!FnTZfQQ%w7&=tcfO0hO-H5tX`i=y zdmBR!Z|0a?T?J)Qyu1|*(;P$-wnR%F5!B~kA;Ql4#3e7OGH|dQi~BfjiU;gy26%=u z6E%?2Z$0pTf7?6uJ!;G|&%(p-+V@H`RuD3!R+8c;rq`_Mb=H4-+i1+bYj$nDEqe!L z+9X%ef3c9y`*q!tdNZM>)Zl%{2AFLiHCTKfWcc`igX5#6c9#q7eA%?c#)?V|9(!El zao+e7lD>K+T39JI;j;NbI_TwgS}FKi>w0M3Esag+HWCG`jMgycoiX``W)->^GJNyf zmzj-?iI3s&hfNHK^9xu^q_e8)d%}I8!8QFTkZc2>YO8>6&DqYYX(gc@l3{|wAki>&9n)VZt`TkSR4S|()7Ev5} z=?VyIIW8hi9^l?OiKK( z`Y)UTyukI5+8J)g@YHQEIVjw$XaJIgEkW)q6fT1*5%RB$0F;bqYVobetGwxKabd3H z;eW;!mrytbNSyZ0;Fw-l?+Y}^o{r&gcsNlym>SF#b&U2X$b9xm>AP3x#b!=qp(`G` zX6V{(&Y{Ezpe_pUfk`Wf1)uzMyQpRqP7jVKPiM~OBF~)0oMtRW-By-|M`u1Hnge#b zcwlZg2{t63KJ|fELNw0UfH+o3Zf+`SQBa-3(^*ENX4gl^x;f_fpZ|B==mbb(Mp?KR zfMC(9j1uc{%}bb*FA;^tRLnYbJ1VEZyWn=;K2pwQq=PQeQtC69M5v0xKu#7(4vjuw;q!s`smLnFJfzvlJYp@Jez3@T2QM!Eo2 zz`-u*Vus7J>muO&xfA%ZycRFL_PpbL^0)iawA6WhO7Ob)#6=frv~W^SbNH_V;(4UH z`+c$-k#4@$%mf3a@Go`l(?gli)^W}w-MS^@A3vcP%r@3D8>0lD?P;T}2?vVDrv*Ex z)Mx+9Ox;t8#aYf} zBLqOEq|BX{kox-i6WP2;Ky-50O#5!zQ2GRD)()7*q_FK4*r3&9FjC0xd2c7rgx~(b-)iI;58(_9X?dL+j%);0w9Z+G^+Kc zEtNJtAHw+VX91Tcd{sb~q-aK7V)hS@qf}~qS)|r_ ze#$#BxMH)uXR|X$i!1s?MYA5Vj~gtO8;pT*Kol$@ZjMFfG*gqGiI-gVONY!?)s#hy z#9bzNu`#wmq9`dDGd8weW*(t^NiyU!6ZWu{9T+T0Ig?qZM_yyI$5Swup}JZ}tV@?f z$;uZc<0iuyrmm~bNJX!iIAj8bUY;gRF5HppQ#W-NvFczo#tG;=7H#j`qHAAExV89t z_Vnj7Bpihm31{kn>x|gKXe~p3DV{7G3pP3QPyfc~2BT)G1QIY}2+4(PG3LOUkxz9r z*WWIWldfYo1}*z~*}cpsze2GD{QkE*A#D3IIxdFd3@P%FWU?zlyHZhvsw!!CI8vD~ z@xj(~3UQT-c^-sV3a;P**=!m}CA9pj(G#sj(C-p%t?RThueYn7y34KY>yg@vU61W& z+Mb@nw2hadXfO9!dItYP?OeahZ^V9=$Xv;(Xr*{Hn#G)f0<@|kMrzl&5~s-~`66YQ zF32F8*){ZilP*XVyND)=IP^k!<&lo`a(GR#y<3tbxZS~ssoUbSx44EJ^{@i$6zxVA z-m%|>=yyhYsFnN`U%gL<7x7K(XK3LL3u3=dnXup)kuKh|NV*+`FzpWI+t=Ew z@tN@fq%U%kZyXh~W*H#~!KH=2&_<75|2Qml^-Mc`AkvrpKdDt}JX_~vH2yrB?D6hE zKl@8p(*k&bPPZTbfbtGDKKFd?g}UF`*xt^2e}Qh?jLG;+a?@8$vHeX0M-gXUpq}gZ)}l_@#JhJ!F2iYY1Cxn4SLjv;1`5;M3ux<-=E;e(%UuClhZ zy!!{g07h(x$<>*t6ASA4ww`<8d)$GGWI7aYI(S{;yAQs3+(qJcdA>Ne*zUU9+X&!C zvLzj#i^cdVwn$ymfM~y)yZr(dhKt;nxf6bX>&)&C+wM%ACUWIz*?N}F^*^HR{`Twe z@5?~^CPZN_1kl0cXn!*foGjJHQQhaVXm zcb3kl(@G#$7EdXcdimEeAd5VXXD@H9CvN;!dQqM!4gGeD8-G7o0Tdg(&wJ7eX#l06 zIa?Uy%T%IKlTR2nbt;QH>>4p2lbtqfBW`M%%Q99MCn1fdUC4^tbQYpmr>cr26nC~m zFN%Sm@lP3>Q489-Iyj42RngmVVlIZ{GYI~q1}`&Os9i_uh#-NgAC@T>%o7MFp6wf$ zwp3miacRwg2C{;ii_xo(aKn5w5!va`B1lxH$m`j`=SxCNT)KeJm)?bxBB)Ypp(uq^ zr5v?{HD{#olSqctL?eiHWU$sCCzCb^TBm+s!9JtIgtSJq3L%G)T9l;uudj9;*8T^Y zzhehvl0|Emwze237=pKyPgW*{;_Rz<+t7|VcIQ)QMuYpU3nqb`yI^Hn)2zm4?Vo07 z&X9^F-%ZriUKtU`LynET1yIlGKsb{w44Y&Wl~sNC;-L8A@{SX$XsxcQkW#8aW=But zPja@VA~nA(%U0*DZ`%`9XVlI~w}Ja3M=sXw8RB808SJuqMK~S|nOI`K)@1|215B~H z6=Bt}5j|uEed6Mn)pfEBTC9Q>cu0eA9z?36M2Q=@JtK?j6O#{b&BwBYYK|uGwv4*mC|9@dUuMq%mxkUhU}pd%6FH%=}UW3k!J*;TZ%5Vs_*)LD4Y#s5O&?;GVvd~zPv1ZxSoy}8aNA<&b`AhSP9-1kfmCHBd+b^kMN`k|0pNQl=EOC}3UJlwT z(*^ADQ*2U7qH$(tR^&CMsTE>jbfn`1b9xZwgsFWY81EveY7gg&17T%rJ&&)61rJ8uKU6WO)#}rMG@r#b z6N*fsYDCNy2&$KnCJpVy z55Ypuz%!w}tde|U(jXutm0^peKjWV0`}$f7uerM#qYNjHJ4+@wJR2N?EM<7VtVs1Mm~$IASpVVbTE5x!$khaJ8F(3CH_oo zYltUqP%8*1^OaeB_F&sNB)H6Ow-NZsODH_Z%n_6}d<6~D3y0ETR97D|G@NKIp9!`C zQOcf4I`la-_>!xrl1)Hcn<-0~xWlJtTDkDlki_yQ!pY;4ZwQP@SRtiKN$833kZM;W zIMCN*6>!SHmt!|YvXJ#+Fjdg)-}&c4GNTxyVA&`BK4N6J3nKeTxGX+uK-H3F=0eCB zSaph&@I}JHUe6<;p|XWh@iZXc(cl{uj=__-5Ws49e&#<~33;4|9KJj$iU*h8MklVW zpZ_OPtzrK6G=*ZcSNPIMRTfTE+>|{wb}~e!-2F^LjWLaTwBp3Pvf$lWME+%cY2D3v z|7TW$`D>?EUeuoeMLT$-i52H6?XDj!*ZaMM)lc1Al#Nd*7Jj7nQ0n>wm1KS2)-PCS zRs!bz(Si@hx6RJ)#0w5DxCz~6ME~@>zcFal1%{vqrGGqt5#A*N5f~E@e((&Art_x% z{hs$aNR$p&$9NaPHRX8??Z*>zXPZ<&B6R-;vEe@4FVR0VH@`R(?|+RE9!oeSq}!&x z#C$X>{WjLHm}5qDSpV#BJg0UKYl_NeddbD9!6WUAI$m?H2n`$WX*8o>GxZwG{*ig7VB>eF@LUXdV`%l zj*p`-a7*igGp1}Ti#xbIJhOH{T=B02F?ibw20X5#e?>y>5u(_3^)9lhY8=Dufwp56DYKU$+48)Zs9`%Wt$~-9tVbkm*BL8Ep2SIU)JP0 zAO09x+2O(SiPFhwG1UXZhB~`JUA?Q;&#<7dhABea!L`Fkvf3><#TeVX44 zH6B^$;~QhAx@>;bB=xRs9LTo~CVeT|^&$qEh4(+2;Q_ytQI`ErW56$!?L3618w$KG z)VCfoL~+1i&j&>Ezc>N#wMMJiLdML|A2f+P{Z2%AVBGKp(q`~S~EKH2S;A6i?U9bY)-6)aMcuvm@=mD z|1p-!c@&rHLZ2;>6H1e&P^3WGpB8`3wqdg$eI_9UDF#a#&&5n35kW61YS_zIIqHJi z)PGsvWw=DH2@!gdKff?l{0pERnwlu{-nO2Jqct(##5B1po?i>-x>yTGy7aNkyv&PXBDO2D={@zQ6 zloT$+q~?G|9vd&%qpQJdAbab-T=YuASo$H7W0omos;W$5{x*^AlPb6ZNAZHL|PquTh5kEb!g3O&_GyTIup z$L(JNB&&=hC83PU+U`tV*Q3i1@&vH$sxe@<{JRWi3B4ZxLLt+DGNquaOYqSj_=(7E zCY5;Zoez$b_iaEakyCzO>3+K}6r{$xSN_@tGz;!LI*i8(KcP9B@V?AS^WHubX?53B z6K|Gts^ShQW=-UN$s81H*_IPG&24)o>$4zOty}Z zEvhJ<`;l7AuZ1{*@p386=)Gd@m;FY3SZ3p>+yuj-1ESl%H)+~Q{4w% zHUw(Ej=|xiIQlMlIYgVcdJ-j82#`YFC-pD8aoZ|$!NzS7hiB~%E%V5xo9(y0`(rSH zUbVt!s9aFtC|{-kBnZ?L&pzVE&hf$Q`q0gthl#kYt{vgTJ$njjT`mE^Y8a5wU%D#@ z?IfW5RYhTxBbG_C1(59rRHEFX%|Lif=hOdvOCd?fZ1|R-Gf%_rrrZnn;qo*c?Ic`O zjhtEdoPKx>0b(S>M4w9!zSt>dtr!Uk^K}InKC1MmZR#lw5~iP3(8)KYvKhoPB8K$h zpucy{$xvQx{wM4-!lsaEBhcf}VLK{n=cji#Hs}0*UVv@NXbc?}-aVN;+D|Fw>QF&> z_*EP{afJy<{}wcMVTCeS2aLzS=HnH7=t=}`n!#6u5;`rLmZ~aoCgGn_X*ku{qB+Bn z&enhbu@1RIcdRn_o>x-NAc}=x#OVOxyN|9WR!)`!gM(96!x zt^GQ~D%d9uRvFP1J0y=47Z)n&$TTfm5;$xPuhxp16dJp73X?p{is(-_*(z%OH8={x z!O2l1A!93t5m#0R8w!o3HD`lFO#}G-gGkxYvta&((k{A0G;@Ym#2`6;8mstz@|nRp zeeML#rU6yibft46m`bKGu1In`bvHoMEdiCr*y}Ef?EuJ4OMal5KNUL-qcvjy+85TJ^oNP z$2~7V*tPs+_^+nZ8{#Z`A_Z(wixU7H=0O5AoYeko*+D%tQXxCqFSb*BZ;7Ag7wpel zm`2BgL@w=fLy!GyfLE$@wKR8MM}$n##5K8ID4b=R_4iv<<@uI4?NUpp-EXjmfPuK@ zd%hNf3*ZEF0S4C20Bi+lN}ec)QWE#vHW`e<(sP@Y6nHu*((`{j6n`(vLb}br;_V0s z&hxuawfIx_W!%s+khbyLQE!OQPCI2vVS?;#knL9&?qDFJsa-XEo@Xe?s#`*k1JpQ z?^}8!=O)o#w^zfvDgNHL9}e$%Y8FSS)gUf&HF)@9R2C8c41hQaA zI?h0oP!a{q&oq)EFePwYQ4hhW5TwZ>B&1z`9lqWFq%C`SYwgII`6n5IdH-m6oSVVx zYH>a#cr0-I?3b$=TY(YYSkw637nQ|+j|ZDse{`l`(vH(hARy}<5~)o9F;Sq=iFdvQ zx4)6O#$r6OsO{zGIYY?QR)ax56agz5hoKaEn1h4M<*_8~>b25;Ouywd{KCKsi<_cq>(LmuN~&fzU&8iOXtNJn}tnd}g(t<0AC>GyMFt^Xq-5K%5o8UKUPfO5cfpYVg=QSL-U(u zNrgQ(yw|8&3^3}*M4%m*={pJ3vCiqx85DF;CM$o7YRU#jb4+>t_z@UmDyxAu=Dn8N z5H2E00;5AKkuI(sG>2bw2GWy-Yw(3C0Ea%pSu$jL(-lq}UloebokE_g!pP9VLxK_p zQ4d(O)c>0j+atZkZ%FRE9HPXfr@+4RpjR(oSsXxkxAa&r2$E^^N z)lYeEzOs(v?evtcr^v-0H*f?0oVCH8QBcDO z{foiZpe`wnV9k&~;J=8M1SGSh~o`<@CLIb>Qt zl(hq2WKXWb}DKDI=>{&-O$6Do(R1~@} z!jZGq;2oQgRipX~1`}#i!HJ2}5C#8N29=B>qry#ec^+Gm`(_(a{gL0=LLrO*|A=or zRTB5*RH$B_S@p()2oF@f;5%=BEwid_d$Yuu1&R`Y7Sj>yvL#UE=cBjKjtjp);Q23* zU6DU7$73T7&`*Pb$0XnHBNFooNc%6?aDLGHj{TlpTpk7Xhm|B^@_0lJ%&hxdr-ecq z-+Q$cMY@%ZUMw&^AwVnBrfGHANN&?zj8Csdv|XQ<91^gaK-EOlCar+Q8de8JJ1<`v zZ@mq2zqPU!aMtzsOFsRybZB|C)w4}l@$M+vzWQANP+~qRpFgUf0q}rPZP%T5V-{D0 zs4`O;@B7P5+g=ns53m@1gbt0&b_4z+muhnUV~umYZp+kn$SqAtDI00ok>g>xaI*Vy zfa5`4j&jtD3`#TIN}X=>@2>}^eS^PjJALAr-oL?_S=;DKH=Y#e@}$IATgRPS8Zi8# z-Ft9Vq`f*jIOe|jhsBglPNS+&uVQuqx6aL-nw_e}c~{AQICZ}4s;{q%Hf;>|xLm_0 zUGUh%q301t;1Td<_#7naeVbJ9y=^52vFWxv{X{PAd-mS`4ddx}mbgOjTi>RlT#0zB~nH=509IXPOmDh z_J~O;M^QP`IL1=Dand}Ylvu~L=BT*lEQ+7{Zjf1%Za9pmnW3_hR2^iY|fz; zjiVS357co+2j$Krgzr`m4yf8Qh z{_w3NN)zwC+)M|^Nns*DVFAOX~u+#+q6XBSey;VH1u!+xt(RJxv93n z(lEEbeZY9dHI{WU5`um7U(Luwc*F~6dnt%33h;5@`=G&)WWlW_PP|G0ADSUSRDvPu zz%OTI&3{Z8TQGMv-}tdmI^nV41oc`wR3&x7P3>=uNhRK)f%qg7Q9|bLy!~b_tg9{3 z=*dtz5+!Es?;&-O2?)f|7;(F?Xy~F^Olq{)qg5926p>_-_`0aUT$<)NAT+^J8VxYpW;)El%D&{(q-}q+9b6|@qS4J7O({Y6vTrOoW zsj9XfFFCVqm1}0x-e?#eD0`PJq%15hH>T#Ca$u28&fvsYa#Dp2`8QEwGA2X=X|g*t zTEdZ76px;rOi^IxWpM@Rm^CEjRlyLxbU8+_vI?!c$uKg6uKBZXN{y_DoLX+PlnUeR zoDB10DdWtWBnerqz>*osX4^r7-ibo%SsMX&}vp*lYZqXz0HCUa;F`&k{nb%Nr@pz?r;py2~wJaK2RjD45q! z8tzw>c4N6lCDij9fIY1nCg$JEHa%^sZaa8hE=Z<|a+z4Mpdu)P{N`R`x;i(=+_4@T zwsR(pLx7*b;dR=(q6Vkc(;W@eACq-{@BV6Y)!;4guZ{gKkJ^(rpE1xbKy^}Z4-ppScTe({ac-7{Z3EP5KkZDkK&G8pYz>RU5DMzh7W)w zqOjNZnR&x(O%gyM0tg95a69bP(m<2-{0h*i$OY0L!mVjPrTYj<3jxW)YoI9oRk~{E z)308MGOdZLw~%<_KByL#zd0z4H!;ptwO{dAjrk1u9VpUXE|-&SS*NI8?&1UXMw9}g z3^(sAk$E4I81!BcaSXqa+IGkmN0z!y+6Y}1_&r<#@t^^fVGL{n?T&A}_Wj{Wn+7J8 z@ruWmz-QO)=*kk_c*ZFPyWQW_{VYl%QHRSh{oUYhC+O~~QFTfZha~Hr>u=17A>C|} zZT?W_EO0v^#?M0gcO-g-Zca<%YMmM$D1q>|jP(_jC7Vbrt` z8Z@Az#1thX4+}?Fvo#2cyupT+K`~e$FJeo(>bI>q9GCXb{kzqSG~Lr0%)9-@70~_8 zoKIer0tl7CR~THdIc=rlFT%V)KI&75R)#0Gh>4o%h1|1JpN$C1*v$r6Pxu zKVw+xnyruUr*@!yD)?EF)$(Uw1kAtB4xj7q_ym?DDLDl7>Ipw1*#p7J>+lI3= zvha%&kY8$2DAfmC^V6KGFX7(1CdmMw-h*M)Zk4Le4kr~D&~MIx)cVj zs*8d>LMu9{)r6T$-|UTK%LNOwtG1@bhzp#)Ql5NiowW1YS*?>JuRJLZ-&MC`2eSvaG{r-(MWJM6eqfCOX&P9%oH^t+{~fXKV*{ED73W4(eGl_=VS?Ni3)C5_z%s> z%;Lll9iifjX;2}UhB|R82^2J!0}UCI04=N9oUj}vBPX9nUW|#}*}vXSt809-i6>~y z7Zg4RMsM)L{b@}&xCT_)>cn%O}jjAWD7V#HJyHj&YKnodahENt-eB%7cg~z2RF29#PHPzhI z5?|0(p@n0PL6D^3ClQHxySp~@%oX*=#%e_*syTimcYFK(Ay9nJ_Wq5j(167*^Iyl7iYtVC^oTSv0xme3G zq^gy^_eWF(NZARt>{!EI-3<)IDFNVV>b!>mYOcur`9G_TZ9wP{Rth(e8`V8On#yuCo=~1F>v`bR`5wC$!AvYS=+(Yl z4M49ZwSKzMF6ux$M-QjBzjvfR7v)|34na2hdu`63y$MoN`@Fc7>#ZX$-unW>T!;y` z>ukX8ug=b={HN(J;#BJ;-_o~aS`IAjt{1PES`%otR=F}VR%%79ltM&Ut8!(OWG3OdEeX|ULL1MV-A0L#j{x~$Q(_y z1%hxH{`7IF3b~sGsIG$dHV1;+I^5 zs^aZ|GBAPSpzj{JEAUY|K_jSa(iCcAlyaoh^@=mLve07Weo-pHonQ$sCq-rFxFed9 zBO;jEQMTw7x;Q0yK;VjrpzyEC8;y}o_K?#|JBl4o zn@T2|QkEUemfoxO+hDX^6$Wp)c_7B4b%L~c0O5P(;`}w_u~X?eDosjYuW~g4+eLzQ zm>z|bHbD?aItQs5f;oGG>L+J~`T5PkHLSCfY8yU&pOXoJjGOd{1gg{pp3qO!B%g4r zd$k1I!GmF>OxJKIef)D(-Ip`V1tA&2i1`pKa7zDg< zid;#Zo8?U}hw!sH_amy04LuVZr`jTN&k>Hye|r;<{X88Qzc!E7uD4@-^bM-EJRdnp zWF(QuyXl1`vlXYnAwbh3Nq`!VeRoC*+xTzRWvXraAbL12_&;##kk9>E^j0phR6Oxy zb;}mtObr0spXfT!S*kwUJE%3h1aq}CaX1fI4>vAq=+@hn@p6|#I<&|V+aRrG;hO*W^!`4Z6dCTjOm79i3d^b4Qe;zh)!5Y?SJ#+;eyiF#ns zHbIYoRk!x1p!3ZrbK8b!d&w$#teaEj*^xBF(3UVDAEf7b8;T~ugVa$D#- z3ei8j&VQICJGz>$QI9C^u}M9?3?S9YWk$;JRE9zL@&!79mZmh;8x8iquj~)MrXBWr zwSDSeV@4-@_O!Q}Z_UW6y-qHs3!BC06>Qbwex{PiExWOM51 zz$>$~avHdJ-nYf zPEhJjD<%C)cw6GQn76IV;Ae$e8>>XczE^|U0dJ4*OBcF;MGr8%@UjD2 zVJIWffG*6<@$|7;-qS+QSLq(t%Y)IRZH?%tO{rNz++x%N7X%lWA76(@NFkgT6PM^@ zHszC`9c`1@#MMlLI6#-ifuN=QCbBW<;)-5ANz-2@@?wT7|G`wF29ZUw{}=+~ml7WF z-5{wHB?#ff5L0)h%ic3efh39R-_O$wsTah7WbqcNE* zxhmwDS4#-rK$;-2;t8T$*KpZdIaLQo;I%V=eO$8jpO5i-&4SLLUA;U||!g;tn(eo3mO z9RsC^SS?j4op6GiD>Y~93qxWwQfsvoRUO&P_i0XJ$>N_&JVQl1;|qyZu;4}K()1~y zkotnaaAz{lr|7_^1calA6cQ(7a|UPBow^7XkwJJolIr2_5OnM`rWFVYZK!!>>TGhh z#r2PYB4HddqUk6z1>qBQc3#{|;^ojxh!L^mQS4?y()%;tG-{*pmN&v(b6OdSB+D2K zyAi*aVNydc%_e*@Wj8@gPnR-|h!Q9LO{pRYZh~;sBwdhEU6(9Uq%GBtAR!q;r)z*A zCG^UX<_Wokw8J_>)KOKMO(xL~M0dmuv0~?{&Xqx|C%BhsMdZ)o)ph ztKW_gKQu6z64<%>z@Wbz3J>f3_ctCTtNz2AK-*WC7_ffe>%N*TRi?1kZLTDI!F>_D zoSApKRY!$8f7!p_`I~GC(Yh1-Ii3GFIjxv%%i}#{<2{Y~v%{ERQ`fJmL= z#ADq~n(eswU;1w+$nxdThD-juT(!``luEoB{3Q<@24W6sa|OQOU`)+wgchSL6*bDd)YwKOTOH z`IYyC`|AVK&nxC*ZbEf8Zf}>Dkk=}qC!e3=5n#qrLjShl4@Yq-xgH_~n5_T(d0at# zJg*m1UL4NDMA~E_>5)Q0w-dHIczkrzcN0Cz&G8?yC6Q`iDkP=kwu$O1{_Qrmw5=LO zn!z{PyvGSN9tKN&7p&=*LoNUsCUxF^MJ-`GGNMwH!DUJX^o1i`Z25bHqu_-*;Y})3 z+x>i$c>6cpv1;?A!NJAJUPU>5QlI5Kfzur^#T^VudPYB_fCK}q_oT`48TSjWF}W-$ zR6TJy7WTu`$b5it=((By6L2MrOXsr32UhoE5sA|exEfF%^od;cQ$6Tvx#umV7N`OS ziW~hO`oArMMnPmXQV(~xG{Jt{pE1*(|GyXew?`A-c+JaV=Lo_!RzfLYf?p?jIJKD zjPRFm&P(Uo_zUP$(090U5PU;-Z*iwIDDnz9Rzm0dC?e_Yzh6PlVW<&2gLEJ}qA7}2 zkt7}^MQ?ReiKBx0Y8g3Kh}dCzQ6|)6wHeu+Y-+6PnT>GmTLv9oRLHYl@AzcMoJs=3 zf8#3aJmd+Gl~_8`FTd|>t?>E4R)1)uVsR0I%)jY`XRS86WRkuRVBbi zp)j+tNibxjbuNO5Oz7(dVuv6`TulitX-w~HuE9j|N_Cn8^lTegXdz5>HHCDHfvsIr zCCr17!LfI>Y;k-?7^`VTZ8&(A0<@iKm4{H-&Xu##o(mk2uI6RiVU3p zVC&lbdOXga_~U4BhhEnE*3|#@MC^a!9~zkBv6?g#F0e0!vW}WKI7G25LZ)YkxeN;~ z4JfBJkXpgKCM}X`3Jmvmt6zWDa0^0&ac7=Tp`V=k-abWn4@T zf6IdHtBP$9a184P*qS}73Iqe|xXn7TZLY^`fTHrDrsVqFttym?vPUR<4^qEl>GM%4 zy3T%`bc71N2k=kP*v%Mx)As?sMA50WMID&rV_!d_z-yeg&NRM^qB4ZcRs4Q;E^jkx5G@RCQ-9O<_Vf4azhCsmJE;xKq8ZDs zSIFa8Y&_|wnYE`bcgf3Be;l}pRI3-z2*_e-{q)2G!t_lCdpAl2&0f&M*`Bbr9X@EU zOud11$fVF67d#>HUwp9hgr9C=2FZZ&b@B{PWa!Q>@I>_s`LT%Bqa927 zg?+UeiX~D?HQ%@$_QB=T2!t*`$rG{-9P-|F-&~0t@9l!x#~pm@4tbfc3gZ*gIh95%raKntO>qTD8oNwM z!a~lr6E?4zfV#$BS3ar*)N3>t9IP0TBmRSMj566SS4y8e&#^$~FI6qpCVUe%=9nB^ zGrj>YzANb=Pf`5^9@l|bjC-+|iE2n3v4ro^VR^I-!*p*f|fKNfFNr6plS4A0aEC0+%%II?IZU3`Gk4w1~T z_z#6>OW=p4-u{C@dsehf$xf&-fiL=8 zm)qHb#-NJ)KS<^ZcxeL>L@N|`O4&=*1m+`UX9S%Z4hk|41^(2t3|S!@Bz0% z5j2xGASMs<%PB}7*hNLEHL!>thO1WM>!@SNMWDx(pOjP82`zEZM<;bjgo)*x+;XC3 zR=r)5*pY8ZVY<)`d2Ps1#BBxM-^EtH8TPvizf&$71U$=)b>4S+#M`gl2=W6XKUp82 z=QA>dj@Rm!8}2X{`>6MLDttE-F>xx3fG^xS!k3+z5}5^DR|p&2|xM zYYz`d=1>b$;dI<&y-5{|33nefU9vw9oN> z0M&OWo|@a7ecSu3S?BNr)CK^>$zoi5_a_{0 z3j9z!VKO-UhB^#f0#aln!={A|gW@!v-3bTz-2@AOF;KFj;M& z6v^q#WVb|qzUUEd*?yvjy_y1?mVbT$?SL#h4^4n{25=m*MTg5oJDGTnTY;EJhM*5u z2T-P+&+@Vkr#cp!?S2-`2;d*`+a67!Nnie~8D6cZ$^AFl&RJ<~WmD49fnnxnM4#P% zdrQCdx$4IENPOPQK^x~{)n6_u=#cwfVDygtZm;4n+KWtUB8j`Z_e$C?9O$Vg_xw`|gn0WoL`O&Ip7<&wq?YGfLF+0w2(I z%>Ae7hPdkDcd5N6|KS#~RCByIbTBYmz%ykZQrrM9j^nUf&!zsU>yNul+2JU42ZXi+ z&Up7+qHo(+wn%cC_jQ{!{5Qk84tqCwYav*2nyk5!Egqpub z+h=%zKIiEt0tDV4*5RzFBjWkc&XdZiuo4ldczg?HOD3HZwMda5cn;_wDlXUx!X;WV z>r2tldv~%b8j=*FhENH(VpTKJg_z<7J5GDP!i}@58XPs`(GBl**~!*91l6y-lvqoe zM1q?{>W%4J$f6~h36Y`rDM2(cY75ouNoU}J@cnr=xRXEq~NbVW>k z;yD}5h8CFOF)5(sLMcerh%D}fs7Xb&0{wt81A`rjK;3@OQ#@m(Lu)^%#;Qx4twI^U z%6#_nZooZujZno&yjw7XYF|?*sQ9l?1Xnv-vv@HkTc%Ewcn(1VW)IV)_~0|zlo>Q# zJUiYF>Mo03dci(EvM5;FOo&_oi7lc|vFq2xxh~wb8CE^M~%-Yy`d#C-%- z8f-TL-e3RwC{z^yoGp4@x06){&B3veDX~TM#5wmQa3{Z4Qm%aLBv|sCU}| z@7xnt)~FYH8vq3$8{oi6s0<)+Z}bB5r+*gQ)~N5&b{mEcgq#$iW-E1ELUr%&MQ!y# z{O2!%+}l_G!GS88h=~qIZLm7kWoVTn+OrZGn^5cv)8kj1hj<)XpRIr92_%Qa2}C;j zA9ws=aYaxP`Uk!4>qJ*J{V2p<<|t(=>Uy=|JAaXE_XfNa!=(qH>Z59)PPKg z=UAK|MfG)x7rdOhkso)GJ=0XP8%Y|((^Xsx<~-wjc;5bEzT0Psw<#1QRv#H24!Ni^ zQ4|mmS~4xH@Vqi<#UN$Jxess_u##2(G|VH5iqJx(PGQtvO$JZ(MjT#qqaC04Eg_P`o`c$zHsl@nAo;A#>Td7+qRvFZEtKl z*<|C5|FNA-va$8f-uvDUr)sLEs;j%Y&w2Di`K>mEw7e*;bvVEqYfl{|*}YUf7*N2& zT0{vaqllQoLy_5FY!R*wQ_ca{cfg~FJru7iK*woITI!yd5FAbvg+ve2BwM(bx$1;s z!4wt2q$RJTrP47#5=8nIkS#1@3J(!A+X29pE4tM_kq&DuK*&lpW`KGjcd3&XfuHpG zO{Mi2(h8G3{s&Q-To^G-tf);qr~9iE23=RVpFnGFd`TIA&IBcC6Us;d+1g~T8`5$} zgnQDYx*V~bKTIE^fk4NR>@fn->j6gxSNAItyn0rf@rD@7n(azOm!f=-Ckj1u$*&dj zP%H)`ln_7xe^V6N9aes~1QcV?xLO2?MWCB78PbP`35)zG`a_n9TdVqTud0O#BUe|0 z;ToKT?jA4zBads$9)`r3xaq^dR65%7`_styc!bNb=gA~Pz!{c^bBL$BkxL9VC83^P zEGpjk_TGknpkCJIms)E!K15tBJ|3S5y2c4y4#J^0qV7rKkDsv>pNb;2lvt#9Xym^E z-nGkF`og-LODXujnH0>oh${EYs%ksZ;>)#NX>I0I5=NlQWK-`T3FPpwS^RYkL6x%5Z-E{fopJE*_6P z5_Hu4BkQ<6o4nl&*EsqZ%xc46Pn$ZK!j}tv2Pr>>w9ly1wSSNcrTJZ3|IQzYrLO!oo5!eavR-W=oOz&L*5^kjX-yRQ~)|wzNFt^ZW8COp4~xv#C2K6iq+$f zI!II(^Pk@+dZbgW@E+-Qpf{+Vcpl~MA9{bedpYJFmP?{aey`b^`H-%I6*}cy|2H9xgEA`o#Ixo=o8qtRkqnngI^qVaA91Ph4tau{If z_`F^3hRafdPcs`&D&}b8Vhj9vERCjYZErCV7l-%VmqVp~uV>YX|9<`r;)Z1=O8jO#-S1Lu*To$v!EI%RlU`<2S>4Piz(-kv(|lU z0qO>!%CYzW@=9|uGCJgV1TxNOd`0VOn;3rp1dL2{D&8cwa`j_LxTuwc=uX6BRA;T^ z{0dGmo70>y)6!}yd^XELJQXJ~p1Lwr5v2&2jHPq&D4twS;-I#?Ws$YB7=1Ku9`pA(nzZnfp}&y~Y006p zOARZ~!&OZJ1T30x>GoFv;RvEJF2*XDl-j7W!4M0&@_Dnx!OEicZ;uQy52Sfxaw;p| z?}|#n4oHC<*$*Bm^=`ahe!smsjZn<~DEc*>OQHTc!T`!;;U|#Kh0fGF`pQK@Ghnm# zvW~6(9!p)eb@zB+v)s7+<{~_U55T4oL)R1O3D z__pWHAT>rACI@m%3pO<}+SU*T3<FHlHvXr|Jm!FMhEH9fZ(gT>_0;j zkb8}QvgatCmGca*2UA07;v2mb$y<6zz!y$mEsmk~c!OhaWKGa}Ux--;$ihzW>jfl9 zry|uf%dYe}b@}1ta`Owv?I%3V^=|3xqM9tOcG|u1#i(O!!H>w`x*x!UlNAFgt=UBF z9W}FsL%LeMp4ftd0`Ah6FmJr|_4Us8+bLcU{gvmeEcM@SP-!qzRJuh9c6xfc3(AoW zLG|AM;5tF*L0n3~onnA!QMmE!6HzGT;k}9(@7K>OH3cG7KKbMMV)M;1n>?R&8UBIl z>EuG8SY-yJP+O&RqtA;mLa$ry=M9RWliRx)&?J#?n8axyH4$|U2-A{r9yAdBh$hB+ zly}#8s@Ed3kH7MHiXhni73lw`^5Es~W>;%_yDEJq??+xsWq0(>)-y(dQ7e=k6N4sG zsmJLzT|Hgz!-gkx>4>qr50Wp;b0VY9O%rW1T<-4tat6)jt$QY&d7U3!#o4lLl5Kge zV-71V8wGx)t&&y2{>8#(as)yH$59ur1%2>tXg!KMXjK%obxL_xTtI*4q3!I zj9Ei>D#`P$tSQ4Ber$YQn%ovG1>FXiO*IFmTT<{+#?r}z52ClZk+L{v!kg+!M%wgH!9xJuDjhrRNw${WHzpC_PwR{Sc zH60v;#6G_uyY%UzoU3&kv7Vc?ju9dHj0t-jmT`ozZG;+BIll*A}^Jq`HZ82)B$(5M$C2t5FnzmX1ZIeg`T`b4;N@-15 zFfE`{aFKnb;wsHINjH`6lv_l7S^2V5JVg+Kf&O@$Fn|&p?n-$y`H@%cHU4;0Rd|!z z!+m)#o&piFtOmnkw9abH%&YOjMZuEohhm|kN68PrBUxuo{9L`P{te>$dj0W93n~!2 z6JfAYI(dEA(>yd}=G$%GS- zsM|_z8_Fp;6|%^B$k#6qm%ds-=aY>>El4<=s%&J5P~2V9FPUyaW&{X zI{!5lQ%~U3n+)pi;08bSJ7H%Ae&K^TcK)RYooi_!SLI)u|AtVgSA7^-AE&np>-9l6 zqHrLKP~cdBVDwF?UgNSU({o_?Smx*1oATF^Hk>srl>SrP4zl*_3`n%YYv66`Yu*oc zq{hr_tfC>{(k?7P>FY>(G3}rD^*;jNKhXma&IRNn64|%*8-FASOq6fC>%>ULsazI7A6rM!bsy@+vtP;5WP5~Owq!noCacs`HQqZ`co@N%L7mUamf86C z40g@MmZ3B@)WxrG1W2Z&R{h}mfR)+gsenVQBxZ&Ix+9Y3#jT)G-_yUB``>Xsf_YC0 zMD*)QAY}TR;OU@#idCtXw3Mbw)7fTAkUuZ58j;p(cAdB9uANYj43op9o40@zRZ=5r z4SQ0GDMtSZ%}FNMm-d(;YY*S!>9ttzx$(ab1Ql0RWot|snXf!uNb1+^MZi+ZPVs42 zwD|gFcf8+h`{)NfShR9s^BNb{>9p7~oy@$j20V^AJ!z3R76?6{UBcaqc%##U?7tA);-gf zgOiKGVgN>kg%1HdBvT^%f(pYYt**o!tq#K;oh%HWnX^)q{fMKui&O;xfR5#DpF^&W zmRqKsJa3O*d5W*GBfY%@7Yd zX@gRG`MT)y$}`u<{`wL;i$ut$W}vxI??5>|KC*2IL221mn^z%jV7($$o=TWvV4 zHyzYiGcbUx50Ma&KQ;Xs9*j`JGZ;LG^zB#}=!1~l(EyjX@REs-;7#Vsa{hG9+{DN!15J4uovqa}YT7CDu(~(K*ADyOwQ=LHO-uT2eF!|WR5!W)gR9l+YhUBk}|2c24d@BFmY;$Q_-<0x^ zNg}NBFrGS&9fXKs3r`R4PA|o7H_!5;$Vo=ZuA~J(gg>j^6!B=C+gc!!ou+*6Y|E_b zhaW?->IpIAqfA^b6*IrE3}`FyoC9nL{qcJ!c-ILex2XdWYy$!-`lX0{pva(NONwX_ zEG;dwa&p$|m4L~G`mbutpL;BHu_-hp0q9_FmmSTCyN=Q(zvb=IcFEaQYt>pX&tG z@IFM42a;wC$y+DQjTny4o1WoR&+Id^zp{Ux*Dt->9T9Rh&Z%XKZ4pi0m`>g@xz;l$Q#(Q3idV6n0oCrXW*u|R- zBt8lHJjiP!>dB!o`)#5UT6HcM*{iD&a|F3w; zzw)O6k-<;?(R@HFpfif=P)WRF<4EAj2bJXGRLW;<%5c;v@GkdjarAls!xmFT!89OZ zf-RbA2$dhhuUlsLsj^O-L5kd0eY-TRM9)_j4|hHU&O%z67R~g!i$q<~S)le#dZ2(q zje|g;4BeWlQ6fqm3L+HO)t>g7EqZ!laSbt>%uT!K5-%Gp9%fmnzPdNKhK-6WsfXw( zB56@NEE<4Zbv$&se7x-Ed2|POjT|MyInz4rF&EZKkMO84Ke}*Q*stXF3?4o9Vx~TR zvP5OMh-uYH#}HYnf@t`HO}}0U0liFv`%fbOdjO z%edY4N~mDrT14|K@3cl*B(5etGC}9|P<80LFkN;bW(~~B_PS?HDo4_l;8J<+)mKTemZ&9a=8U}#-2|pi!t81Xo%8kIKQt`fa(cmNKhlZ;5uF_c z$Ym-gZSd!lxdQY>etG!H_)uN1WQ<$NdCPg8E1Q z(=r-MO%#k#GkQ}^c;5hJ;a`&s4N%5s3+14pX=II-)9(J2LAVE&%zFQq`p-AC`q+}$ z{9Nvvbi|pXVG@7T_I?KSws~uih4J@)`WJVR+`S=375#ZDg|D}7ecJ~GZwTFeg3ed6 z(WuaR0*!yOyYDWngx<)6o~~r!LUNr9hhK2~bK`=X&-xO^aJx=_ejQ5*^@Vg-tLUm` zaBhs$h*b2vveQD7bP#PWcRLJJ+nEAEe#MJEn+Ju1>;<>D`#NA+x24?Fgn`GTJ3bG8 z{`*I*Lj4_q+GSLh)_X|Bvd25?Gt(ZcR9aek(XkVV`ZO2GKf-@Rr$nZp_Kz(B8nRzU z`SFMmOM-$J1Ob)H=I>Rzt@>97$MXXxaR*5?zs9yFpA%nThV)OYRzQ+FB~`-Pxy0OCnw>plsV|R zp8Bo=dO@6w6J#fENDvGib?dKK&#mC$-aq`g8HhRv^0rBTe?JlWs;MH}v|n1~GqwoG2fnJTmJe~9-QgoWErro%-=+u+gxheJkumD-?d{Nmm9Cegb63W%o8mAO7 z-Y~y@tDe#2k*Y=FLTqc&)-@XLwf(}$;Gc+QE-8bdvCf6b@18A@h+`e-gv6jo2O}a^ zWUxP*@1mgt-{92Jm+Z4ZwxOjnQ*`^RpEl^ufUm^n-+UAW%S0fmM zCo;**>R9J_Dq|iMn1st23BW4NHvXYk>aHjR6e_#g8p!FvDPL-bcQ9DV`!-&AAoO*v zFL*ulwI4?E3Wc*R6}zt~_69=A=WZ<59mLi+b!E!gyAIkv)Is{Km#qyK~qdh0mFnCg1y=wE2>3zxL~ya_8l*MViLP#&<}e&mpbnzloa2 z;@xmfkQO$cF&a2zILI`lH@9}-o zkHr3+h3*S7{(sbhHq++GP^Xt;l`8UF5&i{M-q%wh1(Q%RR8){&L?EU$c zK^h1SuFLS+C&)INB+4czC{kbriqJrHDDo?whb!%(@BFqdGoX`d@}xgNK-4b5dmkfv z)do+E;P38nu2V&020hYW5l0<2NWZHV7Kyck>-0n_)8OFfWX7pVyC^^ir9z{JLWf%8 z6tUd%{8P|R_^7{%9XLLhHdms#J=6N-?=@XagtvZ;paRP6^X0@1)L6d>BY6)7*}4mE zis9b^n%vJ+4WGJKT>drA=R{xyHiutQ7q0GQn!^LTgLzFc@Zfi=da2cNrg=dF4NJ?Ixf5=JblD^k zDC>*jB&8#gc+DiqC1hIiF)UE-0sX=iO!(E3l`!co>KZZ&-<}ut>=jZh=z!*Jq@Ko#TR5WSKW(?ga)RJid$ ze8AbX|D|H zB6r8jB8skgOYigqrF(soNoh3wg}`OMIyhy-Ctdee(Ge6~L3n4{fAilPHqk#VE#uuU z4-mnVT~Kg_g5*WI;4bgPc|nHerk(o>(#h{mh@bMHt~%DN@Z$*#RE8+#Jvdc-sT4fn z40OhJyx&E^k=d{GAE3DLzTdz$+pj@N;d$^0)PFvB=m$L5{`gL{$ZoJ)Z!iXWdY-Fy zr>zsSv^2tpvh<4{dz{BrGcOQ}aSWCp^moVgVqx8WDv0R-694O6^fz?=IS))oSg_~H z&dMs9x3-sqym)$>o}O-WKjU3$>&yLyb>@jUqIoya6QkAAvq9cz3iLu;$A9k+Jir!> z-gt!78$vX6;VXQ5(ewEe(mzKML&T z47=mF5jDtvaer7KoGd6q+;iQBuI{l#S=Mda$7p{{XaHQiXyq!ITQ{u_uYI#C;yitq|`dcEw#iz(aQOL=wYMS<6dYy!P=&a_!Sx) z^XqE_q1Qh7@eE1v&XqD>jQC!k7{hOej#|s3$>ErvfY9Nd=%)ez%)AzuM1!TRW$YMX zAg`b7yQ3~0Y74Kn^7!PO>|20AKfwO7T?S1*}6xbPc)2Lh) z2k5q}UxgF4C0BC+QdUVzkN{}G)6;3O=IBNF5~|vjwF<=L_e&)o{*tOdq*Fi74Qi;} zYs5uY0O8x)%g8Ba9|kKX9ftg3q6K6*5me_A3_?|&AX6=KHb%0U7qQ5ZJ@!7IE9EVTP8$gk&a`{=5dRNl-g*~Y4>l>*5D!m*5>4XR zwpR-(862I7(V}=FoF*L~jVb1STw8f8Eu;3Db>WFFJ8~Byrq#WU8WEu!TE#Zyl(i*} zi@ANiIBdqPtf4YO1YY5qm}Q6(IXp=_-^@V76dzcfvLJ`H09 zUD{Oknz^>n!mriPqy*LUJ`u7U${|hcY}hheG}9PXbUnHx^lD~JMEV_amhVt%XbPc{ z81^{sx$Tu`rb!TIwLd8_#5=+QS8I6ZRq4j-^(l6S^&^31& zA3Fq(wLrqrg~sMyO^#c9fv<}qN28JyC-Dv6kDdbS?HYPQxCb5r(k$8x-nRXi_k3sw ze}lhWeH8^1Yu57v0T3U7g&yb2^XCuk-wjtdbGZ~;hqMO9h|akW#6WrwhSL!{{?`Xe zscC9PcmCAW)Y|R#Yo7DCS_U3iV}x!Nf;2+{`6%5vVZBBo;jx*IUkwkwx%&H~C2QcJk3ubO7-F|TQMkH&FhDIRjxZUArOoIv+ z`9y$-Yy^5J|75zT)Nfjyd5N(!ol@|bXXu4?Ol6+!1e)5&`)MINY z)$C!4FraRsh>or*)i)ba6`D%%q{@(>rOv-9J~9~<@|g&GCMB0i^Luq8aIidZDYy(J z<4t^XvgG+ci^UL2Ir>~9J*l%}l7D!FGY(~Pb_JJQQ`$rl+Z^N%uOx^cXNk`;LC3X_UQFy;MTffNFI!Ofw@*G;2im?n0>>Fat*ax}K#F=-rJx#|$KAf}`yW4_iT zYc{gVDTq{wXcRgg4oM7{}tHe9H#tSV=yu&KCARsgFXn(mKyRN}ZnSQ&Nj^uw~I zMA2Qd)X39)dBl=2Ua@I(dPHQ#u2VJ)0%@(JY;>tOTu3ro)2%Rh476teU2L>9m-0GB zK#}KvMeF7TMdiDrMg~Jat@z`ck_|c?4xF_87FpH;)Uo1X2mg$k>=B znR-2LXmI>`NqA{~bsxzF?q8dIPnO5kQ&nK;?ZOOPPV2!d;8i##tJ8$ZDlg1c5EmSL zL}TUPJDK4lBDE7Ov9gp)7K!qlfTqz%C_0FGMwQ>#la%fZsEVm4yt|fRg0kV#r>qm! z<7Y4u=yoNAVrLg(uiGCrnC+l|KaMl|h9J~?NY9tw6P}f7^u8J8qW<(d5}81|*&L1H zlA1lAn8oiGNxv`1;}fO#`en>{@bhia`hAZqL{(O|4%_dt4M$7g1-kHU^W=H+L~v|m z1Zu_5j|nX3ts{z^lk?Zo(vs)T#jUDyd^-VMh6VTC6HY$9NtEvwgCOGMB#qFE%s-l< z1I!nM_j1T}iP)aa+i-Q==Ytnc8dNmS5RPKA*WGltTpE2%&RG?TF2k+8^NinPjCe1q zyWf!jd26Rvj%m13;A7B)p*!Z$$(2jU6PY{H2J}7-IHO*FPgedHn&TGIKixAckVa^j zKh^(kX-JH3qt{DTpG2}Y$IN+SV>6%h{jZj9O5a;2+P(hD1a=h@hiO-(C%>}X_^@pkWN^oXr|xhac$z0xbUa*vqm<%6HE8L!|(?MA^ao=rkYsx(ebN!>6kmTrtAf93j}T~Ke0c49Lg%uKDOQ{xy8Kcg1+o*24 zXf;Q@caQ8S0MU7yrVRbq3%s)13wCAwD^+~+V#*n^I{*4tuT{s}dODs@rC6Hc8Z`$8 ze2~4nJ~YtDDGBbBh7BzjUHJ0jrvpP$msFB*nt~s7&Anzic!jg0`S!mko?y+c0067!8ViCDy2&b6I`O`5?rs2@p*XG5Fk7lj52r#*$|0T@Qd4v1kznSMzV zryDXO4ggc)*=MCK|L48+*8=Rz`0VLTAEc1=&+TT@eNka!J@+@4lJB}3@9Azjhy8YMwnQ9u6G&$lHbAkCGv@wY5ar5;`-uSFqhaT&-AL;}0IKS; zLjwyo^8JZSear2;x3>SF!!kasTjt6-WW2-q)dBqGZA{(UmBms2)lpQ9vAKEp!}-c= z_1?cg#di245#951x6uD0PP*mJXXE|l{Txcm`H$Hffu`Vl&F zkEy1nSIHoU1YSpFlTs93nhw|PvD-_sIbQ#L_DBxLXsT&UAk(m7c$WDM9xetGtrSTY z!E|ZKgI78LiTFfd-j9!+$g%s3T7G+XT!K^ea)iO?&2xbR)@7EZ^xr1MYsMh?hrKA2zOut*(YQVdu3}w&CU}ig}_^Ma+vUlPoE(z{xG^r;HS&R%kLzp^a09 zL8F3-LMO6?O<#UqH&ul%9vOp)NJvw&T()8;idD!GSHt2g2emuNTg&ud%fKSUm^8JO=UZ2k&WW0Y4{qSspp%DCqG=<20BlrLyhZM@ z+8m2QC7|NC@Y?Q{_$1<_ff*e0>N7=V!bQoR#>b8kq^Z25NyQ_GGST3ol(O;80_!@m zmy9A6kn=K!+FE30Bd5W&-8`wOmJ~cjZX3VZrw#PKIhm3Xa5wzI&OLSaEa7azSi9u@ zrbczj4|!zGMU}r$0&aq|4GRZeX1)^eRDs3mJMS;KlE}`iW`9Ns&Qx^8k4%B9faQP{ zBH}Y)JsKStDav7E4NWPYt~wd=rHjU>!+2v&Us&3lxBis$^FTk|D>*W+I0KnJGiAg^ ze!YZ*Q=y8~eZE=-D3EenY@qxWhuLoU6uGG5@jHIw@nnYRWvpk?9>Ffd6x?VeA zh9T#rGkw|NgsV<}3vK}ta6F#b2ywJRNCNOvPg%F=0fF)C%Z}`PTnTk{f7aOqIDbvw zb9e|eLXF=IJ++|`pV*D=W20;ak@P>sdDQlpA&&JuQ*AbTB5LX1I;>x!l@MgLN3NaL zawx<=^xmm!DBKrh&mfHne(~mcj1IWm#xQi?RtvS`5@`I#B$i)6)oM3&J zLq!$q)DD?5El?Kehiuy#k+Vf}Dsr7J39QRRO%MaPLLHOfbw3~z>9xj`h6@f#+a^d%0 znH&x>l29qD&a>r|T%?r2&!iVgo#6zej4WE)90JEuRA10B@U=BcA}Dd=8(@P9)kQOO ze!S8t@OitMF5N=_$Af7qY8kuOIHMkTPJ>j;|o3WAS ze=Qe?T6(9O_LUdg_TFVN4yDe#&Oxc-C3)v5To*@H3thw2kWS?+1=IZ?qNL+h zMvQ<9`H3)k7u(&K)S669m7LOifmTw10RJ2<10^YJivG9rlKyyycFpXC%swxNdY!3u z;EWFh4yLp82S1+SbSL5v!!Q*eGB%mwvrLsogLCX{8V+QeyXO3P)`BU=UtMZ`mB;g(-#hIHp2xw33uz5+3~u^ii06<>P|n#X5Qiym7TEOs5&( zxCVCRyVCP%`&%IDf1;~}U7L9L@ij%l@lPlJe69XJRQ?yWN-pQG$olUOZe7m=C-b(z zZ;R({b0UeR4jNilD!@$KHsU%&(=M$U)UhI>U1Y zlF)%puM1U)=+0h|VY#b-1>Ke&t!%P@S3SA^Mg*X1OANF14`vb|vqOu{TBWc{L_bH# zr)NuXDsd)GD@nF4X;H`Jz&00!D`-;IBND?9hL`o^-SU*N(oB**E8@kaLlP01;a&I8Y$Vav%ZkgAki)Cz zc*>;5@31A-#3~&8@58&JzQIREdjQhNaG+JG$Nj_kBo`P}Vddzd1szHaWW?b0fg{Q( zesXho^SD1mAs5|GjnM+R%xHhJdfS7^3tm^$%au(i+vJ`*cIFd#oi!W(GKPyo-^cJz0gmICoz{PGBRZgHb9Dh-NFb`B9Y>rcw}#$v`=R2E3wJ z6ON{vmrMgE5*UZ4-;u~LppQJh8DI}gq8WT%rQLb^RMH9fz!&_SA22K|S?N9I{D()e zUvIV1+xY9pcv3aipVZU@uSxs@ffBSI6Grgv2d5oH*qSF1cbp;^{H^o1aeybM=r`xf z&Npl_(x1seZlvPR|8a8P^as5$!g-%D7|x!|e8S=AJA?mYUqTvA#T9sAg4Hw(L^Qk& zz6tp=OI$}=2_*WIHr}v5c@G9ei_P*O?VEgC3m|YSKm-Yjk+1|k=ymjD^t6YacdvLp z?mFGA-EO=5aY5QP2`Z}em<@oe%}4e{+%M$WgZ~=&^7m4HxcWES{TGEI`FRRn4=Y@M zX=J+H?i3Ev2z}}-*KYuy3LG24CfxJ^7frMMo1S;^7u|2@j@ki>#ws#1%vW&MZ8?YW z)NUuhR8HNNvyhOI6^oC{4i#)FGN=@BRL41o-3$*qZI|oP)n*eSWTNNoa_$!I#E)@| zVVdnA7!gD^v}Bb=n_(jVI|72!r|%pz*o|j1GLlkb&aB_qdBtjq&t~pB|H2lYfJi0B zHe-ad%srP1K+=)NIOYG{iGfLU9u4G9l){6)G1>VH4@Q<5v@(Sn1?&kuKvz%r|K=$h^3RW7e=#;#cXFP8V?}G zurpm!r778 z6JFE`%4&Xe?(CuS^Ht-b=L=(;Pmk6Yx?{UHL*UVIj@XVZzzWASahmg{S(vo4R}5Dm zdW0*5k)-^}mignChPjU-DY<1B%j@>ya?S^F5Xazg zuM+znH?#jO!-m;`pm&D68>bV};69@-M@^$AImb7~3!W%g%xLOSvOvULTgk)#ln=f= zqN|q?fdz~!me_O0dHpBAaBZ9a8z_x!nHo?k*>%_n*mZdydNVct@SFJ#D-`YF|CcBf zr#Im32Kis>I0=@TT-#-^RHxP13ZHs!vG9{)p!*Z07xh^YM@AfB`1ze^wb_N@A6jhv zzZFsC=r#D*q?C#8-0V(!3E_aszEbW*v#I-hagyly#c{XrG?2?FWib^2laaAT~ z#S&9tX^EbBQtzk+XmW4cEy`4?6ckn2@aTJk(8}+$TM&dYwlEql=ixuj%nafu?nJoa z!L@vPGp$X~eyYI&RLMh2|4QL2gvfKGVYiCX$5ayaF$s*aivf}=N0TOyY_b=vL+fN! zONSJTQ(@X#)Z55q7=yfL@p$+u8614xg@Jg z(r*dFhQy{+R}SKquvq_K(zj3IW^7W1N>)RcX&e3zV(+8K*8&K)I9L;oOHS`Vjvmti z-6Rz6kPuQ6LJcRzm^*F`m{?A_&b6yISt;*f3mQt;biI4n{ju8Vg5id9C10~)A%~US ze_$of0f7o99u0LR!eGBGIVSuKo=o^UKwLemR;2XSzW>tpxZv9U-3g|un#;EpMO@fd zN)Ci=Go$`#y#_rGg&sSZ{1%%7V@Q3NJrwzB`7ihqL+RlJVKZ-rP!zl~;v)}p54fNieatAicnH(| z)?#@^w<%~cUlCaAy+I*v+WD;2^+2}JAuY$3hYH{AHZuB^5a;!yJ)`*)8EHRV_$&_q z?d7;B-;>VD)eTig7)9L4Qqlh)K==?YMpsv%rP%EKN$a+bCq>*G%H*{vc`{>D-|w4( zQFurBsK0s0eU8Nvuvf!-g<-XDiDl1$SCRLw&KEEy)PJ+J(W@P41pP1W-tNxHKx#d~ ztwB+TkXs(c6ydO?-Ev%FyYHXUUDomAY-JPaK!>XBboTIo?f<%jT&6<*8iY|hL z9WktSzOQ(^thN*?k2x6JiR6@ilm8Do+p8?Q*b}dlm@GfhnMyGsC7RVftGF25 z-vJE*-BD^3>O2=pgS-*dhxK@X#{>}u<`08rEvVUV8u)AiyLkTavhoy|=T&$^()$Md z0^8+m@CTO?IDK~I5yhZ!Rv2xHry^~BG6ZoXNXqyF>m!CeUtN2>sa(nDS z)YfIlxN1qu$6+xp+uEdd-&70gX82=U1Gy}4<$jf{O56U39==8&x8czfrA{@nY~67A z=71FmGj`><+~dwJ?0Q<785TU%p#3}Q^DYPgxBXSDbl1+^2a1Wi&>-vZr)l=hf|UYS zLNKAO3)#Tu)a$PnuVWXL|F%fJHvO#3Fp?BJvBaU#R{psB4k!l!KRBN_7ANoL^(Utp zSAepYH!cB7M$G0h*?O8e$Dy4Kr1Ye5<6Pg^cXmjIk=(3caE$>IcY%G>S6)I-eld80 zZZj{YXE=IAnl(cnvEoEZyEBTV;FcpLoptL$2dO)fmw~z%kYS=Xz7>L%XZytig?SfN z&zzR1^@hB#U_4(&#%qO^$8DZ#yS}^j#!oEk=kOR6rCK{^JOH)lJ8%@+HhhnOEnxtZ zNE&j&!S3N9FhL+vlstWKYKq7xCNI zyi1x6r(6{>7IRa1q=TqKk7ce3U&cn)?B<&M{>=IZ7WP2Lk}uD8bw4$6J8E+RamQ&h zoW@4SJ0lg^FsU>l3XR@ui?Ay?f3swMo!lH>O=s}TG7U)%W5T(X7A&lAx0v=VG2iY5zMc57b z(NmRwYKfZm1pLqvXHe4;@mltfffK;PnWc*$GPGNSJ~(ldR0+L$Xdz5B&zJp;htwb) zg^nevr37Z-2C2)IrgKS|On@DFl96*M57SkGIjsx*ni18OwrB}+&@d@ZHu%J?XzAOyN-#t=1n6x)s=|B65UvaP9E~qx3J=*8O>2oVtqz93-e%#;T0-K% zUi0ELb|i;XL07sK3Y%OZNaL|(6CE;=a6;iN`K*nn^9?3XiE0)gaN1uCHThd}K#yA@ zjCb*axnA!kqw?PR2&*O`!?{*M^YVBIdPgvs_kxv6LL!fefraTNiKS*D^P*n6>X};! zK#Mtym&J6t9YOHtQ(b#LjC?$E2&c!xdeu{Wqs8RnQv83N{dH88QP(vNAEX-r>6UH~ zq(M>vrKA+3K?IbN?v_Ro0VSlQ1tg?FQURqyx}=fr`mN)AKhOLA#`pd4jn8q01NC^$ zb?s~KwdR~_?!E4*DThP|d}qF$N7rTd@yD;AqR^XPg1tpmZ36QX@>Um6Fq37z z2-TE&9a6Z>FPhxPmykqXe1Ryr)>+}Htky`ZCMcGq<+Tz}&Q1O(g{Fq8SvD)M?HdMq z3Mo1j0RoewS3YOp4zF9_r&)q*2Sl|Ue>lCUTJ(KJ>R*8vG+#32MDM}a%ZpWYMJq7L zmRtQqAi~4L^>_Ox5dLr93Kc!ByHPmu;#)zb0RpkrOBXvjQCU@sA4@OO@%rXne&2KV z#igaSO()0VkeDZDSugI$qls+B#C@8I4CW$D6XvLhGn8($n<%OeDU|XEpK)o`A$iAo z!RmN!c2$m0n9V|}Tj9kE-bJSxj|r3t&tl5Q4WE3b)4eZ^z3aViiN*wNmDae&5yfJj zq1d}Ec#)A`cq4vNKH(snHFMl1b=bj}-NMG(#5Hjj5HYc|=SEat5n10Nc8^076=UC? zJEJ$-o=6q25ch9MC;!ynJUE5H^FBE(MHv}BXp`?ps6p)D{4@7g6Spb7DHs3lk3?Bi z{J+!nc$Edx&H4R#jwC5EUSua8VnobZ)gv#JbYIX>n3t9hvz|WieG}1B!Inp&O(>SU zs=<*Er^@nO6MKxfl1?jxCoLQDw>z2{!G@BOnzWry3j~bZ3#ndFp({Pi$yx^-Wx^K$ ziT6ID^vw;6Z|@z*=Kk{0Xwuv(n7)mS7QGoWyxNu6Xr}KD()m8ykVIt2>rf+R>3Qua z=QlU;?d|Omcf7qN-*Kntx~KZ*;mer(-nB2YJNb(6SKBm(1{U!=X%f7=1SG8Y?-&}= z2nq`BAJB>)DYh#8oLgB5beq1qrYQEAfw*+iFtxA#8LFt*xI7UWe+Q1U5vBD5&yvD7 zyR44$emLlC(T?{rD0_L-mSt??ZmP;C}IlEcW3-zb7x3r7`=VRQ{xkBw}S1bcUy<7 z$NNYE0#G`>UdU+}QZV=KIXF7XUYs5XILzL;pCa17IHa{ucH<|B?zlG`nkoT3u)~b~ zE-K~L-&#IU?OZLjnBkPO+>mwT?6(mwce4H&amhZk5Jy|P(a8I~UizPl5JZR9Fr5#TFsgp|8) z4*Sjho%-PLSre5inu>-^R!fUGC1qpIdMoyPl4kopYCz)bqJ7iNYE221X{{G!RWG5kT-0@efp9F*8FxC`%n=|b_!9+GrJ(g=YP0wVR$#9xR-3t{_?vhq@8{*PRKQ~ z-hxwkRXbc1;94wK#A&6CP8E&8!NGA)S^1lN(*+o6ZqI&yebd3k#piF;`Nh#p5;PR> zJzdRRZghQ=U*zL8?e$Tc^Ew?}3^W(`P{G2=$|N9g{p@I~bEQA4%yFTEvoe99!a82| z<*Fcsfe5`qqXGdsP8=>uJ;QA0)kL6d7Te8>Z%^*T<0cyhWOriEB1lOWWtmB)nZg5FE~ zyOcrB_!4*i`ulW#zQdbn(vcldO-vpct7kXzzRQu-{?@DW4SoT7$#7(U*~l2Tb4kXG#K4!`=%&d7YN_xIpjz(dUvZuhCIh zOaAK8SA0u;_19?-O=){^+p~;s6A{UCSNI9cPUvpvpQlHRdQ)x_$UZom{jgOdS0eh{ zw>E}biu@m>Xn z7#%zQ%_jC-o#Ewf-*yo01jK1UPw}xa2s}|~M7_`3{cs2INz*_1GhhWWV9i_3=8#pr z7kU;Lm0N@Ld;mulzoqZo*rz{JM+VWiTsNSEXA|#KS0kQf+h2_*^M$Nw8zvXzVf;yNLSX0EwlQUWx59W?K|`Dos@{m2bs*u zwnv;Ezu92_(DmJ#$?{bgc8#aP? z?i@o?-1ZFlu)bmg5g%jQk|$3%x*K&c!BNV@X+Keg?{jvj2#IXkbDf7q#@BELngGv) z2lE8xskme5e|<&*Bs-K!n5Mt{t{cs{7zVLyVDQ;!GcNv|)*$-0n=M8R$w#dl3^GlK znl8gJ9Gb;z+uRcLaOS9F_ua&IjiN3bD8luDv*#Nq?~fkYy`Fb2r+=lPl7d1g zWwb#r`IK?_`TOa*1cj*bjyDI-}0~2XkgQ3kEsV4K>p< zd&g2_Y1!W2Wm8#QW+x>$7^N|GKh64F^aJ) z)n`#BXNisnGXXbjUFTcXt6E!2&=&=0ic|!bt!|j z2S?*Q8LBexB)AZMx?PXo-gkWLjz__d5VjfekB=u|Vq%JW|32dHRNaS7;{k7$gImlH z4YwMO=-!Li6A%&--eV>no0z!Cz<>zCBKPP)Cnui)UopRM&Q*-p4+bAyHjjZL+)g<9l!K zUC7hY$Fr#WEB&ZJ82ByUf-rfe^)h!&qXL#a>}DGA#VCLDIcU9H9iww~J&eO~l6=*K zzb%Otj(4r(XMDb?|Klv#G_8;xNtRvQ-HiUck5+iGgHAh}(=z?V9z1B)zf6x}Qbm3L zP`)h)Y&nwh2jr)fpD|+Hyhk(b%SD4neE-9NfaJxs3?KCo?Sqm3r1p9uhn_B8{CGBX zC2MPT)(7t`em>(0;W4P1?JDNZW@hsj`1mfjXn!Z>txPkNg{-V`N& z$7NbQG|iBv)3medfqt!ZjN*?al-b|q+}@|{x)&*4S6|5z`8t{QSZ7V_ztB<$Vvp?v z9g5fMk=Kv=in^zf|JH3v;}fsI56UuEt{F~~Y4AGgfDWVze%l6-18;KECEN&j9#`}w z%FD^^*R1zM|NQ>_j=ny{{KA6b^OD9>P8u4T?QXs%(zLXV+Kg1<|2=cv{363tt&-4?=`P9`unEPm!<=POZFmoUxfUntWD@svoz`W;4 z1=(cxg^xvLE})aKS{E)kdHKR|(m?lTucD*dOHErHV8e33?GT1nW=ND*23^J!?%qxG zib;GtW)?LUnRv5 zIy-Xj{!T}Ql$?9ByvOjmDJrV}_PmLCL}|05^)AP(D8Y_fiD|c=?%eQF^QyCdabRbh ztbGd{zR)6!bMzK9(5BABA^4A9l3K94uX{NU(na7c&$ zu4E?0*5=eHvrW(&dk^RA!!{-ZI~m$1b*{)fqw-{sxU0_oPg!M!RNnUs@=kcz!P5<1 zK!vvO2Hj5PA5xcK9%t59J- zvM#wg*G+}Fo2bsGnk}Q7akH*|0QjGKr-R^nZfe?vSI2wvH z!OCbdu|KDX}%v+gm$#Wn=k2539yjHZzcM&3n?b`3-6aiTG;C(dlZ-S7g)8K7Z8 zLd`ujPlPNH1D2$(_&HmeP+Ms&s4`_UpfXn!w(s!G>^TXYZR`EjMJ& zwPNHD#*KZLHn&5v>9QNoZDGOrZKwYBkVc$!dYFR00u!k;_23s?Ax(pk5DpxeRjtuy zlw(JG^m%_)@nwlrZcu+xqW~cIK3JgDt9gPCi@xUyht|t4L=1PtyaUrXL-&pd!2X`3 zNkZJEsBhV44BD)?vdc<-la)~Yirx0f6Qrk*OUvvkm{>iFN_&{cg!C*^6fHQit(RW3w@Pe3mn_5J%j zA-gdmP({cl9@9J@uaH$y!TJ28F4W&20WCxfnQe-n)RC#DODpQ?l4WLQDwsE2p4whi z3LhbNev3NH`YT`5x~!M_UHNKGwMUYxrpCHAt~A|8DP5Y_VptH;$RCRPVbPc8(iB;- z)pkECR3!%@gyc_83<>m)r6u7X$S?gP3Sr1wAtt? z-FgeBozAR7Ptj7-$?ahxSG>lZ4hmpVdBY)m(T6#jxAKJXsPKc7vN(DwEr~GnBiItA zZ+2(P?G^;RNO#(!-?m^jM(m)NtlW z+u`Pf;styTm!*$0=~w#%Q(Ma^KX-Rg82Zqa73+Z~`l*F9uqFwjBB&VJjIgeDzBRKoCrnL{U|($;)ED=z(=KijkAkNy1B zqN15Gi8sA{8g|ZxJHK~#-~B8|NGywQM8xkkj*#?u7q+_Phl5KijSYMtkip2t$kUWd zY}GX5E)gHG4uas(qhxq~!LjyF0C2}Qb+$}&-*B<@l7k}z3PV=gI8#RxKC9(Ep(J~0 z7I}Q9rA7QAA-O9wxZ!`i0C5VMdZ@D9AB#-!?zhIBaFah%FR#eZ6IbVXt#6?*5^jef z_vTl5mwxp;dd4-mcPDXj=8Ro}jNKa5f_5ZXx`jK(JM!7NIcw`wA-6en?hADM`bDtN zS^wyhK(I$t2p(bVn-IAL?|ZeEjg5`79@BQ#AB11U#B_8eaP2^knB-R~IEgcqmJ)IUZ?Mz+>_?3KE08Tq6qB_-jM3}!2nXo~Uh{G2aSR#wjZQh5ju z{`bZf2OAq(eC?Wd=CVv`=F{(`W>cf?ey7aY%Qgs7I`0;okJ?L&C;d0MpIp&f%*X`M zo0TJCPcricey_cCkvcit$)|Rjh3?!IYa&L;UpqAXW$BGdl&5Nr4g0mjAXHR)J z7-1Zm;mf~j@-PNa;M?pnEj(Tk72cY+LUi_Ok*ZBDOva_?b-{-k( z&&mdeg{^nP5%zKl3TTfjtOI6eXH_1R3q?$P?JBJlT(TSeOiN5c@;W&=yr<{BVT}_y z3JMAqHug7&c?w5~>FLIwh4K15Y*zDh3g4|PuK-TUgFKkOr|-EcdJ_bXQ%Yju={lj2(sFz%1`Qc+d{O9Ckf0 zX->Slep7{J;-f6;YX<1{CdmD`;@(TACyzAQNi)+kCcfIs^Cq@-c48v#%hAZ3ZQMda zeQ2Zf$EaLV|BL;f%F1l1yr?sBG!(bLll_VC=wkEo*xfxmOn<%?&TKR_HAN-|t$c0m z7gM#ut{Y<+eCkR3C_qFUoSa%fI@|fdmcBB9NAk6aT?V%;GHlLku!oRr_R95z()!_( zW@j2*?ER>6^cza~>ZW-Gg5ALZG($x0RjNeUR;T!1a=%Dq< z?=Afl@Z7iFUmfhUFm$Q@I-mEeiUe(^H!zszPCC00TTipTg52xb{n>9%j?d8j$< z3mpXh@={@rqI5d5iWQ6Qgj7%El{EIC9Fb@NDLG)$NJi(TFpNCaqgOAgs9*z}VfcA* zHs|%5H->i5obB}OV$Q(lClclKyLjPIQEhXrVF!PP3-!$5)S20nT{bOOH#hP>YB+d! z3IOhT4WX+EYnlloBjX>V!g~GM{~h~up=ZQ^u0Qe7OL>w4bG15COP8K9GvN6H=iYvU zJKe`#G&eKT$W^0__YGv2-RqSZO*9TpN1tyG69|3MUA@X!=wzW`9Xo%@qTfe?w|3pZIGIcj@K+T@zRo5cKuNw(XCrcm5<;Fbw zH8~To2nor3jQU?ECB15EQ`nekq6huAqa&KSuo+pq^SjM=aa{t*Z50ae6-k-L2alK~ zjbHAjHOt3g5it|rLqj2!y<;}-BkAqlv`s3F{dxLc^TCI3&j2j(ox6NCju`WA^zRRN zgj+u4a%7XHbX$o3hPapTYsJvBPV;okq>AZJ4?wl_{yVOrqHW5V&Qt`dE**jx=)!nK)D7jCfNJ!*VWB z$gf`y7%4XRFr=rDvN2NpLHP+V8tVtn!66|TKw2_umy_?%@lSo-9e+GPr`>TuNF{{z z`t|Fa!w{?+~Ro2z)^;vg1n$Go3 z5(S;OloUHBx%D(DF9;t-iex(UWW0vfxthzNfy_efDdwmB<|(BU9Lx4D+s?Yd(k-~9M+H%xU4 z;jfly%Zk@@VPvtMk%mU?3!$Bk+<9W}HFQwb*(h~G;(0VXy<~6e)D-QL+Lzw|jyS9h zaa7mUC5o#ty`BYPK_TNSnUb11x3m-rCr+CDc*BzEYnYK6%))I@g$HtG-lK9>;4qVu zlL~2~s2F(7AXO6)6JMjIriK8tDitH{vc~*=9aLzt;zvd*6aRfoBNtGnI2x;QW@~9} zom*HytuZ8km$9)i9*rnb7y&IZEIsH*IIQQkTpP+4_1I;G4-Or#v~3+3A=Anyot~bi z;5R|2rHBTEldwf})ZdfARX7L~*gU&vdR*B)>Bsjif-h_Pcj9`PN&nN82|spsSvHe~ zefsuS))u+-*L|vin!~ydMeGxQkTXlQ;=bfht)`qxJJM_wl2Znu(P~b*|g-h@q9`rNqYv z4YB=jKP+;J&0iKJFq&?3a3W6Uf46^pos1_bIz6*eIggf>w#@1$6&}5GN+XI$rrXwZ z5(FR5gEgJuPj4dw1FtD4Dw=|a`Ba>qo<2Sv6?@(?YLO0D zQP-)c9uI#?VgXG`#C{s>&uwl-L$E}?O#s^`79>_^)^(kP1T}5BACy&ZI4OkUwjBilt+@7v zcsqQqLhceUAJUShOL4^P>A|}7KsGjVQf_SE$;il@?+>bzO&NG>cpLR*Gf(gtR{KNm zg*iwqoe=rrQd9A33}YTw+GLn_#w0;UmTT9psZ8nF5>Zn}!ojI?&?>6eQYsM6T#J>t zdbYUyy)0;#*D~AdCM|H-Cp=?z8^)KsA%VM?18x1uTiCPgfA@5=Ob2pDlq zG&mFPy=ubLkquBQEF^^@QEDpfxh>|aX;Eiq=k0|{DR=u%x{?V$ELKK}sewI&1!4N; zNd~>*l;uq{c&TFK$Y}nrfbzDd%)E0ylMK<5E<+Ej5fjnY-j2NWyM?;NDk(Ri2m}(F zf|*%n<6k(%zO=0D+wsl&?{*}>^^zb8ND3<@7Zis~P zmI)lsEeh-=Ayw!BQJYL`;`G(j^fX{*dwYpkj}=y~Go>Y&hMjSK4NXTy$4uCi)ZVY1QBMjcZU zA{knb^oHL2u)xB?6U4sR^Yf=-@2`^8RxE?Bd0~@L?mh1XWVgN)Yjc(Xjo$4#4HI;j zZPq$N!^AY7uJ`EuMumi&$IGTkLPq4f^b{0%C1-G0lS=9W#5g9D_Q^3I-XE~oJ3u?= zSFU7ngr$r}Cpo4tB$)m2BLbPdPxh8k5Mb3J3Re^dV8J84n9U6!@jG+aLb1VDIF`zL z=<^e5q-q2OVxH4XwJ_n0qKK!0z$0Jhx$G_~gApP^j{laRV8MfzgtA1#L5W6V1O4Ss z)nOa^%H<5jz7_R7H0;2&u;#%*%)mB=)e@jC!oT=rM$%3_1e;Oz%_EuobnGesW80N5tsHlbbXX};dEHku*s8hw8W^Rvasx) ziYHz|ErO<``?{_pGFwd9hNBfJWjxR*|HL&?@+gD66e+UV9GLBIoKt;%0_U-p(Mfy1 zf}4qdbwCXDOC@hOjmjDrgw1dPdh&e?2qG&hugG{Fo6NO@i29rgrKF@3jBEeH_O76< zn8Iv2b%LHZ46pC;14;IoLZVFomRidY32qS3h%yw^c^(v8dcrXqnN@%z82R|r`NUUY z3cgjW;(Jm{>fzyW>eLxS>v(nP!_3MWK|rUOuMMY%P$H6oYkQIeP@g?}_9`lh`{6f!!cfwM5}rzO45e{{Z*en~Lv-;+z}{^pH^)0Yh1^OBXg)=U~h-WPwt z96%m&SW_c9tL&+Z?qrt0_m*fjj>wN(Ozih~R@=czqls{T7loG>CM*jR=8F{~$5Vt`NZ3AGcuw`OG`tMEv%`@ zFW)s$0X{7=D+{TG(MWj?+5PQ>T`VRORnV9>q7InHt|9tm}_yWSQ__-Cv@;T`v*Ko-?^CS7kij@JrH99G6ys%vW&lvRiY z1qa&1%J6nyp!DHtst*pvC8x!F3}sX_eU)4@KKb|$@fW6dci%S+jPtYGd>fLu; z-3yfE4t#_g(t=TGvhEq7ue=-P)CA`=9D* zU@32?=_`annp($2R0xl`p`jrImRz_G@;06RsGLLd!pz|HKa4CairSxHv@gf?&y`hG zQ4#Tz>U4DDsOfNvAm0d4J*e4y4f$ZSgdQ>=<{hqzpC3dBy^j74AA$N;X3cB+`=mbo z2UIAdAy+c+^8U)^f#JQn*zzkwIzy)F5*tleuv%>5N_BA7M~Yhk?DZAsa6w^{UUb)h zMzXI zGmx&fax7Csx_Ypuxex zCP*Z1+C3m?F!E*3Lxu!UreU=MO4Io+E)qXNvYLn7=)Suc-WUs=L!tH5-4@U&b%TO= za8JN%fr3EhP`eGwb09Zk!PXYSy$zHWmt8{5fg6*QypQ~1*>eTK)&%d1~$qf@iAK2~cvz6 zUoXTW$jpdNM`)7pDbGGvEfs;lrxGH@YSX%rx4r*NTvCrt_%WXU8+gzO8zQiW#Q|?}e~&$$8u2E~Se8 zXC!vKfAsXUU0ohE2}b`eGskQ^-&GYA6@6>_z+62mE-udLXVyY1p-dZ+WE*L~1qTA6 zRF(nEM<{)aKoC(ogkhedd*0N;sIwcYnuG||w}lQ$)NYAub?^g>gY zN)K;&K;^{YbpM&p2>{)8P-fy15?IzoVY%QGgRRUID>Xu24LP||Hn=NnjL1_bM3gix zLSX|Zw!0C64>)u!35f^RwUVYKbQHI($(Cr_S`w@UhqFVMY-#0C2GW=tX!p>JCelaK zvaO@zv88N07)7(oR)ktSW$_(0zB3BhF6PR-c4*0K%rovp|IlcVD^tS^#X}gFih;k^ z|6`od`BC+JLgB{`h=bhXm1;+8lQrdy>aMO;>^mNh!e71OH=rjYvvN8P$#~v=orWfA zbK>gg`$4NYw? zHjmkrj)&6)ny06YjOl<1lH!E0PXhgTuV3S2DaON!704eFT#S>cmA@@?6Lr(r*8kPz z6Qc2I4moO(5Cx|Gh({q;Drk-OHaP3wtxN>VX%^o5KG4bkE(mN8nk7c4ulv%GVWByA})FsOAvZ(?RM|C%I|3nwI6{Fy)xGjV0MY35hI@QIZD+TVJY~Z5;glXHraD| z>xn9!cf3z*b~nZUKR6$e5-BMu11BdA1jfP9ljGx8PKFIw+T;?(%x3210(N8kU{=a6 zc)*C2N#T3GbGOL2i4HLPpR^z+yGN8yqGUQ9SH^PK8qY5MOrjY7?zZFnT%Vf@f6x1w zmF+{@IZd<{^Ob(zsm(o@ftGzyEYV_fry~-@=c~#U{Dais`_P%*B<}ZcL;(HTP24WC*+zr zTYYrRo=gDrsvhPl%cIsHynVZBHcE~}#J7%MebhTkbFU?|PVfH^?@$dJ%cX6fv97F%}9&OcoWB*-y|9M*h3$xvS2O8d^aO0a} z%5OcL&sX&$0=^uiI7lLbEJ`DNFzp2M>6lRd{ok*X)fR(+2d>x&`a?gUk0PUn+JXm6 z1t|abXQJ)MW%OHb|B~361z|wvInGX?JTf8w@8|H*P(_EjJGrrU0H`3%t*xj|H6Y-VzIgEhNrG-a zA4iK;GCwFA#<8*lD@|MD=^B@;Vvg zT>qIWf*6cAd7sp_{j*#|fwX*R$pI2PHxpClm`9W`*w`#>Dr?&gpgB%tu?&R8oXKSv zkDjXTKf7kjNZkz=7nfu>nqJ0e#<*Cw9B%4X%!0~fJT?g{e}amonX{1*9kuvN>wGWH z_#b0X$@w|`RV&}(=G_=>mzeEshr|8Vhy7zBiiq+_1B*vFSU`2G z33mUlS@+7O3po^^P&}Tz3ZwUJhLVxWMtnkoj-3w_n+664yDiKWL2YTTq6G*^&SykA ztf-{4R$#{_jta{>wJ2XoceyPo;@|%GEp+>nf)6|sr9HjJPV4nwnP%#OTCimchf!=1WWq+Q+ zC0JFfS-+3mL-5~M8}3gKl^p&~iuK!q6WzM+BMM>`PTOm#+iK*Za=tu2Azn88VuAf$ z*cJnE4B{KotFC#5%%HX-+=XMkj)vizASZK_O|`e9g9rI87~Q}Zb#MSj;0f;xJ%)d3 zX=&LXg_KQFc~?tj#|{d;;R1>)H2`C|M`OswMt}# zavkd5P{;94N}{lvsvWlI0r;TOv zM2orzvd^ngg}saDJ#fo-=zoHkpPLa0L$6g+08C21i^GRhgzol>3+V>2vddr z86^@&By>X@nBCfng|?m`5kfD{2G;9{?m6$<6kwU->ZEd93c4ueFl7)>8 z6Jq%>s2~C!yB0tVXJMfxeEFAKl5XC*MIz;O`0wd}jIjXgj%WC0Av3763|OaM9v9zU zH8(eZ`1eG$1?&Ytu$mWt#5=AIuk+88hX~l8^oE^d$Hx(*sMQjX z(WAjVKzyZU8D$EEMZnHEd5uiwh182>Iw&uu>%##jv`kD;gW2;NEKM#UW6(k1-a?Tn z1u1a3Zcrdg=im&2ngxha^8iWQVW9(rmV%IJu&QQcRCIv{?u=Jm%bQA>~PU`G6*sx$d^4Q#PV z%n_Bh0e>a&n+E=#q|-rZ=mn5+UM`>}O<=9QU^`yHf!ItuvHSz__bJI)&!2El=z`oO z`P7mzLFMO&+s4@SuP>&Ehf_rzufb+$6hw-o$ACqYDZytDA(DcL>BOASp!jhO0Sqb= z9w;1E7{cyRpPQT8=m%1}18BDWG@)JwWRp`<{h)eWJd5hM{(MP}uUMc;{0^PLjpq0C zq#$-YE6dA~FV-~&V<(fIVy0bRm=8R(HF-}@apa&>J@5M{i_{3;s<6z@&-0r!Bg!wP zJ(g)LEG>1$$T}$C355byk)|coz2Xc;EH~wh-HyGb+ter8D#YYX3`umZ=q)*_qDGw1z|;P*X!>h zODu5dkiNp8V)$wt%zm&=4*vXuO*Qbe3>&>EL8bwig#)rqFl40JtXOF|utQCI?>*4G zg8ZA@vjd*0d1&YN{rmT3SfdZpY-8!95C~*xedcU$cefP$+VS8lo8%O%dfZaf0}N_R z&)CPZ3g7>?p5mEc2h*i^=apHkFE1k8BDBpgaO~+@vUSv;aj##j=eJJJ*#y z#--U=6W3I@M|~IdsO8vKulgp$ta>Px78Y6o=I`z7n8JEC#m2@yErTTZ6wr$mh&T6H z$kfS zwjI$Q{)~=Gmb7^b`aZ{>!1JdTbF#?ak^vgL0b%{r(b)GS=l7ACd?*2}&A?N*cCv=1 zKY#ut)7qaywZsloB&(x>`lG`yL{wB=064XWt%%xG+re(EZ*6T2U(fmO^10UJ)~;^x z;{@A!l^o8|Q^;_qWh2$S5x+Evp-$V_esnPHwUr#THC&k3zTlDe6lS|XvN?F$$$Fs% z@E!E0Rtj@Fu)|n-^3M3475n}KAUXZNKr+UL&kpd>ZJ5^`089vNT7t1zul91XvrCnt zsS-}(qS3>?TxN1aLyhGFtqcr{W)nch5Bt~A0$jGHr)<2;{$9c!0OWj1Dl9Dg?Exi- zc7QX#Vai23;bLYEhNMw6CJeg)eo0D7_QVu}&9}~d$1K11W5pT&#>2Fy`mYH$I()#3 z&I@{>(Tx;L0vi5_CNO~OR;~m4u{x`GHrQd& z2r1X#oK6Uk)gyFYaY6!fa&ry#)5M@O7r9A{_HBdQ;!nfZ zM9}Q8=1=y%U>N`nun)B$+NWcaLTg@y%q*H{$g zEtRQm&{vW~EBHI~p*dYyx(uGNQ%#Bw)a_D~s!|f~xFirZ?PM>1{eF zB4cBp!o7gX;0twl%MA$8+!7KK1;~-FeYx5K+W}QlI)D7gAF704ti2>P)DYElqtpVq zEdD#Vn^jd+tS&4b{g0@Tcbwkd&184u$mnfSlC|qEFhqUW+=AkaP94;#e;)2^ZxbDy zfd%Km>C3I@R2F9D((G*JktRRCc-K~Y-?RNy^8sHdd3I2kkCqsVJR9_QnP7DVTZ-?G zOG!!nhKcgX#-`x63uvJ(h0_z=h<^@ek4JFF6cS#C-0Oq6gw8H5mc-$~H8nM5fW689 z_3^_X0dcbs^o50DH9D#|ct2S%WH|p}*pEL>OY7_1P+9GSVyNu_@=3fyN|3j0hS+t# zzIgIUgFOkr5H1#$2>?ASNFyAMMM_zw$W*#M()FqfdbyxbhVa2R&W!qSa`C?7f1 zBwrN3{PwW0yH;N8a6OzWvGhsQP(Y&WkfB*h*$5hF2n*O?2vR5S}&o*Irs$*~kV_?cjYHDgyJ_AdD z3XT1JWuLB7Jg(D#h6%18tllM;ne;UmAZcR(YAAX(oRGn!A_h$T|ed9@}K!?7z_FLr%i1?2;q$r3f zDW45o0xMdd0FCH}q?FVnKpMXT(Q(HBoIhx5i}>GXo6igSLw%3F{8+)rj|Cu8wr~7j z0+q(X#gzwggVfmsSvfgX{8Cd>d2HhEF(Wr#0E)REGb!ozH>ENC^DmlEb8Z$XsVTb# z=vvn9ypp$)MtT=8zT?TRrGv78E8JJ;1YL-X3v-70HXZ`!UGL$&ro?P&2I51sMS` zwNcRf6=zjjtZ*h2jMZ>I_-+eeQQxAZ=3x#z^?h5|crcND0l5DZX=Qp(Q}S8DqyHGK z17z=c7^1Ij-sP??s{@LDv=kJt!U*Xj-YihjXBhQ+-TcS1*!hMZj|sX(Rn6_B02&r~ zCL-wpMB-iM?f)%8$gs7r_pMH5|F3wrY)?Vg$U;}8pxxfE9 zU=XeIJTA!wX9cHrCItUqxmJ2sqc^El3l>K-TRFD=1%`>362Wv1G|Hy8;TE!v7AhIV7L55NF+nk#-9e8p4&30$L9gOjr zu9c6Y0o#IQgbE1xT|kKZz{pjk-q%(Wu64-ufwY9g==VR|#s_gK>o?)Rjj8x~m^OoO znw?m}c;}=z%Vq}DfMtXLI6gQ{I-9+y&x<15pp|gtE)fF^#>WC~L#y?x({;Y`gLWUr zfjrHdg}>2~{I<~Vw=;$-Xf4$Y4h$�gFX=7ht58MxV3omHwMPsSH@G7b-0&PYoW) z9O*Ai|9eghU9Gr`c9dZkk5m-|MPf~>?*NuZN&)jVmXe)o!-dG2WZ{@a3pM~{ zGf7r1uENQxq%1+{(ovw3^-CZx)W3bXKJwG9p@!eP*_%QP0pWM5z_q=tEveXkydpo( z?iVg63rqXPGQ(82XbN)QGV2~BCk<_gixTw>4Lnsd!^6Ybyio3*-|=_(8~snZ%#^Gr zYSHx&__c+2)nL)%(L>?aXFJm<1#mS80{b~AE=dw@ya4NL1z!N?&@CO4L}oz)`*T?j z&=4}eXyv!TR0{+sy0TtW#-cYl`;XF;Kk6gNE+RKKHzfR5ea9{E!MV#YDL{-b zZP)t@b{^l0kGps0!~R90v2Os}GkAQ;Y)5&^7j7~!?T?O3#xF;k`j)~(ZOxwIM{A#? zzm1&KN*z~U-S`+aeH;;;ep$Ev6vFxcq&I{gT$5*tVjj2t7)23NNx^hqh>`Qnmlhm3 z!wL>hq7VvF-X29lVq5b4kC|l8Za>q$$HU23im5Q0IpcR-McmEmZ&cP^)8R$)6VYWy zzh%Sz^m>{C-yp$ETGCCK;bS*+lIFJ%>#HxUsytqt`M&$wW!3`*PD*zD%J%{HS@($Ktx z?RG!0E4$< zXJ8jVN)$e9SFkAe%*_k{r_CzlF1+rxHm-8{dn6Kw4)l(qzQ;xJqQ^1=4-_`<@%DHKWKmWqpue{LnA z(!$%t!MXKX3|r{P>a#k#OH>zZ9&s@-xdU=ZE^H{-=K!F(sC@=Jt8|HL()M`q2T8go zggSA4{*M5ohCyjPeygXe8!BYH2k_z5;$`PS~4>ZC619T ze_$s{+@J5<1#fMm@5Oj&Q)np0;02gG@87+97yrz$ZYuQoV*`T+(WXE>EX6+qeFWv^ zZ%Xv@3{GC&k&KKC>oAn_hoPaN71hb6TT%=#MVNI5SYna~h~!51jY%LnD3!p59|nHj$I(UKz$TsO7MpDR0ZuVp?A zfYPhx^)kD%a(HWL9VUyoxVQyC0@+^5E@4T(%le^_5sb~j)t6oHbjE1t5K9`Ws*&}6 zS4O->_3SUc8sOmIFhfFv8Ywd`uNq8|oG)Lr0B*9-OMAxwuonxzDJ^XTnxF+lc_#oG z&`dRR6>b-k$P`kRPt{z)$$P3yZQCKUZYuyuo$2mns_s1tDEZyD5wgrxrVNj&) z8F;z4;$in#X-64Et{R`SD%fTCaBXdkSwut+gsJuyUsY99A^`Cz!5sMm@lVUxSSHsT z6@kD~4t`_zaLKEEBs*6XMTBUC}bV?Dj6YiDdjwqt{XS-gq1 zYxOW-4KhwbOiDj*00@IrfdIxoSjiH z!~ORY;@$tZpM*+2bfU(O-KYKco*pu;s{g#%M49>j$DitNTu1n$&q8@Z5FpSdKjIkT z;Pp)+1VTUVo*fFp#1XD>gwup8XKkGJh}FY zKX;IWkWMlV=9zUE^7?zi%gO{e`1le*Z-BpH@Q;Zh5CcLows|vc>_0b%SVDz6_;=CG jZ;;=I{Pq9OPnW32ui`iOEVgQppP;O$rtn$LB=G+MOu5pD literal 0 HcmV?d00001 diff --git a/docs/src/man/introduction.md b/docs/src/man/introduction.md index 3fbddbb..b3487ed 100644 --- a/docs/src/man/introduction.md +++ b/docs/src/man/introduction.md @@ -1,5 +1,5 @@ # Introduction - + This project is developing a software package in [Julia](https://julialang.org/) for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BBB) From 5825cd2b142143e264a198163dac5041497b30f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 14:24:16 +0200 Subject: [PATCH 16/47] fixed dead figure link. --- docs/build/man/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build/man/introduction.md b/docs/build/man/introduction.md index 5ed1fc4..4374052 100644 --- a/docs/build/man/introduction.md +++ b/docs/build/man/introduction.md @@ -4,7 +4,7 @@ # Introduction - + This project is developing a software package in [Julia](https://julialang.org/) for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BBB) with custom [IO-board cape](https://gitlab.control.lth.se/labdev/ioboards), or the old IO-boxes in the labs using Comedi. With this package, the user is able to setup a connection between the host computer and the IO-device, and send and receive control signals and measurements from the lab process. From 0db3c5480bba20f58d748138993bb259624cc00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 16:02:30 +0200 Subject: [PATCH 17/47] Updated installation instructions. --- docs/build/index.md | 2 +- docs/build/lib/functions.md | 34 +++++------ docs/build/man/installation.md | 105 +++++++++++++++++++++++---------- docs/src/man/installation.md | 81 ++++++++++++------------- 4 files changed, 130 insertions(+), 92 deletions(-) diff --git a/docs/build/index.md b/docs/build/index.md index 9ff9ffc..5d7908c 100644 --- a/docs/build/index.md +++ b/docs/build/index.md @@ -42,8 +42,8 @@ - [`Base.read`](lib/functions.md#Base.read) - [`Base.read`](lib/functions.md#Base.read) - [`LabConnections.BeagleBone.assert_pwm_write`](lib/functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) - [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) +- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) - [`LabConnections.BeagleBone.closedev`](lib/functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) - [`LabConnections.BeagleBone.export_gpio`](lib/functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) - [`LabConnections.BeagleBone.export_led`](lib/functions.md#LabConnections.BeagleBone.export_led) diff --git a/docs/build/lib/functions.md b/docs/build/lib/functions.md index 36fff70..b929ebc 100644 --- a/docs/build/lib/functions.md +++ b/docs/build/lib/functions.md @@ -2,8 +2,8 @@ - [`Base.read`](functions.md#Base.read) - [`Base.read`](functions.md#Base.read) - [`LabConnections.BeagleBone.assert_pwm_write`](functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) - [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) +- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) - [`LabConnections.BeagleBone.closedev`](functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) - [`LabConnections.BeagleBone.export_gpio`](functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) - [`LabConnections.BeagleBone.export_led`](functions.md#LabConnections.BeagleBone.export_led) @@ -56,7 +56,7 @@ Reads the current brightness value from the LED 'SysLED'. ```julia -l = read(pwm::PWM, operation::Int32, debug::Bool=false) +l = read(gpio::GPIO, operation::Int32, debug::Bool=false) ``` Reads the current value from an operation on a GPIO. @@ -67,7 +67,7 @@ Reads the current value from an operation on a GPIO. ```julia -l = read(gpio::GPIO, operation::Int32, debug::Bool=false) +l = read(pwm::PWM, operation::Int32, debug::Bool=false) ``` Reads the current value from an operation on a GPIO. @@ -103,7 +103,7 @@ Parse and execute the command `cmd`. bbparse(l::Tuple, sock) ``` -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)` and send back on socket (vals, timestamps). +Parse input on the form `l=(operation, ndev, cmd1, cmd2, ..., cmdn)` where if `operation==1` (write) `cmdi = (devname, id, val)` and if `operation==0` (read) `cmdi = (devname, id)` and if `operation==2` (initialize) `cmdi = (devname, id)` and send back on socket (vals, timestamps). # **`LabConnections.BeagleBone.closedev`** — *Method*. @@ -199,10 +199,10 @@ Prints all the active devices and writes out specifics of a single devices. ```julia -teardown(led::SysLED, debug::Bool=false) +teardown(gpio::GPIO, debug::Bool=false) ``` -Closes all open filestreams for the SysLED 'led'. +Closes all open streams on the GPIO, and unexports it from the file system. # **`LabConnections.BeagleBone.teardown`** — *Function*. @@ -210,10 +210,10 @@ Closes all open filestreams for the SysLED 'led'. ```julia -teardown(gpio::GPIO, debug::Bool=false) +teardown!(pwd::PWM) ``` -Closes all open streams on the GPIO, and unexports it from the file system. +Closes all open streams on the PWM, and unexports it from the file system # **`LabConnections.BeagleBone.teardown`** — *Function*. @@ -221,10 +221,10 @@ Closes all open streams on the GPIO, and unexports it from the file system. ```julia -teardown!(pwd::PWM) +teardown(led::SysLED, debug::Bool=false) ``` -Closes all open streams on the PWM, and unexports it from the file system +Closes all open filestreams for the SysLED 'led'. # **`LabConnections.BeagleBone.to_string`** — *Function*. @@ -232,7 +232,7 @@ Closes all open streams on the PWM, and unexports it from the file system ```julia -to_string(led::SysLED, debug::Bool=false) +to_string(gpio::GPIO, debug::Bool=false) ``` Generates a string representation of the GPIO device. @@ -243,7 +243,7 @@ Generates a string representation of the GPIO device. ```julia -to_string(gpio::GPIO, debug::Bool=false) +to_string(pwm::PWM,, debug::Bool=false) ``` Generates a string representation of the GPIO device. @@ -254,7 +254,7 @@ Generates a string representation of the GPIO device. ```julia -to_string(pwm::PWM,, debug::Bool=false) +to_string(led::SysLED, debug::Bool=false) ``` Generates a string representation of the GPIO device. @@ -265,10 +265,10 @@ Generates a string representation of the GPIO device. ```julia -write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false) +write!(led::SysLED, val::Bool, debug::Bool=false) ``` -Writes an entry to an operation on a GPIO, of the form args = (operation, entry). +Turns the LED 'SysLed' on/off for val = true/false respectively. # **`LabConnections.BeagleBone.write!`** — *Function*. @@ -276,10 +276,10 @@ Writes an entry to an operation on a GPIO, of the form args = (operation, entry) ```julia -write!(led::SysLED, val::Bool, debug::Bool=false) +write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false) ``` -Turns the LED 'SysLed' on/off for val = true/false respectively. +Writes an entry to an operation on a GPIO, of the form args = (operation, entry). # **`LabConnections.BeagleBone.write!`** — *Function*. diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index 3ba1d5f..99b697b 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -4,12 +4,38 @@ # Installation instructions -In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black (BBB). If you already have a prepared micro-SD card for flashing a BBB, then you can safely skip the first section of these instructions. +In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black (BBB). + + + + +## Host computer setup + + + + +### Installing Julia and LabConnections.jl + + +To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified [here](https://github.com/JuliaLang/julia/blob/master/README.md). Once Julia is installed, open up a Julia REPL and add LabConnections.jl using the package manager by typing + + +``` +] add https://gitlab.control.lth.se/labdev/LabConnections.jl#julia1 +``` + + +You now have the LabConnections.jl package available on the host computer. Note that for Julia v1.0.X it is the branch `julia1` of the package that should be used. + + + + +## BeagleBone setup -## Preparing a micro-SD card +### Preparing a micro-SD card First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BBB. @@ -31,15 +57,15 @@ The final step is to make sure that the micro-SD will automatically flash the De -## Flashing the BeagleBone +### Flashing the BeagleBone Insert a prepared micro-SD card in the slot on the BBB, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BBB. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to blink in a wave pattern, indicating that the BBB is being flashed. After a while (can vary between 5-45 minutes) the BBB will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BBB again (otherwise it will start to flash the BBB again). - + -## Trying out the BeagleBone +### Accessing the BeagleBone Now your BBB should be ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing @@ -61,79 +87,94 @@ The default password is `temppwd`. You are now logged in to the BBB running Debi If the Julia REPL starts up correctly, then you have a functioning BBB ready for use with the LabConnections.jl package. - + -## Setting up the host computer +### Getting LabConnections.jl on the BeagleBone -To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified [here](https://github.com/JuliaLang/julia/blob/master/README.md). Once Julia is installed, run +To update the BBB with the latest revision of the code, ``` -using Pkg -`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)' +`cd && cd .julia/v0.6/LabConnection/util' +`./flash_BB.sh' ``` -in the Julia REPL to install all dependencies on the host computer. The source code is then located in `./julia/v1.0/LabConnections'. +This scripts bundles the current code in LabConnections (and serbus, see SPI development below) on the host computer and transfers it to the /home/debian/juliapackages directory on the BBB. + + + + + + +### Setting up automatic communication -If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus' repository which wraps the`linux/spi/spidev'. Simply + +To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system ``` -`cd && cd .julia/v0.6' -`git clone https://github.com/mgreiff/serbus' +`ssh debian@192.168.7.2' +`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) ``` -to get the latest revision of the serbus fork. +Then execute the commands -To update the BB with the latest revision of the code, +`sudo systemctl enable juliaserver` (on the BeagleBone) `sudo systemctl start juliaserver` (on the BeagleBone) -``` -`cd && cd .julia/v0.6/LabConnection/util' -`./flash_BB.sh' -``` +After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. -This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB. + +## Package Development - + - +### LabConnections.jl Development -## Setting up automatic communication +If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type -To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system + +``` +] dev https://gitlab.control.lth.se/labdev/LabConnections.jl +``` + + +Open a new terminal and navigate to `.julia/dev/LabConnections`, where the package source code is now located. Then type ``` -`ssh debian@192.168.7.2' -`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) +git checkout julia1 +git pull ``` -Then execute the commands +to ensure that you are working on the correct development branch for Julia v1.0.X. -`sudo systemctl enable juliaserver` (on the BeagleBone) `sudo systemctl start juliaserver` (on the BeagleBone) + +### SPI Development -After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. +If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Simply -```@systemConfiguration +``` +`cd && cd .julia/v0.6' +`git clone https://github.com/mgreiff/serbus' ``` - +to get the latest revision of the serbus fork. diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 29ccd14..193b545 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -1,9 +1,20 @@ # Installation instructions In these instructions we explain how to set up a working environment on a host computer and -a BeagleBone Black (BBB). If you already have a prepared micro-SD card for flashing a BBB, -then you can safely skip the first section of these instructions. +a BeagleBone Black (BBB). -## Preparing a micro-SD card +## Host computer setup + +### Installing Julia and LabConnections.jl + +To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified [here](https://github.com/JuliaLang/julia/blob/master/README.md). Once Julia is installed, open up a Julia REPL and add LabConnections.jl using the package manager by typing +``` +] add https://gitlab.control.lth.se/labdev/LabConnections.jl#julia1 +``` +You now have the LabConnections.jl package available on the host computer. Note that for Julia v1.0.X it is the branch `julia1` of the package that should be used. + +## BeagleBone setup + +### Preparing a micro-SD card First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BBB. Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). @@ -16,10 +27,10 @@ The file structure on the micro-SD now has the correct structure. The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BBB when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing a BBB. -## Flashing the BeagleBone +### Flashing the BeagleBone Insert a prepared micro-SD card in the slot on the BBB, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BBB. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to blink in a wave pattern, indicating that the BBB is being flashed. After a while (can vary between 5-45 minutes) the BBB will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BBB again (otherwise it will start to flash the BBB again). -## Trying out the BeagleBone +### Accessing the BeagleBone Now your BBB should be ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing ``` ssh debian@192.168.7.2 @@ -31,48 +42,20 @@ You can now start a Julia REPL on the BBB by typing ``` If the Julia REPL starts up correctly, then you have a functioning BBB ready for use with the LabConnections.jl package. -## Setting up the host computer - - -To get started, first install Julia v1.0.X on the host computer running a Linux distribution by following the instructions specified [here](https://github.com/JuliaLang/julia/blob/master/README.md). Once Julia is installed, run -``` -using Pkg -`Pkg.clone(https://gitlab.control.lth.se/labdev/LabConnections.jl)' -``` -in the Julia REPL to install all dependencies on the host computer. The source code is then located in `./julia/v1.0/LabConnections'. - - -If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus' repository which wraps the`linux/spi/spidev'. Simply - - -``` -`cd && cd .julia/v0.6' -`git clone https://github.com/mgreiff/serbus' -``` - - -to get the latest revision of the serbus fork. - - -To update the BB with the latest revision of the code, - +### Getting LabConnections.jl on the BeagleBone +To update the BBB with the latest revision of the code, ``` `cd && cd .julia/v0.6/LabConnection/util' `./flash_BB.sh' ``` - - -This scripts bundles the current code in LabCOnnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BB. +This scripts bundles the current code in LabConnections (and serbus, see SPI development below) on the host computer and transfers it to the /home/debian/juliapackages directory on the BBB. -## Setting up automatic communication - - -To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the lates revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system - +### Setting up automatic communication +To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system ``` `ssh debian@192.168.7.2' @@ -82,19 +65,33 @@ To setup automatic start of Julia server on the BB, make sure to have completed Then execute the commands - `sudo systemctl enable juliaserver` (on the BeagleBone) `sudo systemctl start juliaserver` (on the BeagleBone) - After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. +## Package Development -```@systemConfiguration +### LabConnections.jl Development +If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type +``` +] dev https://gitlab.control.lth.se/labdev/LabConnections.jl +``` +Open a new terminal and navigate to `.julia/dev/LabConnections`, where the package source code is now located. Then type ``` +git checkout julia1 +git pull +``` +to ensure that you are working on the correct development branch for Julia v1.0.X. +### SPI Development - +If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Simply +``` +`cd && cd .julia/v0.6' +`git clone https://github.com/mgreiff/serbus' +``` +to get the latest revision of the serbus fork. ## Debugging From de0b9dc8c4c32723e36f5c73973c4782ca1e3859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 16:06:33 +0200 Subject: [PATCH 18/47] Added dev page to docs --- docs/build/man/development.md | 47 ++++++++++++++++++++++++++++++++ docs/build/man/installation.md | 49 +--------------------------------- docs/src/index.md | 2 +- docs/src/man/development.md | 23 ++++++++++++++++ docs/src/man/installation.md | 26 +----------------- 5 files changed, 73 insertions(+), 74 deletions(-) create mode 100644 docs/build/man/development.md create mode 100644 docs/src/man/development.md diff --git a/docs/build/man/development.md b/docs/build/man/development.md new file mode 100644 index 0000000..aec7e66 --- /dev/null +++ b/docs/build/man/development.md @@ -0,0 +1,47 @@ + + + +## Package Development + + + + +### LabConnections.jl Development + + +If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type + + +``` +] dev https://gitlab.control.lth.se/labdev/LabConnections.jl +``` + + +Open a new terminal and navigate to `.julia/dev/LabConnections`, where the package source code is now located. Then type + + +``` +git checkout julia1 +git pull +``` + + +to ensure that you are working on the correct development branch for Julia v1.0.X. + + + + +### SPI Development + + +If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Simply + + +``` +`cd && cd .julia/v0.6' +`git clone https://github.com/mgreiff/serbus' +``` + + +to get the latest revision of the serbus fork. + diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index 99b697b..21b6b3e 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -45,7 +45,7 @@ Start by downloading the Debian image [here](http://beagleboard.org/latest-image ``` -mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' +mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia ``` @@ -130,53 +130,6 @@ Then execute the commands After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. - - -## Package Development - - - - -### LabConnections.jl Development - - -If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type - - -``` -] dev https://gitlab.control.lth.se/labdev/LabConnections.jl -``` - - -Open a new terminal and navigate to `.julia/dev/LabConnections`, where the package source code is now located. Then type - - -``` -git checkout julia1 -git pull -``` - - -to ensure that you are working on the correct development branch for Julia v1.0.X. - - - - -### SPI Development - - -If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Simply - - -``` -`cd && cd .julia/v0.6' -`git clone https://github.com/mgreiff/serbus' -``` - - -to get the latest revision of the serbus fork. - - ## Debugging diff --git a/docs/src/index.md b/docs/src/index.md index 02d150e..0db694b 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -5,7 +5,7 @@ CurrentModule = LabConnections ``` ## Getting Started ```@contents -Pages = ["man/introduction.md", "man/installation.md"] +Pages = ["man/introduction.md", "man/installation.md", "man/development.md"] Depth = 1 ``` ## Examples diff --git a/docs/src/man/development.md b/docs/src/man/development.md new file mode 100644 index 0000000..3250b92 --- /dev/null +++ b/docs/src/man/development.md @@ -0,0 +1,23 @@ +## Package Development + +### LabConnections.jl Development + +If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type +``` +] dev https://gitlab.control.lth.se/labdev/LabConnections.jl +``` +Open a new terminal and navigate to `.julia/dev/LabConnections`, where the package source code is now located. Then type +``` +git checkout julia1 +git pull +``` +to ensure that you are working on the correct development branch for Julia v1.0.X. + +### SPI Development + +If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Simply +``` +`cd && cd .julia/v0.6' +`git clone https://github.com/mgreiff/serbus' +``` +to get the latest revision of the serbus fork. diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 193b545..3af1af7 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -21,7 +21,7 @@ Start by downloading the Debian image [here](http://beagleboard.org/latest-image Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. Make sure that the Julia folder has the correct name by typing ``` -mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia' +mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia ``` The file structure on the micro-SD now has the correct structure. @@ -69,30 +69,6 @@ Then execute the commands After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. -## Package Development - -### LabConnections.jl Development - -If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type -``` -] dev https://gitlab.control.lth.se/labdev/LabConnections.jl -``` -Open a new terminal and navigate to `.julia/dev/LabConnections`, where the package source code is now located. Then type -``` -git checkout julia1 -git pull -``` -to ensure that you are working on the correct development branch for Julia v1.0.X. - -### SPI Development - -If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Simply -``` -`cd && cd .julia/v0.6' -`git clone https://github.com/mgreiff/serbus' -``` -to get the latest revision of the serbus fork. - ## Debugging From ad219552d7d969796e27c53ab698b0a135849367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 16:15:33 +0200 Subject: [PATCH 19/47] Updated index --- docs/build/index.md | 2 +- docs/makeOld.jl | 30 ------------------------------ docs/mkdocs.yml | 1 + 3 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 docs/makeOld.jl diff --git a/docs/build/index.md b/docs/build/index.md index 5d7908c..862628d 100644 --- a/docs/build/index.md +++ b/docs/build/index.md @@ -12,6 +12,7 @@ - [Introduction](man/introduction.md#Introduction-1) - [Installation instructions](man/installation.md#Installation-instructions-1) +- [Development](man/development.md#Package-Development-1) @@ -62,4 +63,3 @@ - [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) - [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) - [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) - diff --git a/docs/makeOld.jl b/docs/makeOld.jl deleted file mode 100644 index be2ee4f..0000000 --- a/docs/makeOld.jl +++ /dev/null @@ -1,30 +0,0 @@ -push!(LOAD_PATH,"../src/") -println(LOAD_PATH) -using Documenter, LabConnections -# makedocs() -# deploydocs( -# deps = Deps.pip("pygments", "mkdocs", "python-markdown-math", "mkdocs-cinder"), -# repo = "gitlab.control.lth.se/processes/LabProcesses.jl", -# branch = "gh-pages", -# julia = "0.6", -# osname = "linux" -# ) - -makedocs( - format = :html, - sitename = "LabConnections", - pages = [ - "index.md", - "installation.md", - "systemConfiguration.md", - "testing.md", - "examples.md", - ] -) - -deploydocs( - repo = "gitlab.control.lth.se/labdev/LabConnections.jl.git", - target = "build", - deps = nothing, - make = nothing -) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 47530e9..30f1baf 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -29,6 +29,7 @@ pages: - Guide: - Introduction: 'man/introduction.md' - Installation: 'man/installation.md' + - Development: 'man/development.md' - API: - IO devices: 'lib/io_devices.md' - Functions: 'lib/functions.md' From 556b5e7f5a6aa353e64c9c643559951ad6872dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 17:20:18 +0200 Subject: [PATCH 20/47] Minor change to flashing script --- docs/src/man/development.md | 9 --------- docs/src/man/installation.md | 23 +++++++++++++++-------- util/flash_BB.sh | 8 ++++---- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/docs/src/man/development.md b/docs/src/man/development.md index 3250b92..3b66de5 100644 --- a/docs/src/man/development.md +++ b/docs/src/man/development.md @@ -12,12 +12,3 @@ git checkout julia1 git pull ``` to ensure that you are working on the correct development branch for Julia v1.0.X. - -### SPI Development - -If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Simply -``` -`cd && cd .julia/v0.6' -`git clone https://github.com/mgreiff/serbus' -``` -to get the latest revision of the serbus fork. diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 3af1af7..03be1fe 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -12,6 +12,14 @@ To get started, first install Julia v1.0.X on the host computer running a Linux ``` You now have the LabConnections.jl package available on the host computer. Note that for Julia v1.0.X it is the branch `julia1` of the package that should be used. +### Installing Serbus +To work with the SPI devices you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Open up a terminal and type +``` +cd && cd .julia/packages +git clone https://github.com/mgreiff/serbus +``` +to get the latest revision of the `serbus` fork. You are now done with the setup required on the host computer side. + ## BeagleBone setup ### Preparing a micro-SD card @@ -42,15 +50,14 @@ You can now start a Julia REPL on the BBB by typing ``` If the Julia REPL starts up correctly, then you have a functioning BBB ready for use with the LabConnections.jl package. -### Getting LabConnections.jl on the BeagleBone +### Getting LabConnections.jl and serbus on the BeagleBone -To update the BBB with the latest revision of the code, +To update the BBB with the latest revision of the code, open up a terminal and type ``` -`cd && cd .julia/v0.6/LabConnection/util' -`./flash_BB.sh' +cd && cd .julia/packages/LabConnections//util +./flash_BB.sh ``` -This scripts bundles the current code in LabConnections (and serbus, see SPI development below) on the host computer and transfers it to the /home/debian/juliapackages directory on the BBB. - +This scripts bundles the current code in LabConnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BBB. @@ -58,8 +65,8 @@ This scripts bundles the current code in LabConnections (and serbus, see SPI dev To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system ``` -`ssh debian@192.168.7.2' -`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) +ssh debian@192.168.7.2 +sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) ``` diff --git a/util/flash_BB.sh b/util/flash_BB.sh index cfb7432..d8ececa 100755 --- a/util/flash_BB.sh +++ b/util/flash_BB.sh @@ -1,14 +1,14 @@ #!/bin/bash -#Run in this file un util folder, copies to BB +#Run in this file in util folder, copies to BB BLUE='\033[0;34m' GREEN='\033[0;32m' RED='\033[0;31m' NC='\033[0m' -BASEDIR=../../$(dirname "$0") +BASEDIR=../../../$(dirname "$0") # Dependencies -# LabConnections - main repository -# serbus - a fork of a SPI communicaiton interface +# LabConnections.jl package +# serbus - a fork of a SPI communication interface packages=(LabConnections serbus) # Create an empty directory to bundle packages From 6827c1bd5677244a3b6787a0d4b2c0b95202258d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 17:24:31 +0200 Subject: [PATCH 21/47] Updated flashing script --- util/flash_BB.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/flash_BB.sh b/util/flash_BB.sh index d8ececa..af7a7a2 100755 --- a/util/flash_BB.sh +++ b/util/flash_BB.sh @@ -23,7 +23,7 @@ printf "${GREEN}Bundling...${NC}\n\n" for (( i=0; i<${#packages[@]}; i++ )); do { printf "${BLUE} * ${packages[$i]}${NC}\n" - cp -r ../../${packages[$i]} ${BASEDIR}/juliapackages + cp -r ../../../${packages[$i]} ${BASEDIR}/juliapackages } || { printf "${BLUE}WARNING.${NC} Could not bundle package ${packages[$i]}${NC}\n" flag=false From ae91cb63e236f789c041545b12426389eb85fb4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Thu, 11 Apr 2019 17:28:01 +0200 Subject: [PATCH 22/47] Updated installation instructions --- docs/build/index.md | 4 ++-- docs/build/lib/functions.md | 32 ++++++++++++++++---------------- docs/build/man/development.md | 17 ----------------- docs/build/man/installation.md | 34 ++++++++++++++++++++++++++-------- docs/src/man/installation.md | 5 +++-- 5 files changed, 47 insertions(+), 45 deletions(-) diff --git a/docs/build/index.md b/docs/build/index.md index 862628d..9ff9ffc 100644 --- a/docs/build/index.md +++ b/docs/build/index.md @@ -12,7 +12,6 @@ - [Introduction](man/introduction.md#Introduction-1) - [Installation instructions](man/installation.md#Installation-instructions-1) -- [Development](man/development.md#Package-Development-1) @@ -43,8 +42,8 @@ - [`Base.read`](lib/functions.md#Base.read) - [`Base.read`](lib/functions.md#Base.read) - [`LabConnections.BeagleBone.assert_pwm_write`](lib/functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) - [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) +- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) - [`LabConnections.BeagleBone.closedev`](lib/functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) - [`LabConnections.BeagleBone.export_gpio`](lib/functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) - [`LabConnections.BeagleBone.export_led`](lib/functions.md#LabConnections.BeagleBone.export_led) @@ -63,3 +62,4 @@ - [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) - [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) - [`LabConnections.BeagleBone.write!`](lib/functions.md#LabConnections.BeagleBone.write!) + diff --git a/docs/build/lib/functions.md b/docs/build/lib/functions.md index b929ebc..23f8f58 100644 --- a/docs/build/lib/functions.md +++ b/docs/build/lib/functions.md @@ -2,8 +2,8 @@ - [`Base.read`](functions.md#Base.read) - [`Base.read`](functions.md#Base.read) - [`LabConnections.BeagleBone.assert_pwm_write`](functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) - [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) +- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) - [`LabConnections.BeagleBone.closedev`](functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) - [`LabConnections.BeagleBone.export_gpio`](functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) - [`LabConnections.BeagleBone.export_led`](functions.md#LabConnections.BeagleBone.export_led) @@ -45,10 +45,10 @@ Run a server on `port` that listens for commands from computer Optional debug ke ```julia -l = read(led::SysLED, debug::Bool=false) +l = read(pwm::PWM, operation::Int32, debug::Bool=false) ``` -Reads the current brightness value from the LED 'SysLED'. +Reads the current value from an operation on a GPIO. # **`Base.read`** — *Function*. @@ -56,10 +56,10 @@ Reads the current brightness value from the LED 'SysLED'. ```julia -l = read(gpio::GPIO, operation::Int32, debug::Bool=false) +l = read(led::SysLED, debug::Bool=false) ``` -Reads the current value from an operation on a GPIO. +Reads the current brightness value from the LED 'SysLED'. # **`Base.read`** — *Function*. @@ -67,7 +67,7 @@ Reads the current value from an operation on a GPIO. ```julia -l = read(pwm::PWM, operation::Int32, debug::Bool=false) +l = read(gpio::GPIO, operation::Int32, debug::Bool=false) ``` Reads the current value from an operation on a GPIO. @@ -210,10 +210,10 @@ Closes all open streams on the GPIO, and unexports it from the file system. ```julia -teardown!(pwd::PWM) +teardown(led::SysLED, debug::Bool=false) ``` -Closes all open streams on the PWM, and unexports it from the file system +Closes all open filestreams for the SysLED 'led'. # **`LabConnections.BeagleBone.teardown`** — *Function*. @@ -221,10 +221,10 @@ Closes all open streams on the PWM, and unexports it from the file system ```julia -teardown(led::SysLED, debug::Bool=false) +teardown!(pwd::PWM) ``` -Closes all open filestreams for the SysLED 'led'. +Closes all open streams on the PWM, and unexports it from the file system # **`LabConnections.BeagleBone.to_string`** — *Function*. @@ -243,7 +243,7 @@ Generates a string representation of the GPIO device. ```julia -to_string(pwm::PWM,, debug::Bool=false) +to_string(led::SysLED, debug::Bool=false) ``` Generates a string representation of the GPIO device. @@ -254,7 +254,7 @@ Generates a string representation of the GPIO device. ```julia -to_string(led::SysLED, debug::Bool=false) +to_string(pwm::PWM,, debug::Bool=false) ``` Generates a string representation of the GPIO device. @@ -276,10 +276,10 @@ Turns the LED 'SysLed' on/off for val = true/false respectively. ```julia -write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false) +write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false) ``` -Writes an entry to an operation on a GPIO, of the form args = (operation, entry). +Writes an entry to an operation on the PWM, of the form args = (operation, entry). # **`LabConnections.BeagleBone.write!`** — *Function*. @@ -287,8 +287,8 @@ Writes an entry to an operation on a GPIO, of the form args = (operation, entry) ```julia -write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false) +write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false) ``` -Writes an entry to an operation on the PWM, of the form args = (operation, entry). +Writes an entry to an operation on a GPIO, of the form args = (operation, entry). diff --git a/docs/build/man/development.md b/docs/build/man/development.md index aec7e66..256b57a 100644 --- a/docs/build/man/development.md +++ b/docs/build/man/development.md @@ -28,20 +28,3 @@ git pull to ensure that you are working on the correct development branch for Julia v1.0.X. - - - -### SPI Development - - -If you plan on working with the SPI devices to debug the ADC/DAC, then you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Simply - - -``` -`cd && cd .julia/v0.6' -`git clone https://github.com/mgreiff/serbus' -``` - - -to get the latest revision of the serbus fork. - diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index 21b6b3e..9d27023 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -28,6 +28,23 @@ To get started, first install Julia v1.0.X on the host computer running a Linux You now have the LabConnections.jl package available on the host computer. Note that for Julia v1.0.X it is the branch `julia1` of the package that should be used. + + +### Installing Serbus + + +To work with the SPI devices you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Open up a terminal and type + + +``` +cd && cd .julia/packages +git clone https://github.com/mgreiff/serbus +``` + + +to get the latest revision of the `serbus` fork. You are now done with the setup required on the host computer side. + + ## BeagleBone setup @@ -87,21 +104,22 @@ The default password is `temppwd`. You are now logged in to the BBB running Debi If the Julia REPL starts up correctly, then you have a functioning BBB ready for use with the LabConnections.jl package. - + -### Getting LabConnections.jl on the BeagleBone +### Getting LabConnections.jl and serbus on the BeagleBone -To update the BBB with the latest revision of the code, +To update the BBB with the latest revision of the code, open up a terminal and type ``` -`cd && cd .julia/v0.6/LabConnection/util' -`./flash_BB.sh' +cd +cd .julia/packages/LabConnections//util +./flash_BB.sh ``` -This scripts bundles the current code in LabConnections (and serbus, see SPI development below) on the host computer and transfers it to the /home/debian/juliapackages directory on the BBB. +This scripts bundles the current code in LabConnections.jl and serbus on the host computer and transfers it to the BBB and puts it in the directory `/home/debian/juliapackages`. @@ -116,8 +134,8 @@ To setup automatic start of Julia server on the BB, make sure to have completed ``` -`ssh debian@192.168.7.2' -`sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) +ssh debian@192.168.7.2 +sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) ``` diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 03be1fe..c3b75b9 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -54,10 +54,11 @@ If the Julia REPL starts up correctly, then you have a functioning BBB ready for To update the BBB with the latest revision of the code, open up a terminal and type ``` -cd && cd .julia/packages/LabConnections//util +cd +cd .julia/packages/LabConnections//util ./flash_BB.sh ``` -This scripts bundles the current code in LabConnections and serbus on the host computer and transfers it to the /home/debian/juliapackages directory on the BBB. +This scripts bundles the current code in LabConnections.jl and serbus on the host computer and transfers it to the BBB and puts it in the directory `/home/debian/juliapackages`. From 441ec877d7ea7177271331a8da3103579b3598b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20F=C3=A4lt?= Date: Thu, 11 Apr 2019 18:43:37 +0200 Subject: [PATCH 23/47] Fixed GPIO for julia1 and added GPIO on computer side --- src/BeagleBone/BeagleBone.jl | 10 ++++++++- src/BeagleBone/GPIO.jl | 9 ++++++++ src/Computer/AbstractDevice.jl | 2 ++ src/Computer/BeagleBoneStream.jl | 11 ++++++++-- src/Computer/ComediStream.jl | 2 +- src/Computer/Computer.jl | 1 + src/Computer/GPIO.jl | 36 ++++++++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 src/Computer/GPIO.jl diff --git a/src/BeagleBone/BeagleBone.jl b/src/BeagleBone/BeagleBone.jl index 1d888ac..0278241 100644 --- a/src/BeagleBone/BeagleBone.jl +++ b/src/BeagleBone/BeagleBone.jl @@ -177,10 +177,18 @@ function run_server(port=2001; debug=false) @async while isopen(sock) try l = deserialize(sock); - bbparse(l, sock) + println("deserialized:") + println(l) + try + bbparse(l, sock) + catch err + @warn "Failure in bbparse, server should keep running, error:" + println(err) + end catch err if !isopen(sock) && (isa(err, Base.EOFError) || isa(err, Base.UVError)) println("Connection to server closed") + # TODO teardown and remove all devices else println("error: $(typeof(err))") println("err: $err") diff --git a/src/BeagleBone/GPIO.jl b/src/BeagleBone/GPIO.jl index 88a1879..e016325 100644 --- a/src/BeagleBone/GPIO.jl +++ b/src/BeagleBone/GPIO.jl @@ -35,6 +35,11 @@ struct GPIO <: IO_Object end end +# Default to writing "value" +function write!(gpio::GPIO, val::String, debug::Bool=false) + write!(gpio, (Int32(1), val), debug=debug) +end + """ write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false) Writes an entry to an operation on a GPIO, of the form args = (operation, entry). @@ -53,6 +58,10 @@ function write!(gpio::GPIO, args::Tuple{Int32,String}, debug::Bool=false) end end +# Default to reading "value" +function read(gpio::GPIO, debug::Bool=false) + read(gpio, Int32(1), debug=debug) +end """ l = read(gpio::GPIO, operation::Int32, debug::Bool=false) Reads the current value from an operation on a GPIO. diff --git a/src/Computer/AbstractDevice.jl b/src/Computer/AbstractDevice.jl index f5c5552..c88a2b0 100644 --- a/src/Computer/AbstractDevice.jl +++ b/src/Computer/AbstractDevice.jl @@ -10,6 +10,8 @@ getstream(dev::AbstractDevice) = dev.stream #Set the stream the AbstractDevice is connected to setstream!(dev::AbstractDevice, stream::LabStream) = dev.stream = stream +# Write command that needs to be sent after setup (for example direction of GPIO) +getsetupwrite(::LabStream, ::AbstractDevice) = nothing function safe_getwritecommand(dev::AbstractDevice, val) stream = try getstream(dev) catch diff --git a/src/Computer/BeagleBoneStream.jl b/src/Computer/BeagleBoneStream.jl index 844d721..1da986b 100644 --- a/src/Computer/BeagleBoneStream.jl +++ b/src/Computer/BeagleBoneStream.jl @@ -27,8 +27,16 @@ function init_devices!(bbstream::BeagleBoneStream, devs::AbstractDevice...) name = readcmd[1]::String idx = readcmd[2]::Integer serialize(bbstream.stream, (Int32(2), Int32(1), (name, Int32(idx)))) + + setupwrite = getsetupwrite(bbstream, dev) + if setupwrite !== nothing + name = setupwrite[1]::String + idx = setupwrite[2]::Integer + commands = setupwrite[3]::Tuple + serialize(bbstream.stream, (Int32(1), Int32(1), (name, Int32(idx), commands))) + end else - warn("Device $dev already added to a stream") + @warn "Device $dev already added to a stream" end end return @@ -69,7 +77,6 @@ function read(bbstream::BeagleBoneStream, cmd) end function close(bbstream::BeagleBoneStream) - cmds = Tuple[] for dev in bbstream.devices close(dev) end diff --git a/src/Computer/ComediStream.jl b/src/Computer/ComediStream.jl index c2cddda..f3ac457 100644 --- a/src/Computer/ComediStream.jl +++ b/src/Computer/ComediStream.jl @@ -23,7 +23,7 @@ function init_devices!(comedistream::ComediStream, devs::AbstractDevice...) push!(comedistream.devices, dev) initialize(dev) else - warn("Device $dev already added to the stream") + @warn "Device $dev already added to the stream" end end return diff --git a/src/Computer/Computer.jl b/src/Computer/Computer.jl index 19e6ab5..1a803e4 100644 --- a/src/Computer/Computer.jl +++ b/src/Computer/Computer.jl @@ -34,4 +34,5 @@ include("BeagleBoneStream.jl") #Include the device definitions include("SysLED.jl") +include("GPIO.jl") include("10V.jl") diff --git a/src/Computer/GPIO.jl b/src/Computer/GPIO.jl new file mode 100644 index 0000000..a611e2a --- /dev/null +++ b/src/Computer/GPIO.jl @@ -0,0 +1,36 @@ +export GPIO + +""" +GPIO(i::Integer, direction:Bool) +direction = true if output (write) +direction = false if input (read) + +""" +mutable struct GPIO <: AbstractDevice + i::Int32 + direction::Bool + stream::LabStream + GPIO(i::Int32, direction::Bool) = new(i, direction) +end +GPIO(i::Integer, direction::Bool) = GPIO(convert(Int32, i), direction) + +function getsetupwrite(stream::BeagleBoneStream, gpio::GPIO) + if gpio.direction + return ("gpio", gpio.i, (Int32(2), "out")) + else + return ("gpio", gpio.i, (Int32(2), "in")) + end +end + +#Stream specific methods +function getwritecommand(stream::BeagleBoneStream, gpio::GPIO, val::Bool) + if !gpio.direction + error("Can not write to GPIO input (read) device") + end + # TODO Check valid GPIO index + return ("gpio", gpio.i, (Int32(1), val ? "1" : "0")) +end +function getreadcommand(stream::BeagleBoneStream, gpio::GPIO) + # TODO Check valid GPIO index + return ("gpio", gpio.i) +end From 12e1d3f67ff876f49a5d290509210edbd2d72d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20F=C3=A4lt?= Date: Thu, 11 Apr 2019 19:00:10 +0200 Subject: [PATCH 24/47] more readable commands and gpio test --- Examples/tetsGPIO.jl | 12 ++++++++++++ src/BeagleBone/BeagleBone.jl | 10 +++++++--- src/BeagleBone/GPIO.jl | 8 ++++++-- src/Computer/BeagleBoneStream.jl | 16 ++++++++++------ src/Computer/GPIO.jl | 9 ++++++--- 5 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 Examples/tetsGPIO.jl diff --git a/Examples/tetsGPIO.jl b/Examples/tetsGPIO.jl new file mode 100644 index 0000000..76ab897 --- /dev/null +++ b/Examples/tetsGPIO.jl @@ -0,0 +1,12 @@ +using LabConnections.Computer +using Sockets + +stream = BeagleBoneStream(ip"192.168.7.2") + +gpio112 = GPIO(1, true) # Writing P9.30 (according to setup specification on BB) +gpio66 = GPIO(29, false) # Reading P8.7 + +init_devices!(stream, gpio112, gpio66) + +send(gpio112, true) +val = read(gpio112) diff --git a/src/BeagleBone/BeagleBone.jl b/src/BeagleBone/BeagleBone.jl index 0278241..db415c9 100644 --- a/src/BeagleBone/BeagleBone.jl +++ b/src/BeagleBone/BeagleBone.jl @@ -1,3 +1,7 @@ +const READ = Int32(0) +const WRITE = Int32(1) +const INIT = Int32(2) + include("IO_Object.jl") include("Debug.jl") include("SysLED.jl") @@ -118,14 +122,14 @@ and send back on socket (vals, timestamps). function bbparse(l::Tuple, sock) operation = l[1]::Int32 #1 if write command, 0 if read, 2 if init ndev = l[2]::Int32 #Number of devices/commands - if operation == 1 + if operation == WRITE for i = 1:ndev command = l[2+i]::Tuple dev = getdev(command[1], command[2]) write!(dev, command[3]) end return - elseif operation == 0 + elseif operation == READ #TODO fix to have at least partial type stability vals = Array{Any,1}(undef,ndev) timestamps = Array{UInt64,1}(undef,ndev) @@ -137,7 +141,7 @@ function bbparse(l::Tuple, sock) end bbsend(sock, (vals, timestamps)) return - elseif operation == 2 + elseif operation == INIT for i = 1:ndev command = l[2+i]::Tuple dev = initdev(command[1], command[2]) diff --git a/src/BeagleBone/GPIO.jl b/src/BeagleBone/GPIO.jl index e016325..f71d78f 100644 --- a/src/BeagleBone/GPIO.jl +++ b/src/BeagleBone/GPIO.jl @@ -1,3 +1,7 @@ +const GPIO_VALUE = Int32(1) +const GPIO_DIRECTION = Int32(2) +const GPIO_EDGE = Int32(3) + """ GPIO(i::Int32) Lowest form of communication with the GPIO pins. The available pins are @@ -37,7 +41,7 @@ end # Default to writing "value" function write!(gpio::GPIO, val::String, debug::Bool=false) - write!(gpio, (Int32(1), val), debug=debug) + write!(gpio, (GPIO_VALUE, val), debug=debug) end """ @@ -60,7 +64,7 @@ end # Default to reading "value" function read(gpio::GPIO, debug::Bool=false) - read(gpio, Int32(1), debug=debug) + read(gpio, GPIO_VALUE, debug=debug) end """ l = read(gpio::GPIO, operation::Int32, debug::Bool=false) diff --git a/src/Computer/BeagleBoneStream.jl b/src/Computer/BeagleBoneStream.jl index 1da986b..ee87330 100644 --- a/src/Computer/BeagleBoneStream.jl +++ b/src/Computer/BeagleBoneStream.jl @@ -1,5 +1,9 @@ export BeagleBoneStream, init_devices! +const BB_READ = Int32(0) +const BB_WRITE = Int32(1) +const BB_INIT = Int32(2) + struct BeagleBoneStream <: LabStream devices::Array{AbstractDevice,1} sendbuffer::Array{Tuple,1} @@ -26,14 +30,14 @@ function init_devices!(bbstream::BeagleBoneStream, devs::AbstractDevice...) readcmd = getreadcommand(bbstream, dev) name = readcmd[1]::String idx = readcmd[2]::Integer - serialize(bbstream.stream, (Int32(2), Int32(1), (name, Int32(idx)))) + serialize(bbstream.stream, (BB_INIT, Int32(1), (name, Int32(idx)))) setupwrite = getsetupwrite(bbstream, dev) if setupwrite !== nothing name = setupwrite[1]::String idx = setupwrite[2]::Integer commands = setupwrite[3]::Tuple - serialize(bbstream.stream, (Int32(1), Int32(1), (name, Int32(idx), commands))) + serialize(bbstream.stream, (BB_WRITE, Int32(1), (name, Int32(idx), commands))) end else @warn "Device $dev already added to a stream" @@ -44,14 +48,14 @@ end function send(bbstream::BeagleBoneStream) ncmds = length(bbstream.sendbuffer) - serialize(bbstream.stream, (Int32(1), Int32(ncmds), bbstream.sendbuffer...)) + serialize(bbstream.stream, (BB_WRITE, Int32(ncmds), bbstream.sendbuffer...)) empty!(bbstream.sendbuffer) return end #TODO know the types of outputs some way function read(bbstream::BeagleBoneStream) ncmds = length(bbstream.readbuffer) - serialize(bbstream.stream, (Int32(0), Int32(ncmds), bbstream.readbuffer...)) + serialize(bbstream.stream, (BB_READ, Int32(ncmds), bbstream.readbuffer...)) empty!(bbstream.readbuffer) vals, timestamps = deserialize(bbstream.stream) length(vals) == ncmds || error("Wrong number of return values in $vals on request $(bbstream.readbuffer)") @@ -61,13 +65,13 @@ end #The following are for interal use only function send(bbstream::BeagleBoneStream, cmd) - allcmds = (Int32(1), Int32(1), cmd) + allcmds = (BB_WRITE, Int32(1), cmd) println("Sending single command: $allcmds") serialize(bbstream.stream, allcmds) return end function read(bbstream::BeagleBoneStream, cmd) - allcmds = (Int32(0), Int32(1), cmd) + allcmds = (BB_READ, Int32(1), cmd) println("Sending single command: $allcmds") serialize(bbstream.stream, allcmds) vals, timestamps = deserialize(bbstream.stream) diff --git a/src/Computer/GPIO.jl b/src/Computer/GPIO.jl index a611e2a..30a2216 100644 --- a/src/Computer/GPIO.jl +++ b/src/Computer/GPIO.jl @@ -1,5 +1,8 @@ export GPIO +const GPIO_VALUE = Int32(1) +const GPIO_DIRECTION = Int32(2) +const GPIO_EDGE = Int32(3) """ GPIO(i::Integer, direction:Bool) direction = true if output (write) @@ -16,9 +19,9 @@ GPIO(i::Integer, direction::Bool) = GPIO(convert(Int32, i), direction) function getsetupwrite(stream::BeagleBoneStream, gpio::GPIO) if gpio.direction - return ("gpio", gpio.i, (Int32(2), "out")) + return ("gpio", gpio.i, (GPIO_DIRECTION, "out")) else - return ("gpio", gpio.i, (Int32(2), "in")) + return ("gpio", gpio.i, (GPIO_DIRECTION, "in")) end end @@ -28,7 +31,7 @@ function getwritecommand(stream::BeagleBoneStream, gpio::GPIO, val::Bool) error("Can not write to GPIO input (read) device") end # TODO Check valid GPIO index - return ("gpio", gpio.i, (Int32(1), val ? "1" : "0")) + return ("gpio", gpio.i, (GPIO_VALUE, val ? "1" : "0")) end function getreadcommand(stream::BeagleBoneStream, gpio::GPIO) # TODO Check valid GPIO index From 52b6b29e0921f5cea3a67ec016f118cb65ab7c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 13:46:33 +0200 Subject: [PATCH 25/47] Minor changes to installation instructions --- docs/build/man/installation.md | 5 ++--- docs/src/man/installation.md | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index 9d27023..1ad925e 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -37,7 +37,7 @@ To work with the SPI devices you will need a forked `serbus` repository which wr ``` -cd && cd .julia/packages +cd ~/.julia/packages git clone https://github.com/mgreiff/serbus ``` @@ -113,8 +113,7 @@ To update the BBB with the latest revision of the code, open up a terminal and t ``` -cd -cd .julia/packages/LabConnections//util +cd ~/.julia/packages/LabConnections//util ./flash_BB.sh ``` diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index c3b75b9..4000395 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -15,7 +15,7 @@ You now have the LabConnections.jl package available on the host computer. Note ### Installing Serbus To work with the SPI devices you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Open up a terminal and type ``` -cd && cd .julia/packages +cd ~/.julia/packages git clone https://github.com/mgreiff/serbus ``` to get the latest revision of the `serbus` fork. You are now done with the setup required on the host computer side. @@ -54,8 +54,7 @@ If the Julia REPL starts up correctly, then you have a functioning BBB ready for To update the BBB with the latest revision of the code, open up a terminal and type ``` -cd -cd .julia/packages/LabConnections//util +cd ~/.julia/packages/LabConnections//util ./flash_BB.sh ``` This scripts bundles the current code in LabConnections.jl and serbus on the host computer and transfers it to the BBB and puts it in the directory `/home/debian/juliapackages`. From c64d3012e3e82ab7510536a0537fdd961a350f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 14:41:16 +0200 Subject: [PATCH 26/47] Changes in instructions to transfer LabConnections and serbus to BB --- Project.toml | 2 +- docs/src/man/installation.md | 29 ++++++++++++++++------------- util/flash_BB.sh | 13 +++++++------ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Project.toml b/Project.toml index 221164a..a4e5270 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "LabConnections" uuid = "e9ebaa62-f26d-11e8-0a59-692f6511a9a1" -authors = ["Mattias Fält ", "Marcus Greiff", "Marcus Thelander Andrén"] +authors = ["Mattias Fält ", "Marcus Greiff", "Marcus Thelander Andrén "] version = "0.1.0" [deps] diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 4000395..3fd4520 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -52,29 +52,32 @@ If the Julia REPL starts up correctly, then you have a functioning BBB ready for ### Getting LabConnections.jl and serbus on the BeagleBone -To update the BBB with the latest revision of the code, open up a terminal and type +To update the BBB with the latest revision of the code, open up a terminal on the host computer and begin by cloning the `serbus` and `LabConnections.jl` repositories to a common directory ``` -cd ~/.julia/packages/LabConnections//util +git clone https://github.com/mgreiff/serbus +git clone --branch julia1 https://gitlab.control.lth.se/labdev/LabConnections.jl.git +``` +Then proceed by navigating to `LabConnections.jl/util` and run the `flash_BB.sh` shell script +``` +cd LabConnections/util ./flash_BB.sh ``` This scripts bundles the current code in LabConnections.jl and serbus on the host computer and transfers it to the BBB and puts it in the directory `/home/debian/juliapackages`. -### Setting up automatic communication -To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system - +### Setting up a Julia server on the BeagleBone +To setup automatic start of Julia server on the BBB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BBB. SSH into the BBB, and copy the file `juliaserver.service` to the folder `systemd/system` ``` ssh debian@192.168.7.2 -sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) +sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service ``` - - -Then execute the commands - -`sudo systemctl enable juliaserver` (on the BeagleBone) `sudo systemctl start juliaserver` (on the BeagleBone) - -After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. +Then, still SSH:d into the BBB, execute the commands +``` +sudo systemctl enable juliaserver +sudo systemctl start juliaserver +``` +After a while, the BBB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BBB is now running, and server should now start automatically every time you restart the BBB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. ## Debugging diff --git a/util/flash_BB.sh b/util/flash_BB.sh index af7a7a2..867cf10 100755 --- a/util/flash_BB.sh +++ b/util/flash_BB.sh @@ -1,15 +1,15 @@ #!/bin/bash -#Run in this file in util folder, copies to BB +#Run in this file un util folder, copies to BB BLUE='\033[0;34m' GREEN='\033[0;32m' RED='\033[0;31m' NC='\033[0m' -BASEDIR=../../../$(dirname "$0") +BASEDIR=../../$(dirname "$0") # Dependencies -# LabConnections.jl package -# serbus - a fork of a SPI communication interface -packages=(LabConnections serbus) +# LabConnections - main repository +# serbus - a fork of a SPI communicaiton interface +packages=(LabConnections.jl serbus) # Create an empty directory to bundle packages if [ -d ${BASEDIR}/juliapackages ]; then @@ -23,12 +23,13 @@ printf "${GREEN}Bundling...${NC}\n\n" for (( i=0; i<${#packages[@]}; i++ )); do { printf "${BLUE} * ${packages[$i]}${NC}\n" - cp -r ../../../${packages[$i]} ${BASEDIR}/juliapackages + cp -r ../../${packages[$i]} ${BASEDIR}/juliapackages } || { printf "${BLUE}WARNING.${NC} Could not bundle package ${packages[$i]}${NC}\n" flag=false } done +mv ${BASEDIR}/juliapackages/LabConnections.jl ${BASEDIR}/juliapackages/LabConnections # Transfer files if [ "$flag" = true ] ; then From a9c8ff4f95e396b70ed774e8cf3abf72fdc19612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 14:42:34 +0200 Subject: [PATCH 27/47] updated make --- docs/build/man/installation.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index 1ad925e..b03ead2 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -109,11 +109,20 @@ If the Julia REPL starts up correctly, then you have a functioning BBB ready for ### Getting LabConnections.jl and serbus on the BeagleBone -To update the BBB with the latest revision of the code, open up a terminal and type +To update the BBB with the latest revision of the code, open up a terminal on the host computer and begin by cloning the `serbus` and `LabConnections.jl` repositories to a common directory ``` -cd ~/.julia/packages/LabConnections//util +git clone https://github.com/mgreiff/serbus +git clone --branch julia1 https://gitlab.control.lth.se/labdev/LabConnections.jl.git +``` + + +Then proceed by navigating to `LabConnections.jl/util` and run the `flash_BB.sh` shell script + + +``` +cd LabConnections/util ./flash_BB.sh ``` @@ -124,27 +133,30 @@ This scripts bundles the current code in LabConnections.jl and serbus on the hos - + -### Setting up automatic communication +### Setting up a Julia server on the BeagleBone -To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BB. SSH to the BeagleBone and copy the julilaserver.service to the systemd/system +To setup automatic start of Julia server on the BBB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BBB. SSH into the BBB, and copy the file `juliaserver.service` to the folder `systemd/system` ``` ssh debian@192.168.7.2 -sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service` (on the BeagleBone) +sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service ``` -Then execute the commands +Then, still SSH:d into the BBB, execute the commands -`sudo systemctl enable juliaserver` (on the BeagleBone) `sudo systemctl start juliaserver` (on the BeagleBone) +``` +sudo systemctl enable juliaserver +sudo systemctl start juliaserver +``` -After a while, the BeagleBone should start blinking on SysLED 2: on-off-on-sleep-repeat. The server should now start automatically on restart of the BeagleBone, and you should be able to run the examples in in /Examples on the host computer. +After a while, the BBB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BBB is now running, and server should now start automatically every time you restart the BBB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. From 291ab8191f80b3f1cb7dbd15e3eaf33ed5966993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 14:48:51 +0200 Subject: [PATCH 28/47] Updated auto-server instructions --- docs/build/man/installation.md | 11 +++-------- docs/src/man/installation.md | 15 +++------------ 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index b03ead2..0264da2 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -143,7 +143,7 @@ To setup automatic start of Julia server on the BBB, make sure to have completed ``` ssh debian@192.168.7.2 -sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service +sudo cp -r /home/debian/juliapackages/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service ``` @@ -159,12 +159,7 @@ sudo systemctl start juliaserver After a while, the BBB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BBB is now running, and server should now start automatically every time you restart the BBB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. - - -## Debugging - - -No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root: +Note that no errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it can also be useful to start the service manually on the BBB. To do this, start Julia as root on the BBB ``` @@ -172,7 +167,7 @@ sudo /home/debian/julia/bin/julia ``` -and run the startup script: +and then run the startup script ``` diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 3fd4520..b96ab0e 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -70,7 +70,7 @@ This scripts bundles the current code in LabConnections.jl and serbus on the hos To setup automatic start of Julia server on the BBB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BBB. SSH into the BBB, and copy the file `juliaserver.service` to the folder `systemd/system` ``` ssh debian@192.168.7.2 -sudo cp -r /home/debian/juliapackets/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service +sudo cp -r /home/debian/juliapackages/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service ``` Then, still SSH:d into the BBB, execute the commands ``` @@ -79,20 +79,11 @@ sudo systemctl start juliaserver ``` After a while, the BBB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BBB is now running, and server should now start automatically every time you restart the BBB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. -## Debugging - - -No errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it might be useful to start the service manually on the beagle bone. Start julia as root: - - +Note that no errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it can also be useful to start the service manually on the BBB. To do this, start Julia as root on the BBB ``` sudo /home/debian/julia/bin/julia ``` - - -and run the startup script: - - +and then run the startup script ``` include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl") ``` From 48ea36614539d5c863c0bf886d8485d61ae7252b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 14:51:59 +0200 Subject: [PATCH 29/47] minor update to docs --- docs/build/man/installation.md | 3 ++- docs/src/man/installation.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index 0264da2..9007828 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -159,10 +159,11 @@ sudo systemctl start juliaserver After a while, the BBB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BBB is now running, and server should now start automatically every time you restart the BBB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. -Note that no errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it can also be useful to start the service manually on the BBB. To do this, start Julia as root on the BBB +Note that no errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it can therefore also be useful to start the service manually on the BBB. This way, any warnings or errors will be printed when starting up the Julia server. To start up the Julia server manually on the BBB, SHH into the BBB and start Julia as root ``` +ssh debian@192.168.7.2 sudo /home/debian/julia/bin/julia ``` diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index b96ab0e..4a8ff9c 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -79,8 +79,9 @@ sudo systemctl start juliaserver ``` After a while, the BBB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BBB is now running, and server should now start automatically every time you restart the BBB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. -Note that no errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it can also be useful to start the service manually on the BBB. To do this, start Julia as root on the BBB +Note that no errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it can therefore also be useful to start the service manually on the BBB. This way, any warnings or errors will be printed when starting up the Julia server. To start up the Julia server manually on the BBB, SHH into the BBB and start Julia as root ``` +ssh debian@192.168.7.2 sudo /home/debian/julia/bin/julia ``` and then run the startup script From 8aed4a9b0a5bdb26fd4f88f472fff7be67933baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 16:22:16 +0200 Subject: [PATCH 30/47] Added development to docs --- docs/build/examples/examples.md | 4 ++-- docs/build/examples/testing.md | 6 +++--- docs/build/index.md | 9 ++++++++- docs/build/man/development.md | 8 ++++---- docs/src/examples/examples.md | 15 +++++++-------- docs/src/examples/testing.md | 4 ++-- docs/src/index.md | 9 +++++++-- docs/src/man/development.md | 8 ++++---- 8 files changed, 37 insertions(+), 26 deletions(-) diff --git a/docs/build/examples/examples.md b/docs/build/examples/examples.md index 7a6fece..0ab33e8 100644 --- a/docs/build/examples/examples.md +++ b/docs/build/examples/examples.md @@ -4,7 +4,7 @@ # Examples -The following examples may be run from the BB, and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the following line in the Julia prompt +The following examples may be run from the BeagleBone (BB), and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the following line in the Julia REPL (while SSH:d into the BB) ``` @@ -12,7 +12,7 @@ push!(LOAD_PATH, "/home/debian/juliapackages") ``` -When running the examples with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in parallel. See the configuration page for information on which functionality specific pins support. +When running the examples with hardware in the loop, take caution not to short the BBB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in parallel. diff --git a/docs/build/examples/testing.md b/docs/build/examples/testing.md index d6c3c74..e65cc55 100644 --- a/docs/build/examples/testing.md +++ b/docs/build/examples/testing.md @@ -1,10 +1,10 @@ - + -# Tests +# Testing -The BeagleBone tests can be run on any computer, regrdless of their file-syste. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis. +The BeagleBone tests can be run on any computer, regardless of their file-system. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis. To run the tests, simply enter the /test/ directory and run diff --git a/docs/build/index.md b/docs/build/index.md index 9ff9ffc..b209639 100644 --- a/docs/build/index.md +++ b/docs/build/index.md @@ -19,7 +19,14 @@ ## Examples - [Examples](examples/examples.md#Examples-1) -- [Tests](examples/testing.md#Tests-1) + + + + +## Development + +- [Package Development](man/development.md#Package-Development-1) +- [Testing](examples/testing.md#Testing-1) diff --git a/docs/build/man/development.md b/docs/build/man/development.md index 256b57a..7b2e4be 100644 --- a/docs/build/man/development.md +++ b/docs/build/man/development.md @@ -1,12 +1,12 @@ -## Package Development +# Package Development - + -### LabConnections.jl Development +## Development environment If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type @@ -26,5 +26,5 @@ git pull ``` -to ensure that you are working on the correct development branch for Julia v1.0.X. +to ensure that you are working on the correct development branch for Julia v1.0.X. You can now edit the code in `.julia/dev/LabConnections` and run it using a Julia REPL. When you are satisfied with your changes, simply commit and push the changes in the `.julia/dev/LabConnections` directory to the GitLab server. diff --git a/docs/src/examples/examples.md b/docs/src/examples/examples.md index 4bac901..2747250 100644 --- a/docs/src/examples/examples.md +++ b/docs/src/examples/examples.md @@ -1,15 +1,14 @@ # Examples -The following examples may be run from the BB, and may require the user to +The following examples may be run from the BeagleBone (BB), and may require the user to export the the LabConnections module to the LOAD_PATH manually, executing the -following line in the Julia prompt - - push!(LOAD_PATH, "/home/debian/juliapackages") - +following line in the Julia REPL (while SSH:d into the BB) +``` +push!(LOAD_PATH, "/home/debian/juliapackages") +``` When running the examples with hardware in the loop, take caution not to short -the BB ground with any output pin, as this will damage the board. For instance, +the BBB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1000 Ohm in -parallel. See the configuration page for information on which functionality -specific pins support. +parallel. ## Example with LEDs (BB) To test the system LED functionality of the Julia code from the BBB, open a diff --git a/docs/src/examples/testing.md b/docs/src/examples/testing.md index 98cde17..69d3d2b 100644 --- a/docs/src/examples/testing.md +++ b/docs/src/examples/testing.md @@ -1,5 +1,5 @@ -# Tests -The BeagleBone tests can be run on any computer, regrdless of their file-syste. +# Testing +The BeagleBone tests can be run on any computer, regardless of their file-system. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, diff --git a/docs/src/index.md b/docs/src/index.md index 0db694b..d19da74 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -5,12 +5,17 @@ CurrentModule = LabConnections ``` ## Getting Started ```@contents -Pages = ["man/introduction.md", "man/installation.md", "man/development.md"] +Pages = ["man/introduction.md", "man/installation.md"] Depth = 1 ``` ## Examples ```@contents -Pages = ["examples/examples.md", "examples/testing.md"] +Pages = ["examples/examples.md"] +Depth = 1 +``` +## Development +```@contents +Pages = ["man/development.md", "examples/testing.md"] Depth = 1 ``` ## Functions diff --git a/docs/src/man/development.md b/docs/src/man/development.md index 3b66de5..0f56758 100644 --- a/docs/src/man/development.md +++ b/docs/src/man/development.md @@ -1,7 +1,6 @@ -## Package Development - -### LabConnections.jl Development +# Package Development +## Development environment If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type ``` ] dev https://gitlab.control.lth.se/labdev/LabConnections.jl @@ -11,4 +10,5 @@ Open a new terminal and navigate to `.julia/dev/LabConnections`, where the packa git checkout julia1 git pull ``` -to ensure that you are working on the correct development branch for Julia v1.0.X. +to ensure that you are working on the correct development branch for Julia v1.0.X. You can now edit the code in `.julia/dev/LabConnections` +and run it using a Julia REPL. When you are satisfied with your changes, simply commit and push the changes in the `.julia/dev/LabConnections` directory to the GitLab server. From a8bc9af2d7f388c6ca9b604c93e37ed132c31a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 17:14:20 +0200 Subject: [PATCH 31/47] Modified development and testing instructions --- docs/build/examples/testing.md | 15 +++++++-------- docs/build/man/development.md | 12 ++++++++++-- docs/build/man/installation.md | 28 ++++++++++++++-------------- docs/build/man/introduction.md | 2 +- docs/src/examples/testing.md | 27 ++++++++++++--------------- docs/src/man/development.md | 7 ++++++- docs/src/man/installation.md | 31 +++++++++++++++---------------- docs/src/man/introduction.md | 2 +- 8 files changed, 66 insertions(+), 58 deletions(-) diff --git a/docs/build/examples/testing.md b/docs/build/examples/testing.md index e65cc55..41b839d 100644 --- a/docs/build/examples/testing.md +++ b/docs/build/examples/testing.md @@ -4,24 +4,23 @@ # Testing -The BeagleBone tests can be run on any computer, regardless of their file-system. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run operate. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian FS, thereby enabling the automatic testing through Travis. +Scripts for testing the code in `LabConnections.jl` are found under `/test`. The test-sets under `/test/BeagleBone` can be run on any computer (i.e not only on a real BeagleBone (BB)), regardless of their file system. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian file system, thereby enabling the automatic testing through Travis. -To run the tests, simply enter the /test/ directory and run +To run the tests, simply navigate to the `/test` directory and run ``` -julia run_tests.jl +julia runtests.jl ``` -If the tests are to be run on the BB with hardware in the loop, run +If the tests are to be run on the BB with hardware in the loop, SSH into the BB and run the tests from a local Julia REPL ``` -julia run_tests.jl +push!(LOAD_PATH, "/home/debian/juliapackages") +using LabConnections +include("/home/debian/juliapackages/LabConnections/test/runtests.jl") ``` - -on the BB, to run examples separately, see - diff --git a/docs/build/man/development.md b/docs/build/man/development.md index 7b2e4be..5670c25 100644 --- a/docs/build/man/development.md +++ b/docs/build/man/development.md @@ -4,9 +4,9 @@ # Package Development - + -## Development environment +## Host computer development environment If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type @@ -28,3 +28,11 @@ git pull to ensure that you are working on the correct development branch for Julia v1.0.X. You can now edit the code in `.julia/dev/LabConnections` and run it using a Julia REPL. When you are satisfied with your changes, simply commit and push the changes in the `.julia/dev/LabConnections` directory to the GitLab server. + + + +## Development with the BeagleBone in the loop + + +The pin map of the BeagleBone (BB) is shown below. When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. + diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index 9007828..c33a812 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -4,7 +4,7 @@ # Installation instructions -In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black (BBB). +In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black (BB). @@ -33,7 +33,7 @@ You now have the LabConnections.jl package available on the host computer. Note ### Installing Serbus -To work with the SPI devices you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Open up a terminal and type +To work with SPI on the BB you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Open up a terminal and type ``` @@ -55,7 +55,7 @@ to get the latest revision of the `serbus` fork. You are now done with the setup ### Preparing a micro-SD card -First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BBB. +First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BB. Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. Make sure that the Julia folder has the correct name by typing @@ -69,7 +69,7 @@ mv /home/debian/julia-/bin/julia /home/debian/julia/bin/jul The file structure on the micro-SD now has the correct structure. -The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BBB when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing a BBB. +The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BB when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing a BB. @@ -77,7 +77,7 @@ The final step is to make sure that the micro-SD will automatically flash the De ### Flashing the BeagleBone -Insert a prepared micro-SD card in the slot on the BBB, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BBB. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to blink in a wave pattern, indicating that the BBB is being flashed. After a while (can vary between 5-45 minutes) the BBB will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BBB again (otherwise it will start to flash the BBB again). +Insert a prepared micro-SD card in the slot on the BB, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BB. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to blink in a wave pattern, indicating that the BB is being flashed. After a while (can vary between 5-45 minutes) the BB will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BB again (otherwise it will start to flash the BB again). @@ -85,7 +85,7 @@ Insert a prepared micro-SD card in the slot on the BBB, and press down the boot ### Accessing the BeagleBone -Now your BBB should be ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing +Now your BB should be ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing ``` @@ -93,7 +93,7 @@ ssh debian@192.168.7.2 ``` -The default password is `temppwd`. You are now logged in to the BBB running Debian. If the micro-SD was prepared correctly, the Julia binary should be located at `/home/debian/julia/bin/julia`. You can now start a Julia REPL on the BBB by typing +The default password is `temppwd`. You are now logged in to the BB running Debian. If the micro-SD was prepared correctly, the Julia binary should be located at `/home/debian/julia/bin/julia`. You can now start a Julia REPL on the BB by typing ``` @@ -101,7 +101,7 @@ The default password is `temppwd`. You are now logged in to the BBB running Debi ``` -If the Julia REPL starts up correctly, then you have a functioning BBB ready for use with the LabConnections.jl package. +If the Julia REPL starts up correctly, then you have a functioning BB ready for use with the LabConnections.jl package. @@ -109,7 +109,7 @@ If the Julia REPL starts up correctly, then you have a functioning BBB ready for ### Getting LabConnections.jl and serbus on the BeagleBone -To update the BBB with the latest revision of the code, open up a terminal on the host computer and begin by cloning the `serbus` and `LabConnections.jl` repositories to a common directory +To update the BB with the latest revision of the code, open up a terminal on the host computer and begin by cloning the `serbus` and `LabConnections.jl` repositories to a common directory ``` @@ -127,7 +127,7 @@ cd LabConnections/util ``` -This scripts bundles the current code in LabConnections.jl and serbus on the host computer and transfers it to the BBB and puts it in the directory `/home/debian/juliapackages`. +This scripts bundles the current code in LabConnections.jl and serbus on the host computer and transfers it to the BB and puts it in the directory `/home/debian/juliapackages`. @@ -138,7 +138,7 @@ This scripts bundles the current code in LabConnections.jl and serbus on the hos ### Setting up a Julia server on the BeagleBone -To setup automatic start of Julia server on the BBB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BBB. SSH into the BBB, and copy the file `juliaserver.service` to the folder `systemd/system` +To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BB. SSH into the BB, and copy the file `juliaserver.service` to the folder `systemd/system` ``` @@ -147,7 +147,7 @@ sudo cp -r /home/debian/juliapackages/LabConnections/src/BeagleBone/startup/juli ``` -Then, still SSH:d into the BBB, execute the commands +Then, still SSH:d into the BB, execute the commands ``` @@ -156,10 +156,10 @@ sudo systemctl start juliaserver ``` -After a while, the BBB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BBB is now running, and server should now start automatically every time you restart the BBB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. +After a while, the BB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BB is now running, and server should now start automatically every time you restart the BB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. -Note that no errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it can therefore also be useful to start the service manually on the BBB. This way, any warnings or errors will be printed when starting up the Julia server. To start up the Julia server manually on the BBB, SHH into the BBB and start Julia as root +Note that no errors will be seen on the BB when the automatic startup is used. For debugging purposes it can therefore also be useful to start the service manually on the BB. This way, any warnings or errors will be printed when starting up the Julia server. To start up the Julia server manually on the BB, SHH into the BB and start Julia as root ``` diff --git a/docs/build/man/introduction.md b/docs/build/man/introduction.md index 4374052..0990b82 100644 --- a/docs/build/man/introduction.md +++ b/docs/build/man/introduction.md @@ -7,7 +7,7 @@ -This project is developing a software package in [Julia](https://julialang.org/) for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BBB) with custom [IO-board cape](https://gitlab.control.lth.se/labdev/ioboards), or the old IO-boxes in the labs using Comedi. With this package, the user is able to setup a connection between the host computer and the IO-device, and send and receive control signals and measurements from the lab process. +This project is developing a software package in [Julia](https://julialang.org/) for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BB) with custom [IO-board cape](https://gitlab.control.lth.se/labdev/ioboards), or the old IO-boxes in the labs using Comedi. With this package, the user is able to setup a connection between the host computer and the IO-device, and send and receive control signals and measurements from the lab process. To get started, first follow the installation instruction found [here](installation.md). diff --git a/docs/src/examples/testing.md b/docs/src/examples/testing.md index 69d3d2b..2e7d8eb 100644 --- a/docs/src/examples/testing.md +++ b/docs/src/examples/testing.md @@ -1,16 +1,13 @@ # Testing -The BeagleBone tests can be run on any computer, regardless of their file-system. -By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in -which the tests are run operate. This has the advantage of enabling testing of -the code run on the BB free from the BB itself, without building the Debian FS, -thereby enabling the automatic testing through Travis. - -To run the tests, simply enter the /test/ directory and run - - julia run_tests.jl - -If the tests are to be run on the BB with hardware in the loop, run - - julia run_tests.jl - -on the BB, to run examples separately, see +Scripts for testing the code in `LabConnections.jl` are found under `/test`. The test-sets under `/test/BeagleBone` can be run on any computer (i.e not only on a real BeagleBone (BB)), regardless of their file system. By setting the flag RUNNING_TESTS to true, a dummy file-system is exported in which the tests are run. This has the advantage of enabling testing of the code run on the BB free from the BB itself, without building the Debian file system, thereby enabling the automatic testing through Travis. + +To run the tests, simply navigate to the `/test` directory and run +``` +julia runtests.jl +``` +If the tests are to be run on the BB with hardware in the loop, SSH into the BB and run the tests from a local Julia REPL +``` +push!(LOAD_PATH, "/home/debian/juliapackages") +using LabConnections +include("/home/debian/juliapackages/LabConnections/test/runtests.jl") +``` diff --git a/docs/src/man/development.md b/docs/src/man/development.md index 0f56758..5a7f001 100644 --- a/docs/src/man/development.md +++ b/docs/src/man/development.md @@ -1,6 +1,6 @@ # Package Development -## Development environment +## Host computer development environment If you want to develop the code in LabConnections.jl, then this is how you setup a development environment. First, open up a Julia REPL and type ``` ] dev https://gitlab.control.lth.se/labdev/LabConnections.jl @@ -12,3 +12,8 @@ git pull ``` to ensure that you are working on the correct development branch for Julia v1.0.X. You can now edit the code in `.julia/dev/LabConnections` and run it using a Julia REPL. When you are satisfied with your changes, simply commit and push the changes in the `.julia/dev/LabConnections` directory to the GitLab server. + +## Development with the BeagleBone in the loop +The pin map of the BeagleBone (BB) is shown below. + +When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 4a8ff9c..c491571 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -1,6 +1,5 @@ # Installation instructions -In these instructions we explain how to set up a working environment on a host computer and -a BeagleBone Black (BBB). +In these instructions we explain how to set up a working environment on a host computer and a BeagleBone Black (BB). ## Host computer setup @@ -13,7 +12,7 @@ To get started, first install Julia v1.0.X on the host computer running a Linux You now have the LabConnections.jl package available on the host computer. Note that for Julia v1.0.X it is the branch `julia1` of the package that should be used. ### Installing Serbus -To work with the SPI devices you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Open up a terminal and type +To work with SPI on the BB you will need a forked `serbus` repository which wraps the`linux/spi/spidev`. Open up a terminal and type ``` cd ~/.julia/packages git clone https://github.com/mgreiff/serbus @@ -23,7 +22,7 @@ to get the latest revision of the `serbus` fork. You are now done with the setup ## BeagleBone setup ### Preparing a micro-SD card -First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BBB. +First, we will prepare a micro-SD card with an image of Debian and a binary of Julia, which we then can flash onto the BB. Start by downloading the Debian image [here](http://beagleboard.org/latest-images) (Debian 9.5 2018-10-07 4GB SD IoT) and write the image onto a micro-SD card ([this guide](http://derekmolloy.ie/write-a-new-image-to-the-beaglebone-black/) is helpful). Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. @@ -33,26 +32,26 @@ mv /home/debian/julia-/bin/julia /home/debian/julia/bin/jul ``` The file structure on the micro-SD now has the correct structure. -The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BBB when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing a BBB. +The final step is to make sure that the micro-SD will automatically flash the Debian image onto the BB when booting up. To do this, follow the instructions found [here](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Flashing_eMMC). Congratulations, you now have a prepared micro-SD card ready for flashing a BB. ### Flashing the BeagleBone -Insert a prepared micro-SD card in the slot on the BBB, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BBB. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to blink in a wave pattern, indicating that the BBB is being flashed. After a while (can vary between 5-45 minutes) the BBB will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BBB again (otherwise it will start to flash the BBB again). +Insert a prepared micro-SD card in the slot on the BB, and press down the boot button S2 (the button closest to the micro-SD slot) and hold it down while you plug in the USB-cable to the BB. Keep the S2 button held down for a couple of seconds, until the onboard LEDs start to blink. After a short while the onboard LEDs should start to blink in a wave pattern, indicating that the BB is being flashed. After a while (can vary between 5-45 minutes) the BB will be turn off automatically, indicating that the flashing is complete. Remove the micro-SD before powering on the BB again (otherwise it will start to flash the BB again). ### Accessing the BeagleBone -Now your BBB should be ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing +Now your BB should be ready to use. Log on to the BeagleBone via SSH by opening a terminal and typing ``` ssh debian@192.168.7.2 ``` -The default password is `temppwd`. You are now logged in to the BBB running Debian. If the micro-SD was prepared correctly, the Julia binary should be located at `/home/debian/julia/bin/julia`. -You can now start a Julia REPL on the BBB by typing +The default password is `temppwd`. You are now logged in to the BB running Debian. If the micro-SD was prepared correctly, the Julia binary should be located at `/home/debian/julia/bin/julia`. +You can now start a Julia REPL on the BB by typing ``` /home/debian/julia/bin/julia ``` -If the Julia REPL starts up correctly, then you have a functioning BBB ready for use with the LabConnections.jl package. +If the Julia REPL starts up correctly, then you have a functioning BB ready for use with the LabConnections.jl package. ### Getting LabConnections.jl and serbus on the BeagleBone -To update the BBB with the latest revision of the code, open up a terminal on the host computer and begin by cloning the `serbus` and `LabConnections.jl` repositories to a common directory +To update the BB with the latest revision of the code, open up a terminal on the host computer and begin by cloning the `serbus` and `LabConnections.jl` repositories to a common directory ``` git clone https://github.com/mgreiff/serbus git clone --branch julia1 https://gitlab.control.lth.se/labdev/LabConnections.jl.git @@ -62,24 +61,24 @@ Then proceed by navigating to `LabConnections.jl/util` and run the `flash_BB.sh` cd LabConnections/util ./flash_BB.sh ``` -This scripts bundles the current code in LabConnections.jl and serbus on the host computer and transfers it to the BBB and puts it in the directory `/home/debian/juliapackages`. +This scripts bundles the current code in LabConnections.jl and serbus on the host computer and transfers it to the BB and puts it in the directory `/home/debian/juliapackages`. ### Setting up a Julia server on the BeagleBone -To setup automatic start of Julia server on the BBB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BBB. SSH into the BBB, and copy the file `juliaserver.service` to the folder `systemd/system` +To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BB. SSH into the BB, and copy the file `juliaserver.service` to the folder `systemd/system` ``` ssh debian@192.168.7.2 sudo cp -r /home/debian/juliapackages/LabConnections/src/BeagleBone/startup/juliaserver.service /lib/systemd/system/juliaserver.service ``` -Then, still SSH:d into the BBB, execute the commands +Then, still SSH:d into the BB, execute the commands ``` sudo systemctl enable juliaserver sudo systemctl start juliaserver ``` -After a while, the BBB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BBB is now running, and server should now start automatically every time you restart the BBB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. +After a while, the BB should start blinking onboard LED 2 in the following pattern: on-off-on-sleep-repeat. This indicates that the server on the BB is now running, and server should now start automatically every time you restart the BB. With this setup ready, you should be able to run the examples in the `/Examples` folder from the host computer. -Note that no errors will be seen on the BeagleBone when the automatic startup is used. For debugging purposes it can therefore also be useful to start the service manually on the BBB. This way, any warnings or errors will be printed when starting up the Julia server. To start up the Julia server manually on the BBB, SHH into the BBB and start Julia as root +Note that no errors will be seen on the BB when the automatic startup is used. For debugging purposes it can therefore also be useful to start the service manually on the BB. This way, any warnings or errors will be printed when starting up the Julia server. To start up the Julia server manually on the BB, SHH into the BB and start Julia as root ``` ssh debian@192.168.7.2 sudo /home/debian/julia/bin/julia diff --git a/docs/src/man/introduction.md b/docs/src/man/introduction.md index b3487ed..1d57dcf 100644 --- a/docs/src/man/introduction.md +++ b/docs/src/man/introduction.md @@ -2,7 +2,7 @@ This project is developing a software package in [Julia](https://julialang.org/) -for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BBB) +for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BB) with custom [IO-board cape](https://gitlab.control.lth.se/labdev/ioboards), or the old IO-boxes in the labs using Comedi. With this package, the user is able to setup a connection between the host computer and the IO-device, and send and From 9dc39aaa6d7154daa72af3c1628947807d02acd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 17:17:45 +0200 Subject: [PATCH 32/47] Removed DTO instructions, since they are not required with Debian 4.14 and over --- util/device_tree_overlay/.gitkeep | 0 util/device_tree_overlay/README.md | 48 - .../cape-universallc-00A0.dts | 1688 ----------------- 3 files changed, 1736 deletions(-) delete mode 100644 util/device_tree_overlay/.gitkeep delete mode 100644 util/device_tree_overlay/README.md delete mode 100644 util/device_tree_overlay/cape-universallc-00A0.dts diff --git a/util/device_tree_overlay/.gitkeep b/util/device_tree_overlay/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/util/device_tree_overlay/README.md b/util/device_tree_overlay/README.md deleted file mode 100644 index ffdde3e..0000000 --- a/util/device_tree_overlay/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Instructions on compiling and loading a device tree overlay -The BeagleBone Black (BBB) uses device tree overlays (DTOs) to specify the operation and -default settings of the pins. You can read more about using DTOs -for the BBB [here](https://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/overview). -Here we give instructions on how to compile and load the overlay `cape-universallc` -found in this folder. All commands in the instructions are performed on the BBB. - -First, make sure to have a copy of the file `cape-universallc-00A0.dts` in the folder `/lib/firmware` -on the BBB: -```shell -cp cape-universallc-00A0.dts /lib/firmware -``` -Then we use the device tree compiler (dtc) to compile the human readable -`.dts`-file into a `.dtbo`-file usable by the Linux kernel: -```shell -cd /lib/firmware -dtc -0 dtb -o cape-universallc-00A0.dtbo -b 0 -@ cape-universallc-00A0.dts -``` -Now we have a new file `cape-universallc-00A0.dtbo` in `/lib/firmware/`. To load -the new DTO, we send it to the slots-file of the BBB: -```shell -echo cape-universallc > /sys/devices/bone_capemgr.*/slots -``` -Note that the extension `-00A0.dtbo` is omitted in the command above. To check -that the overlay has been loaded properly we can check the slots file: -```shell -cat /sys/devices/bone_capemgr.*/slots -``` -which should give the following printout: -```shell - 0: 54:PF--- - 1: 55:PF--- - 2: 56:PF--- - 3: 57:PF--- - 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G - 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI - 8: ff:P-O-L Override Board Name,00A0,Override Manuf,cape-universallc -``` -Here the overlays in slots 4 and 5 are related to the eMMC and HDMI, while the -new overlay `cape-universallc` is loaded to slot 8. Now the behaviour of the BBBs -pins is properly defined, and you can start using the framework of `LabConnections.BeagleBone`. - -### Note about `cape-universallc` -The DTO `cape-universallc` is essentially identical to the standard DTO -`cape-universaln` found [here](https://github.com/cdsteinkuehler/beaglebone-universal-io) -which exports all pins except for those used by the HDMI and eMMC. However, there -is a bug in the default version of `cape-universaln` found on the BBB (described [here](https://github.com/cdsteinkuehler/beaglebone-universal-io/issues/21)), -which prevents it from loading properly. This bug has been taken care of in `cape-universallc`. \ No newline at end of file diff --git a/util/device_tree_overlay/cape-universallc-00A0.dts b/util/device_tree_overlay/cape-universallc-00A0.dts deleted file mode 100644 index 3cc5c53..0000000 --- a/util/device_tree_overlay/cape-universallc-00A0.dts +++ /dev/null @@ -1,1688 +0,0 @@ -// Copyright 2013 -// Charles Steinkuehler -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -/dts-v1/; -/plugin/; - -/ { - compatible = "ti,beaglebone", "ti,beaglebone-black"; - - /* identification */ - part-number = "cape-bone-universaln"; - version = "00A0"; - - /* state the resources this cape uses */ - exclusive-use = - -/* "P8.1", GND */ -/* "P8.2", GND */ -/* "P8.3", emmc */ -/* "P8.4", emmc */ -/* "P8.5", emmc */ -/* "P8.6", emmc */ - "P8.7", - "P8.8", - "P8.9", - "P8.10", - "P8.11", - "P8.12", - "P8.13", - "P8.14", - "P8.15", - "P8.16", - "P8.17", - "P8.18", - "P8.19", -/* "P8.20", emmc */ -/* "P8.21", emmc */ -/* "P8.22", emmc */ -/* "P8.23", emmc */ -/* "P8.24", emmc */ -/* "P8.25", emmc */ - "P8.26", -/* "P8.27", hdmi */ -/* "P8.28", hdmi */ -/* "P8.29", hdmi */ -/* "P8.30", hdmi */ -/* "P8.31", hdmi */ -/* "P8.32", hdmi */ -/* "P8.33", hdmi */ -/* "P8.34", hdmi */ -/* "P8.35", hdmi */ -/* "P8.36", hdmi */ -/* "P8.37", hdmi */ -/* "P8.38", hdmi */ -/* "P8.39", hdmi */ -/* "P8.40", hdmi */ -/* "P8.41", hdmi */ -/* "P8.42", hdmi */ -/* "P8.43", hdmi */ -/* "P8.44", hdmi */ -/* "P8.45", hdmi */ -/* "P8.46", hdmi */ - -/* "P9.1", GND */ -/* "P9.2", GND */ -/* "P9.3", 3.3V */ -/* "P9.4", 3.3V */ -/* "P9.5", VDD_5V */ -/* "P9.6", VDD_5V */ -/* "P9.7", SYS_5V */ -/* "P9.8", SYS_5V */ -/* "P9.9", PWR_BUT */ -/* "P9.10", RESETn */ - "P9.11", - "P9.12", - "P9.13", - "P9.14", - "P9.15", - "P9.16", - "P9.17", - "P9.18", -/* "P9.19", I2C */ -/* "P9.20", I2C */ - "P9.21", - "P9.22", - "P9.23", - "P9.24", -/* "P9.25", Audio */ - "P9.26", - "P9.27", -/* "P9.28", Audio */ -/* "P9.29", Audio */ - "P9.30", -/* "P9.31", Audio */ -/* "P9.32", VADC */ -/* "P9.33", AIN4 */ -/* "P9.34", AGND */ -/* "P9.35", AIN6 */ -/* "P9.36", AIN5 */ -/* "P9.37", AIN2 */ -/* "P9.38", AIN3 */ -/* "P9.39", AIN0 */ -/* "P9.40", AIN1 */ - "P9.41", - "P9.41.1", - "P9.42", - "P9.42.1", -/* "P9.43", GND */ -/* "P9.44", GND */ -/* "P9.45", GND */ -/* "P9.46", GND */ - - "uart1", - "uart2", - "uart4", -// "uart5", /* Conflicts with HDMI */ - - "ehrpwm0A", - "ehrpwm0B", - "ehrpwm1A", - "ehrpwm1B", - "ehrpwm2A", - "ehrpwm2B", - -// "epwmss0", -// "ehrpwm0", -// "ecap0", -// "epwmss1", -// "ehrpwm1", -// "epwmss2", -// "ehrpwm2", -// "ecap2", - - "i2c1", - "spi1", - "spi0", - "dcan0", - "dcan1", - - "pru0", - "pru1", - "pruss"; - - fragment@0 { - target = <&am33xx_pinmux>; - __overlay__ { - - /************************/ - /* P8 Header */ - /************************/ - - /* P8_01 GND */ - /* P8_02 GND */ - /* P8_03 (ZCZ ball R9 ) emmc */ - /* P8_04 (ZCZ ball T9 ) emmc */ - /* P8_05 (ZCZ ball R8 ) emmc */ - /* P8_06 (ZCZ ball T8 ) emmc */ - - /* P8_07 (ZCZ ball R7 ) */ - P8_07_default_pin: pinmux_P8_07_default_pin { - pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_07_gpio_pin: pinmux_P8_07_gpio_pin { - pinctrl-single,pins = <0x090 0x2F>; }; /* Mode 7, RxActive */ - P8_07_gpio_pu_pin: pinmux_P8_07_gpio_pu_pin { - pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_07_gpio_pd_pin: pinmux_P8_07_gpio_pd_pin { - pinctrl-single,pins = <0x090 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_07_timer_pin: pinmux_P8_07_timer_pin { - pinctrl-single,pins = <0x090 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - - /* P8_08 (ZCZ ball T7 ) */ - P8_08_default_pin: pinmux_P8_08_default_pin { - pinctrl-single,pins = <0x094 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_08_gpio_pin: pinmux_P8_08_gpio_pin { - pinctrl-single,pins = <0x094 0x2F>; }; /* Mode 7, RxActive */ - P8_08_gpio_pu_pin: pinmux_P8_08_gpio_pu_pin { - pinctrl-single,pins = <0x094 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_08_gpio_pd_pin: pinmux_P8_08_gpio_pd_pin { - pinctrl-single,pins = <0x094 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_08_timer_pin: pinmux_P8_08_timer_pin { - pinctrl-single,pins = <0x094 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - - /* P8_09 (ZCZ ball T6 ) */ - P8_09_default_pin: pinmux_P8_09_default_pin { - pinctrl-single,pins = <0x09c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_09_gpio_pin: pinmux_P8_09_gpio_pin { - pinctrl-single,pins = <0x09c 0x2F>; }; /* Mode 7, RxActive */ - P8_09_gpio_pu_pin: pinmux_P8_09_gpio_pu_pin { - pinctrl-single,pins = <0x09c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_09_gpio_pd_pin: pinmux_P8_09_gpio_pd_pin { - pinctrl-single,pins = <0x09c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_09_timer_pin: pinmux_P8_09_timer_pin { - pinctrl-single,pins = <0x09c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - - /* P8_10 (ZCZ ball U6 ) */ - P8_10_default_pin: pinmux_P8_10_default_pin { - pinctrl-single,pins = <0x098 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_10_gpio_pin: pinmux_P8_10_gpio_pin { - pinctrl-single,pins = <0x098 0x2F>; }; /* Mode 7, RxActive */ - P8_10_gpio_pu_pin: pinmux_P8_10_gpio_pu_pin { - pinctrl-single,pins = <0x098 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_10_gpio_pd_pin: pinmux_P8_10_gpio_pd_pin { - pinctrl-single,pins = <0x098 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_10_timer_pin: pinmux_P8_10_timer_pin { - pinctrl-single,pins = <0x098 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - - /* P8_11 (ZCZ ball R12) */ - P8_11_default_pin: pinmux_P8_11_default_pin { - pinctrl-single,pins = <0x034 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_11_gpio_pin: pinmux_P8_11_gpio_pin { - pinctrl-single,pins = <0x034 0x2F>; }; /* Mode 7, RxActive */ - P8_11_gpio_pu_pin: pinmux_P8_11_gpio_pu_pin { - pinctrl-single,pins = <0x034 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_11_gpio_pd_pin: pinmux_P8_11_gpio_pd_pin { - pinctrl-single,pins = <0x034 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_11_pruout_pin: pinmux_P8_11_pruout_pin { - pinctrl-single,pins = <0x034 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - P8_11_qep_pin: pinmux_P8_11_qep_pin { - pinctrl-single,pins = <0x034 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P8_12 (ZCZ ball T12) */ - P8_12_default_pin: pinmux_P8_12_default_pin { - pinctrl-single,pins = <0x030 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_12_gpio_pin: pinmux_P8_12_gpio_pin { - pinctrl-single,pins = <0x030 0x2F>; }; /* Mode 7, RxActive */ - P8_12_gpio_pu_pin: pinmux_P8_12_gpio_pu_pin { - pinctrl-single,pins = <0x030 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_12_gpio_pd_pin: pinmux_P8_12_gpio_pd_pin { - pinctrl-single,pins = <0x030 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_12_pruout_pin: pinmux_P8_12_pruout_pin { - pinctrl-single,pins = <0x030 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - P8_12_qep_pin: pinmux_P8_12_qep_pin { - pinctrl-single,pins = <0x030 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P8_13 (ZCZ ball T10) */ - P8_13_default_pin: pinmux_P8_13_default_pin { - pinctrl-single,pins = <0x024 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_13_gpio_pin: pinmux_P8_13_gpio_pin { - pinctrl-single,pins = <0x024 0x2F>; }; /* Mode 7, RxActive */ - P8_13_gpio_pu_pin: pinmux_P8_13_gpio_pu_pin { - pinctrl-single,pins = <0x024 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_13_gpio_pd_pin: pinmux_P8_13_gpio_pd_pin { - pinctrl-single,pins = <0x024 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_13_pwm_pin: pinmux_P8_13_pwm_pin { - pinctrl-single,pins = <0x024 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P8_14 (ZCZ ball T11) */ - P8_14_default_pin: pinmux_P8_14_default_pin { - pinctrl-single,pins = <0x028 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_14_gpio_pin: pinmux_P8_14_gpio_pin { - pinctrl-single,pins = <0x028 0x2F>; }; /* Mode 7, RxActive */ - P8_14_gpio_pu_pin: pinmux_P8_14_gpio_pu_pin { - pinctrl-single,pins = <0x028 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_14_gpio_pd_pin: pinmux_P8_14_gpio_pd_pin { - pinctrl-single,pins = <0x028 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_14_pwm_pin: pinmux_P8_14_pwm_pin { - pinctrl-single,pins = <0x028 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P8_15 (ZCZ ball U13) */ - P8_15_default_pin: pinmux_P8_15_default_pin { - pinctrl-single,pins = <0x03c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_15_gpio_pin: pinmux_P8_15_gpio_pin { - pinctrl-single,pins = <0x03c 0x2F>; }; /* Mode 7, RxActive */ - P8_15_gpio_pu_pin: pinmux_P8_15_gpio_pu_pin { - pinctrl-single,pins = <0x03c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_15_gpio_pd_pin: pinmux_P8_15_gpio_pd_pin { - pinctrl-single,pins = <0x03c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_15_pruin_pin: pinmux_P8_15_pruin_pin { - pinctrl-single,pins = <0x03c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - P8_15_pru_ecap_pin: pinmux_P8_15_pru_ecap_pin { - pinctrl-single,pins = <0x03c 0x25>; }; /* Mode 5, Pull-Down, RxActive */ - P8_15_qep_pin: pinmux_P8_15_qep_pin { - pinctrl-single,pins = <0x03c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P8_16 (ZCZ ball V13) */ - P8_16_default_pin: pinmux_P8_16_default_pin { - pinctrl-single,pins = <0x038 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_16_gpio_pin: pinmux_P8_16_gpio_pin { - pinctrl-single,pins = <0x038 0x2F>; }; /* Mode 7, RxActive */ - P8_16_gpio_pu_pin: pinmux_P8_16_gpio_pu_pin { - pinctrl-single,pins = <0x038 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_16_gpio_pd_pin: pinmux_P8_16_gpio_pd_pin { - pinctrl-single,pins = <0x038 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_16_pruin_pin: pinmux_P8_16_pruin_pin { - pinctrl-single,pins = <0x038 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - P8_16_qep_pin: pinmux_P8_16_qep_pin { - pinctrl-single,pins = <0x038 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P8_17 (ZCZ ball U12) */ - P8_17_default_pin: pinmux_P8_17_default_pin { - pinctrl-single,pins = <0x02c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_17_gpio_pin: pinmux_P8_17_gpio_pin { - pinctrl-single,pins = <0x02c 0x2F>; }; /* Mode 7, RxActive */ - P8_17_gpio_pu_pin: pinmux_P8_17_gpio_pu_pin { - pinctrl-single,pins = <0x02c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_17_gpio_pd_pin: pinmux_P8_17_gpio_pd_pin { - pinctrl-single,pins = <0x02c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_17_pwm_pin: pinmux_P8_17_pwm_pin { - pinctrl-single,pins = <0x02c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P8_18 (ZCZ ball V12) */ - P8_18_default_pin: pinmux_P8_18_default_pin { - pinctrl-single,pins = <0x08c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_18_gpio_pin: pinmux_P8_18_gpio_pin { - pinctrl-single,pins = <0x08c 0x2F>; }; /* Mode 7, RxActive */ - P8_18_gpio_pu_pin: pinmux_P8_18_gpio_pu_pin { - pinctrl-single,pins = <0x08c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_18_gpio_pd_pin: pinmux_P8_18_gpio_pd_pin { - pinctrl-single,pins = <0x08c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - - /* P8_19 (ZCZ ball U10) */ - P8_19_default_pin: pinmux_P8_19_default_pin { - pinctrl-single,pins = <0x020 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_19_gpio_pin: pinmux_P8_19_gpio_pin { - pinctrl-single,pins = <0x020 0x2F>; }; /* Mode 7, RxActive */ - P8_19_gpio_pu_pin: pinmux_P8_19_gpio_pu_pin { - pinctrl-single,pins = <0x020 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_19_gpio_pd_pin: pinmux_P8_19_gpio_pd_pin { - pinctrl-single,pins = <0x020 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P8_19_pwm_pin: pinmux_P8_19_pwm_pin { - pinctrl-single,pins = <0x020 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P8_20 (ZCZ ball V9 ) emmc */ - /* P8_21 (ZCZ ball U9 ) emmc */ - /* P8_22 (ZCZ ball V8 ) emmc */ - /* P8_23 (ZCZ ball U8 ) emmc */ - /* P8_24 (ZCZ ball V7 ) emmc */ - /* P8_25 (ZCZ ball U7 ) emmc */ - - /* P8_26 (ZCZ ball V6 ) */ - P8_26_default_pin: pinmux_P8_26_default_pin { - pinctrl-single,pins = <0x07c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_26_gpio_pin: pinmux_P8_26_gpio_pin { - pinctrl-single,pins = <0x07c 0x2F>; }; /* Mode 7, RxActive */ - P8_26_gpio_pu_pin: pinmux_P8_26_gpio_pu_pin { - pinctrl-single,pins = <0x07c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P8_26_gpio_pd_pin: pinmux_P8_26_gpio_pd_pin { - pinctrl-single,pins = <0x07c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - - /* P8_27 (ZCZ ball U5 ) hdmi */ - /* P8_28 (ZCZ ball V5 ) hdmi */ - /* P8_29 (ZCZ ball R5 ) hdmi */ - /* P8_30 (ZCZ ball R6 ) hdmi */ - /* P8_31 (ZCZ ball V4 ) hdmi */ - /* P8_32 (ZCZ ball T5 ) hdmi */ - /* P8_33 (ZCZ ball V3 ) hdmi */ - /* P8_34 (ZCZ ball U4 ) hdmi */ - /* P8_35 (ZCZ ball V2 ) hdmi */ - /* P8_36 (ZCZ ball U3 ) hdmi */ - /* P8_37 (ZCZ ball U1 ) hdmi */ - /* P8_38 (ZCZ ball U2 ) hdmi */ - /* P8_39 (ZCZ ball T3 ) hdmi */ - /* P8_40 (ZCZ ball T4 ) hdmi */ - /* P8_41 (ZCZ ball T1 ) hdmi */ - /* P8_42 (ZCZ ball T2 ) hdmi */ - /* P8_43 (ZCZ ball R3 ) hdmi */ - /* P8_44 (ZCZ ball R4 ) hdmi */ - /* P8_45 (ZCZ ball R1 ) hdmi */ - /* P8_46 (ZCZ ball R2 ) hdmi */ - - - /************************/ - /* P9 Header */ - /************************/ - - /* P9_01 GND */ - /* P9_02 GND */ - /* P9_03 3.3V */ - /* P9_04 3.3V */ - /* P9_05 VDD_5V */ - /* P9_06 VDD_5V */ - /* P9_07 SYS_5V */ - /* P9_08 SYS_5V */ - /* P9_09 PWR_BUT */ - /* P9_10 (ZCZ ball A10) RESETn */ - - /* P9_11 (ZCZ ball T17) */ - P9_11_default_pin: pinmux_P9_11_default_pin { - pinctrl-single,pins = <0x070 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_11_gpio_pin: pinmux_P9_11_gpio_pin { - pinctrl-single,pins = <0x070 0x2F>; }; /* Mode 7, RxActive */ - P9_11_gpio_pu_pin: pinmux_P9_11_gpio_pu_pin { - pinctrl-single,pins = <0x070 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_11_gpio_pd_pin: pinmux_P9_11_gpio_pd_pin { - pinctrl-single,pins = <0x070 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_11_uart_pin: pinmux_P9_11_uart_pin { - pinctrl-single,pins = <0x070 0x36>; }; /* Mode 6, Pull-Up, RxActive */ - - /* P9_12 (ZCZ ball U18) */ - P9_12_default_pin: pinmux_P9_12_default_pin { - pinctrl-single,pins = <0x078 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_12_gpio_pin: pinmux_P9_12_gpio_pin { - pinctrl-single,pins = <0x078 0x2F>; }; /* Mode 7, RxActive */ - P9_12_gpio_pu_pin: pinmux_P9_12_gpio_pu_pin { - pinctrl-single,pins = <0x078 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_12_gpio_pd_pin: pinmux_P9_12_gpio_pd_pin { - pinctrl-single,pins = <0x078 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - - /* P9_13 (ZCZ ball U17) */ - P9_13_default_pin: pinmux_P9_13_default_pin { - pinctrl-single,pins = <0x074 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_13_gpio_pin: pinmux_P9_13_gpio_pin { - pinctrl-single,pins = <0x074 0x2F>; }; /* Mode 7, RxActive */ - P9_13_gpio_pu_pin: pinmux_P9_13_gpio_pu_pin { - pinctrl-single,pins = <0x074 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_13_gpio_pd_pin: pinmux_P9_13_gpio_pd_pin { - pinctrl-single,pins = <0x074 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_13_uart_pin: pinmux_P9_13_uart_pin { - pinctrl-single,pins = <0x074 0x36>; }; /* Mode 6, Pull-Up, RxActive */ - - /* P9_14 (ZCZ ball U14) */ - P9_14_default_pin: pinmux_P9_14_default_pin { - pinctrl-single,pins = <0x048 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_14_gpio_pin: pinmux_P9_14_gpio_pin { - pinctrl-single,pins = <0x048 0x2F>; }; /* Mode 7, RxActive */ - P9_14_gpio_pu_pin: pinmux_P9_14_gpio_pu_pin { - pinctrl-single,pins = <0x048 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_14_gpio_pd_pin: pinmux_P9_14_gpio_pd_pin { - pinctrl-single,pins = <0x048 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_14_pwm_pin: pinmux_P9_14_pwm_pin { - pinctrl-single,pins = <0x048 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - - /* P9_15 (ZCZ ball R13) */ - P9_15_default_pin: pinmux_P9_15_default_pin { - pinctrl-single,pins = <0x040 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_15_gpio_pin: pinmux_P9_15_gpio_pin { - pinctrl-single,pins = <0x040 0x2F>; }; /* Mode 7, RxActive */ - P9_15_gpio_pu_pin: pinmux_P9_15_gpio_pu_pin { - pinctrl-single,pins = <0x040 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_15_gpio_pd_pin: pinmux_P9_15_gpio_pd_pin { - pinctrl-single,pins = <0x040 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_15_pwm_pin: pinmux_P9_15_pwm_pin { - pinctrl-single,pins = <0x040 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - - /* P9_16 (ZCZ ball T14) */ - P9_16_default_pin: pinmux_P9_16_default_pin { - pinctrl-single,pins = <0x04c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_16_gpio_pin: pinmux_P9_16_gpio_pin { - pinctrl-single,pins = <0x04c 0x2F>; }; /* Mode 7, RxActive */ - P9_16_gpio_pu_pin: pinmux_P9_16_gpio_pu_pin { - pinctrl-single,pins = <0x04c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_16_gpio_pd_pin: pinmux_P9_16_gpio_pd_pin { - pinctrl-single,pins = <0x04c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_16_pwm_pin: pinmux_P9_16_pwm_pin { - pinctrl-single,pins = <0x04c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - - /* P9_17 (ZCZ ball A16) */ - P9_17_default_pin: pinmux_P9_17_default_pin { - pinctrl-single,pins = <0x15c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_17_gpio_pin: pinmux_P9_17_gpio_pin { - pinctrl-single,pins = <0x15c 0x2F>; }; /* Mode 7, RxActive */ - P9_17_gpio_pu_pin: pinmux_P9_17_gpio_pu_pin { - pinctrl-single,pins = <0x15c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_17_gpio_pd_pin: pinmux_P9_17_gpio_pd_pin { - pinctrl-single,pins = <0x15c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_17_spi_pin: pinmux_P9_17_spi_pin { - pinctrl-single,pins = <0x15c 0x30>; }; /* Mode 0, Pull-Up, RxActive */ - P9_17_i2c_pin: pinmux_P9_17_i2c_pin { - pinctrl-single,pins = <0x15c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - P9_17_pwm_pin: pinmux_P9_17_pwm_pin { - pinctrl-single,pins = <0x15c 0x33>; }; /* Mode 3, Pull-Up, RxActive */ - P9_17_pru_uart_pin: pinmux_P9_17_pru_uart_pin { - pinctrl-single,pins = <0x15c 0x34>; }; /* Mode 4, Pull-Up, RxActive */ - - /* P9_18 (ZCZ ball B16) */ - P9_18_default_pin: pinmux_P9_18_default_pin { - pinctrl-single,pins = <0x158 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_18_gpio_pin: pinmux_P9_18_gpio_pin { - pinctrl-single,pins = <0x158 0x2F>; }; /* Mode 7, RxActive */ - P9_18_gpio_pu_pin: pinmux_P9_18_gpio_pu_pin { - pinctrl-single,pins = <0x158 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_18_gpio_pd_pin: pinmux_P9_18_gpio_pd_pin { - pinctrl-single,pins = <0x158 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_18_spi_pin: pinmux_P9_18_spi_pin { - pinctrl-single,pins = <0x158 0x30>; }; /* Mode 0, Pull-Up, RxActive */ - P9_18_i2c_pin: pinmux_P9_18_i2c_pin { - pinctrl-single,pins = <0x158 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - P9_18_pwm_pin: pinmux_P9_18_pwm_pin { - pinctrl-single,pins = <0x158 0x33>; }; /* Mode 3, Pull-Up, RxActive */ - P9_18_pru_uart_pin: pinmux_P9_18_pru_uart_pin { - pinctrl-single,pins = <0x158 0x34>; }; /* Mode 4, Pull-Up, RxActive */ - - // Leave the cape I2C EEPROM bus alone - /* P9_19 (ZCZ ball D17) I2C */ - /* P9_20 (ZCZ ball D18) I2C */ - - /* P9_21 (ZCZ ball B17) */ - P9_21_default_pin: pinmux_P9_21_default_pin { - pinctrl-single,pins = <0x154 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_21_gpio_pin: pinmux_P9_21_gpio_pin { - pinctrl-single,pins = <0x154 0x2F>; }; /* Mode 7, RxActive */ - P9_21_gpio_pu_pin: pinmux_P9_21_gpio_pu_pin { - pinctrl-single,pins = <0x154 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_21_gpio_pd_pin: pinmux_P9_21_gpio_pd_pin { - pinctrl-single,pins = <0x154 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_21_spi_pin: pinmux_P9_21_spi_pin { - pinctrl-single,pins = <0x154 0x30>; }; /* Mode 0, Pull-Up, RxActive */ - P9_21_uart_pin: pinmux_P9_21_uart_pin { - pinctrl-single,pins = <0x154 0x31>; }; /* Mode 1, Pull-Up, RxActive */ - P9_21_i2c_pin: pinmux_P9_21_i2c_pin { - pinctrl-single,pins = <0x154 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - P9_21_pwm_pin: pinmux_P9_21_pwm_pin { - pinctrl-single,pins = <0x154 0x33>; }; /* Mode 3, Pull-Up, RxActive */ - P9_21_pru_uart_pin: pinmux_P9_21_pru_uart_pin { - pinctrl-single,pins = <0x154 0x34>; }; /* Mode 4, Pull-Up, RxActive */ - - /* P9_22 (ZCZ ball A17) */ - P9_22_default_pin: pinmux_P9_22_default_pin { - pinctrl-single,pins = <0x150 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_22_gpio_pin: pinmux_P9_22_gpio_pin { - pinctrl-single,pins = <0x150 0x2F>; }; /* Mode 7, RxActive */ - P9_22_gpio_pu_pin: pinmux_P9_22_gpio_pu_pin { - pinctrl-single,pins = <0x150 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_22_gpio_pd_pin: pinmux_P9_22_gpio_pd_pin { - pinctrl-single,pins = <0x150 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_22_spi_pin: pinmux_P9_22_spi_pin { - pinctrl-single,pins = <0x150 0x30>; }; /* Mode 0, Pull-Up, RxActive */ - P9_22_uart_pin: pinmux_P9_22_uart_pin { - pinctrl-single,pins = <0x150 0x31>; }; /* Mode 1, Pull-Up, RxActive */ - P9_22_i2c_pin: pinmux_P9_22_i2c_pin { - pinctrl-single,pins = <0x150 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - P9_22_pwm_pin: pinmux_P9_22_pwm_pin { - pinctrl-single,pins = <0x150 0x33>; }; /* Mode 3, Pull-Up, RxActive */ - P9_22_pru_uart_pin: pinmux_P9_22_pru_uart_pin { - pinctrl-single,pins = <0x150 0x34>; }; /* Mode 4, Pull-Up, RxActive */ - - /* P9_23 (ZCZ ball V14) */ - P9_23_default_pin: pinmux_P9_23_default_pin { - pinctrl-single,pins = <0x044 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_23_gpio_pin: pinmux_P9_23_gpio_pin { - pinctrl-single,pins = <0x044 0x2F>; }; /* Mode 7, RxActive */ - P9_23_gpio_pu_pin: pinmux_P9_23_gpio_pu_pin { - pinctrl-single,pins = <0x044 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_23_gpio_pd_pin: pinmux_P9_23_gpio_pd_pin { - pinctrl-single,pins = <0x044 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_23_pwm_pin: pinmux_P9_23_pwm_pin { - pinctrl-single,pins = <0x044 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - - /* P9_24 (ZCZ ball D15) */ - P9_24_default_pin: pinmux_P9_24_default_pin { - pinctrl-single,pins = <0x184 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_24_gpio_pin: pinmux_P9_24_gpio_pin { - pinctrl-single,pins = <0x184 0x2F>; }; /* Mode 7, RxActive */ - P9_24_gpio_pu_pin: pinmux_P9_24_gpio_pu_pin { - pinctrl-single,pins = <0x184 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_24_gpio_pd_pin: pinmux_P9_24_gpio_pd_pin { - pinctrl-single,pins = <0x184 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_24_uart_pin: pinmux_P9_24_uart_pin { - pinctrl-single,pins = <0x184 0x30>; }; /* Mode 0, Pull-Up, RxActive */ - P9_24_can_pin: pinmux_P9_24_can_pin { - pinctrl-single,pins = <0x184 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - P9_24_i2c_pin: pinmux_P9_24_i2c_pin { - pinctrl-single,pins = <0x184 0x33>; }; /* Mode 3, Pull-Up, RxActive */ - P9_24_pru_uart_pin: pinmux_P9_24_pru_uart_pin { - pinctrl-single,pins = <0x184 0x35>; }; /* Mode 5, Pull-Up, RxActive */ - P9_24_pruin_pin: pinmux_P9_24_pruin_pin { - pinctrl-single,pins = <0x184 0x36>; }; /* Mode 6, Pull-Up, RxActive */ - - /* P9_25 (ZCZ ball A14) Audio */ - - /* P9_26 (ZCZ ball D16) */ - P9_26_default_pin: pinmux_P9_26_default_pin { - pinctrl-single,pins = <0x180 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_26_gpio_pin: pinmux_P9_26_gpio_pin { - pinctrl-single,pins = <0x180 0x2F>; }; /* Mode 7, RxActive */ - P9_26_gpio_pu_pin: pinmux_P9_26_gpio_pu_pin { - pinctrl-single,pins = <0x180 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_26_gpio_pd_pin: pinmux_P9_26_gpio_pd_pin { - pinctrl-single,pins = <0x180 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_26_uart_pin: pinmux_P9_26_uart_pin { - pinctrl-single,pins = <0x180 0x30>; }; /* Mode 0, Pull-Up, RxActive */ - P9_26_can_pin: pinmux_P9_26_can_pin { - pinctrl-single,pins = <0x180 0x32>; }; /* Mode 2, Pull-Up, RxActive */ - P9_26_i2c_pin: pinmux_P9_26_i2c_pin { - pinctrl-single,pins = <0x180 0x33>; }; /* Mode 3, Pull-Up, RxActive */ - P9_26_pru_uart_pin: pinmux_P9_26_pru_uart_pin { - pinctrl-single,pins = <0x180 0x35>; }; /* Mode 5, Pull-Up, RxActive */ - P9_26_pruin_pin: pinmux_P9_26_pruin_pin { - pinctrl-single,pins = <0x180 0x36>; }; /* Mode 6, Pull-Up, RxActive */ - - /* P9_27 (ZCZ ball C13) */ - P9_27_default_pin: pinmux_P9_27_default_pin { - pinctrl-single,pins = <0x1a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_27_gpio_pin: pinmux_P9_27_gpio_pin { - pinctrl-single,pins = <0x1a4 0x2F>; }; /* Mode 7, RxActive */ - P9_27_gpio_pu_pin: pinmux_P9_27_gpio_pu_pin { - pinctrl-single,pins = <0x1a4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_27_gpio_pd_pin: pinmux_P9_27_gpio_pd_pin { - pinctrl-single,pins = <0x1a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_27_qep_pin: pinmux_P9_27_qep_pin { - pinctrl-single,pins = <0x1a4 0x21>; }; /* Mode 1, Pull-Down, RxActive */ - P9_27_pruout_pin: pinmux_P9_27_pruout_pin { - pinctrl-single,pins = <0x1a4 0x25>; }; /* Mode 5, Pull-Down, RxActive */ - P9_27_pruin_pin: pinmux_P9_27_pruin_pin { - pinctrl-single,pins = <0x1a4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - - /* P9_28 (ZCZ ball C12) Audio */ - /* P9_29 (ZCZ ball B13) Audio */ - - /* P9_30 (ZCZ ball D12) */ - P9_30_default_pin: pinmux_P9_30_default_pin { - pinctrl-single,pins = <0x198 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_30_gpio_pin: pinmux_P9_30_gpio_pin { - pinctrl-single,pins = <0x198 0x2F>; }; /* Mode 7, RxActive */ - P9_30_gpio_pu_pin: pinmux_P9_30_gpio_pu_pin { - pinctrl-single,pins = <0x198 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_30_gpio_pd_pin: pinmux_P9_30_gpio_pd_pin { - pinctrl-single,pins = <0x198 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_30_pwm_pin: pinmux_P9_30_pwm_pin { - pinctrl-single,pins = <0x198 0x21>; }; /* Mode 1, Pull-Down, RxActive */ - P9_30_spi_pin: pinmux_P9_30_spi_pin { - pinctrl-single,pins = <0x198 0x23>; }; /* Mode 3, Pull-Down, RxActive */ - P9_30_pruout_pin: pinmux_P9_30_pruout_pin { - pinctrl-single,pins = <0x198 0x25>; }; /* Mode 5, Pull-Down, RxActive */ - P9_30_pruin_pin: pinmux_P9_30_pruin_pin { - pinctrl-single,pins = <0x198 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - - /* P9_31 (ZCZ ball A13) Audio */ - - /* P9_32 VADC */ - /* P9_33 (ZCZ ball C8 ) AIN4 */ - /* P9_34 AGND */ - /* P9_35 (ZCZ ball A8 ) AIN6 */ - /* P9_36 (ZCZ ball B8 ) AIN5 */ - /* P9_37 (ZCZ ball B7 ) AIN2 */ - /* P9_38 (ZCZ ball A7 ) AIN3 */ - /* P9_39 (ZCZ ball B6 ) AIN0 */ - /* P9_40 (ZCZ ball C7 ) AIN1 */ - - /* P9_41 (ZCZ ball D14) */ - P9_41_default_pin: pinmux_P9_41_default_pin { - pinctrl-single,pins = <0x1b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_41_gpio_pin: pinmux_P9_41_gpio_pin { - pinctrl-single,pins = <0x1b4 0x2F>; }; /* Mode 7, RxActive */ - P9_41_gpio_pu_pin: pinmux_P9_41_gpio_pu_pin { - pinctrl-single,pins = <0x1b4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_41_gpio_pd_pin: pinmux_P9_41_gpio_pd_pin { - pinctrl-single,pins = <0x1b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_41_timer_pin: pinmux_P9_41_timer_pin { - pinctrl-single,pins = <0x1b4 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - P9_41_pruin_pin: pinmux_P9_41_pruin_pin { - pinctrl-single,pins = <0x1b4 0x25>; }; /* Mode 5, Pull-Down, RxActive */ - - /* P9_41.1 */ - /* P9_91 (ZCZ ball D13) */ - P9_91_default_pin: pinmux_P9_91_default_pin { - pinctrl-single,pins = <0x1a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_91_gpio_pin: pinmux_P9_91_gpio_pin { - pinctrl-single,pins = <0x1a8 0x2F>; }; /* Mode 7, RxActive */ - P9_91_gpio_pu_pin: pinmux_P9_91_gpio_pu_pin { - pinctrl-single,pins = <0x1a8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_91_gpio_pd_pin: pinmux_P9_91_gpio_pd_pin { - pinctrl-single,pins = <0x1a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_91_qep_pin: pinmux_P9_91_qep_pin { - pinctrl-single,pins = <0x1a8 0x21>; }; /* Mode 1, Pull-Down, RxActive */ - P9_91_pruout_pin: pinmux_P9_91_pruout_pin { - pinctrl-single,pins = <0x1a8 0x25>; }; /* Mode 5, Pull-Down, RxActive */ - P9_91_pruin_pin: pinmux_P9_91_pruin_pin { - pinctrl-single,pins = <0x1a8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - - /* P9_42 (ZCZ ball C18) */ - P9_42_default_pin: pinmux_P9_42_default_pin { - pinctrl-single,pins = <0x164 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_42_gpio_pin: pinmux_P9_42_gpio_pin { - pinctrl-single,pins = <0x164 0x2F>; }; /* Mode 7, RxActive */ - P9_42_gpio_pu_pin: pinmux_P9_42_gpio_pu_pin { - pinctrl-single,pins = <0x164 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_42_gpio_pd_pin: pinmux_P9_42_gpio_pd_pin { - pinctrl-single,pins = <0x164 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_42_pwm_pin: pinmux_P9_42_pwm_pin { - pinctrl-single,pins = <0x164 0x20>; }; /* Mode 0, Pull-Down, RxActive */ - P9_42_uart_pin: pinmux_P9_42_uart_pin { - pinctrl-single,pins = <0x164 0x21>; }; /* Mode 1, Pull-Down, RxActive */ - P9_42_spics_pin: pinmux_P9_42_spics_pin { - pinctrl-single,pins = <0x164 0x22>; }; /* Mode 2, Pull-Down, RxActive */ - P9_42_pru_ecap_pin: pinmux_P9_42_pru_ecap_pin { - pinctrl-single,pins = <0x164 0x23>; }; /* Mode 3, Pull-Down, RxActive */ - P9_42_spiclk_pin: pinmux_P9_42_spiclk_pin { - pinctrl-single,pins = <0x164 0x24>; }; /* Mode 4, Pull-Down, RxActive */ - - /* P9_42.1 */ - /* P9_92 (ZCZ ball B12) */ - P9_92_default_pin: pinmux_P9_92_default_pin { - pinctrl-single,pins = <0x1a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_92_gpio_pin: pinmux_P9_92_gpio_pin { - pinctrl-single,pins = <0x1a0 0x2F>; }; /* Mode 7, RxActive */ - P9_92_gpio_pu_pin: pinmux_P9_92_gpio_pu_pin { - pinctrl-single,pins = <0x1a0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ - P9_92_gpio_pd_pin: pinmux_P9_92_gpio_pd_pin { - pinctrl-single,pins = <0x1a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ - P9_92_qep_pin: pinmux_P9_92_qep_pin { - pinctrl-single,pins = <0x1a0 0x21>; }; /* Mode 1, Pull-Down, RxActive */ - P9_92_pruout_pin: pinmux_P9_92_pruout_pin { - pinctrl-single,pins = <0x1a0 0x25>; }; /* Mode 5, Pull-Down, RxActive */ - P9_92_pruin_pin: pinmux_P9_92_pruin_pin { - pinctrl-single,pins = <0x1a0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ - - /* P9_43 GND */ - /* P9_44 GND */ - /* P9_45 GND */ - /* P9_46 GND */ - - }; - }; - - - /************************/ - /* Pin Multiplexing */ - /************************/ - - fragment@1 { - target = <&ocp>; - __overlay__ { - - /************************/ - /* P8 Header */ - /************************/ - - P8_07_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; - pinctrl-0 = <&P8_07_default_pin>; - pinctrl-1 = <&P8_07_gpio_pin>; - pinctrl-2 = <&P8_07_gpio_pu_pin>; - pinctrl-3 = <&P8_07_gpio_pd_pin>; - pinctrl-4 = <&P8_07_timer_pin>; - }; - - P8_08_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; - pinctrl-0 = <&P8_08_default_pin>; - pinctrl-1 = <&P8_08_gpio_pin>; - pinctrl-2 = <&P8_08_gpio_pu_pin>; - pinctrl-3 = <&P8_08_gpio_pd_pin>; - pinctrl-4 = <&P8_08_timer_pin>; - }; - - P8_09_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; - pinctrl-0 = <&P8_09_default_pin>; - pinctrl-1 = <&P8_09_gpio_pin>; - pinctrl-2 = <&P8_09_gpio_pu_pin>; - pinctrl-3 = <&P8_09_gpio_pd_pin>; - pinctrl-4 = <&P8_09_timer_pin>; - }; - - P8_10_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; - pinctrl-0 = <&P8_10_default_pin>; - pinctrl-1 = <&P8_10_gpio_pin>; - pinctrl-2 = <&P8_10_gpio_pu_pin>; - pinctrl-3 = <&P8_10_gpio_pd_pin>; - pinctrl-4 = <&P8_10_timer_pin>; - }; - - P8_11_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "qep"; - pinctrl-0 = <&P8_11_default_pin>; - pinctrl-1 = <&P8_11_gpio_pin>; - pinctrl-2 = <&P8_11_gpio_pu_pin>; - pinctrl-3 = <&P8_11_gpio_pd_pin>; - pinctrl-4 = <&P8_11_pruout_pin>; - pinctrl-5 = <&P8_11_qep_pin>; - }; - - P8_12_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "qep"; - pinctrl-0 = <&P8_12_default_pin>; - pinctrl-1 = <&P8_12_gpio_pin>; - pinctrl-2 = <&P8_12_gpio_pu_pin>; - pinctrl-3 = <&P8_12_gpio_pd_pin>; - pinctrl-4 = <&P8_12_pruout_pin>; - pinctrl-5 = <&P8_12_qep_pin>; - }; - - P8_13_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; - pinctrl-0 = <&P8_13_default_pin>; - pinctrl-1 = <&P8_13_gpio_pin>; - pinctrl-2 = <&P8_13_gpio_pu_pin>; - pinctrl-3 = <&P8_13_gpio_pd_pin>; - pinctrl-4 = <&P8_13_pwm_pin>; - }; - - P8_14_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; - pinctrl-0 = <&P8_14_default_pin>; - pinctrl-1 = <&P8_14_gpio_pin>; - pinctrl-2 = <&P8_14_gpio_pu_pin>; - pinctrl-3 = <&P8_14_gpio_pd_pin>; - pinctrl-4 = <&P8_14_pwm_pin>; - }; - - P8_15_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruin", "pru_ecap", "qep"; - pinctrl-0 = <&P8_15_default_pin>; - pinctrl-1 = <&P8_15_gpio_pin>; - pinctrl-2 = <&P8_15_gpio_pu_pin>; - pinctrl-3 = <&P8_15_gpio_pd_pin>; - pinctrl-4 = <&P8_15_pruin_pin>; - pinctrl-5 = <&P8_15_pru_ecap_pin>; - pinctrl-6 = <&P8_15_qep_pin>; - }; - - P8_16_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruin", "qep"; - pinctrl-0 = <&P8_16_default_pin>; - pinctrl-1 = <&P8_16_gpio_pin>; - pinctrl-2 = <&P8_16_gpio_pu_pin>; - pinctrl-3 = <&P8_16_gpio_pd_pin>; - pinctrl-4 = <&P8_16_pruin_pin>; - pinctrl-5 = <&P8_16_qep_pin>; - }; - - P8_17_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; - pinctrl-0 = <&P8_17_default_pin>; - pinctrl-1 = <&P8_17_gpio_pin>; - pinctrl-2 = <&P8_17_gpio_pu_pin>; - pinctrl-3 = <&P8_17_gpio_pd_pin>; - pinctrl-4 = <&P8_17_pwm_pin>; - }; - - P8_18_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; - pinctrl-0 = <&P8_18_default_pin>; - pinctrl-1 = <&P8_18_gpio_pin>; - pinctrl-2 = <&P8_18_gpio_pu_pin>; - pinctrl-3 = <&P8_18_gpio_pd_pin>; - }; - - P8_19_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; - pinctrl-0 = <&P8_19_default_pin>; - pinctrl-1 = <&P8_19_gpio_pin>; - pinctrl-2 = <&P8_19_gpio_pu_pin>; - pinctrl-3 = <&P8_19_gpio_pd_pin>; - pinctrl-4 = <&P8_19_pwm_pin>; - }; - - P8_26_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; - pinctrl-0 = <&P8_26_default_pin>; - pinctrl-1 = <&P8_26_gpio_pin>; - pinctrl-2 = <&P8_26_gpio_pu_pin>; - pinctrl-3 = <&P8_26_gpio_pd_pin>; - }; - - - /************************/ - /* P9 Header */ - /************************/ - - P9_11_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart"; - pinctrl-0 = <&P9_11_default_pin>; - pinctrl-1 = <&P9_11_gpio_pin>; - pinctrl-2 = <&P9_11_gpio_pu_pin>; - pinctrl-3 = <&P9_11_gpio_pd_pin>; - pinctrl-4 = <&P9_11_uart_pin>; - }; - - P9_12_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; - pinctrl-0 = <&P9_12_default_pin>; - pinctrl-1 = <&P9_12_gpio_pin>; - pinctrl-2 = <&P9_12_gpio_pu_pin>; - pinctrl-3 = <&P9_12_gpio_pd_pin>; - }; - - P9_13_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart"; - pinctrl-0 = <&P9_13_default_pin>; - pinctrl-1 = <&P9_13_gpio_pin>; - pinctrl-2 = <&P9_13_gpio_pu_pin>; - pinctrl-3 = <&P9_13_gpio_pd_pin>; - pinctrl-4 = <&P9_13_uart_pin>; - }; - - P9_14_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; - pinctrl-0 = <&P9_14_default_pin>; - pinctrl-1 = <&P9_14_gpio_pin>; - pinctrl-2 = <&P9_14_gpio_pu_pin>; - pinctrl-3 = <&P9_14_gpio_pd_pin>; - pinctrl-4 = <&P9_14_pwm_pin>; - }; - - P9_15_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; - pinctrl-0 = <&P9_15_default_pin>; - pinctrl-1 = <&P9_15_gpio_pin>; - pinctrl-2 = <&P9_15_gpio_pu_pin>; - pinctrl-3 = <&P9_15_gpio_pd_pin>; - pinctrl-4 = <&P9_15_pwm_pin>; - }; - - P9_16_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; - pinctrl-0 = <&P9_16_default_pin>; - pinctrl-1 = <&P9_16_gpio_pin>; - pinctrl-2 = <&P9_16_gpio_pu_pin>; - pinctrl-3 = <&P9_16_gpio_pd_pin>; - pinctrl-4 = <&P9_16_pwm_pin>; - }; - - P9_17_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm", "pru_uart"; - pinctrl-0 = <&P9_17_default_pin>; - pinctrl-1 = <&P9_17_gpio_pin>; - pinctrl-2 = <&P9_17_gpio_pu_pin>; - pinctrl-3 = <&P9_17_gpio_pd_pin>; - pinctrl-4 = <&P9_17_spi_pin>; - pinctrl-5 = <&P9_17_i2c_pin>; - pinctrl-6 = <&P9_17_pwm_pin>; - pinctrl-7 = <&P9_17_pru_uart_pin>; - }; - - P9_18_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm", "pru_uart"; - pinctrl-0 = <&P9_18_default_pin>; - pinctrl-1 = <&P9_18_gpio_pin>; - pinctrl-2 = <&P9_18_gpio_pu_pin>; - pinctrl-3 = <&P9_18_gpio_pd_pin>; - pinctrl-4 = <&P9_18_spi_pin>; - pinctrl-5 = <&P9_18_i2c_pin>; - pinctrl-6 = <&P9_18_pwm_pin>; - pinctrl-7 = <&P9_18_pru_uart_pin>; - }; - - // I2C Pins - // P9_19_pinmux - // P9_20_pinmux - - P9_21_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm", "pru_uart"; - pinctrl-0 = <&P9_21_default_pin>; - pinctrl-1 = <&P9_21_gpio_pin>; - pinctrl-2 = <&P9_21_gpio_pu_pin>; - pinctrl-3 = <&P9_21_gpio_pd_pin>; - pinctrl-4 = <&P9_21_spi_pin>; - pinctrl-5 = <&P9_21_uart_pin>; - pinctrl-6 = <&P9_21_i2c_pin>; - pinctrl-7 = <&P9_21_pwm_pin>; - pinctrl-8 = <&P9_21_pru_uart_pin>; - }; - - P9_22_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm", "pru_uart"; - pinctrl-0 = <&P9_22_default_pin>; - pinctrl-1 = <&P9_22_gpio_pin>; - pinctrl-2 = <&P9_22_gpio_pu_pin>; - pinctrl-3 = <&P9_22_gpio_pd_pin>; - pinctrl-4 = <&P9_22_spi_pin>; - pinctrl-5 = <&P9_22_uart_pin>; - pinctrl-6 = <&P9_22_i2c_pin>; - pinctrl-7 = <&P9_22_pwm_pin>; - pinctrl-8 = <&P9_22_pru_uart_pin>; - }; - - P9_23_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; - pinctrl-0 = <&P9_23_default_pin>; - pinctrl-1 = <&P9_23_gpio_pin>; - pinctrl-2 = <&P9_23_gpio_pu_pin>; - pinctrl-3 = <&P9_23_gpio_pd_pin>; - pinctrl-4 = <&P9_23_pwm_pin>; - }; - - P9_24_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pru_uart", "pruin"; - pinctrl-0 = <&P9_24_default_pin>; - pinctrl-1 = <&P9_24_gpio_pin>; - pinctrl-2 = <&P9_24_gpio_pu_pin>; - pinctrl-3 = <&P9_24_gpio_pd_pin>; - pinctrl-4 = <&P9_24_uart_pin>; - pinctrl-5 = <&P9_24_can_pin>; - pinctrl-6 = <&P9_24_i2c_pin>; - pinctrl-7 = <&P9_24_pru_uart_pin>; - pinctrl-8 = <&P9_24_pruin_pin>; - }; - - - // Audio pin - // P9_25_pinmux - - P9_26_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pru_uart", "pruin"; - pinctrl-0 = <&P9_26_default_pin>; - pinctrl-1 = <&P9_26_gpio_pin>; - pinctrl-2 = <&P9_26_gpio_pu_pin>; - pinctrl-3 = <&P9_26_gpio_pd_pin>; - pinctrl-4 = <&P9_26_uart_pin>; - pinctrl-5 = <&P9_26_can_pin>; - pinctrl-6 = <&P9_26_i2c_pin>; - pinctrl-7 = <&P9_26_pru_uart_pin>; - pinctrl-8 = <&P9_26_pruin_pin>; - }; - - P9_27_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; - pinctrl-0 = <&P9_27_default_pin>; - pinctrl-1 = <&P9_27_gpio_pin>; - pinctrl-2 = <&P9_27_gpio_pu_pin>; - pinctrl-3 = <&P9_27_gpio_pd_pin>; - pinctrl-4 = <&P9_27_qep_pin>; - pinctrl-5 = <&P9_27_pruout_pin>; - pinctrl-6 = <&P9_27_pruin_pin>; - }; - - // Audio pins - // P9_28_pinmux - // P9_29_pinmux - - P9_30_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; - pinctrl-0 = <&P9_30_default_pin>; - pinctrl-1 = <&P9_30_gpio_pin>; - pinctrl-2 = <&P9_30_gpio_pu_pin>; - pinctrl-3 = <&P9_30_gpio_pd_pin>; - pinctrl-4 = <&P9_30_pwm_pin>; - pinctrl-5 = <&P9_30_spi_pin>; - pinctrl-6 = <&P9_30_pruout_pin>; - pinctrl-7 = <&P9_30_pruin_pin>; - }; - - // Audio pin - // P9_31_pinmux - - P9_41_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer", "pruin"; - pinctrl-0 = <&P9_41_default_pin>; - pinctrl-1 = <&P9_41_gpio_pin>; - pinctrl-2 = <&P9_41_gpio_pu_pin>; - pinctrl-3 = <&P9_41_gpio_pd_pin>; - pinctrl-4 = <&P9_41_timer_pin>; - pinctrl-5 = <&P9_41_pruin_pin>; - }; - - P9_91_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; - pinctrl-0 = <&P9_91_default_pin>; - pinctrl-1 = <&P9_91_gpio_pin>; - pinctrl-2 = <&P9_91_gpio_pu_pin>; - pinctrl-3 = <&P9_91_gpio_pd_pin>; - pinctrl-4 = <&P9_91_qep_pin>; - pinctrl-5 = <&P9_91_pruout_pin>; - pinctrl-6 = <&P9_91_pruin_pin>; - }; - - P9_42_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "uart", "spics", "pru_ecap", "spiclk"; - pinctrl-0 = <&P9_42_default_pin>; - pinctrl-1 = <&P9_42_gpio_pin>; - pinctrl-2 = <&P9_42_gpio_pu_pin>; - pinctrl-3 = <&P9_42_gpio_pd_pin>; - pinctrl-4 = <&P9_42_pwm_pin>; - pinctrl-5 = <&P9_42_uart_pin>; - pinctrl-6 = <&P9_42_spics_pin>; - pinctrl-7 = <&P9_42_pru_ecap_pin>; - pinctrl-8 = <&P9_42_spiclk_pin>; - }; - - P9_92_pinmux { - compatible = "bone-pinmux-helper"; - status = "okay"; - pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; - pinctrl-0 = <&P9_92_default_pin>; - pinctrl-1 = <&P9_92_gpio_pin>; - pinctrl-2 = <&P9_92_gpio_pu_pin>; - pinctrl-3 = <&P9_92_gpio_pd_pin>; - pinctrl-4 = <&P9_92_qep_pin>; - pinctrl-5 = <&P9_92_pruout_pin>; - pinctrl-6 = <&P9_92_pruin_pin>; - }; - }; - }; - - fragment@2 { - target = <&ocp>; - __overlay__ { - - // !!!WARNING!!! - // gpio-of-helper &gpio pointers are off-by-one vs. the hardware: - // hardware GPIO bank 0 = &gpio1 - cape-universal { - compatible = "gpio-of-helper"; - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - - P8_07 { - gpio-name = "P8_07"; - gpio = <&gpio3 2 0>; - input; - dir-changeable; - }; - P8_08 { - gpio-name = "P8_08"; - gpio = <&gpio3 3 0>; - input; - dir-changeable; - }; - P8_09 { - gpio-name = "P8_09"; - gpio = <&gpio3 5 0>; - input; - dir-changeable; - }; - P8_10 { - gpio-name = "P8_10"; - gpio = <&gpio3 4 0>; - input; - dir-changeable; - }; - P8_11 { - gpio-name = "P8_11"; - gpio = <&gpio2 13 0>; - input; - dir-changeable; - }; - P8_12 { - gpio-name = "P8_12"; - gpio = <&gpio2 12 0>; - input; - dir-changeable; - }; - P8_13 { - gpio-name = "P8_13"; - gpio = <&gpio1 23 0>; - input; - dir-changeable; - }; - P8_14 { - gpio-name = "P8_14"; - gpio = <&gpio1 26 0>; - input; - dir-changeable; - }; - P8_15 { - gpio-name = "P8_15"; - gpio = <&gpio2 15 0>; - input; - dir-changeable; - }; - P8_16 { - gpio-name = "P8_16"; - gpio = <&gpio2 14 0>; - input; - dir-changeable; - }; - P8_17 { - gpio-name = "P8_17"; - gpio = <&gpio1 27 0>; - input; - dir-changeable; - }; - P8_18 { - gpio-name = "P8_18"; - gpio = <&gpio3 1 0>; - input; - dir-changeable; - }; - P8_19 { - gpio-name = "P8_19"; - gpio = <&gpio1 22 0>; - input; - dir-changeable; - }; - P8_26 { - gpio-name = "P8_26"; - gpio = <&gpio2 29 0>; - input; - dir-changeable; - }; - - - P9_11 { - gpio-name = "P9_11"; - gpio = <&gpio1 30 0>; - input; - dir-changeable; - }; - P9_12 { - gpio-name = "P9_12"; - gpio = <&gpio2 28 0>; - input; - dir-changeable; - }; - P9_13 { - gpio-name = "P9_13"; - gpio = <&gpio1 31 0>; - input; - dir-changeable; - }; - P9_14 { - gpio-name = "P9_14"; - gpio = <&gpio2 18 0>; - input; - dir-changeable; - }; - P9_15 { - gpio-name = "P9_15"; - gpio = <&gpio2 16 0>; - input; - dir-changeable; - }; - P9_16 { - gpio-name = "P9_16"; - gpio = <&gpio2 19 0>; - input; - dir-changeable; - }; - P9_17 { - gpio-name = "P9_17"; - gpio = <&gpio1 5 0>; - input; - dir-changeable; - }; - P9_18 { - gpio-name = "P9_18"; - gpio = <&gpio1 4 0>; - input; - dir-changeable; - }; - - // I2C pins - // P9_19 - // P9_20 - - P9_21 { - gpio-name = "P9_21"; - gpio = <&gpio1 3 0>; - input; - dir-changeable; - }; - P9_22 { - gpio-name = "P9_22"; - gpio = <&gpio1 2 0>; - input; - dir-changeable; - }; - P9_23 { - gpio-name = "P9_23"; - gpio = <&gpio2 17 0>; - input; - dir-changeable; - }; - P9_24 { - gpio-name = "P9_24"; - gpio = <&gpio1 15 0>; - input; - dir-changeable; - }; - - // Audio pin - // P9_25 - - P9_26 { - gpio-name = "P9_26"; - gpio = <&gpio1 14 0>; - input; - dir-changeable; - }; - P9_27 { - gpio-name = "P9_27"; - gpio = <&gpio4 19 0>; - input; - dir-changeable; - }; - - // Audio pins - // P9_28 - // P9_29 - - P9_30 { - gpio-name = "P9_30"; - gpio = <&gpio4 16 0>; - input; - dir-changeable; - }; - - // Audio pin - // P9_31 - - P9_41 { - gpio-name = "P9_41"; - gpio = <&gpio1 20 0>; - input; - dir-changeable; - }; - P9_91 { - gpio-name = "P9_91"; - gpio = <&gpio4 20 0>; - input; - dir-changeable; - }; - P9_42 { - gpio-name = "P9_42"; - gpio = <&gpio1 7 0>; - input; - dir-changeable; - }; - P9_92 { - gpio-name = "P9_92"; - gpio = <&gpio4 18 0>; - input; - dir-changeable; - }; - }; - }; - }; - - - - /************************/ - /* UARTs */ - /************************/ - - fragment@10 { - target = <&uart2>; /* really uart1 */ - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - fragment@11 { - target = <&uart3>; /* really uart2 */ - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - fragment@12 { - target = <&uart5>; /* really uart4 */ - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - -// /* UART 5 only available on LCD/HDMI pins */ -// fragment@13 { -// target = <&uart6>; /* really uart5 */ -// __overlay__ { -// status = "okay"; -// pinctrl-names = "default"; -// pinctrl-0 = <>; -// }; -// }; - - /************************/ - /* Timers / PWM */ - /************************/ - - fragment@20 { - target = <&epwmss0>; - __overlay__ { - status = "okay"; - }; - }; - - fragment@21 { - target = <&ehrpwm0>; - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - fragment@22 { - target = <&ecap0>; - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - fragment@23 { - target = <&epwmss1>; - __overlay__ { - status = "okay"; - }; - }; - - fragment@24 { - target = <&ehrpwm1>; - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - fragment@25 { - target = <&epwmss2>; - __overlay__ { - status = "okay"; - }; - }; - - fragment@26 { - target = <&ehrpwm2>; - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - fragment@27 { - target = <&ecap2>; - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - /************************/ - /* I2C / SPI */ - /************************/ - - - fragment@30 { - target = <&i2c1>; /* i2c1 is numbered correctly */ - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - - /* this is the configuration part */ - clock-frequency = <100000>; - - #address-cells = <1>; - #size-cells = <0>; - - /* add any i2c devices on the bus here */ - - // commented out example of a touchscreen (taken from BB-BONE-LCD7-01-00A4) */ - // maxtouch@4a { - // compatible = "mXT224"; - // reg = <0x4a>; - // interrupt-parent = <&gpio4>; - // interrupts = <19 0x0>; - // atmel,irq-gpio = <&gpio4 19 0>; - // }; - }; - }; - - fragment@31 { - target = <&spi0>; /* spi0 is numbered correctly */ - __overlay__ { - #address-cells = <1>; - #size-cells = <0>; - - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - - spi0channel@0 { - #address-cells = <1>; - #size-cells = <0>; - - compatible = "spidev"; - - reg = <0>; - spi-max-frequency = <16000000>; - spi-cpha; - }; - - - spi0channel@1 { - #address-cells = <1>; - #size-cells = <0>; - - compatible = "spidev"; - - reg = <1>; - spi-max-frequency = <16000000>; - }; - }; - }; - - fragment@32 { - target = <&spi1>; /* spi1 is numbered correctly */ - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - - #address-cells = <1>; - #size-cells = <0>; - - spi1channel@0 { - #address-cells = <1>; - #size-cells = <0>; - - compatible = "spidev"; - - reg = <0>; - spi-max-frequency = <16000000>; - spi-cpha; - }; - - spi1channel@1 { - #address-cells = <1>; - #size-cells = <0>; - - compatible = "spidev"; - - reg = <1>; - spi-max-frequency = <16000000>; - }; - }; - }; - - fragment@33 { - target = <&dcan0>; - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - fragment@34 { - target = <&dcan1>; - __overlay__ { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <>; - }; - }; - - - /************************/ - /* PRUSS */ - /************************/ - - fragment@40 { - target = <&pruss>; - __overlay__ { - status = "okay"; - }; - }; - - - /************************/ - /* eQEP */ - /************************/ - - fragment@50 { - target = <&eqep0>; - __overlay__ { - pinctrl-names = "default"; - pinctrl-0 = <>; - - count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ - swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ - invert_qa = <1>; /* Should we invert the channel A input? */ - invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ - invert_qi = <0>; /* Should we invert the index input? */ - invert_qs = <0>; /* Should we invert the strobe input? */ - - status = "okay"; - }; - }; - - fragment@51 { - target = <&eqep1>; - __overlay__ { - pinctrl-names = "default"; - pinctrl-0 = <>; - - count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ - swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ - invert_qa = <1>; /* Should we invert the channel A input? */ - invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ - invert_qi = <0>; /* Should we invert the index input? */ - invert_qs = <0>; /* Should we invert the strobe input? */ - - status = "okay"; - }; - }; - - fragment@52 { - target = <&eqep2>; - __overlay__ { - pinctrl-names = "default"; - pinctrl-0 = <>; - - count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ - swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ - invert_qa = <1>; /* Should we invert the channel A input? */ - invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ - invert_qi = <0>; /* Should we invert the index input? */ - invert_qs = <0>; /* Should we invert the strobe input? */ - - status = "okay"; - }; - }; -}; From 002c1d8c0a43b9f5dcbc19e9468a7b5789d6f2d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 17:19:21 +0200 Subject: [PATCH 33/47] Delete obsolete startup.sh --- util/startup.sh | 4 ---- 1 file changed, 4 deletions(-) delete mode 100755 util/startup.sh diff --git a/util/startup.sh b/util/startup.sh deleted file mode 100755 index f7fd68d..0000000 --- a/util/startup.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -ls -cd "LabConnections.jl/test/BeagleBone" -sudo /home/debian/julia-903644385b/bin/julia From b2a2f41b780bc7157020d5ceb79fb2f167260fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 17:40:09 +0200 Subject: [PATCH 34/47] Updated development instructions --- docs/build/man/development.md | 28 +++++++++++++++++++++++++--- docs/src/man/development.md | 14 ++++++++++++-- util/copy_BB.sh | 33 --------------------------------- 3 files changed, 37 insertions(+), 38 deletions(-) delete mode 100755 util/copy_BB.sh diff --git a/docs/build/man/development.md b/docs/build/man/development.md index 5670c25..0d02f32 100644 --- a/docs/build/man/development.md +++ b/docs/build/man/development.md @@ -29,10 +29,32 @@ git pull to ensure that you are working on the correct development branch for Julia v1.0.X. You can now edit the code in `.julia/dev/LabConnections` and run it using a Julia REPL. When you are satisfied with your changes, simply commit and push the changes in the `.julia/dev/LabConnections` directory to the GitLab server. - + -## Development with the BeagleBone in the loop +## Development with the BeagleBone -The pin map of the BeagleBone (BB) is shown below. When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. + + +### Transferring development code from host to the BeagleBone + + +Because of the limited performance of the BeagleBone (BB), it is often preferable to do most code development on the host computer. However, you will also do testing of the code locally on the BB, and will thus need to transfer the latest code from the host computer to the BB. To do this, there is a handy utility shell script found in `/util` that handles this. Open a terminal on the host computer and type + + +``` +cd ~/.julia/dev/LabConnections/util +./copyfoldertobb.sh +``` + + +This will transfer the current development version of `LabConnections.jl` found in the `/dev` directory to the BB. + + + + +### Development with hardware in the loop + + +When testing `LabConnections.jl` with hardware in the loop, the external hardware will be connected to the pin headers on the BB. For reference, the pin map of the BeagleBone (BB) is shown below. When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. diff --git a/docs/src/man/development.md b/docs/src/man/development.md index 5a7f001..61428e6 100644 --- a/docs/src/man/development.md +++ b/docs/src/man/development.md @@ -13,7 +13,17 @@ git pull to ensure that you are working on the correct development branch for Julia v1.0.X. You can now edit the code in `.julia/dev/LabConnections` and run it using a Julia REPL. When you are satisfied with your changes, simply commit and push the changes in the `.julia/dev/LabConnections` directory to the GitLab server. -## Development with the BeagleBone in the loop -The pin map of the BeagleBone (BB) is shown below. +## Development with the BeagleBone + +### Transferring development code from host to the BeagleBone +Because of the limited performance of the BeagleBone (BB), it is often preferable to do most code development on the host computer. However, you will also do testing of the code locally on the BB, and will thus need to transfer the latest code from the host computer to the BB. To do this, there is a handy utility shell script found in `/util` that handles this. Open a terminal on the host computer and type +``` +cd ~/.julia/dev/LabConnections/util +./copyfoldertobb.sh +``` +This will transfer the current development version of `LabConnections.jl` found in the `/dev` directory to the BB. + +### Development with hardware in the loop +When testing `LabConnections.jl` with hardware in the loop, the external hardware will be connected to the pin headers on the BB. For reference, the pin map of the BeagleBone (BB) is shown below. When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. diff --git a/util/copy_BB.sh b/util/copy_BB.sh deleted file mode 100755 index 7e6de24..0000000 --- a/util/copy_BB.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -#Run in this file un util folder, copies to BB -BLUE='\033[0;34m' -GREEN='\033[0;32m' -RED='\033[0;31m' -NC='\033[0m' -BASEDIR=../$(dirname "$0") - -# store arguments in a special array -args=("$@") -# get number of elements -numberOfArguments=${#args[@]} -echo $ELEMENTS -# echo each element in array -# for loop -#for (( i=0;i<$ELEMENTS;i++)); do -# echo ${args[${i}]} -#done - -if [ ${#args[@]} == 0 ] -then - printf "${RED}ABORTING.${NC} No directory provided\n" -else - for (( i=0;i<$numberOfArguments;i++)); do - if [ -d $BASEDIR/${args[${i}]} ] - then - printf "${GREEN}Copying $BASEDIR/${args[${i}]} to BB${NC}\n" - scp -r $BASEDIR/${args[${i}]} debian@192.168.7.2:/home/debian/juliapackages/LabConnections/${args[${i}]} - else - printf "${RED}ABORTING.${NC} The provided directory $BASEDIR/${args[${i}]} does not exist\n" - fi - done -fi From cb48ab8724e76aa502fe4d3fdf869c76613100ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20F=C3=A4lt?= Date: Mon, 15 Apr 2019 18:34:07 +0200 Subject: [PATCH 35/47] updates startupscript and precompile --- src/BeagleBone/BeagleBone.jl | 21 ++++++++++--- src/BeagleBone/GPIO.jl | 2 +- src/BeagleBone/precompile.jl | 36 +++++++++++++++------- src/BeagleBone/startup/juliaserver.service | 2 +- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/BeagleBone/BeagleBone.jl b/src/BeagleBone/BeagleBone.jl index db415c9..95e7aca 100644 --- a/src/BeagleBone/BeagleBone.jl +++ b/src/BeagleBone/BeagleBone.jl @@ -152,6 +152,18 @@ function bbparse(l::Tuple, sock) end end +function close_all_devices() + # When connection fails or closes, close devices + for key in keys(DEVICES) + for (devkey, active_device) in active_devices[key] + println("teardown $active_device") + teardown(active_device) + #Remove the device from the dict of active devices + delete!(active_devices[key], devkey) + end + end +end + global __waiting_first_connection__ = false """ run_server(port=2001; debug=false) @@ -181,8 +193,8 @@ function run_server(port=2001; debug=false) @async while isopen(sock) try l = deserialize(sock); - println("deserialized:") - println(l) + # println("deserialized:") + # println(l) try bbparse(l, sock) catch err @@ -192,7 +204,7 @@ function run_server(port=2001; debug=false) catch err if !isopen(sock) && (isa(err, Base.EOFError) || isa(err, Base.UVError)) println("Connection to server closed") - # TODO teardown and remove all devices + close_all_devices() else println("error: $(typeof(err))") println("err: $err") @@ -201,10 +213,11 @@ function run_server(port=2001; debug=false) end end catch err + close_all_devices() if isa(err,Base.UVError) && err.prefix == "accept" println("Server closed successfully") else - rethrow() + rethrow(err) end end end diff --git a/src/BeagleBone/GPIO.jl b/src/BeagleBone/GPIO.jl index f71d78f..662f761 100644 --- a/src/BeagleBone/GPIO.jl +++ b/src/BeagleBone/GPIO.jl @@ -64,7 +64,7 @@ end # Default to reading "value" function read(gpio::GPIO, debug::Bool=false) - read(gpio, GPIO_VALUE, debug=debug) + read(gpio, GPIO_VALUE, debug) end """ l = read(gpio::GPIO, operation::Int32, debug::Bool=false) diff --git a/src/BeagleBone/precompile.jl b/src/BeagleBone/precompile.jl index 77862a6..3dac1e7 100644 --- a/src/BeagleBone/precompile.jl +++ b/src/BeagleBone/precompile.jl @@ -8,26 +8,38 @@ function precompile_bb() #Precompile serialize initdev("debug", Int32(1)) - serialize(clientside, (true, Int32(2), ("debug", Int32(1), true), ("debug", Int32(1), (1,2.0,"asd")))) - serialize(clientside, (true, Int32(2), ("debug", Int32(1), Int32(1)), ("debug", Int32(1), 1.0))) - serialize(clientside, (false, Int32(2), ("debug", Int32(1)), ("debug", Int32(1)))) - - serialize(clientside, (true, Int32(1), ("debug", Int32(1), true))) - serialize(clientside, (false, Int32(1), ("debug", Int32(1)))) - serialize(clientside, (true, Int32(4), ("debug", Int32(1), true), ("debug", Int32(2), false), ("debug", Int32(3), true), ("debug", Int32(4), false))) - + serialize(clientside, (WRITE, Int32(2), ("debug", Int32(1), true), ("debug", Int32(1), (1,2.0,"asd")))) + serialize(clientside, (WRITE, Int32(2), ("debug", Int32(1), Int32(1)), ("debug", Int32(1), 1.0))) + serialize(clientside, (READ, Int32(2), ("debug", Int32(1)), ("debug", Int32(1)))) + + serialize(clientside, (WRITE, Int32(1), ("debug", Int32(1), true))) + serialize(clientside, (READ, Int32(1), ("debug", Int32(1)))) + initdev("debug", Int32(2)) + initdev("debug", Int32(3)) + initdev("debug", Int32(4)) + serialize(clientside, (WRITE, Int32(4), ("debug", Int32(1), true), ("debug", Int32(2), false), ("debug", Int32(3), true), ("debug", Int32(4), false))) + + closedev("debug", Int32(1)) + closedev("debug", Int32(2)) + closedev("debug", Int32(3)) + closedev("debug", Int32(4)) + + println("closing clientside") # Close the client side close(clientside) + println("closing server") #Close server close(server) debug = true - + println("initdev") #Precompile SysLED led = initdev("sysled",Int32(1)) write!(led, "1", debug) read(led, debug) + println("closedev") + closedev("sysled", Int32(1)) ind = 1 println("False: $(ind ∉ [1,2,3,4])") @@ -36,11 +48,13 @@ function precompile_bb() gpio = initdev("gpio",Int32(1)) write!(gpio, (Int32(1), "1"), debug) + closedev("gpio", Int32(1)) #read(gpio, ind, args, debug) + # TODO activate when pwn is working # Precompile PWM - pwm = initdev("pwm", Int32(1)) - write!(pwm, (Int32(1),"1"), debug) + #pwm = initdev("pwm", Int32(1)) + #write!(pwm, (Int32(1),"1"), debug) #Do read/write to file val = true diff --git a/src/BeagleBone/startup/juliaserver.service b/src/BeagleBone/startup/juliaserver.service index 27861b3..aa7d285 100644 --- a/src/BeagleBone/startup/juliaserver.service +++ b/src/BeagleBone/startup/juliaserver.service @@ -2,7 +2,7 @@ Description=JuliaServer service [Service] -ExecStart=/home/debian/julia/bin/julia -i -e 'include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl")' & +ExecStart=/usr/bin/screen -Dm /home/debian/julia/bin/julia -i -e 'include("/home/debian/juliapackages/LabConnections/src/BeagleBone/startup/startup.jl")' & [Install] WantedBy=multi-user.target From c217d0d8f225506eca9482a84602cfda405b87d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20F=C3=A4lt?= Date: Mon, 15 Apr 2019 18:47:12 +0200 Subject: [PATCH 36/47] Remove test file and remove unnessesary code --- src/Computer/BeagleBoneStream.jl | 8 ------- test/testConenction.jl | 39 -------------------------------- 2 files changed, 47 deletions(-) delete mode 100644 test/testConenction.jl diff --git a/src/Computer/BeagleBoneStream.jl b/src/Computer/BeagleBoneStream.jl index ee87330..4ec6a38 100644 --- a/src/Computer/BeagleBoneStream.jl +++ b/src/Computer/BeagleBoneStream.jl @@ -79,11 +79,3 @@ function read(bbstream::BeagleBoneStream, cmd) #TODO Do something with timestamps return vals[1], timestamps[1] end - -function close(bbstream::BeagleBoneStream) - for dev in bbstream.devices - close(dev) - end - close(bbstream.stream) - return -end diff --git a/test/testConenction.jl b/test/testConenction.jl deleted file mode 100644 index 47c46e3..0000000 --- a/test/testConenction.jl +++ /dev/null @@ -1,39 +0,0 @@ -using Sockets, Serialization -#BB side -function startbb() - @async begin - server = listen(2001) - while true - sock = accept(server) - println("accepted") - @async while isopen(sock) - l = deserialize(sock); - println(typeof(l)) - #print("Read: "); - println(l); - serialize(sock,l) - end - end - end -end - -#Computer side -clientside = connect(ip"192.168.7.2", 2001) -function getminor(t) - println(Int64(t)) - t2 = UInt64(floor(UInt64,t/1e9)*1e9) - tsmall = Int32(t-t2) -end - -function runcomp(clientside) - @async while isopen(clientside) - l = deserialize(clientside)::Int32; - #print("Read:"); - t = time_ns() - #println(t) - t2 = getminor(t) - println((t2-l)/1e6) - end -end -serialize(clientside, getminor(time_ns())) -end # module From f1ce9b32f7436ece26a5078deb56f3117e01de66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 19:06:45 +0200 Subject: [PATCH 37/47] Changed overview figs --- docs/src/fig/beaglebonetypes.png | Bin 31694 -> 40874 bytes docs/src/fig/computertypes.png | Bin 28182 -> 34131 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/src/fig/beaglebonetypes.png b/docs/src/fig/beaglebonetypes.png index d6174c5b519aa20644fa7fa8080c8608485a9a3e..9078fcad20ecb2a22ccaa1abfb82cd7f6d4daa4b 100644 GIT binary patch literal 40874 zcmeFZ2T)d9w=D=qQN)0#D2j-fP@;fJ21QUn0Z9UqlPE~eNHCB=P@*6~5R@oM$w5Rw zf*_&Qi+NhY$F^z1Ny+&N0Urb9>#AzP_8{2n7iV z$!-a8Q8^M4GC>lOE$7L%;gz1NUxx5yhncvFB?-x%FT}s3!OVMT@#0}CF=Z=x)4Nu- z+7|jG1}3J)`mC0^7W(=omiJ7pCbyIbk&qlGkr2J2U>7mgZmV!WiFSKe=Z`DiXFWa7 zY8^;_O7_r8?t-V*vv3-z3*HsVIzAQQ2??@qyaX%Qw%r&zd;5UGW!a4F{6`YyMEM?; z2n$R-=I7#9eMHtd7{Pmeu&&KMESqbxE$^hZFNfoC-oxqXOJ*rL6cjXZzE@>faxa z3lX;ukZ?G7U~RK^T<*TT$JPIKVSg_%>0DUvRuZ~%tDEH87P{yDkIQ!58`~f`z(acZ zy3FEcC+CkQru9ARxXS9&XaB=nlT#V>Ry>Q(A7;VZ42_QehrfT$;|XaxeeKB^5n<+A@OVwXXK`<|fVIVAJ#eVG;JmCI#?HKhiK|{0}cGa0Jbr z`j6kA`(N#QJ~FbDC1JVyWY-Woil0h0H+&Kj&YrK(($acFx@DV!mH6M=r>Oe&tvvol z=w5nyN|Jj&;&!O1sWI^|;crBhtBx{~42idHUO%5s`3|dh;<&IdeRp>^kHg$qKRSMQ zm(BH@+}i4D?|%hZ;(>sG0JEMiJB|uE9C#-kDRTGjUGrAo!(3;FCGd8=!L{c9Jo1a0 z*z7cGZVCvp6~Mt9F0`NBR$5xhV>3o09VOuP;ll^-Jzjg|+^7#6IL^dGVLRF378yzR zJIB=D@K=(em9pz|Nk0zv0^7-h!ns8j{S-8Bt`VEfl!iSf`JVWihnyi!?stJLyZdh1 zZNt}_=*6#GA;r7Cju%tEvR^Lhn4p7e%vFyQOiW33YU?ZW84njttj1b0{yBNlRl&w- zWv+C(x00D}7ZxC{_HWiW@H`~sw*LO8;o;$2hk2&YWo71z6Y2uaYc%HO=60(KtTVH- z3@^mBbaejV;^Jy)Y5COJdbqBx&dl0cY;|E=TTf4+!Q~$YMM)DAww3u&k3Tu4p+`2? zmMxc7R(d*$9;Sczkn(znoFQ16pSc&)w{8V?aE|U7d3qxE1)qw-9f)5wE=7t-;*4Gb4hH$w1`tH)x(>u<_ zwnr&VgO#oE*DtqMuV{tV=j7)m+G&k{e~7sq9arC)kRhV0c3*t6;* zrv-N~6voM&!z#R!qf=2)G4#I1b-}db=(ktg>=#WYJBotYhE;CedemNEtK0qA%}_#e zaB%P>3(GETZEfXTGX@q`)`kLGQ4(xwr<2#vO)R!3O z=~Pu!gR845%f5e4uMK_i;>F|fKRItK2kU4A?9TV}^i(^Bxt>iDxO0-L!fd)n%$JV; zAa2_82EH->_ObywCT-y zf2ODeMmZZjUt4p;w(S^gO5Gpv-hOsqYIgQ%S{i%!MWb!T#^ZARa)}3WOgk%DvkWqf zn%UZN&EK$;o#}hi-`!2BtE;Pb_ilBN#HoFD4<9OBRuJ8zCN=+Xp#0Ij8!n_Tw$L;Kjwm zzg`v*`NyO^->oK;{p6`rTix8;B4&jh=E$R+77pJ|QGR?*{%z2&Xffm-iG39`%q#U3 z&uBAn$335on%^sm-*VmiEf~v&JGUs#Ho1G({mU28U{#OXmmV%ols{*iPzeL5D7i&otz^Yzm27y-G@g zdl2((v9wFq9zbhB=e;88|J`3DbJj$AbSqH@V@N^7jWK*`Lx zg671@lhb9C!p8*!B5d>Td^BW04xAtPC4WvMmUr7Onnzo<@A>K*&7r&PpMU;gI)37p zHBy&?((cpx1_m|8bm7mRKMH16(kb_*F07L2a{6pt`;vpHToNn5F*EaW&VipnlwsSp zZRa^Sx>=GnidL?NPNnQRChY8c$@urw8G&cdo@F?#+K7sZo(+C&WocQKDF5!~0>f?* zreu|@yQQ6-^cx!+E&0~TcShD`YS_&IeU?^N-^jm{rV(=FLH?H5A#>vEj~{aJ%cuA4 zXlrXDg0?n-H_$d8OKaGE?Lt&i<JT<{@AUNZ*v%PfZtD?+wZ%>sCRU%lBAyPi z1aeDCudTgF=`CI-H} z(rwST&b1oemu=d)M@FWeQ)LeW{f{3%KI1K>%MWQzNn3V(A{7-A3)WR|Rq(YL|81WA zgf$>6%uCGYV6d(z4pU!D93z9Pf~+rx?@``>#hnB|tiS~{yp^K;$WmWbCBZtsSMG4C zX2~(R#1FA$$3@3a?b{K;uIY!;G%anpG}Ue4>-pTfG0Q+^7tQ%cIcr~EoIKm`@F;`p zbBb#cG9u)OvDmhBmrdu68TA62#Q7};P$vwNeV$jJ;^!|=&=hf1xQGuuxMtQA#$`~= zaYTeE9s+9l=ehhUSWTy%VyDU&Fk;t7?+jFwr%S{ z?xd#M#-J}b#NFFp6WUL+gMm6(HOJ(M`accRs4n48iE=GRwvHX-)O^UMV`{2-MpMh$ z%1Ys3r0YGt3L59l^+oSJPoHxd=<1fKhCF|MIc+Y$-~I7pQp2W{D%E53^qPJRfY($a zxGC}A3Yx3Z(t82|1F7ig{l~_}y!RvqVf*6Z;u7ZXPNST*WE<0(E`RabuYK=cLUunj z2N&1XNIvVI8m1CqVPWEul0Sxu_aD|3mzKVE`}S=y4>=0mT@n%!)JK$%G;s7}m6esX zIr;_$P6!DdyMO<_p;zxv!<$_D*|$ed1hTWT?nZ+Df+X-FFi`$&4HNSD)Vi2&TbtUc z)2D;~2$j=Z#ryR1_P&UUdfza3!kX*Sr2$s1^XDIlo;VlSKhW2AoPmK9DMeqdWN)H^ zH?IBEsZ+;!dBYa9byS%1I{OC(Zj0~IPd$;7#p&wjk(pcZPsil;!-o$WmY67T<1cWl zoSTvR}y$fznw?A zAb$PKnKP2CgD7DGMPG486{t=@>-+oitw(PszWR*Ja#meQP3`C&dLiF8*Zq4M-dq%U!onX++V7-txBGGsi5Xi@|7ej_@70C-C%7UNn96@8 zD-qZNX{;MtS?+aW|Ni|%K?HUxo9Zr$Nls3-P(#gVXlN*Bl{j+Y-lx`&j}(~1?Cf}u z+s(Q^lL0E_@(i0A8hW#-=WBg>L`rk%0gaW_PZwSwEBCH0t)sjaaXcM>DPM=s4r!emG5rep?DV`-`$pHNxoyp6=h`_jUop(z_}g^FVQF4b{~0-(>paYBhp#y zq<#PXxg3oOnz{(yr>Ad(bgeDVMl=>WF7HG24OCUCj}p|@()y%&jF#4?%!9J`d(72b z$7PG@XA{GX?;3Dq^X7e!qaPtH9p$qkKg6!_Wwbf%#mkq<5#PBkUUd8T@#0ZBy6(|Y zA0elePoF=Fu-32zL`C@}E2SM|6u?rJhVh6?NtFX!njzB=+n%OT^pEbYeO_Dl?Ae2h z{QQzb_j`&8*T*lx;o;t|UmsV?x7vZ4Z?`a}k{IVJdg5_j9xwK7tAT;Rhx?7&kkFnY zqQg#;GJD@Tv}eSjD>yjV4bY(%d4-54BBaB^@2F{H-IcmkA+!$o(0f66=A4-&KI z*CyKeT|GQbUbsMPjpwsxA7L~FO`*t828Q3 z&D|=nF>d+&`*V9c9iroE<6Eg;`B4-*cT!PPyY=SlDGh{3Cr>0k9c`_ z%qmWsnps%r0DVZZ3!gv#JWGR_nK>jnx_)7@v)*BG;u}Isv{DaoGEf&;lbMx8?S1;< z#b7}H=_Y>XHM{uDx|w~)j@9v5kHk&ceE9fLpZ3xNEiy7PNp^mAcK=9TOLwQmcH0!7 zlK7Em9&??<`&^uyEomhi)g!->8JUW&Jv)*yG;}Y%r~2DBeFg@G+Ro1CU#PMQMO=4l z&t5dXbLWU^zE$GQHOH%H@>_uhgEb83y?uOiPhRuY!qKHLE@8Opo<3L~oqXCI|IGqw z+Hq{B+SB4M&5L|cW~fTS8tcA@$~Uw zzBoQV+T4n_*MHl41l5mL*jb>arbeDGJ1*|jCBvU*?`mni{%K=vV{_M^UikL?^@I~x zKkn?(r`wqo2Z6MHY8bo-3OaB}zxu#kRD!NsDLE*q?XNhoQQ`7CU?!@wSIxj#TUxXBdERD^o< zz-Dd9oVfPe$+uJG=Gj#;<9>dqs;YWW`h=`-k&J#18yg$TrAxQtt>u3pleQpA59Akz zh@X0ZUV=qPNW<714QP}5?)cf4pdlnAe6QTo5h3r6JtrZPs8GGJHY?+1+LE`8m6dg2 zb+Uw+db{Qic}-1CD-mB)Gb<}SY|tUPnr!1gTSxgHE~Lo0=-S&Y&zzS`cIW=Y0Q1h*}R&V>BqgtBI%cr@xxd&5o&JKr#hgUnV3^U#?az|dX ziqZRFiB>muRO#Yyo@u90-XJ5Y#F-c3Tm37m0vWTA+8b(|mZlgG+vkA2BfBzv0>sh7 z)wZ{*Ct9PxX~rLW;_B*p{>F_P!8zl=um?1<^Mk~G$PcYKVt3+4f+XX|&=c$xSgfYS zxogEO#7t$Prwc17Dd`eovq5#d%Wc}BU`ThqLK%4E6|d!)N!~=j{o3Z{Py})2?~g{w z2aFJ(S}gi6=2E_n*S=f{j6yCboZo$v=T;)kVO?x<$oxdRs+r)>@NktAO(XK3&1e&A zLygpp8@gZ}?gD`8p`$6BKX_WOx3{-7P9m^R!{2;2fXf(yTr%xsMF%~*{M(yU^Lu?w z&tJUwYsg4P#M2J&n_!sE-rOG$g+}E8YAq+n(CBDZvD0d%^=MN@AfrqszwJc2tLxSU zBvqT4K8Z^vZ9E-BVbDIrrgn?xU~wE{vzCcT-Prgzwd6}crwl}fYzDCA@%J}aU7R#9{*&DwasB#rkMWKo)d>rk z2p)#~)6F@Z&dB$wZ+}RsHgwLSc9iCBEDzGZMQ4~)JXyTz$Es1Ne4c~p?!C6$3^{HW z-y)f#i^Gi`i<6Op4=?ds4edpXiSC|GS9o)c%hJlKFG2(9#JDw6teXbBP|Le$=W3OA z;Br=b{e_k9+_{rzA0_y(Vr^}WXVBct?0HyJMy8a5bOev=oMZJF!FaiIukgl``I~FA z^{r^Hyf+sjB97Wjb_kZbI^dux>*&O`>ANhn8pLiE?`M>rnvnP2MI7LJ>k&du;j=9` z_qu^+q;#%axx&K4F7rP;+rg94jz9l*RX z)I=5rhR5wCF45y{d4cwJc2jJfrKOLHoK|ml&!bB(D=aMJ8J(M+)<%L&t9AJE(I`}o zvg6T=jKl3d8@AYqxIrK}p3xsoO?PEwWht5~TUNIVI5r#4rXCTVYQg3GvwIrI2Sex+Ya}mNWLI%48 z9p;|%Pd?pFX~+I3{KEa%DWfYQ67}E$Gs$)yOb5Wo3rf-Mh89^4N(ZyG zp@~e!`WoSKEp2QLwvQk$_CGN<2HoDDo06L9)0-sw#yw#<=>B*FGT`qI_fN`)Vi&Y* zw*bzMg=#u?`(8z)quG+O+O=cHj>2};T}Li>a@nis0ihI*o;-g1^4%2x{sqt$J=*Bt z3Ts$-={j$r<5070_~u;o*tGNZ8G?iQbj|N*l}fam8(D$la%R`s^z?KJ?j&NC+wiBj z$>LVT)vfy_mpD0f78Vv#h_utup`oxyhGfAaD5(B(1uyN+!losbAshtlXIyQIfg;ha z3WeDx%l*LmhecQqBO|O#GGXTpGWd~oBF9o<T>?b?ivJ=k$CtJUz)fc5;YmJiB`{S4JiyO4y~&(a~`$`(B&{#-*gYYHAT(YxD~e zi93iN{mIl`7;BB){~bMS|9XL&MnU1jMK;x9NBhJp3G`xJ>&&vqI|P{Gth#`D8ztma zeUMG^;VHfolhm?;4_RcG(9 zoA%7eWT;1)*fUOvdhD}#lj56eyBpS1aOy*H+&=pF_;g*uF;q=-a;We<{AATiHqxjm zMH{&11@C5mUtcy zE-|(sr)#u2{&wme7G7Qzvkp)OGw*3RBxEXRUI{tz4Xz#LErrr(%I-rp!?IWVsu2rj<0_jsk$>TPv&d5a7vZ>`BZ_HO=3eH4lka?KvF1gUl zk?%22MMe`}zkW1pya(k$Hf`ocyxc;&ZKrv~k7B2X@!50?qFnzyD z^laV~Gn6bpBJRMsuyKDK-98!n1+duP_&1kl2gwE%`+D*O`uh7bz=oSu{EokI$ZfT! z*QgW-j@6AXWw3zP@Mi+mpJJziHl;=%^kO%rel6p|nC2FN1T30*$HrRH^mA^2@!Q8E4Z@%SzbW+ZU$g`wYiEn*3OWW%kMsqn32Q%2!90WS$a438??W zHyrJI&p4x^#dPLGUIA|FHed1>N20Gk?eNn%W?kPgqHA4=wzYtHq-+1Pp zkrA^(r)kN$J36HrUzwXXzu0yn`&s1K9aF2X?CxOp<-g$rC3O{C1Ea zah!k9a-IeqWq2`K9vW_wh-&ll%F133dgtedCx?f<>V-Ge6zE7^Cnx)u7B9PJJsAJ} z@yYBp$S0`a5&CH0L2W%A;>mTKsbXaMmUa$0%oLg;5vJhkpyj2dPtDCrF)ILF8Cs?P z)MZjL-|ngoW|k~h`2mWddt`*k@D89oi%O>J;?YB3gezWZ(E*8yiikX^wFA(Swty%Hf z%#FHC1gVMwo&J^m*;z?Q1Lm^>QY`BE2e3C41jAiNg_8aW91n-fhND}W3W*lzlZe$f z;QE^0tMBv@J(2%D)`(GET|F!$^+fc)y#Se&{`9&{DJm3|i!oQ8Zqx4i^!R&o^P!7Q zfEOH~X**`1HOkI^si?5n7}!O}r!W=1d=-6Nub@Vsx+%IPc0%A{qNAmy{rIyH(n#Gj zcn7%~>($T2PqpNlpET7W8ciPH69W|si%hNdfq?<0%6Dw7t*y!#I%Ec6&|yTp+)uoH z`?j#E5OC!<8nkXc#f!QXyE?KArPg%{Ly!0O3;%+pFoV^CMFJsIE==g2=j=C(* z=-0(ve!*)wVCJ{DurQD+Pqn_fsFb%yDjmQBoKZm5&9HGYk~i0$^$5OWQO&-Y$fqca z-s7Zv<}$wt^wmC~;=xat4O^{zGmo+jWx0-^XYF z%|fH6&Mz%6lNjMj`HrqZ_DLMV>>$HIuJ5m z=;qx<6@JMGuYXZJW3vgS>fGQ}erpZWqx?3zOgoDebA?1a2O1NHNT4mq0)C4kG2rG1 zsy3;%yj;vm5DjNUFS4AXw~Qiy<Iz5u0 zJk&x%LP8`zZh*4sWi5bAYruJqlXD-VbVOH#!52@e*wFEj5pS$g&8Z?n4})scFn=!z zpr_-M9=Zguf!pIpE`mk{r$NqM7R6Ef7A#h8+ka^Q{$ zUWfd_#H9i4ue+&&gka6k2%hBTR(d;z+&9#g$2I7PR`APAe+}>ccJEW7ibd|Zwv)#O z?ZoI;Kx0jXh>41lM`_kPdHcX1LqtSGR3Q#R^$_!n*B}3Qa zZ}Pfe)O54kZpm*uXl``wG2n(MnkC2^9uVEE0w2UALwn;J*F9Dbe6`kA@Axa$#TkJ7 zjgw2fY2;N{C{W6mteE^Zdr6_ZIluJNClbV`Vtxl`>R52Mxz?j0H(LR|GqBeUY5Ivb zfZ2EgqtM*;AF1>p=;W}u1N)oNhw-Y4&W*LoCn~M=wg23MhW)PNty_By)B&)E+6!`q z^mB~=9HgWd`hs&wMMt+ANC!N%%CO$+x4gC!Mu)+eY< z!6Qlv_*A=^zVT)x(1>0vBq14fVG%4Ajd3X4@@*1WP(XRRWnF zva`2OjM(~96g@yc>;6|MJ&k#m1|51eST)5Y)x$|+jUp26;6HR)(zTUyOd_v+e5n)y z4hzR_4+tSbL`M3DX!$rMh5^O-IdpP#AH4`0;#e4bzQPpTgHYzdHaj{wWk3O`6AHc| zw`jkGWRi2ajyBwNl6$#~Te*))QY%-~h!>=!Bo)6Ql<|M}CZvxuUEq~ZPhrQp1AWP{E< zoFAb^s3}aOPNk-%@&-ofBs_HCgnkeba&T~TCb+xs3c2i2qAjAQtDw=*)de0H_TJ+b z3i>}enc4Klb9Cv|rvyRMla2NjD6^Y_`{`oc?;xni64M+Bn0;$PLPl(roteG5qMW9; zXor`t?}4$B8|0ckl<(IUpjQ^Axg)aW68n`D9sf|=TDODLbRDIPhhB$pH9)trsJ}51 zSDi61HnxkKo4bS3ejOQteE05hgjDz7pwfHR_@AkO+bspQX$b^_O(+^EDp~G}TLhu( ze+CO`27aovxoml%yro4szMj@m!aH-V2vqP@5VjK?Mago4$jA|?|qh ziHi%wv?H^F_1EEDVYZ%;-vx#VYVtl5lS-tF^Y$}(bs?VU`>t$mtWzC4Sh4)u7N7B6 zy`Un`ms#n3LjThXrxUsCWrO-y@}0?X!Q(!%RF0Ipayu0Ep14qS%OzSrhSSu*9zw-; zv^|83v;WM^PpDtKntAm#HDy3`U0q!yxTv~(rWL+>b3+YG>~9268D`JSEemaZO9AL5 zck%w++5K>_$U*?v*jP0MMmuon(j@?gFHouW($FZM+ZRQ$wWO^ocrGY(tRcvUx40>p zPU(Ok+a4mQj zEShW3pmvRqKLf?xgPa<%dQb69YU;Bc`_Gs;--;6#72O)bqVicKBq-=h0ec9UVvYoK zOBgsvZEbB8(lqEm#(f47aYd7yaJqX3NmNu68jZHxm|I3N#gx+*9<-#lsTM0`kEf)d zStG>4!u6{M4;;`!J}F!;_+kB=C)}*)3VGsMLOdfwT=iEh6MzI24UH$5adYQyYD!9n zzzw>Gh926rdpC#nXIBbOg`>snW&d=oQM`Tg<|G(r`_(NEr@9{h){!UcR0<$nUJvjt zUA(gIwT{rptzYD+W$??)I=5X_0c;ID%=m$_YE)@TSFWk@$gO$59H95lb#;5Ly6?Jj z=T3On2f*a3(LzoH5Mxox-HRJiEbbq~CYmozX?IY1rD_x%fgtoKDoP`9T4ePziVoQF zm?j=KXW`{jjEuSvImmbI`T}Z_=Ut*o))@go!S4QkHylhI{7ABrN9z;G%}74Qft^j@ z3Srq`zFYf}A;%B(xI+{n@utSfC1uwi74-)X9;BPJ^L0=T3ffJP053g?j*h;0Sbe)! z*`Z|6{s1}g3;hkRPPi&a{Vn+pkkiP?$v*){l(&YoYL@FokfxGWDhj`Eh&BUqibBMhnUAwGrp(+nBP{3(L;clUi&(1T_5eagR)!+NZ)eeHe z{hn`a)S7 zF2NFZ&S*0cnOpYl+edgo=0=-kj8k7#KmE>Z<(PWfwOEL5|NgSpm5+tg?dL6ID?{&s z3!fad4%#bE*E#C&Y1Ka}XnRZ=txJpHi0wqgeuaUaURPGV(0)g1d&JgDUdy+&OJHerz#?*{8rM8MV=|a|>V>$Ss>45P zUelRE+)BZ-oShqAXc|37RYb)5Un}1Fbn8Np?jaT!oCCndmBLI2t~ey`Ihx=KaE()4 zrCZ<=eJi5rBIkB%#yzc5#MIQZ!yc4zY;3H8-wj37l0to=@5pm5PJ2|NdWq`#(EJya zsNfsBMAmH#tG5?ixS~RDG&7P&QK<@o61mkKZONx^-=rqy!2C|l&57Q-caK+8i34dH z&Z=_Nx?h?xSP#h+6u<7izAwwvt1vD?cBSQUUgK$NZ~qlF#3FJ1`gTYVlm?xzK!)A> z{ox#z$O|6~%y9yCSZM1sycVZmML0G42zuBy7zY$;D$Rmo?*GXXAg9~u<>duKX6Rwf zron+E3ylq$MMe?N5!k$UQqX*e^NqQu^}6oi4u3upa`=R@PkrcMYAi2)yYG%i|1Z;&@6Yx&H(Lqc z)^|!FrLUZZ1ou5ziCrzvf{ZZaLZc&l7b+RQ)Z@d>Bg~_uNN%k9-rxV;XZtO7ogxn! zV#Ss=RwwoEl)+@9jTVc?a^Pm3GYK4B`+!0|DQP;LmJbOCctY>IL<)}44aa+Ke!d|| zk@>-&Y^l4y;eF^q`GiDd&MW#&N3-^p#ye2__x@|e9=TRFf&2|;<_ zsAi6dddr_bmLbDKLt4-d3aux8f4nhK$*Vwh^eEBK9-vg?E)j7G0*C_#S{^ALQ<6_a&^F2ln}>BqyWH;lCYs6x=0%Q%#>QT!)2d9tN&N%ilXmbH9dsPe;tUi&wFJx9^i=m%JE&UH zK*~aON~+2K#CRB}wadW%`>CSB-EsxgVNi{OjxPf|7g@D6H9O&4I6F(zXAVCh64Ks7 zhm@E&V7hVzK6nk4XsGcW<=wgnFT#|A;)$|$U`?G>2FymytHSM7K>nP)Lww>#V@!@D zIdoPbu@XK#(Km!4I^7Y5CVt`dML&xp+$}ICR zKs`(_!Tjoo0sFvgDk>_bN`{}N_mRbjl`welp!Q)I0)$Qg8houTT*_C<+;{WVz_e=C z_w@y*|CK08RXxQZ&^ps0i4KLQ85u2|dGqh(<>%)!{Yo3I{r1fqC>i)KJWJr@$){N^ zH`t&N@jP5$fx$9`W7Ti(``c?`Bh6{-T+%0AOgY~poNI`#+o}&7VfC_8^;lk630a;g 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

        bn~ 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 literal 31694 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 KV*l-%^ZyHj;|z2F literal 28182 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 From 5a354624e2eee58a6a74036830294d2919cdf18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 19:23:14 +0200 Subject: [PATCH 38/47] Changes to overview in README --- README.md | 56 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index c6da30d..4233f05 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,14 @@ [![coverage report](https://gitlab.control.lth.se/labdev/LabConnections.jl/badges/master/coverage.svg)](https://gitlab.control.lth.se/labdev/LabConnections.jl/commits/master) # Welcome to LabConnections.jl - the IO-software part of the LabDev project - - +

        + +

        The goal of this project is to develop a software package in [Julia](https://julialang.org/) -for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BBB) +for interfacing with lab processes using either the [BeagleBone Black Rev C](http://beagleboard.org/) (BB) with custom [IO-board cape](https://gitlab.control.lth.se/labdev/ioboards), or the old IO-boxes in the labs using Comedi. With this package, the user is able to setup a connection between the -host computer and the IO-device, and send and +host computer and the IO-device (BB or old IO-box), and send and receive control signals and measurements from the lab process. The full documentation of the package is available [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/index.md). @@ -17,54 +18,55 @@ The full documentation of the package is available [here](https://gitlab.control The `LabConnections.jl` package is subdivided into two main modules; `Computer` and `BeagleBone`. `Computer` defines the user interface on the host computer side, while `BeagleBone` defines low-level types and functions meant -to be used locally on the BBB. - -### Computer - +to be used locally on the BB. -This module contains the user interface on the host computer side, and defines +### LabConnections.Computer +

        + +

        +The module `LabConnections.Computer` contains the user interface on the host computer side, and defines types for devices/connections to the lab process, and filestreams between the -host computer and different IO-devices (BBB or Comedi). There are currently 3 +host computer and different IO-devices (BB or Comedi). There are currently 3 different device/connection types (each has the abstract super type `AbstractDevice`): * `AnalogInput10V` : Represents ±10V connections from the lab process to the IO-device. Each instance will correspond to a physical ±10V measurement signal from the lab process, whose value can be read. * `AnalogOutput10V` : Represents ±10V connections from the IO-device to the lab process. Each instance will correspond to a physical ±10V input signal to the lab process, whose value can be set. -* `SysLED` : Represents the System LEDs on the BBB. Used for simple testing and debugging from the host computer side. +* `SysLED` : Represents the System LEDs on the BB. Used for simple testing and debugging from the host computer side. There are 2 different filestream types (each has the abstract super type `LabStream`): -* `BeagleBoneStream` : Represents the data stream between the host computer and the BBB. +* `BeagleBoneStream` : Represents the data stream between the host computer and the BB. * `ComediStream` : Represent the data stream between the host computer and the old IO-boxes using Comedi. -### BeagleBone - +### LabConnections.BeagleBone +

        + +

        -This module defines types representing different pins and LEDs on the BBB, and +The module `LabConnections.BeagleBone` defines types representing different pins and LEDs on the BB, and functions to change their status and behaviour. There are currently 4 different types defined (each has the abstract super type `IO_Object`): -* `GPIO` : Represents the BBB's General Purpose Input Output (GPIO) pins. +* `GPIO` : Represents the BB's General Purpose Input Output (GPIO) pins. Each instance will correspond to a physical GPIO pin on the board, and can be set as an input or output pin, and to output high (1) or low (0). -* `PWM` : Represents the BBB's Pulse Width Modulation (PWM) pins. +* `PWM` : Represents the BB's Pulse Width Modulation (PWM) pins. Each instance will correspond to a physical PWM pin on the board, which can be turned on/off, and whose period, duty cycle and polarity can be specified. -* `SysLED` : Represents the 4 system LEDs on the BBB, and can be turned on/off. -Used to perform simple tests and debugging on the BBB. -* `Debug` : Used for debugging and pre-compilation on the BBB. It does +* `SysLED` : Represents the 4 system LEDs on the BB, and can be turned on/off. +Used to perform simple tests and debugging on the BB. +* `Debug` : Used for debugging and pre-compilation on the BB. It does not represent any physical pin or LED on the board. -**Note:** In addition to GPIO and PWM, the BBB also has pins dedicated for [Serial Peripheral +**Note:** In addition to GPIO and PWM, the BB also has pins dedicated for [Serial Peripheral Interface](https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus) (SPI). -Work to feature this functionality in the module `BeagleBone` is currently ongoing. More -information can be found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/master/docs/build/man/introduction.md#spi-development) +Work to include this functionality in the module `LabConnections.BeagleBone` is currently ongoing. ## Getting Started ### Installation -Instructions on installing the required software and setting up a connection between -the host computer and the BBB are found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/man/installation.md#installation-instructions). +First, you should follow the instructions on how to install the required software and setting up a connection between the host computer and the BB. These instructions are found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/man/installation.md#installation-instructions). ### A Simple Example -We will here go through a simple example of using the host computer interface to communicate with the BBB and control the onboard system LEDs. +This is a simple example that demonstrates the usage of local devices on the BB via a host computer. The devices that will be used in the example are `SysLED` and `GPIO`. -First make sure that you have followed the installation guide, and that the BBB is running a server and is connected to the host computer. +First make sure that you have followed the installation guide, and that the BB is running a server connected to the host computer. Then, start the Julia REPL and input using LabConnections.Computer From 31b65c2f8f742bf835dc4655cf79342aca5a7572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 19:53:03 +0200 Subject: [PATCH 39/47] Changes to simple example --- README.md | 83 +++++++++++++++++++++--------------- docs/src/man/development.md | 6 ++- docs/src/man/installation.md | 2 +- 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 4233f05..f465874 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ to be used locally on the BB.

        + The module `LabConnections.Computer` contains the user interface on the host computer side, and defines types for devices/connections to the lab process, and filestreams between the host computer and different IO-devices (BB or Comedi). There are currently 3 @@ -67,45 +68,57 @@ First, you should follow the instructions on how to install the required softwar This is a simple example that demonstrates the usage of local devices on the BB via a host computer. The devices that will be used in the example are `SysLED` and `GPIO`. First make sure that you have followed the installation guide, and that the BB is running a server connected to the host computer. -Then, start the Julia REPL and input - - using LabConnections.Computer -to load the host computer interface. Then define a file stream `stream` and connect to the server running on the BBB by inputting - - stream = BeagleBoneStream(ip"192.168.7.2") -Now, we continue by defining the LED we want to control - - led = SysLED(1) - -The object `led` will now correspond to the first system LED on the BBB. -To tell the BBB that we want to control the LED, we make a call to `init_devices!` - - init_devices!(stream, led) -Now we can start controlling the LED on the BBB. Let's begin by turning it on - - send(led, true) -You should now see the first system LED on the BBB being lit. -The function `send` puts a new command (`true`) to a device (`led`) to the file stream buffer and -sends it immediately to the BBB. +Then, start a Julia REPL on the host computer and type +``` +using LabConnections.Computer +using Sockets +``` +to load the host computer interface. Then define a file stream and connect to the server running on the BB by typing +``` +stream = BeagleBoneStream(ip"192.168.7.2") +``` +Now, we continue by defining the onboard LED on the BB we want to control +``` +led = SysLED(1) +``` +The argument `1` means that the object `led` will correspond to the first system LED on the BB. So far, this definition is only known to the host computer. To tell the BB that we want to control the LED, we make a call to `init_devices!` +``` +init_devices!(stream, led) +``` +Now the LED object is defined also on the BB, and we can start controlling it from the host computer. Let's begin by turning it on +``` +send(led, true) +``` +You should now see the first onboard LED on the BB being lit. The function `send` puts a new command (in this case `true`) to a device (in this case `led`) to the file stream buffer and +immediately sends it to the BB. We can read the current status of the LED by calling `read` - - v = read(led) +``` +v = read(led) +``` You should now see a printout saying that the LED is turned on. -We can also stack several commands to the buffer before sending them to the BBB. -We do this with the command `put!`. To turn on 2 LEDS at the same time, we can call - - led2 = SysLED(2) - led3 = SysLED(3) - init_devices!(stream, led2, led3) - put!(led2, true) - put!(led3, true) - send(stream) +We can also stack several commands to the message buffer before sending them to the BB. +We do this with the command `put!`. To turn on 2 LEDS at the same time, we do the following call +``` +led2 = SysLED(2) +led3 = SysLED(3) +init_devices!(stream, led2, led3) +put!(led2, true) +put!(led3, true) +send(stream) +``` Similarly we can read from several devices at the same time by using `get` - - get(led2) - get(led3) - v1, v2 = read(stream) +``` +get(led2) +get(led3) +v1, v2 = read(stream) +``` +We can also manipulate other types of devices on the BB. Let's try manipulating a couple of physical GPIO's on the BB. Similar to the LEDs, we begin by defining two `GPIO`-objects +``` +gpio112 = GPIO(1, true) +gpio66 = GPIO(29,false) +``` +When creating the `GPIO`-objects, we input two arguments. The first one is an integer value (1-33) which defines which physical GPIO pin we want to access. The integer corresponds to the index of the physical GPIO in the `gpio_channels`-array defined [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/src/BeagleBone/IO_Object.jl). Additionally, the pin map of the BB can be found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/man/development.md#Package-Development-1). ### More Examples There are several examples found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/master/docs/build/examples/examples.md#examples) diff --git a/docs/src/man/development.md b/docs/src/man/development.md index 61428e6..039132b 100644 --- a/docs/src/man/development.md +++ b/docs/src/man/development.md @@ -25,5 +25,9 @@ This will transfer the current development version of `LabConnections.jl` found ### Development with hardware in the loop When testing `LabConnections.jl` with hardware in the loop, the external hardware will be connected to the pin headers on the BB. For reference, the pin map of the BeagleBone (BB) is shown below. - + +

        + +

        + When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index c491571..333ad1d 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -28,7 +28,7 @@ Start by downloading the Debian image [here](http://beagleboard.org/latest-image Proceed by downloading the Julia v1.0 binary for 32-bit ARMv7 found [here](https://julialang.org/downloads/). Put the .tar-file of the Julia binary on the micro-SD card containing the Debian image under `/home/debian`, and unzip it. Make sure that the Julia folder has the correct name by typing ``` -mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia +mv /home/debian/julia- /home/debian/julia ``` The file structure on the micro-SD now has the correct structure. From 752d7a3498b88f8190dfdb684f617ea32ccd1750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 19:56:36 +0200 Subject: [PATCH 40/47] Changes in figs --- docs/build/fig/beaglebonetypes.png | Bin 31694 -> 40874 bytes docs/build/fig/computertypes.png | Bin 28182 -> 34131 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/build/fig/beaglebonetypes.png b/docs/build/fig/beaglebonetypes.png index d6174c5b519aa20644fa7fa8080c8608485a9a3e..9078fcad20ecb2a22ccaa1abfb82cd7f6d4daa4b 100644 GIT binary patch literal 40874 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%0AOgY~poNI`#+o}&7VfC_8^;lk630a;g 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

        bn~ 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 literal 31694 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 KV*l-%^ZyHj;|z2F literal 28182 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 From 774ceda9ea44180f6ead9712150f031f3c46013e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 19:59:06 +0200 Subject: [PATCH 41/47] Update development.md --- docs/build/man/development.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/build/man/development.md b/docs/build/man/development.md index 0d02f32..c0f9e58 100644 --- a/docs/build/man/development.md +++ b/docs/build/man/development.md @@ -1,4 +1,3 @@ - # Package Development @@ -56,5 +55,9 @@ This will transfer the current development version of `LabConnections.jl` found ### Development with hardware in the loop -When testing `LabConnections.jl` with hardware in the loop, the external hardware will be connected to the pin headers on the BB. For reference, the pin map of the BeagleBone (BB) is shown below. When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. +When testing `LabConnections.jl` with hardware in the loop, the external hardware will be connected to the pin headers on the BB. For reference, the pin map of the BeagleBone (BB) is shown below. + + + +When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. From 8a6c7382622ab183d06c97eba3f0f473f7b9c3fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 20:13:21 +0200 Subject: [PATCH 42/47] README.md is fully updated. --- README.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f465874..3092ab4 100644 --- a/README.md +++ b/README.md @@ -113,15 +113,25 @@ get(led2) get(led3) v1, v2 = read(stream) ``` -We can also manipulate other types of devices on the BB. Let's try manipulating a couple of physical GPIO's on the BB. Similar to the LEDs, we begin by defining two `GPIO`-objects +We can also manipulate other types of devices on the BB. Let's try manipulating a couple of physical GPIO's on the BB. Similar to the LEDs, we begin by defining two `GPIO`-objects and initializing them on the BB ``` gpio112 = GPIO(1, true) gpio66 = GPIO(29,false) +init_devices!(stream, gpio112, gpio66) ``` -When creating the `GPIO`-objects, we input two arguments. The first one is an integer value (1-33) which defines which physical GPIO pin we want to access. The integer corresponds to the index of the physical GPIO in the `gpio_channels`-array defined [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/src/BeagleBone/IO_Object.jl). Additionally, the pin map of the BB can be found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/man/development.md#Package-Development-1). +When creating the `GPIO`-objects, we input two arguments. The first one is an integer value (1-33) which defines which physical GPIO pin we want to access. The integer corresponds to the index of the physical GPIO in the `gpio_channels`-array defined [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/src/BeagleBone/IO_Object.jl). Additionally, the pin map of the BB can be found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/man/development.md#Package-Development-1). The second argument defines if the GPIO should be of output (`true`) or input (`false`) type. + +Now that we have access to two GPIO pins, we can e.g set the output pin's value to high (`true`) +``` +send(gpio112, true) +``` +The physical GPIO pin on the BB will now output a voltage. The other GPIO pin was defined to be of input type, and if we want to read from it we simply type +``` +val = read(gpio66) +``` +where `val` will be either 0 or 1 depending on the voltage value read by the pin. ### More Examples -There are several examples found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/master/docs/build/examples/examples.md#examples) -which let's you test out the functionality of `LabConnections.jl`. +More examples for testing out the functionality of `LabConnections.jl` are found [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/master/docs/build/examples/examples.md#examples). -Examples of real-world usage are available in [ball-and-beam](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_implementations/ballandbeam.jl) +A real-world example using `LabConnections.jl` with the old IO-boxes for controlling the ball and beam process is avaible [here](https://gitlab.control.lth.se/processes/LabProcesses.jl/blob/master/src/interface_implementations/ballandbeam.jl). From d2b044d3bfaaa3d94bafee1dccf5eba5274f58d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Thelander=20Andr=C3=A9n?= Date: Mon, 15 Apr 2019 20:15:16 +0200 Subject: [PATCH 43/47] small fix to README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3092ab4..64e80bc 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ receive control signals and measurements from the lab process. The full documentation of the package is available [here](https://gitlab.control.lth.se/labdev/LabConnections.jl/blob/julia1/docs/build/index.md). ## Package Overview -The `LabConnections.jl` package is subdivided into two main modules; `Computer` -and `BeagleBone`. `Computer` defines the user interface on the host -computer side, while `BeagleBone` defines low-level types and functions meant +The `LabConnections.jl` package is subdivided into two main modules; `LabConnections.Computer` +and `LabConnections.BeagleBone`. `LabConnections.Computer` defines the user interface on the host +computer side, while `LabConnections.BeagleBone` defines low-level types and functions meant to be used locally on the BB. ### LabConnections.Computer From 25aa435f34efb3a3f07833ccac6a67def59c400f Mon Sep 17 00:00:00 2001 From: mgreiff Date: Mon, 15 Apr 2019 20:22:19 +0200 Subject: [PATCH 44/47] Revised PWM functionality to be compatible with the 4.14 kernel --- src/BeagleBone/IO_Object.jl | 23 +++++++++---- src/BeagleBone/PWM.jl | 66 ++++++++++++++++++++++--------------- test/BeagleBone/PWM_test.jl | 10 +++--- 3 files changed, 60 insertions(+), 39 deletions(-) diff --git a/src/BeagleBone/IO_Object.jl b/src/BeagleBone/IO_Object.jl index 9215ea2..bc25ddb 100644 --- a/src/BeagleBone/IO_Object.jl +++ b/src/BeagleBone/IO_Object.jl @@ -44,14 +44,23 @@ const gpio_channels =[ "gpio7" ] -# These pins are exported with the Device Tree Overlay cape-universaln (default) +# Device Tree Overlay cape-universaln (default) before the v.4.14 kernel +#const pwm_pins = 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"), +#) +# After and including the 4.14 kernel const pwm_pins = 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"), + "P9.22" => ("1", "pwmchip1", "0"), # PWM0A + "P9.21" => ("1", "pwmchip1", "1"), # PWM0B + "P9.14" => ("4", "pwmchip4", "0"), # PWM1A + "P9.16" => ("4", "pwmchip4", "1"), # PWM1B + "P8.19" => ("7", "pwmchip7", "0"), # PWM2A + "P8.13" => ("7", "pwmchip7", "1"), # PWM2B ) # These pins are exported with the Device Tree Overlay cape-universala diff --git a/src/BeagleBone/PWM.jl b/src/BeagleBone/PWM.jl index c554de5..1e91d9a 100644 --- a/src/BeagleBone/PWM.jl +++ b/src/BeagleBone/PWM.jl @@ -1,8 +1,21 @@ """ PWM(i::Int32) This device allows for low level PWM control of selected pins. The valid pins -dictionary pwm_pins relates to memory adresses in of the AM3359 chip, see p.182 +dictionary pwm_pins relates to memory adresses in of the AM3359 chip, see p.184 in www.ti.com/product/AM3359/technicaldocuments. + + pwm = PWM(1) + write!(pwm, (1,"1")) + write!(pwm, (2, "1000000000")) + write!(pwm, (3, "800000000")) + +The operation of reading the current output value of the GPIO is done by + + read(pwm, 1) + read(pwm, 2) + read(pwm, 3) + +See the test/BeagleBone/GPIO_test.jl for more examples. """ struct PWM <: IO_Object @@ -20,13 +33,14 @@ struct PWM <: IO_Object # Setup filestreams pins = collect(keys(pwm_pins)) - pin = pins[i] + pin = pins[i] chip = pwm_pins[pin][2] + location = "$(basedir)/$(pwm_pins[pin][2])/pwm-$(pwm_pins[pin][1]):$(pwm_pins[pin][3])" - 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+") + enable_filestream = open("$(location)/enable","r+") + period_filestream = open("$(location)/period","r+") + duty_cycle_filestream = open("$(location)/duty_cycle","r+") + polarity_filestream = open("$(location)/polarity","r+") return new(i, pin, chip, basedir, [enable_filestream, period_filestream, duty_cycle_filestream, polarity_filestream]) end end @@ -37,17 +51,17 @@ Writes an entry to an operation on the PWM, of the form args = (operation, entry """ function write!(pwm::PWM, args::Tuple{Int32,String}, debug::Bool=false) debug && return - operation, entry = args[1], args[2] - (operation < 1 || operation > length(pwm.filestreams)) && error("Invalid PWM operation: $operation") - # Input data check - assert_pwm_write(operation, entry) + operation ∉ [1,2,3,4] && error("Invalid PWM operation $operation for writing") - # Write to file - seekstart(pwm.filestreams[operation]) - write(pwm.filestreams[operation], "$entry\n") - flush(pwm.filestreams[operation]) + if assert_pwm_write(operation, entry) + seekstart(pwm.filestreams[operation]) + write(pwm.filestreams[operation], "$entry\n") + #flush(pwm.filestreams[operation]) + else + error("Invalid entry for PWM operation $(operation): $(entry)") + end end """ @@ -55,34 +69,31 @@ end 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") + if operation == 1 + entry in ["0", "1"] || error("Invalid PWM entry $(entry), valid options are 0 and 1 of type ::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]") + !(number < 0 || number > 1000000000) || error("Invalid PWM entry $(entry), not in the range [0,1000000000]") end end """ l = read(pwm::PWM, operation::Int32, debug::Bool=false) -Reads the current value from an operation on a GPIO. +Reads the current value from an operation on a PWM pin. """ function read(pwm::PWM, operation::Int32, debug::Bool=false) debug && return # Filestreams 1, 2 and 3 are readable - operation ∉ [1,2,3,4] && error("Invalid GPIO operation: $operation for reading") + operation ∉ [1,2,3,4] && error("Invalid PWM operation: $operation for reading") seekstart(pwm.filestreams[operation]) l = readline(pwm.filestreams[operation]) return l end - - - """ teardown!(pwd::PWM) Closes all open streams on the PWM, and unexports it from the file system @@ -101,7 +112,7 @@ function teardown(pwm::PWM, debug::Bool=false) try rm("$(pwm.basedir)/$(pwm_pins[pwm.pin][2])/pwm$(pwm_pins[pwm.pin][3])"; recursive=true) catch - error("Could not remove the requested GPIO testfiles for channel $(pwm_pins[pwm.pin][2])/pwm$(pwm_pins[pwm.pin][3]).") + error("Could not remove the requested PWM testfiles for channel $(pwm_pins[pwm.pin][2])/pwm$(pwm_pins[pwm.pin][3]).") end else #Unexport filestructure @@ -112,8 +123,8 @@ function teardown(pwm::PWM, debug::Bool=false) end """ - export_gpio(i::Int32, debug::Bool=false) -Export the GPIO file system, either for real-time or testing usecases. + export_pwm(i::Int32, debug::Bool=false) +Export the PWM file system, either for real-time or testing usecases. """ function export_pwm(i::Int32) # Find chip and export number @@ -137,7 +148,7 @@ function export_pwm(i::Int32) 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).") + error("Could not open the requested PWM testfiles for $(complete_path).") end else basedir = "/sys/class/pwm" @@ -147,6 +158,7 @@ function export_pwm(i::Int32) # Export the filestructure of the corresponding chip filename = "/sys/class/pwm/$(chip)/export" + println(filename) exportNumber = pwm_pins[pin][3] write(filename, exportNumber) end @@ -155,7 +167,7 @@ end """ to_string(pwm::PWM,, debug::Bool=false) -Generates a string representation of the GPIO device. +Generates a string representation of the PWM pin. """ function to_string(pwm::PWM, debug::Bool=false) debug && return diff --git a/test/BeagleBone/PWM_test.jl b/test/BeagleBone/PWM_test.jl index dcd6fa9..18bf4a2 100644 --- a/test/BeagleBone/PWM_test.jl +++ b/test/BeagleBone/PWM_test.jl @@ -59,13 +59,13 @@ using Test @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), "1000000001")) @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), "1000000001")) @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), "1000000001")) @test_throws ErrorException write!(device, (Int32(4), "bad_entry")) # Close Gpio @@ -81,8 +81,8 @@ using Test 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(2), "1000000000")) + @test read(device, Int32(2)) == "1000000000" write!(device, (Int32(3), "50000000")) @test read(device, Int32(3)) == "50000000" write!(device, (Int32(1), "1")) From 369b27a078b26ca990427529d14beeedbba8b46e Mon Sep 17 00:00:00 2001 From: mgreiff Date: Mon, 15 Apr 2019 20:29:44 +0200 Subject: [PATCH 45/47] add precompilatoin of the PWM read/write --- src/BeagleBone/precompile.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/BeagleBone/precompile.jl b/src/BeagleBone/precompile.jl index 3dac1e7..93ac201 100644 --- a/src/BeagleBone/precompile.jl +++ b/src/BeagleBone/precompile.jl @@ -46,15 +46,14 @@ function precompile_bb() # Precompile GPIO gpio = initdev("gpio",Int32(1)) - write!(gpio, (Int32(1), "1"), debug) closedev("gpio", Int32(1)) #read(gpio, ind, args, debug) # TODO activate when pwn is working - # Precompile PWM - #pwm = initdev("pwm", Int32(1)) - #write!(pwm, (Int32(1),"1"), debug) + pwm = initdev("pwm",Int32(1)) + write!(pwm, (Int32(1), "1"), debug) + closedev("pwm", Int32(1)) #Do read/write to file val = true From a367636aeb04d5f427b5fdf5a4ba7f5236d6b531 Mon Sep 17 00:00:00 2001 From: mgreiff Date: Tue, 16 Apr 2019 10:06:04 +0200 Subject: [PATCH 46/47] Add notes on the new kernel --- docs/build/index.md | 2 +- docs/build/lib/functions.md | 28 ++--- docs/build/man/development.md | 218 ++++++++++++++++++++++++++++++++- docs/build/man/installation.md | 2 +- docs/src/man/development.md | 133 ++++++++++++++++++++ 5 files changed, 366 insertions(+), 17 deletions(-) diff --git a/docs/build/index.md b/docs/build/index.md index b209639..a076763 100644 --- a/docs/build/index.md +++ b/docs/build/index.md @@ -49,8 +49,8 @@ - [`Base.read`](lib/functions.md#Base.read) - [`Base.read`](lib/functions.md#Base.read) - [`LabConnections.BeagleBone.assert_pwm_write`](lib/functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) - [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) +- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) - [`LabConnections.BeagleBone.closedev`](lib/functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) - [`LabConnections.BeagleBone.export_gpio`](lib/functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) - [`LabConnections.BeagleBone.export_led`](lib/functions.md#LabConnections.BeagleBone.export_led) diff --git a/docs/build/lib/functions.md b/docs/build/lib/functions.md index 23f8f58..6f71a12 100644 --- a/docs/build/lib/functions.md +++ b/docs/build/lib/functions.md @@ -2,8 +2,8 @@ - [`Base.read`](functions.md#Base.read) - [`Base.read`](functions.md#Base.read) - [`LabConnections.BeagleBone.assert_pwm_write`](functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) - [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) +- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) - [`LabConnections.BeagleBone.closedev`](functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) - [`LabConnections.BeagleBone.export_gpio`](functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) - [`LabConnections.BeagleBone.export_led`](functions.md#LabConnections.BeagleBone.export_led) @@ -45,10 +45,10 @@ Run a server on `port` that listens for commands from computer Optional debug ke ```julia -l = read(pwm::PWM, operation::Int32, debug::Bool=false) +l = read(led::SysLED, debug::Bool=false) ``` -Reads the current value from an operation on a GPIO. +Reads the current brightness value from the LED 'SysLED'. # **`Base.read`** — *Function*. @@ -56,10 +56,10 @@ Reads the current value from an operation on a GPIO. ```julia -l = read(led::SysLED, debug::Bool=false) +l = read(pwm::PWM, operation::Int32, debug::Bool=false) ``` -Reads the current brightness value from the LED 'SysLED'. +Reads the current value from an operation on a PWM pin. # **`Base.read`** — *Function*. @@ -144,10 +144,10 @@ Exports a dummy filesystem for testing the LED implementation ```julia -export_gpio(i::Int32, debug::Bool=false) +export_pwm(i::Int32, debug::Bool=false) ``` -Export the GPIO file system, either for real-time or testing usecases. +Export the PWM file system, either for real-time or testing usecases. # **`LabConnections.BeagleBone.getdev`** — *Method*. @@ -199,10 +199,10 @@ Prints all the active devices and writes out specifics of a single devices. ```julia -teardown(gpio::GPIO, debug::Bool=false) +teardown(led::SysLED, debug::Bool=false) ``` -Closes all open streams on the GPIO, and unexports it from the file system. +Closes all open filestreams for the SysLED 'led'. # **`LabConnections.BeagleBone.teardown`** — *Function*. @@ -210,10 +210,10 @@ Closes all open streams on the GPIO, and unexports it from the file system. ```julia -teardown(led::SysLED, debug::Bool=false) +teardown(gpio::GPIO, debug::Bool=false) ``` -Closes all open filestreams for the SysLED 'led'. +Closes all open streams on the GPIO, and unexports it from the file system. # **`LabConnections.BeagleBone.teardown`** — *Function*. @@ -232,7 +232,7 @@ Closes all open streams on the PWM, and unexports it from the file system ```julia -to_string(gpio::GPIO, debug::Bool=false) +to_string(led::SysLED, debug::Bool=false) ``` Generates a string representation of the GPIO device. @@ -243,7 +243,7 @@ Generates a string representation of the GPIO device. ```julia -to_string(led::SysLED, debug::Bool=false) +to_string(gpio::GPIO, debug::Bool=false) ``` Generates a string representation of the GPIO device. @@ -257,7 +257,7 @@ Generates a string representation of the GPIO device. to_string(pwm::PWM,, debug::Bool=false) ``` -Generates a string representation of the GPIO device. +Generates a string representation of the PWM pin. # **`LabConnections.BeagleBone.write!`** — *Function*. diff --git a/docs/build/man/development.md b/docs/build/man/development.md index c0f9e58..9394339 100644 --- a/docs/build/man/development.md +++ b/docs/build/man/development.md @@ -1,3 +1,4 @@ + # Package Development @@ -57,7 +58,222 @@ This will transfer the current development version of `LabConnections.jl` found When testing `LabConnections.jl` with hardware in the loop, the external hardware will be connected to the pin headers on the BB. For reference, the pin map of the BeagleBone (BB) is shown below. - + +

        + When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. + + + +## Notes on updates with the >=v.4.14 kernel + + +At the time of writing, the image used to flash the beaglebone is a v4.14 kernel, more specifically Linux beaglebone 4.14.71-ti-r80. + + +Since the deployment of the v4.14 kernel, the slots file and bone_capemgr have been permanantly disabled. This means that there is no need for compiling the device tree overlays as we did for the v0.6 version of the software stack. Instead, we need to configure the /boot/uEnv.txt file to enable the PWM pins correctly. Simply open the `/boot/uEnv.txt` file, add the line + + +``` +cape_enable=bone_capemgr.enable_partno=univ-all,BB-ADC,BB-PWM0,BB-PWM1,BB-PWM2 +``` + + +and uncomment the line + + +``` +disable_uboot_overlay_video=1 +``` + + +Reboot the BeagleBone, and you should now have access to the PWM pins. + + + + +### Changes to the device maps + + +The filesystem has also changed with 4.14. we now have a pwm device in `/sys/class/pwm` where we can export and then write to the PWM pins of of the BBB. However, in order to do this, we first need to idetify which pwm chip that corresponds to which pin. + + +The address of each PWM interface is + + +``` +> ls -lh /sys/class/pwm + +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip0 -> ../../devices/platform/ocp/48300000.epwmss/48300100.ecap/pwm/pwmchip0 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip1 -> ../../devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip1 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip3 -> ../../devices/platform/ocp/48302000.epwmss/48302100.ecap/pwm/pwmchip3 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip4 -> ../../devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip4 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip6 -> ../../devices/platform/ocp/48304000.epwmss/48304100.ecap/pwm/pwmchip6 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip7 -> ../../devices/platform/ocp/48304000.epwmss/48304200.pwm/pwm/pwmchip7 +``` + + +Page 184 of the TI AM335x and AMIC110 Sitara Processors Technical Reference Manual gives the memory map for the PWM chips + + +``` + PWM Subsystem 0: 0x48300000 + eCAP0: 0x48300100 + ePWM0: 0x48300200 + PWM Subsystem 1: 0x48302000 + eCAP1: 0x48302100 + ePWM1: 0x48302200 + PWM Subsystem 2: 0x48304000 + eCAP2: 0x48304100 + ePWM2: 0x48304200 +``` + + +From this we can conclude that + + +``` +ECAP0 (eCAP0) is pwmchip0 +EHRPWM0 (ePWM0) is pwmchip1 +eCAP1 (eCAP1) is pwmchip3 +EHRPWM1 (ePWM1) is pwmchip4 +eCAP2 (eCAP2) is pwmchip6 +EHRPWM2 (ePWM2) is pwmchip7 +``` + + +Based on the headers on the BeagleBone expansion cape + + +``` +EHRPWM0A = P9_22 +EHRPWM0B = P9_21 +EHRPWM1A = P9_14 +EHRPWM1B = P9_16 +EHRPWM2A = P8_19 +EHRPWM2B = P8_13 +ECAP0 = P9_42 +``` + + +which means that we get a mapping + + +``` +const pwm_pins = Dict( + "P9.22" => ("PWM0A", "pwmchip1", "0"), + "P9.21" => ("PWM0B", "pwmchip1", "1"), + "P9.14" => ("PWM1A", "pwmchip4", "0"), + "P9.16" => ("PWM1B", "pwmchip4", "1"), + "P8.19" => ("PWM2A", "pwmchip7", "0"), + "P8.13" => ("PWM2B", "pwmchip7", "1"), +) +``` + + +note that before the v4.14 kernel, this mapping was + + +``` +const pwm_pins = 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"), +) +``` + + + + +### Changes to the file system + + +Before the v4.14 kernel, the file system was structured in such a way that, after export, P9.22 could be enabled by writing to the file + + +``` +/sys/class/pwm/pwmchip0/pwm0/enable +``` + + +however, in the new kernel + + +``` +/sys/class/pwm/pwmchip1/pwm-1:0/enable +``` + + +is used to enable the PWM on the P9.22 pin. + + + + +### Testing the PWM pins individually + + +In order to test the PWM pins from the terminal, make sure that you have added the lines in the /boot/uEnv.txt file, and then configure the desired pin to a PWM pin. For instance, if we wish to control the P9.22 pin, run + + +``` +config-pin P9.22 pwm +``` + + +and make sure that it is configured correctly by running + + +``` +config-pin -q P9.22 +``` + + +which should return "P9_22 Mode: pwm". Now you first need to export the correct pin, which, according the the device mapping above, can be done by + + +``` +echo 0 > /sys/class/pwm/pwmchip1/export +``` + + +once this is done, we set a period and duty cycle to the pin + + +``` +echo 1000000000 > /sys/class/pwm/pwmchip1/pwm-1\:0/period +echo 800000000 > /sys/class/pwm/pwmchip1/pwm-1\:0/duty_cycle +``` + + +and enable it through + + +``` +echo 1 > /sys/class/pwm/pwmchip1/pwm-1\:0/enable +``` + + +disable and unexport the PWM pin by + + +``` +echo 0 > /sys/class/pwm/pwmchip1/pwm-1\:0/enable +echo 0 > /sys/class/pwm/pwmchip1/unexport +``` + + +Alternatively, this can be done using the Julia, by writing + + +``` +p = PWM(1) +write!(p, (1, "1")) +write!(p, (2, "1000000000")) +write!(p, (3, "800000000")) +``` + diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index c33a812..0858bac 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -62,7 +62,7 @@ Start by downloading the Debian image [here](http://beagleboard.org/latest-image ``` -mv /home/debian/julia-/bin/julia /home/debian/julia/bin/julia +mv /home/debian/julia- /home/debian/julia ``` diff --git a/docs/src/man/development.md b/docs/src/man/development.md index 039132b..9837dfb 100644 --- a/docs/src/man/development.md +++ b/docs/src/man/development.md @@ -31,3 +31,136 @@ When testing `LabConnections.jl` with hardware in the loop, the external hardwar

        When running examples and tests with hardware in the loop, take caution not to short the BB ground with any output pin, as this will damage the board. For instance, if connecting a diode to the output pins, always use a resistor of >1 kOhm in parallel. + +## Notes on updates with the >=v.4.14 kernel +At the time of writing, the image used to flash the beaglebone is +a v4.14 kernel, more specifically Linux beaglebone 4.14.71-ti-r80. + +Since the deployment of the v4.14 kernel, the slots file and bone_capemgr have been permanantly disabled. This means that there is no need for compiling the device tree overlays as we did for the v0.6 version of the software stack. Instead, we need to configure the /boot/uEnv.txt file to enable the PWM pins correctly. Simply open the `/boot/uEnv.txt` file, add the line + +``` +cape_enable=bone_capemgr.enable_partno=univ-all,BB-ADC,BB-PWM0,BB-PWM1,BB-PWM2 +``` +and uncomment the line +``` +disable_uboot_overlay_video=1 +``` +Reboot the BeagleBone, and you should now have access to the PWM pins. + +### Changes to the device maps +The filesystem has also changed with 4.14. we now have a pwm device in +`/sys/class/pwm` where we can export and then write to the PWM pins of +of the BBB. However, in order to do this, we first need to idetify which +pwm chip that corresponds to which pin. + +The address of each PWM interface is +``` +> ls -lh /sys/class/pwm + +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip0 -> ../../devices/platform/ocp/48300000.epwmss/48300100.ecap/pwm/pwmchip0 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip1 -> ../../devices/platform/ocp/48300000.epwmss/48300200.pwm/pwm/pwmchip1 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip3 -> ../../devices/platform/ocp/48302000.epwmss/48302100.ecap/pwm/pwmchip3 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip4 -> ../../devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip4 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip6 -> ../../devices/platform/ocp/48304000.epwmss/48304100.ecap/pwm/pwmchip6 +lrwxrwxrwx 1 root pwm 0 Oct 7 16:40 pwmchip7 -> ../../devices/platform/ocp/48304000.epwmss/48304200.pwm/pwm/pwmchip7 +``` +Page 184 of the TI AM335x and AMIC110 Sitara Processors Technical Reference Manual gives the memory map for the PWM chips +``` + PWM Subsystem 0: 0x48300000 + eCAP0: 0x48300100 + ePWM0: 0x48300200 + PWM Subsystem 1: 0x48302000 + eCAP1: 0x48302100 + ePWM1: 0x48302200 + PWM Subsystem 2: 0x48304000 + eCAP2: 0x48304100 + ePWM2: 0x48304200 +``` +From this we can conclude that +``` +ECAP0 (eCAP0) is pwmchip0 +EHRPWM0 (ePWM0) is pwmchip1 +eCAP1 (eCAP1) is pwmchip3 +EHRPWM1 (ePWM1) is pwmchip4 +eCAP2 (eCAP2) is pwmchip6 +EHRPWM2 (ePWM2) is pwmchip7 +``` +Based on the headers on the BeagleBone expansion cape +``` +EHRPWM0A = P9_22 +EHRPWM0B = P9_21 +EHRPWM1A = P9_14 +EHRPWM1B = P9_16 +EHRPWM2A = P8_19 +EHRPWM2B = P8_13 +ECAP0 = P9_42 +``` + +which means that we get a mapping +``` +const pwm_pins = Dict( + "P9.22" => ("PWM0A", "pwmchip1", "0"), + "P9.21" => ("PWM0B", "pwmchip1", "1"), + "P9.14" => ("PWM1A", "pwmchip4", "0"), + "P9.16" => ("PWM1B", "pwmchip4", "1"), + "P8.19" => ("PWM2A", "pwmchip7", "0"), + "P8.13" => ("PWM2B", "pwmchip7", "1"), +) +``` +note that before the v4.14 kernel, this mapping was +``` +const pwm_pins = 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"), +) +``` + +### Changes to the file system +Before the v4.14 kernel, the file system was structured in such a way that, after export, P9.22 could be enabled by writing to the file +``` +/sys/class/pwm/pwmchip0/pwm0/enable +``` +however, in the new kernel +``` +/sys/class/pwm/pwmchip1/pwm-1:0/enable +``` +is used to enable the PWM on the P9.22 pin. + +### Testing the PWM pins individually +In order to test the PWM pins from the terminal, make sure that you have added the lines in the /boot/uEnv.txt file, and then configure the desired pin to a PWM pin. For instance, if we wish to control the P9.22 pin, run +``` +config-pin P9.22 pwm +``` +and make sure that it is configured correctly by running +``` +config-pin -q P9.22 +``` +which should return "P9_22 Mode: pwm". Now you first need to export the correct pin, which, according the the device mapping above, can be done by +``` +echo 0 > /sys/class/pwm/pwmchip1/export +``` +once this is done, we set a period and duty cycle to the pin +``` +echo 1000000000 > /sys/class/pwm/pwmchip1/pwm-1\:0/period +echo 800000000 > /sys/class/pwm/pwmchip1/pwm-1\:0/duty_cycle +``` +and enable it through +``` +echo 1 > /sys/class/pwm/pwmchip1/pwm-1\:0/enable +``` +disable and unexport the PWM pin by +``` +echo 0 > /sys/class/pwm/pwmchip1/pwm-1\:0/enable +echo 0 > /sys/class/pwm/pwmchip1/unexport +``` +Alternatively, this can be done using the Julia, by writing +``` +p = PWM(1) +write!(p, (1, "1")) +write!(p, (2, "1000000000")) +write!(p, (3, "800000000")) +``` From 838a086a20bb82dae793385ddadcefa6d68307ea Mon Sep 17 00:00:00 2001 From: mgreiff Date: Tue, 16 Apr 2019 10:10:03 +0200 Subject: [PATCH 47/47] Update installation instructions --- docs/build/index.md | 2 +- docs/build/lib/functions.md | 2 +- docs/build/man/installation.md | 24 ++++++++++++++++++++++++ docs/src/man/installation.md | 12 ++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/docs/build/index.md b/docs/build/index.md index a076763..b209639 100644 --- a/docs/build/index.md +++ b/docs/build/index.md @@ -49,8 +49,8 @@ - [`Base.read`](lib/functions.md#Base.read) - [`Base.read`](lib/functions.md#Base.read) - [`LabConnections.BeagleBone.assert_pwm_write`](lib/functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) - [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) +- [`LabConnections.BeagleBone.bbparse`](lib/functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) - [`LabConnections.BeagleBone.closedev`](lib/functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) - [`LabConnections.BeagleBone.export_gpio`](lib/functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) - [`LabConnections.BeagleBone.export_led`](lib/functions.md#LabConnections.BeagleBone.export_led) diff --git a/docs/build/lib/functions.md b/docs/build/lib/functions.md index 6f71a12..c23e902 100644 --- a/docs/build/lib/functions.md +++ b/docs/build/lib/functions.md @@ -2,8 +2,8 @@ - [`Base.read`](functions.md#Base.read) - [`Base.read`](functions.md#Base.read) - [`LabConnections.BeagleBone.assert_pwm_write`](functions.md#LabConnections.BeagleBone.assert_pwm_write-Tuple{Int32,String}) -- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) - [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Any}) +- [`LabConnections.BeagleBone.bbparse`](functions.md#LabConnections.BeagleBone.bbparse-Tuple{Tuple,Any}) - [`LabConnections.BeagleBone.closedev`](functions.md#LabConnections.BeagleBone.closedev-Tuple{String,Int32}) - [`LabConnections.BeagleBone.export_gpio`](functions.md#LabConnections.BeagleBone.export_gpio-Tuple{Int32}) - [`LabConnections.BeagleBone.export_led`](functions.md#LabConnections.BeagleBone.export_led) diff --git a/docs/build/man/installation.md b/docs/build/man/installation.md index 0858bac..bbfba5c 100644 --- a/docs/build/man/installation.md +++ b/docs/build/man/installation.md @@ -133,6 +133,30 @@ This scripts bundles the current code in LabConnections.jl and serbus on the hos + + +### Setting up the uEnv file + + +Since the deployment of the v4.14 kernel, the slots file and bone_capemgr have been permanantly disabled. This means that there is no need for compiling the device tree overlays as we did for the v0.6 version of the software stack. Instead, we need to configure the /boot/uEnv.txt file to enable the PWM pins correctly. Simply open the `/boot/uEnv.txt` file, add the line + + +``` +cape_enable=bone_capemgr.enable_partno=univ-all,BB-ADC,BB-PWM0,BB-PWM1,BB-PWM2 +``` + + +and uncomment the line + + +``` +disable_uboot_overlay_video=1 +``` + + +Reboot the BeagleBone, and you should now have access to the PWM pins. + + ### Setting up a Julia server on the BeagleBone diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md index 333ad1d..eafab98 100644 --- a/docs/src/man/installation.md +++ b/docs/src/man/installation.md @@ -65,6 +65,18 @@ This scripts bundles the current code in LabConnections.jl and serbus on the hos +### Setting up the uEnv file +Since the deployment of the v4.14 kernel, the slots file and bone_capemgr have been permanantly disabled. This means that there is no need for compiling the device tree overlays as we did for the v0.6 version of the software stack. Instead, we need to configure the /boot/uEnv.txt file to enable the PWM pins correctly. Simply open the `/boot/uEnv.txt` file, add the line + +``` +cape_enable=bone_capemgr.enable_partno=univ-all,BB-ADC,BB-PWM0,BB-PWM1,BB-PWM2 +``` +and uncomment the line +``` +disable_uboot_overlay_video=1 +``` +Reboot the BeagleBone, and you should now have access to the PWM pins. + ### Setting up a Julia server on the BeagleBone To setup automatic start of Julia server on the BB, make sure to have completed all prior installation instructions, and that the latest revision of the LabConnections package is located on the BB. SSH into the BB, and copy the file `juliaserver.service` to the folder `systemd/system` ```