From 2855a4677ff30213eaec1fb4047fcd5f8e3e5e2c Mon Sep 17 00:00:00 2001 From: Marc-Antoine Ruel Date: Mon, 20 Jun 2022 14:33:06 -0400 Subject: [PATCH] Remove stale code, use periph.io/x/host/v3 instead --- .gohci.yml | 90 - .travis.yml | 44 - CONTRIBUTING.md | 4 - cmd/README.md | 20 - cmd/d2xx-program/main.go | 104 -- cmd/d2xx/main.go | 144 -- cmd/extra-smoketest/README.md | 6 - cmd/extra-smoketest/main.go | 137 -- conn/README.md | 11 - devices/README.md | 11 - devices/screen/screen.go | 116 -- experimental/README.md | 17 - experimental/cmd/README.md | 7 - experimental/cmd/lsusb/main.go | 35 - experimental/conn/README.md | 7 - experimental/conn/usb/usb.go | 87 - experimental/devices/README.md | 7 - experimental/hostextra/README.md | 8 - experimental/hostextra/usbbus/doc.go | 6 - experimental/hostextra/usbbus/usbbus.go | 283 ---- experimental/hostextra/usbbus/usbbus_test.go | 32 - .../hostextra/winthermal/winthermal.go | 78 - .../hostextra/winthermal/winthermal_others.go | 13 - .../winthermal/winthermal_windows.go | 23 - go.mod | 9 - go.sum | 16 - hostextra/README.md | 12 - hostextra/d2xx/README.md | 46 - hostextra/d2xx/WinTypes.h | 154 -- hostextra/d2xx/cbus.go | 12 - hostextra/d2xx/d2xx.go | 624 ------- hostextra/d2xx/d2xx_darwin_amd64.go | 12 - hostextra/d2xx/d2xx_linux_amd64.go | 12 - hostextra/d2xx/d2xx_linux_arm.go | 15 - hostextra/d2xx/d2xx_posix.go | 224 --- hostextra/d2xx/d2xx_posix_no_cgo.go | 112 -- hostextra/d2xx/d2xx_posix_other.go | 16 - hostextra/d2xx/d2xx_windows.go | 283 ---- hostextra/d2xx/d2xxsmoketest/README.md | 3 - hostextra/d2xx/d2xxsmoketest/d2xxsmoketest.go | 210 --- hostextra/d2xx/darwin_amd64/libftd2xx.a | Bin 350680 -> 0 bytes hostextra/d2xx/debian/98-ft232h.rules | 14 - hostextra/d2xx/dev.go | 878 ---------- hostextra/d2xx/doc.go | 8 - hostextra/d2xx/driver.go | 206 --- hostextra/d2xx/driver_test.go | 145 -- hostextra/d2xx/example_test.go | 28 - hostextra/d2xx/ftd2xx.h | 1446 ----------------- hostextra/d2xx/ftdi/eeprom.go | 348 ---- hostextra/d2xx/gpio.go | 241 --- hostextra/d2xx/i2c.go | 291 ---- hostextra/d2xx/jtag.go | 10 - hostextra/d2xx/linux_amd64/libftd2xx.a | Bin 403410 -> 0 bytes hostextra/d2xx/linux_arm/libftd2xx.a | Bin 342444 -> 0 bytes hostextra/d2xx/mpsse.go | 616 ------- hostextra/d2xx/parallel.go | 10 - hostextra/d2xx/pin.go | 85 - hostextra/d2xx/spi.go | 696 -------- hostextra/d2xx/test.sh | 25 - hostextra/d2xx/uart.go | 7 - hostextra/doc.go | 8 - hostextra/hostextra.go | 23 - hostextra/hostextra_test.go | 15 - 63 files changed, 8150 deletions(-) delete mode 100644 .gohci.yml delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 cmd/README.md delete mode 100644 cmd/d2xx-program/main.go delete mode 100644 cmd/d2xx/main.go delete mode 100644 cmd/extra-smoketest/README.md delete mode 100644 cmd/extra-smoketest/main.go delete mode 100644 conn/README.md delete mode 100644 devices/README.md delete mode 100644 devices/screen/screen.go delete mode 100644 experimental/README.md delete mode 100644 experimental/cmd/README.md delete mode 100644 experimental/cmd/lsusb/main.go delete mode 100644 experimental/conn/README.md delete mode 100644 experimental/conn/usb/usb.go delete mode 100644 experimental/devices/README.md delete mode 100644 experimental/hostextra/README.md delete mode 100644 experimental/hostextra/usbbus/doc.go delete mode 100644 experimental/hostextra/usbbus/usbbus.go delete mode 100644 experimental/hostextra/usbbus/usbbus_test.go delete mode 100644 experimental/hostextra/winthermal/winthermal.go delete mode 100644 experimental/hostextra/winthermal/winthermal_others.go delete mode 100644 experimental/hostextra/winthermal/winthermal_windows.go delete mode 100644 hostextra/README.md delete mode 100644 hostextra/d2xx/README.md delete mode 100644 hostextra/d2xx/WinTypes.h delete mode 100644 hostextra/d2xx/cbus.go delete mode 100644 hostextra/d2xx/d2xx.go delete mode 100644 hostextra/d2xx/d2xx_darwin_amd64.go delete mode 100644 hostextra/d2xx/d2xx_linux_amd64.go delete mode 100644 hostextra/d2xx/d2xx_linux_arm.go delete mode 100644 hostextra/d2xx/d2xx_posix.go delete mode 100644 hostextra/d2xx/d2xx_posix_no_cgo.go delete mode 100644 hostextra/d2xx/d2xx_posix_other.go delete mode 100644 hostextra/d2xx/d2xx_windows.go delete mode 100644 hostextra/d2xx/d2xxsmoketest/README.md delete mode 100644 hostextra/d2xx/d2xxsmoketest/d2xxsmoketest.go delete mode 100644 hostextra/d2xx/darwin_amd64/libftd2xx.a delete mode 100644 hostextra/d2xx/debian/98-ft232h.rules delete mode 100644 hostextra/d2xx/dev.go delete mode 100644 hostextra/d2xx/doc.go delete mode 100644 hostextra/d2xx/driver.go delete mode 100644 hostextra/d2xx/driver_test.go delete mode 100644 hostextra/d2xx/example_test.go delete mode 100644 hostextra/d2xx/ftd2xx.h delete mode 100644 hostextra/d2xx/ftdi/eeprom.go delete mode 100644 hostextra/d2xx/gpio.go delete mode 100644 hostextra/d2xx/i2c.go delete mode 100644 hostextra/d2xx/jtag.go delete mode 100644 hostextra/d2xx/linux_amd64/libftd2xx.a delete mode 100644 hostextra/d2xx/linux_arm/libftd2xx.a delete mode 100644 hostextra/d2xx/mpsse.go delete mode 100644 hostextra/d2xx/parallel.go delete mode 100644 hostextra/d2xx/pin.go delete mode 100644 hostextra/d2xx/spi.go delete mode 100755 hostextra/d2xx/test.sh delete mode 100644 hostextra/d2xx/uart.go delete mode 100644 hostextra/doc.go delete mode 100644 hostextra/hostextra.go delete mode 100644 hostextra/hostextra_test.go diff --git a/.gohci.yml b/.gohci.yml deleted file mode 100644 index da8341c..0000000 --- a/.gohci.yml +++ /dev/null @@ -1,90 +0,0 @@ -# See https://github.com/periph/gohci -version: 1 -workers: -- name: mbp - checks: - - cmd: - - go - - test - - ./... - - cmd: - - ./hostextra/d2xx/test.sh - - cmd: - - go - - install - - ./cmd/... - - cmd: - - d2xx - - cmd: - - extra-smoketest - - d2xx - - -type - - ft232r - - cmd: - - go - - install - - -tags - - periphextra - - periph.io/x/periph/cmd/gpio-list - - periph.io/x/periph/cmd/headers-list - - periph.io/x/periph/cmd/i2c-list - - periph.io/x/periph/cmd/spi-list - - cmd: - - gpio-list - - cmd: - - headers-list - - cmd: - - i2c-list - - cmd: - - spi-list -- name: raspberrypi-2f34 - checks: - - cmd: - - go - - test - - ./... - - cmd: - - go - - install - - ./cmd/... - - cmd: - - d2xx -- name: win10 - checks: - - cmd: - - go - - test - - -race - - ./... - - cmd: - - go - - vet - - ./... - - cmd: - - go - - install - - ./cmd/... - - cmd: - - d2xx - - cmd: - - extra-smoketest - - d2xx - - -type - - ft232h - - cmd: - - go - - install - - -tags - - periphextra - - periph.io/x/periph/cmd/gpio-list - - periph.io/x/periph/cmd/headers-list - - periph.io/x/periph/cmd/i2c-list - - periph.io/x/periph/cmd/spi-list - - cmd: - - gpio-list - - cmd: - - headers-list - - cmd: - - i2c-list - - cmd: - - spi-list diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 030ca72..0000000 --- a/.travis.yml +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2019 The Periph Authors. All rights reserved. -# Use of this source code is governed under the Apache License, Version 2.0 -# that can be found in the LICENSE file. - -language: go -sudo: false -dist: xenial -go_import_path: periph.io/x/extra - -matrix: - include: - - go: 1.12.x - env: GO111MODULE=on - cache: - directories: - # go1.10+ 'go test' cache on linux (macOS and Windows are # different). - - $HOME/.cache/go-build - # go1.11+ with GO111MODULE=on - - $GOPATH/pkg/mod - # Cache tools sources. Manually verified that both misspell and ineffassign - # only depend on the stdlib. - - $GOPATH/src/github\.com - # For shadow. - - $GOPATH/src/golang\.org - -before_install: - - sudo apt-get -qq update - - sudo apt-get install -y libusb-1.0.0 libusb-dev - -before_script: - - echo $TRAVIS_GO_VERSION - - go get -v periph.io/x/extra/... - - go get -u -v github.com/client9/misspell/cmd/misspell github.com/gordonklaus/ineffassign golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow - -script: - - echo 'Check Code is well formatted'; ! gofmt -s -d . | read - - echo 'Erroring on misspelling'; ! misspell . | grep a - - ineffassign . - - go vet -vettool=$GOPATH/bin/shadow ./... - - bash -c 'set -e; echo "" > coverage.txt; for d in $(go list ./...); do go test -covermode=count -coverprofile=p.out $d; if [ -f p.out ]; then cat p.out >> coverage.txt; rm p.out; fi; done' - - go test -race ./... - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 56a90a0..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,4 +0,0 @@ -# Contributing - -Thanks for contributing to the project! Please look at [the periph contribution -guidelines](https://periph.io/project/contributing/) first. diff --git a/cmd/README.md b/cmd/README.md deleted file mode 100644 index 180b4c3..0000000 --- a/cmd/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# extra/cmd - read-to-use executables - -This directory contains directly usable tools installable via: - -``` -go get periph.io/x/extra/cmd/... -``` - -It is expected that many of these packages cannot be cross compiled easily, as -they likely leverage `cgo`. - -This directory contains executables that are considered stable and complete as -per [driver lifetime -management](https://periph.io/project/#driver-lifetime-management). - -You are welcome to create pull requests to add tools here or improve the -quality of executables already here. Please make sure to abide to requests in -[project/contributing/](https://periph.io/project/contributing/). - -Unlike code in periph/cmd, code in extra/cmd is allowed to use `cgo`. diff --git a/cmd/d2xx-program/main.go b/cmd/d2xx-program/main.go deleted file mode 100644 index a67039c..0000000 --- a/cmd/d2xx-program/main.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// d2xx-program programs a FTDI device. -// -// It can either program the EEPROM or the User Area. -package main - -import ( - "encoding/hex" - "errors" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - - "periph.io/x/extra/hostextra/d2xx" - "periph.io/x/extra/hostextra/d2xx/ftdi" - "periph.io/x/periph/host" -) - -func writeEEPROM(d d2xx.Dev, manufacturer, manufacturerID, desc, serial string) error { - ee := ftdi.EEPROM{} - if err := d.EEPROM(&ee); err != nil { - fmt.Printf("Failed to read EEPROM: %v\n", err) - } - ee.Manufacturer = manufacturer - ee.ManufacturerID = manufacturerID - ee.Desc = desc - ee.Serial = serial - log.Printf("Writing: %x", ee.Raw) - return d.WriteEEPROM(&ee) -} - -func mainImpl() error { - verbose := flag.Bool("v", false, "verbose mode") - erase := flag.Bool("e", false, "erases the EEPROM instead of programming it") - manufacturer := flag.String("m", "", "manufacturer") - manufacturerID := flag.String("mid", "", "manufacturer ID") - desc := flag.String("d", "", "description") - serial := flag.String("s", "", "serial") - ua := flag.String("ua", "", "hex encoded data") - - flag.Parse() - if !*verbose { - log.SetOutput(ioutil.Discard) - } - log.SetFlags(log.Lmicroseconds) - - if flag.NArg() != 0 { - return errors.New("unexpected argument, try -help") - } - if *erase { - if *ua != "" || *manufacturer != "" || *manufacturerID != "" || *desc != "" || *serial != "" { - return errors.New("-e cannot be used with any of -m, -mid, -d, -s, -ua") - } - } else { - if *ua == "" { - if *manufacturer == "" || *manufacturerID == "" || *desc == "" || *serial == "" { - return errors.New("all of -m, -mid, -d and -s are required, or use -ua") - } - } else { - if *manufacturer != "" || *manufacturerID != "" || *desc != "" || *serial != "" { - return errors.New("all of -m, -mid, -d and -s cannot be used with -ua") - } - } - } - - if _, err := host.Init(); err != nil { - return err - } - major, minor, build := d2xx.Version() - log.Printf("Using library %d.%d.%d\n", major, minor, build) - - all := d2xx.All() - if len(all) == 0 { - return errors.New("found no FTDI device on the USB bus") - } - if len(all) > 1 { - return fmt.Errorf("for safety reasons, plug exactly one FTDI device on the USB bus, found %d devices", len(all)) - } - d := all[0] - - if *erase { - return d.EraseEEPROM() - } - if *ua == "" { - return writeEEPROM(d, *manufacturer, *manufacturerID, *desc, *serial) - } - raw, err := hex.DecodeString(*ua) - if err != nil { - return err - } - return d.WriteUserArea(raw) -} - -func main() { - if err := mainImpl(); err != nil { - fmt.Fprintf(os.Stderr, "d2xx-program: %s.\n", err) - os.Exit(1) - } -} diff --git a/cmd/d2xx/main.go b/cmd/d2xx/main.go deleted file mode 100644 index a34130e..0000000 --- a/cmd/d2xx/main.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// d2xx prints out information about the FTDI devices found on the USB bus. -package main - -import ( - "errors" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - - "periph.io/x/extra/hostextra/d2xx" - "periph.io/x/extra/hostextra/d2xx/ftdi" - "periph.io/x/periph/host" -) - -func process(d d2xx.Dev) { - i := d2xx.Info{} - d.Info(&i) - fmt.Printf(" Type: %s\n", i.Type) - fmt.Printf(" Vendor ID: %#04x\n", i.VenID) - fmt.Printf(" Device ID: %#04x\n", i.DevID) - - ee := ftdi.EEPROM{} - if err := d.EEPROM(&ee); err == nil { - fmt.Printf(" Manufacturer: %s\n", ee.Manufacturer) - fmt.Printf(" ManufacturerID: %s\n", ee.ManufacturerID) - fmt.Printf(" Desc: %s\n", ee.Desc) - fmt.Printf(" Serial: %s\n", ee.Serial) - - h := ee.AsHeader() - fmt.Printf(" MaxPower: %dmA\n", h.MaxPower) - fmt.Printf(" SelfPowered: %x\n", h.SelfPowered) - fmt.Printf(" RemoteWakeup: %x\n", h.RemoteWakeup) - fmt.Printf(" PullDownEnable: %x\n", h.PullDownEnable) - switch i.Type { - case "FT232H": - p := ee.AsFT232H() - fmt.Printf(" CSlowSlew: %d\n", p.ACSlowSlew) - fmt.Printf(" CSchmittInput: %d\n", p.ACSchmittInput) - fmt.Printf(" CDriveCurrent: %dmA\n", p.ACDriveCurrent) - fmt.Printf(" DSlowSlew: %d\n", p.ADSlowSlew) - fmt.Printf(" DSchmittInput: %d\n", p.ADSchmittInput) - fmt.Printf(" DDriveCurrent: %dmA\n", p.ADDriveCurrent) - fmt.Printf(" Cbus0: %s\n", p.Cbus0) - fmt.Printf(" Cbus1: %s\n", p.Cbus1) - fmt.Printf(" Cbus2: %s\n", p.Cbus2) - fmt.Printf(" Cbus3: %s\n", p.Cbus3) - fmt.Printf(" Cbus4: %s\n", p.Cbus4) - fmt.Printf(" Cbus5: %s\n", p.Cbus5) - fmt.Printf(" Cbus6: %s\n", p.Cbus6) - fmt.Printf(" Cbus7: %s\n", p.Cbus7) - fmt.Printf(" Cbus8: %s\n", p.Cbus8) - fmt.Printf(" Cbus9: %s\n", p.Cbus9) - fmt.Printf(" FT1248Cpol: %d\n", p.FT1248Cpol) - fmt.Printf(" FT1248Lsb: %d\n", p.FT1248Lsb) - fmt.Printf(" FT1248FlowCtrl: %d\n", p.FT1248FlowControl) - fmt.Printf(" IsFifo: %d\n", p.IsFifo) - fmt.Printf(" IsFifoTar: %d\n", p.IsFifoTar) - fmt.Printf(" IsFastSer: %d\n", p.IsFastSer) - fmt.Printf(" IsFT1248: %d\n", p.IsFT1248) - fmt.Printf(" PowerSaveEnabl: %d\n", p.PowerSaveEnable) - fmt.Printf(" DriverType: %d\n", p.DriverType) - case "FT232R": - p := ee.AsFT232R() - fmt.Printf(" IsHighCurrent: %d\n", p.IsHighCurrent) - fmt.Printf(" UseExtOsc: %d\n", p.UseExtOsc) - fmt.Printf(" InvertTXD: %d\n", p.InvertTXD) - fmt.Printf(" InvertRXD: %d\n", p.InvertRXD) - fmt.Printf(" InvertRTS: %d\n", p.InvertRTS) - fmt.Printf(" InvertCTS: %d\n", p.InvertCTS) - fmt.Printf(" InvertDTR: %d\n", p.InvertDTR) - fmt.Printf(" InvertDSR: %d\n", p.InvertDSR) - fmt.Printf(" InvertDCD: %d\n", p.InvertDCD) - fmt.Printf(" InvertRI: %d\n", p.InvertRI) - fmt.Printf(" Cbus0: %s\n", p.Cbus0) - fmt.Printf(" Cbus1: %s\n", p.Cbus1) - fmt.Printf(" Cbus2: %s\n", p.Cbus2) - fmt.Printf(" Cbus3: %s\n", p.Cbus3) - fmt.Printf(" Cbus4: %s\n", p.Cbus4) - fmt.Printf(" DriverType: %d\n", p.DriverType) - default: - fmt.Printf("Unknown device: %s\n", i.Type) - } - log.Printf(" Raw: %x\n", ee.Raw) - } else { - fmt.Printf("Failed to read EEPROM: %v\n", err) - } - - if ua, err := d.UserArea(); err != nil { - fmt.Printf("Failed to read UserArea: %v\n", err) - } else { - fmt.Printf("UserArea: %x\n", ua) - } - - hdr := d.Header() - for _, p := range hdr { - fmt.Printf("%s: %s\n", p, p.Function()) - } -} - -func mainImpl() error { - verbose := flag.Bool("v", false, "verbose mode") - flag.Parse() - if !*verbose { - log.SetOutput(ioutil.Discard) - } - log.SetFlags(log.Lmicroseconds) - if flag.NArg() != 0 { - return errors.New("unexpected argument, try -help") - } - - if _, err := host.Init(); err != nil { - return err - } - - major, minor, build := d2xx.Version() - fmt.Printf("Using library %d.%d.%d\n", major, minor, build) - all := d2xx.All() - plural := "" - if len(all) > 1 { - plural = "s" - } - fmt.Printf("Found %d device%s\n", len(all), plural) - for i, d := range all { - fmt.Printf("- Device #%d\n", i) - process(d) - if i != len(all)-1 { - fmt.Printf("\n") - } - } - return nil -} - -func main() { - if err := mainImpl(); err != nil { - fmt.Fprintf(os.Stderr, "d2xx: %s.\n", err) - os.Exit(1) - } -} diff --git a/cmd/extra-smoketest/README.md b/cmd/extra-smoketest/README.md deleted file mode 100644 index 19a1910..0000000 --- a/cmd/extra-smoketest/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# extra-smoketest - -This executable runs smoke tests, that is, tests that require hardware to -interact with and confirm that both the driver and the actual hardware work. -The executable exits with return code 0 when successful and non-zero when an -error is detected to enable automated testing lab. diff --git a/cmd/extra-smoketest/main.go b/cmd/extra-smoketest/main.go deleted file mode 100644 index eb3f51e..0000000 --- a/cmd/extra-smoketest/main.go +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// extra-smoketest runs all known smoke tests. -package main - -import ( - "errors" - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "sort" - - "periph.io/x/extra/hostextra/d2xx/d2xxsmoketest" - "periph.io/x/periph/host" -) - -// SmokeTest must be implemented by a smoke test. It will be run by this -// executable. -type SmokeTest interface { - // Name is the name of the smoke test, it is the identifier used on the - // command line. - Name() string - // Description returns a short description to be printed to the user in the - // help page, to explain what this test does and any requirement to make it - // work. - Description() string - // Run runs the test and return an error in case of failure. - Run(f *flag.FlagSet, args []string) error -} - -// tests is the list of registered smoke tests. -var tests = []SmokeTest{ - &d2xxsmoketest.SmokeTest{}, -} - -func usage(fs *flag.FlagSet) { - _, _ = io.WriteString(os.Stderr, "Usage: extra-smoketest ...\n\n") - fs.PrintDefaults() - _, _ = io.WriteString(os.Stderr, "\nTests available:\n") - names := make([]string, len(tests)) - desc := make(map[string]string, len(tests)) - l := 0 - for i := range tests { - n := tests[i].Name() - if len(n) > l { - l = len(n) - } - names[i] = n - desc[n] = tests[i].Description() - } - sort.Strings(names) - for _, name := range names { - fmt.Fprintf(os.Stderr, " %-*s %s\n", l, name, desc[name]) - } -} - -func mainImpl() error { - state, err := host.Init() - if err != nil { - return fmt.Errorf("error loading drivers: %v", err) - } - fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError) - verbose := fs.Bool("v", false, "verbose mode") - fs.Usage = func() { usage(fs) } - if err = fs.Parse(os.Args[1:]); err == flag.ErrHelp { - return nil - } else if err != nil { - return err - } - if fs.NArg() == 0 { - fs.Usage() - _, _ = io.WriteString(os.Stdout, "\n") - return errors.New("please specify a test to run or use -help") - } - cmd := fs.Arg(0) - if cmd == "help" { - usage(fs) - return nil - } - - if !*verbose { - log.SetOutput(ioutil.Discard) - } - log.SetFlags(log.Lmicroseconds) - - if *verbose { - if len(state.Failed) > 0 { - log.Print("Failed to load some drivers:") - for _, failure := range state.Failed { - log.Printf("- %s: %v", failure.D, failure.Err) - } - } - log.Printf("Using drivers:") - for _, driver := range state.Loaded { - log.Printf("- %s", driver) - } - if len(state.Skipped) > 0 { - log.Printf("Drivers skipped:") - for _, failure := range state.Skipped { - log.Printf("- %s: %v", failure.D, failure.Err) - } - } - } - - for _, t := range tests { - if t.Name() == cmd { - f := flag.NewFlagSet("extra-smoketest "+t.Name(), flag.ExitOnError) - u := f.Usage - f.Usage = func() { - fmt.Printf("%s: %s\n\n", t.Name(), t.Description()) - u() - flags := false - f.VisitAll(func(*flag.Flag) { flags = true }) - if !flags { - fmt.Printf(" This smoke test doesn't have any flag.\n") - } - } - if err = t.Run(f, fs.Args()[1:]); err == nil { - log.Printf("Test %s successful", cmd) - } - return err - } - } - return fmt.Errorf("test case %q was not found", cmd) -} - -func main() { - if err := mainImpl(); err != nil { - fmt.Fprintf(os.Stderr, "extra-smoketest: %s.\n", err) - os.Exit(1) - } -} diff --git a/conn/README.md b/conn/README.md deleted file mode 100644 index c1abf68..0000000 --- a/conn/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# conn - -This directory contains protocols and connections that are considered stable and -complete as per [driver lifetime -management](https://periph.io/project/#driver-lifetime-management). - -You are welcome to create pull requests to add drivers here or improve the -quality of drivers already here. Please make sure to abide to requests in -[project/contributing/](https://periph.io/project/contributing/). - -Unlike code in periph, code in extra is allowed to use `cgo`. diff --git a/devices/README.md b/devices/README.md deleted file mode 100644 index ffd7a9c..0000000 --- a/devices/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# devices - -This directory contains device drivers that are considered stable and complete -as per [driver lifetime -management](https://periph.io/project/#driver-lifetime-management). - -You are welcome to create pull requests to add drivers here or improve the -quality of drivers already here. Please make sure to abide to requests in -[project/contributing/](https://periph.io/project/contributing/). - -Unlike code in periph, code in extra is allowed to use `cgo`. diff --git a/devices/screen/screen.go b/devices/screen/screen.go deleted file mode 100644 index e13c821..0000000 --- a/devices/screen/screen.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Package screen implements a 1D display.Drawer that outputs to terminal -// (stdout) using ANSI color codes. -// -// Useful while you are waiting for your super nice APA-102 LED strip to come -// by mail. -package screen // import "periph.io/x/extra/devices/screen" - -import ( - "bytes" - "errors" - "fmt" - "image" - "image/color" - "io" - - "github.com/maruel/ansi256" - "github.com/mattn/go-colorable" - "periph.io/x/periph/conn/display" -) - -// Dev is a 1D LED strip emulator that outputs to the console. -type Dev struct { - w io.Writer - l int - pixels []byte - buf bytes.Buffer -} - -// New returns a Dev that displays at the console. -// -// Permits to do local testing of LEDs animation. -func New(l int) *Dev { - return &Dev{ - w: colorable.NewColorableStdout(), - l: l, - pixels: make([]byte, 3*l), - } -} - -func (d *Dev) String() string { - return "Screen" -} - -// Halt implements conn.Resource. -// -// It clears the display so it is not corrupted. -func (d *Dev) Halt() error { - _, err := d.w.Write([]byte("\n\033[0m")) - if err != nil { - return err - } - return nil -} - -// Write accepts a stream of raw RGB pixels and writes it to the console. -func (d *Dev) Write(pixels []byte) (int, error) { - if len(pixels)%3 != 0 { - return 0, errors.New("invalid RGB stream length") - } - copy(d.pixels, pixels) - return d.refresh() -} - -// ColorModel implements display.Drawer. -func (d *Dev) ColorModel() color.Model { - return color.NRGBAModel -} - -// Bounds implements display.Drawer. -func (d *Dev) Bounds() image.Rectangle { - return image.Rectangle{Max: image.Point{X: d.l, Y: 1}} -} - -// Draw implements display.Drawer. -func (d *Dev) Draw(r image.Rectangle, src image.Image, sp image.Point) error { - r = r.Intersect(d.Bounds()) - srcR := src.Bounds() - srcR.Min = srcR.Min.Add(sp) - if dX := r.Dx(); dX < srcR.Dx() { - srcR.Max.X = srcR.Min.X + dX - } - if dY := r.Dy(); dY < srcR.Dy() { - srcR.Max.Y = srcR.Min.Y + dY - } - // TODO(maruel): Allow non-full screen drawing. - // Generic version. - deltaX3 := 3 * (r.Min.X - srcR.Min.X) - for sX := srcR.Min.X; sX < srcR.Max.X; sX++ { - r16, g16, b16, _ := src.At(sX, srcR.Min.Y).RGBA() - dX3 := 3*sX + deltaX3 - d.pixels[dX3] = byte(r16 >> 8) - d.pixels[dX3+1] = byte(g16 >> 8) - d.pixels[dX3+2] = byte(b16 >> 8) - } - _, err := d.refresh() - return err -} - -func (d *Dev) refresh() (int, error) { - // This code is designed to minimize the amount of memory allocated per call. - d.buf.Reset() - _, _ = d.buf.WriteString("\r\033[0m") - for i := 0; i < len(d.pixels)/3; i++ { - _, _ = io.WriteString(&d.buf, ansi256.Default.Block(color.NRGBA{d.pixels[3*i], d.pixels[3*i+1], d.pixels[3*i+2], 255})) - } - _, _ = d.buf.WriteString("\033[0m ") - _, err := d.buf.WriteTo(d.w) - return len(d.pixels), err -} - -var _ display.Drawer = &Dev{} -var _ fmt.Stringer = &Dev{} diff --git a/experimental/README.md b/experimental/README.md deleted file mode 100644 index d8c60d7..0000000 --- a/experimental/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# experimental code - -This directory contains drivers that are considered unstable or incomplete as -per [driver lifetime -management](https://periph.io/project/#driver-lifetime-management). We -encourage you to try them and give feedback via new issues or improvements via a -pull request, so we can assert of their quality before promoting them as stable -drivers. - -You are welcome to create pull requests to add drivers here or improve the -quality of drivers already here. Please make sure to abide to requests in -[project/contributing/](https://periph.io/project/contributing/). - -To add a new driver, you can optionally start your work off -[driverskeleton/](driverskeleton/) and follow the instructions in the files. - -Unlike code in periph, code in extra is allowed to use `cgo`. diff --git a/experimental/cmd/README.md b/experimental/cmd/README.md deleted file mode 100644 index 750d31b..0000000 --- a/experimental/cmd/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# experimental/cmd - -You are welcome to send PR (pull request) to add experimental executables here. -Please follow the instructions in -[project/contributing/](https://periph.io/project/contributing/). - -Unlike code in periph, code in extra is allowed to use `cgo`. diff --git a/experimental/cmd/lsusb/main.go b/experimental/cmd/lsusb/main.go deleted file mode 100644 index 597a0df..0000000 --- a/experimental/cmd/lsusb/main.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build !cgo,!windows - -// lsusb prints out information about the USB devices. -package main - -import ( - "fmt" - "os" - - "periph.io/x/extra/experimental/hostextra/usbbus" - "periph.io/x/periph/host" -) - -func mainImpl() error { - if _, err := host.Init(); err != nil { - return err - } - - fmt.Printf("Addr ID\n") - for _, d := range usbbus.All() { - fmt.Printf("%02x:%02x %s\n", d.Bus, d.Addr, d.ID) - } - return nil -} - -func main() { - if err := mainImpl(); err != nil { - fmt.Fprintf(os.Stderr, "lsusb: %s.\n", err) - os.Exit(1) - } -} diff --git a/experimental/conn/README.md b/experimental/conn/README.md deleted file mode 100644 index 5f64438..0000000 --- a/experimental/conn/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# experimental/conn - -You are welcome to send PR (pull request) to add experimental protocols and -connections here. Please follow the instructions in -[project/contributing/](https://periph.io/project/contributing/). - -Unlike code in periph, code in extra is allowed to use `cgo`. diff --git a/experimental/conn/usb/usb.go b/experimental/conn/usb/usb.go deleted file mode 100644 index 8d6b637..0000000 --- a/experimental/conn/usb/usb.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Package usb implements an USB device registry. -package usb - -import ( - "fmt" - "io" - "sync" - - "periph.io/x/periph/conn" -) - -// Conn represents a connection to an USB device. -type Conn interface { - conn.Conn - ID() *ID -} - -// ConnCloser is an USB device handle that can be closed. -// -// This interface is meant to be handled by the USB device driver, not the -// application. -type ConnCloser interface { - io.Closer - Conn -} - -// ID represents an USB device by its ID. -type ID struct { - VenID uint16 - DevID uint16 -} - -func (i ID) String() string { - return fmt.Sprintf("%04x:%04x", i.VenID, i.DevID) -} - -// Opener takes control of an already opened USB device. -// -// TODO(maruel): Should accept a Conn. -type Opener func(dev ConnCloser) error - -// Register registers a driver for an USB device. -// -// When this device is found, the factory will be called with a device handle. -func Register(id ID, opener Opener) error { - mu.Lock() - defer mu.Unlock() - if _, ok := byID[id]; ok { - return fmt.Errorf("usb: registering the same USB device id %s twice", id) - } - - byID[id] = opener - for _, c := range buses { - c <- Driver{id, opener} - } - return nil -} - -// Driver is a registered driver. -type Driver struct { - ID // TODO(maruel): Using only the ID as the selector is a bit naive. There's known conflicts. - Opener -} - -// RegisterBus is called by a bus that will send a notification everytime -// there's a new driver being registered. -func RegisterBus(c chan<- Driver) { - mu.Lock() - defer mu.Unlock() - buses = append(buses, c) - // First start by sending all the known drivers. - for id, opener := range byID { - c <- Driver{id, opener} - } -} - -// - -var ( - mu sync.Mutex - byID = map[ID]Opener{} // - buses []chan<- Driver // That's highly unlikely that the number of items is not exactly 1. -) diff --git a/experimental/devices/README.md b/experimental/devices/README.md deleted file mode 100644 index e11a4d7..0000000 --- a/experimental/devices/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# experimental/devices - -You are welcome to send PR (pull request) to add experimental device drivers -here. Please follow the instructions in -[project/contributing/](https://periph.io/project/contributing/). - -Unlike code in periph, code in extra is allowed to use `cgo`. diff --git a/experimental/hostextra/README.md b/experimental/hostextra/README.md deleted file mode 100644 index a8530bf..0000000 --- a/experimental/hostextra/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# experimental/hostextra - -You are welcome to send PR (pull request) to add experimental host drivers here. -Please follow the instructions in -[project/contributing/](https://periph.io/project/contributing/). - -Unlike code in [periph.io/x/periph/host](https://periph.io/x/periph/host), code -under `hostextra` is allowed to use `cgo` or depend on third party Go packages. diff --git a/experimental/hostextra/usbbus/doc.go b/experimental/hostextra/usbbus/doc.go deleted file mode 100644 index 4a5a83e..0000000 --- a/experimental/hostextra/usbbus/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Package usbbus never worked and is obsolete. -package usbbus diff --git a/experimental/hostextra/usbbus/usbbus.go b/experimental/hostextra/usbbus/usbbus.go deleted file mode 100644 index 16fb7c2..0000000 --- a/experimental/hostextra/usbbus/usbbus.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build !cgo,!windows - -package usbbus - -import ( - "log" - "sort" - "sync" - - "github.com/google/gousb" - "periph.io/x/extra/experimental/conn/usb" - "periph.io/x/periph" - "periph.io/x/periph/conn" -) - -// Desc represents the description of an USB device on an USB bus. -type Desc struct { - ID usb.ID - Bus int - Addr int -} - -// All returns all the USB devices detected. -func All() []Desc { - mu.Lock() - defer mu.Unlock() - // TODO(maruel): driver.Init() should skip scanning the USB bus unless - // there's at least one USB driver registered. So in this case an USB scan - // should be done synchronously. - out := make([]Desc, len(all)) - copy(out, all) - return out -} - -// - -var ( - newDriver = make(chan usb.Driver) - - mu sync.Mutex - all descriptors - drivers = map[usb.ID]usb.Opener{} -) - -type descriptors []Desc - -func (d descriptors) Len() int { return len(d) } -func (d descriptors) Swap(i, j int) { d[i], d[j] = d[j], d[i] } -func (d descriptors) Less(i, j int) bool { - if d[i].Bus < d[j].Bus { - return true - } - if d[i].Bus > d[j].Bus { - return false - } - return d[i].Addr < d[j].Addr -} - -func fromDesc(d *gousb.DeviceDesc) Desc { - return Desc{usb.ID{uint16(d.Vendor), uint16(d.Product)}, d.Bus, d.Address} -} - -// Options: -// - https://github.com/kylelemons/gousb (which was forked multiple times) -// - https://github.com/truveris/gousb -// - https://github.com/gotmc/libusb -// The only one which does not require libusb but only works on linux: -// - https://github.com/swetland/go-usb/tree/master/src/usb - -// dev is an open handle to an USB device. -// -// The device can disappear at any moment. -type dev struct { - desc Desc - name string - d *gousb.Device - - done func() - i *gousb.Interface - in *gousb.InEndpoint - out *gousb.OutEndpoint -} - -func (d *dev) String() string { - return d.name -} - -func (d *dev) Close() error { - d.done() - return d.d.Close() -} - -func (d *dev) ID() *usb.ID { - return &d.desc.ID -} - -func (d *dev) Duplex() conn.Duplex { - return conn.Full -} - -func (d *dev) Read(b []byte) (int, error) { - return d.in.Read(b) -} - -func (d *dev) Write(b []byte) (int, error) { - return d.out.Write(b) -} - -func (d *dev) Tx(w, r []byte) error { - if _, err := d.Write(w); err != nil { - return err - } - if len(r) == 0 { - return nil - } - _, err := d.Read(r) - return err -} - -// driver implements periph.Driver. -type driver struct { -} - -func (d *driver) String() string { - return "usb" -} - -func (d *driver) Prerequisites() []string { - return nil -} - -func onNewDriver() { - for d := range newDriver { - mu.Lock() - // The items are guaranteed to not have duplicates. - drivers[d.ID] = d.Opener - for _, devices := range all { - if d.ID == devices.ID { - // Only rescan if the device had been detectd. - scanDevices(map[usb.ID]usb.Opener{d.ID: d.Opener}) - break - } - } - mu.Unlock() - } -} - -func (d *driver) Init() (bool, error) { - // Gather all the previously registered device drivers and do one scan - // synchronously. - // - // Start one loop that will be called during the function call. - var wg sync.WaitGroup - wg.Add(1) - quit := make(chan struct{}) - go func() { - mu.Lock() - defer mu.Unlock() - wg.Done() - for { - select { - case d := <-newDriver: - // The items are guaranteed to not have duplicates. - drivers[d.ID] = d.Opener - case <-quit: - return - } - } - }() - wg.Wait() - usb.RegisterBus(newDriver) - quit <- struct{}{} - - mu.Lock() - defer mu.Unlock() - scanDevices(drivers) - - // After this initial scan, scan asynchronously when drivers are registered. - go onNewDriver() - - // TODO(maruel): Start an event loop when new devices are plugged in without - // polling. - // go func() { for { WaitForUSBBusEvents(); usb.OnDevice(...) } }() - return true, nil -} - -// Getting go error: -// could not determine kind of name for C.LIBUSB_TRANSFER_TYPE_BULK_STREAM -/* -func option1() error { - ctx, err := libusb.Init() - if err != nil { - return err - } - defer ctx.Close() - devs, err := ctx.GetDeviceList() - if err != nil { - // TODO(maruel): This shouldn't be handled this way. Failures happen all - // the time on USB, this doesn't mean the driver is faulty. - return err - } - for _, dev := range devs { - desc, err := dev.GetDeviceDescriptor() - if err != nil { - continue - } - if usb.OnDevice(d.VendorID, d.ProductID, nil) { - h, err := dev.Open() - if err != nil { - continue - } - //usb.OnDevice(d.VendorID, d.ProductID, &dev{}) - h.Close() - } - } - return err -} -*/ - -func scanDevices(m map[usb.ID]usb.Opener) error { - // I'd much prefer something that just talks to the OS instead of using - // libusb. Especially we only require a small API surface. - ctx := gousb.NewContext() - defer ctx.Close() - all = nil - devs, err := ctx.OpenDevices(func(d *gousb.DeviceDesc) bool { - // Return true to keep the device open. - desc := fromDesc(d) - all = append(all, desc) - _, ok := m[desc.ID] - return ok - }) - // This API is really poor as there can be multiple devices opened and you - // don't know how many failed. - // If the user needs root access, LIBUSB_ERROR_ACCESS (-3) will be returned. - sort.Sort(all) - for _, d := range devs { - desc := fromDesc(d.Desc) - name, err := d.GetStringDescriptor(1) - if err != nil { - // Sometimes the USB device will return junk, default to the vendor and - // device ids. - name = desc.ID.String() - } - // Control, isochronous or bulk? - i, done, err := d.DefaultInterface() - if err != nil { - log.Printf("Open: %v", err) - d.Close() - continue - } - in, err := i.InEndpoint(0) - if err != nil { - log.Printf("InEndpoint: %v", err) - d.Close() - continue - } - out, err := i.OutEndpoint(0) - if err != nil { - log.Printf("OutEndpoint: %v", err) - d.Close() - continue - } - - if err := m[desc.ID](&dev{desc: desc, name: name, d: d, done: done, i: i, in: in, out: out}); err != nil { - log.Printf("opener: %v", err) - d.Close() - continue - } - } - return err -} - -func init() { - periph.MustRegister(&driver{}) -} - -var _ periph.Driver = &driver{} -var _ usb.ConnCloser = &dev{} diff --git a/experimental/hostextra/usbbus/usbbus_test.go b/experimental/hostextra/usbbus/usbbus_test.go deleted file mode 100644 index 304f331..0000000 --- a/experimental/hostextra/usbbus/usbbus_test.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build !cgo,!windows - -package usbbus - -import ( - "fmt" - "log" - "testing" - - "periph.io/x/extra/experimental/conn/usb" - "periph.io/x/periph/host" -) - -func Example() { - usb.Register(usb.ID{0x1234, 0x5678}, func(dev usb.ConnCloser) error { - fmt.Printf("Detected USB device: %s\n", dev) - return dev.Close() - }) - - if _, err := host.Init(); err != nil { - log.Fatal(err) - } - - // TODO(maruel): Check if the device is there. -} - -func TestUSBBus(t *testing.T) { -} diff --git a/experimental/hostextra/winthermal/winthermal.go b/experimental/hostextra/winthermal/winthermal.go deleted file mode 100644 index 28391e5..0000000 --- a/experimental/hostextra/winthermal/winthermal.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Package winthermal reads the temperature sensors via WMI on Windows. -// -// This is an incomplete work-in-progress. -package winthermal - -import ( - "errors" - "time" - - "periph.io/x/periph" - "periph.io/x/periph/conn/physic" -) - -// Dev represents an handle to a WMI based sensor. -// -// Dev implements physic.SenseEnv. -type Dev struct { - h obj -} - -// String implements conn.Resource. -func (d *Dev) String() string { - return d.h.InstanceName -} - -// Halt implements conn.Resource. -func (d *Dev) Halt() error { - return nil -} - -// Sense implements physic.SenseEnv. -func (d *Dev) Sense(env *physic.Env) error { - env.Temperature = physic.Temperature(d.h.CurrentTemperature)*100*physic.MilliCelsius + physic.ZeroCelsius - return nil -} - -func (d *Dev) SenseContinuous(interval time.Duration) (<-chan physic.Env, error) { - return nil, errors.New("winthermal: not implemented yet") -} - -func (d *Dev) Precision(e *physic.Env) { -} - -// - -// obj represents a MSAcpi_ThermalZoneTemperature instance. It intentionally -// leaves a lot of members out. -type obj struct { - CurrentTemperature uint32 - InstanceName string - SamplingPeriod int -} - -type driver struct { -} - -func (d *driver) String() string { - return "winthermal" -} - -func (d *driver) After() []string { - return nil -} - -func (d *driver) Prerequisites() []string { - return nil -} - -func (d *driver) Init() (bool, error) { - return true, initWindows() -} - -var _ periph.Driver = &driver{} -var _ physic.SenseEnv = &Dev{} diff --git a/experimental/hostextra/winthermal/winthermal_others.go b/experimental/hostextra/winthermal/winthermal_others.go deleted file mode 100644 index f23b946..0000000 --- a/experimental/hostextra/winthermal/winthermal_others.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build !windows - -package winthermal - -import "errors" - -func initWindows() error { - return errors.New("not implemented") -} diff --git a/experimental/hostextra/winthermal/winthermal_windows.go b/experimental/hostextra/winthermal/winthermal_windows.go deleted file mode 100644 index 23b1d63..0000000 --- a/experimental/hostextra/winthermal/winthermal_windows.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -package winthermal - -import ( - "github.com/StackExchange/wmi" - "periph.io/x/periph" -) - -func initWindows() error { - // https://msdn.microsoft.com/en-us/library/aa394493.aspx - var obj interface{} - if err := wmi.Query("SELECT * FROM Win32_TemperatureProbe", &obj); err != nil { - return err - } - return nil -} - -func init() { - periph.MustRegister(&driver{}) -} diff --git a/go.mod b/go.mod index ff3b9ac..796d719 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,3 @@ module periph.io/x/extra go 1.11 - -require ( - github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d - github.com/go-ole/go-ole v1.2.4 // indirect - github.com/google/gousb v0.0.0-20190525092738-2dc560e6bea3 - github.com/maruel/ansi256 v1.0.0 - github.com/mattn/go-colorable v0.1.2 - periph.io/x/periph v3.6.2+incompatible -) diff --git a/go.sum b/go.sum index b888aef..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +0,0 @@ -github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= -github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= -github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= -github.com/google/gousb v0.0.0-20190525092738-2dc560e6bea3 h1:3RtjTHQgWbD7dsPreVSkA5/LGfNnAZyjOtDXhargyEE= -github.com/google/gousb v0.0.0-20190525092738-2dc560e6bea3/go.mod h1:Tl4HdAs1ThE3gECkNwz+1MWicX6FXddhJEw7L8jRDiI= -github.com/maruel/ansi256 v1.0.0 h1:HEUR2vV+gi/Uat8dE+rZ7r+7GZaOkyHD898leivLEeE= -github.com/maruel/ansi256 v1.0.0/go.mod h1:TRJwQ7LqnqgZq0zP9lRNEO9hlwgPbUy5JY6dc0d442k= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -periph.io/x/periph v3.6.2+incompatible h1:B9vqhYVuhKtr6bXua8N9GeBEvD7yanczCvE0wU2LEqw= -periph.io/x/periph v3.6.2+incompatible/go.mod h1:EWr+FCIU2dBWz5/wSWeiIUJTriYv9v2j2ENBmgYyy7Y= diff --git a/hostextra/README.md b/hostextra/README.md deleted file mode 100644 index 1588f99..0000000 --- a/hostextra/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# hostextra - -This directory contains host drivers that are considered stable and complete as -per [driver lifetime -management](https://periph.io/project/#driver-lifetime-management). - -You are welcome to create pull requests to add drivers here or improve the -quality of drivers already here. Please make sure to abide to requests in -[project/contributing/](https://periph.io/project/contributing/). - -Unlike code in [periph.io/x/periph/host](https://periph.io/x/periph/host), code -under `hostextra` is allowed to use `cgo` or depend on third party Go packages. diff --git a/hostextra/d2xx/README.md b/hostextra/d2xx/README.md deleted file mode 100644 index 8efa3f6..0000000 --- a/hostextra/d2xx/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# d2xx - -Go driver wrapper for the [Future Technology "D2XX" driver]( -http://www.ftdichip.com/Drivers/D2XX.htm). - -See https://periph.io/device/ftdi/ for more details, and how to configure -the host to be able to use this driver. - - -## Included driver license - -- ftd2xx.h is v2.12.28 -- WinTypes.h is v1.4.6 -- darwin_amd64/libftd2xx.a v1.4.4 -- linux_arm/libftd2xx.a v1.4.6 with ARMv6 hard float (RPi compatible) -- linux_amd64/libftd2xx.a v1.4.6 - -> This software is provided by Future Technology Devices International Limited -> ``as is'' and any express or implied warranties, including, but not limited -> to, the implied warranties of merchantability and fitness for a particular -> purpose are disclaimed. In no event shall future technology devices -> international limited be liable for any direct, indirect, incidental, special, -> exemplary, or consequential damages (including, but not limited to, -> procurement of substitute goods or services; loss of use, data, or profits; or -> business interruption) however caused and on any theory of liability, whether -> in contract, strict liability, or tort (including negligence or otherwise) -> arising in any way out of the use of this software, even if advised of the -> possibility of such damage. FTDI drivers may be used only in conjunction with -> products based on FTDI parts. -> -> FTDI drivers may be distributed in any form as long as license information is -> not modified. -> -> If a custom vendor ID and/or product ID or description string are used, it is -> the responsibility of the product manufacturer to maintain any changes and -> subsequent WHCK re-certification as a result of making these changes. -> -> For more detail on FTDI Chip Driver licence terms, please [click -> here](http://www.ftdichip.com/Drivers/FTDriverLicenceTermsSummary.htm). - - -### Modifications - -- Fixed ftd2xx.h to UTF-8 -- Converted header files from CRLF to LF -- Removed trailing spaces and tabs diff --git a/hostextra/d2xx/WinTypes.h b/hostextra/d2xx/WinTypes.h deleted file mode 100644 index 7b0c9ed..0000000 --- a/hostextra/d2xx/WinTypes.h +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef __WINDOWS_TYPES__ -#define __WINDOWS_TYPES__ - -#define WINAPI - -typedef unsigned int DWORD; -typedef unsigned int ULONG; -typedef unsigned short USHORT; -typedef unsigned short SHORT; -typedef unsigned char UCHAR; -typedef unsigned short WORD; -typedef unsigned short WCHAR; -typedef unsigned char BYTE; -typedef BYTE *LPBYTE; -typedef unsigned int BOOL; -typedef unsigned char BOOLEAN; -typedef unsigned char CHAR; -typedef BOOL *LPBOOL; -typedef UCHAR *PUCHAR; -typedef const char *LPCSTR; -typedef char *PCHAR; -typedef void *PVOID; -typedef void *HANDLE; -typedef unsigned int LONG; -typedef int INT; -typedef unsigned int UINT; -typedef char *LPSTR; -typedef char *LPTSTR; -typedef const char *LPCTSTR; -typedef DWORD *LPDWORD; -typedef WORD *LPWORD; -typedef ULONG *PULONG; -typedef LONG *LPLONG; -typedef PVOID LPVOID; -typedef void VOID; -typedef USHORT *PUSHORT; -typedef unsigned long long int ULONGLONG; - -typedef struct _OVERLAPPED { - DWORD Internal; - DWORD InternalHigh; - union { - struct{ - DWORD Offset; - DWORD OffsetHigh; - }; - PVOID Pointer; - }; - HANDLE hEvent; -} OVERLAPPED, *LPOVERLAPPED; - -typedef struct _SECURITY_ATTRIBUTES { - DWORD nLength; - LPVOID lpSecurityDescriptor; - BOOL bInheritHandle; -} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES; - -#include -// Substitute for HANDLE returned by Windows CreateEvent API. -// FT_SetEventNotification expects parameter 3 to be the address -// of one of these structures. -typedef struct _EVENT_HANDLE -{ - pthread_cond_t eCondVar; - pthread_mutex_t eMutex; - int iVar; -} EVENT_HANDLE; - -typedef struct timeval SYSTEMTIME; -typedef struct timeval FILETIME; - -// WaitForSingleObject return values. -#define WAIT_ABANDONED 0x00000080L -#define WAIT_OBJECT_0 0x00000000L -#define WAIT_TIMEOUT 0x00000102L -#define WAIT_FAILED 0xFFFFFFFF -// Special value for WaitForSingleObject dwMilliseconds parameter -#define INFINITE 0xFFFFFFFF // Infinite timeout - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef CONST -#define CONST const -#endif -// -// Modem Status Flags -// -#define MS_CTS_ON ((DWORD)0x0010) -#define MS_DSR_ON ((DWORD)0x0020) -#define MS_RING_ON ((DWORD)0x0040) -#define MS_RLSD_ON ((DWORD)0x0080) - -// -// Error Flags -// -#define CE_RXOVER 0x0001 // Receive Queue overflow -#define CE_OVERRUN 0x0002 // Receive Overrun Error -#define CE_RXPARITY 0x0004 // Receive Parity Error -#define CE_FRAME 0x0008 // Receive Framing error -#define CE_BREAK 0x0010 // Break Detected -#define CE_TXFULL 0x0100 // TX Queue is full -#define CE_PTO 0x0200 // LPTx Timeout -#define CE_IOE 0x0400 // LPTx I/O Error -#define CE_DNS 0x0800 // LPTx Device not selected -#define CE_OOP 0x1000 // LPTx Out-Of-Paper -#define CE_MODE 0x8000 // Requested mode unsupported - -// -// Events -// -#define EV_RXCHAR 0x0001 // Any Character received -#define EV_RXFLAG 0x0002 // Received certain character -#define EV_TXEMPTY 0x0004 // Transmit Queue Empty -#define EV_CTS 0x0008 // CTS changed state -#define EV_DSR 0x0010 // DSR changed state -#define EV_RLSD 0x0020 // RLSD changed state -#define EV_BREAK 0x0040 // BREAK received -#define EV_ERR 0x0080 // Line status error occurred -#define EV_RING 0x0100 // Ring signal detected -#define EV_PERR 0x0200 // Printer error occurred -#define EV_RX80FULL 0x0400 // Receive buffer is 80 percent full -#define EV_EVENT1 0x0800 // Provider specific event 1 -#define EV_EVENT2 0x1000 // Provider specific event 2 - -// -// Escape Functions -// -#define SETXOFF 1 // Simulate XOFF received -#define SETXON 2 // Simulate XON received -#define SETRTS 3 // Set RTS high -#define CLRRTS 4 // Set RTS low -#define SETDTR 5 // Set DTR high -#define CLRDTR 6 // Set DTR low -#define RESETDEV 7 // Reset device if possible -#define SETBREAK 8 // Set the device break line. -#define CLRBREAK 9 // Clear the device break line. - -// -// PURGE function flags. -// -#define PURGE_TXABORT 0x0001 // Kill the pending/current writes to the comm port. -#define PURGE_RXABORT 0x0002 // Kill the pending/current reads to the comm port. -#define PURGE_TXCLEAR 0x0004 // Kill the transmit queue if there. -#define PURGE_RXCLEAR 0x0008 // Kill the typeahead buffer if there. - -#ifndef INVALID_HANDLE_VALUE -#define INVALID_HANDLE_VALUE 0xFFFFFFFF -#endif - -#endif /* __WINDOWS_TYPES__ */ diff --git a/hostextra/d2xx/cbus.go b/hostextra/d2xx/cbus.go deleted file mode 100644 index 2f92e9a..0000000 --- a/hostextra/d2xx/cbus.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Cbus bitbang -// -// http://www.ftdichip.com/Support/Knowledgebase/index.html?cbusbitbangmode.htm -// -// FTDI device input output pin states: -// http://www.ftdichip.com/Support/Documents/AppNotes/AN_184%20FTDI%20Device%20Input%20Output%20Pin%20States.pdf - -package d2xx diff --git a/hostextra/d2xx/d2xx.go b/hostextra/d2xx/d2xx.go deleted file mode 100644 index 4768804..0000000 --- a/hostextra/d2xx/d2xx.go +++ /dev/null @@ -1,624 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// This file is the abstraction layer against the various OS specific -// implementations. -// -// It converts the int error value into error type. -// -// D2XX programmer's guide; Explains how to use the DLL provided by ftdi. -// http://www.ftdichip.com/Support/Documents/ProgramGuides/D2XX_Programmer%27s_Guide(FT_000071).pdf -// -// D2XX samples; http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples/VC.htm -// -// There is multiple ways to access a FT232H: -// -// - Some operating systems include a limited "serial port only" driver. -// - Future Technologic Devices International Ltd provides their own private -// source driver. -// - FTDI also provides a "serial port only" driver surnamed VCP. -// - https://www.intra2net.com/en/developer/libftdi/ is an open source driver, -// that is acknowledged by FTDI. - -package d2xx - -import ( - "errors" - "fmt" - "io" - "log" - "strconv" - "time" - - "periph.io/x/extra/hostextra/d2xx/ftdi" -) - -// Version returns the version number of the D2xx driver currently used. -func Version() (uint8, uint8, uint8) { - return d2xxGetLibraryVersion() -} - -// - -func numDevices() (int, error) { - num, e := d2xxCreateDeviceInfoList() - if e != 0 { - return 0, toErr("GetNumDevices initialization failed", e) - } - return num, nil -} - -// - -func openDev(opener func(i int) (d2xxHandle, int), i int) (*device, error) { - h, e := opener(i) - d := &device{h: h} - if e != 0 { - return d, toErr("Open", e) - } - if d.t, d.venID, d.devID, e = h.d2xxGetDeviceInfo(); e != 0 { - return d, toErr("GetDeviceInfo", e) - } - return d, nil -} - -// device is the lower level d2xx device handle, just above 'handle' which -// directly maps to D2XX function calls. -// -// device converts the int error type into Go native error and handles higher -// level functionality like reading and writing to the USB connection. -// -// The content of the struct is immutable after initialization. -type device struct { - h d2xxHandle - t ftdi.DevType - venID uint16 - devID uint16 -} - -func (d *device) closeDev() error { - // Not yet called. - return toErr("Close", d.h.d2xxClose()) -} - -// setupCommon is the general setup for common devices. -// -// It tries first the 'happy path' which doesn't reset the device. By doing so, -// the goal is to reduce the amount of glitches on the GPIO pins, on a best -// effort basis. On all devices, the GPIOs are still reset as inputs, since -// there is no way to determine if each GPIO is an input or output. -func (d *device) setupCommon() error { - // Driver: maximum packet size. Note that this clears any data in the buffer, - // so it is good to do it immediately after a reset. The 'out' parameter is - // ignored. - // TODO(maruel): The FT232H doc claims a 512 byte packets support in hi-speed - // mode, which means that this would likely be better to use this value. - if e := d.h.d2xxSetUSBParameters(65536, 0); e != 0 { - return toErr("SetUSBParameters", e) - } - // Driver: Set I/O timeouts to 15 sec. The reason is that we want the - // timeouts to be very visible, at least as the driver is being developed. - if e := d.h.d2xxSetTimeouts(15000, 15000); e != 0 { - return toErr("SetTimeouts", e) - } - // Not sure: Disable event/error characters. - if e := d.h.d2xxSetChars(0, false, 0, false); e != 0 { - return toErr("SetChars", e) - } - // Not sure: Latency timer at 1ms. - if e := d.h.d2xxSetLatencyTimer(1); e != 0 { - return toErr("SetLatencyTimer", e) - } - // Not sure: Turn on flow control to synchronize IN requests. - if e := d.h.d2xxSetFlowControl(); e != 0 { - return toErr("SetFlowControl", e) - } - // Just in case. It's a very small cost. - return d.flushPending() -} - -// reset resets the device. -func (d *device) reset() error { - if e := d.h.d2xxResetDevice(); e != 0 { - return toErr("Reset", e) - } - if err := d.setBitMode(0, bitModeReset); err != nil { - return err - } - // USB/driver: Flush any pending read buffer that had been sent by device - // before it reset. Do not return any error there, as the device may spew a - // read error right after being initialized. - _ = d.flushPending() - return nil -} - -func (d *device) getBitMode() (byte, error) { - l, e := d.h.d2xxGetBitMode() - if e != 0 { - return 0, toErr("GetBitMode", e) - } - return l, nil -} - -// setBitMode change the mode of operation of the device. -// -// mask sets which pins are inputs and outputs for bitModeCbusBitbang. -func (d *device) setBitMode(mask byte, mode bitMode) error { - return toErr("SetBitMode", d.h.d2xxSetBitMode(mask, byte(mode))) -} - -// flushPending flushes any data left in the read buffer. -func (d *device) flushPending() error { - var buf [128]byte - for { - p, err := d.read(buf[:]) - if err != nil { - return err - } - if p == 0 { - return nil - } - } -} - -// read returns as much as available in the read buffer without blocking. -func (d *device) read(b []byte) (int, error) { - // d2xxGetQueueStatus() 60µs is relatively slow compared to d2xxRead() 4µs, - // but surprisingly if d2xxGetQueueStatus() is *not* called, d2xxRead() - // becomes largely slower (800µs). - // - // TODO(maruel): This asks for more perf testing before settling on the best - // solution. - // TODO(maruel): Investigate FT_GetStatus(). - p, e := d.h.d2xxGetQueueStatus() - if p == 0 || e != 0 { - return int(p), toErr("Read/GetQueueStatus", e) - } - v := int(p) - if v > len(b) { - v = len(b) - } - n, e := d.h.d2xxRead(b[:v]) - return n, toErr("Read", e) -} - -// readAll blocks to return all the data. -func (d *device) readAll(b []byte) error { - // TODO(maruel): Use FT_SetEventNotification() instead of looping when - // waiting for bytes. - last := time.Now() - for offset := 0; offset != len(b); { - chunk := len(b) - offset - if chunk > 4096 { - chunk = 4096 - } - p, err := d.read(b[offset : offset+chunk]) - if err != nil { - return err - } - if p != 0 { - offset += p - last = time.Now() - } else if time.Since(last) > 200*time.Millisecond { - return io.EOF - } - } - return nil -} - -// write writes to the USB device. -// -// In practice this takes at least 0.1ms, which limits the effective rate. -func (d *device) write(b []byte) (int, error) { - // Use a stronger guarantee that all bytes have been written. - n, e := d.h.d2xxWrite(b) - return n, toErr("Write", e) -} - -// writeAll blocks until all data is written. -func (d *device) writeAll(b []byte) error { - for offset := 0; offset != len(b); { - chunk := len(b) - offset - if chunk > 4096 { - chunk = 4096 - } - p, err := d.write(b[offset : offset+chunk]) - if err != nil { - return err - } - if p != 0 { - offset += p - } - } - return nil -} - -func (d *device) readEEPROM(ee *ftdi.EEPROM) error { - if e := d.h.d2xxEEPROMRead(d.t, ee); e != 0 { - // 15 == FT_EEPROM_NOT_PROGRAMMED - if e != 15 { - return toErr("EEPROMRead", e) - } - // It's a fresh new device. Devices bought via Adafruit already have - // their EEPROM programmed with Adafruit branding but devices sold by - // CJMCU are not. Since d2xxGetDeviceInfo() above succeeded, we know the - // device type via the USB descriptor, which is sufficient to load the - // driver, which permits to program the EEPROM to "bootstrap" it. - // - // Fill it with an empty yet valid EEPROM content. We don't want to set - // VenID or DevID to 0! Nobody would do that, right? - ee.Raw = make([]byte, d.t.EEPROMSize()) - hdr := ee.AsHeader() - hdr.DeviceType = d.t - hdr.VendorID = d.venID - hdr.ProductID = d.devID - } - return nil -} - -func (d *device) programEEPROM(ee *ftdi.EEPROM) error { - // Verify that the values are set correctly. - if len(ee.Manufacturer) > 40 { - return errors.New("d2xx: Manufacturer is too long") - } - if len(ee.ManufacturerID) > 40 { - return errors.New("d2xx: ManufacturerID is too long") - } - if len(ee.Desc) > 40 { - return errors.New("d2xx: Desc is too long") - } - if len(ee.Serial) > 40 { - return errors.New("d2xx: Serial is too long") - } - if len(ee.Manufacturer)+len(ee.Desc) > 40 { - return errors.New("d2xx: length of Manufacturer plus Desc is too long") - } - if len(ee.Raw) != 0 { - hdr := ee.AsHeader() - if hdr == nil { - return errors.New("d2xx: unexpected EEPROM header size") - } - if hdr.DeviceType != d.t { - return errors.New("d2xx: unexpected device type set while programming EEPROM") - } - if hdr.VendorID != d.venID { - return errors.New("d2xx: unexpected VenID set while programming EEPROM") - } - if hdr.ProductID != d.devID { - return errors.New("d2xx: unexpected DevID set while programming EEPROM") - } - } - return toErr("EEPROMWrite", d.h.d2xxEEPROMProgram(ee)) -} - -func (d *device) eraseEEPROM() error { - // Will fail on FT232R and FT245R. Not checking here, the driver will report - // an error. - return toErr("EraseEE", d.h.d2xxEraseEE()) -} - -func (d *device) readUA() ([]byte, error) { - size, e := d.h.d2xxEEUASize() - if e != 0 { - return nil, toErr("EEUASize", e) - } - if size == 0 { - // Happens on uninitialized EEPROM. - return nil, nil - } - b := make([]byte, size) - if e := d.h.d2xxEEUARead(b); e != 0 { - return nil, toErr("EEUARead", e) - } - return b, nil -} - -func (d *device) writeUA(ua []byte) error { - size, e := d.h.d2xxEEUASize() - if e != 0 { - return toErr("EEUASize", e) - } - if size == 0 { - return errors.New("d2xx: please program EEPROM first") - } - if size < len(ua) { - return fmt.Errorf("d2xx: maximum user area size is %d bytes", size) - } - if size != len(ua) { - b := make([]byte, size) - copy(b, ua) - ua = b - } - if e := d.h.d2xxEEUAWrite(ua); e != 0 { - return toErr("EEUAWrite", e) - } - return nil -} - -func (d *device) setBaudRate(hz int64) error { - if hz >= 1<<31 { - return errors.New("d2xx: baud rate too high") - } - return toErr("SetBaudRate", d.h.d2xxSetBaudRate(uint32(hz))) -} - -// - -const missing = -1 -const noCGO = -2 - -// bitMode is used by setBitMode to change the chip behavior. -type bitMode uint8 - -const ( - // Resets all Pins to their default value - bitModeReset bitMode = 0x00 - // Sets the DBus to asynchronous bit-bang. - bitModeAsyncBitbang bitMode = 0x01 - // Switch to MPSSE mode (FT2232, FT2232H, FT4232H and FT232H). - bitModeMpsse bitMode = 0x02 - // Sets the DBus to synchronous bit-bang (FT232R, FT245R, FT2232, FT2232H, - // FT4232H and FT232H). - bitModeSyncBitbang bitMode = 0x04 - // Switch to MCU host bus emulation (FT2232, FT2232H, FT4232H and FT232H). - bitModeMcuHost bitMode = 0x08 - // Switch to fast opto-isolated serial mode (FT2232, FT2232H, FT4232H and - // FT232H). - bitModeFastSerial bitMode = 0x10 - // Sets the CBus in 4 bits bit-bang mode (FT232R and FT232H) - // In this case, upper nibble controls which pin is output/input, lower - // controls which of outputs are high and low. - bitModeCbusBitbang bitMode = 0x20 - // Single Channel Synchronous 245 FIFO mode (FT2232H and FT232H). - bitModeSyncFifo bitMode = 0x40 -) - -func toErr(s string, e int) error { - msg := "" - switch e { - case missing: - // when the library d2xx couldn't be loaded at runtime. - msg = "couldn't load driver; visit https://periph.io/device/ftdi/ for help" - case noCGO: - msg = "can't be used without cgo" - case 0: // FT_OK - return nil - case 1: // FT_INVALID_HANDLE - msg = "invalid handle" - case 2: // FT_DEVICE_NOT_FOUND - msg = "device not found; see https://periph.io/device/ftdi/ for help" - case 3: // FT_DEVICE_NOT_OPENED - msg = "device busy; see https://periph.io/device/ftdi/ for help" - case 4: // FT_IO_ERROR - msg = "I/O error" - case 5: // FT_INSUFFICIENT_RESOURCES - msg = "insufficient resources" - case 6: // FT_INVALID_PARAMETER - msg = "invalid parameter" - case 7: // FT_INVALID_BAUD_RATE - msg = "invalid baud rate" - case 8: // FT_DEVICE_NOT_OPENED_FOR_ERASE - msg = "device not opened for erase" - case 9: // FT_DEVICE_NOT_OPENED_FOR_WRITE - msg = "device not opened for write" - case 10: // FT_FAILED_TO_WRITE_DEVICE - msg = "failed to write device" - case 11: // FT_EEPROM_READ_FAILED - msg = "eeprom read failed" - case 12: // FT_EEPROM_WRITE_FAILED - msg = "eeprom write failed" - case 13: // FT_EEPROM_ERASE_FAILED - msg = "eeprom erase failed" - case 14: // FT_EEPROM_NOT_PRESENT - msg = "eeprom not present" - case 15: // FT_EEPROM_NOT_PROGRAMMED - msg = "eeprom not programmed" - case 16: // FT_INVALID_ARGS - msg = "invalid argument" - case 17: // FT_NOT_SUPPORTED - msg = "not supported" - case 18: // FT_OTHER_ERROR - msg = "other error" - case 19: // FT_DEVICE_LIST_NOT_READY - msg = "device list not ready" - default: - msg = "unknown status " + strconv.Itoa(e) - } - return errors.New("d2xx: " + s + ": " + msg) -} - -// Common functions that must be implemented in addition to -// d2xxGetLibraryVersion(), d2xxCreateDeviceInfoList() and d2xxOpen(). -type d2xxHandle interface { - d2xxClose() int - // d2xxResetDevice takes >1.2ms - d2xxResetDevice() int - d2xxGetDeviceInfo() (ftdi.DevType, uint16, uint16, int) - d2xxEEPROMRead(d ftdi.DevType, e *ftdi.EEPROM) int - d2xxEEPROMProgram(e *ftdi.EEPROM) int - d2xxEraseEE() int - d2xxWriteEE(offset uint8, value uint16) int - d2xxEEUASize() (int, int) - d2xxEEUARead(ua []byte) int - d2xxEEUAWrite(ua []byte) int - d2xxSetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) int - d2xxSetUSBParameters(in, out int) int - d2xxSetFlowControl() int - d2xxSetTimeouts(readMS, writeMS int) int - d2xxSetLatencyTimer(delayMS uint8) int - d2xxSetBaudRate(hz uint32) int - // d2xxGetQueueStatus takes >60µs - d2xxGetQueueStatus() (uint32, int) - // d2xxRead takes <5µs if d2xxGetQueueStatus was called just before, - // 300µs~800µs otherwise (!) - d2xxRead(b []byte) (int, int) - // d2xxWrite takes >0.1ms - d2xxWrite(b []byte) (int, int) - d2xxGetBitMode() (byte, int) - // d2xxSetBitMode takes >0.1ms - d2xxSetBitMode(mask, mode byte) int -} - -// handle is a d2xx handle. -// -// This is the base type which each OS specific implementation adds methods to. -type handle uintptr - -// d2xxLoggingHandle adds logging to help diagnose issues with the d2xx driver. -type d2xxLoggingHandle struct { - d d2xxHandle -} - -// log10 is a cheap way to find the most significant digit -func log10(i int64) uint { - switch { - case i < 10: - return 0 - case i < 100: - return 1 - case i < 1000: - return 2 - case i < 10000: - return 3 - case i < 100000: - return 4 - case i < 1000000: - return 5 - case i < 10000000: - return 6 - case i < 100000000: - return 7 - case i < 1000000000: - return 8 - case i < 10000000000: - return 9 - case i < 100000000000: - return 10 - case i < 1000000000000: - return 11 - case i < 10000000000000: - return 12 - case i < 100000000000000: - return 13 - case i < 1000000000000000: - return 14 - case i < 10000000000000000: - return 15 - default: - return 16 - } -} - -func roundDuration(d time.Duration) time.Duration { - if l := log10(int64(d)); l > 3 { - m := time.Duration(1) - for i := uint(3); i < l; i++ { - m *= 10 - } - d = (d + (m / 2)) / m * m - } - return d -} - -func logDefer(fmt string) func(args ...interface{}) { - var start time.Time - f := func(args ...interface{}) { - log.Printf("%7s "+fmt, append([]interface{}{roundDuration(time.Since(start))}, args...)...) - } - start = time.Now() - return f -} - -func (d *d2xxLoggingHandle) d2xxClose() int { - defer logDefer("d2xxClose()")() - return d.d.d2xxClose() -} -func (d d2xxLoggingHandle) d2xxResetDevice() int { - defer logDefer("d2xxResetDevice()")() - return d.d.d2xxResetDevice() -} -func (d d2xxLoggingHandle) d2xxGetDeviceInfo() (ftdi.DevType, uint16, uint16, int) { - defer logDefer("d2xxGetDeviceInfo()")() - return d.d.d2xxGetDeviceInfo() -} -func (d d2xxLoggingHandle) d2xxEEPROMRead(dev ftdi.DevType, e *ftdi.EEPROM) int { - defer logDefer("d2xxEEPROMRead(%v, %d bytes)")(dev, e) - return d.d.d2xxEEPROMRead(dev, e) -} -func (d d2xxLoggingHandle) d2xxEEPROMProgram(e *ftdi.EEPROM) int { - defer logDefer("d2xxEEPROMProgram(%#x)")(e) - return d.d.d2xxEEPROMProgram(e) -} -func (d d2xxLoggingHandle) d2xxEraseEE() int { - defer logDefer("d2xxEraseEE()")() - return d.d.d2xxEraseEE() -} -func (d d2xxLoggingHandle) d2xxWriteEE(offset uint8, value uint16) int { - defer logDefer("d2xxWriteEE(%d, %d)")(offset, value) - return d.d.d2xxWriteEE(offset, value) -} -func (d d2xxLoggingHandle) d2xxEEUASize() (int, int) { - defer logDefer("d2xxEEUASize()")() - return d.d.d2xxEEUASize() -} -func (d d2xxLoggingHandle) d2xxEEUARead(ua []byte) int { - defer logDefer("d2xxEEUARead(%d bytes)")(len(ua)) - return d.d.d2xxEEUARead(ua) -} -func (d d2xxLoggingHandle) d2xxEEUAWrite(ua []byte) int { - defer logDefer("d2xxEEUAWrite(%#x)")(ua) - return d.d.d2xxEEUAWrite(ua) -} -func (d d2xxLoggingHandle) d2xxSetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) int { - defer logDefer("d2xxSetChars(%d, %t, %d, %t)")(eventChar, eventEn, errorChar, errorEn) - return d.d.d2xxSetChars(eventChar, eventEn, errorChar, errorEn) -} -func (d d2xxLoggingHandle) d2xxSetUSBParameters(in, out int) int { - defer logDefer("d2xxSetUSBParameters(%d, %d)")(in, out) - return d.d.d2xxSetUSBParameters(in, out) -} -func (d d2xxLoggingHandle) d2xxSetFlowControl() int { - defer logDefer("d2xxSetFlowControl()")() - return d.d.d2xxSetFlowControl() -} -func (d d2xxLoggingHandle) d2xxSetTimeouts(readMS, writeMS int) int { - defer logDefer("d2xxSetTimeouts(%d, %d)")(readMS, writeMS) - return d.d.d2xxSetTimeouts(readMS, writeMS) -} -func (d d2xxLoggingHandle) d2xxSetLatencyTimer(delayMS uint8) int { - defer logDefer("d2xxSetLatencyTimer(%d)")(delayMS) - return d.d.d2xxSetLatencyTimer(delayMS) -} -func (d d2xxLoggingHandle) d2xxSetBaudRate(hz uint32) int { - defer logDefer("d2xxSetBaudRate(%d)")(hz) - return d.d.d2xxSetBaudRate(hz) -} -func (d d2xxLoggingHandle) d2xxGetQueueStatus() (uint32, int) { - f := logDefer("d2xxGetQueueStatus() = %d, %d") - p, e := d.d.d2xxGetQueueStatus() - f(p, e) - return p, e -} -func (d d2xxLoggingHandle) d2xxRead(b []byte) (int, int) { - f := logDefer("d2xxRead(%d bytes) = %#x") - n, e := d.d.d2xxRead(b) - f(len(b), b[:n]) - return n, e -} -func (d d2xxLoggingHandle) d2xxWrite(b []byte) (int, int) { - defer logDefer("d2xxWrite(%#x)")(b) - return d.d.d2xxWrite(b) -} -func (d d2xxLoggingHandle) d2xxGetBitMode() (byte, int) { - f := logDefer("d2xxGetBitMode() = %02X") - b, e := d.d.d2xxGetBitMode() - f(b) - return b, e -} -func (d d2xxLoggingHandle) d2xxSetBitMode(mask, mode byte) int { - f := logDefer("d2xxSetBitMode(0x%02X, 0x%02X) = %d") - e := d.d.d2xxSetBitMode(mask, mode) - f(mask, mode, e) - return e -} diff --git a/hostextra/d2xx/d2xx_darwin_amd64.go b/hostextra/d2xx/d2xx_darwin_amd64.go deleted file mode 100644 index 6ee62f0..0000000 --- a/hostextra/d2xx/d2xx_darwin_amd64.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build cgo - -package d2xx - -/* -#cgo LDFLAGS: -framework CoreFoundation -framework IOKit ${SRCDIR}/darwin_amd64/libftd2xx.a -*/ -import "C" diff --git a/hostextra/d2xx/d2xx_linux_amd64.go b/hostextra/d2xx/d2xx_linux_amd64.go deleted file mode 100644 index 8b90643..0000000 --- a/hostextra/d2xx/d2xx_linux_amd64.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build cgo - -package d2xx - -/* -#cgo LDFLAGS: ${SRCDIR}/linux_amd64/libftd2xx.a -*/ -import "C" diff --git a/hostextra/d2xx/d2xx_linux_arm.go b/hostextra/d2xx/d2xx_linux_arm.go deleted file mode 100644 index 32b6d3e..0000000 --- a/hostextra/d2xx/d2xx_linux_arm.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build cgo - -package d2xx - -// TODO(maruel): https://github.com/golang/go/issues/7211 would help target the -// optimal ARM architecture. - -/* -#cgo LDFLAGS: ${SRCDIR}/linux_arm/libftd2xx.a -*/ -import "C" diff --git a/hostextra/d2xx/d2xx_posix.go b/hostextra/d2xx/d2xx_posix.go deleted file mode 100644 index 0ba65c6..0000000 --- a/hostextra/d2xx/d2xx_posix.go +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build !windows - -package d2xx - -/* -#include "ftd2xx.h" -#include -*/ -import "C" -import ( - "unsafe" - - "periph.io/x/extra/hostextra/d2xx/ftdi" -) - -const disabled = false - -// Library functions. - -func d2xxGetLibraryVersion() (uint8, uint8, uint8) { - var v C.DWORD - C.FT_GetLibraryVersion(&v) - return uint8(v >> 16), uint8(v >> 8), uint8(v) -} - -func d2xxCreateDeviceInfoList() (int, int) { - var num C.DWORD - e := C.FT_CreateDeviceInfoList(&num) - return int(num), int(e) -} - -// Device functions. - -func d2xxOpen(i int) (d2xxHandle, int) { - var h C.FT_HANDLE - e := C.FT_Open(C.int(i), &h) - if uintptr(h) == 0 && e == 0 { - panic("unexpected") - } - return handle(h), int(e) -} - -func (h handle) d2xxClose() int { - return int(C.FT_Close(h.toH())) -} - -func (h handle) d2xxResetDevice() int { - return int(C.FT_ResetDevice(h.toH())) -} - -func (h handle) d2xxGetDeviceInfo() (ftdi.DevType, uint16, uint16, int) { - var dev C.FT_DEVICE - var id C.DWORD - if e := C.FT_GetDeviceInfo(h.toH(), &dev, &id, nil, nil, nil); e != 0 { - return ftdi.Unknown, 0, 0, int(e) - } - return ftdi.DevType(dev), uint16(id >> 16), uint16(id), 0 -} - -func (h handle) d2xxEEPROMRead(t ftdi.DevType, ee *ftdi.EEPROM) int { - var manufacturer [64]C.char - var manufacturerID [64]C.char - var desc [64]C.char - var serial [64]C.char - if l := t.EEPROMSize(); len(ee.Raw) < l { - ee.Raw = make([]byte, l) - } else if len(ee.Raw) > l { - ee.Raw = ee.Raw[:l] - } - eepromVoid := unsafe.Pointer(&ee.Raw[0]) - hdr := ee.AsHeader() - - // There something odd going on here. - // - // On a ft232h, we observed that hdr.DeviceType MUST NOT be set, but on a - // ft232r, it MUST be set. Since we can't know in advance what we must use, - // just try both. ¯\_(ツ)_/¯ - hdr.DeviceType = t - if e := C.FT_EEPROM_Read(h.toH(), eepromVoid, C.DWORD(len(ee.Raw)), &manufacturer[0], &manufacturerID[0], &desc[0], &serial[0]); e != 0 { - // FT_INVALID_PARAMETER - if e == 6 { - hdr.DeviceType = 0 - e = C.FT_EEPROM_Read(h.toH(), eepromVoid, C.DWORD(len(ee.Raw)), &manufacturer[0], &manufacturerID[0], &desc[0], &serial[0]) - } - if e != 0 { - return int(e) - } - } - - ee.Manufacturer = C.GoString(&manufacturer[0]) - ee.ManufacturerID = C.GoString(&manufacturerID[0]) - ee.Desc = C.GoString(&desc[0]) - ee.Serial = C.GoString(&serial[0]) - return 0 -} - -func (h handle) d2xxEEPROMProgram(ee *ftdi.EEPROM) int { - // len(manufacturer) + len(desc) <= 40. - /* - var cmanu [64]byte - copy(cmanu[:], ee.manufacturer) - var cmanuID [64]byte - copy(cmanuID[:], ee.manufacturerID) - var cdesc [64]byte - copy(cdesc[:], ee.desc) - var cserial [64]byte - copy(cserial[:], ee.serial) - */ - cmanu := C.CString(ee.Manufacturer) - defer C.free(unsafe.Pointer(cmanu)) - cmanuID := C.CString(ee.ManufacturerID) - defer C.free(unsafe.Pointer(cmanuID)) - cdesc := C.CString(ee.Desc) - defer C.free(unsafe.Pointer(cdesc)) - cserial := C.CString(ee.Serial) - defer C.free(unsafe.Pointer(cserial)) - - if len(ee.Raw) == 0 { - return int(C.FT_EEPROM_Program(h.toH(), unsafe.Pointer(uintptr(0)), 0, cmanu, cmanuID, cdesc, cserial)) - } - return int(C.FT_EEPROM_Program(h.toH(), unsafe.Pointer(&ee.Raw[0]), C.DWORD(len(ee.Raw)), cmanu, cmanuID, cdesc, cserial)) -} - -func (h handle) d2xxEraseEE() int { - return int(C.FT_EraseEE(h.toH())) -} - -func (h handle) d2xxWriteEE(offset uint8, value uint16) int { - return int(C.FT_WriteEE(h.toH(), C.DWORD(offset), C.WORD(value))) -} - -func (h handle) d2xxEEUASize() (int, int) { - var size C.DWORD - if e := C.FT_EE_UASize(h.toH(), &size); e != 0 { - return 0, int(e) - } - return int(size), 0 -} - -func (h handle) d2xxEEUARead(ua []byte) int { - var size C.DWORD - if e := C.FT_EE_UARead(h.toH(), (*C.UCHAR)(unsafe.Pointer(&ua[0])), C.DWORD(len(ua)), &size); e != 0 { - return int(e) - } - if int(size) != len(ua) { - return 6 // FT_INVALID_PARAMETER - } - return 0 -} - -func (h handle) d2xxEEUAWrite(ua []byte) int { - if e := C.FT_EE_UAWrite(h.toH(), (*C.UCHAR)(&ua[0]), C.DWORD(len(ua))); e != 0 { - return int(e) - } - return 0 -} - -func (h handle) d2xxSetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) int { - v := C.UCHAR(0) - if eventEn { - v = 1 - } - w := C.UCHAR(0) - if errorEn { - w = 1 - } - return int(C.FT_SetChars(h.toH(), C.UCHAR(eventChar), v, C.UCHAR(errorChar), w)) -} - -func (h handle) d2xxSetUSBParameters(in, out int) int { - return int(C.FT_SetUSBParameters(h.toH(), C.DWORD(in), C.DWORD(out))) -} - -func (h handle) d2xxSetFlowControl() int { - return int(C.FT_SetFlowControl(h.toH(), C.FT_FLOW_RTS_CTS, 0, 0)) -} - -func (h handle) d2xxSetTimeouts(readMS, writeMS int) int { - return int(C.FT_SetTimeouts(h.toH(), C.DWORD(readMS), C.DWORD(writeMS))) -} - -func (h handle) d2xxSetLatencyTimer(delayMS uint8) int { - return int(C.FT_SetLatencyTimer(h.toH(), C.UCHAR(delayMS))) -} - -func (h handle) d2xxSetBaudRate(hz uint32) int { - return int(C.FT_SetBaudRate(h.toH(), C.DWORD(hz))) -} - -func (h handle) d2xxGetQueueStatus() (uint32, int) { - var v C.DWORD - e := C.FT_GetQueueStatus(h.toH(), &v) - return uint32(v), int(e) -} - -func (h handle) d2xxRead(b []byte) (int, int) { - var bytesRead C.DWORD - e := C.FT_Read(h.toH(), C.LPVOID(unsafe.Pointer(&b[0])), C.DWORD(len(b)), &bytesRead) - return int(bytesRead), int(e) -} - -func (h handle) d2xxWrite(b []byte) (int, int) { - var bytesSent C.DWORD - e := C.FT_Write(h.toH(), C.LPVOID(unsafe.Pointer(&b[0])), C.DWORD(len(b)), &bytesSent) - return int(bytesSent), int(e) -} - -func (h handle) d2xxGetBitMode() (byte, int) { - var s C.UCHAR - e := C.FT_GetBitMode(h.toH(), &s) - return uint8(s), int(e) -} - -func (h handle) d2xxSetBitMode(mask, mode byte) int { - return int(C.FT_SetBitMode(h.toH(), C.UCHAR(mask), C.UCHAR(mode))) -} - -func (h handle) toH() C.FT_HANDLE { - return C.FT_HANDLE(h) -} diff --git a/hostextra/d2xx/d2xx_posix_no_cgo.go b/hostextra/d2xx/d2xx_posix_no_cgo.go deleted file mode 100644 index 4c5c5e4..0000000 --- a/hostextra/d2xx/d2xx_posix_no_cgo.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build !cgo -// +build !windows - -package d2xx - -import "periph.io/x/extra/hostextra/d2xx/ftdi" - -const disabled = true - -// Library functions. - -func d2xxGetLibraryVersion() (uint8, uint8, uint8) { - return 0, 0, 0 -} - -func d2xxCreateDeviceInfoList() (int, int) { - return 0, noCGO -} - -// Device functions. - -func d2xxOpen(i int) (d2xxHandle, int) { - return handle(0), noCGO -} - -func (h handle) d2xxClose() int { - return noCGO -} - -func (h handle) d2xxResetDevice() int { - return noCGO -} - -func (h handle) d2xxGetDeviceInfo() (ftdi.DevType, uint16, uint16, int) { - return ftdi.Unknown, 0, 0, noCGO -} - -func (h handle) d2xxEEPROMRead(t ftdi.DevType, ee *ftdi.EEPROM) int { - return noCGO -} - -func (h handle) d2xxEEPROMProgram(e *ftdi.EEPROM) int { - return noCGO -} - -func (h handle) d2xxEraseEE() int { - return noCGO -} - -func (h handle) d2xxWriteEE(offset uint8, value uint16) int { - return noCGO -} - -func (h handle) d2xxEEUASize() (int, int) { - return 0, noCGO -} - -func (h handle) d2xxEEUARead(ua []byte) int { - return noCGO -} - -func (h handle) d2xxEEUAWrite(ua []byte) int { - return noCGO -} - -func (h handle) d2xxSetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) int { - return noCGO -} - -func (h handle) d2xxSetUSBParameters(in, out int) int { - return noCGO -} - -func (h handle) d2xxSetFlowControl() int { - return noCGO -} - -func (h handle) d2xxSetTimeouts(readMS, writeMS int) int { - return noCGO -} - -func (h handle) d2xxSetLatencyTimer(delayMS uint8) int { - return noCGO -} - -func (h handle) d2xxSetBaudRate(hz uint32) int { - return noCGO -} - -func (h handle) d2xxGetQueueStatus() (uint32, int) { - return 0, noCGO -} - -func (h handle) d2xxRead(b []byte) (int, int) { - return 0, noCGO -} - -func (h handle) d2xxWrite(b []byte) (int, int) { - return 0, noCGO -} - -func (h handle) d2xxGetBitMode() (byte, int) { - return 0, noCGO -} - -func (h handle) d2xxSetBitMode(mask, mode byte) int { - return noCGO -} diff --git a/hostextra/d2xx/d2xx_posix_other.go b/hostextra/d2xx/d2xx_posix_other.go deleted file mode 100644 index 09a0538..0000000 --- a/hostextra/d2xx/d2xx_posix_other.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// +build cgo -// +build !darwin,!amd64 -// +build !linux,!amd64 -// +build !linux,!arm -// +build !windows - -package d2xx - -/* -#cgo LDFLAGS: -lftd2xx -*/ -import "C" diff --git a/hostextra/d2xx/d2xx_windows.go b/hostextra/d2xx/d2xx_windows.go deleted file mode 100644 index 268617c..0000000 --- a/hostextra/d2xx/d2xx_windows.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -package d2xx - -import ( - "bytes" - "syscall" - "unsafe" - - "periph.io/x/extra/hostextra/d2xx/ftdi" -) - -var disabled = true - -// Library functions. - -func d2xxGetLibraryVersion() (uint8, uint8, uint8) { - var v uint32 - if pGetLibraryVersion != nil { - pGetLibraryVersion.Call(uintptr(unsafe.Pointer(&v))) - } - return uint8(v >> 16), uint8(v >> 8), uint8(v) -} - -func d2xxCreateDeviceInfoList() (int, int) { - var num uint32 - r1, _, _ := pCreateDeviceInfoList.Call(uintptr(unsafe.Pointer(&num))) - return int(num), int(r1) -} - -// Device functions. - -func d2xxOpen(i int) (d2xxHandle, int) { - var h handle - r1, _, _ := pOpen.Call(uintptr(i), uintptr(unsafe.Pointer(&h))) - return h, int(r1) -} - -func (h handle) d2xxClose() int { - r1, _, _ := pClose.Call(h.toH()) - return int(r1) -} - -func (h handle) d2xxResetDevice() int { - r1, _, _ := pResetDevice.Call(h.toH()) - return int(r1) -} - -func (h handle) d2xxGetDeviceInfo() (ftdi.DevType, uint16, uint16, int) { - var d ftdi.DevType - var id uint32 - if r1, _, _ := pGetDeviceInfo.Call(h.toH(), uintptr(unsafe.Pointer(&d)), uintptr(unsafe.Pointer(&id)), 0, 0, 0); r1 != 0 { - return ftdi.Unknown, 0, 0, int(r1) - } - return d, uint16(id >> 16), uint16(id), 0 -} - -func (h handle) d2xxEEPROMRead(t ftdi.DevType, ee *ftdi.EEPROM) int { - var manufacturer [64]byte - var manufacturerID [64]byte - var desc [64]byte - var serial [64]byte - // Shortcuts. - m := uintptr(unsafe.Pointer(&manufacturer[0])) - mi := uintptr(unsafe.Pointer(&manufacturerID[0])) - de := uintptr(unsafe.Pointer(&desc[0])) - s := uintptr(unsafe.Pointer(&serial[0])) - - if l := t.EEPROMSize(); len(ee.Raw) < l { - ee.Raw = make([]byte, l) - } else if len(ee.Raw) > l { - ee.Raw = ee.Raw[:l] - } - eepromVoid := unsafe.Pointer(&ee.Raw[0]) - hdr := ee.AsHeader() - // It MUST be set here. This is not always the case on posix. - hdr.DeviceType = t - if r1, _, _ := pEEPROMRead.Call(h.toH(), uintptr(eepromVoid), uintptr(len(ee.Raw)), m, mi, de, s); r1 != 0 { - return int(r1) - } - - ee.Manufacturer = toStr(manufacturer[:]) - ee.ManufacturerID = toStr(manufacturerID[:]) - ee.Desc = toStr(desc[:]) - ee.Serial = toStr(serial[:]) - return 0 -} - -func (h handle) d2xxEEPROMProgram(ee *ftdi.EEPROM) int { - var cmanu [64]byte - copy(cmanu[:], ee.Manufacturer) - var cmanuID [64]byte - copy(cmanuID[:], ee.ManufacturerID) - var cdesc [64]byte - copy(cdesc[:], ee.Desc) - var cserial [64]byte - copy(cserial[:], ee.Serial) - r1, _, _ := pEEPROMProgram.Call(h.toH(), uintptr(unsafe.Pointer(&ee.Raw[0])), uintptr(len(ee.Raw)), uintptr(unsafe.Pointer(&cmanu[0])), uintptr(unsafe.Pointer(&cmanuID[0])), uintptr(unsafe.Pointer(&cdesc[0])), uintptr(unsafe.Pointer(&cserial[0]))) - return int(r1) -} - -func (h handle) d2xxEraseEE() int { - r1, _, _ := pEraseEE.Call(h.toH()) - return int(r1) -} - -func (h handle) d2xxWriteEE(offset uint8, value uint16) int { - r1, _, _ := pWriteEE.Call(h.toH(), uintptr(offset), uintptr(value)) - return int(r1) -} - -func (h handle) d2xxEEUASize() (int, int) { - var size uint32 - if r1, _, _ := pEEUASize.Call(h.toH(), uintptr(unsafe.Pointer(&size))); r1 != 0 { - return 0, int(r1) - } - return int(size), 0 -} - -func (h handle) d2xxEEUARead(ua []byte) int { - var size uint32 - if r1, _, _ := pEEUARead.Call(h.toH(), uintptr(unsafe.Pointer(&ua[0])), uintptr(len(ua)), uintptr(unsafe.Pointer(&size))); r1 != 0 { - return int(r1) - } - if int(size) != len(ua) { - return 6 // FT_INVALID_PARAMETER - } - return 0 -} - -func (h handle) d2xxEEUAWrite(ua []byte) int { - r1, _, _ := pEEUAWrite.Call(h.toH(), uintptr(unsafe.Pointer(&ua[0])), uintptr(len(ua))) - return int(r1) -} - -func (h handle) d2xxSetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) int { - v := uintptr(0) - if eventEn { - v = 1 - } - w := uintptr(0) - if errorEn { - w = 1 - } - r1, _, _ := pSetChars.Call(h.toH(), uintptr(eventChar), v, uintptr(errorChar), w) - return int(r1) -} - -func (h handle) d2xxSetUSBParameters(in, out int) int { - r1, _, _ := pSetUSBParameters.Call(h.toH(), uintptr(in), uintptr(out)) - return int(r1) -} - -func (h handle) d2xxSetFlowControl() int { - // FT_FLOW_RTS_CTS - r1, _, _ := pSetFlowControl.Call(h.toH(), 0x0100, 0, 0) - return int(r1) -} - -func (h handle) d2xxSetTimeouts(readMS, writeMS int) int { - r1, _, _ := pSetTimeouts.Call(h.toH(), uintptr(readMS), uintptr(writeMS)) - return int(r1) -} - -func (h handle) d2xxSetLatencyTimer(delayMS uint8) int { - r1, _, _ := pSetLatencyTimer.Call(h.toH(), uintptr(delayMS)) - return int(r1) -} - -func (h handle) d2xxSetBaudRate(hz uint32) int { - r1, _, _ := pSetBaudRate.Call(h.toH(), uintptr(hz)) - return int(r1) -} - -func (h handle) d2xxGetQueueStatus() (uint32, int) { - var v uint32 - r1, _, _ := pGetQueueStatus.Call(h.toH(), uintptr(unsafe.Pointer(&v))) - return v, int(r1) -} - -func (h handle) d2xxRead(b []byte) (int, int) { - var bytesRead uint32 - r1, _, _ := pRead.Call(h.toH(), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), uintptr(unsafe.Pointer(&bytesRead))) - return int(bytesRead), int(r1) -} - -func (h handle) d2xxWrite(b []byte) (int, int) { - var bytesSent uint32 - r1, _, _ := pWrite.Call(h.toH(), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), uintptr(unsafe.Pointer(&bytesSent))) - return int(bytesSent), int(r1) -} - -func (h handle) d2xxGetBitMode() (byte, int) { - var s uint8 - r1, _, _ := pGetBitMode.Call(h.toH(), uintptr(unsafe.Pointer(&s))) - return s, int(r1) -} - -func (h handle) d2xxSetBitMode(mask, mode byte) int { - r1, _, _ := pSetBitMode.Call(h.toH(), uintptr(mask), uintptr(mode)) - return int(r1) -} - -func (h handle) toH() uintptr { - return uintptr(h) -} - -// - -var ( - pClose *syscall.Proc - pCreateDeviceInfoList *syscall.Proc - pEEPROMRead *syscall.Proc - pEEPROMProgram *syscall.Proc - pEraseEE *syscall.Proc - pWriteEE *syscall.Proc - pEEUASize *syscall.Proc - pEEUARead *syscall.Proc - pEEUAWrite *syscall.Proc - pGetBitMode *syscall.Proc - pGetDeviceInfo *syscall.Proc - pGetLibraryVersion *syscall.Proc - pGetQueueStatus *syscall.Proc - pOpen *syscall.Proc - pRead *syscall.Proc - pResetDevice *syscall.Proc - pSetBaudRate *syscall.Proc - pSetBitMode *syscall.Proc - pSetChars *syscall.Proc - pSetFlowControl *syscall.Proc - pSetLatencyTimer *syscall.Proc - pSetTimeouts *syscall.Proc - pSetUSBParameters *syscall.Proc - pWrite *syscall.Proc -) - -func init() { - if dll, _ := syscall.LoadDLL("ftd2xx.dll"); dll != nil { - // If any function is not found, disable the support. - disabled = false - find := func(n string) *syscall.Proc { - s, _ := dll.FindProc(n) - if s == nil { - disabled = true - } - return s - } - pClose = find("FT_Close") - pCreateDeviceInfoList = find("FT_CreateDeviceInfoList") - pEEPROMRead = find("FT_EEPROM_Read") - pEEPROMProgram = find("FT_EEPROM_Program") - pEraseEE = find("FT_EraseEE") - pWriteEE = find("FT_WriteEE") - pEEUASize = find("FT_EE_UASize") - pEEUARead = find("FT_EE_UARead") - pEEUAWrite = find("FT_EE_UAWrite") - pGetBitMode = find("FT_GetBitMode") - pGetDeviceInfo = find("FT_GetDeviceInfo") - pGetLibraryVersion = find("FT_GetLibraryVersion") - pGetQueueStatus = find("FT_GetQueueStatus") - pOpen = find("FT_Open") - pRead = find("FT_Read") - pResetDevice = find("FT_ResetDevice") - pSetBaudRate = find("FT_SetBaudRate") - pSetBitMode = find("FT_SetBitMode") - pSetChars = find("FT_SetChars") - pSetFlowControl = find("FT_SetFlowControl") - pSetLatencyTimer = find("FT_SetLatencyTimer") - pSetTimeouts = find("FT_SetTimeouts") - pSetUSBParameters = find("FT_SetUSBParameters") - pWrite = find("FT_Write") - } -} - -func toStr(c []byte) string { - i := bytes.IndexByte(c, 0) - if i != -1 { - return string(c[:i]) - } - return string(c) -} diff --git a/hostextra/d2xx/d2xxsmoketest/README.md b/hostextra/d2xx/d2xxsmoketest/README.md deleted file mode 100644 index ec4d21c..0000000 --- a/hostextra/d2xx/d2xxsmoketest/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# D2XX smoke test - -Verifies that a FT232H/FT232R works as expected. diff --git a/hostextra/d2xx/d2xxsmoketest/d2xxsmoketest.go b/hostextra/d2xx/d2xxsmoketest/d2xxsmoketest.go deleted file mode 100644 index 60eefaf..0000000 --- a/hostextra/d2xx/d2xxsmoketest/d2xxsmoketest.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Package d2xxsmoketest is leveraged by extra-smoketest to verify that a -// FT232H/FT232R is working as expectd. -package d2xxsmoketest - -import ( - "errors" - "flag" - "fmt" - "time" - - "periph.io/x/extra/hostextra/d2xx" - "periph.io/x/periph/conn/gpio" -) - -// SmokeTest is imported by extra-smoketest. -type SmokeTest struct { -} - -// Name implements the SmokeTest interface. -func (s *SmokeTest) Name() string { - return "d2xx" -} - -// Description implements the SmokeTest interface. -func (s *SmokeTest) Description() string { - return "Tests FT232H/FT232R" -} - -// Run implements the SmokeTest interface. -func (s *SmokeTest) Run(f *flag.FlagSet, args []string) (err error) { - devType := f.String("type", "", "Device type to test, i.e. ft232h or ft232r") - if err := f.Parse(args); err != nil { - return err - } - if f.NArg() != 0 { - f.Usage() - return errors.New("unrecognized arguments") - } - - all := d2xx.All() - if len(all) != 1 { - return fmt.Errorf("exactly one device is expected, got %d", len(all)) - } - dev := all[0] - switch *devType { - case "ft232h": - if d, ok := dev.(*d2xx.FT232H); ok { - return testFT232H(d) - } - case "ft232r": - if d, ok := dev.(*d2xx.FT232R); ok { - return testFT232R(d) - } - case "": - return errors.New("-type is required") - default: - return errors.New("unrecognized -type, only ft232h and ft232r are supported") - } - return fmt.Errorf("expected %s, got %T; %s", *devType, dev, dev.String()) -} - -func testFT232H(d *d2xx.FT232H) error { - // TODO(maruel): Read EEPROM, UA. - if err := gpioTest(&loggingPin{d.D2}, &loggingPin{d.D1}, false); err != nil { - return err - } - if err := gpioPerfTest(d.C7); err != nil { - return err - } - if err := i2cTest(d); err != nil { - return err - } - return spiTest(d) -} - -func testFT232R(d *d2xx.FT232R) error { - // TODO(maruel): Read EEPROM, UA. - // TODO(maruel): Remove broken once FT232R driver is stable for GPIO I/O. - if err := gpioTest(&loggingPin{d.RX}, &loggingPin{d.TX}, true); err != nil { - return err - } - return gpioPerfTest(d.CTS) -} - -// gpioPerfTest reads and write in a tight loop to evaluate performance. -// -// It doesn't evaluate correctness. -// -// This makes sure that the flush operation is used, vs relying on -// SetLatencyTimer value. -func gpioPerfTest(p gpio.PinIO) error { - fmt.Printf(" GPIO performance on %s:\n", p) - const loops = 1000 - fmt.Printf(" %d reads: ", loops) - if err := p.In(gpio.PullNoChange, gpio.NoEdge); err != nil { - return err - } - start := time.Now() - for i := 0; i < loops; i++ { - p.Read() - } - s := time.Since(start) - fmt.Printf("%s; %s/op\n", s, s/loops) - fmt.Printf(" %d writes: ", loops) - if err := p.Out(gpio.Low); err != nil { - return err - } - start = time.Now() - for i := 0; i < loops; i++ { - if err := p.Out(gpio.Low); err != nil { - return err - } - } - s = time.Since(start) - fmt.Printf("%s; %s/op\n", s, s/loops) - return nil -} - -// gpioTest ensures connectivity works. -func gpioTest(p1, p2 gpio.PinIO, broken bool) error { - fmt.Printf(" GPIO functionality on %s and %s:\n", p1, p2) - if err := p1.In(gpio.PullNoChange, gpio.NoEdge); err != nil { - return err - } - if err := p2.Out(gpio.Low); err != nil { - return err - } - if l := p1.Read(); l != gpio.Low { - if broken { - fmt.Printf("TODO(maruel): Not working; %s: expected to read %s but got %s\n", p1, gpio.Low, l) - } else { - return fmt.Errorf("%s: expected to read %s but got %s", p1, gpio.Low, l) - } - } - if err := p2.Out(gpio.High); err != nil { - return err - } - if l := p1.Read(); l != gpio.High { - if broken { - fmt.Printf("TODO(maruel): Not working; %s: expected to read %s but got %s\n", p1, gpio.High, l) - } else { - return fmt.Errorf("%s: expected to read %s but got %s", p1, gpio.High, l) - } - } - return nil -} - -func i2cTest(d *d2xx.FT232H) error { - fmt.Printf(" I²C functionality:\n") - i, err := d.I2C(gpio.Float) - if err != nil { - return err - } - if err = i.Close(); err != nil { - return err - } - // TODO(maruel): Do a write; this would require a device. - fmt.Printf(" OK\n") - return nil -} - -func spiTest(d *d2xx.FT232H) error { - fmt.Printf(" SPI functionality:\n") - s, err := d.SPI() - if err != nil { - return err - } - if err = s.Close(); err != nil { - return err - } - // TODO(maruel): Do a write. This can be done without a device. - fmt.Printf(" OK\n") - return nil -} - -// loggingPin logs when its state changes. -type loggingPin struct { - gpio.PinIO -} - -func (p *loggingPin) In(pull gpio.Pull, edge gpio.Edge) error { - start := time.Now() - if err := p.PinIO.In(pull, edge); err != nil { - fmt.Printf(" %s %s.In(%s, %s) = %v\n", time.Since(start), p, pull, edge, err) - return err - } - fmt.Printf(" %s %s.In(%s, %s)\n", time.Since(start), p, pull, edge) - return nil -} - -func (p *loggingPin) Read() gpio.Level { - start := time.Now() - l := p.PinIO.Read() - fmt.Printf(" %s %s.Read() = %s\n", time.Since(start), p, l) - return l -} - -func (p *loggingPin) Out(l gpio.Level) error { - start := time.Now() - if err := p.PinIO.Out(l); err != nil { - fmt.Printf(" %s %s.Out(%s) = %v\n", time.Since(start), p, l, err) - return err - } - fmt.Printf(" %s %s.Out(%s)\n", time.Since(start), p, l) - return nil -} diff --git a/hostextra/d2xx/darwin_amd64/libftd2xx.a b/hostextra/d2xx/darwin_amd64/libftd2xx.a deleted file mode 100644 index bcee16178e41189b07b3da3e833d0c9798ce923d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 350680 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%0A3`Fp5VoR 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 diff --git a/hostextra/d2xx/debian/98-ft232h.rules b/hostextra/d2xx/debian/98-ft232h.rules deleted file mode 100644 index 170fbdc..0000000 --- a/hostextra/d2xx/debian/98-ft232h.rules +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 2017 The Periph Authors. All rights reserved. -# Use of this source code is governed under the Apache License, Version 2.0 -# that can be found in the LICENSE file. - -# udev rule file to make FTDI devices accessible usable as non-root and disable -# the ftdi_sio driver. -# -# See https://periph.io/device/ftdi/ for more information. - -# Make FTDI device usable from users in group plugdev. -SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", MODE="0664", GROUP="plugdev" - -# Disallow ftdi_sio from loading. -SUBSYSTEM=="usb", DRIVER=="ftdi_sio", ATTRS{idVendor}=="0403", RUN+="/bin/sh -c 'echo $kernel > /sys/bus/usb/drivers/ftdi_sio/unbind'" diff --git a/hostextra/d2xx/dev.go b/hostextra/d2xx/dev.go deleted file mode 100644 index fe5ec67..0000000 --- a/hostextra/d2xx/dev.go +++ /dev/null @@ -1,878 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -package d2xx - -import ( - "errors" - "strconv" - "sync" - - "periph.io/x/extra/hostextra/d2xx/ftdi" - "periph.io/x/periph/conn" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/i2c" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/spi" -) - -// Info is the information gathered about the connected FTDI device. -// -// The data is gathered from the USB descriptor. -type Info struct { - // Opened is true if the device was successfully opened. - Opened bool - // Type is the FTDI device type. - // - // The value can be "FT232H", "FT232R", etc. - // - // An empty string means the type is unknown. - Type string - // VenID is the vendor ID from the USB descriptor information. It is expected - // to be 0x0403 (FTDI). - VenID uint16 - // DevID is the product ID from the USB descriptor information. It is - // expected to be one of 0x6001, 0x6006, 0x6010, 0x6014. - DevID uint16 -} - -// Dev represents one FTDI device. -// -// There can be multiple FTDI devices connected to a host. -// -// The device may also export one or multiple of I²C, SPI buses. You need to -// either cast into the right hardware, but more simply use the i2creg / spireg -// bus/port registries. -type Dev interface { - // conn.Resource - String() string - Halt() error - - // Info returns information about an opened device. - Info(i *Info) - - // Header returns the GPIO pins exposed on the chip. - Header() []gpio.PinIO - - // SetSpeed sets the base clock for all I/O transactions. - // - // The device defaults to its fastest speed. - SetSpeed(f physic.Frequency) error - - // EEPROM returns the EEPROM content. - EEPROM(ee *ftdi.EEPROM) error - // WriteEEPROM updates the EEPROM. Must be used carefully. - WriteEEPROM(ee *ftdi.EEPROM) error - // EraseEEPROM erases the EEPROM. Must be used carefully. - EraseEEPROM() error - // UserArea reads and return the EEPROM part that can be used to stored user - // defined values. - UserArea() ([]byte, error) - // WriteUserArea updates the user area in the EEPROM. - // - // If the length of ua is less than the available space, is it zero extended. - WriteUserArea(ua []byte) error -} - -// broken represents a device that couldn't be opened correctly. -// -// It returns an error message to help the user diagnose issues. -type broken struct { - index int - err error - name string -} - -func (b *broken) String() string { - return b.name -} - -func (b *broken) Halt() error { - return nil -} - -func (b *broken) Info(i *Info) { - i.Opened = false -} - -func (b *broken) Header() []gpio.PinIO { - return nil -} - -func (b *broken) SetSpeed(f physic.Frequency) error { - return b.err -} - -func (b *broken) EEPROM(ee *ftdi.EEPROM) error { - return b.err -} - -func (b *broken) WriteEEPROM(ee *ftdi.EEPROM) error { - return b.err -} - -func (b *broken) EraseEEPROM() error { - return b.err -} - -func (b *broken) UserArea() ([]byte, error) { - return nil, b.err -} - -func (b *broken) WriteUserArea(ua []byte) error { - return b.err -} - -// generic represents a generic FTDI device. -// -// It is used for the models that this package doesn't fully support yet. -type generic struct { - // Immutable after initialization. - index int - h device - name string -} - -func (f *generic) String() string { - return f.name -} - -// Halt implements conn.Resource. -// -// This halts all operations going through this device. -func (f *generic) Halt() error { - return f.h.reset() -} - -// Info returns information about an opened device. -func (f *generic) Info(i *Info) { - i.Opened = true - i.Type = f.h.t.String() - i.VenID = f.h.venID - i.DevID = f.h.devID -} - -// Header returns the GPIO pins exposed on the chip. -func (f *generic) Header() []gpio.PinIO { - return nil -} - -func (f *generic) SetSpeed(freq physic.Frequency) error { - // TODO(maruel): Doc says the actual speed is 16x, confirm. - return f.h.setBaudRate(int64(freq / physic.Hertz)) -} - -func (f *generic) EEPROM(ee *ftdi.EEPROM) error { - return f.h.readEEPROM(ee) - /* - if f.ee.Raw == nil { - if err := f.h.readEEPROM(&f.ee); err != nil { - return nil - } - if f.ee.Raw == nil { - // It's a fresh new device. Devices bought via Adafruit already have - // their EEPROM programmed with Adafruit branding but devices sold by - // CJMCU are not. Since d2xxGetDeviceInfo() above succeeded, we know the - // device type via the USB descriptor, which is sufficient to load the - // driver, which permits to program the EEPROM to "bootstrap" it. - f.ee.Raw = []byte{} - } - } - *ee = f.ee - return nil - */ -} - -func (f *generic) WriteEEPROM(ee *ftdi.EEPROM) error { - // TODO(maruel): Compare with the cached EEPROM, and only update the - // different values if needed so reduce the EEPROM wear. - // f.h.h.d2xxWriteEE() - return f.h.programEEPROM(ee) -} - -func (f *generic) EraseEEPROM() error { - return f.h.eraseEEPROM() -} - -func (f *generic) UserArea() ([]byte, error) { - return f.h.readUA() -} - -func (f *generic) WriteUserArea(ua []byte) error { - return f.h.writeUA(ua) -} - -// - -func newFT232H(g generic) (*FT232H, error) { - f := &FT232H{ - generic: g, - cbus: gpiosMPSSE{h: &g.h, cbus: true}, - dbus: gpiosMPSSE{h: &g.h}, - c8: invalidPin{num: 16, n: g.name + ".C8"}, // , dp: gpio.PullUp - c9: invalidPin{num: 17, n: g.name + ".C9"}, // , dp: gpio.PullUp - } - f.cbus.init(f.name) - f.dbus.init(f.name) - - for i := range f.dbus.pins { - f.hdr[i] = &f.dbus.pins[i] - } - for i := range f.cbus.pins { - f.hdr[i+8] = &f.cbus.pins[i] - } - // TODO(maruel): C8 and C9 can be used when their mux in the EEPROM is set to - // ft232hCBusIOMode. - f.hdr[16] = &f.c8 - f.hdr[17] = &f.c9 - f.D0 = f.hdr[0] - f.D1 = f.hdr[1] - f.D2 = f.hdr[2] - f.D3 = f.hdr[3] - f.D4 = f.hdr[4] - f.D5 = f.hdr[5] - f.D6 = f.hdr[6] - f.D7 = f.hdr[7] - f.C0 = f.hdr[8] - f.C1 = f.hdr[9] - f.C2 = f.hdr[10] - f.C3 = f.hdr[11] - f.C4 = f.hdr[12] - f.C5 = f.hdr[13] - f.C6 = f.hdr[14] - f.C7 = f.hdr[15] - f.C8 = f.hdr[16] - f.C9 = f.hdr[17] - - // This function forces all pins as inputs. - if err := f.h.setupMPSSE(); err != nil { - return nil, err - } - f.s.c.f = f - f.i.f = f - return f, nil -} - -// FT232H represents a FT232H device. -// -// It implements Dev. -// -// The FT232H has 1024 bytes output buffer and 1024 bytes input buffer. It -// supports 512 bytes USB packets. -// -// The device can be used in a few different modes, two modes are supported: -// -// - D0~D3 as a serial protocol (MPSEE), supporting I²C and SPI (and eventually -// UART), In this mode, D4~D7 and C0~C7 can be used as synchronized GPIO. -// -// - D0~D7 as a synchronous 8 bits bit-bang port. In this mode, only a few pins -// on CBus are usable in slow mode. -// -// Each group of pins D0~D7 and C0~C7 can be changed at once in one pass via -// DBus() or CBus(). -// -// This enables usage as an 8 bit parallel port. -// -// Pins C8 and C9 can only be used in 'slow' mode via EEPROM and are currently -// not implemented. -// -// Datasheet -// -// http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf -type FT232H struct { - generic - - D0 gpio.PinIO // Clock output - D1 gpio.PinIO // Data out - D2 gpio.PinIO // Data in - D3 gpio.PinIO // Chip select - D4 gpio.PinIO - D5 gpio.PinIO - D6 gpio.PinIO - D7 gpio.PinIO - C0 gpio.PinIO - C1 gpio.PinIO - C2 gpio.PinIO - C3 gpio.PinIO - C4 gpio.PinIO - C5 gpio.PinIO - C6 gpio.PinIO - C7 gpio.PinIO - C8 gpio.PinIO // Not implemented - C9 gpio.PinIO // Not implemented - - hdr [18]gpio.PinIO - cbus gpiosMPSSE - dbus gpiosMPSSE - c8 invalidPin // gpio.PullUp - c9 invalidPin // gpio.PullUp - - mu sync.Mutex - usingI2C bool - usingSPI bool - i i2cBus - s spiMPSEEPort - // TODO(maruel): Technically speaking, a SPI port could be hacked up too in - // sync bit-bang but there's less point when MPSEE is available. -} - -// Header returns the GPIO pins exposed on the chip. -func (f *FT232H) Header() []gpio.PinIO { - out := make([]gpio.PinIO, len(f.hdr)) - copy(out, f.hdr[:]) - return out -} - -func (f *FT232H) SetSpeed(freq physic.Frequency) error { - // TODO(maruel): When using MPSEE, use the MPSEE command. If using sync - // bit-bang, use setBaudRate(). - - // TODO(maruel): Doc says the actual speed is 16x, confirm. - return f.h.setBaudRate(int64(freq / physic.Hertz)) -} - -// CBus sets the values of C0 to C7 in the specified direction and value. -// -// 0 direction means input, 1 means output. -func (f *FT232H) CBus(direction, value byte) error { - return f.h.mpsseCBus(direction, value) -} - -// DBus sets the values of D0 to d7 in the specified direction and value. -// -// 0 direction means input, 1 means output. -// -// This function must be used to set Clock idle level. -func (f *FT232H) DBus(direction, value byte) error { - return f.h.mpsseDBus(direction, value) -} - -// CBusRead reads the values of C0 to C7. -func (f *FT232H) CBusRead() (byte, error) { - return f.h.mpsseCBusRead() -} - -// DBusRead reads the values of D0 to D7. -func (f *FT232H) DBusRead() (byte, error) { - return f.h.mpsseDBusRead() -} - -// I2C returns an I²C bus over the AD bus. -// -// pull can be either gpio.PullUp or gpio.Float. The recommended pull up -// resistors are 10kΩ for 100kHz and 2kΩ for 400kHz when using Float. The -// GPIO's pull up is 75kΩ, which may require using a lower speed for signal -// reliability. Optimal pull up resistor calculation depends on the capacitance. -// -// It uses D0, D1 and D2. -// -// D0 is SCL. It must to be pulled up externally. -// -// D1 and D2 are used for SDA. D1 is the output using open drain, D2 is the -// input. D1 and D2 must be wired together and must be pulled up externally. -// -// It is recommended to set the mode to ‘245 FIFO’ in the EEPROM of the FT232H. -// -// The FIFO mode is recommended because it allows the ADbus lines to start as -// tristate. If the chip starts in the default UART mode, then the ADbus lines -// will be in the default UART idle states until the application opens the port -// and configures it as MPSSE. Care should also be taken that the RD# input on -// ACBUS is not asserted in this initial state as this can cause the FIFO lines -// to drive out. -func (f *FT232H) I2C(pull gpio.Pull) (i2c.BusCloser, error) { - if pull != gpio.PullUp && pull != gpio.Float { - return nil, errors.New("d2xx: I²C pull can only be PullUp or Float") - } - f.mu.Lock() - defer f.mu.Unlock() - if f.usingI2C { - return nil, errors.New("d2xx: already using I²C") - } - if f.usingSPI { - return nil, errors.New("d2xx: already using SPI") - } - if err := f.i.setupI2C(pull == gpio.PullUp); err != nil { - f.i.stopI2C() - return nil, err - } - return &f.i, nil -} - -// SPI returns a SPI port over the AD bus. -// -// It uses D0, D1, D2 and D3. D0 is the clock, D1 the output (MOSI), D2 is the -// input (MISO) and D3 is CS line. -func (f *FT232H) SPI() (spi.PortCloser, error) { - f.mu.Lock() - defer f.mu.Unlock() - if f.usingI2C { - return nil, errors.New("d2xx: already using I²C") - } - if f.usingSPI { - return nil, errors.New("d2xx: already using SPI") - } - // Don't mark it as being used yet. It only become used once Connect() is - // called. - return &f.s, nil -} - -// - -func newFT232R(g generic) (*FT232R, error) { - f := &FT232R{ - generic: g, - dbus: [...]dbusPinSync{{num: 0}, {num: 1}, {num: 2}, {num: 3}, {num: 4}, {num: 5}, {num: 6}, {num: 7}}, - cbus: [...]cbusPin{{num: 8, p: gpio.PullUp}, {num: 9, p: gpio.PullUp}, {num: 10, p: gpio.PullUp}, {num: 11, p: gpio.Float}}, - } - // Use the UART names, as this is how all FT232R boards are marked. - dnames := [...]string{"TX", "RX", "RTS", "CTS", "DTR", "DSR", "DCD", "RI"} - for i := range f.dbus { - f.dbus[i].n = f.name + "." + dnames[i] - f.dbus[i].bus = f - f.hdr[i] = &f.dbus[i] - } - for i := range f.cbus { - f.cbus[i].n = f.name + ".C" + strconv.Itoa(i) - f.cbus[i].bus = f - f.hdr[i+8] = &f.cbus[i] - } - f.D0 = f.hdr[0] - f.D1 = f.hdr[1] - f.D2 = f.hdr[2] - f.D3 = f.hdr[3] - f.D4 = f.hdr[4] - f.D5 = f.hdr[5] - f.D6 = f.hdr[6] - f.D7 = f.hdr[7] - f.TX = f.hdr[0] - f.RX = f.hdr[1] - f.RTS = f.hdr[2] - f.CTS = f.hdr[3] - f.DTR = f.hdr[4] - f.DSR = f.hdr[5] - f.DCD = f.hdr[6] - f.RI = f.hdr[7] - f.C0 = f.hdr[8] - f.C1 = f.hdr[9] - f.C2 = f.hdr[10] - f.C3 = f.hdr[11] - - // Default to 3MHz. - if err := f.h.setBaudRate(3000000); err != nil { - return nil, err - } - - // Set all CBus pins as input. - if err := f.h.setBitMode(0, bitModeCbusBitbang); err != nil { - return nil, err - } - // And read their value. - // TODO(maruel): Sadly this is impossible to know which pin is input or - // output, but we could try to guess, as the call above may generate noise on - // the line which could interfere with the device connected. - var err error - if f.cbusnibble, err = f.h.getBitMode(); err != nil { - return nil, err - } - // Set all DBus as asynchronous bitbang, everything as input. - if err := f.h.setBitMode(0, bitModeAsyncBitbang); err != nil { - return nil, err - } - // And read their value. - var b [1]byte - if err := f.h.readAll(b[:]); err != nil { - return nil, err - } - f.dvalue = b[0] - f.s.c.f = f - return f, nil -} - -// FT232R represents a FT232RL/FT232RQ device. -// -// It implements Dev. -// -// Not all pins may be physically connected on the header! -// -// Adafruit's version only has the following pins connected: RX, TX, RTS and -// CTS. -// -// SparkFun's version exports all pins *except* (inexplicably) the CBus ones. -// -// The FT232R has 128 bytes output buffer and 256 bytes input buffer. -// -// Pin C4 can only be used in 'slow' mode via EEPROM and is currently not -// implemented. -// -// Datasheet -// -// http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf -type FT232R struct { - generic - - // Pin and their alias to the Dn pins for user convenience. Each pair points - // to the exact same pin. - D0, TX gpio.PinIO // Transmit; SPI_MOSI - D1, RX gpio.PinIO // Receive; SPI_MISO - D2, RTS gpio.PinIO // Request To Send Control Output / Handshake signal; SPI_CLK - D3, CTS gpio.PinIO // Clear to Send Control input / Handshake signal; SPI_CS - D4, DTR gpio.PinIO // Data Terminal Ready Control Output / Handshake signal - D5, DSR gpio.PinIO // Data Set Ready Control Input / Handshake signal - D6, DCD gpio.PinIO // Data Carrier Detect Control input - D7, RI gpio.PinIO // Ring Indicator Control Input. When remote wake up is enabled in the internal EEPROM taking RI# low can be used to resume the PC USB host controller from suspend. - - // The CBus pins are slower to use, but can drive an high load, like a LED. - C0 gpio.PinIO - C1 gpio.PinIO - C2 gpio.PinIO - C3 gpio.PinIO - - dbus [8]dbusPinSync - cbus [4]cbusPin - hdr [12]gpio.PinIO - - // Mutable. - mu sync.Mutex - usingSPI bool - usingCBus bool - s spiSyncPort - dmask uint8 // 0 input, 1 output - dvalue uint8 - cbusnibble uint8 // upper nibble is I/O control, lower nibble is values. -} - -// Header returns the GPIO pins exposed on the chip. -func (f *FT232R) Header() []gpio.PinIO { - out := make([]gpio.PinIO, len(f.hdr)) - copy(out, f.hdr[:]) - return out -} - -// SetDBusMask sets all D0~D7 input or output mode at once. -// -// mask is the input/output pins to use. A bit value of 0 sets the -// corresponding pin to an input, a bit value of 1 sets the corresponding pin -// to an output. -// -// It should be called before calling Tx(). -func (f *FT232R) SetDBusMask(mask uint8) error { - f.mu.Lock() - defer f.mu.Unlock() - if f.usingSPI { - return errors.New("d2xx: already using SPI") - } - return f.setDBusMaskLocked(mask) -} - -// Tx does synchronized read-then-write on all the D0~D7 GPIOs. -// -// SetSpeed() determines the pace at which the I/O is done. -// -// SetDBusMask() determines which bits are interpreted in the w and r byte -// slice. w has its significant value masked by 'mask' and r has its -// significant value masked by '^mask'. -// -// Input sample is done *before* updating outputs. So r[0] is sampled before -// w[0] is used. The last w byte should be duplicated if an addition read is -// desired. -// -// On the Adafruit cable, only the first 4 bits D0(TX), D1(RX), D2(RTS) and -// D3(CTS) are connected. This is just enough to create a full duplex SPI bus! -func (f *FT232R) Tx(w, r []byte) error { - if len(w) != 0 { - if len(r) != 0 && len(w) != len(r) { - return errors.New("d2xx: length of buffer w and r must match") - } - } else if len(r) == 0 { - return errors.New("d2xx: at least one of w or r must be passed") - } - f.mu.Lock() - defer f.mu.Unlock() - if f.usingSPI { - return errors.New("d2xx: already using SPI") - } - return f.txLocked(w, r) -} - -// SPI returns a SPI port over the first 4 pins. -// -// It uses D0(TX), D1(RX), D2(RTS) and D3(CTS). D2(RTS) is the clock, D0(TX) -// the output (MOSI), D1(RX) is the input (MISO) and D3(CTS) is CS line. -func (f *FT232R) SPI() (spi.PortCloser, error) { - f.mu.Lock() - defer f.mu.Unlock() - if f.usingSPI { - return nil, errors.New("d2xx: already using SPI") - } - // Don't mark it as being used yet. It only become used once Connect() is - // called. - return &f.s, nil -} - -// setDBusMaskLocked is the locked version of SetDBusMask. -func (f *FT232R) setDBusMaskLocked(mask uint8) error { - if mask != f.dmask { - if err := f.h.setBitMode(mask, bitModeAsyncBitbang); err != nil { - return err - } - f.dmask = mask - } - return nil -} - -func (f *FT232R) txLocked(w, r []byte) error { - // Investigate FT232R clock issue: - // http://developer.intra2net.com/mailarchive/html/libftdi/2010/msg00240.html - - // The FT232R has 128 bytes TX buffer and 256 bytes RX buffer. Chunk into 64 - // bytes chunks. That's half the buffer size of the TX buffer and permits - // pipelining and removes the risk of buffer overrun. This is important - // otherwise there's huge gaps due to the USB transmit overhead. - // TODO(maruel): Determine what's optimal via experimentation. - chunk := 64 - var scratch [128]byte - if len(w) == 0 { - // Read only. - for i := range scratch { - scratch[i] = f.dvalue - } - for len(r) != 0 { - // TODO(maruel): Optimize. - c := len(r) - if c > chunk { - c = chunk - } - if err := f.h.writeAll(scratch[:c]); err != nil { - return err - } - if err := f.h.readAll(r[:c]); err != nil { - return err - } - r = r[c:] - } - } else if len(r) == 0 { - // Write only. - // The first write is 128 bytes to fill the buffer. - chunk = 128 - for len(w) != 0 { - c := len(w) - if c > chunk { - c = chunk - } - if err := f.h.writeAll(w[:c]); err != nil { - return err - } - w = w[c:] - chunk = 64 - } - /* - // Let the USB drive pace it. - if err := f.h.writeAll(w); err != nil { - return err - } - */ - } else { - // R/W. - // Always write one 'w' ahead. - // The first write is 128 bytes to fill the buffer. - chunk = 128 - cw := len(w) - if cw > chunk { - cw = chunk - } - if err := f.h.writeAll(w[:cw]); err != nil { - return err - } - w = w[cw:] - chunk = 64 - for len(r) != 0 { - // Read then write. - cr := len(r) - if cr > chunk { - cr = chunk - } - if err := f.h.readAll(r[:cr]); err != nil { - return err - } - r = r[cr:] - - cw = len(w) - if cw > chunk { - cw = chunk - } - if cw != 0 { - if err := f.h.writeAll(w[:cw]); err != nil { - return err - } - w = w[cw:] - } - } - } - return nil -} - -// dbusSyncGPIOFunc implements dbusSync. It returns the function of a GPIO -// pin. -func (f *FT232R) dbusSyncGPIOFunc(n int) string { - f.mu.Lock() - defer f.mu.Unlock() - if f.usingSPI { - switch n { - case 0: - return "SPI_MOSI" // TX - case 1: - return "SPI_MISO" // RX - case 2: - return "SPI_CLK" // RTS - case 3: - return "SPI_CS" // CTS - } - } - mask := uint8(1 << uint(n)) - if f.dmask&mask != 0 { - return "Out/" + gpio.Level(f.dvalue&mask != 0).String() - } - return "In/" + f.dbusSyncReadLocked(n).String() -} - -// dbusSyncGPIOIn implements dbusSync. -func (f *FT232R) dbusSyncGPIOIn(n int) error { - f.mu.Lock() - defer f.mu.Unlock() - // TODO(maruel): if f.usingSPI && n < 4. - mask := uint8(1 << uint(n)) - if f.dmask&mask == 0 { - // Already input. - return nil - } - v := f.dmask &^ mask - if err := f.h.setBitMode(v, bitModeAsyncBitbang); err != nil { - return err - } - f.dmask = v - return nil -} - -// dbusSyncGPIORead implements dbusSync. -func (f *FT232R) dbusSyncGPIORead(n int) gpio.Level { - f.mu.Lock() - defer f.mu.Unlock() - return f.dbusSyncReadLocked(n) -} - -func (f *FT232R) dbusSyncReadLocked(n int) gpio.Level { - // In synchronous mode, to read we must write first to for a sample. - b := [1]byte{f.dvalue} - if err := f.h.writeAll(b[:]); err != nil { - return gpio.Low - } - mask := uint8(1 << uint(n)) - if err := f.h.readAll(b[:]); err != nil { - return gpio.Low - } - f.dvalue = b[0] - return f.dvalue&mask != 0 -} - -// dbusSyncGPIOOut implements dbusSync. -func (f *FT232R) dbusSyncGPIOOut(n int, l gpio.Level) error { - f.mu.Lock() - defer f.mu.Unlock() - mask := uint8(1 << uint(n)) - if f.dmask&mask != 1 { - // Was input. - v := f.dmask | mask - if err := f.h.setBitMode(v, bitModeAsyncBitbang); err != nil { - return err - } - f.dmask = v - } - return f.dbusSyncGPIOOutLocked(n, l) -} - -func (f *FT232R) dbusSyncGPIOOutLocked(n int, l gpio.Level) error { - b := [1]byte{f.dvalue} - if err := f.h.writeAll(b[:]); err != nil { - return err - } - f.dvalue = b[0] - // In synchronous mode, we must read after writing to flush the buffer. - if err := f.h.writeAll(b[:]); err != nil { - return err - } - return nil -} - -// cBusGPIOFunc implements cBusGPIO. -func (f *FT232R) cBusGPIOFunc(n int) string { - f.mu.Lock() - defer f.mu.Unlock() - fmask := uint8(0x10 << uint(n)) - vmask := uint8(1 << uint(n)) - if f.cbusnibble&fmask != 0 { - return "Out/" + gpio.Level(f.cbusnibble&vmask != 0).String() - } - return "In/" + f.cBusReadLocked(n).String() -} - -// cBusGPIOIn implements cBusGPIO. -func (f *FT232R) cBusGPIOIn(n int) error { - f.mu.Lock() - defer f.mu.Unlock() - fmask := uint8(0x10 << uint(n)) - if f.cbusnibble&fmask == 0 { - // Already input. - return nil - } - v := f.cbusnibble &^ fmask - if err := f.h.setBitMode(v, bitModeCbusBitbang); err != nil { - return err - } - f.cbusnibble = v - return nil -} - -// cBusGPIORead implements cBusGPIO. -func (f *FT232R) cBusGPIORead(n int) gpio.Level { - f.mu.Lock() - defer f.mu.Unlock() - return f.cBusReadLocked(n) -} - -func (f *FT232R) cBusReadLocked(n int) gpio.Level { - v, err := f.h.getBitMode() - if err != nil { - return gpio.Low - } - f.cbusnibble = v - vmask := uint8(1 << uint(n)) - return f.cbusnibble&vmask != 0 -} - -// cBusGPIOOut implements cBusGPIO. -func (f *FT232R) cBusGPIOOut(n int, l gpio.Level) error { - f.mu.Lock() - defer f.mu.Unlock() - fmask := uint8(0x10 << uint(n)) - vmask := uint8(1 << uint(n)) - v := f.cbusnibble | fmask - if l { - v |= vmask - } else { - v &^= vmask - } - if f.cbusnibble == v { - // Was already in the right mode. - return nil - } - if err := f.h.setBitMode(v, bitModeCbusBitbang); err != nil { - return err - } - f.cbusnibble = v - return nil -} - -// - -var _ conn.Resource = Dev(nil) diff --git a/hostextra/d2xx/doc.go b/hostextra/d2xx/doc.go deleted file mode 100644 index 30540b2..0000000 --- a/hostextra/d2xx/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Package d2xx is obsolete. -// -// Please use https://periph.io/x/host/v3 (or later) directly. -package d2xx diff --git a/hostextra/d2xx/driver.go b/hostextra/d2xx/driver.go deleted file mode 100644 index 23f865a..0000000 --- a/hostextra/d2xx/driver.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -package d2xx - -import ( - "strconv" - "sync" - - "periph.io/x/extra/hostextra/d2xx/ftdi" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/i2c" - "periph.io/x/periph/conn/i2c/i2creg" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/conn/pin/pinreg" - "periph.io/x/periph/conn/spi/spireg" -) - -// All enumerates all the connected FTDI devices. -func All() []Dev { - drv.mu.Lock() - defer drv.mu.Unlock() - out := make([]Dev, len(drv.all)) - copy(out, drv.all) - return out -} - -// - -// open opens a FTDI device. -// -// Must be called with mu held. -func open(opener func(i int) (d2xxHandle, int), i int) (Dev, error) { - h, err := openDev(opener, i) - if err != nil { - return nil, err - } - if err := h.setupCommon(); err != nil { - // setupCommon() takes the device in its previous state. It could be in an - // unexpected state, so try resetting it first. - if err := h.reset(); err != nil { - h.closeDev() - return nil, err - } - if err := h.setupCommon(); err != nil { - h.closeDev() - return nil, err - } - // The second attempt worked. - } - // Makes a copy of the handle. - g := generic{index: i, h: *h, name: h.t.String()} - if i > 0 { - // When more than one device is present, add "(index)" suffix. - // TODO(maruel): Using the serial number would be nicer than a number. - g.name += "(" + strconv.Itoa(i) + ")" - } - // Makes a copy of the generic instance. - switch g.h.t { - case ftdi.FT232H: - f, err := newFT232H(g) - if err != nil { - h.closeDev() - return nil, err - } - return f, nil - case ftdi.FT232R: - f, err := newFT232R(g) - if err != nil { - h.closeDev() - return nil, err - } - return f, nil - default: - return &g, nil - } -} - -// registerDev registers the header and supported buses and ports in the -// relevant registries. -func registerDev(d Dev, multi bool) error { - name := d.String() - hdr := d.Header() - - // Register the GPIOs. - for _, p := range hdr { - if err := gpioreg.Register(p); err != nil { - return err - } - } - if !multi { - // Register shorthands. - // The "." used here vs the "_" used in pinreg is unfortunate. Investigate - // a better way. - prefix := len(name) + 1 - for _, p := range hdr { - n := p.Name() - if err := gpioreg.RegisterAlias(n[prefix:], n); err != nil { - return err - } - } - } - - // Register the header. - raw := make([][]pin.Pin, len(hdr)) - for i := range hdr { - raw[i] = []pin.Pin{hdr[i]} - } - if err := pinreg.Register(name, raw); err != nil { - return err - } - switch t := d.(type) { - case *FT232H: - // Register I²C without pull up. - if err := i2creg.Register(name, nil, -1, func() (i2c.BusCloser, error) { return t.I2C(gpio.Float) }); err != nil { - return err - } - if err := spireg.Register(name, nil, -1, t.SPI); err != nil { - return err - } - // TODO(maruel): UART - case *FT232R: - // TODO(maruel): SPI, UART - } - return nil -} - -// driver implements periph.Driver. -type driver struct { - mu sync.Mutex - all []Dev - d2xxOpen func(i int) (d2xxHandle, int) - numDevices func() (int, error) -} - -func (d *driver) String() string { - return "d2xx" -} - -func (d *driver) Prerequisites() []string { - return nil -} - -func (d *driver) After() []string { - return nil -} - -func (d *driver) Init() (bool, error) { - num, err := d.numDevices() - if err != nil { - return true, err - } - multi := num > 1 - for i := 0; i < num; i++ { - // TODO(maruel): Close the device one day. :) - if dev, err1 := open(d.d2xxOpen, i); err1 == nil { - d.all = append(d.all, dev) - if err = registerDev(dev, multi); err != nil { - return true, err - } - } else { - // Create a shallow broken handle, so the user can learn how to fix the - // problem. - // - // TODO(maruel): On macOS with a FT232R, calling two processes in a row - // often results in a broken device on the second process. Figure out why - // and make it more resilient. - err = err1 - // The serial number is not available so what can be listed is limited. - // TODO(maruel): Add VID/PID? - name := "broken#" + strconv.Itoa(i) + ": " + err.Error() - d.all = append(d.all, &broken{index: i, err: err, name: name}) - } - } - return true, err -} - -func (d *driver) reset() { - d.mu.Lock() - defer d.mu.Unlock() - d.all = nil - // numDevices is mocked in tests. - d.numDevices = numDevices - // d2xxOpen is mocked in tests. - d.d2xxOpen = d2xxOpen - - // The d2xx can hang for up to the timeout under certain circumstances and the - // Go profiler is not very useful to find the source, so use manual logging - // to see where time it spent. - //d.d2xxOpen = func(i int) (d2xxHandle, int) { - // h, e := d2xxOpen(i) - // return &d2xxLoggingHandle{h}, e - //} -} - -func init() { - if !disabled { - drv.reset() - periph.MustRegister(&drv) - } -} - -var drv driver diff --git a/hostextra/d2xx/driver_test.go b/hostextra/d2xx/driver_test.go deleted file mode 100644 index 2b8bf63..0000000 --- a/hostextra/d2xx/driver_test.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2016 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -package d2xx - -import ( - "testing" - - "periph.io/x/extra/hostextra/d2xx/ftdi" -) - -func TestDriver(t *testing.T) { - defer reset(t) - drv.numDevices = func() (int, error) { - return 1, nil - } - drv.d2xxOpen = func(i int) (d2xxHandle, int) { - if i != 0 { - t.Fatalf("unexpected index %d", i) - } - d := &d2xxFakeHandle{ - d: ftdi.FT232R, - vid: 0x0403, - pid: 0x6014, - data: [][]byte{{}, {0}}, - } - return d, 0 - } - if b, err := drv.Init(); !b || err != nil { - t.Fatalf("Init() = %t, %v", b, err) - } -} - -// - -type d2xxFakeHandle struct { - d ftdi.DevType - vid uint16 - pid uint16 - data [][]byte - ua []byte - e ftdi.EEPROM -} - -func (d *d2xxFakeHandle) d2xxClose() int { - return 0 -} -func (d *d2xxFakeHandle) d2xxResetDevice() int { - return 0 -} -func (d *d2xxFakeHandle) d2xxGetDeviceInfo() (ftdi.DevType, uint16, uint16, int) { - return d.d, d.vid, d.pid, 0 -} -func (d *d2xxFakeHandle) d2xxEEPROMRead(dev ftdi.DevType, e *ftdi.EEPROM) int { - *e = d.e - return 0 -} -func (d *d2xxFakeHandle) d2xxEEPROMProgram(e *ftdi.EEPROM) int { - d.e = *e - return 0 -} -func (d *d2xxFakeHandle) d2xxEraseEE() int { - return 0 -} -func (d *d2xxFakeHandle) d2xxWriteEE(offset uint8, value uint16) int { - return 1 -} -func (d *d2xxFakeHandle) d2xxEEUASize() (int, int) { - return len(d.ua), 0 -} -func (d *d2xxFakeHandle) d2xxEEUARead(ua []byte) int { - copy(ua, d.ua) - return 0 -} -func (d *d2xxFakeHandle) d2xxEEUAWrite(ua []byte) int { - d.ua = make([]byte, len(ua)) - copy(d.ua, ua) - return 0 -} -func (d *d2xxFakeHandle) d2xxSetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) int { - return 0 -} -func (d *d2xxFakeHandle) d2xxSetUSBParameters(in, out int) int { - return 0 -} -func (d *d2xxFakeHandle) d2xxSetFlowControl() int { - return 0 -} -func (d *d2xxFakeHandle) d2xxSetTimeouts(readMS, writeMS int) int { - return 0 -} -func (d *d2xxFakeHandle) d2xxSetLatencyTimer(delayMS uint8) int { - return 0 -} -func (d *d2xxFakeHandle) d2xxSetBaudRate(hz uint32) int { - return 0 -} -func (d *d2xxFakeHandle) d2xxGetQueueStatus() (uint32, int) { - if len(d.data) == 0 { - return 0, 0 - } - // This is to work around flushPending(). - l := len(d.data[0]) - if l == 0 { - d.data = d.data[1:] - } - return uint32(l), 0 -} -func (d *d2xxFakeHandle) d2xxRead(b []byte) (int, int) { - if len(d.data) == 0 { - return 0, 0 - } - l := len(b) - if j := len(d.data[0]); j < l { - l = j - } - if l == 0 { - d.data = d.data[1:] - return 0, 0 - } - copy(b, d.data[0]) - d.data[0] = d.data[0][l:] - if len(d.data[0]) == 0 { - d.data = d.data[1:] - } - return l, 0 -} -func (d *d2xxFakeHandle) d2xxWrite(b []byte) (int, int) { - return 0, 0 -} -func (d *d2xxFakeHandle) d2xxGetBitMode() (byte, int) { - return 0, 0 -} -func (d *d2xxFakeHandle) d2xxSetBitMode(mask, mode byte) int { - return 0 -} - -func reset(t *testing.T) { - drv.reset() -} - -func init() { - reset(nil) -} diff --git a/hostextra/d2xx/example_test.go b/hostextra/d2xx/example_test.go deleted file mode 100644 index 96d1cc4..0000000 --- a/hostextra/d2xx/example_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -package d2xx_test - -import ( - "fmt" - "log" - - "periph.io/x/extra/hostextra/d2xx" - "periph.io/x/periph/host" -) - -func Example() { - if _, err := host.Init(); err != nil { - log.Fatal(err) - } - for _, d := range d2xx.All() { - fmt.Printf("%s\n", d) - } -} - -func ExampleVersion() { - // Print the d2xx driver version. It will be 0.0.0 if not found. - major, minor, build := d2xx.Version() - fmt.Printf("Using library %d.%d.%d\n", major, minor, build) -} diff --git a/hostextra/d2xx/ftd2xx.h b/hostextra/d2xx/ftd2xx.h deleted file mode 100644 index 6e055db..0000000 --- a/hostextra/d2xx/ftd2xx.h +++ /dev/null @@ -1,1446 +0,0 @@ -/*++ - -Copyright © 2001-2011 Future Technology Devices International Limited - -THIS SOFTWARE IS PROVIDED BY FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -FTDI DRIVERS MAY BE USED ONLY IN CONJUNCTION WITH PRODUCTS BASED ON FTDI PARTS. - -FTDI DRIVERS MAY BE DISTRIBUTED IN ANY FORM AS LONG AS LICENSE INFORMATION IS NOT MODIFIED. - -IF A CUSTOM VENDOR ID AND/OR PRODUCT ID OR DESCRIPTION STRING ARE USED, IT IS THE -RESPONSIBILITY OF THE PRODUCT MANUFACTURER TO MAINTAIN ANY CHANGES AND SUBSEQUENT WHQL -RE-CERTIFICATION AS A RESULT OF MAKING THESE CHANGES. - - -Module Name: - -ftd2xx.h - -Abstract: - -Native USB device driver for FTDI FT232x, FT245x, FT2232x and FT4232x devices -FTD2XX library definitions - -Environment: - -kernel & user mode - - ---*/ - - -#ifndef FTD2XX_H -#define FTD2XX_H - -#ifdef _WIN32 -// Compiling on Windows -#include - -// The following ifdef block is the standard way of creating macros -// which make exporting from a DLL simpler. All files within this DLL -// are compiled with the FTD2XX_EXPORTS symbol defined on the command line. -// This symbol should not be defined on any project that uses this DLL. -// This way any other project whose source files include this file see -// FTD2XX_API functions as being imported from a DLL, whereas this DLL -// sees symbols defined with this macro as being exported. - -#ifdef FTD2XX_EXPORTS -#define FTD2XX_API __declspec(dllexport) -#elif defined(FTD2XX_STATIC) -// Avoid decorations when linking statically to D2XX. -#define FTD2XX_API -// Static D2XX depends on these Windows libs: -#pragma comment(lib, "setupapi.lib") -#pragma comment(lib, "advapi32.lib") -#pragma comment(lib, "user32.lib") -#else -#define FTD2XX_API __declspec(dllimport) -#endif - -#else // _WIN32 -// Compiling on non-Windows platform. -#include "WinTypes.h" -// No decorations needed. -#define FTD2XX_API - -#endif // _WIN32 - -typedef PVOID FT_HANDLE; -typedef ULONG FT_STATUS; - -// -// Device status -// -enum { - FT_OK, - FT_INVALID_HANDLE, - FT_DEVICE_NOT_FOUND, - FT_DEVICE_NOT_OPENED, - FT_IO_ERROR, - FT_INSUFFICIENT_RESOURCES, - FT_INVALID_PARAMETER, - FT_INVALID_BAUD_RATE, - - FT_DEVICE_NOT_OPENED_FOR_ERASE, - FT_DEVICE_NOT_OPENED_FOR_WRITE, - FT_FAILED_TO_WRITE_DEVICE, - FT_EEPROM_READ_FAILED, - FT_EEPROM_WRITE_FAILED, - FT_EEPROM_ERASE_FAILED, - FT_EEPROM_NOT_PRESENT, - FT_EEPROM_NOT_PROGRAMMED, - FT_INVALID_ARGS, - FT_NOT_SUPPORTED, - FT_OTHER_ERROR, - FT_DEVICE_LIST_NOT_READY, -}; - - -#define FT_SUCCESS(status) ((status) == FT_OK) - -// -// FT_OpenEx Flags -// - -#define FT_OPEN_BY_SERIAL_NUMBER 1 -#define FT_OPEN_BY_DESCRIPTION 2 -#define FT_OPEN_BY_LOCATION 4 - -#define FT_OPEN_MASK (FT_OPEN_BY_SERIAL_NUMBER | \ - FT_OPEN_BY_DESCRIPTION | \ - FT_OPEN_BY_LOCATION) - -// -// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags -// - -#define FT_LIST_NUMBER_ONLY 0x80000000 -#define FT_LIST_BY_INDEX 0x40000000 -#define FT_LIST_ALL 0x20000000 - -#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL) - -// -// Baud Rates -// - -#define FT_BAUD_300 300 -#define FT_BAUD_600 600 -#define FT_BAUD_1200 1200 -#define FT_BAUD_2400 2400 -#define FT_BAUD_4800 4800 -#define FT_BAUD_9600 9600 -#define FT_BAUD_14400 14400 -#define FT_BAUD_19200 19200 -#define FT_BAUD_38400 38400 -#define FT_BAUD_57600 57600 -#define FT_BAUD_115200 115200 -#define FT_BAUD_230400 230400 -#define FT_BAUD_460800 460800 -#define FT_BAUD_921600 921600 - -// -// Word Lengths -// - -#define FT_BITS_8 (UCHAR) 8 -#define FT_BITS_7 (UCHAR) 7 - -// -// Stop Bits -// - -#define FT_STOP_BITS_1 (UCHAR) 0 -#define FT_STOP_BITS_2 (UCHAR) 2 - -// -// Parity -// - -#define FT_PARITY_NONE (UCHAR) 0 -#define FT_PARITY_ODD (UCHAR) 1 -#define FT_PARITY_EVEN (UCHAR) 2 -#define FT_PARITY_MARK (UCHAR) 3 -#define FT_PARITY_SPACE (UCHAR) 4 - -// -// Flow Control -// - -#define FT_FLOW_NONE 0x0000 -#define FT_FLOW_RTS_CTS 0x0100 -#define FT_FLOW_DTR_DSR 0x0200 -#define FT_FLOW_XON_XOFF 0x0400 - -// -// Purge rx and tx buffers -// -#define FT_PURGE_RX 1 -#define FT_PURGE_TX 2 - -// -// Events -// - -typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); - -#define FT_EVENT_RXCHAR 1 -#define FT_EVENT_MODEM_STATUS 2 -#define FT_EVENT_LINE_STATUS 4 - -// -// Timeouts -// - -#define FT_DEFAULT_RX_TIMEOUT 300 -#define FT_DEFAULT_TX_TIMEOUT 300 - -// -// Device types -// - -typedef ULONG FT_DEVICE; - -enum { - FT_DEVICE_BM, - FT_DEVICE_AM, - FT_DEVICE_100AX, - FT_DEVICE_UNKNOWN, - FT_DEVICE_2232C, - FT_DEVICE_232R, - FT_DEVICE_2232H, - FT_DEVICE_4232H, - FT_DEVICE_232H, - FT_DEVICE_X_SERIES, - FT_DEVICE_4222H_0, - FT_DEVICE_4222H_1_2, - FT_DEVICE_4222H_3, - FT_DEVICE_4222_PROG, - FT_DEVICE_900, - FT_DEVICE_930, - FT_DEVICE_UMFTPD3A, -}; - -// -// Bit Modes -// - -#define FT_BITMODE_RESET 0x00 -#define FT_BITMODE_ASYNC_BITBANG 0x01 -#define FT_BITMODE_MPSSE 0x02 -#define FT_BITMODE_SYNC_BITBANG 0x04 -#define FT_BITMODE_MCU_HOST 0x08 -#define FT_BITMODE_FAST_SERIAL 0x10 -#define FT_BITMODE_CBUS_BITBANG 0x20 -#define FT_BITMODE_SYNC_FIFO 0x40 - -// -// FT232R CBUS Options EEPROM values -// - -#define FT_232R_CBUS_TXDEN 0x00 // Tx Data Enable -#define FT_232R_CBUS_PWRON 0x01 // Power On -#define FT_232R_CBUS_RXLED 0x02 // Rx LED -#define FT_232R_CBUS_TXLED 0x03 // Tx LED -#define FT_232R_CBUS_TXRXLED 0x04 // Tx and Rx LED -#define FT_232R_CBUS_SLEEP 0x05 // Sleep -#define FT_232R_CBUS_CLK48 0x06 // 48MHz clock -#define FT_232R_CBUS_CLK24 0x07 // 24MHz clock -#define FT_232R_CBUS_CLK12 0x08 // 12MHz clock -#define FT_232R_CBUS_CLK6 0x09 // 6MHz clock -#define FT_232R_CBUS_IOMODE 0x0A // IO Mode for CBUS bit-bang -#define FT_232R_CBUS_BITBANG_WR 0x0B // Bit-bang write strobe -#define FT_232R_CBUS_BITBANG_RD 0x0C // Bit-bang read strobe - -// -// FT232H CBUS Options EEPROM values -// - -#define FT_232H_CBUS_TRISTATE 0x00 // Tristate -#define FT_232H_CBUS_TXLED 0x01 // Tx LED -#define FT_232H_CBUS_RXLED 0x02 // Rx LED -#define FT_232H_CBUS_TXRXLED 0x03 // Tx and Rx LED -#define FT_232H_CBUS_PWREN 0x04 // Power Enable -#define FT_232H_CBUS_SLEEP 0x05 // Sleep -#define FT_232H_CBUS_DRIVE_0 0x06 // Drive pin to logic 0 -#define FT_232H_CBUS_DRIVE_1 0x07 // Drive pin to logic 1 -#define FT_232H_CBUS_IOMODE 0x08 // IO Mode for CBUS bit-bang -#define FT_232H_CBUS_TXDEN 0x09 // Tx Data Enable -#define FT_232H_CBUS_CLK30 0x0A // 30MHz clock -#define FT_232H_CBUS_CLK15 0x0B // 15MHz clock -#define FT_232H_CBUS_CLK7_5 0x0C // 7.5MHz clock - -// -// FT X Series CBUS Options EEPROM values -// - -#define FT_X_SERIES_CBUS_TRISTATE 0x00 // Tristate -#define FT_X_SERIES_CBUS_TXLED 0x01 // Tx LED -#define FT_X_SERIES_CBUS_RXLED 0x02 // Rx LED -#define FT_X_SERIES_CBUS_TXRXLED 0x03 // Tx and Rx LED -#define FT_X_SERIES_CBUS_PWREN 0x04 // Power Enable -#define FT_X_SERIES_CBUS_SLEEP 0x05 // Sleep -#define FT_X_SERIES_CBUS_DRIVE_0 0x06 // Drive pin to logic 0 -#define FT_X_SERIES_CBUS_DRIVE_1 0x07 // Drive pin to logic 1 -#define FT_X_SERIES_CBUS_IOMODE 0x08 // IO Mode for CBUS bit-bang -#define FT_X_SERIES_CBUS_TXDEN 0x09 // Tx Data Enable -#define FT_X_SERIES_CBUS_CLK24 0x0A // 24MHz clock -#define FT_X_SERIES_CBUS_CLK12 0x0B // 12MHz clock -#define FT_X_SERIES_CBUS_CLK6 0x0C // 6MHz clock -#define FT_X_SERIES_CBUS_BCD_CHARGER 0x0D // Battery charger detected -#define FT_X_SERIES_CBUS_BCD_CHARGER_N 0x0E // Battery charger detected inverted -#define FT_X_SERIES_CBUS_I2C_TXE 0x0F // I2C Tx empty -#define FT_X_SERIES_CBUS_I2C_RXF 0x10 // I2C Rx full -#define FT_X_SERIES_CBUS_VBUS_SENSE 0x11 // Detect VBUS -#define FT_X_SERIES_CBUS_BITBANG_WR 0x12 // Bit-bang write strobe -#define FT_X_SERIES_CBUS_BITBANG_RD 0x13 // Bit-bang read strobe -#define FT_X_SERIES_CBUS_TIMESTAMP 0x14 // Toggle output when a USB SOF token is received -#define FT_X_SERIES_CBUS_KEEP_AWAKE 0x15 // - - -// Driver types -#define FT_DRIVER_TYPE_D2XX 0 -#define FT_DRIVER_TYPE_VCP 1 - - - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifdef FTD2XX_STATIC - FTD2XX_API - FT_STATUS WINAPI FT_Initialise( - void - ); - - FTD2XX_API - void WINAPI FT_Finalise( - void - ); -#endif // FTD2XX_STATIC - - FTD2XX_API - FT_STATUS WINAPI FT_Open( - int deviceNumber, - FT_HANDLE *pHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_OpenEx( - PVOID pArg1, - DWORD Flags, - FT_HANDLE *pHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_ListDevices( - PVOID pArg1, - PVOID pArg2, - DWORD Flags - ); - - FTD2XX_API - FT_STATUS WINAPI FT_Close( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_Read( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD dwBytesToRead, - LPDWORD lpBytesReturned - ); - - FTD2XX_API - FT_STATUS WINAPI FT_Write( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD dwBytesToWrite, - LPDWORD lpBytesWritten - ); - - FTD2XX_API - FT_STATUS WINAPI FT_IoCtl( - FT_HANDLE ftHandle, - DWORD dwIoControlCode, - LPVOID lpInBuf, - DWORD nInBufSize, - LPVOID lpOutBuf, - DWORD nOutBufSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetBaudRate( - FT_HANDLE ftHandle, - ULONG BaudRate - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetDivisor( - FT_HANDLE ftHandle, - USHORT Divisor - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetDataCharacteristics( - FT_HANDLE ftHandle, - UCHAR WordLength, - UCHAR StopBits, - UCHAR Parity - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetFlowControl( - FT_HANDLE ftHandle, - USHORT FlowControl, - UCHAR XonChar, - UCHAR XoffChar - ); - - FTD2XX_API - FT_STATUS WINAPI FT_ResetDevice( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetDtr( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_ClrDtr( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetRts( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_ClrRts( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetModemStatus( - FT_HANDLE ftHandle, - ULONG *pModemStatus - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetChars( - FT_HANDLE ftHandle, - UCHAR EventChar, - UCHAR EventCharEnabled, - UCHAR ErrorChar, - UCHAR ErrorCharEnabled - ); - - FTD2XX_API - FT_STATUS WINAPI FT_Purge( - FT_HANDLE ftHandle, - ULONG Mask - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetTimeouts( - FT_HANDLE ftHandle, - ULONG ReadTimeout, - ULONG WriteTimeout - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetQueueStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetEventNotification( - FT_HANDLE ftHandle, - DWORD Mask, - PVOID Param - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes, - DWORD *dwTxBytes, - DWORD *dwEventDWord - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetBreakOn( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetBreakOff( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetWaitMask( - FT_HANDLE ftHandle, - DWORD Mask - ); - - FTD2XX_API - FT_STATUS WINAPI FT_WaitOnMask( - FT_HANDLE ftHandle, - DWORD *Mask - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetEventStatus( - FT_HANDLE ftHandle, - DWORD *dwEventDWord - ); - - FTD2XX_API - FT_STATUS WINAPI FT_ReadEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - LPWORD lpwValue - ); - - FTD2XX_API - FT_STATUS WINAPI FT_WriteEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - WORD wValue - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EraseEE( - FT_HANDLE ftHandle - ); - - // - // structure to hold program data for FT_EE_Program, FT_EE_ProgramEx, FT_EE_Read - // and FT_EE_ReadEx functions - // - typedef struct ft_program_data { - - DWORD Signature1; // Header - must be 0x00000000 - DWORD Signature2; // Header - must be 0xffffffff - DWORD Version; // Header - FT_PROGRAM_DATA version - // 0 = original - // 1 = FT2232 extensions - // 2 = FT232R extensions - // 3 = FT2232H extensions - // 4 = FT4232H extensions - // 5 = FT232H extensions - - WORD VendorId; // 0x0403 - WORD ProductId; // 0x6001 - char *Manufacturer; // "FTDI" - char *ManufacturerId; // "FT" - char *Description; // "USB HS Serial Converter" - char *SerialNumber; // "FT000001" if fixed, or NULL - WORD MaxPower; // 0 < MaxPower <= 500 - WORD PnP; // 0 = disabled, 1 = enabled - WORD SelfPowered; // 0 = bus powered, 1 = self powered - WORD RemoteWakeup; // 0 = not capable, 1 = capable - // - // Rev4 (FT232B) extensions - // - UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise - UCHAR IsoIn; // non-zero if in endpoint is isochronous - UCHAR IsoOut; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable; // non-zero if pull down enabled - UCHAR SerNumEnable; // non-zero if serial number to be used - UCHAR USBVersionEnable; // non-zero if chip uses USBVersion - WORD USBVersion; // BCD (0x0200 => USB2) - // - // Rev 5 (FT2232) extensions - // - UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise - UCHAR IsoInA; // non-zero if in endpoint is isochronous - UCHAR IsoInB; // non-zero if in endpoint is isochronous - UCHAR IsoOutA; // non-zero if out endpoint is isochronous - UCHAR IsoOutB; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable5; // non-zero if pull down enabled - UCHAR SerNumEnable5; // non-zero if serial number to be used - UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion - WORD USBVersion5; // BCD (0x0200 => USB2) - UCHAR AIsHighCurrent; // non-zero if interface is high current - UCHAR BIsHighCurrent; // non-zero if interface is high current - UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFAIsFastSer; // non-zero if interface is Fast serial - UCHAR AIsVCP; // non-zero if interface is to use VCP drivers - UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFBIsFastSer; // non-zero if interface is Fast serial - UCHAR BIsVCP; // non-zero if interface is to use VCP drivers - // - // Rev 6 (FT232R) extensions - // - UCHAR UseExtOsc; // Use External Oscillator - UCHAR HighDriveIOs; // High Drive I/Os - UCHAR EndpointSize; // Endpoint size - UCHAR PullDownEnableR; // non-zero if pull down enabled - UCHAR SerNumEnableR; // non-zero if serial number to be used - UCHAR InvertTXD; // non-zero if invert TXD - UCHAR InvertRXD; // non-zero if invert RXD - UCHAR InvertRTS; // non-zero if invert RTS - UCHAR InvertCTS; // non-zero if invert CTS - UCHAR InvertDTR; // non-zero if invert DTR - UCHAR InvertDSR; // non-zero if invert DSR - UCHAR InvertDCD; // non-zero if invert DCD - UCHAR InvertRI; // non-zero if invert RI - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - UCHAR RIsD2XX; // non-zero if using D2XX driver - // - // Rev 7 (FT2232H) Extensions - // - UCHAR PullDownEnable7; // non-zero if pull down enabled - UCHAR SerNumEnable7; // non-zero if serial number to be used - UCHAR ALSlowSlew; // non-zero if AL pins have slow slew - UCHAR ALSchmittInput; // non-zero if AL pins are Schmitt input - UCHAR ALDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR AHSlowSlew; // non-zero if AH pins have slow slew - UCHAR AHSchmittInput; // non-zero if AH pins are Schmitt input - UCHAR AHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BLSlowSlew; // non-zero if BL pins have slow slew - UCHAR BLSchmittInput; // non-zero if BL pins are Schmitt input - UCHAR BLDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BHSlowSlew; // non-zero if BH pins have slow slew - UCHAR BHSchmittInput; // non-zero if BH pins are Schmitt input - UCHAR BHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR IFAIsFifo7; // non-zero if interface is 245 FIFO - UCHAR IFAIsFifoTar7; // non-zero if interface is 245 FIFO CPU target - UCHAR IFAIsFastSer7; // non-zero if interface is Fast serial - UCHAR AIsVCP7; // non-zero if interface is to use VCP drivers - UCHAR IFBIsFifo7; // non-zero if interface is 245 FIFO - UCHAR IFBIsFifoTar7; // non-zero if interface is 245 FIFO CPU target - UCHAR IFBIsFastSer7; // non-zero if interface is Fast serial - UCHAR BIsVCP7; // non-zero if interface is to use VCP drivers - UCHAR PowerSaveEnable; // non-zero if using BCBUS7 to save power for self-powered designs - // - // Rev 8 (FT4232H) Extensions - // - UCHAR PullDownEnable8; // non-zero if pull down enabled - UCHAR SerNumEnable8; // non-zero if serial number to be used - UCHAR ASlowSlew; // non-zero if A pins have slow slew - UCHAR ASchmittInput; // non-zero if A pins are Schmitt input - UCHAR ADriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BSlowSlew; // non-zero if B pins have slow slew - UCHAR BSchmittInput; // non-zero if B pins are Schmitt input - UCHAR BDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR CSlowSlew; // non-zero if C pins have slow slew - UCHAR CSchmittInput; // non-zero if C pins are Schmitt input - UCHAR CDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR DSlowSlew; // non-zero if D pins have slow slew - UCHAR DSchmittInput; // non-zero if D pins are Schmitt input - UCHAR DDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR ARIIsTXDEN; // non-zero if port A uses RI as RS485 TXDEN - UCHAR BRIIsTXDEN; // non-zero if port B uses RI as RS485 TXDEN - UCHAR CRIIsTXDEN; // non-zero if port C uses RI as RS485 TXDEN - UCHAR DRIIsTXDEN; // non-zero if port D uses RI as RS485 TXDEN - UCHAR AIsVCP8; // non-zero if interface is to use VCP drivers - UCHAR BIsVCP8; // non-zero if interface is to use VCP drivers - UCHAR CIsVCP8; // non-zero if interface is to use VCP drivers - UCHAR DIsVCP8; // non-zero if interface is to use VCP drivers - // - // Rev 9 (FT232H) Extensions - // - UCHAR PullDownEnableH; // non-zero if pull down enabled - UCHAR SerNumEnableH; // non-zero if serial number to be used - UCHAR ACSlowSlewH; // non-zero if AC pins have slow slew - UCHAR ACSchmittInputH; // non-zero if AC pins are Schmitt input - UCHAR ACDriveCurrentH; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR ADSlowSlewH; // non-zero if AD pins have slow slew - UCHAR ADSchmittInputH; // non-zero if AD pins are Schmitt input - UCHAR ADDriveCurrentH; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR Cbus0H; // Cbus Mux control - UCHAR Cbus1H; // Cbus Mux control - UCHAR Cbus2H; // Cbus Mux control - UCHAR Cbus3H; // Cbus Mux control - UCHAR Cbus4H; // Cbus Mux control - UCHAR Cbus5H; // Cbus Mux control - UCHAR Cbus6H; // Cbus Mux control - UCHAR Cbus7H; // Cbus Mux control - UCHAR Cbus8H; // Cbus Mux control - UCHAR Cbus9H; // Cbus Mux control - UCHAR IsFifoH; // non-zero if interface is 245 FIFO - UCHAR IsFifoTarH; // non-zero if interface is 245 FIFO CPU target - UCHAR IsFastSerH; // non-zero if interface is Fast serial - UCHAR IsFT1248H; // non-zero if interface is FT1248 - UCHAR FT1248CpolH; // FT1248 clock polarity - clock idle high (1) or clock idle low (0) - UCHAR FT1248LsbH; // FT1248 data is LSB (1) or MSB (0) - UCHAR FT1248FlowControlH; // FT1248 flow control enable - UCHAR IsVCPH; // non-zero if interface is to use VCP drivers - UCHAR PowerSaveEnableH; // non-zero if using ACBUS7 to save power for self-powered designs - - } FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; - - FTD2XX_API - FT_STATUS WINAPI FT_EE_Program( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EE_ProgramEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EE_Read( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EE_ReadEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EE_UASize( - FT_HANDLE ftHandle, - LPDWORD lpdwSize - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EE_UAWrite( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EE_UARead( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen, - LPDWORD lpdwBytesRead - ); - - - typedef struct ft_eeprom_header { - FT_DEVICE deviceType; // FTxxxx device type to be programmed - // Device descriptor options - WORD VendorId; // 0x0403 - WORD ProductId; // 0x6001 - UCHAR SerNumEnable; // non-zero if serial number to be used - // Config descriptor options - WORD MaxPower; // 0 < MaxPower <= 500 - UCHAR SelfPowered; // 0 = bus powered, 1 = self powered - UCHAR RemoteWakeup; // 0 = not capable, 1 = capable - // Hardware options - UCHAR PullDownEnable; // non-zero if pull down in suspend enabled - } FT_EEPROM_HEADER, *PFT_EEPROM_HEADER; - - - // FT232B EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program - typedef struct ft_eeprom_232b { - // Common header - FT_EEPROM_HEADER common; // common elements for all device EEPROMs - } FT_EEPROM_232B, *PFT_EEPROM_232B; - - - // FT2232 EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program - typedef struct ft_eeprom_2232 { - // Common header - FT_EEPROM_HEADER common; // common elements for all device EEPROMs - // Drive options - UCHAR AIsHighCurrent; // non-zero if interface is high current - UCHAR BIsHighCurrent; // non-zero if interface is high current - // Hardware options - UCHAR AIsFifo; // non-zero if interface is 245 FIFO - UCHAR AIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR AIsFastSer; // non-zero if interface is Fast serial - UCHAR BIsFifo; // non-zero if interface is 245 FIFO - UCHAR BIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR BIsFastSer; // non-zero if interface is Fast serial - // Driver option - UCHAR ADriverType; // - UCHAR BDriverType; // - } FT_EEPROM_2232, *PFT_EEPROM_2232; - - - // FT232R EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program - typedef struct ft_eeprom_232r { - // Common header - FT_EEPROM_HEADER common; // common elements for all device EEPROMs - // Drive options - UCHAR IsHighCurrent; // non-zero if interface is high current - // Hardware options - UCHAR UseExtOsc; // Use External Oscillator - UCHAR InvertTXD; // non-zero if invert TXD - UCHAR InvertRXD; // non-zero if invert RXD - UCHAR InvertRTS; // non-zero if invert RTS - UCHAR InvertCTS; // non-zero if invert CTS - UCHAR InvertDTR; // non-zero if invert DTR - UCHAR InvertDSR; // non-zero if invert DSR - UCHAR InvertDCD; // non-zero if invert DCD - UCHAR InvertRI; // non-zero if invert RI - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - // Driver option - UCHAR DriverType; // - } FT_EEPROM_232R, *PFT_EEPROM_232R; - - - // FT2232H EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program - typedef struct ft_eeprom_2232h { - // Common header - FT_EEPROM_HEADER common; // common elements for all device EEPROMs - // Drive options - UCHAR ALSlowSlew; // non-zero if AL pins have slow slew - UCHAR ALSchmittInput; // non-zero if AL pins are Schmitt input - UCHAR ALDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR AHSlowSlew; // non-zero if AH pins have slow slew - UCHAR AHSchmittInput; // non-zero if AH pins are Schmitt input - UCHAR AHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BLSlowSlew; // non-zero if BL pins have slow slew - UCHAR BLSchmittInput; // non-zero if BL pins are Schmitt input - UCHAR BLDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BHSlowSlew; // non-zero if BH pins have slow slew - UCHAR BHSchmittInput; // non-zero if BH pins are Schmitt input - UCHAR BHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - // Hardware options - UCHAR AIsFifo; // non-zero if interface is 245 FIFO - UCHAR AIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR AIsFastSer; // non-zero if interface is Fast serial - UCHAR BIsFifo; // non-zero if interface is 245 FIFO - UCHAR BIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR BIsFastSer; // non-zero if interface is Fast serial - UCHAR PowerSaveEnable; // non-zero if using BCBUS7 to save power for self-powered designs - // Driver option - UCHAR ADriverType; // - UCHAR BDriverType; // - } FT_EEPROM_2232H, *PFT_EEPROM_2232H; - - - // FT4232H EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program - typedef struct ft_eeprom_4232h { - // Common header - FT_EEPROM_HEADER common; // common elements for all device EEPROMs - // Drive options - UCHAR ASlowSlew; // non-zero if A pins have slow slew - UCHAR ASchmittInput; // non-zero if A pins are Schmitt input - UCHAR ADriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BSlowSlew; // non-zero if B pins have slow slew - UCHAR BSchmittInput; // non-zero if B pins are Schmitt input - UCHAR BDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR CSlowSlew; // non-zero if C pins have slow slew - UCHAR CSchmittInput; // non-zero if C pins are Schmitt input - UCHAR CDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR DSlowSlew; // non-zero if D pins have slow slew - UCHAR DSchmittInput; // non-zero if D pins are Schmitt input - UCHAR DDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - // Hardware options - UCHAR ARIIsTXDEN; // non-zero if port A uses RI as RS485 TXDEN - UCHAR BRIIsTXDEN; // non-zero if port B uses RI as RS485 TXDEN - UCHAR CRIIsTXDEN; // non-zero if port C uses RI as RS485 TXDEN - UCHAR DRIIsTXDEN; // non-zero if port D uses RI as RS485 TXDEN - // Driver option - UCHAR ADriverType; // - UCHAR BDriverType; // - UCHAR CDriverType; // - UCHAR DDriverType; // - } FT_EEPROM_4232H, *PFT_EEPROM_4232H; - - - // FT232H EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program - typedef struct ft_eeprom_232h { - // Common header - FT_EEPROM_HEADER common; // common elements for all device EEPROMs - // Drive options - UCHAR ACSlowSlew; // non-zero if AC bus pins have slow slew - UCHAR ACSchmittInput; // non-zero if AC bus pins are Schmitt input - UCHAR ACDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR ADSlowSlew; // non-zero if AD bus pins have slow slew - UCHAR ADSchmittInput; // non-zero if AD bus pins are Schmitt input - UCHAR ADDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - // CBUS options - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - UCHAR Cbus5; // Cbus Mux control - UCHAR Cbus6; // Cbus Mux control - UCHAR Cbus7; // Cbus Mux control - UCHAR Cbus8; // Cbus Mux control - UCHAR Cbus9; // Cbus Mux control - // FT1248 options - UCHAR FT1248Cpol; // FT1248 clock polarity - clock idle high (1) or clock idle low (0) - UCHAR FT1248Lsb; // FT1248 data is LSB (1) or MSB (0) - UCHAR FT1248FlowControl; // FT1248 flow control enable - // Hardware options - UCHAR IsFifo; // non-zero if interface is 245 FIFO - UCHAR IsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IsFastSer; // non-zero if interface is Fast serial - UCHAR IsFT1248 ; // non-zero if interface is FT1248 - UCHAR PowerSaveEnable; // - // Driver option - UCHAR DriverType; // - } FT_EEPROM_232H, *PFT_EEPROM_232H; - - - // FT X Series EEPROM structure for use with FT_EEPROM_Read and FT_EEPROM_Program - typedef struct ft_eeprom_x_series { - // Common header - FT_EEPROM_HEADER common; // common elements for all device EEPROMs - // Drive options - UCHAR ACSlowSlew; // non-zero if AC bus pins have slow slew - UCHAR ACSchmittInput; // non-zero if AC bus pins are Schmitt input - UCHAR ACDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR ADSlowSlew; // non-zero if AD bus pins have slow slew - UCHAR ADSchmittInput; // non-zero if AD bus pins are Schmitt input - UCHAR ADDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - // CBUS options - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - UCHAR Cbus5; // Cbus Mux control - UCHAR Cbus6; // Cbus Mux control - // UART signal options - UCHAR InvertTXD; // non-zero if invert TXD - UCHAR InvertRXD; // non-zero if invert RXD - UCHAR InvertRTS; // non-zero if invert RTS - UCHAR InvertCTS; // non-zero if invert CTS - UCHAR InvertDTR; // non-zero if invert DTR - UCHAR InvertDSR; // non-zero if invert DSR - UCHAR InvertDCD; // non-zero if invert DCD - UCHAR InvertRI; // non-zero if invert RI - // Battery Charge Detect options - UCHAR BCDEnable; // Enable Battery Charger Detection - UCHAR BCDForceCbusPWREN; // asserts the power enable signal on CBUS when charging port detected - UCHAR BCDDisableSleep; // forces the device never to go into sleep mode - // I2C options - WORD I2CSlaveAddress; // I2C slave device address - DWORD I2CDeviceId; // I2C device ID - UCHAR I2CDisableSchmitt; // Disable I2C Schmitt trigger - // FT1248 options - UCHAR FT1248Cpol; // FT1248 clock polarity - clock idle high (1) or clock idle low (0) - UCHAR FT1248Lsb; // FT1248 data is LSB (1) or MSB (0) - UCHAR FT1248FlowControl; // FT1248 flow control enable - // Hardware options - UCHAR RS485EchoSuppress; // - UCHAR PowerSaveEnable; // - // Driver option - UCHAR DriverType; // - } FT_EEPROM_X_SERIES, *PFT_EEPROM_X_SERIES; - - - FTD2XX_API - FT_STATUS WINAPI FT_EEPROM_Read( - FT_HANDLE ftHandle, - void *eepromData, - DWORD eepromDataSize, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - - - FTD2XX_API - FT_STATUS WINAPI FT_EEPROM_Program( - FT_HANDLE ftHandle, - void *eepromData, - DWORD eepromDataSize, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - - - FTD2XX_API - FT_STATUS WINAPI FT_SetLatencyTimer( - FT_HANDLE ftHandle, - UCHAR ucLatency - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetLatencyTimer( - FT_HANDLE ftHandle, - PUCHAR pucLatency - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetBitMode( - FT_HANDLE ftHandle, - UCHAR ucMask, - UCHAR ucEnable - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetBitMode( - FT_HANDLE ftHandle, - PUCHAR pucMode - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetUSBParameters( - FT_HANDLE ftHandle, - ULONG ulInTransferSize, - ULONG ulOutTransferSize - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetDeadmanTimeout( - FT_HANDLE ftHandle, - ULONG ulDeadmanTimeout - ); - -#ifndef _WIN32 - // Extra functions for non-Windows platforms to compensate - // for lack of .INF file to specify Vendor and Product IDs. - - FTD2XX_API - FT_STATUS FT_SetVIDPID( - DWORD dwVID, - DWORD dwPID - ); - - FTD2XX_API - FT_STATUS FT_GetVIDPID( - DWORD * pdwVID, - DWORD * pdwPID - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetDeviceLocId( - FT_HANDLE ftHandle, - LPDWORD lpdwLocId - ); -#endif // _WIN32 - - FTD2XX_API - FT_STATUS WINAPI FT_GetDeviceInfo( - FT_HANDLE ftHandle, - FT_DEVICE *lpftDevice, - LPDWORD lpdwID, - PCHAR SerialNumber, - PCHAR Description, - LPVOID Dummy - ); - - FTD2XX_API - FT_STATUS WINAPI FT_StopInTask( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_RestartInTask( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_SetResetPipeRetryCount( - FT_HANDLE ftHandle, - DWORD dwCount - ); - - FTD2XX_API - FT_STATUS WINAPI FT_ResetPort( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_CyclePort( - FT_HANDLE ftHandle - ); - - - // - // Win32-type functions - // - - FTD2XX_API - FT_HANDLE WINAPI FT_W32_CreateFile( - LPCTSTR lpszName, - DWORD dwAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreate, - DWORD dwAttrsAndFlags, - HANDLE hTemplate - ); - - FTD2XX_API - BOOL WINAPI FT_W32_CloseHandle( - FT_HANDLE ftHandle - ); - - FTD2XX_API - BOOL WINAPI FT_W32_ReadFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - - FTD2XX_API - BOOL WINAPI FT_W32_WriteFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten, - LPOVERLAPPED lpOverlapped - ); - - FTD2XX_API - DWORD WINAPI FT_W32_GetLastError( - FT_HANDLE ftHandle - ); - - FTD2XX_API - BOOL WINAPI FT_W32_GetOverlappedResult( - FT_HANDLE ftHandle, - LPOVERLAPPED lpOverlapped, - LPDWORD lpdwBytesTransferred, - BOOL bWait - ); - - FTD2XX_API - BOOL WINAPI FT_W32_CancelIo( - FT_HANDLE ftHandle - ); - - - // - // Win32 COMM API type functions - // - typedef struct _FTCOMSTAT { - DWORD fCtsHold : 1; - DWORD fDsrHold : 1; - DWORD fRlsdHold : 1; - DWORD fXoffHold : 1; - DWORD fXoffSent : 1; - DWORD fEof : 1; - DWORD fTxim : 1; - DWORD fReserved : 25; - DWORD cbInQue; - DWORD cbOutQue; - } FTCOMSTAT, *LPFTCOMSTAT; - - typedef struct _FTDCB { - DWORD DCBlength; /* sizeof(FTDCB) */ - DWORD BaudRate; /* Baudrate at which running */ - DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ - DWORD fParity: 1; /* Enable parity checking */ - DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ - DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ - DWORD fDtrControl:2; /* DTR Flow control */ - DWORD fDsrSensitivity:1; /* DSR Sensitivity */ - DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ - DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ - DWORD fInX: 1; /* Enable input X-ON/X-OFF */ - DWORD fErrorChar: 1; /* Enable Err Replacement */ - DWORD fNull: 1; /* Enable Null stripping */ - DWORD fRtsControl:2; /* Rts Flow control */ - DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ - DWORD fDummy2:17; /* Reserved */ - WORD wReserved; /* Not currently used */ - WORD XonLim; /* Transmit X-ON threshold */ - WORD XoffLim; /* Transmit X-OFF threshold */ - BYTE ByteSize; /* Number of bits/byte, 4-8 */ - BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ - BYTE StopBits; /* FT_STOP_BITS_1 or FT_STOP_BITS_2 */ - char XonChar; /* Tx and Rx X-ON character */ - char XoffChar; /* Tx and Rx X-OFF character */ - char ErrorChar; /* Error replacement char */ - char EofChar; /* End of Input character */ - char EvtChar; /* Received Event character */ - WORD wReserved1; /* Fill for now. */ - } FTDCB, *LPFTDCB; - - typedef struct _FTTIMEOUTS { - DWORD ReadIntervalTimeout; /* Maximum time between read chars. */ - DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ - DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ - } FTTIMEOUTS,*LPFTTIMEOUTS; - - - FTD2XX_API - BOOL WINAPI FT_W32_ClearCommBreak( - FT_HANDLE ftHandle - ); - - FTD2XX_API - BOOL WINAPI FT_W32_ClearCommError( - FT_HANDLE ftHandle, - LPDWORD lpdwErrors, - LPFTCOMSTAT lpftComstat - ); - - FTD2XX_API - BOOL WINAPI FT_W32_EscapeCommFunction( - FT_HANDLE ftHandle, - DWORD dwFunc - ); - - FTD2XX_API - BOOL WINAPI FT_W32_GetCommModemStatus( - FT_HANDLE ftHandle, - LPDWORD lpdwModemStatus - ); - - FTD2XX_API - BOOL WINAPI FT_W32_GetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - - FTD2XX_API - BOOL WINAPI FT_W32_GetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - - FTD2XX_API - BOOL WINAPI FT_W32_PurgeComm( - FT_HANDLE ftHandle, - DWORD dwMask - ); - - FTD2XX_API - BOOL WINAPI FT_W32_SetCommBreak( - FT_HANDLE ftHandle - ); - - FTD2XX_API - BOOL WINAPI FT_W32_SetCommMask( - FT_HANDLE ftHandle, - ULONG ulEventMask - ); - - FTD2XX_API - BOOL WINAPI FT_W32_GetCommMask( - FT_HANDLE ftHandle, - LPDWORD lpdwEventMask - ); - - FTD2XX_API - BOOL WINAPI FT_W32_SetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - - FTD2XX_API - BOOL WINAPI FT_W32_SetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - - FTD2XX_API - BOOL WINAPI FT_W32_SetupComm( - FT_HANDLE ftHandle, - DWORD dwReadBufferSize, - DWORD dwWriteBufferSize - ); - - FTD2XX_API - BOOL WINAPI FT_W32_WaitCommEvent( - FT_HANDLE ftHandle, - PULONG pulEvent, - LPOVERLAPPED lpOverlapped - ); - - - // - // Device information - // - - typedef struct _ft_device_list_info_node { - ULONG Flags; - ULONG Type; - ULONG ID; - DWORD LocId; - char SerialNumber[16]; - char Description[64]; - FT_HANDLE ftHandle; - } FT_DEVICE_LIST_INFO_NODE; - - // Device information flags - enum { - FT_FLAGS_OPENED = 1, - FT_FLAGS_HISPEED = 2 - }; - - - FTD2XX_API - FT_STATUS WINAPI FT_CreateDeviceInfoList( - LPDWORD lpdwNumDevs - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetDeviceInfoList( - FT_DEVICE_LIST_INFO_NODE *pDest, - LPDWORD lpdwNumDevs - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetDeviceInfoDetail( - DWORD dwIndex, - LPDWORD lpdwFlags, - LPDWORD lpdwType, - LPDWORD lpdwID, - LPDWORD lpdwLocId, - LPVOID lpSerialNumber, - LPVOID lpDescription, - FT_HANDLE *pftHandle - ); - - - // - // Version information - // - - FTD2XX_API - FT_STATUS WINAPI FT_GetDriverVersion( - FT_HANDLE ftHandle, - LPDWORD lpdwVersion - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetLibraryVersion( - LPDWORD lpdwVersion - ); - - - FTD2XX_API - FT_STATUS WINAPI FT_Rescan( - void - ); - - FTD2XX_API - FT_STATUS WINAPI FT_Reload( - WORD wVid, - WORD wPid - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetComPortNumber( - FT_HANDLE ftHandle, - LPLONG lpdwComPortNumber - ); - - - // - // FT232H additional EEPROM functions - // - - FTD2XX_API - FT_STATUS WINAPI FT_EE_ReadConfig( - FT_HANDLE ftHandle, - UCHAR ucAddress, - PUCHAR pucValue - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EE_WriteConfig( - FT_HANDLE ftHandle, - UCHAR ucAddress, - UCHAR ucValue - ); - - FTD2XX_API - FT_STATUS WINAPI FT_EE_ReadECC( - FT_HANDLE ftHandle, - UCHAR ucOption, - LPWORD lpwValue - ); - - FTD2XX_API - FT_STATUS WINAPI FT_GetQueueStatusEx( - FT_HANDLE ftHandle, - DWORD *dwRxBytes - ); - - FTD2XX_API - FT_STATUS WINAPI FT_ComPortIdle( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_ComPortCancelIdle( - FT_HANDLE ftHandle - ); - - FTD2XX_API - FT_STATUS WINAPI FT_VendorCmdGet( - FT_HANDLE ftHandle, - UCHAR Request, - UCHAR *Buf, - USHORT Len - ); - - FTD2XX_API - FT_STATUS WINAPI FT_VendorCmdSet( - FT_HANDLE ftHandle, - UCHAR Request, - UCHAR *Buf, - USHORT Len - ); - - FTD2XX_API - FT_STATUS WINAPI FT_VendorCmdGetEx( - FT_HANDLE ftHandle, - USHORT wValue, - UCHAR *Buf, - USHORT Len - ); - - FTD2XX_API - FT_STATUS WINAPI FT_VendorCmdSetEx( - FT_HANDLE ftHandle, - USHORT wValue, - UCHAR *Buf, - USHORT Len - ); - -#ifdef __cplusplus -} -#endif - - -#endif /* FTD2XX_H */ - diff --git a/hostextra/d2xx/ftdi/eeprom.go b/hostextra/d2xx/ftdi/eeprom.go deleted file mode 100644 index 59e2952..0000000 --- a/hostextra/d2xx/ftdi/eeprom.go +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Package ftdi constains the low level common FTDI device information -// independent of the driver used, mostly EEPROM definitions. -package ftdi - -import ( - "fmt" - "unsafe" -) - -// EEPROM is the unprocessed EEPROM content. -// -// The EEPROM is in 3 parts: the defined struct, the 4 strings and the rest -// which is used as an 'user area'. The size of the user area depends on the -// length of the strings. The user area content is not included in this struct. -type EEPROM struct { - // Raw is the raw EEPROM content. It excludes the strings. - Raw []byte - - // The following condition must be true: len(Manufacturer) + len(Desc) <= 40. - Manufacturer string - ManufacturerID string - Desc string - Serial string -} - -func (e *EEPROM) AsHeader() *EEPROMHeader { - // sizeof(EEPROMHeader) - if len(e.Raw) < 16 { - return nil - } - return (*EEPROMHeader)(unsafe.Pointer(&e.Raw[0])) -} - -// AsFT232H returns the Raw data aliased as EEPROMFT232H. -func (e *EEPROM) AsFT232H() *EEPROMFT232H { - // sizeof(EEPROMFT232H) - if len(e.Raw) < 44 { - return nil - } - return (*EEPROMFT232H)(unsafe.Pointer(&e.Raw[0])) -} - -// AsFT2232H returns the Raw data aliased as EEPROMFT2232H. -func (e *EEPROM) AsFT2232H() *EEPROMFT2232H { - // sizeof(EEPROMFT2232H) - if len(e.Raw) < 40 { - return nil - } - return (*EEPROMFT2232H)(unsafe.Pointer(&e.Raw[0])) -} - -// AsFT232R returns the Raw data aliased as EEPROMFT232R. -func (e *EEPROM) AsFT232R() *EEPROMFT232R { - // sizeof(EEPROMFT232R) - if len(e.Raw) < 32 { - return nil - } - return (*EEPROMFT232R)(unsafe.Pointer(&e.Raw[0])) -} - -// FT232hCBusMux is stored in the FT232H EEPROM to control each CBus pin. -type FT232hCBusMux uint8 - -const ( - // TriSt-PU; Sets in Tristate (pull up) (C0~C6, C8, C9) on 75kΩ. - FT232hCBusTristatePullUp FT232hCBusMux = 0x00 - // TXLED#; Pulses low when transmitting data (C0~C6, C8, C9). - FT232hCBusTxLED FT232hCBusMux = 0x01 - // RXLED#; Pulses low when receiving data (C0~C6, C8, C9). - FT232hCBusRxLED FT232hCBusMux = 0x02 - // TX&RXLED#; Pulses low when either receiving or transmitting data (C0~C6, - // C8, C9). - FT232hCBusTxRxLED FT232hCBusMux = 0x03 - // PWREN#; Output is low after the device has been configured by USB, then - // high during USB suspend mode (C0~C6, C8, C9). - // - // Must be used with an external 10kΩ pull up. - FT232hCBusPwrEnable FT232hCBusMux = 0x04 - // SLEEP#; Goes low during USB suspend mode (C0~C6, C8, C9). - FT232hCBusSleep FT232hCBusMux = 0x05 - // DRIVE1; Drives pin to logic 0 (C0~C6, C8, C9). - FT232hCBusDrive0 FT232hCBusMux = 0x06 - // DRIVE1; Drives pin to logic 1 (C0, C5, C6, C8, C9). - FT232hCBusDrive1 FT232hCBusMux = 0x07 - // I/O Mode; CBus bit-bang mode option (C5, C6, C8, C9). - FT232hCBusIOMode FT232hCBusMux = 0x08 - // TXDEN; Tx Data Enable. Used with RS485 level converters to enable the line - // driver during data transmit. It is active one bit time before the start - // bit up to until the end of the stop bit (C0~C6, C8, C9). - FT232hCBusTxdEnable FT232hCBusMux = 0x09 - // CLK30 30MHz clock output (C0, C5, C6, C8, C9). - FT232hCBusClk30 FT232hCBusMux = 0x0A - // CLK15 15MHz clock output (C0, C5, C6, C8, C9). - FT232hCBusClk15 FT232hCBusMux = 0x0B - // CLK7.5 7.5MHz clock output (C0, C5, C6, C8, C9). - FT232hCBusClk7_5 FT232hCBusMux = 0x0C -) - -const ft232hCBusMuxName = "FT232hCBusTristatePullUpFT232hCBusTxLEDFT232hCBusRxLEDFT232hCBusTxRxLEDFT232hCBusPwrEnableFT232hCBusSleepFT232hCBusDrive0FT232hCBusDrive1FT232hCBusIOModeFT232hCBusTxdEnableFT232hCBusClk30FT232hCBusClk15FT232hCBusClk7_5" - -var fr232hCBusMuxIndex = [...]uint8{0, 24, 39, 54, 71, 90, 105, 121, 137, 153, 172, 187, 202, 218} - -func (f FT232hCBusMux) String() string { - if f >= FT232hCBusMux(len(fr232hCBusMuxIndex)-1) { - return fmt.Sprintf("FT232hCBusMux(%d)", f) - } - return ft232hCBusMuxName[fr232hCBusMuxIndex[f]:fr232hCBusMuxIndex[f+1]] -} - -// FT232rCBusMux is stored in the FT232R EEPROM to control each CBus pin. -type FT232rCBusMux uint8 - -const ( - // TXDEN; Tx Data Enable. Used with RS485 level converters to enable the line - // driver during data transmit. It is active one bit time before the start - // bit up to until the end of the stop bit (C0~C4). - FT232rCBusTxdEnable FT232rCBusMux = 0x00 - // PWREN#; Output is low after the device has been configured by USB, then - // high during USB suspend mode (C0~C4). - // - // Must be used with an external 10kΩ pull up. - FT232rCBusPwrEnable FT232rCBusMux = 0x01 - // RXLED#; Pulses low when receiving data (C0~C4). - FT232rCBusRxLED FT232rCBusMux = 0x02 - // TXLED#; Pulses low when transmitting data (C0~C4). - FT232rCBusTxLED FT232rCBusMux = 0x03 - // TX&RXLED#; Pulses low when either receiving or transmitting data (C0~C4). - FT232rCBusTxRxLED FT232rCBusMux = 0x04 - // SLEEP# Goes low during USB suspend mode (C0~C4). - FT232rCBusSleep FT232rCBusMux = 0x05 - // CLK48 48Mhz +/-0.7% clock output (C0~C4). - FT232rCBusClk48 FT232rCBusMux = 0x06 - // CLK24 24Mhz clock output (C0~C4). - FT232rCBusClk24 FT232rCBusMux = 0x07 - // CLK12 12Mhz clock output (C0~C4). - FT232rCBusClk12 FT232rCBusMux = 0x08 - // CLK6 6Mhz +/-0.7% clock output (C0~C4). - FT232rCBusClk6 FT232rCBusMux = 0x09 - // CBitBangI/O; CBus bit-bang mode option (C0~C3). - FT232rCBusIOMode FT232rCBusMux = 0x0A - // BitBangWRn; CBus WR# strobe output (C0~C3). - FT232rCBusBitBangWR FT232rCBusMux = 0x0B - // BitBangRDn; CBus RD# strobe output (C0~C3). - FT232rCBusBitBangRD FT232rCBusMux = 0x0C -) - -const ft232rCBusMuxName = "FT232rCBusTxdEnableFT232rCBusPwrEnableFT232rCBusRxLEDFT232rCBusTxLEDFT232rCBusTxRxLEDFT232rCBusSleepFT232rCBusClk48FT232rCBusClk24FT232rCBusClk12FT232rCBusClk6FT232rCBusIOModeFT232rCBusBitBangWRFT232rCBusBitBangRD" - -var ft232rCBusMuxIndex = [...]uint8{0, 19, 38, 53, 68, 85, 100, 115, 130, 145, 159, 175, 194, 213} - -func (f FT232rCBusMux) String() string { - if f >= FT232rCBusMux(len(ft232rCBusMuxIndex)-1) { - return fmt.Sprintf("FT232rCBusMux(%d)", f) - } - return ft232rCBusMuxName[ft232rCBusMuxIndex[f]:ft232rCBusMuxIndex[f+1]] -} - -// EEPROMHeader is the common header found on FTDI devices. -// -// It is 16 bytes long. -type EEPROMHeader struct { - DeviceType DevType // 0x00 FTxxxx device type to be programmed - VendorID uint16 // 0x04 Defaults to 0x0403; can be changed - ProductID uint16 // 0x06 Defaults to 0x6001 for FT232R, 0x6014 for FT232H, relevant value - SerNumEnable uint8 // 0x07 bool Non-zero if serial number to be used - Unused0 uint8 // 0x08 For alignment. - MaxPower uint16 // 0x0A 0mA < MaxPower <= 500mA - SelfPowered uint8 // 0x0C bool 0 = bus powered, 1 = self powered - RemoteWakeup uint8 // 0x0D bool 0 = not capable, 1 = capable; RI# low will wake host in 20ms. - PullDownEnable uint8 // 0x0E bool Non zero if pull down in suspend enabled - Unused1 uint8 // 0x0F For alignment. -} - -// EEPROMFT232H is the EEPROM layout of a FT232H device. -// -// It is 44 bytes long. -type EEPROMFT232H struct { - EEPROMHeader - - // FT232H specific. - ACSlowSlew uint8 // 0x10 bool Non-zero if AC bus pins have slow slew - ACSchmittInput uint8 // 0x11 bool Non-zero if AC bus pins are Schmitt input - ACDriveCurrent uint8 // 0x12 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units - ADSlowSlew uint8 // 0x13 bool Non-zero if AD bus pins have slow slew - ADSchmittInput uint8 // 0x14 bool Non-zero if AD bus pins are Schmitt input - ADDriveCurrent uint8 // 0x15 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units - Cbus0 FT232hCBusMux // 0x16 - Cbus1 FT232hCBusMux // 0x17 - Cbus2 FT232hCBusMux // 0x18 - Cbus3 FT232hCBusMux // 0x19 - Cbus4 FT232hCBusMux // 0x1A - Cbus5 FT232hCBusMux // 0x1B - Cbus6 FT232hCBusMux // 0x1C - Cbus7 FT232hCBusMux // 0x1D C7 is limited a sit can only do 'suspend on C7 low'. Defaults pull down. - Cbus8 FT232hCBusMux // 0x1E - Cbus9 FT232hCBusMux // 0x1F - FT1248Cpol uint8 // 0x20 bool FT1248 clock polarity - clock idle high (true) or clock idle low (false) - FT1248Lsb uint8 // 0x21 bool FT1248 data is LSB (true), or MSB (false) - FT1248FlowControl uint8 // 0x22 bool FT1248 flow control enable - IsFifo uint8 // 0x23 bool Non-zero if Interface is 245 FIFO - IsFifoTar uint8 // 0x24 bool Non-zero if Interface is 245 FIFO CPU target - IsFastSer uint8 // 0x25 bool Non-zero if Interface is Fast serial - IsFT1248 uint8 // 0x26 bool Non-zero if Interface is FT1248 - PowerSaveEnable uint8 // 0x27 bool Suspect on ACBus7 low. - DriverType uint8 // 0x28 bool 0 is D2XX, 1 is VCP - Unused2 uint8 // 0x29 - Unused3 uint16 // 0x30 -} - -func (e *EEPROMFT232H) Defaults() { - // As found on Adafruit device. - e.ACDriveCurrent = 4 - e.ADDriveCurrent = 4 - e.Cbus0 = FT232hCBusTristatePullUp - e.Cbus1 = FT232hCBusTristatePullUp - e.Cbus2 = FT232hCBusTristatePullUp - e.Cbus3 = FT232hCBusTristatePullUp - e.Cbus4 = FT232hCBusTristatePullUp - e.Cbus5 = FT232hCBusTristatePullUp - e.Cbus6 = FT232hCBusTristatePullUp - e.Cbus7 = FT232hCBusTristatePullUp - e.Cbus8 = FT232hCBusDrive1 - e.Cbus9 = FT232hCBusDrive0 -} - -// EEPROMFT2232H is the EEPROM layout of a FT2232H device. -// -// It is 40 bytes long. -type EEPROMFT2232H struct { - EEPROMHeader - - // FT232H specific. - ALSlowSlew uint8 // 0x10 bool non-zero if AL pins have slow slew - ALSchmittInput uint8 // 0x11 bool non-zero if AL pins are Schmitt input - ALDriveCurrent uint8 // 0x12 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units - AHSlowSlew uint8 // 0x13 bool non-zero if AH pins have slow slew - AHSchmittInput uint8 // 0x14 bool non-zero if AH pins are Schmitt input - AHDriveCurrent uint8 // 0x15 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units - BLSlowSlew uint8 // 0x16 bool non-zero if BL pins have slow slew - BLSchmittInput uint8 // 0x17 bool non-zero if BL pins are Schmitt input - BLDriveCurrent uint8 // 0x18 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units - BHSlowSlew uint8 // 0x19 bool non-zero if BH pins have slow slew - BHSchmittInput uint8 // 0x1A bool non-zero if BH pins are Schmitt input - BHDriveCurrent uint8 // 0x1B Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units - AIsFifo uint8 // 0x1C bool non-zero if interface is 245 FIFO - AIsFifoTar uint8 // 0x1D bool non-zero if interface is 245 FIFO CPU target - AIsFastSer uint8 // 0x1E bool non-zero if interface is Fast serial - BIsFifo uint8 // 0x1F bool non-zero if interface is 245 FIFO - BIsFifoTar uint8 // 0x20 bool non-zero if interface is 245 FIFO CPU target - BIsFastSer uint8 // 0x21 bool non-zero if interface is Fast serial - PowerSaveEnable uint8 // 0x22 bool non-zero if using BCBUS7 to save power for self-powered designs - ADriverType uint8 // 0x23 bool - BDriverType uint8 // 0x24 bool - Unused2 uint8 // 0x25 - Unused3 uint16 // 0x26 -} - -// EEPROMFT232R is the EEPROM layout of a FT232R device. -// -// It is 32 bytes long. -type EEPROMFT232R struct { - EEPROMHeader - - // FT232R specific. - IsHighCurrent uint8 // 0x10 bool High Drive I/Os; 3mA instead of 1mA (@3.3V) - UseExtOsc uint8 // 0x11 bool Use external oscillator - InvertTXD uint8 // 0x12 bool - InvertRXD uint8 // 0x13 bool - InvertRTS uint8 // 0x14 bool - InvertCTS uint8 // 0x15 bool - InvertDTR uint8 // 0x16 bool - InvertDSR uint8 // 0x17 bool - InvertDCD uint8 // 0x18 bool - InvertRI uint8 // 0x19 bool - Cbus0 FT232rCBusMux // 0x1A Default ft232rCBusTxLED - Cbus1 FT232rCBusMux // 0x1B Default ft232rCBusRxLED - Cbus2 FT232rCBusMux // 0x1C Default ft232rCBusTxdEnable - Cbus3 FT232rCBusMux // 0x1D Default ft232rCBusPwrEnable - Cbus4 FT232rCBusMux // 0x1E Default ft232rCBusSleep - DriverType uint8 // 0x1F bool 0 is D2XX, 1 is VCP -} - -func (e *EEPROMFT232R) Defaults() { - // As found on Adafruit device. - e.Cbus0 = FT232rCBusTxLED - e.Cbus1 = FT232rCBusRxLED - e.Cbus2 = FT232rCBusTxdEnable - e.Cbus3 = FT232rCBusPwrEnable - e.Cbus4 = FT232rCBusSleep - e.DriverType = 1 -} - -// - -// DevType is the FTDI device type. -type DevType uint32 - -const ( - FTBM DevType = iota // 0 - FTAM - FT100AX - Unknown // 3 - FT2232C - FT232R // 5 - FT2232H - FT4232H - FT232H // 8 - FTXSeries - FT4222H0 - FT4222H1_2 - FT4222H3 - FT4222Prog - FT900 - FT930 - FTUMFTPD3A -) - -// EEPROMSize returns the size of the EEPROM for this device. -func (d DevType) EEPROMSize() int { - switch d { - case FT232H: - // sizeof(EEPROMFT232H) - return 44 - case FT2232H: - // sizeof(EEPROMFT2232H) - return 40 - case FT232R: - // sizeof(EEPROMFT232R) - return 32 - default: - return 256 - } -} - -const devTypeName = "FTBMFTAMFT100AXUnknownFT2232CFT232RFT2232HFT4232HFT232HFTXSeriesFT4222H0FT4222H1/2FT4222H3FT4222ProgFT900FT930FTUMFTPD3A" - -var devTypeIndex = [...]uint8{0, 4, 8, 15, 22, 29, 35, 42, 49, 55, 64, 72, 82, 90, 100, 105, 110, 120} - -func (d DevType) String() string { - if d >= DevType(len(devTypeIndex)-1) { - d = Unknown - } - return devTypeName[devTypeIndex[d]:devTypeIndex[d+1]] -} diff --git a/hostextra/d2xx/gpio.go b/hostextra/d2xx/gpio.go deleted file mode 100644 index 875f3e9..0000000 --- a/hostextra/d2xx/gpio.go +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Emulate independent GPIOs. - -package d2xx - -import ( - "errors" - "time" - - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/physic" -) - -// dbusSync is the handler of a synchronous bitbang on DBus. -// -// More details at: -// http://www.ftdichip.com/Support/Documents/AppNotes/AN_232R-01_Bit_Bang_Mode_Available_For_FT232R_and_Ft245R.pdf -type dbusSync interface { - dbusSyncGPIOFunc(n int) string - dbusSyncGPIOIn(n int) error - dbusSyncGPIORead(n int) gpio.Level - dbusSyncGPIOOut(n int, l gpio.Level) error -} - -// dbusPinSync represents a GPIO on a synchronous bitbang DBus. -// -// It is immutable and stateless. -type dbusPinSync struct { - n string - num int - bus dbusSync -} - -// String implements conn.Resource. -func (s *dbusPinSync) String() string { - return s.n -} - -// Halt implements conn.Resource. -func (s *dbusPinSync) Halt() error { - return nil -} - -// Name implements pin.Pin. -func (s *dbusPinSync) Name() string { - return s.n -} - -// Number implements pin.Pin. -func (s *dbusPinSync) Number() int { - return s.num -} - -// Function implements pin.Pin. -func (s *dbusPinSync) Function() string { - return s.bus.dbusSyncGPIOFunc(s.num) -} - -// In implements gpio.PinIn. -func (s *dbusPinSync) In(pull gpio.Pull, e gpio.Edge) error { - if e != gpio.NoEdge { - // We could support it on D5. - return errors.New("d2xx: edge triggering is not supported") - } - if pull != gpio.PullUp && pull != gpio.PullNoChange { - // EEPROM has a PullDownEnable flag. - return errors.New("d2xx: pull is not supported") - } - return s.bus.dbusSyncGPIOIn(s.num) -} - -// Read implements gpio.PinIn. -func (s *dbusPinSync) Read() gpio.Level { - return s.bus.dbusSyncGPIORead(s.num) -} - -// WaitForEdge implements gpio.PinIn. -func (s *dbusPinSync) WaitForEdge(t time.Duration) bool { - return false -} - -// DefaultPull implements gpio.PinIn. -func (s *dbusPinSync) DefaultPull() gpio.Pull { - // 200kΩ - // http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf - // p. 24 - return gpio.PullUp -} - -// Pull implements gpio.PinIn. -func (s *dbusPinSync) Pull() gpio.Pull { - return gpio.PullUp -} - -// Out implements gpio.PinOut. -func (s *dbusPinSync) Out(l gpio.Level) error { - return s.bus.dbusSyncGPIOOut(s.num, l) -} - -// PWM implements gpio.PinOut. -func (s *dbusPinSync) PWM(d gpio.Duty, f physic.Frequency) error { - return errors.New("d2xx: not implemented") -} - -/* -func (s *dbusPinSync) Drive() physic.ElectricCurrent { - // optionally 3 - //return s.bus.ee.DDriveCurrent * physic.MilliAmpere - return physic.MilliAmpere -} - -func (s *dbusPinSync) SlewLimit() bool { - //return s.bus.ee.DSlowSlew - return false -} - -func (s *dbusPinSync) Hysteresis() bool { - //return s.bus.ee.DSchmittInput - return true -} -*/ - -// - -// cBusGPIO is the handler of a CBus bitbang bus. -// -// This is an asynchronous mode. -// -// More details at: -// http://www.ftdichip.com/Support/Knowledgebase/index.html?cbusbitbangmode.htm -type cBusGPIO interface { - cBusGPIOFunc(n int) string - cBusGPIOIn(n int) error - cBusGPIORead(n int) gpio.Level - cBusGPIOOut(n int, l gpio.Level) error -} - -// cbusPin represents a GPIO on a CBus bitbang bus. -// -// It is immutable and stateless. -type cbusPin struct { - n string - num int - p gpio.Pull - bus cBusGPIO -} - -// String implements conn.Resource. -func (c *cbusPin) String() string { - return c.n -} - -// Halt implements conn.Resource. -func (c *cbusPin) Halt() error { - return nil -} - -// Name implements pin.Pin. -func (c *cbusPin) Name() string { - return c.n -} - -// Number implements pin.Pin. -func (c *cbusPin) Number() int { - return c.num -} - -// Function implements pin.Pin. -func (c *cbusPin) Function() string { - return c.bus.cBusGPIOFunc(c.num) -} - -// In implements gpio.PinIn. -func (c *cbusPin) In(pull gpio.Pull, e gpio.Edge) error { - if e != gpio.NoEdge { - // We could support it on D5. - return errors.New("d2xx: edge triggering is not supported") - } - if pull != c.p && pull != gpio.PullNoChange { - // EEPROM has a PullDownEnable flag. - return errors.New("d2xx: pull is not supported") - } - return c.bus.cBusGPIOIn(c.num) -} - -// Read implements gpio.PinIn. -func (c *cbusPin) Read() gpio.Level { - return c.bus.cBusGPIORead(c.num) -} - -// WaitForEdge implements gpio.PinIn. -func (c *cbusPin) WaitForEdge(t time.Duration) bool { - return false -} - -// DefaultPull implements gpio.PinIn. -func (c *cbusPin) DefaultPull() gpio.Pull { - // 200kΩ - // http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf - // p. 24 - return c.p -} - -// Pull implements gpio.PinIn. -func (c *cbusPin) Pull() gpio.Pull { - return c.p -} - -// Out implements gpio.PinOut. -func (c *cbusPin) Out(l gpio.Level) error { - return c.bus.cBusGPIOOut(c.num, l) -} - -// PWM implements gpio.PinOut. -func (c *cbusPin) PWM(d gpio.Duty, f physic.Frequency) error { - return errors.New("d2xx: not implemented") -} - -/* -func (c *cbusPin) Drive() physic.ElectricCurrent { - // optionally 3 - //return c.bus.ee.CDriveCurrent * physic.MilliAmpere - return physic.MilliAmpere -} - -func (c *cbusPin) SlewLimit() bool { - //return c.bus.ee.CSlowSlew - return false -} - -func (c *cbusPin) Hysteresis() bool { - //return c.bus.ee.CSchmittInput - return true -} -*/ - -var _ gpio.PinIO = &dbusPinSync{} -var _ gpio.PinIO = &cbusPin{} diff --git a/hostextra/d2xx/i2c.go b/hostextra/d2xx/i2c.go deleted file mode 100644 index 7e92dea..0000000 --- a/hostextra/d2xx/i2c.go +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// This functionality requires MPSSE. -// -// Interfacing I²C: -// http://www.ftdichip.com/Support/Documents/AppNotes/AN_113_FTDI_Hi_Speed_USB_To_I2C_Example.pdf -// -// Implementation based on -// http://www.ftdichip.com/Support/Documents/AppNotes/AN_255_USB%20to%20I2C%20Example%20using%20the%20FT232H%20and%20FT201X%20devices.pdf -// -// Page 18: MPSSE does not automatically support clock stretching for I²C. - -package d2xx - -import ( - "errors" - "fmt" - - "periph.io/x/periph/conn" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/i2c" - "periph.io/x/periph/conn/physic" -) - -const i2cSCL = 1 // D0 -const i2cSDAOut = 2 // D1 -const i2cSDAIn = 4 // D2 - -type i2cBus struct { - f *FT232H - pullUp bool -} - -// Close stops I²C mode, returns to high speed mode, disable tri-state. -func (d *i2cBus) Close() error { - d.f.mu.Lock() - err := d.stopI2C() - d.f.mu.Unlock() - return err -} - -// Duplex implements conn.Conn. -func (d *i2cBus) Duplex() conn.Duplex { - return conn.Half -} - -func (d *i2cBus) String() string { - return d.f.String() -} - -// SetSpeed implements i2c.Bus. -func (d *i2cBus) SetSpeed(f physic.Frequency) error { - if f > 10*physic.MegaHertz { - return fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 10MHz", f) - } - if f < 100*physic.Hertz { - return fmt.Errorf("d2xx: invalid speed %s; minimum supported clock is 100Hz; did you forget to multiply by physic.KiloHertz?", f) - } - d.f.mu.Lock() - defer d.f.mu.Unlock() - _, err := d.f.h.mpsseClock(f * 2 / 3) - return err -} - -// Tx implements i2c.Bus. -func (d *i2cBus) Tx(addr uint16, w, r []byte) error { - d.f.mu.Lock() - defer d.f.mu.Unlock() - if err := d.setI2CStart(); err != nil { - return err - } - a := [1]byte{byte(addr)} - if err := d.writeBytes(a[:]); err != nil { - return err - } - if len(w) != 0 { - if err := d.writeBytes(w); err != nil { - return err - } - } - if len(r) != 0 { - if err := d.readBytes(r); err != nil { - return err - } - } - if err := d.setI2CStop(); err != nil { - return err - } - return d.setI2CLinesIdle() -} - -// SCL implements i2c.Pins. -func (d *i2cBus) SCL() gpio.PinIO { - return d.f.D0 -} - -// SDA implements i2c.Pins. -func (d *i2cBus) SDA() gpio.PinIO { - return d.f.D1 -} - -// setupI2C initializes the MPSSE to the state to run an I²C transaction. -// -// Defaults to 400kHz. -// -// When pullUp is true; output alternates between Out(Low) and In(PullUp). -// -// when pullUp is false; pins are set in Tristate so Out(High) becomes float -// instead of drive High. Low still drives low. That's called open collector. -func (d *i2cBus) setupI2C(pullUp bool) error { - if pullUp { - return errors.New("d2xx: PullUp will soon be implemented") - } - // TODO(maruel): We could set these only *during* the I²C operation, which - // would make more sense. - f := 400 * physic.KiloHertz - clk := ((30 * physic.MegaHertz / f) - 1) * 2 / 3 - - buf := [4 + 3]byte{ - clock3Phase, - clock30MHz, byte(clk), byte(clk >> 8), - } - cmd := buf[:4] - if !d.pullUp { - // TODO(maruel): Do not mess with other GPIOs tristate. - cmd = append(cmd, dataTristate, 7, 0) - } - if err := d.f.h.writeAll(cmd); err != nil { - return err - } - d.f.usingI2C = true - d.pullUp = pullUp - return d.setI2CLinesIdle() -} - -// stopI2C resets the MPSSE to a more "normal" state. -func (d *i2cBus) stopI2C() error { - // Resets to 30MHz. - buf := [4 + 3]byte{ - clock2Phase, - clock30MHz, 0, 0, - } - cmd := buf[:4] - if !d.pullUp { - // TODO(maruel): Do not mess with other GPIOs tristate. - cmd = append(cmd, dataTristate, 0, 0) - } - err := d.f.h.writeAll(cmd) - d.f.usingI2C = false - return err -} - -// setI2CLinesIdle sets all D0 and D1 lines high. -// -// Does not touch D3~D7. -func (d *i2cBus) setI2CLinesIdle() error { - const mask = 0xFF &^ (i2cSCL | i2cSDAOut | i2cSDAIn) - // TODO(maruel): d.pullUp - d.f.dbus.direction = d.f.dbus.direction&mask | i2cSCL | i2cSDAOut - d.f.dbus.value = d.f.dbus.value & mask - cmd := [...]byte{gpioSetD, d.f.dbus.value | i2cSCL | i2cSDAOut, d.f.dbus.direction} - return d.f.h.writeAll(cmd[:]) -} - -// setI2CStart starts an I²C transaction. -// -// Does not touch D3~D7. -func (d *i2cBus) setI2CStart() error { - // TODO(maruel): d.pullUp - dir := d.f.dbus.direction - v := d.f.dbus.value - // Assumes last setup was d.setI2CLinesIdle(), e.g. D0 and D1 are high, so - // skip this. - // - // Runs the command 4 times as a way to delay execution. - cmd := [...]byte{ - // SCL high, SDA low for 600ns - gpioSetD, v | i2cSCL, dir, - gpioSetD, v | i2cSCL, dir, - gpioSetD, v | i2cSCL, dir, - gpioSetD, v | i2cSCL, dir, - // SCL low, SDA low - gpioSetD, v, dir, - gpioSetD, v, dir, - gpioSetD, v, dir, - } - return d.f.h.writeAll(cmd[:]) -} - -// setI2CStop completes an I²C transaction. -// -// Does not touch D3~D7. -func (d *i2cBus) setI2CStop() error { - // TODO(maruel): d.pullUp - dir := d.f.dbus.direction - v := d.f.dbus.value - // Runs the command 4 times as a way to delay execution. - cmd := [...]byte{ - // SCL low, SDA low - gpioSetD, v, dir, - gpioSetD, v, dir, - gpioSetD, v, dir, - gpioSetD, v, dir, - // SCL high, SDA low - gpioSetD, v | i2cSCL, dir, - gpioSetD, v | i2cSCL, dir, - gpioSetD, v | i2cSCL, dir, - gpioSetD, v | i2cSCL, dir, - // SCL high, SDA high - gpioSetD, v | i2cSCL | i2cSDAOut, dir, - gpioSetD, v | i2cSCL | i2cSDAOut, dir, - gpioSetD, v | i2cSCL | i2cSDAOut, dir, - gpioSetD, v | i2cSCL | i2cSDAOut, dir, - } - return d.f.h.writeAll(cmd[:]) -} - -// writeBytes writes multiple bytes within an I²C transaction. -// -// Does not touch D3~D7. -func (d *i2cBus) writeBytes(w []byte) error { - // TODO(maruel): d.pullUp - dir := d.f.dbus.direction - v := d.f.dbus.value - // TODO(maruel): WAT? - if err := d.f.h.flushPending(); err != nil { - return err - } - // TODO(maruel): Implement both with and without NAK check. - var r [1]byte - cmd := [...]byte{ - // Data out, the 0 will be replaced with the byte. - dataOut | dataOutFall, 0, 0, 0, - // Set back to idle. - gpioSetD, v | i2cSCL | i2cSDAOut, dir, - // Read ACK/NAK. - dataIn | dataBit, 0, - flush, - } - for _, c := range w { - cmd[3] = c - if err := d.f.h.writeAll(cmd[:]); err != nil { - return err - } - if err := d.f.h.readAll(r[:]); err != nil { - return err - } - if r[0]&1 == 0 { - return errors.New("got NAK") - } - } - return nil -} - -// readBytes reads multiple bytes within an I²C transaction. -// -// Does not touch D3~D7. -func (d *i2cBus) readBytes(r []byte) error { - // TODO(maruel): d.pullUp - dir := d.f.dbus.direction - v := d.f.dbus.value - - cmd := [...]byte{ - // Read 8 bits. - dataIn | dataBit, 7, - // Send ACK/NAK. - dataOut | dataOutFall | dataBit, 0, 0, - // Set back to idle. - gpioSetD, v | i2cSCL | i2cSDAOut, dir, - // Force read buffer flush. This is only necessary if NAK are not ignored. - flush, - } - for i := range r { - if i == len(r)-1 { - // NAK. - cmd[4] = 0x80 - } - if err := d.f.h.writeAll(cmd[:]); err != nil { - return err - } - if err := d.f.h.readAll(r[i:1]); err != nil { - return err - } - } - return nil -} - -var _ i2c.BusCloser = &i2cBus{} -var _ i2c.Pins = &i2cBus{} diff --git a/hostextra/d2xx/jtag.go b/hostextra/d2xx/jtag.go deleted file mode 100644 index dfccc5d..0000000 --- a/hostextra/d2xx/jtag.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// This functionality requires MPSSE. -// -// Interfacing JTAG: -// http://www.ftdichip.com/Support/Documents/AppNotes/AN_129_FTDI_Hi_Speed_USB_To_JTAG_Example.pdf - -package d2xx diff --git a/hostextra/d2xx/linux_amd64/libftd2xx.a b/hostextra/d2xx/linux_amd64/libftd2xx.a deleted file mode 100644 index 5d7b3366e8b76438cfe6f9b9b910f6f67fa752a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 403410 zcmeEv4SZcymG4Q?(hojv`L0qWNWr3|^o!Ek7H*r|atlox+6Ib%$!&7e2J+?2z5PH6 z!6e%2B^rI=6bH5QM8z4#$2ig!R7^{4G7h6ft5%2SM2(tEsz$65pwRbUYp;FoIw$A! z!x?Ahy*KCgyZ7$>Uu&~@s&p6K1_XmF#u5_IL{`^^NP*C{Sj^`8kfKx!9OTRq&GyT&} z!Jq5%?jJh^C;Pnrey2cxa?suXd1RMU@TY!Wx!WoDclZ=W{^3n|huTJ4h8AayC6*@A31TfxZmO$Jngk%GA+W`%Zfa~vr!v*) z(%Dn)Z%fsslVzFubluvGsbr$Y#nwPt zeKHSnYLg@JxY;jntZniDE1Ig8*EpL=Ze`k)xvDwY7~4XO6rx|!z{qQ%C<<`v^3w9< zr6MdJDXDL2NfNqR>qo%yrjm5MBrdJnRM*m!lGxHjre<{_&B-8{ELO5HkxEpjlPTm| zS8elLR^PN47KD*pL1`9JQlBa{A*5fOW`1B2Lh;L*YLX3W(us7&%Ay=NT%Jj7uvxFI zYe+U_OnRicC6mk~^QpXuF%a^LZAvz#S2m^VYU`>K)Hnlg>tP7U0Y;z-HX z>iT54L~ffio7>c~x_Z`(;w3OmI_W{E5ycaYHF+j#PMU?gf(BrORhyEj`b2YcvIYvE zm#{f0gG6I>vVJ+Ye9o{wnMjp1H8gOgxLg*ErBbG85^t=fI?;@7+t9Eq)5v|_@*_in zeJzX92!-m*Eu>(&feGu1L`&L}B{xVCZF7R5M`W)wXkvpruGa#?#22l6!;`yX)>LtSTSBae&6M)WD3EWHl6pfaTJFBr5Gdz+01zHBG6Kh8hTc)ZTx>R8@b zmo_0JrUAl4NKK}5Z!iX%mge5bfj#EiE@ ziFI=~o)c8lkEn}Q#$pb4O$x+PiIyYex8$l|k zJk?a4Y-u4aP{x`%GBJ(Cny@ChWS~Mw-+Mq#(27D9bN|Io# z5=PvBae;VZZp^fP#7TgVSQbwafLAP8Q+F@BI*zb(;j38UON6??lu4+}=|Na-Nr|DC zuU=KAGUce%(6oB)8=M1u-PV+D2Nuy0IO-{UNA+(h+2 zMrNJXHu2c9HkRbs2v5@-Pi(n28ixopIS6TiVM~{+U9yHJc9~StS-UJ9o2}(|<8h}p zot({ufM%vmV^W4N%36cTp^20w8Z)(+6G37MvSmW5(dDIiT$1L2HJD2!>Lre@#pQ0v zG*CV|toc^e*0zwBp?<7!>%=fj!k*z2cFJ&t<*8(C-4<`ERqO*>D0>@(tX0Vd*8nD( zw*lfy8!!T;>egq_?I@)u4tiN)OL@~~^h40x@bVVZ$0&c4zoe;o>)Iv+95*5q(-ur| zP>oy#6)nlsl2kGwrhr_FaFa)#Hcol!@ap8Ixr8lmXs zy9qIwngJ}2Vwxs{Ul1lOu8y1B?9ojwHha!&bcPm`lv-duYT7EO&!Qp(M%&g#+n#C`fm+|?)U*C+1PC+^cHPHo;+G&G2lel~8Ji65n=;>S2n zmf(QLrg48Ez~U){8<#>L?kxlXstzftE0N;55ELI>2p`IY@L{tl&V`_WDg>edh45Ad zc)WE%z^HO~YJ)j^CGpk=a|D*fQ%|-q9*|076fhxgdHl69m$-GcD8SSU1D*mIBwsTo zt_oxTRW}A0RiIHY6=)P_0IDAo$`^>^`5MX-maScvhg;COn^R8Ryt(P7gi|TMYqhg7 z1}M2rIk6^qk`>9u4e5;M=8MM@cOupJip`=2W7&vLV?}-MrPww5+eIY=F1l zQdx(Dm8oQP26qUXl7_M&nXXJ@_QY(>xD7R-^@-|xFu6C8nq+MP_kxwxnD-{Pq#cZ) zNN=MpmGw;+{zrjWc5v!3&a|wr%rs*3s;n^+vYNV z4MvGXJ+iSfgn474r4sj+iS=;cX(=j{Y{UwaER`V7)>kJZ>?;> zbQqK1N?1tpRCJ6QZV_u!Nh_yPq!Eu+|*6KD}ik>*4S3nv;8 z)e|)}DX1PmX=zSkSXMF`5?d;psk+mZEi?u7k+8_*A+teS>Na3jT$$WNxif+VibP5P zkUE-f?TjNfz}R$Rv2vwOaV87Vi6b^iM)!MR*FuaOfxnI^-V1Sa@eDUQc(8F*_AUZ;ir?0?7BiUITc3A3dJK{uA-AmOQss0xAjFrtz_4TzfxPh2&^(kICuykpN zrcbBs`h=idSU=d3S>J#$)(>OB4XdZ4V9Q3XrqcKaHPEk8y{ zC(A9tbXK6=xK8E}5AJ3{EmtH+0kPu2BfD|xt}~;--UnqG13(@djH2+Ol}-29KBEYz zb+6~k%c*1|)X@kmmT*&5LeFuma&2`fo#$Gk0;Xf2o@8Uxt^ zWdwpJ6G$b^XJ#5?i(9XD4@HVX?ZdECHu5HkG7J?{l3PW%X1~afEtOUY-fC&V{)?HP*4JqwnIGZ_A_Izd%g>sKki?uViRp%& z*9pIs?~(<#0~t+kd9KOTOM+1J+LlT?rEY1Y0u$btOe1g)x;{3AOyjL=Xu@!e;nUB7 zVwjE-%wUzGT6dgl{D+0SM~6nmX3e)y)x_F#4K`A*ZpOp}MW4}h%|tW$AtX%h$s?RE znl+P78M)u{=FKfGzV^E7<{8$ii4Vk9EGsN1aO_p!T<_##7ImD1IHP2*C+0I0# zBA)$4yzR)$cy`<2cs6seCw7de@t)W)|K=(V$2()cjb~qYhQvNgU-4|u028yZ;h}fs zV#hkm3$hi*;?)P^x!A#Y!M@0@*l)KN#!r?u-nMPnNslM)MH4f-A;=YR@POm|!*inC zBq%om(IfHffq3U)%9``<=+2DWL$RTCM15u~fMB>Dorl+;lnTdlu!}c`d$O)8thfyN9xO^lWcxOkS*HkWI+s#11f%dV) z1mm1?Q7fcO@y@P)Mxk7x2jbZu4nPG5)pccF-stK&&sNv@HlXTlXqyQ7l+lCHwbi>*Di+U0Cr5TgC$)D++HXfwvZvT|_y@$qJ+0)%>B8VQK<%LOVd6)B zev-OLfMXm*8sOv@dwKlKTx%1lkr6ox_2LszBkhlnCY=u-L?c408de^D=uTwJxb&-R z?8UZiFBYX2$E9)QDu&~oPZ3Kl_M*#ltZmz|g3P5MLam>P>|)vN-RU!kKm9*U?&2b4 z^6?MP-Em`m)A~ex%U#YLIKEYB_DwhN>9xh4$jmKQtTQ}Uth*9tzA6#DqNVtXYJ6W~ zW?VC>Yd1J4=bB7Q>Ke>W6ZO|%)~#uV;>DaBOG@5VJgs6qP7P&>=gycvWA4?nGaQ?B z|E#$)X3m{4=PH9!tvJpF=Eo_xcePWnWm3TOU^!{ za0fUHZ4u$P+Ud)sKj6~uBpg?qzFc~VOTUkBTx;mdrLT19j}ne+9Zhg7y=YA#F-!sU zH6r5r&=`EV^o}tsU`ETQ2jX= zIqB*$KMvI&rM2m8{ZTdhZBI!y%KcM7Id#%7dc1d+Z2>-GW9DnHv%(ntK$-hi0CXP5= z)%XxzCpi0PU@3fp^xrD{bVEfK`)vGv5T79a4+AIp7f98x4+r-75dMD%!Cwf$sow?V z`;!oyj*VkWVMaCYubQJkl{c!cJR|EzxCMb0#gZ#wWk?P%$#O#p<|b|bfmzbbeM?*&>k%kmIj?|S1Xy|q-E6n z3b`zBw_u^BF_GjSt`5bo^ZkOtb-ue4uJbJr zr%QV3eBYyR@-AjO$y?o9~#oEK7-mqH5vGgkOPV&vqx_x6?RZz^!|gcL>cj0gwbO^&@u=H}+i^$kwMMUH&r++{ zW<}eqWzSq7i`l2XmL0uEGRIGpgHeoq5xbT>$*yH_)5juedg`;prI(JgF}hE6G8224 ziJVu?vS%Vb&ita7y2ZZBU7fb;Y1hP!FwV;acYdG%+49QpHwYe}FRY!8X~Uwd$q?&y zJ?#A5CE`inppL|>@hmG9H>`2+jvf3pl$9(6f3~2iXpCL{D!?kbVSo0FV0cn6d~Ps& zUNC$?FnnP!JS7<3`)Z)x`-0);g5mwa@Hd0u1HteWlb#qKV8H_C2Nx=snoJr?8|0{+ zXK1Pvu)3lvdTZg(l6(t$nv%skFMRHGS|H-^V*0VI;;ekqA=NNV!?3L-Jx#STsc4oZ zD=>K(rUgmU5vppU`39VQH9K634V>C6c1U)|j_vK6l--BG$b@~;l=2JzZYwR9HrNvz z;p{uHz?(gg&pjJE+P3YevvoYST?U^6%i#O*74NLTQYDtd@)9j$;ZP0o{8nW5LHzV$ zxi>CkmEs!hg z%Wqlji0|zyiWl_8b67uyTC^w^>9`e{B2AxXw+rQP3m>KJvTWv1JX_Ig`=VX&?ySIK zU+l0?!I8FYBTi-lC6>OTg zH+gJKE_P@FqrKQC%1&bOQc$l`p$)!)Y^EO?AI@t$Y^n|mdHy=d>pN`prNL$BnmG3K za%KI*p8Yl{KJ*6H53TFbi~-$oBVw9?*m?M0dlcK>KP+e&S|i1a(X!PScbk?UzWz zZBEB>u_qSBjz!x3U<%9)4HfcUN+MkEj2+AF17E?xY^*;Qd%Uf091TQg+F)Vkl3dy2 zu;$Jj>V%DNjD{{abid^qlWEDt`a9zV#7JDm=2yYy#CNOZ^9X*62qyk#>1M>%2PL`O zCK;2NY=ycl^#vFTOjHb;2I0g0UNCf%m!s@3S}1P;AB_k1ryHU0C`nwgwny!6Mf=== z7Sfficqp)i*bQmh&3a;e+;G~q?Qm$h+4$slqL~KxWc2GU#Wg*ID;MkPA)!t#_E5gY zOt3I>E{XsZV*}6+ZNeG4)Uu7qOcYw*(8N8|4+dYMR?`{l^)+f*LU$YW_rWvxaboO= zJx~SNvc`6H_qpA zGl#eoywdXqe@z*qS%_O{;z4ea@r3PPH$-@}Nx96?T-ifLJ=<2fzof?wGFw}0VEo`i zNI=bj+iV|kn>L%lHUTyzc*lS2U?+)fi}j5es^skEa(3y};ODGNKEBp#5*H4wLCS&g zLs#U=;4CXt9_Ok&3Wuh129Vg5bI>{|ke$>PJ4zugEd1@l*wM&Gj+@r`xNY;KBQ}e3 zWxa6u+^$D_?fM|pJ&19l)THe7^^jp{)n<&4){I=?;ou$d+Y_A*1CZ4Z=gOzkPqus} zGvs))ay;soQQp^9go!SJcD993j9t@7xr#&a>hH$){%lOV0BId*rnSX z3*s9KK2&+(_Smm*0OMEf-CHMtXE?H};#b?t&l>DE`bqq3rGwf@#SL7f{ew~x-n;c| zv|<{Yt`AO$TeBw9wgGpqQ zIl&~@Bn>YgJA9yZ8r?@AINTHEVh>$~2o<`pt-BzLXm6RW6haCDYBM)o8(FCY*){B9WQi6-**CT^dY+ znIav1Pz94In;m;0rIEq%#;du*t6+fYpg$5M{aqR`MhM5{T9VayqNJEH43if--Lg@Rt=STEdp#EwwXTu~0Rr7m>dV zC>^>=rs}lvYU?hv3Q)T?e z@H7$HI>7ZEBHxW{<%R11Q6fE zk0&qoZsvQ~%^Lg=zT%w^KS{h)MY_Cpo>U8-$nK73z{AtNjy)VQx5kTyj~}O-im`(? zkf>Y-X-Pvr%I!{wUxSr`Cd4@|Q)tG&MxXIW%ulh$p^FDfl>Bk~n=MDDm1uObN1wBT zQ-6bQhX>evG#Z(-*>a3tS`22n{~I;vf|@>Qv;nt{9sH7Jj~07Wxg=N>E4{P4*ak7B z@Xe@Ab&efe3Hfbbr-pGn(q4p?lY5vVIQ2-)#HKe>;HNNCH|vhzrS)Py+R5cJb^l%X zRZQjKry0yujAXmUz^@@rEy^>?+(Wh+{E#Z1+XuA8(r>dmz(=_wm>9Ju3Xh}AY3!p? zpwG$>=%y%^6r&ZQ?l|}g+*_`LdJT`Hh3WHD3`atv)EsS{&dhak|LT0WkBt=@Sd#61 z8k?Bte**c1&p5q$`kARk?x3~|ZhqWBl-2(u>gksMLJHAnGT6;? zPt$b&vn|95UGrZ^A?{kAhPxX434*Fejfr$TZ+a9DSFwH!C^Q_AUw1uL9Onx$B#a%T zJxFQhG`@DF(OL7&-Zzm$@!eChW?=D8^>_;Z2~=LF40tC#B^#U`&WBIQ22*J+Pp4#q zsWhFZQ?kKSx*5DwsJT`uW?SDde1_ro6go4hBKN;ZjxQpqOTjd)Kz^Igtf@@BFAw!Vn*eLOw1M$~?<^P{Si|0Vk4 zXW*mT8jcm@kE+ujBUpDcdVc&5r|XqhD7XKgT}JNWUxm@zVk20PFm>`Ds#GTp=_gys zy%|P^cB4ms@|m8+-0ko|+wC}RTibX{vy^Xv<^F+Sm4M zR~5VF*!Em2g)kDILwWUZEXwT`v1lA2q=l%S=zJUQiLStXT>xC}ap=(QK0ZAgSC;-oG=}74O_q zY<}aD%y0SlcxPsWxRyLkg;|~*u@wnp--~&vkuU;jZsaV8%T??!lu0C;G#WdZbE!Zs zH%)p5g~im4_l-!d;h2`^D1Igyz>%v!$+|XLk)2%^*r2{;QsuqNT5)U_S;p-}q)(J4 zJ|1KTXKClT#4|Dq*+MybQXL+JOoilU=oqy-@FL7*JkUBHdPs0VKKQPDaG?!iVR9+L zrR>^yD#KLTdRATzVi3civ!t;@dyahUVBXGO7ow;OylDpBfaFS|KWL3htM!BN{t+BSe~vXo=q} z27o{N{^=+twz0?945_{trck7Bm4fth(jYVw{lQx zw9(|%hm4w4%cVH(l-<^TDs&J3f!2ehhRGKD#@Q~am$ulEg0^i(iXtB_gz1gJdIo;; ziZ=KUOfvjuWXpWRu{UlHC+y>v$2E+GIho1gwXKO|k&u!{Pn`ThNghRps1>fEp*sk~ z5Ha2yIcJv6J?juXu`to4l{mG$Gm)&98W<{!wy+}YwEJw^z!PA_1`@XJN4JB{G3Um| zuH))aKILS*J)HXqWzJ+be`+$B*T~G*-A%Ucq=o03$uI__R@Ol5gn zEVqqhGe>dQVE}bBfUQdiz##U*Gvpdbp@q1Iciq^e?6zardq$RU7&uOmeIaXFr0H@I z%{!CUF~Qu2m2i`L$B(o>`vXenIU z05moSfJ~CrNRl6c8eDr#W*6W_sa$+c=6ZA_YqX&8*M`Sy(`} zqd3R<=3v9|u{6!Gb`Z-B)lrW=mBARUg1qo(X7$VRW3fX=>_88W|*VGmrIGkC9+>`#n?nBB!zccdQ3m9OKU=$%*X%fj{3 zccgzC5aequkpRFj-$}tksFNMg5fOA zjKRh@OoRhh3-)csIm4sb*h7Qsv7|G27rsD+$10E0Z!WqP{t&JtOJ^vQZPyyx9-^~E zxmYXqZ!5^otvN@Gjsp_>gqAW&H=^$3i2#wt-aXN^u#Q8gf73MW4$PPpJQOOBlI6^R#7uzfDtS5Ge zlt+SI*atq324qT1hr--l)p8nVl?ma=xYlxuXWZ9FLqhG1|7R z-$}3Iw7J&#Jg9M94VUJkGv)j(cB#&e@FOr_U}&=ql~!>$mffqCYs~HLEBq(>Pw68J zZ}i={WDroFba;cLC-L^H+XdN7^NRvdv}>VxjRC|Ay&UxfY30lkmhtDczBz>E49~ACo|vFYoB{m6*Se%$5zWz@S>1 zEqief{UOhHumyjh!0wxAO=ySY9o;G&XCB*hUSv0)c2PGgZd0K?GeF1lPblGBb6h4! zz)Tj<8{MAi-(JzTJx0x#T6Tyo({Sdqe|zjD{D2wlJ@(@E*za(B7!8GVcWHIE!T1b_|5R+dkBWo_qTk%-oxH zvbed9N{orpI@^f37A7f3lEkP;-(-@Ih19!)~A3$}>bd20hZl6J9Ww z>ZFG*V&-Nhz1#%5R>%z4c0&}Kd2_9IBGlGv4uGS7Qgp~PT|<&tw2-{@#M;wBD65~J zOZi6}DZ<~FBJ?@wbI_a*o7+!JZ=_X+H^+Qi4z07*L3L)ks5{Vr>2SW&XK{HXz zo6%cL(@leGN5(q(V-QA`D6E<_qtog5eo0N{@uoI&4?WqCd9{Y@&=>AUM9EnmpM5#0 z?3zG&=Lt=a9o~NO3C^w)PjI-koY0h)d9=i`6W3zkgoG<5i>c@KG7JWNC{R!blG0!1 z9WqWjNcfv zB&Bm+BVZuf=%lnawlLObv!SS2I6|IAY@Zb?tX3>;tQ}0d1NzEIXR+@j-(@EcIK*WJ z%C3!8OX&q((dG7D3f`udZl*99-?JiH_T+(B-;x8dpDsNR`&r3>*w0H3#QNz>IGi8~ zOobM4`CF^&X$6can1|9WR{A22diJy`4rU8M>~+%bv_zai!5_2CCWON9pRDc)wARoI zM?yDgk@i}-{W>5S(fEX{G+91-nMtKQB#-^Y#2oYaEezfU#wlDH*FBt}4w_R|_n&%~$61Q#J zlQ;MtufZej-H~>m!R6tWV(>jrFHwHiXYh+mEt0|MVUJK@&ofbG|9{`$d#JQQ2KV+# znggJx(PBd2&7k7d)Ozuq*aU z+Wb2vOhLz1rLmI?A6Yl{0J3fD0VLbl14y>92as%I4MpQl zJ4h>VzMaEUn2St;Sw?!IwDl6?oIyRoC}|TTttWBdOeAO)BGT=j`l*xW-LDMAQ%OU$ z2W0QU$C>%J=i%0PFuB=G&SGMbEjwIlR$#Dhe1wN^enbRmD~kv?(?qeMG1NHRNm!Ix zDb_9IloEvO$1+a$9&;7|3rex>w!Q)k5LjJCs1TtuNWf6KE!kZ}8DZ57z~TJSHJjfA zR|ve+u!$_#m%fgYW5w%;IY76Bwc@jMy!NGxLZdVmTd^EUr|Br-s(s?x=5o@E81-qF zMEHptk&ojpyxWyRg$E0tSD+P7jGOSNA+3OgF2EuoS|3)BFt_*0M-;adNAWOnD9a1{ zVsPJ6&i_*~C1=DXr5loL8SP;Nw{Z&_c(|Sr7 zQbaj#LH}KWyX`agTDW{Y+Es66VD8-j#pwd|aAen{wx7MRojimI zzplcssqo7x{96_N7Zv^nhmm8Kk**dN*cIaM@YI9xKY2K0qn)}pA=lV+v`H%S5nCcHGwoc--OL z5o$Vvax6{Nq?ci6D+&@$HTz?32ll1Kqn1yQ_Rx;v~P9K2#+mh^LlJD z%+M0K4MQ>9n`yJhii!(Z;yZz37?m-~5RhXjH(Ps;Kod#S0v$X4(0CX6@0F6JsvrYN*o+v4`u*At~p1JhA>O%Drt$Qmrsv+{(Q zgy7$gLHUPyBWlh=^!yOI&x87|+SJqeAw%d1m^ryeg}hB$DtHzDd3_@GP;l}K&laP< zvX7NmA^(95!MPF`R8d_ns&S zEn7^CXSZ{6&D}H}L2j?Pn8axsFLudir`jq8l%#?U}U4NEd5T7nza!R6u>rI0)ix5{#Oty-ERPqG8nF>xCLYLj z(H~tn&T|w1@@JP3Gavwv|EB<;I>&jb?UN-9R^WpE1w$;;@+`&AL`lDVpQY?@#JUQo zsBOwKND~?&KC=-4Pi2tp4HK7z4)y2t#vSe$+Nwn<>G?INXZ&q$BVr4&EBO8~=D<@gnwR$u+TI`Jn-VP&vilZa z^ewWBF_vstjKFR?fyzCtd5R&|YWYUoXrLgNmvr8Qa2fnQeE#@2`+M@cdo95$pK7P?9<5B#^@f*i)IeyFWyAHqW;9?a z@(J*cn)3#}#~rF7|91p8fm#I8PZ3ox2AL5wyiuQUXw8Z~c+Ux3C zZrNsI+1@ptmf3KussF#58JgMd&}PQ{7(RfGfE|UcY>!4$k_&HBFpvLs->T#!>BZJ9 z#fujg&vcrXW@>BkV%6fy78g&OwyCMEruZFK&AiHKuGw7Dg!e1?aS-^O4Od?esdd#e z@Rm<{k0=S#$(=AhUp9&lQusv=qeXE^+>B%V@Ota=bc(dOa($-uj(K-E^6KxE{8Ibk>tQ`FvIqvY-Ycqe zb>Dii0&kODg7=oL!VBY}cU^VT*_^`Le=E})`Q;mu$dkp|rg+jLO-Vk@mtw(H@^zwj zV%)dx%Eiy^*e0N1JV=}+9>Q15GqUnVz-1PSe{Y|)2aOD?W;J)+fQK8@F zNx#}n|23h{)AaY|^M6t3uWNeYh@1YH(7)`V|E)`>XLHi^0DZaTzt^QN68dEx{inG4 z-zoGTc<3*GyEWNBFM10bfaG@z{c)YX@Utv{=zT)x?qc;TY;oxhl?zwg zqkoC3f3eV)d&*y$FTc=NdGx!<)vrqEk5VRX{(s@--zxM54}GIc-zoHOdgOPz^1Fq8 znNEKvCujTi2|cFig;7^N{!7o-5>3A^pT1b=2~96F8IXO=(ktE_;-Np{%CD02)gJnL zTzad}7ifAqpa0I2(7R7U?>h3u@~l_&krT)IOyAGofkFPnZV zlTH6W37uAR=?WVIs)SDOQE}y)*B+YwFZA`AUU-+Q-%g>IYPxytBB$>b`f5!tG=mWL zf1$7Q(AT)~9W3q86_&nO=!3*$?NiwArjH8!4iEiSmtH0GPf$O!>5D$<`j1wjH+ky+ z?tJ|Vo&JgLrr*NiP5Dnk?-P1h{W#-EFz&SI%j$PiUVgFA!|WFodRYBb34OPgU-)I$ zKCMDu=Akcf={tp<@z9%HdiP1_eL}z4lYW_-o?i$AT2#~D$7Iv~ClJAL!s<6F^oXba zCc5=kCG>e7`Ye~;D)gGr=vxjab2wZ-l&)0M_e4F+!^pwZG z4X%CrguYa#-=@k>^B!Eh(r)!H`mH;EDi-?7#ANA(FS+H53Z33+?b3@TyZKiM{YRek zhurk7LcdniP4njR?G*YfO*g}nDZkM9$LeRAH`Dusez8t(rqE1xc!$(+!u)fw(8K(L z*FAt zeh+S4V_mv3kxC`D%8PMpfmq-_=oPxfC<>WKhBJiB6_wvj+(9LRAL7;5C5XsWNW;#- zkC^Ddbn}a)OHM0p)0r&XR|+oENkJWFmoHyS@aIqBNv1!2x1>+ogz{VLi_<+G$&~55 zOSS30=gW}Fp)cw`LFM1`HN*9|FjG33GWpA20*v0Z=+}P--yG-p!NQkKZ{sw-3d+Cg z>xRSHnewM0+orepT42-%{rT@a#r#(xZBYJO0`jLJ!=HZ@Ff#E>eDw9W3j2BQ7tCM(hb4WV_yH@&>TlyTz6O=QOUiHGVNCWv8y}nA+W%Z& ze%k|b_S{Y1cmSaJalifgQ{1mRF?TnaBsPQL-|%w1eYxzg^SpOP$+-3BUk`@ zvt&)a#9ra=V5VC4UY|mg^qDD*f!Dr(eNpgQ!C#kTdjzi*!+crrZwr2*+#m897qC9T zKQ1`0Z2|j@;7`f@1g~iUJB|;Pt4qp7{e&*MpCvtWGXLT=F5q;agz$CL$>@?!L2GG@ zlas^6>sk0M6Z{h*n94~PJx7xGZ;*=O^()}?Y(3KFukcHkOn;mQh5!9;F*vVhA^5Q1 z_grRhUdKZ4e*&laZ8k7M=6aIxvCb3trOOuM9}p*fX5MOWp6?;}qVRVMzjSkEDsp_C z)+9yyu~G$aaa)=^{s+j_ZO>B9gk6L1w}#-eLhxlFcr|c(r**ev$ZNO=zc+-xH3WYs z1gED;2I>F#5d5hSd@pd)^GEol>o)VlYpy}^e=PjJEH{ixh5rcfApT<^_yqLBApYVI zd~pc=?ht%S2;LQfe?A274#A%f!G9Ej|0V?gLkRwQ2u|;+4YJ#G;8c&TvrL6ND)kZ- ze9CMCGzeZ1BInK!d}9dS5Q0Atf`1S=>3NiI=*+w2Nu^JO@P94@e@f(h{{~YaUOz(c zKnVXo3I9DMhM(7y5d4=A{=pD@I0Sz!1RslWBB;JD3Bjj^;Il*U65wRdSu;(!c%2A$?s0r`!BubgWPcA5EcHVfV)cueq)5cyrg{}th1BK)5T;r|=q|AX)+ zg#Vi%{D*}9R_X7b7XDv`@c$tMr$azN?V$+stsp!Sf?o)n>gzU{7%mWfE)~4XhhG&U zXQuG~gOC4Rf*10FqT^Wkr6F=|7XF38|6bAOF2SD=yixGF5IHH~fAf69XzTHPg5M$d z3X$_6!M`9l@2`ONsNmla#s5|KpA`Iy?=rx%g7*r(fo?!>{mT3}-xqx4A_LIyh>eNY8VZ8H4Q>yM0XXUcu$Z`JCYA+-Mki{{X?K1aI@<2LvAx{AQ8=Q^8B( z28as&J1a+UTVLaFzejrhL~!00L7KM+{_EvN0Plw&c%9&vONLuT{w;z(D!A1@Dfqe4 z(OZT8KEXdKxVROkOYmO7KOp>nCHTrR16ci^68wvTe@6Iw1&^;ZK)c{C0uQRkUkLy6 z!rv_X#{^%r$^hb?oU?IjM|MjK&iff)c^mL^-Mi2H`pGQ8(cJkOBfmF`oN2chfcG^J ztOg#WXQS{>S!?)T7CCK#pI>1B-rqp*lOb~cO86(-X82_|beyY603VyNRKN0++f?I$1lHiXCZu?!qS;n4!@53(=e4pUFFM&L+1Ri9cIl}*vbX?x2 z0Dnmcf4T5q^=_lMmA_u_+ohqsMat!vQ+YG0o#v+c`br$rqoZ_k_N%7J0-5HTL^|ng zSdOiTx5X-b zs}qeIk`8!l>o#OkNjXTD*D$z@bLY>4kUGg}4Ik7)YG>KnlBR}+rbbHd)ZqkQqOm$T zW8Sqh=LO5TcK&tVGl1rRUQpq#n>lNaQ+eZxRZEwws9d#d*_zne%C$?Du837S&8F5X zxlSv&D!q`YMh{oU)U7m|jfuvZ`ebEtQ?fDLQkkx6NH%5CzB7o+Yt|;#gQ*&)3(=x% zG*MH7vL#wtlBslMZKAH;5t$x6B$1GkThQ8Sk~rYlw3W{{T6OPks%vysCtH%~CFyjc zdSkMNPC2@HNfI}X?X()3-G*eE4wB*+Bw8ubNLC6)>grTobGj*|iRw70msp!hqOjaB z_^@aIH6%au#L7lK8ARo%}H1P z>iR@o11j9MYt_}LJ)l!z-pjlSlMn^--GWF@YwdQ!J#nynMJ}F>Bq8@FomB{emYofwX_u1u#AjV(BfY*k-1YHG4cBPN_J=yR zE-x)#UMgjki0wsa$%*<{V>-pQVEa4ETTJ>};kLyfXcE+Cd_CTF3)_sy>D2qoaa#hW zgj%a%5@!Q74D|8Z8thDGTI!R@X4?kWXX@|CCq)8oIFxdEQ%Sm>0w_vp-KIJilAWyt z4Pj{_Q?r`f1DM>fq)DU`B^wi|L^YZ#j8j+LLR>5A8k6LzQ%zR*GPH4vfWa4Co#tev z>6CF4(h|xuDfn^82{eRC>QlreKZZo94T(Y^3E*qDhMBbG%uE2F&V^buyd=v*@>?>= zOj4RXIK7Bz8Ym1m>y=IEy4pG!`3!G9AsG(s_MTOZY(ol4u?$>WD^aS^vP270DZHxD z#*jDX;}PoVhh+EB{n8JSD#!!iYmkok|6cuZhmZOpzlBi|d@=MX^8WN3S zF{gs(Bt8&=OjWMk+MKklaRZz>T0C5oa={pEs_W{UmS*5-V~uoE^YX^EVhlKmbRq@k zVF75xj-$M;Ik`HCK4xYj(AU6CDef92TdV7n2jvbuV1Y7{R) z1*MZ7gq&xb2UMGgI-O?WKBWN^eiaVt*C(2rlQmEZe%huj;oiKw$&JGmrD&GH&0!Q8 zqyJ`DG}cm`Xh!d9XjqnMtmcW96ayI&tbMhYLT$$_q;TsNPh|(ZBGHoeWXU~*L|YwT z{88EpX4@;t63AqWh$nv``tt{zY1VmBH=sDTey4eZXA)7f+5GWhRjq}Udp6Z*02-Kh z+OZ7N3vn+n4od5%`@qs(3@yC;?Sote_ zxRo!rtE|gA!DHpugz(o1PO_&f{x%=KU2plY53iE=BR>32iGNmpN&eONSbhFZa9iFB zB>rvrCH`yhvHaf`-16JGJEdA%s62!he4Ve=dZd_V?-XmzVbU>GJDi_x1h!Plxb77b5>)2>*{m z_tN9eB!t3KkrxaY0b&<(|H5B$PTmdvG@)phiG;!=qo-P%Q$>Jt>nxBV&(KG zoVJiG{vDqj>o@+zhfg-*ok1UN^|9-DL?%70J_XoMr;9N1$u{3J6|VJ}r10w$|HXn^ z`PN@us`%$C{wsa_vh3^J>cg#^DkX=uV62{5h0_*{#lNiZg$k#01$0q)7vW?1FCzdK z{m`1d#ow)P+Ip}!?aR|eKU&UL6;4|cmY??7>7t(~J{F%i77<*8>wK3fd-%G|Jg3FJuQn=Q?O5xgW?^U?w|7(S7 z{x<}tc13;kA?eq&&qbHTt)A!l@JkGvbCKYrzwXylef(DbOdoFLU+2TA57V_MME<7~ zuIq*Nq39xgbiJI9{Smqd*Y#4ba9uAy3c*XTUqBbh(RO~n!nK{(oWtzQUy7hD@A?q@ zp%DBpL-1!p@b4--rt+O84w>}V`dk-+A38U$Kka2%{a;u3jS9a+HsHv7afM%_@Z}2s zgy5u)uE+ff*Yy~YjRxC3KPBz<5+82$e47uqe(&vqQ@*<0E>^hq4+)PukPq!*u%m22*X{*u7 z`Gvwu6<%-=BDhGOmH1fxE`@9PUsSl(|9ORL{ohcy*8j4LDOZ!Pmj5n=Yx#F6T+9E6 z!nOP_D_qO}M}=$ozfriBUn~w;U$WQE$5dC*K$Te@QLIEaZ$b8jgPg@7KPuV@ZT!DUg2lH z6A@f~ISUo8+xd+OzZvOlzIQ8J_pdL7;Lj^u_tPPTYdgFaf?qkE)o1;6zN-|j`)`B7 zwfqMZPFdM<{jI`vJ$^&sTFwg!r=XSdzZG7k@QZ2D9~aqQx97CN8$q*jKA>=|=NA;N z^L;J^|DM9NoDqdIuQGB&Q?%TA!rg z686V4Et#I9b z4u;^rQn=3d6@}}3@19M$j?VX4h3j^8OyRm7U!cKQiivNCvYyK}Q{9eWX9fiM7;R6c4 zPvMiu>ErVE_vs4X2D&Zp%?iI?;VlZ+dVWaZI^QQ0uKAx+_=8IRFBGo%k11T2_pR3< zF)n|(u2pzD=(b#UC|t|`aR`3Fd=}60Kd9s^P`H*;p>S=tZ3@@?Jt24@Z64sFa_N3? zxx#h(zaa!)rEo3huNAK4d`029zx<2Bwf=8@7ppl+&xH!t^4EsoH44{yeq7;N&ZiZw z^?Y98TF;Lx%!X#_3*KPvn)3V&VU zdcN_qC1Ap3=MTqC)cLL8RF6CHvGNx!H4KDn`Hc$K^4F9Yek*^B%ulKW_sh>IT-#@# z!f#Oed|%;Fh5xbClMCXSzdlZ;eV@ey*}2jaINQS z3g4jQEVwZ*U-RFg@CL>IC53DLg9?AI;=eQ=EWa`Y|4azJOW|Ege&O<9`RCshj4u(~ zwx6@4{j3bZE0vrFRKBeWZ&moG75;vOe@)?S3jeXfKdkT(h3oR(bTgQ6`P<<}g?E5% z``6bLzER<`R*;m@a{e|1|4j&fWm#U%b_8v{cPm`y`=G*gd3zPE`G28s?GMjena}s# zD&MIJ*M4%N!nOQo75=o6b41~q|FTv2e6x!GJqp+SJ3{c+6|Tz_DbLHlP03%ca9yrV zA$X_4>y?~63fFr6TJQLuwkf-p>)-FK3FvpH=*KC^PLhyI4MPgk3a{Wf(x?XrwMEEs+Z3T-NC8t#3n*UCP zYy1DR;8b3%|7#)mZDbT&)^AS}zg;6Z$=QjIwcC9Pe@@{$d~&`favt;HR?gq}@N0$t zNhN=llK-ra-^%}%54ZAP@ZmR#{2zqK|CNv5%KyC&xAI^0;kS$Y<00~okki3M_SF92 z$U24@e;z?Af6DE7T=QQ}P8k=;`8Gb5e~rR5|C&39+wg1olSE&tclvxn#>ESK_#VOS zxmn9^$L}dV{&wLn_Tg`p@p7sU|E2KTc4y^}7k<*6E=o3oL*6gKuT@a7gsmJ)iu&-o zBwppinDlVnJeXh*ZBCr1T`7WhC+&*`w#)sSIFtz(| z`y8gne7JqS%YGkjpYPJ|!|n53#*hQRMa83!eU8giA8w!5QtHF)b6IM9xP3lTyAQX| zO?k|R+vle2_u=;WDE&U%J|AVwSkgYPzkLqMR3C1igHr0l?ek7*e7JqyNxKjKf~=Q4 z=ELptPWJn7`@EBWA8wy_GUg1g{`Pq%Q+>F7u1Tp6x6d`H@!|HlChb1lKG)=a=;RaQpm{G2^`Y+vk)__2Kq;B=j5`x@>#1&m*bv;r6*)?LOQ-f9o+HZl5o* z--p}hi}d?&`+Six&h)nh2ZE?d_>cj1GL~4AveU3=G54X<|dCZ5~=ZNh0;r2Nq z{XX12M`X-IqnFj+K1XD#54X<|DfQv@IU+Sa+TjR_G1Z6L=YN#?aQpm^8Xs<-|IzNl?Q=dJ^WpY+9{YW`eV)fPGmAaftho!Woi}IB zyt%WAi)YQ8399=&Z{FPE;yJVD%r*(CCO!~bv8>Sk!3)JLz}q-vI${bh-_yiLQ#8t0 z6i*7B=v2hBzu>pb;XQnj-O;lmySo?DgLWhBhrq?b2TB*?p{PK#q@uf^!o-s%ak_}(+4!=23ggDJUq6hOL}s5lM6Zg>KHN)@ z&V%?qfOl#hi2ZKqf!IqW2V%c3JrFw@i}!R4fJ9Q-zD_B|ZaUutj;AN?IS=q4za_f! zVPcEtI!Lz1K*#9i_8Gj+lLg@=$aoVZxzE8uQYQBlrOR>t@y>^b^Fo$nd!MFuZ_9(X zp1vvGX@p1-`30bZ&p?=!E(Fmq(%uSMu7e6E)iOKRL8XZ7DjhorPNB&>1{6FCx3r%>OQNo!~jemLL0U^$e z#-?;~#*Hg0uEu}<@vNd5{N9D+#>!fH1cAx<-~L?;5u`r(5Pd}@@+5U>brG+=E+f7(e%n)$ZV{TGh`Rh`4bq+1H%dl*l7Q5q!OWjOVL|!F zW$yO^==$>KuW33=e1Fb&08m~*&%`%44dkP*BDeHjTG6Q9OV4>T&w8_*>;n-g7Tm_! z_W_%Y59TYQu6PJe4k(C!J8*htpRG6coxnaG!v9yoe}Ob$_NBmfh4AkS!M_!P%d_OJ z#uHUG;jtfhrkwk*3w|04V)R%e^Y{yX{8R9Q$mF>x8{DU+sHe8rhpG@U?2#_|xl{IG zM&ZxI5)OWXmVFouB-8Vxcee2U5}?h&1kyDy}voxz0KU2^W|>n)bDME#fOm!QPv~soCzO5 z_cm*?+xjsx$27d+V79EUwkLM9z-imo?_gqyN01yJd<~Y%-POOR`@q#s{E_&}uU+AE zV{(THq%hD^7jl_A!yDOsm@OZ!#VhDBb`6ayN`lX`H6IiMihuQCh$nMzD!P`iMQxkg^i+zp6(z~-W zx0CQQHlK-t{}I#ZKR^RQ&J(1YZ`%mDLXg%$8VU%xS&-=9Hwa+?WIu@clCb0jKRQbA zhXlEF^LS3%I`lr0`p(Vg8c|}s0%xe2@cF_P9a>A#Qelhc*%lFgi{Pz!d@A903ErK@ z&(bOb<|;Zf_D8q=$hLQwo47UESF*#|iWh6MW&FNyh~y?htzz(pC<%D`Tl;Ugr@JN_ zJKDDGMJF?dAT$=bOK!#e=|zhvoSv|l+F<&ep>x|}N6#8M6W?zd8jJ7QT|@UnEb8P> zNLi{fBk`AWE)Sf6W_sSx+l>Mj8U-#Gx)`}#!TDd$`QOa>-`178>*yZmvp+qTn>mV+ zQ^n8s5~^Zv7r6wEfx3uu$?o7T@+#V=*uBtsa9jU39{oFK(-G zHb^&+SAn3oZxphhAA#GSLeZj31V32wp+SPsGw7H7?TEX26+Mj#h`AL|MimfedrgMD zMpeKir&<9A^A(W&0jz({>;HdP-#MKHCbYc^r~%^guQ3$^n?eL!Z^u~Tt`RN4`{*y@ z*QGkefTQ@(#S4gb9SJ;zub8!@V$f=c0avMC&hy1?A^W&oC=g>+y`=|Hx%3T4N%W&mbMu6_s$5 z76H^ny!yHf5yIqF!6mi&(piE({o6qp|8Gc7Yd|E^zeZ&9C%V3D{`Qy7xY)4fd*T%J zze&BzzZJhlIu*(Fu&mUu70_+;W@1`4YT8suT6q_HoM;cAu)O2=O{*vm`_*Sc#<;o6;8tM=|Ari!80J zUCL-4xAxoU!>#=u^5NEgPxx?K?&p2DEjK^2RV@~rY^`9|7(2jtK%rNcjSinRr_f1rC>OojrDQ=0|oe7ALuOo>f@l&W{!mj_U^cvh;iN`+0W~ zj*G@imtGii)89upu6NOwO`pl9f0S@sJE(Y;Ui3fy#QnhkTKj;X)s7U!qax}nY#(sD zjPXxO0*X>_yd<`BgewL2kAgq<&uqk{!*K;Va*ru zDFtkS ze~SBcC*El?_D6*nwvQM#N82cK)HnGu^hK>&qkf6+^yg?nmI$8vP=?`iB`Lg5tDrd- z6_e&r_F^A~2<>SE?Xz7Kf-elg?Oe>tWgiIMJ3{!ILvUK_57Or^fs_6p#4lac9_e}v zpCJC-A^5j}lN?&Cr;B|pet(1y;r7|y>|=rb9G@Whv>_0L(|Ma9+`L%@+k-q=V;&%hFkl;6($lHlLV(eQ^ENI?#WKkAI&$0KCJ#Ri@ZPusoeEn*? zwm`p8hEww^QfzYO-Ape{!7MuMzAVKYO@KS}yrtnm94uH}3*1TRKfx`-?+9FOvM9=HCW z%7@#2-0H($koZm?Zu=#@sSOQ`-g(1!JSV%?nKkRW>*n#z&Z*z)Y`IJ_$4``lo_n1r zrpMW`!=>4MrP;DW(e2x?be|c(GAVYz`0V1O(p+l|ZhIrUxAkF>y`n#|y9|dfD~{x1 zha$T$0gqt|)LD@u8KqOlXBSP4kw|l6fHmd^w;k$6wwXy-pzm84JC?bCN9UpQc)@p^ ziHzMtRp`0v7|3S&amNInKOX7p0 zk@g2d*>PtcX|D<;lQG(tgpx6gMcU~t32uhwM6IZbxkRMBD3pw$Ez;hPLIC>iq?b1pYn_?xhAQXfphokaSUU=liTdR{OIeKmbaFzGT>$vD2blUp0! z$>?89&&rLo)1nIpH{ZDUNi+>PGEBkE=P#ZP>!mY`*P&X|TL(vow;OIP(*7X|wqD@| zt61y2gUu3rZ{c84g7cRQzFUHiwhq#3$VtM=?!i(C z&UFSCNbt?h;0y_#?F?Qn!84+RlO zJcoTu_;r$+tLV>mO@~};l=_@Ec7bCUDrgvqy`eSOVX^{tl6>w!K3<`;{VGEOB=+GS z0ELlV-N@ioi54J=;%E0E<5#(iLUEXIrjLOCI?#?}*HV-qKt-etSCLxWz@8B{1&?G? zNCH-Qut__yHoJW$WJY$aF5KQV+h?DsT~gyMPWA$CaQ>(Ps;@uRKDh0V&X~+)5O@$} zEHZ@>I}*aBp1@{3?5)^8PJj@qNir{%)TrZ(u11>T3>)nLH-RPVvwLWBo{B3fosTM z)L(V(`UPG?8bAoKDxc;L=8Ae44c8m$8?o2&up}h!1*=h!8XLvd3nWruqEg3>>t}jDGLuu2R4$1Ir-j3`p zLZ;CnF})XI(eY!)-CV{}2+CqEdWT_@l&hNkdmdo{j{eI}rS^xF+c$70IuI(SVIReD zfp3!2@`r*{Q->9wV6tnglNIY8<_5wbP&&6%VV|V1)2oH){picvQzaBldy>50>UPzG zX5y119|4l3$&=(QsbtiIhI^f}SduO>Ha#yjwv0`ur;_DKavY_RtQy9P4fj5lN|qoR^5FHQ^Z`y(|udsYy+WwH?xu0@{$!qgKfC?zp4~x=o;?* zzpY9waaF)QJ)z%Z&;CNxZw{l%ERbo8pl9cl@92HcMD=Jo>JTF3%YBWB^(N>bQs%ap zL~`v)v`GD_>|&ALn@Sdo^tM#8SR_urBrY2UqWbOaUT)8>r|KFG^E_#pt z`%j|!lVYxlc+A^{I#9$sw5$c_Uyxy`RvR|7SgYbsybu z+%tV&{-0n=dAY0l?f-_}Vb^jfpuVSEhetX(hmT}x#^0$D0M~oCcKj-Zr{Njs-r;U; zZotU6tOXa}s~E{pQ-UY<<-e_`uj$KwNBqr4kfp(v5x@!hbk9ZW9BIEYQ`3FC`oM=yD?s&jH5_ONh8cJjT$4O@r%@{j8ENqu=fl(IBWQqtE@eq@i8pCE&M zXS2>A!dGYU&PFa!>87c_u6p`PUP*8d&=8XueZ#*>y-g6(vcG>{uCJTpK|T`UVF>e` z<(lr3p#-MQXnWmM>5HHq#OU!j9P!|UyIGd!Gma(QEL*~Jf^?K$aCJ0+EFGm9{{%8R z%CsqX^kZog!|cOSCWhHjxv7eQ_}UmcD#^2d$aHhShh%>A5GETBmNK{Vg$o?9$cN`r z|BwZ*HG59XA*&1eC-9Jn-Yqlw@V`_~&a%L;aC5|Xcd-&x;M^Kc*z9_RS%FcggQ67_DAEKqcXTjFRAH!DunQvX~7Vn!kpE$xp zD0)wyv}-aM7!_nXA4*uWrZ2+$|34`Rg>1=noUxo9jkP}*_zokzsDgEMX7yqGHg0V}-l<-f! z-=yy-{oKO$d!%nuJ$@ZNrCG?r3`AA9ECs&~IDITl59v#Ry(@)(Z3@0w_D`R)7jA0!ds%lHw0SSy0zUr{{A3V~oa2iWA_ z9m5}0d=V=)g7lp@GJWzFSm6+)&&2Wj_z{0daqAO*1U#vnf0lwzMa4?ur;jt`zmpDr z2-4T$NY5+c-&9=sSm3W${G8*+4L>4x$Xu%UeTqw;3fg?d#}t>o6gYhvlk{1s{EOJY z5u|U$k$o8T*-YnT1nE<8+^qP|PZZeme^~MJwZTds3YIOvlhXZN<^R|zPLA}cIQ^XB z-%(upQsC?#sLvvHqzKZ7@+5RdT$Q53cM*00{sv83&`?lySICOi1r?mW(kaYa|h z%JrS?Z5$ro_lD1A1PTTEkR<&i^4OzHuHJG9cMCR>V$v*`4 zO>Cm(Q~N3Htaz9a;JX8yO~v?&WI`aBRnYK%4{$t)di<9G&Z=hoS7o105xb+w17;gOq zOoar~$NGzG47dIw7sIW;XpQ04UzB3F^%p}i-0b{t3^zMpj^SqKt#D0$v-4Rkbi>Wg z=VG|o^VS${_Pi9s&7Kd%aI@#bG2HBSIfk3vw!s?7{F&XpxqI#V@JfY$Q}&3y<4sNT z<{hK&cq`_PEac=QmpKltR`&~@fVaT`@gFZ^v)fVZhO)m8n{CkXV*rkxvNzTQUB&x~ z+#+ORPi}fGj{_|;;XR{#K&cfxJ)^ZYCtW*!y~8Jff0bGKMfah8PGoX=jElUO7Hs${&H}@Y zgnsYB9-WnL1y&;w9NjCH6)z}pRYxp!g~5BT*w1G2*q4wJC1Lh!HYU#T7BTmHnLI{s z1>nd~X_Tj&Q}4O!K&HEP{QboD=499=O3-O$a@S0MUL!e&!x5cnx-S8KpfH)X-)5kR z>?zG=Z%|Dfm&I*~JgJKt3XcvHDSHA=exhC1>qU8aKb46{DNXcmDVxeY!y7H7Es;x- z?$XlV!W&T5mj{^hZ82}4dv?5Ww_{+hwM6AF`?&|>g*!a&P2i}-TFVmL%D9>5LEWSaXQUC=+$e~>x25L>w%HgOeW zxz);q0y><=jD*`qvot>YXgIkOT{w?jUDLD3^Tb}M_sj#Y3X`|6l2+D!dxafz-%5@? zZVnZBA7t+vC>?-ow6MuzyQLuW``}PD50$h`a$#UgiD?VxCZ28MzILqLgtoAGM#S@W zqqxO7@TKXjX$*$)KyjHIa?2glQv>;@uE;;rIR!@-B~nGUNeTswabp6F-oG20{nU&| zO)d8qmq)3GlzshML|e&1sZX@z&e@;j>A-YUmYQ#h?Sf)UDUhwbJdj&<`R;~~^6`t8 zg@Izh!AmXMTn!8GWro9;z#77t*S(EilYeIX&A5#6R69No*AoS9`_$ip(xaFBwK#9a z>dFayjg&i(TdKQ4^%rGDsc=PpqSOa`=(xB_^h95NB=W-8KTujO)#Ey-pMpx##yx$dePxGOg(p^u4(dmbHnCQ;yH;P_c;+|Vk>UD>Yjx|Rr z<5RB_7tU*`JUXL#?r}+i@&PFopLzNg^C1vB1K&zDGdca5$+ojiu(J!M;_YU7#p%4g_VzPEaG?Up#%sClU zH3)jM%Ulkp-1h^CkXNbQ8i7#hF}FXUDs@luAxe-6LSML%p7LpsakG=L7IhP&v5}sC zK5d%T2|_{gCER21&k53WQ1|H(G@}$|07;TX_I<0k+pN_U1p%P4AbiEvf~aL0@k#`D zW4f~d&mq57xqL(3h=#l!!_cArmizYPf0WsSm0a1KRPwbQm6hGqNY7pO)!uzJg`f6CGG*phNCF+?l@o3*&Wr@-IN)11Lfqp5Xxvr}hJr$FkI; zCqGm>kble#U=ei$LbFx~ydKCc$2*mGu~)31js24|S|bC+BE}Tbg@IYRux;VeGF;u$CB*JKO&J`e^^GHeWb4u)%lS(%w?|_m+WWey|SI~9{J@yW#ZFp1qi$!Jty`H=v zaDM(VceC8^rQ)VO!Yqm*MvY+^(5=huR^O@Z6;ToK=Ky5eVLFfUbu9mmPUEuD#R7Q^s&dk{3 zt}^4rpl!H(n9NbN%H!dLz1R$J!$e?bQE-oa7JmS^(lPc)jUMp<$jIxO$k%9Lpf4*0 z@f_}O~7V#tSvpm_1H<$QpRpa4ZV*+5O&Wznut*sI#8NmdM&U&e8G%+c|r`o z*Mg_QLtRtw|BLQsQ7!&FHyS<9p)_I-dqBd60c2nD`64@ zFkb6;uC5y&(Rq#{A_^@e1*QwnUTi-owoK^r^>kP}rQE&v6HGjB z5mg$WG+wg>Rbfg)?>K7aE~f2GdRX5M*kknGyc>YXv$3ym+i-giQ{nFM6^@hc$5P?m z3V!4f&(jl7EneX;>Z_=5Cxd&8d!1{AlbCq(q$1wf&s|LlBFo)*3jZAZS64lKJeEn&j2k5uak{Zc%6uCXYrB_&-} za_fNJw zd>$?S9Z~vE9f5vG>9W_A#h>&;@7pqqdLev+U5}@KeG*fc1!%s~=T^`!_VndSznDTS z{(B?+HY

Z_+udY@1KKBfPng8nn1A8yZD`CwAj#7KLFjmafs_>0bZ>Wxm|_^f{nR z-oh|!(e&>LL7a14EDV?6g7!Ba8qaY^Ru!IsOBO{u|8E9HmL~kdaJ)8r<}VB?PT~-M zD}IKBd{>&`2*Cv2<%-4gpVRpA!c8E<^f%}oI7!NX6K^cSydeM6aBcDJ{&QU~e(xA> zLf7isc@czoUU?nYo$O^@Yuv8FIc(-yXFPrCl$3s-`Z&ENCOn=#q9+FO{U&{MxSkvO z=ya)oUJHeVOe2R@G%g`k)%{ zZ&Y61R}1Oihhphhhe_hiRf&HLm-MBue9l(#7jcZYNs=DIkNn@$a*#d**ofkPh$Dma zeK`Ire&jz+Z?N=vzt^PNpeW1K7SCqk2j_8)8`~f z&ZZQcTQX7p1M)oS_F|@9pHlqCic8-I{Et)Q{8bA6w<-A7Q}8EK@TY)N&l@#!($_+t ze^243F-R(hOf=k6N1FCEYuBz2)VtCw+^}xr+P1DXx}TU&O6Qte)~{T9!-jQjvSS^b zT-=E6Dl7_Lvwjgjjksb(aY=sZ(s!=7y5+isORu^9x)m!fx@=C=*fxpe_ zHC<~qtiO8g%3D%ge>BNZtwg_~ zi#}Ii=2X+&xwfrsqqyDN+11urZ0lHRj!PURN5kb6D^_-Pwsmx^XkWQzt=lM2b_W!_ z#5KqCS+%xpWygwJSFY{KIN?=eY}3cN8_CXxm5^;=n92MuD?I}HFxo8hCE?5l195hR zh7SigyC}n7sqLElT*^265yffgIHWNAg@B)Zq2XJ#y~pJ|o`S!Xj0kZ(`vN@F^M9yG zCppBoXulB0N7eT+F8{dzr`wI`U#A^xTuwH?!}4s?ekaaEdllOQTehjC@aN{>$8RIuw^?K!Jx*R$i z|B{#->-Scq;2#d;WCJ-h9Q+_qeilEI|Hc46Bfysg_(=iY8Q|f4+!Ekn`Tt3PhxhR~ z%{cWrGm!t<06#0hdla{FTMHV)$78tV>oYN2FEf9jC-HLrT8uv@(lK60!6yPaS@2rA zO*-(Qe2&Eo|5Sj7{9g|6u>2nm@UWbJ6yRYw|1`kEa&DkQ9Rl?U`R@wwkpK4soVU*O zp9t{qe%0!866J^Y>#6|fqkze==NaBd{%+O!+Jtik!#62D*TEkDE5+x<@JAH4@vg~v zM(bZL#=lJO-=Y})eZ>ngd`$7hF+8i~UX0;+#h1qLuV^`%oiIJ$qUDv1@#|$K7sI>t zx;2K|xV99-ZCpDP!)-h|9K-GTp&Y|)Jc=Qi1k>Nf+1VIw&l|ZIZqFO7G2F(Zr5JAG z(V-Y_@@^1pS&OaEIFK4+V_d-@{err_8i5Ag3gq9SL8=!<$#$_5%oQ+jrfJ6 z#)q5Ge?CI?QIY6VoVttGD{DJXRUel{^b^uFo6XHP!4ijjy$GOfNm4;8mrfbJfGpQAPh{DB{?$6*IP6@|0 zm3ma~aW0@>n+x0=%>|lWxi+K+-(cW#F@wAVVexCD_Y5~Xa%PZ6Pw#UH9OnC0$#aFj zUEg5n)HbPE%)~BJ=Lko13^}Y3Ipkwp9V+_wxY&OX*C8;@T=+^nA;se``y9%Q$G5pH zOHZTw^zHf*oKR+y0eZCf)~6ZS(zoNAK(KS;;qmDtFoE}a#RBug=$TQCzfG>9zj%IF zXW2i;!xm+1RRYVOx5VPlRGeK|yzEFSsY35mK0Cy-#p}54@$`u$ zrQfRcXFcd)h^HUY!gKQdCg|C&bke^k(GMQ8Hsd zp?$rMS6VO-80B}oZHV9pF5Ud76Gk9=C88VMypG)c^j4baZ{+{poTww5GQ^S9?`Tki z)o#4$AcKqA@q%L$hfR3nsmINQRBMn;2!|_qaGJ_M2E3|(#MSf4F%!1yKni$8!HeXa ze1b^0Hc)cQfREjmrH3?%WfQE%DYs#^DF|bbqa+nX7aD*?5ViE+NBOezC%SUvj2Z zV9#iczG`qM{2ZkGoqkoNZ(~oE3qs^iV6AFZ24@$(dClrhp2VFBu35d5ZEuCmK-zUX z>|n+&R<2&{q-Q(?`pUI=e81vOtobcm_@?aamYciRcXemyUNrBbxfjmqma9wdzGUu2 zO>-~0^gM?j-QFc1XJUR#`VkqE&H^-Fl~_?hf0w5(SNf(3dZ(vvR{BpX=+AiieM(ACE;|$tB<|{t7?os`ZG`7A<0}#uxh%NVf7fXbDb|?%y&FBoL%+;K=*OxE9~;U)tFERu#Gual$}d z!;qvq>5ZC@)t?!_s8T%rw6XO(9Yp<%!h#S_KOj|{lJ7S;wq{~U>(j2CO!oE3>f71i z=lXPx5fSwE;L|4#Zx+<~sqpkh#anrSpwn}5p0qwqLi##)+&W}38^9lq-Ngn2yBj~# z8K*vc8fQs3d*&p32sq`NT(RN6cBJsrfs*{s;>ck2_U~~{yj^d+*m7Xs!!Ie_A1VJk zv_Xk&2gbfo2A!)CS4HPs-t@*4!X=lc5awKxMwsWj%~e=r#2fy}j}YtJBZNFPSl4U) za^-TQQLB1sh?mEZfWddu%(bj-@W|%efS)~EEFy>y$L*PnILp`g|Ax#6ELJ`?n_V2n zIfLQGzt_PYw|n)N;*`&+Xybn>z{7M$Q*iDT!eHsncbA!0#c-2PBbyDA6`JA;VA$QI-U9u;Xc*t zr@eE0f1jd)Dhmyv54>G9TqmM0MPfO`ts zjQ509P>lOn%(_c?I36wx(m>%J2p8Tluy1h;_sRAG zM7B!8c_7@2mB?p2!d(f7{H{m1ttpXh9+{=c?|Fo850K~gJ;KErB05Qcv`$y#KF>qN z$;0JIoPy^JML7B9kTVteBah&#B@%1MBYd%ta{kyO+!&n5pLpb4MO>jXEzYEn=kuOt zwjzJ(k@FP!f=BqNCdT@rNBHV6k?kJ2K#@Q5$c2i0$s>FI+wV#i8#M;k*N38vP)Fak@20dc!=VKnR_QTzH_pwF}ZgsWM)$;AGlHztL>?-NlXuT-lYdPL?`+}?GnI|i1 zd1Kkvaz{C0Ex!qVF~7!Iew>I)ujT0Bq?UI`Q5-`p-@&?}wR}fqEytzQ@*UN+{1(L8 z5!Lcr-KEy@BHv8}RjYXMz3x)$ckzAhQY&|Ht-I8kU0mlbwOSX~yGyOp#SQLKD|B(A zyVTlTyvg zwYGStyVNRMe80QY`da)Qcd3=NxY=E*r7zy)E@9?-=dqFvZgmyRRot1b-r)`?tQGfS z3~dn6SKPXW-s@e(9l`e{0`pwPcgu8;<0x8j(+4@9#{x7X_e%y z?$T9~2V|d_?d@(qEJnW8k*!+1&0SixSnMvXS~R;$s}|R}OYQxO*SkyY`sGb@+x+qR3%pvTn!s_6$C}4u-34DfJH$>U&AIh^q%Kx z*hbdLXaG=Rg>%DbM>(Qtyb9BnM^VEnN6e`3nX!6_$;XNOkV$YI^pMm5H!gM~T_92k zhAJw7aG=Pz{xsBAgiSJJnL}Wf3|Z=snGwQ;M8u+<8`_gQB^OcN=_s&b7W-Wefgv;G z-41~*Gi13#vJrBVLtxR2=RFRAQ8Q$PLtxhoX>|xpn;|P5f{JU%%??4`HDr}TP<;(q z?GTtbL)shyOJ_*CLr|-G``oQZ32zN=y?k}KFxZ=8ZHp>OQJ!q%dCO6>qGWMrNAbh6 z2<~k7ymd0>yfk6ZMv(BY^t|=W<0vlO6p0QnMRTdku{>{WgH$s`+bT^FE~OT3tEh$2 zF6SZEHrI!4+mkz)s^NGFk8IReI5KLeT+VlwsGf3prMpCZ!{r0TH}evvhqY~)D`%v* zH7sXvpxxNhFJtA7!(;zv+I!kQGpR7xTOO{sTNykoW8&d6d>6YgaNEqn;GpC9mOMAq z^I3Xu>vBdKyuVcrAp^?;JLq8%n5xMIHVnb{UBrYH2C((YV6Q}r<`z8SlJ5oM`46; z>^RO*gXgXj?lL~(8R-*t*yHRyJojYbE{%oUVGHD2`n|;$LvmOZ_DV6aSY0U zdN|@zr7P+CBDyLa(8nHRcN*MOJbb9qGgB)~veG}DCQ4@+EkSA4x=87!h)b2Oq|b}! zs&qgfn;KIZ15Z_YG_~#~D?Q&SeSpytlxF3Rl+HZoxm4*&dVNG!r33od5*UH7q%oFJ zrTbEwP_oh=mIub(EsU0+G}~aL^iag5N>|diM|4#>ppUu9uHI#-tvFf3f1N6Ip_S1R zG^81bG~5_*sfLyGO%Yu+4Cs6EKPjP9*^$g`hoP@4HUA{1z-0zx!*Z|h##pqs6-~Ke zXY)@A&fEjpq+iR9#k1@3z4nXDUwgG~?fa5O!2A8)mfz&k42)S$OX>8U4v7)Ia?vIt2% z^*(3qR38?$=T7LUZ)J&kWms^Yn?3bB7LX^i9E^;-x+JQ`Ny;d0Oh|9kTS{V>L5A-+ zhAmYL4ZRP5v`d)&TA0FuVyg90fud=|DAf--p$EPrYWb2B1`)W@F=VPFH1sa;sm_n3 zIz{rjNorv<2Nb0`!wGFoVvtnF#g6oDtYT>B{dh*JHG6WWx- zAgOjchFldxLvM>uRd>jW3{XSw4_P}0w_g7+3elGN{3@d&58pv1|IE@mI$BwupyoLZ zJ9{ZZ_BxZ*!svOz)sZJC1NHtG<4We-QdV!dI_~DfrOUYEE0E|e?j{vfcPKnnv>IOk z>QE9@;_}gcM=I5=Tl+QGoV-)j-(AMS^?vL{JhB*Dl zp<)Hry`u)30Rfq@w~H7o?c;(1apqTD%We_3A35AjiZ1|c>xR9>0vHw-D)bD`sDxb+ zVFR>E7^RgT4Hl$_net%oM#+jjlJ}Nq!MW2QOr}uu=}7j{UFJ=K-xG~#^EryCu^Ht2;X}F>HOvc!o-~TybM@?V>xaDS7=1|A!I`#|q zyydfm=Pk`rSvp#ur3373T$UUqB}=kMH_$7+uFp~!gIT)ArOGT-@Jp6r%q~mUGX}EM zcjPRc9m^7)#xzUC%B7%Ic8)Gfj*^lk$YZHXXYaEV#$cBI(scsNQU$+cDaP!ww3#uG zC0*z_++BLR6YlR4p4Bu;Fm1L zm|d3sj4_ZUT>>~?21HF#M zX~;u7}Iw)W5m#UDUF54az5ZKc=w%!!QNz3NAnumA_&RRfEbGLE4pOP za(5wDy-hJ1o^&x?iOxro?r$8s35p;;m`g*~B}zqlOcgzxnedId)!8TN5gHIk+~J1x z4vpzC6r)w?@m)8iY?u=w(rB6_&C?e$QjLOsG(4?VJMs)ok&XpGUS^k@$B;9xqu zFLk1aYmiD`wN{_#TO|bIdc2%JslSPk`R7kH!(EU1! zHfoH%<=J+tLt}c>vp*e-XjOV#8R&6IOpj>|y`Mw9d3ZY}H7j1{SD!TQe=1|530J|< z98Fyg%u0<%2=fkkLx?m7o=F3g;|pu|DD2M?@*-y zgi#Yyhd1IhAUD{PUm#(+}u{;~~anD@`g_`Y{G>}5RfPJS%!osNH=%tWb0j@|d7 zW6377NZv1WEKOA`4ZSCTWO<(=Y*F4Z^3=S)Y~vi}{fn-1-Uf>i&%2W!%ljRUf4iHb z@HRcX?@JxamSh&m`z4NLsEVbb_cb6{-lq#&ly?kK&!$}->^;g3VQ}lWU_ZRA@dF-3 z;*%or-Xkoi0cW%tVF=;{<&<#+MSpf?aU8w|y%TP(%=bo+M><;vKLF8NPNqwIEG59ozk}NI5T&ytrob_7=3A&3#lQbo z>4bF@AN9m}k>5M-Nj6@|(SXa|faJ9>_z-(rOw7-UDKfR2ioEO|u}TrQu-vv~UK)vP2KLqHmzjjV{ByhD`V3j)ZP@ez1K`Zq8gSs-eA5~}%$ZnxsmE_`k@gWCd;zH84vy0$eh-8^ zT!=romEEL0J7f$mGvlpL9}_43sjcjv+M2f)WKPBE11HSoGa`$*1UJy!2lAG}K=)8# z;I8uGf#yceOB@QtjeQPwYV5Q4gJ!RdX|^%0*?wrY-@OXwHN!NH*9=oi`aCI`f#fwK zi61{r&}@IGnHM)UjhfXt%}$SLwk)n0r=CV)nvDdSjZ|s|lGlu+6wO9L&Ad4I#@^U_ zVa`xyuZw9`Rc8C3nZ7>g%WPku*}h86K=PWAl%m10As5kY4-ee$T7T z8vou3`UgCnT@}OS{Im4CqVyjmj_|fq@n`f&SD#9bS%97*5rMB*dV1}kmw$*j!V4U( z`1sFHw)nHqi8FNa&*-)5ef;@Ke;bCxo<8a7I*Y$t>F>cjdPINcRHJWJ`rL~67yJ14 zDSc*`{tc46c8(*Gx){wxgq7?S8OV^6ZSwJR_Bt^20e zb8m5Zw0|uUyG-4$cYCvAS%$Z87&v>xxbUc!AomPs=i)~kqx*_5H&=1#FXHK6019Qk z-1wIvE@kSi#F-10{!#<<$f^*AOK=g#gudKyl~rNppUo(qf2?Lp`c01A|M%tGDf1Tw z%fB7p3Zk8de1DS*ucGrfFV!R#&;PERi!(1qF#R1hli{9dN%=3|Uc#m%Yu!FUIm8Pv3D> z|C8@Gxu+Rt4Z?4FovA9&))BYs*^2X!vD#rBB28 z#rQQU79R2`_zfvIU27=+pbEKHkE|a_@;4|yU5FT@kHqo)_$Bf80H^#1lwbNxV4q0g z|FaaF`A(95e+vF!3jW;`{Mi(o-ylm$munVD_#0AidhsUlFHgZ&rQq*P!S71Jw*Y7P z*Pf0HBFLBo$05Z(t+9{J1NG-HkbTicPsz`LA7V>|W8eVa3|EOD@aY&YiKZZ*T8x!^YW5S1iE?wDS3s z&Fw08($=z7+}07% zJG(ll9}a8V*7LAxr4-^@+qxEGi@^1(?p(TNU0VlB=!R-2?+YWpi7dEgkp`z8Z&`4| zn)kP5bbs&G_FF;3o$7AE)5E0{k@rzc}dPn(|Ky@T+vNz-WAIv2;ru+#!&kZQ1b82Y9H@ zPf~FD&@fO=sLyrm@Dbwr^eGGf7Uh%j- zr*rUyK>kzkGkq2Yc&N{ZQt&?v@KB$B5Ag7Qy^aGIy|(KcQBKRhxO;P0Up}1YnjOe{@VgPv@@rkmCU~=z(YH5 zAizU?PC7f16SmW@1$fB+y#No}UFSKGoRI%R0UoxCLjg{aR{ryKTv-P!EdTxh56k)Z z*G1`u<@tL79+uk~vm^eneEuxJ!*Y1Tc@aNFnx4x7oKX$m8{lDn_Xl`bZXeR|Z#=)> z4Dc|&d(Mya3G=&KCo(7}%5BmZM+Yz**F&XxcV>(7q@ zJk*ExkAd}szsE1*RWu)K_++gII&Am+(-ha?t;b)fIP=0_a(+kc1NgmUOYao<)!A_unOqD%Q?FZN__canis1+KdMJk5 zyzX!exB1(047YhjOvOpC`(^Wr*%)r~in$nGtK+=Z7;f`~r5JAWghMgh<_U*mxXlxm zW4O%|$_+;jOn;jv%n}H2n`2sB76oW%5JftS}mTU>e@5J8}-_Zbkp8u<4f0#l8-zrG4Z^u`>iVD|4w~;@N z2jFDYgt%~ggeM_h4!{eq6O_Zv81SvPN0o;kzbRmge!6Gv9hHP!crJsP6ilqFS^LrGFqsV>z}!adK3=KT-t{{@|A zd*#5L@~K%rU%RvP`}0q$BmH<5o?(SmBcP4q({Bws`SpOpw!TkKE<*^v{U+D^G6230 zSM%+{PGtm5WB(*Xl5+AI-lG+W8Dv;JtW;Kk&ipT+>T@ZHSMfetu5X`~e-0m%uy0Gpn*M+^TCdE66io7^Ru(iN*5?uX z@S&Bjvn8$q$qu4g58r||K3a0s3$>#e_p)X5VX1FXRCkl@ngw!2zTEKX;f9^Vl{F+R ztTZ#ko5jFFas{rn8&|XsInXMlqTc;#g3*Hew@`MaTroGn?fq3WW^Pb)WqjV74NMb? z-Oj>*Ox1yBCU{&FL$X!K>?%Y|oFrti=2h|Jst{)ksGh}g#w$dYRmEzpLT;@>HdY~< zs*q9@(pQCSsY12^x#??n+~+Fvn(o@_nmrodDj?E+z#1#CHSgpcyi ze4}bV?CG0{BV5Hlqu&+DzmGV=6Z|uJ?YDgV2ZlO$DdzILMF3_ax8z7-clnB$NUZX z|8%!B(LIZQsy{`pqQ9J;9yc|@c&0_>!PnxM-~Txv+dIrUCC?aC^B9L_lEnQHRs7r-KBV{?6qh~?*q8B3 z((|uV@V`yLhk-L+Us3teCj$FN#iyxHg!F~LexUeD#n<4P;TilW=bMU4-$#N@f~?9c zX`?$7{cKV^q2QTB4s)&%x0$?LzGFkj>Wui*bgXm!P;{oLaF7xfaf=c^8}*Y~fDd%T zaVT?5r;s4z*0xpegA(GQ#V?MEkfj^0UbD6>)4pLNT#nlBpyO4hebw3xoo$(=`L;!v z#6jY4MXJ2Irt-27_*CWdixw0Cy^rG?wZ0NR zA>iMWf&r)@O+iU1Gi(whVPq=0`#fQM@| zw*@%cy2HQ1^5>OobBHD|2DwcH5>l-0nR?z@E-*D$pQW!0Uoa1)M%H( zGUJ%ea))(;HDaO($#W4QGL1p;p z8^g`6=VG|o_0||}cD)qC&8`o{aI@>fG2HBWIfk1(w!$_2%^qj9&Jd-qaHxuJFnay$^r^rvV z?=20nlW?Y-}XH^aly^mDh`iT*907sc}vpfpxewnvl`Dk)zEWgu^#bd68x^bFTFJP>WWP%&S~&2l56 z6(uLR1Kr&mAGU{^2DH2fv+exi6^f)Zgx1Sa9{42H)+x&xOs!J@cERP&Wm^tk#?`{{ zF(VN^A^AnISMFPf{S$_3p~NxEtyY>P`fF0US~zdY;e})799eZUo|xL!8v3O#0pyAR z3YaSbJ1B>h;{a9wxKJ?O#fydq`dFWFI#C!b)?%;D3Eap_9_>fzLstJ5rGil^KE4Os zfZ0$?{{GlS7j*E|l#s;!iu{jVs*$J(OsbA{e9%QV`J?!x@fJVfTT!_*;Xg2n_kYCV=0SQ6U?nuSoPc^vyZKTMl|$~MZQuWqt5p|j1tkX^EF z#}9mo>YSGl17(Wk3EDTL&()k3r11=<=<(k(%o+Rx{lk0eYA5MB$M~v&mP4Qo&IJc1 z^Zm9UoYk&@R41eV07U50#o@Rgov4pR;BpjI+5PChonABY_yks?KJZaht6}G>xpZ)# zugFcaxm?of8X>X>yW(@7^$T!EF4P)d%E%@1^qkA}gv&LOVO!T^(5R72xc;FxFKG=V z@fJp@={*H7&>~9`g__-1YQU$gnZ>F^HE&U~VGF?;%CV;+?Ff-at88C&F4($`tW;_t zAUZ7Uk@DoD_f;+|Le8jXog8Up^qz}gT5Y;KkUg16dP+4W#`(oaYTJ&lvgLnP=*jQr8gXE4 zTYe^=bAL|Mcn)g(V`b~BT8)(G1Epm!d;?rD!dli~%k#RwXV>wlCeOEH-3nVQbI^v* z<>24!S=6he&9h%{wH}M2v{r|FQ>q4Fg2ZCDuH=gRq1&e;!sDadT$+2lF%ba1?40EY ztOgo?$=Mj!_)#3sV@>jT?gh=r@=Xx5L-tgUkG7wmf8Livj?2Te!Tl|du{e2usXj#Z zg=VXU9n-TA`m7h)iQ;(niu_}png~C2i1>TO$P53A9=^f1?(FmZ?i#GIVg9W1lDs540Q{ycU^jKG^WUw^3aVV3i;C|M<$v|CqOn zaWgP=ew|wbJ?y>R5#C!AkCwN5yAz|(=`z-==^bv^didp3l;}~3s*Q0!pwpAfRRmk=#WJeXUs|p#eLiSZ5BUQ-$ zDx?hL8(+&D<7O-{mAdqkIoy6Mi)d4A&C_j{BJ+qgzkYp4uXT&MoM&8496{!{Eq<_O zyV;R5oO|^0m&uB%$iMFh^aquGQy9P2377@!DW%Iiw@*J>^F4Hg__K8WCQbf)r9WPg z{$qa4c)8Nk^0!&()Ya!dSTny*={JP*+Uvah2bKO}1^t(v{*=md2!}OiYfxG`o=iH?)pO#4egGx^;pQn_5 zRv7<1QT#(nm-QOcKk!N5PO}Uh{4;v(I$u8Xm0qf#JEsfY)8$HET0y_w$KR~@a??U(@Cz#J}$d^aqt*2<6u<^!h!e^nc`iw(^jS^&-J5t*#UBk_c**$E~3A9UXyeucdI6_PnApa^}u){G5y)nnPoB$#R?{#exzCD z8To$mz83LT<8(;cXNQy|-;5c+x%O>gk)F^l6Sr&D6NU@%BmOD5(lHOtFH`(@6{W=| zet_h^D27uW@wX{{lgguEA--MlWs2XWxK&i+|Cr)8>3uT%vxLw_}?jhrOGcUUaM=TGA04d_Su=G zxRnFPZq##w;%BKG-aq1>RNTxdeXofBvEnl3K%7Svf0Y`DlFIou@TBtmzVd%c`DN^Z zIAeeUTf1vm-#ZOZF1{y8|8C&3Zmg3WBP!P^^hs^nk zpRc%#B|w|2`0X*=_T_n0@!2Ye`-V}Uu^4~5;&a(x5lsI375{+Z1xL>GDZW>685@B1 zIp9g}YFWvndb>+VvZ|*1*e#y4fkwwspRA++|cixV~!L zf-aQH&D~vX60_nO^yZbDiW~00c0p2XdVWpkjohFq!}L)&3pZ@MbLj@0Wc-CvY!@Oa zE0-(mtt7XprL(PLK}Xw4EiQ;RM0OQI(ss?H!}BF=x6dVZP3MMd*6Ydj-CaB@cCTH# zXu}=r^XpgM41XjbE>X8fQiQhLaMg`%9i1qyBuxE~)^Hyv)WHfzq-dL?Y8R!<@!HSx z@EZKg*W+Tf1H{h`@aMI?6F)b=|3%vi@i_thtm2GDktSa@bHFum{tQ1seLacMgcyEy zfU}7kep!GsDZ>i^&QrtR72u)o)!G23%{BhJ1Dx&O@GSxUssR6!01th0{wBafAEG@0 z&Y_pd-yh(i&yMYj!}1AzcH|2}z=(%FJI67T2*lYpoBV8mvoAM%PJo{l;EMvBj|j$p zV}NG^{MG>HSk?I7AK)hh_(uc$i~#>^fS(iKI|4kchr0v(bpihq0nR?d^!agspBLa0 z0e)tHPuC8a<;gzVn;WmCP#c&(H4#jXAzYfQ68^4xgxQ$=Yl}qq?@&q9p!)^SU zi{UnYZH?hJel5jtd)^v~;WmC9j^Q>QEyr*hk6PiH{x%-XYCa6N@n|lF+jz7!hTC|w z6vJ&iIuyfgJUSf1Z9H0z;Wi$%hdYw_v+-zF$Mc5Ucr+KoZ9Lim`UNVr_aC)~0tLi5;3eu4RE5@iRE(f+|jP z^*Dzof;`sYbU$INQ_k$me@{fquu8DSF4S4fy=gqqe$LaP!ybM(5r8V-CP7=0%R+V^5^6nZfC8E!hz%QJY>+&kQT zizYv%r#uOU>kEa!-VssEwFU4VAnyY$Uw{Yjj>6!eqe?~WognAn)>-^?+~ECLIRp%Y zy#m4fj=w?^MTSv9Shgjt3&{Htc+;^VjYPGG3|c41Fr|v2jOt#0?{L>l$>d;>=8>75 zj%@Yps~3Ma3Msn!Lm|@>h0K7Ex>EB?IS8Q8SL$_E)yzRa!_H<@n@~S;9+#SYog`0n zj@y%=RYLP;l@zN z@sW@N)k0oXA%umdh6{3bLzxpAcJl5FJ2QvIKG2MI;Y?AC8>z;)QN2^S!5ZT}5OPcT zL33xnM!co7?0H;`9dXEu_|@J)@gi-U$%9F&DsvWBh+8pIp5bg?=v}MY*9^8Vy5q4h z#44hyRG2;z)FxIF)WV@iU6b7xSvbhthp3y}0BE0Zh&LA>@@0PL$hH=vt#M#0&sy>9c1T14F=HB@r`EScN+&jm02c$V~B&ETU{1~2p zKX%_;<0J9-alC%1o8F0h#H2@PL+>v!oJJb({%rYidw-Fxc9iA(m{b<39-P^);vFQd z?6Nb8u4kyS+sQQ+U_xP>X<~3O*aC*&JIxZ^xj#X4b@Z8G^qI-gov&14^lTVCn;hLa zRwYKC9Y&v>9DNyV5sCx76RL{qzENsTS~9akDmo4E6GYYHy8y*G%2WuM`ttt@Pvn2? zDd*G!&ba3~I2(g6Qz1J-AvTPdr^H=J#LJa9oJ4$+689w$uTbJh5^=r~_a_mrRAM^JzlTJq8{I_$0d5aL63PoUaiNs%CUWKu7H-n zCcvpkIOzHz%n+{82K&$kONIWeo7k214{pQ(gO^+7FxX0PAP*ktL%}C6IUr^R-#9E~ zx@Mz~XUt63X*gqK4$pfYVtn^8W{SwjcW-4l!NnC81SFMlEaS-MAe>uM2ZX8yo5L@l zQt7e(;9$$~Xp?t5X!1{@i9hMYv&oNr9jt_2lGtqZW86L-vEiiO@+4{{A7Pl9Hh3qA zH5?6o3TSj7XOAxas`XMErMivw73(#swh0&25h0kv0SeaY?x=W(L%sg4RdU9;V(;88}Sfjz_EzlWh=pfkc!fViqLFsjOGqgmEDwe1^s=I9#l~ZnpNx-6>Hw8(Tu6*cD9+wR`EyV{)e@nK+lZzyRRpx=#wP;?WK zXKB6ks3Fo=h4Axqm9esh44(K^Or^p@l^^P?39!s1W5(tqpi zKA~nZ_f*8+?BhSE^glz>kK%t`e3vNyDW!`$kI8>mq~9T>(-!#n&UH)ln}r6>@Ynpa z__crG1RS$()Nkj0Hh&vi(A6w6#}d+fq;g!4L9qAoS%!>@5sd_{<1lbtf;ews7=9T` z*J$zdxh_DNFE_sVNU@59!P1YX7r(w7k%)2qAPfgpf9e+oi*LuPK(zCa?_4ejC4@L{ z+I}{(HU7L<1S@|Ny#yzC(5?zQcw-UvyMzBunZ>vJ$7JGV&nT@rZ@NmLt1!FzTdo$l{(r43A3H>TWNE3ZBuNQ z($jsf?5+fYa5|~V^UzoF%_w-dEZMMb>75&?Xr_6??QMtxpP5cxMlx{~iE?nF zuLMdWleu61-5L>Vv90l*s#S}(lLKSJuhDi)oVUX852fH=OTjm3lZng!R)Etcnf%k$ z7c8Fc>J#H?7k{lsWFKmR8LpZV zo$h$4@N0Eqp9*jyLCBIdH?dEiS*bj3?SXM#5s5rCV8>dBhv>L3 z<%v|wrt&z|nARDoJdHlBGgEo8p69Goo}A}7JC(=H!?URTim=V46U5@lOq3NSR@}q^ zmV~9~Wbwo;4ND@tPppa(2ZhS5H{>E%JlS6@1dAszAyS8tuwOi(#9;Acq*@3TPXZxq zQQOgN$Rw>>JSj9h%+(X<=og8Rp{iwHq_mr>CkgCOJ&~QuCkgCO(y?1{`1N1ihln_H z=y6>?As(%t9O&Po>nAK;H~a3^rlR$bsMskl#H}PN*G~qETnuCVJICKRx9Hz9{OX3C zoYEulTx@FdXt{2hTlQk|Co1K2J{l1!d}0)Bc2zWc-~GJ4+P(P)Yw=8mSiDCwd5;F0 zAHQ~PP4sY0f%vPod*1Fo#sHaPUEL>i|Em?61`tmQ15q3rCZ%<^B`B6F`3JS z-j94v(2I>$eoIFS<%7yY4c~?u4~xCQ{*;`By~_O&$f)c)s=uNZe-i7WKTg(c1TuH zDP@@*bx&8anE_qN-dPyzElbv%@c?fIGoqMy-ieiLtO*V}scyox9)A+XdtQFG{u$Ns2dSCHD_5ki(B?9*_J(zt0g8*%jt2o z#4KA{Vv}bUH!Sne5)-##q&(%fR>sNi0zM}qwHd8UtWOT|StXB0?U~%((|nLC+XNa7 zkTDkkj77SIgLZoa4eOwD<)U^v^kKXcwEL$r9Qp`Zl&Nvn96YZ|<#9tF%6WAvkE^8Q zIWd(-M`hr7O)8HY`cTeEsXT7zLmm!#Y3i!;<%T}w;m|jk#|?d07J>VK>mM1>jdv-U z{Uh15e6&)R!q&Ea*mXxR=jHdk~qn%n6jr}7jr%5!n0O=TEA1Zo360}>aCTO>a zcI52z{-|4o^!QBycVM=S+f#0Q_GL z6jD3)Ri)P5hDZ`+u-FF>mf)`CUSYuu^H@nz)6!cd#ZkmX_*W*o4Gyc&mO)?#=^j7h6k_> z@^jFljBRuK8+U=u%|f}#0P?YRu*NK~I`N2gDyOTSIEgf3RUvV+&@2l?O-Id~18__1dMIa&uV zR}8k5p{#gF$r)0_bMUb`f&FLrfIZ0dTl1ls^nmyA+6I3#J$}#!1ZiBU1fadGE-awq54z5Fj#y$(!$z#$al+8=0DAc>{gAxDJI;? z-_lC+A)Ch=gHW&WdH)#K;@ka8^C2s%586r!2|`Sr#Ih%QpE~;t>5buhhv`7NrH@D9 zs(VlR>@)eF$-E_&VC>Q{CH#}`{|g^7=94~TZ^Y^YgV;_SX~&80qyr0r*hF`V{L{cz zhhzDM8k;M9sw~XYlS>u1>xGK5dnUj6W=J0ZtQkLb15r+QSe1gmHwC{f1^+|}{`nOA z0pQegHXWJ}q_4qoAAU)CehWDH8?}O&&)E+ZzgThBMTTebBmbKef0v+{%!`VDT5;(^ zfXzS=lmBeBtI~G>KO1Tl9;!eUVC@7B}e727WtGV`>Ek0 zW!S@KF}^dle$|~z*Q~=nM1bI?Rsn@7!Z&S6qC4A?m_OSR?hdr@)-@Z|-OXQLvq)q_ zs`2vZ{M{bX`$03pVTSoIeNS-?E$DV-_%`iGi1U6J{(}_!Ofn+G`8R2kjLZLSfYWxG z{Bvl?5aM#)n}YvU3f{)4Wt9{9a(yhoLm#-)wOugX5PwbJix&EFwWQ#mPQkyEg8!)u zYF&Oq`Q;S+wdzw$JwyH*Q*iTPCqKI)E9bXqyJPXO4I6$_fYSyWz9GO_gofV};Iz$# zKM>$l&G2so_(=i&KLebm!ubC^z2*aS}{Vvzyr%Zgw*l!_98C#&ENn>U($VQTyJ_nfJyy$LM=k)-ez> zl9SxLT;DtP27J2PD<5$$;p&J_%flFHVc7@|&Rn1M+ZO1CB!>}L#N#&>uDf?2!5v)c z!E!0s@qbAE4~i<_kX4@pk%t~mlRWeeVBw9YR5VC<@g%ASp)~gV~_~l@El?Z(do`1%ub5eB<5LP zbZgtAx?c;9vR@01bu4ilWxp02r?5uiIF+AP!%_BU!ExGZUSqKq-W&Nt?t4hQ#D^pD zSUHzv_C2}dvfx6++&jvK(Vu?|UmJ-wLBX^XH$mZ=t=j~JXSN9nh*SkWLaC8ieHg`U zg2FS~1O<_ur$BmS*#reqvi)2*Lj+FLL53Vzx@YJDb3i71rtxzIkNiB6a8@P1!Dkyk zr}oItBl*v%niyTo^AY`3?x5~sm60K4)-+E3vKwG z{0lI8wmHmxq=+Ji?*;uYxDAXs&|&)8wtt~lo%2QW+rPYkfvEbWA=WN1xb0tFZ!UHJ z!!hXgFFTkqb-Qc0mrr5F_t(NFL~*^_B%JVHfm_{LJwFNOt$IEa=Uf2gy*(M{1wE&$ z-h4f$t6r0y(^c5_F_WRZSRGg-iueFM}phl3t3!KKn_D{xb3|_UzbQfCU0(g)yX@L zD5?XuJqj9*I)&|`sJQKIkKFbsgY8)2aH*9()Vv7X_Au(Pp2dW~Z7(K-y$ItqhC-6v z_Dl%e_5vZyvzkuG3EcLeqPXo1W9a6MVT>E8sw19pqk*MzgEhu|Amp~PaBg_}z4f&0 zd0Y)Bak|-gTx}@JmUh$RsT&@yqcUf4g}4f50I!ZUMr#1suYm6?tCgkrFc> z45C0hQO9#+JQ0INj^_^Pc+O#NJa;JL#&ZsHG*xx#8&{dC>&X%=J;mz~nIJ$U{tow~>Q59nHqo{p_$s9%Pk#Q88 zw~ih5R}2tH(2+wmK}QZS60UiSL?Z`iF@mV-Jcy1R9FPy6T3jd)z#hR4M%ND)VQjcbCUvDgSx4#=fET^4!AW=o2)o~sTa6T$(95dARY z^j(}%8hZ)-Fx)|&e+hfSaSmwgS=TXdK^mh-3*A}E^Xdx7^!B@~IB7_jTdU9*kybWZ z;%iVsv!{Op5MZ0U148y%`cyS69HK=-w5O z(Pt+|S64t+E^c(Iu7DJ-u7G+E#P7m6_o4V?FC{V+&@-b%9aCTaC-C|ENu?_wx#@V7lAH&7vU(b zcQ{_JblJNI*RppJjhXjyjhQ{^tf7&ZF=n1~zPHtZm56 zF7d%Y(N9LFpYo@A(XVmCarCyEw-;MRH!Wtlu~G^J_?UM6iTE-QR#+|KM)H^ zn!HeO!KMb3w=o)b?Jm0AHP)`8cD1`!i(RY%*#=j(rrMvfF0N6r8w~o3iW)1WzwdYE zoO|cadk+Fuf2}f~^>o~OJ#<{XOdAR5twX4NUqC6y1( zu1|o(;t>O;u1^MdQD~w#u(fM@fJaQ0x;`cN#27vqBOyK=_+U^q;`5on2gBVFpNE53 zB9>2G|15YNj%L>sd=?lJi53z=KTPNkk)R*8_eTZ)kPQkvD){|ja5-ZXn^`9Nv0rEV z@TgWZ81ZD=HV~B#-fTUPQFf5R;$sJ|v^baZI`qX{%LGkg0`ov?@QjM|w^k(JQIY;m z@QIirjorc@mE-S?9Iq#{i5y1{W2Dd6!HL$#6oJY@pFkEq7+EHA$|jQMABL9=j%F+3 z^AY%%YJ^o8YJZBV@PGq{#$H|A7DK2na;X2&fgS3PhVaD>b+-dM)E^7sOC0J49oV7% zcnFVos2_4*hx(rY@4&x~ao=~i8xO$(gg@G@afO)gL;ek+!_kjxKd$@DbI`egm+jmH zyT(0*!UPREd}cVUzb@0o;WQKc#3ry^2<@4`Zn6y7+c~|F95OO{OShM*39Qk8-^7dj zO;6RAQ%wPk==t&q7K|vSa;gzfMzm7-RRputdwJZ#o^CI{+`_0vt|}?N!g7vi_3}vs z9hF|rGrdul6Jw#wvGOh1=V(H+W5AP%3rYtUI6jEpY~hZM)CFS)X?Uq&pbG<^;=v07 zAAFS*BN_&vLIk-l>nknnX~XjK2}|=J!kkw+NS$oaLXGacvF5aOixvcE@t|Q04xtF= z84JUT8zcv~T1J=RUo_uHO z*O&R~T5S~HqT$DTpuV5rkB-&zqhgu(;;ZG?PbAb68U5?JTY6%xlybPv?z?FE)6T@@ z;97e6Jc0U6YytL%pP*)Pq^^DV&1p{1 zK}#!8m$qva1-NDEl9Da#9FhvT9GASq{XiS;`zejw4-K*`hA;$Cn95++eSUd$z5(}( z(0@G7&d&{}Zcg?$QyAqoWM>^U6!({4WJ8AV$A-|GY6#MmFzL#)_GK#e^(KcA5PP=n zgRyk`rhO~cVYT4C6_#0$aO6FWi6I&wG=T*@P!O^c@>!p6cdR3M1QU%$7mO?(H;(_vm4!Q?)WZ6KLWSWv zi$q?GusXaseFZ#FeqsHf{s;inkJd3eXfQO$B?+wDk^uWk1!eVn#zDnG=38ywwEcxR3=WZ>9 z>M~X2D5}Ul!#IZ8*xG{VCMO~F;aHl-0x%lMY}=tTwdJ{vtkX2rn-y(|;8fu~E(vruRA;V#JGN?JKdmO;(o&YeqhaVN> z(9y=-Q98TY8Vdps9a&c>DIwCqb}gVNS3nVK#BNH}NO%Ul{l=Ck}T%jUm;4R9CR(Vx#em#Xf=>6Z+p@ zOa|itJs|!y5&z1-f2a6wjqq;|_#Y7e7kJh93!e+*J1YMBBmUnC{B_^n6g9VoA2qi? z<#|L2;JYtFD@8QqLqwi8?vay1Q#;f&6;w@CjOxr<*PTV!rXzc z#68z4s55O29Y@Xm8cBM0I46cjt&#tlWssZG}-;oEuI}iRr;FR-8PCUYy zwh7k<@t=$Tr+}0GU&rGH&a_3i^23Mtzwp3VIMW8T*kO+7{eiBKTD-2sqQG;CemqTaWlJ#5+@P3@yRp4!LEGX*d= zk)D7`);##<<<<51mx`h# zP93ZKX+}Wj$NNut@So(t|A~naKJHqOgL!awUt*VjrBqJJxQDAgPI$QL;}ssR`nb)*RUdbIxa#8`4_AF` z)}TPWjCc)7*|b?RPI3)OpR`fTkc7#VQ(c4dE`+vU?#0j}ZFuqqHL`bX=mDV_zRbA> zF_N|;-x?GM0Y75|grS?5jGp55c&ks0;UC9PhG3D#wI|kwPZ2IXF(d^-5-dES zg&M4MzEO(qBe(Vckc~rz>6p>t5JEI;ZG@%jty?!E!Xt1;o)V zacutyWFFpTOedHM|HLyEDHWvY~ zBt&|`{PNk^6TTc@qnQK!&yvgiJ%Ypu?A74xDre?16;hJ)?>Q5&l_5S+;Iorpcw8!c^g zZ^MNaj2en9vS3jp`0W;qS|}|hm~ALlZee^KM_9bc!bKju#KL&>BGh-7*W$RAzU4^- z_04?C=UXtEDYscLn)*2wjHZ6B1>+H6Zna<{0?rc&VN6`gN{1y1DUQ(UXX}e$Ryq_* zUw4XU5}#!i#E^Wx;(Xzd%s|r*8c|0G1{%~g|4ib~fYdW3-DX2m z6`eLEMMl0nO-Z9K4lNU53+ii=a|!!qr{`HP`aaPF5|mMGLd(h=7N)e>1neu03oYy` zj#pXEQI#~#()!xuqCbk2AzyyewS*AX%5VyGM4g`Q%m-_?5*?aKAl#vUVPM-8c&VB$ zW=kE6(3Ks}bTMM72t%HTrQ(IsOL}oE70K=Quv9EZGSK~N?a5T^L}BowdO+08&(hpWU3?sRoKavt^u1CyO1L!|m9PHjv-9 zX(ulw^OHL>$!ElRa`3fa9GV!SyA0jlIhLJv_Oofy*n`iStp(PQaroxsGtK|mk$h%y za%cOdow0N|2&v@TY>(M0d27Qs_?i*2?nv%5#&0{t_>KIe2X6VDz|2a&1883sF;zqb zfvFplJvK3&TU}GJK0B0fqa`NWn;dN&igFsfh-@krb4K86#z^*&i zf)Qq~{1)DyD)f3Z@kj?u3ZF41g^y%-tM$e1?4Pr~XpKDC76JXce_7EZiN~1deAoxVJ^ZR|Mf_i~k)Y3c}wWgkLWHwGsanf&WJF zZ;kM83iv-D{y&I>KM;i9DgJ-THiuVog4=PDFP$IvWz6HJ-Uaz-G_<%rex<;7(w@7$j zehq)BHirXOSwT+K=5Y0R8@@`?qZduL`|Qh3ztXs+I8~d&y;s=qFIStxUDUa7MmOWi zc7isC&x@^{(YYjmdnwo)nl=Wq{IP5fht4udkD0a!w-4f9%%7}>{IVZK+rJOda0t${ zMY!^_hxh;uqTp=LHnchXoHWd)?ScP({FDAn8uq}MHV0RJ`Ve0(xM^#EsmE`OD4KeIc zy`*ui*;$(CqQ-T#FaxY_Sk*F(&#uiOpR;WaJ=EA7dYIv4Y!2z+*c{?S(SgCC-BjMudZJcm<5a6Y~$5B|P9_%9h*4n9+um>hV09{iy^`1Ou0BAXh` z|JMnQ5rBxzVY!1-WTju};I7SK+QD6$!%sUnRfO`{>EN!-;ZqLo+8p*fI8}l2`Gte? zR`DX~4=`Q4Rs2E+|6|x3YP-}88R%Hu`LFu82lsS}YkSpi&=6OB3{_~H(yKm>d${W3 zgomp>Ug6=YkJ~(4^>Md{t3K}WaMj0ZbEq3%Pn|yNh8fpiKV$mTczkMES()=YW5#qm zO`BSV3*3sc?oBS7U&vuIaRss0#lj~=W3j#~!~2A}ec9U_!ZzqRGmvp|mWOJ&XJ-9f z%e`Z2mp93s^(Vz-1vpzzfO}_$W&lJ&^F`%C^Tp5%fHcYXV)CzWw$Z*qwq10$(Y^xF*sZn0 zZM3gIJj}#!8*SYW^0}B=YwCWG&&4!bCps}r3}Pw`Hte1l#1s!U?4B6Jq)DQ^rj1+E zG$BCRkfs;aKywTkj=(?@BhAi+-Q0WvBgbmR^b*^!o5q>rm@XZ+K5d-2o7rLaN;kWG zz6^G)wmT}*KxB(-VBO!FG{bM%8(4$t)J-%mMR)SJCYsNq-wJ}`nrQx)p@ESVj3=?x zC+48o**&z|!lz)OiFt~=dq z5z!99G1FxrG9hArNhI7tx(%Tmi%fdzHqQ3mo-!iaI9n*PjkATEZJY_HIjUJeLV)I| zOqy9hLV&wcvlC|TB@){Svyen$J7E@*NZ4Z`p!Tar^_>iMq&A%}l8lqCk-d-ZeQmMm z-q#j$_r4~gMz417Ya(j&den5nh+N{tbcuArj$)%oZpvi+H745$vzW%DN#cnw?1UYS zX_|Omi$zRHp^xEgfXxY9b~)5UR(E^W=RZ%A+1J_Dk4Ck}H<`Tvgb|b3A{(*`%{n>& zr#E;uRPK6U;Uk z-e6%2ZAA=h-)Uitutwm&w6JgDw-JR*E0E)C4P3qoL9+~oS4+Sgn*yI@E6!b|gVPYQ z-y}S(;Ml=eTaeoUD_A_p?{-wSySULKLPT?=-h$Cwd4~nd+K0<@@5qKAMi?S1^M)Ws z*k}e|5MzVH7`0MfL*^6P@ZAu}#I*+IY_Q#SSmeLEba00CF@>R#+&y;iG7DokE{yx` zAnvjIrZKQ=JZCkGs*NgV-@v9>$&yVoyu#2``b&jHWK!LAtz! zvso_@`|R(aUZbkyvh|Xq4dCV3XMfy==?~jJYigInK6^b#J^Soh8~U_;ww$=|^0d#6 zD&+B~;#ph$QZHrMTw{wrf>G6Db_&i`$b8vz7-GjQjA|6oC9(ss|B_E2wfpv6f$F~B z-Rw7OZ(V9x?4pb2MKuq$)@5n{I$HL;;LSgo?Q|_0SIc5+VTmyw#)w^oB}PZfUJ%4+ z_Yl_8DP(Kh@qC-i=0r zSnS_vmlgQ;jG<9E?U)`A|94_gFZ6E>Z1Q)Ce@%pcWx)S{_@B19uUd(He^E(zWZ;u_-lG>8jY2l`Snm8|_1NamThdk4cS*3?)s=P4 zRcmV{Yk%)c92{u>!y| zNxzY)Aba8=B-nJ4|@f~(E_s|CMK_6z<2!qdG*@Y1+>4EFg= z0MC^!yU#Cd%1^k_FKD7W{f0njcK-+1>zC2wHoTAS_G{=o)B9Ze{Te#QBwvm1Beb-> zPsP;y-lngdGhtA3^p{&Xmtk=x);zu{!}{Vkhl)5hO~x&3ps!KeMavFqZ@ zZ`6EVk-&W3m@Y-l=V|yui<_YX~sNJD%7(8P$ycrnhh z_trS;xq`q#e!N=97X}vc>WiR82yJ}tnQ-G2}>e2%`t z;$ZX&dp#p&uVcg#p}5;VpP6r;WX#{3HpAzfNMM)B9hFN^}`afW$>h7q#U$+kR zsL#tu-4{@!?9Z{gj1B}RqS0s`vGlQcGF@^Qnz5u0Ksg7E;5m+YJ@*zdp&g7m!31`& z^Lmqe3(@(b7g8r%Y9c+0u!qe{c#mWl;~$0jf>{&wWb(IdM*dSb#-EJ->2Zzmi!H%% zjqwkn^9wnAWBmWL@F^JM7oRr9hpiT0FwdlZEZPzn-~TpYvO6%w|7{%4cv;jK|F_v8 zN4Q_|X=D6AF)=^?^o;T2zGeO8**5Zum@XOZwP}vej?%GM8!DP-HBa+?+l!)}B{}W; zEy8+9L{|xh=G|)0f7G&sJvZ&_>@MEe!S(FqQM;KxL+7%~mtL9mmUWA^S7sq=GXETV zWdzhN|2f^O`CPYGMv7c^`OjtB2W^p8Ws$KqbK~Cnf%h$z`3^6WP zvS=4aTFhM>Nkr}P?czuxYL{;pM-s_pm;YQ2yZq;3*>?HQ#WYE3m;YRrUH)@H!O<>X zdP%44@?%iF+tfPoEVEbNp_FMuN3fOkWgv{$<)33icAd7%*OMu*do>Kw{^Yl^Mm0KZ zm(Ls+kzGFMS|!KU$@Lz&u9xcuxxQ1be<|0Ea$P0Y)pET{uJv+#hg=)vx<;;R<$AYV z8|B(0*R))l<=Vn4>_MDO$|H8CU0oP4fm85uD=1s zs7_$_|1QLpW%qwC!K|%~yWVG`flu5Mpfm7Ecs}nJA6K*w029%2tSoqisrqg222ttY z&5%SE7dZIXL0abmr{$}I7Z08t1~!)O-YSExHY*N-MsxkX05?{!!gGr&0}WvvJdlC5 zunr!`z`!CyB2rrI64%5w+(djft53N4KsaxOPwC+6nQAqSb$rGSPP9H4^$ew9m_Qmn z7-_OrB6Phch}Exg?+tv)bUlK^+5w+Hp12z;eFAwfbrQ-$pFkcyh&%}|7c%f-a@;EO zSHPkx6dnPR%6xhK3$!EpLX)}NzuH_nSKzWRvt^mNU@KmbbZoJd+;(=0rN*H~{FVkA zZeyIDhL28q#L|;+M^3TyrMM%rSo(b2kzWkv*X>^>%UJ7JgvU2-?9f3&-` z!jRk>K&{2FjUUt&n+D}mD&q$o${o~}vj*i;cF^J6K~2R-YfwH#gTlz4n*W=q-&rdT z;smqQez{#k(1v>E>WcC!NbS5L#n_+uR`?c2@kS8{)k+TwFb1mL*G${6)e zu4tW^qBP!=uJl}lKrFgZXA0$)+|{7 zR1^`T)Y3)tbvbw02c@@UL81p5*NCuYL81p*8lXY+WnuJY{Q{UKBGDT$vs86C*DpMk zbN#{s#|P6}8YPx6T<7>eQwKi9gWTTVatp;VOBw*;O^*n~B@KW*U0u#44S)khEz8!h zq(KBSJ}7#P7ONUWAmf9&68HoH!6y{Rta3mUem&tTho{_{czTrsTBdKjz?aaTb#Qu> z1Ln1%+Ocg6mhA<5nU|kFQs5FjdttZ({&7^nW^Qjl<@M|Gk0#P6@v~!vEs|{{!NGdX2-&ca6ilu8=~M z3%b-1mv4>3Rx$2B)in-Jc=2kae*BCEz4WX#4kHae6=BH}9}y9!;r;mh=X`4%z9RBV zHUzviyk2jGkKPAFxEUN_`rjhqefftZ{Hd;SSazM2=2X`>?44l4SJ_MO>!+2^zU(A! znq-5V>KX@KWAk!d&5H4e9#1~3*gI+p}+FNHM@rj3CtZ^A#mab^17Ls`{cHit70ddfhYMKPIbFa4&Kd^`IExt;*VVPurn6wKamWHKz%>r` zE<9tvJpcY{92Pli8EDS0Hst@|;4Cl2$6#cMju#i7mj^$CeJwb8yZrBT@N?m({QsGa zADqws7kTg-Y5bmp{=qzJ8Geulk5f3|s-L;Wp)S3CO5=4rI{@bhoZy^+S+i!~>;bxw zpEFP@Z4=X%;17PsV)aTzD)Zx1`{6R@%u`IbnVGSH6b?jW{TwuV(8IdU9Ol|t@ocK2 z6`#+GFnxwWQ}Zp|c|O0X2T}#QF^2jqEx~vmBj)LbU%zg5Fn*XfmbTw3mismhzW|lF z?kgvbDDitmgybv^lEc$g^#Dy?M|VR_iro)#h9C6Fy&Y|j05#J&L#cv3nQt7Z>y3T- z(}T^-vXaL*nKBG}x4_p1d;r9NX}0FkDWEL z7>;`FnUK0UIovuHLGU!tCNd2J?Qh;}88L=_gt+soQV~i~5hywS+jcNP9Tmf75SUnW z-=E&LVi2&k2=d*A&a|=$kwcGiFqI{+(moNR`wsJ!!(_4DX^Uk} zgT^m2f>`>>LD{4Hzf2;w5JjjRAYjz7^i@h=^GWwVe+2ANs)-`*al2M&K4h2}5AJ`S zUTUad894ibds1@$D%{VO`*FB0llzNsKSAy<#{D?CzXbOzU7E^|pMAkPk$19namF zwsgm|AZq7lQ=MD-Og8lnn0Pz343YM+iqAr2>_~NXT3@3zwhWW9^ZxOibM5>>+*}-j z&MgMwwoEV*F_9wsS+n+|W|heVMag4JV3mOPrDDI%LR*5FA;B401kABw7?d(6_lhYi z6MGht)xNiQD|e`7Eaf2+vF~kFT+dSW? z2%GygDK+^($*1L|i3c>-=cP#mG-Y{dY@RbN+N!HOG#+EQoNeXJpr1<2g^bUsDZz|x63Y%S=)OHNhH?x-a-;dnebEt z|6{5;&qX9=%|ctu6sz4o{+L}=z_*Z_y0KxMWXh1p1&W}9WJ`qTg+x0N*92t7_!xjo z#H=RKt^r$249K-Kl=Z?OTpS=Y#39Wk0TLHvJdvPP z{y5LLM(?Dztq5(mZ9>gDq4lOsuRyoOZlgP9hnWGMLt?1h6Hl_vNe@yZA)eDw?=@S zwDUusj|OGv^BLo?jwJk(L!n9F)>!&Fd~vi{dq4)X_J9m)?E$TgAngIk!LbJ{wkzKd zDHj*w-`WM@xp&|Ix+zFIZ3p?$f9L>4Qw>dE2MBVM3VY`;`uiWtmO~wf{sp9jUNE6K znsMkKZRjENiTIxH|6?nO@6QBi^=arET+I|tOett)e=D3jYeX3jJ)7&mTiK6KLxkD z4@3CC4$$U4&FZ>Py=@`7#(We_>;OSPJCh)&EiMhpr>I39gNhxXAJmqw2F;NgSsbEp-LoEbn&thc5MCOuuIa|rYOU~1k=7R_^)%T7T@igB%8sGJfw-aZXz-)9)wT$Kn)geU+yra27 z-5BwX<_r~O#5g}YLUtayP)$?~Ty767dh;r!3 z1U6o#6{AJ15hYP;#b{A$L`l?IF%lIkJ%Y5V1{BQ*S}_8QCZ9Hp00SdRgg!5bJ}{yr z8blu$Q4$TJS0hS-5`8o;Xv6v4iEYqWkqX7-`OKmVY}xPXw>?cl=L4$Sc4l9ofhGy< zIHfH$UZj1MLd9q97OD#^q~SB=*NDf(@X+ecmYv}*aWFRS#Kt=q8+T%_b}(+^O6*bx zv&Zzc_rx7+e7NJYjD*znn!P}$E|WnLz+K@j+NmM$(X^7mh>C4kGp+p)0D8`h3k^dN zEi;O!;urX68Gd2`a@vfhVQAoD^pbMolAvrq<44Oc zLBL}{e$O;RnVHtUOvOIL#1S7Pl-J&Y$I+S~c?C$|;g00Ko0EqzXabpIhn~jIj^+4i z-?VRe$^7I#^aL2sgct@vNiq0Z#?o0{P?xE|cDQ{e5uIbvdqWosFb40KqOAoS_(V3} zoE&KWPh`O4EV@L#+OCY7tC!e4% zQ+em$3op2xs`kSPH%~H)dX)0hW^~5nhvX4TjQKLO?hF)CCb`eclcPw*ufsf{AzhgI z$0~l^`3B_AqF>tq7Yqmg2R_obmIhgJwD~E7=)ss`rqtxo(UL9qA#+i@noq5aA%+}8 z2^<|fPu|?L0$n6$s3z4^5WNV1r`MlxN1q23fCu8r%`7yeJcP@z)tS>FN z1e@u0;X{Jc96HreM*`h%x3G%a?Ha$?#Nq1s6ZqEz{!{~W`ND6s-mzzR4Z?pT2>*ci zzs~jFV7yKIJH?+$KMX%F2!BBQo6&a<{70=llLX@d9Toqryaw^N2jR!_g9@&bYn{}8 z)Yf1>;o0JEra#qxNhsfP@#p7G5Pp8>zft_n^sI(|L+Jm2_;W5d2!DI%zf=6*=K2>_ z7y_p6fcSSs{5t~wqbG=eJSXtrmhngBE4(8JKU@5bIfeSaEtGG$_@B>s)PGb-0Vyco zM)AKo;y*F)e?a`-9r52}{INgrhP7sQV%??qMEe!LwDu|P7{^QvofJg?eB5Dl;5(H_Lldop`O_Gx`9 z9~|eWmCwHHBrg@)rIawIZsEJ+$4`})EB<9yzyt0fFGBCp66N?M-5+wFVWx*Rb?Qvp zfrp8L>$7QdfW2PuZ{SL&{>)$Uxj|T&HU?O&;AcwanzjYl8o_T9+_Wjc(t>vhZrT!H z8wD@q03qB~dx_nLE93nu!A;u%j5?V3tBf*_#l&PL_V#e7q$OJ}(bmlLx;m z58e!%wu@&<0h+c6@n-VS8=F8HrBq{=-*j_*?Yi29jrY_xSG3eN&uOl$n#T?G)u*DV zDUVNiGd9<+PS@51VeY6+&s|+xeOF8C+SuI22DE~5NyR|C3VZH@ZB>o=nbS~HUe(-E zn_M45uqBOamu_gPjX4H?G1}xsNMkVeo4dNc$xzDuf_X$$a%%$UB6C(YuB(MPUwy-> zmTX_z2F4tlLO0~`EgeIH!8>Z3u{-kZt!r1-HiveDNc)=F2Hm?kq@KTYSx98zdTy

&+oimelz)GesBMxVK6pz{{l${wb-F#Q82L{m=5?*Pj6*IG?`BvE_@y zU-^6{5B_W({Bn7L$=~JkYN@Bhsrr>aY3QidM75dcg!v6|)u$^woce>V&HRS+s&BhJ zT=i{_hpWEr_i)v>c-4$kIaS}rJzVu|!oyYHuJCZxw{0G-`nKD{Rp0h_xa!+}4_AGw znXB@vzKu(!E3W!B;o+)pS9rMU+cpnZecSEfs;{7S@CG$Bs*zk^BR389a%E+(hYNmZ z%$OdJUq3^(0X_*ExgkegCrs%@Y~<`fo($p*av*!y4q?eiL55=q!7{`Fl^(HaFm5%gU@xvZe?>0$BdOm-umP!~%vd57C%-{TV? zwwZ>Lf>NQGN9{c@PDFt-nBwijqwjeKLiRt2cYn~%M0GZSZYb5ei)~OUvwH{g0_FFM z&!#eaQ@`nh8Dc@IUP6x{V_ngc$xmSFv4Ya0 z5`}f5eb0KWlU|9Xbn#|+9Dz{$rjwV-lyk1ac`S=Q&b;%*ADc=tXLM|#FkuEC;(%ro zhdaO@^`Fx|s_@(4_{0kO!SP!)pji|8w-JY1#UJHSxY7{to2#2R9KRJq|776bLmbW= z0ifaEWckN|_v4?=jPs~}vVGL3zqUghjH5`}mD@?EG=&Q+lb87z$S8J794AQ)kbGkx zJ@S#XR|1^u7|2{NUX9R?{~CDkyW0Pb9%=Y|V;~xy{9UK<>owmPNaG0QUkv8tC0&6a zswN2^*NDW2X?0z`F_5jY&Z|d=Pj(EXOZo?=ItD_k1-ep67^?#zm0!nT@{NI*MJJ$t z9RIHKvcvU?+>`DPIR?VWUW{*K4ngo+Rh`k5c;HY#u5ahbd2rTa^3m`{rvjTP_~jCX z(WAf;f-e!==ucp8#(%DO?-cqk3BA#$z?$>WZxH%XQvOE20^1_^MS>f>3akVFx#I20 zgMUQ$d_i7(qkDnHg3fa_KQ>#Nn)7_OrW;%NB_FGwF+JT_6|0o%Qup)KezVVgi+;A^ z%UZk}@wvXRwqaFzHU0Qy>-fcPZLMEZ6HC|QNWC?U)m3ZEUHHxGMiKqOjm55H8sPZ) z^PSai!Ib1XalT86w>vmLI~D)iJov#p_>hCM9F)&=DJRCuI;r?P2j{So;y-tA)@{Xq z>)_M@il6Iz)4TDm%7d@VgLme^KkeXd{_GQ+`o~?b_TLU(;>h_E2S3-rf9v4x`nEV| z=$LFtx_M5R-w@aLwZ_BseckNg`o2Eo;rd?g@o;_r4tlu0f5lSnDyP0rYirkH0jhq1 zI_tFZe1lG%&M#5Ak+0L5DREP@gpn`n8`OMa;Zp`5BmBoQEOuULKxg~VCpnX9A{o*7 zsMnHI`*N#oSMKFLpJmcyv%vg1*>9fn_2ssXwt=+Gre0!Lzb(H?aCs$cApEWk?xHt- z{Q3HFBMqOgFQ?&8wJ-PKsMx`iFMqziT(^W^TkJZ`KgHOl7U_d??aq<^9EI2LS}xQ} ze%_PKe*VCnYF}=q2&KB>WczXnk$;XABlz|6FYxegNcVE+%kjO))ra9&wcE$j_wcoO z=wqUMtK}wf+rkC6&aIp_W!jV*VwIKmG*>lMT9Q0{8}OxjjlGyU<+izT!BywWV=TQI zlN~iJl}(K;^<1HQqH)Kmvu4aZS)JeK6ner$oTc;4C>aLr`eUtEU?gOS15Ng7bv|sR z+BY4IrANceY4D9`5c;1WQ*9E|yAb0j96^hYn84TYnw9LwYEi@8as{(stgaN6cpTOF z3co&fP|5-RAgrM}8RH$9ayzc=&U?sQ+nU1rg0YF&#Nnt{1OKW&jkf4vrpa+mwJ>PD zwundm(5<%@(?@1lUl-qlV{wbWVEozheFB3xQypw5*nneCnZHxM(Eou`!C)*a4pJ4@mR1+%KJlX0| z*)n-Kv_s=i=`*M%A&_ zmX-CDYg=)|ePul+!Yi9=t6Q5}>etogX#<;VYi5H~rPIwOSS%aH9yw`FwMTsN5!ck> zbH8zem1b3Kx-wl~6KmPff{*+)COvMO%XdS+bLSgh+rML-RlLT*$2#~X2Y-cwcRRTI zeHs_sZ_^VVuKC~8xMoez(4!GQQCmOl`m&S$zFSRU#3jr%-&v#4hP@cA?4f56z_i`% zJw+X{C)lse^hVlZbOK&zonl(%j@X^-An{zCEa-7GQSO&Q&XP^W8j98)k0@&`u{HppjwKef{V;nUo-c;XI8?UR0*R82q z)pApOVofacN8OA!G&Wqj62nM$!DJ)e*br~1y~l(xq~@(4hm+qyb7XsHzQ8OE`X2*_vK##Ou7pZN-oBv({jq!hsgImtpj>hmQC>MCyUR%>?GDb2)9W9>V38q zD!8j#=*?(^XU71 zHSk=0j6@zhnFpubx%e#4gF`9jq>nj`Z#6#X=U3c5cjUv#@gU{P}kzmsT#FbL+xnWz2ZhRX3#9AaHGSb3NSlm z6aY@YLHRDYeT)P>;fT9^44q3M?v9zijl^)Q(=1)>!&DK3Q~Wmj7;BX)`M7p^5>j8-M`sOR=nR3+>iIi4$g8^`G1`Uj|G~OE z(`@Hy>6;m`!6U4X~ z*gf9{7mOuY-+)^gxb24>Rv&!#lhhhv;TCB`uyr@WBV>xbmbh{>)xHbXK1JBw#|Gje zNZy)U+kfZ_l=+0+Pa7D~wD%y_SSGK6$d$&IwV19wjpFIx}HhLCNCSdCV$tq>37BJt_$)a`Wo0=a6a62aA0+CCIXq^-4lJX*?1~`x3zqM zsXAU^b3u4-awy0zKaV;R<6wt}QcVsIvZ4*6YOLUJ%JSanMgE=NoLc^?Ox^Cj$~@a^bO8J zns(rA#B1j&A3%T+`I$%qBR4tJ=j0IXp(16$6~?9&a`Ii5@1d&1f=3I?40)cF0VJNq|2j=OGf*=zMb zGbv5Aw1Xk$|JJAu$h>En+Ge&NMt#{dkZC<=6?);|VpuW9(znQx|G|h-!zcmTmkc%! zfJtr8G+>1}@|#&AigzDkL=zBc-=t@NHxq`O=1mTfS%L8~l%v=pR~+a_9^jk^Sy`JVr(8C?7Id($j=Z#1fw*t@Fzd?QNJXleHKZRqrIJ5{ znq~HcVoV9711}X?HBh<~w1Dht}+EH;}^6pF@m>5=jEvsGT66)2EFrpfU z@e&Tva3HgHYw}>p7b^~mVg~3~54c%Gsj@OH6-7D{3j<(pW@u}2kCfn{k0GZZ8l+5= za^HvQZ>Dzru*mL%ik&*yn8pShnGdOsVk#Qs4HCDjzmPP$`bVV-P@R(fy~!hnw9KT_ zFgs$Ijke6p3xT{WyeYY-)fhn!&S_5`F|`wL5jIb~IeFyX9_s9d1{&FDRmfKM|G=s+7uo*|f(%$r zUq;OeYcZ6|QK-rn2D!@;_TxYTxF?6Lky5!)#zEnhvHzw5_U93hyZww@z(bpn<050f zmGPq7GA>pbVZ#42bN|J}C}cP`xj}WtZWlkB_`(=7QHYvdkUj&yqguJg$+*mdQy!__7Ub02>Fkj77$rt%1^L8eZJ16t>h{jt@)aG5+RA}F_hk`+C zVn>?@)PXw34aVFi&h+>qNpNx{z@r)PWb!wx>_{6Xc^CagJ7bz*@&Qtirb2_M{|OWt zs^<%XqjU8?Occd`peUdt-A@(m(`trsY|Xq!sOw=F@%ALk2&*VIqM1Ky2S11p-A%Ss z^U}XWNiiC$tU+YDAqy?hfY;$aXj(O{%?Zk72UWnK@s=LSL~8;I`ql&~dlM-W2Ls_d zAh_>LEi`guc1tYZ7_ffYnShFv>Vj25jCsRa1dzO7b0K+w_TyltXu_P#*XBUuMhlx` z1YaRrQ@RoXm7dBOri8L84vxn3U>LcyOhFKEZ|jsHZ0~`lGTo_$A=4r7N%2Badb{0G zPI{`cNKFY0EXX{)U?lTk5NAkoZwSqJ zkbA&cfs2i}M&IF+r)0~+Yz&z@*`?u@RrF2hgX}2R-ht2mR6cJ!XKBzTux22=~t5TBiRsr2G7AreHdVe6G1LtZgyJ?u7T5`i}6U8HE=bOf7e8a9q3 z*|LRlLU}M!`_g@02LbXV2HQcAI%DGE-5)fKCz}{4Qtk7E{cw9&!vItR`o%}FF%))B zkF?b}%UJ8y3idFZkIxm*YW-I0>c=OCG>(*P`96y1$>i@wQiD1xeuw-U=$$vAcmNY~ zy+spPzIgNI7&Y-FJj5O^#?KRN_|f8$o^vbrwG3-uG%e%<`cT^-$w=`FgYzI{LFY3w+uq;RCh zeoWmKrf7Zc6mhgGM~bj+75Q?)G?ha44x>U~Ej7lTO|=-=CjnGLP=J4B69*j@Xn82n zM8Xy(2fYI?(={DjZXi>VM{<;;87B{en6JvoE|(xv+S(8`1#d;=#OOZHb_uGcO&dOe zkKk1sX?>^qSINg%X)#lwUG=Sq4o4&8d=pG`BT;KPqHsQ+x=dzr_QqWf&br5PG9w|2 zPO_|QZhNVk8K%ngu zs3?SjmHAS}z9?FaN3Pd$6axAMTF%==jIhyZBNWwve`p~d$rggpA6E#rV$tTejnMIg zkeX^U6QfoWIqQmE*celN21{56xIt`r$~2L|IGm~9{1owq*YQSj&;;G|)-yG1c=%5_ z-i*De&RZZMyW7T6|s2MrA{$Yrvrr`gpgwo8?3B~3k z{I_$^_C|X?IeT$TZBINhz`%q6T$T-vruxfDXMqiljhkL zg*M>k3AuMsueoD2(cA(_t8(b2y|QbFrg z2EDN#!y5gjM)W2J%=N_e*}S>Y`9BOdIO-=_DjU6Wu#a1M-gW&5-W`YSp$l0(Pb{9q zF5?RhgIwhsRDkb%FRKEC3JU`(n>n;*%0+XPZ*WJV+|Z{e_V`l?$vP?jzme7zmMxJ9c$MrQARgN7r4`!E4*H5~m0mo8gCO+|lvX@uwzQb*37jQ7%4s_%*UwG8a zr{BNbTspgP!5Jyr_|z#12xs=`T)PPq;~wIYd*HK$d~h5JFZOIV-oaKod3f-u$eYOZ zW~NnTm!n^mgVn=DHtE>GiMB16Vktx$-2P=sSJ-+su!4I>ANm>Ug2hG|tPt3D1FXnk zqkuhW-pwsN2pnmW2Np8&A zy$R!%CR(Ur?B;H7aWoH!Mkj79VRqRN_ft3xIC(dxER{UMQ@t3|Sn*5}BPIcaIr0txI9^C!gjNn^X z-5FtKw@oGYQ5%Y_$H{m{@D*FoXCvXGVaI86m?PgkW2nG}7}Ly{DdD&X=IbTT3i|4LVVf*Mb#$8Yv~|!ZTJX!0 z@WGe)!UX){T%&Qg;AQ3UHaO6T2jt-Rt9Z%eWLwGPMO`J6E4oW2-}y+%z+W96=vhjXku>2xDrZ*Z|u5PdWHMIQJiP?ze>Z zgBztf54PydJM^YXZALII)UU+alqvNMb&auxTD#h%zM&cmj9Y5s)m2SZ)%EEOv2-YS-0Q*NVhVjm=mx zV>TaciB~l@S8a&bw_vGFW4vW8*JxEYwyvqcnwoUHS+;tOS5>F$*Fh*F0=TtQH`h0% z8=GUY*h?b7%A6@!oFlHjAzj&JHq|x= z=kS)YwKg}ja50d$c_xwZ)m05OYalC)yKCb2tj0p3c)Gc&p{1_2Iet%7OS~mrzh+H* zWi91tYHqBqZ2{pm@s+LVczSiMCIwky36baqvuAA_Ve6`zdAX-Hepf@|JvQPwD6EF+ z+BIuT$;9g#LDCSfZ@9K@P5r9XV5*U?u4-v`O&YnlwrNc*Ho-MfQcgy?>iB0jk=Ek)q zP$)jOnoT3Z>Z(>$OIwjNj}gFTv*B1LWxTSg`Yx{ALdIbs;F|baWN_80T3cUNZb;X* zNZ}#w`i6KlHU|o1cs**L4Q1=dHE|g4BQ+@HXdMJ#Yoojnq%ak(uBy7$e~4p$A+BL$ zK7+2dp{A)3#PNyixiwL3)ml`e)_84`sZDahegYMD+*&y=d27XOvF6%VQ%E(nbyclv zScItC>(ep5tSm?$x36}5-Ne=@`ZtlUtZ{s^t*N(b9RSs(<0gPo@)fdt-p)OjTGCZ(o9>Li-7W=PFz-%O@oH=@oZf)2 z>uT4;-(J_+fVUr2j0-sLjL(+heBD`=ODuNni|o!qK|&?oQ`Ovn{E3+g5UZ(O*}5v$ z+Q8RN<)1hW>ZWW)4aA>VHgo-*k||jA*8-&F&Unn`k^`vB?o~=Uxn#-WC6x;n$D+@- zzj@BW1@kJ)=Pa4CDC#w5?%d=ZcSNz<7o*0!dBNPI4==5pzqsP|c~KZO?5$B`>4HVc z#T84V;NmwYm&{+d_$^Vid_lPv%YxgNA`unkOOswakZMuVlm7O_ODpfFC@){UB#V6U z(o}MZMz(axoZIi1pIlOD@+S+W!1F2{kpud70cNvp8jCT|ghC z-RYPOFg4fK zP`$NOLZ3lnhq9Xmy)9K(;f}tIXu!}HXCRnCVkaV=FQ?Q42|Zl zX{QZ?1)iEw$Mc4*wu@ zC0gK0X@Wye_D<++idTcsBM|@QT1sq7G(sW%Xq_6XE2TYm3B3>r`EdfdB?-xBA?I6>gKlQ{s( z@UY>JcLvr(lIU9X6?UmQ*9y+IL1Xh=|9eCK<>J4<^)C$1sM;w0H@W_;VfY8c|9013 z_WvCZY^V6YikYGEjXKY4AWZ)Q;=hMi^)LL2iGcn`#s3o#|BnU!G_IukB!7bN4+j3T z#lJh^|M!9aa`C@E;@@TbES;(s9G|D7Ow zkN7u6{NEAy_ly6X5&va@zgch%zYj(HKM?rGN7Dln?EDGR_nyE%A^uw;{%wK(iWB&^ zoxs0a{AalQ?>6ks``vQ_|9NA#^o{dp>=Kk+k26pOusKN`NU zHb`GW{HM77^`U$##Q#y&Lk&ObbE7o=HuZPI7k)0_-!1-TkHjGSC{zF92-73}W=dWC zQ#O9GJo&vv(M746!fjQi;BHEDV~kfk$W|-9_Y|`e@gHpqmN=5cS5cCUJL?j1UFr1* zNb9lWbt^EL1xPd|K*gnuXqX>a1* zGv5Qsl`p)?tHJzd?%m?cMB3qvHiV{=>F2AX;T2B-WBk&r;Lf^!P5)R$>@^;JjLpS! zuJ}tgSwbGzO2_!e;NOqG0$8r}4;cj!?!5vsT(ePUS?5Fs34^V8}>-cNWy0dro*O#BqzU-u&#EJp8UFr|xxgP(1{4A4P z@%Jr;2i)Z(aGW2%;}y9j-5+xA8m5D1<*Az}H|%#1*XMbHQ%?~${a)NJ5S*7>XX06$ zZ%nouWomL1pMXc4WEX&1zOxNp6ibPZ)|ER1Um^G;xvmzxOP*P8=r-V=^8c%Oip9(~ z4(>l7_+i1#w+-$e!hZqY__&DlD)IlK;0eJm5PYxTD?Iw|3f?BTri<}Wp3Q=r{xq=X zguYvF<~!Y36cy#^5&SX>$1WATU-0tpQ4}VPXZoxJGzb1H( zNB`e~_X~cxWgq*g;H76M(cm4&<}g`9|g|xdW^FJ%oP{FEm7ka8!Dj(y{`{Np|D^CQ7knkIblv6`XWr)F^KPLp9Bm2j7y53&|4wi- zHUq!M1pgOlV(Nwd8-iaf6-wXt9}9kshaVOEb%L957w|eC@#V^g@xYnhSBt`%Ch<-c ze6ipf?_9yFJp4|3$`pSIXCHSD= z*9!iyG<44hK40)Q={Ot^e3jtKr6D!rE%4hQ_}2wD<1D~C1)p@WW$+>4^Pu261@932 zi-O-K9gr=8e^c;%9{w}I-y{v7(w~L*is}8f;PP1%yH4=2ueOX8PY8ai;Cd#*Lg2aT z;T?JK6?yR5Ja{v3%K6UAtvqJ@1-I|YL;sOH_+xqSJ$dl2=fR%_PI-Pj!OCOCYjArY z5B;G$_%HI{M}_~Q$(Fwv&%y0E&_|57;%bX){|$y3*bJ~5^B*l~yJ@t!tE#E7P)+R` zog2Z-OAAa5?3@y8hA{1K3@$iPMS}}$Y0XU?vtaK1YYvk#<_wjvdRkTA5X+iKgPzy*S;42z^n>5vCvL_JUyKH5(#na`(lBdlU0;bg+q#xY#mo$@S9QgHNo#To_anV4 z8{|xN?k!Den}_NvGm4SfWmAQ-YP+2_7kXzd+DL~4!>Y-$G=QBxmFZQQ`XH_x`@IW0 z<`Yd6R~l0xntw9&vOwNa?G!GI?A)s5+y?W2M?uYJhBG3k~2|SqO}& z3D3AfJjf`wRYky%h9ky|BH-m1P6%e-b~Tm|(3G}^Ma&)4DnjUUT103B$FYW>I519b zL@DMsnXod`=ubEr8wwOfZNs`4E;L?jtgETo5UWZz*4tWC->Cfy^F|v>3-j))dVxl- zT?G|O0}og_3ukL@D>VSeRe*78I^bxyw4@QVIab%ynr^W^Y%$i^Thne zwys6*BnD%{SlLj;(=J18BfTBlTf+R8+~Bh^HVgk|XA9WlUnt`T#BXx&=?=~@1f{>r z!EbT!e-NC*1^jf>KJh~yK3={n&9WxYF_`lx4C(1Yk>D_p11Si|+4*h0_ zevX5G(!pC=HPlh zCUKYlFC0ED|3VVN`Se#fxJ!SHgS+x9cW_spbq@Xp#G~c-kl@TdmW_1VW1sQx*-{_A z?C^2x!_yx9Jn*91@8Qbla2`Hajke+F?dIDO2Y2h0U5#P$&CQ?PLQk=8z`v%qPjF4I z;@|P`<&xe(Ctf$bXPpts>E=JjJLnkPt>=^T;IDW1BoRjCsd4bx4*od@pYPy11oz_| zh3{%Q=BN99H95GOpZyN*>Y4NLy+=nr?tAwh!8JcO8Y+wz__*ZfM;$(He!fEd$^T9G z*L+yu;N=d!LB^#>{}u=Tpx`Rc1Ms8U=HtTm(+(e3o}WATGK5!oE|&3HKi+AA`|-~5 z@SPIx8y!Awyx(?kH{M@5xLZ$3WgMFFxb@*C2Y2bK9NeXUzu+qWUS=BH{T_ZmE#heJ{S12mh(V$9=z^ckmQ=X}O#!0}afFw>kI)4(`_5IS#(up?{0u znhyuzNB0*VepK?I$>HPX!$S`K7YMI%KJM}1yd2#w4<9e}?^_NZmw(YYHk_ZI(*#%f zuMz&UJp5YWzesTAo6Eo1!QFnyHV3~IVKiO;?BH%bf7QWVJ#);#S2%n|%XqDyu6crM zx^9$oz0t!pU6q3S>AK6o-THZtgS+*o-ND^-ZF6w<{rakdyYJUH>1a`&g-&{BJNQZm zf6&1z9ej_2FLLl_9lYAXhaKFNvq~lmG(S0iOSjs?XGuMIr{I2m{+&m^Px$exM?Zmr!R_&I<@4=4e4cf1H@)Y|Ks@Dl%jGJ;H6OG;daZ|RymK5r?)&l{2Y31Z zwS(6nZhc=KbZ}SB-45>Z`I_MVd-1G8@7CvEIJjG%k2$zopD&Yn49y3X^C}O&RqDe{ zg8TJhxr4jude*_;?&QO;gS+W1Iv+%Ea;|{%BZ}$kU`LFVP-NSc^ zJl}WtxaIge2Y2Opt;`ep^4udh<#*-znBXc8?I7s3d-ws7XQ#u*m1n<$yYl?f!QFVT zlKDwro>_VDgy31}5?tlqB=Wz@!^cYh`>!4TuKb_N!~eS;AJt1g@bGJd|F81!Kks6j zufF_?1XuYpBL7kkUnu-n3+}&0G1^46qyFC0qod-YY@z;0=o!;y6;Prz0>231x zeG>0x!ToqYmWThNdGLdI@XKEv%6|iHwLZT|aFz2xsSj@!obue`(64sr>9-vJbZZ@Y zR}Z8;`uAD#*p@u_Upai%gI49-COF?CSN=~reCYQ%k^i$EJ|OwL+u`r(fxQkr(=`wO zbWi8O_j|bJ!}lEiuHO5#gUfxGi8Ntc>b&i}}9=)dPYaaf6;os-s%KxC?KL6i3_^nR7=ZGOJ>0Nwc9(=jr zOzRAXPmM$G*4uXo&ith4ny$2m4`YmQ^2`#P`RU3t-@)DY^v!wjYQZ($dEiI4 zCT=c)Jc_pn?w8|V3eJ3U%ke{b=pS(C-E=+d;4Yt^IQUJmus*!zay-EK<#nTjzYYFc ze{RczzcmkD>)%$H`^G@aI_V6R3Cm(hAyw0KDEjW3&<=f}* zVP2>_|Ht9u=I4PtdC}4lZw|iE!GGl7n;iU?4(`e`^-2)IF|F=<*Wlo;Jnt905cJHu*^>YF zd${KRCmlX+{`Y$HIzRW6hby1{JbVs2_`4vF=Fcw$r;M)t95n#|oR425IFsY*lgWAT zoAcneIk>A&{!(y1-Vf%%AIyXQr-R=MSv9@i7rY2qn}c645f5-$UP?bzaLVKAnYVfL z+Fz{{oc!JX>N*E^`&U13aJQfNQ-?o!J%E3@-+1^o3&+m9%HF8_n;8ghf`{)D{Phk_ z=tG7&7F+M(+E4x)4_Epp9GrQyezaxu^*s1@Jp59jKj`6C3jT8sf34uhJe>CLbZ5WD zUNs+X6#NpwnbvpXU(5Hc9{oI_zssR-cj!Oh(XSHvkL95+m}KQ)yqg_9w@nW5`y9MU zaFstj#?o!dgJ(SaeIn2O9{zyJ>EVwF{?8u%b-};n;Xf4o-#z@df;M+WWjo=S>c$47W9-bEbArD_K_;wH9DEPx3-X{1X9==)dM?HM2;5$70 zeS+`w@Gil7Jp4m~@A2?$g75Y42L#{e;oXAwdARNq@QjCV7yA7k{;=Q&Jp2*C`#t z^p|<`MS@TF@M6JddiYquXM1?5;0X^uU+{SzK2GqIhmRMW>xJl4{ z@MRu;jo`~YyiD*F9zI?08V{c-_-YTIE%+J_PYB-R;qwGfdw5Fl^&Y-Z@Qof`E_j=V zFBN>Vhc6R+tA{Ta{Cyt2LhvpRuMzx19==-eZ63Zx@CQ7+N$_qDPYeE#hp!iWyN7QS z{9zAo6Z{bm-z@l}9==uZ9UlHZ!FPIim*71f{vpBlc=$HK_j>pPg75S2Zo&IJ{2{@g z@$k0@zTd-_2!6oB7YW|);aU$5diY$SAMo(k34YkaX9zyz;Zp=Z;^9{bKJ4L_3VzhX zFBIH-a65YA9KnmuH0mVKC*Kgf*u(!p@Ub5LX~9c9{4v4L_wYS}kMr=S1t0I>|0B30 z%k)2m#0V~CL;=qJDP7$BhI&#SV+jwRD9-zeB57%|^ zMsWD4KEGg;C5%f#6xVg=2@hY%4?wsT9$qN@={67lJHcJMdd8va&G&fpy59VthhHNF zQpCV;DyObDpWxxTu6&+{>$>t957%|&n>}3Dl|SU+y5Gni4}a@fR=$HCuItB(B){p+ zf8F-z3_9xDR@`uH!E9zWa0?_XH2ub=*3RqUqIj z+%+D(uH)Y9;ku6dArIGe+T~nIC6{aTxkx z994d}Zr4EZ*5uE5yEQq4%TRE<5YOfs<_R^62Ik?Q^TgKHBOt-Kt0j-^flz z_Kh-eY|4&r>-qzAXuM~>*{(@8i&#KuI zOJ8gbTE+P?kF$!V?CCL-d~gb7#|bqBl;Vp$rjQ8P$20qox6k4kMP2c1T?U7hCx;91 zGgNr!GvoxH-0@IjxbeJ6;u)p!jKkSLHtIr!O3zd%l*U3T4G)JxlqeW0N)bgV8pHv? zIAfH_V~@g#mf}+8q0%n=;IbrAzLw3$RvbrC@>wc;W*4s;-?8WsyfHl#*^_o~Ir+~%`fNFFuv;I%tc!uR6%dD=I-;GR>GV__)A@0FiLmJiEz zEt2r`?4oq7xfZ7HG}nT31+OT#5uMx%T9$FXykQkB`N030L&_?4Ag6}xn_y2{i?xmi z)RXE>n0`9%dlTbW4N>%i%W*CvPOFj%35CWt6QvKGnJLFRx2ZqYdY%(z$FESa2d`o% z96)A{DdzERIGH@qp*=V;I8#0j+=KTkZj>=qEe_1wf-?>K5WT!$hdzRP!~nlygdtnJ zU%UDXQ#f^NSO2I~f$G~KyvXJRzfzFfhcH$?n{z?m(3>1)>IN?ts#5CK>TjlY{cto{ zBFKN^C@`oL>XHA)-Pgd$RaE(QCIJS5&JY3w3D97oL?KKd2?+_%2{a6t;0TPOpp&l& zi6)bn=_U!}3p@Fy%ufk)~nI>oI?${~L6eA+3hhKtIqTtDZC?~78@}$diT|a6jkDQ`T8@By^%Htb=;+! zYDo?~Pr4iLyJJzRih`v>;uN~0Jat*5j6pPOoC_ly_W5ll4Wh~p!)bR`ZrKTO))jp> z-dFfJiFP*cB%oX)!h-CCRlJhF$6qxDC^R`S&O9XJ45%ExuzzLj;#Z+cvq0~wu#eN_ zwomYcv3GtiW=7r?w^=EBW$%~>wfd?4KvB?4{5W>~KuXcMaKfR#D{t!C+qc|`Z*)spEvK?oX)|8Jt=@TZeJAcw22q?MI(USEK zO!OcGU`#YDUJNE0hMy*SgqrAofpxRySH%nyEGAkqSb3pLJ_o~sdC*1(EOJvB{|=*O zt>f6841TJxLdLOUB*V&%5_rmr+-efD?Y-%A$Lm0H=ZT>}n>j;oEv;(Z&^t?1r1>7( zFe{*hPW%`i;H#CfnCKl52)c`HB@U~p{iy*xv6(XsF>5occl)?bRLYx$vX6lB^#jx& zG_M&E(Umxw!66anM6@V*iufXh4ML@v+46hHX^>Z%A%ZH?aWVz*34W!JDVb$BL{a9n z9?5XSSQop3nTQ?R;iPGWlhzB;)kwgOW?wZX5jn+$Z!}b1u~ooaxK(Ut&!V$u;*S-U z8JcuI7lIz$&pYI|CUL9$4okd+zbNz7yPwAC{8`EA%vq-sr~2aP-G!7fPCCZfyRgXz zeVd$Bn~au~&Rep{e~;=hgVUC>3Zq*feDSWZt7Y$>LJMRSTnI0(DRL* ztCqn37{Ks}e){ZD9GyFuT0aQM)kFl_0teM7QD?`+gGXj&s!q0+B^ZI`f%WBSi9OV`p+_V}{7j?cyL) zl1(jSQ}{7JkW}qPx}MvRsR3i*tgj!}aKsr@W-dy?yuCBN)0?+rd2b(N6qrStSRQ?x zJjqPvTEaYIi3sS=H+F(x20{bt0n2N~u^8nODO)*i14&N={vCEIq2Vb#TNJ&}A!Y9K!G`fWID zT0|PuWNj^l|KeXk_@DWUgby?6C`^+P{*Y}lFL2OhTPV?5)>^}BFp!7hvs@dnjr7dF6oC^|Wv9UBq2$?#L zBdLL-=v&mx;ut()ri6CHU%aoB$##mv#yZJ}R8t%SB$%r1{JtZyNFeu+YH4jjDi6EU z%VlX`_hR@oU9J~ggP8bFJ-Q@O7|ov1DUr!yN8uTxrZy888Y0=n9V3`TC|39F~PiV})tJy)jeHT_i?oy18rldbuO#>;^c@r#S|WxIG{TueP}{1O*rjly zIfXEdzHU1gi4q`t49^+T~@GX=uoVf$Jxr_loT@l%bE8h*;{4>Ak3SKgSbH#M5(n zYn{i;b$CQ4JDo6_!*~zxEmf#LGZ&e^)tI@i2bt$~InI-E%!!!ZqS5GM>W%Jd)0E8|dEj&nx3$@716Ibiv zGP*BS6STNbc&Po*<|>&c(U9WxPuBun2S95vb<}%P&;(d<466=GfU14td} zW4xkFhRd2(SSIC7?9h4)k;%zJWx~Be#~~A<|6iBMh%z#%^36!s5Sg4lR3@X3PbNhF z+sov>!#oG7G5u5?Rp6xJ;XdAU=J0>VmP7b|(^LFEf`vN#94%}ldgsIacxcRQVXj$S zN5N`fYjBT;?);DbgVw{Webn;RQ5-q3kTHDYDaKfG_e9+jTYd`?w2Dt``7gQSwg=hj z@LNoyep~m%<1D_hv$ITz-T8!HNDifg)Jw=Sb9h2a`i=pTf{ao}HfRF(AnIxetOiHe z;@Zp>);*OUHX}Z;v8K2V=BsgA-4mNnVD`<~HKPHb1LVLG=b!`Pby1qHC}9=0P=;6n z-ygZAIKFJsz7W-p8dy3k%5Moc#5z^NOu0OQSP#NV6&NjhwJ*U*=TUnwLA110DavTu z(eaBe9lt2DU_m6=*1BdTg1EOXa&gA5iCz@I$FG?H%moWp<4W{bwHB;K+b(Kd!@SV3WGip1 zHaThxRieJx5-di0`z5U_FIl)^`N~U(%vviN)n>J}!-5sQvAno=$>g5K03`{B)E7*vTae6NhKLv8Es#B59MQodNJ>U zGa8n*wlk;GzZYEBdiS-#5e~PlU5Tt^`Z>*lsN!n5Nk&XlTT`M9YJhIdE&H*lP|d} zDNmC&Oqx8gVe-VwCm1-+NK@Lw?zts0Y)$>Jb8yV_Rt)=N0p}mD3;CZt2m0OS9B8J^ zBplaW{LiL4=d|BRIIj8pFG#;LIEQ*2;kaV_&!*p7qW=itxb}gcAbt2#!8z%>B{dR} z&n9gC#ijfQHGQ7=&9ANhV9m9!IdS+M!8zH3n*N{swfSob0e{>^%1h3#wduo0o;2^vV3S>BBD#$515B$&aU-P>leWs>Y;*a|QcvZ^3?il$WIY$27$H;$B)4vg_{}WRGS8;~B9@Y+1 zx|~PhOvDjEtrKs!x%m>D^@S6Z%#rS`OIjAM;_(`Pr7H?LWS@)D?iJIA+Ho$_;JT1= z@WAfpUz@HnkWFWr-;wxXIh_0R8e@JUZ@@3%DoTZ7{^XTw6Nu|x7vq66Uv2(L$V-~4 zs<<=PJS~5rCzz;3(BJ9!W&Q>a{x5Gb0P^QvmVf&@8;SPb#ruuscVWEuaoM*B^ZB>m zIuCe)vGOM^Ubo<{T>C|CljKNV3A6o}*XFnF$57N>5t1=KQGU$WWNzhupZ{{a6LITh znn~q+fT-DO)Ga6`TG_BEEVQF{oMrkFq~QZ7L_9xo_T!~ ze=K*kwvUYQfPGHkty~ktC1X2&xz0d3^OO!>Iq-T0f25OS1LOLD`HA%5m++SrE@M1k zhw(=`E0vD*ul}s~@1a8CvcAb_5Haz$D!zu|j=WysI~A@WCnH>vA%0Hb;|#gT4GOpQ zvH0&)c!Rv6jYQ5@e4b4t^;P)A3SSR6>viSX1|VZAZtquo8>58lfxJGU@a;-R#zMfq ztnjSDFB0rX#`s0-WVuIZBF+>@q)*r$1$0O1i8N~xGTkZwuZ-kGJ3fTB`xNTDS`4Kd% zD}1iP#b+Z*X<{cQx5{~H3s)vNUtiWbX=-?a9vrmjOcQaA92V@{38KuYv68`~B^O5) zniK!p7Oh-?WdnazA#{l8S9{TrmVP%|Cy%VaRc>lW>ZuSxn&qLAcaOIM39B;QUe#GSx3*(vYKTC-GF) z8|J)q_N+NAZ@vEdTjRI2+%{|WoOp|ERZj6krx zdR(cV-6(m2C5MG&j_0&zr#dP$bmhlMthmhM;OOFw!=>=S^ZGQ&Ti1D|yrtD2#X9!k zn8#cSaw#1XSr27(^LT4T4*Qi;AcD&4M=tSd5Gl%P7L;7N$APacRd&6}B}s)Xw?C9dC(0-ocML@HaT{7aTZ!5=)=sE-%t? z;qoDB8Te@!CwLLxrGJaUNsc~}rTX)o{Bh}A;o-kUxIye(2jAuY4i8_acaen^ z@bB^P?@;>pd2n0bk2!Q)KL5kRw{rfugYWWbV~tojtkZH&RzKImZMo+toaEec=Xm&! zD4kn9xTVutfzD?Bw#wr2G6_sD3x$Z^EB#cN?pLaJOH);NZLZKS^D6 z;=AzMD!?b!0uh&$+wQo!>g}H-Rs!hnI7K2N%n|2!9s7%z?Z3 zUvS`WcJL4Ae4TV${d}nc{LS(yLrFdlXuU4;;LAu5*L4c_eE z%3+NMw{$*KfzH<)xZCc(ao}#d->eHmmj4S(bs}$9IQewt-|petdE-4E-17N=L&uf> z(;hz833%=I;FeBb1v=;Iq}TF)jnWzC!7ZI>3isvzK?m;2t=oaS{cD4+SCNj3|80d^ ze(qF$p7Y=jFe9#?Idok4{KkR1{c)tOPgwd7DE(1BTe6`O z)b$&Zb=&cLh5LLa9DKK3zN~O7w=OOBpFQ}g>VNEa=(zkJQn+946}p~e>09|+?ZGYm zCWZU$vdqJ`@<}-Ou6$As+?CHG3itW^orCYn=UiR)vi$E=`Hb`67pr`xDct8ju5iEH zLlxjJSAf4m*VRaWlB53*IPeAs{tXB2)@!7`P_gy0_VaXwlfEm@nI8VPRSwsB@HUp2R%Bkweuofcl7Hu*@3(AX;ZkB&uFES^x!u3 z_x%nXx4xhE@Fy#sFFW|IoWJMck3&1~`hf?x<^Iy4CZ zxO8s!@U0wLJh-Lv{t9&d&Vf%w8P;y^@#t9j?04{8`HbKTU|hCdw`sjbdT`6nxeE8| zHQB>oqjY9E_-?uG8F{CmeA_PW8F_@;a@RO?TzP)dD|eli`&kce>3ppMou?i66)4xr zv)`j*<@2%!xAadQi_Exu`JC&(-Tw7f2kw@8uLF0-%`5c9m2Iz2Xnn8t;PxzrCWZU_ ztoQK0s&qDca7*Xo73lo4hi~<5mxJ%N`wu+)?`pXRJ-98m-=X8S`v`rH!Fsv+|A4}M z`FzZSTl!yg=(zO1>cCw)R;&OYsqab1kBfh+!Yw}|h=A)|9(=dj`DG3rm!H4)@U0$x z$%9)uT@~nj%YnOk_-l{O<;v&p9DKJO&yPwqhOF=1rEtH#Z6173>$}OJaOAg$v?->`G@@;)*X?@RCxL@BJ9JpKGs39Zc1!>tUrZmqm!Ef#uV_Uyc&s!0r3xm}_scmCZr?92U14J5M)f*ojNB_4CL?ezuIgjtF5!T$S4@6OF>-^C;v@!& z1aQMga{8OD*D$#@pa{QJ3=%D}d~1gf>yU)NdnT5Od1P3XrrIGiPyq8teq^dQALa1} zPxyY&WGj(yx#0JEwwTN)^GQ4)CRgT`S|vN60Re=xEg@hfrC(R_1IZJ5Adx+kiv3m+ zc>u0OhbaS|RvtXBJeWJU%Mj_(((dKQPf{AYEz4gTK=KNCM*ta6NZdkFSyZ<>Pu^`z zhLiDe)~6YW;YQNUG@?D?`CZ5uDTQLNxaV&boLH^WFi)rIQ}HBn87aP-U?U}4n1N70 zVF+athEObF2qj`6?&q$-*O{tb>3_3WC~W{OUSbkYmPw`!;SCUvH$Xhz0P%PO#N|yW zXEybcUBuSlhu}~%^Q^3dzNzg4LSN$v+aNNsXQBb&OF+u7FqTxD;2fL!0hLGy>3@5g z7^Ns8H%N1e#ws}zS|`TOw5#||6l@m$k<<}G3i93c{kaS3Uw$#&yElJg8ZiX$p)+Ij zCG+@zR?^Zvnz}Tbhl!f7H{G)|8=GAhAvQW`JYPf)DrY{n-~k^-Q!8-&eoDPyiDk3*V>@179XwYMMj__;f-aYaE193&&c}kEm6h+mI*EXj(Kk zNXj-2?VqXa%Ar7MTCH>LMo6cc;7YlmW)On?ocn~rN2P({`D)1^)^@BG-(#k7HPFR# zg>!~%!Goy=A4(krjYT~Kvrt+5p^{E2pI3&S!}<(cFO3pJNRNT_9uVq5#*0+SJx0|X z-9$pZJAMe|;yckC6do!F0gHKcN`v}r%1R=l(%iR?B{fd(O(GOFkUO`^vndL;O>Dru zh>TdcKzfiF9}t(J0qFfQ4&dPx@}`*g=av^OIh6-#bd!e+obq6`Ob^CL0+O!*eLQ10 zgNPZ15D%0z$^^UnHbTKYP?Dei1IrF-$U1%B1~wG}YzdI!vvn#Cz(hAePGEs@8bDbH zK5Q6s@<4t@Li_5rybWd@Nfo5@2~bR}KNJy#(4xBY-vm_hgqi`t?LEDemf9w~fE^PP zf-=%5zQR$6gb>ZdF0#Txvl@LIE4YrNXTb zSI}ixv})a73S3ZiA3_YUY@;O)2KelD1H|r$#iWlRgkORYQxVhQXyL7@c-^sSV2^Fp zzdsg}UlRKR6by2bV5H2$u~)-$NvP#ms;6G;6ykft%9TnY4`C5ViAd)j!Wv5~eA5&U zNt-6pUfbxJOA(qcMdqd{BK9ZRi;hg84ne?Kvf%4dYolc}SSI{Ssyj zLv{0^bkoeh=||O2y)Z`1CYy6H`qGG0M(b(ESQ-d1wHQ+*0ZK4OLcJZLjaz%oU+5$W z&2abcGu`4RB8WaC90Ti#gaDTgrj% zG}3_~kDB=zdOD&N{VbIeC6_d`1C*E65AA|sLZ96MrQXgcgI+_COgVNvL3Cgbr|Xt# zk^Bto;l$a3%5-_7GinpX4^ppZh&!Lz#9;{L={nNQY@(Bbr>T5`SJE$*9&^w8_Q~7} zUJ0Y^Fo`P*GA+Gt-vF_u_a?j{?TBD@Zk1$8CzTze{>xEBz-Ls_B+p*Kgg6i(hCFx1 z;ngk0DEA1H9+(r;7vK@NnLsjc>SgrGOBT~wg^ro=nX%+Rz@0qVVM(jYX;8jQIP*v`5*(uQ`oW@Y1x38V>M`5NxrH~4G=#jj)?M@THoiZeIJ0mktCyV^Sq$c+axq6Owh!wn_REFlgH5Q{p#)*=ySDx9z@DjU zCaJ^2qyeGdE8Yu46nHPTTBZ{UL1_rn)jWxT>{fKFrTtuEG!IysK32CK)^B_sWUT_* zn%xO|xylF)8o{H}5N{pjA;e>K?y#WG?Ln5T6U`GnQk= znmkjqFoPrUM!=*XME}vkR+AQ4d$mccWo$=eE^BAe670w&JKM!xSeOGEy7ET8p*ANj z=9yDpq}SRV@1r_k5+PbqT`%-q%s_Y0E32YlHLqIyvf7A%*2gRi^%ki(8lB45Lnr$n z3OEi~+;`{q{2XGUvA1h}R9?~XRDKMQcK~^ZaoM}`9|1C(z_)0DBc9pBwnER@A*&(w zBpw_(z*#Js4$(|y_qGkZKcwA;l9!nz*FXZ!OvlvTSGVN`+FK-B$tM3ceLCFobjA`K z-1_u|gn6L^)pidI>Z3;2$dNgaI!4Trk?6Dca#qnu96f}tRM-UZrIrs4UoQe}Du^9V_pXPm^wf;QG(aN$(3Bx&)d)d(SbOK*}B^ zE2dbtlg?M@#S()%{>1{Xl(EN6;A+$;a5#-O7OC4zM*vdF!RkoJ;5=_m>0-MV?lWBH zklst*0;YO2YC)@nXGm-MzPd-Uoa>f+N&#)oCe9EckT5f(@yg|GwLJP#3>0$Hp@2m& zaJX{i;9*}OT&1$kw$yVjsH6XwcK)?-7GyF>(dm;(W zCwejjO!ImJcYugjSF&TCY}d;PPi)CRf6y$2Z;K>LFjEj`)lv}ruzTGsDEe~u`Pgg} zCb5%+`|h#1Wxb6n6>v*QnUg@y#_cdU?MxDHg3;Gy@W6e8h0^0X%;|yyyGYULVgY6p zm^ged-anHF8jTYn{`*nQ{4sK+ler-|sd1XSTyYJ7`d6tZ-;{N1IR_mdUYU>veOO5BleMx+1jF| z1%`2O3F{1^csqat-h6;7!~?D;FJYkxk=G?WCxQ=reFy7ziFs^lkaW&yU~Gz^_1(eJ|0JypM*cxo=#E>B&)9cQZDR>%IGwpI_%3W2AZ-)MKV;piA zU|~&;`9fHxX??JCG(DU~aYShb052Y45I>zQLZ^a6Ji|cFK6YJ^ADR@a6;0y3c}2Ig zF2u0Z4&L)n?CI{&vxpOODog1jk z_DaQNBGoR*%D7SL9q0=E&XI4!~U zy~R?gaOYN;P*G^5*R?bMU7Ro0xsOV1&by?9<&lCyeLipZ<%FFm6(gGhlM-DTFsoAH z27HvFse3w^%gjB*lcc2c43UeziIrNz0}A<<<;EzMT8 zSL76s=BeB|1W1Z>&^Ny+OWN1GdVUIOPCWKSY5;A28l%4i4n#(2vMs6~p) z`8CCj;D(5yX5iKV&gkLC;SFo&=x<8Fth+1}pk`brsMILn#5T&4O5G@_OQ*NAA8sh; z`9K8q5P^2LnqugEMSv364d@8om&Y14y1zb7!@^|M{nE-a zw8M1WmicD3<|Oq{m+Zty&Z98O&~ILPR{yRpw2Q%+llHLy`|2O;4tcA+hsc(N!X_B2 z%F)rOfRTt7hI#o4M4DXDwsc{1Ap#b??_$QVZd-8`B1|KMd0YG9)>YB*E17TM{I-Ry z%c22P=>#FKOLW^?6Vb%d<;b~s#i}Smt((Uc$%I24;ieO#5~hsz`^H)2+=0JN<&+PbX0HM$g8m#t`LQS%W? z`tGF*TUjSwCB7y6G-Cjfpd$`c0^*q8zP1fQGE&e?2t6H$Yvl@r`d+-KJ-U3wqNR(M zwl2Du@vIpI3JkT~r9p=-HL+SQ#SYD8HJ4n?%*flauq_e2`l_hNrfvSRmNozl zT7)PUO<=TZ79!!sZN-ZVP5(w*V1RssAT)MI~kY92o0+oXplWiS?#By?7vLdl^S@N#v^49kD`FFKK3JY78 z-rZ_SMXYl)AHr&*IolR3Yi+S@Eh6UYzI?CQ~IjtYABV7u@qeZ6e&tE-%EgLVfYArM9H6Q(C33NKKMDzqTH^n&g zh~2g#+I-9G_KTyq(e}AOD42wB!$Gs4Au0+6G>^XZ))}FkiM}47L^kkeO2r76?eB9aAe_%XROrjH_X-&Vh0@Pm(RwO+m zXnhCA4R~Y=a*}QEuJ+`DxXN)SUn?((%iaeojEyji!`59fapa7RQuKZoSIi9%cq@$m>M_wtm`gkJR*wXV# zv8}n(!s|NzXVW*9((fc3*KGc0(@p4c6I+{bTsQJRn_hEW5WD&j!f|~BK539X{DB}g z_HIdyMC3Qf|74K=pr-R=_fr0Nkbh9qU*K<${|7;SZcXR)DE|x6{~<`XacJt?^qVAE z>UXE+|Bq1leL?x_H2w2#{+iDO^dHgm3$VZvls|lI4H3oyv|H2Hgy^>i^bcx!rS==t zboso{*6&><{%stP=R)+q8_=IgzHlw(e>Q*3{D6NOZ$sK4NH4{XU#IzHRu`myEy(|f zreEvQ-%#Rjx2CUk(`ynz{)3v{5lT-5>4Tcy8A|U6(#H;GLL?$DOD%sZOXbfzM*5wa zesxHG(*yb0@1#G;LM;87hlBDT(fqBU{PTkRyEXltq5QW6`44Kkgr>FhhyU?JB2a$@ zHU0ac{ND@mj~&5;NaSOo@;@AuKU34+L?lbURk9oX*K~dx9HhU$l)g^Wr@QH<`6T}% zn!dzMuUQ!Iw_DRI^}mBQo%OW*4L>D_y+5eww};PyK6h$5;}{3|hc6D&*J=82H@)W10sTib{q=77?~!EF|219qKwAEWKP&YAe~F!6 zBg#bqn2VxvFNOfnW^}=km2WYRxwFmhNc=Ewt$B=$(cd>H+;$ZOM`nBFTDV_6V^Wjm ztIf}NC#0#S2zTb1r{(|Mi56mhqv6L0`wsIrc<`4MK>pmz@^61$j-={iiNm=>Z=UZ@7uKk)?4F+Qu^J4okug!1U?=--C*#l&Pz2j%TJe2

qwQcAd#L^(6Ca|M$zcaQ~Nhf6LhUR4c|%x7T>R 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 l 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 diff --git a/hostextra/d2xx/linux_arm/libftd2xx.a b/hostextra/d2xx/linux_arm/libftd2xx.a deleted file mode 100644 index c4aa74080cb78cc8ef3559dfe9d9c736e59e1846..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 342444 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 QUx$c3jXk8N0CoJo0m&!PS^xk5 diff --git a/hostextra/d2xx/mpsse.go b/hostextra/d2xx/mpsse.go deleted file mode 100644 index 7002f22..0000000 --- a/hostextra/d2xx/mpsse.go +++ /dev/null @@ -1,616 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// MPSSE is Multi-Protocol Synchronous Serial Engine -// -// MPSSE basics: -// http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf -// -// MPSSE and MCU emulation modes: -// http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf - -package d2xx - -import ( - "errors" - "fmt" - "strconv" - "time" - - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/physic" -) - -const ( - // TDI/TDO serial operation synchronised on clock edges. - // - // Long streams (default): - // - [1, 65536] bytes (length is sent minus one, requires 8 bits multiple) - // , , , , ..., - // - // Short streams (dataBit is specified): - // - [1, 8] bits - // , , - // - // When both dataOut and dataIn are specified, one of dataOutFall or - // dataInFall should be specified, at least for most sane protocols. - // - // Flags: - dataOut byte = 0x10 // Enable output, default on +VE (Rise) - dataIn byte = 0x20 // Enable input, default on +VE (Rise) - dataOutFall byte = 0x01 // instead of Rise - dataInFall byte = 0x04 // instead of Rise - dataLSBF byte = 0x08 // instead of MSBF - dataBit byte = 0x02 // instead of Byte - - // Data line drives low when the data is 0 and tristates on data 1. This is - // used with I²C. - // , , - dataTristate byte = 0x9E - - // TSM operation (for JTAG). - // - // - Send bits 6 to 0 to the TMS pin using LSB or MSB. - // - Bit 7 is passed to TDI/DO before the first clock of TMS and is held - // static for the duration of TMS clocking. - // - // , , - tmsOutLSBFRise byte = 0x4A - tmsOutLSBFFall byte = 0x4B - tmsIOLSBInRise byte = 0x6A - tmsIOLSBInFall byte = 0x6B - // Unclear: 0x6E and 0x6F - - // GPIO operation. - // - // - Operates on 8 GPIOs at a time, e.g. C0~C7 or D0~D7. - // - Direction 1 means output, 0 means input. - // - // , , - gpioSetD byte = 0x80 - gpioSetC byte = 0x82 - // , returns - gpioReadD byte = 0x81 - gpioReadC byte = 0x83 - - // Internal loopback. - // - // Connects TDI and TDO together. - internalLoopbackEnable byte = 0x84 - internalLoopbackDisable byte = 0x85 - - // Clock. - // - // The TCK/SK has a 50% duty cycle. - // - // The inactive clock state can be set via the gpioSetD command and control - // bit 0. - // - // By default, the base clock is 6MHz via a 5x divisor. On - // FT232H/FT2232H/FT4232H, the 5x divisor can be disabled. - clock30MHz byte = 0x8A - clock6MHz byte = 0x8B - // Sets clock divisor. - // - // The effective value depends if clock30MHz was sent or not. - // - // - 0(1) 6MHz / 30MHz - // - 1(2) 3MHz / 15MHz - // - 2(3) 2MHz / 10MHz - // - 3(4) 1.5MHz / 7.5MHz - // - 4(5) 1.25MHz / 6MHz - // - ... - // - 0xFFFF(65536) 91.553Hz / 457.763Hz - // - // , , - clockSetDivisor byte = 0x86 - // Uses 3 phases data clocking: data is valid on both clock edges. Needed - // for I²C. - clock3Phase byte = 0x8C - // Uses normal 2 phases data clocking. - clock2Phase byte = 0x8D - // Enables clock even while not doing any operation. Used with JTAG. - // Enables the clock between [1, 8] pulses. - // , - clockOnShort byte = 0x8E - // Enables the clock between [8, 524288] pulses in 8 multiples. - // , , - clockOnLong byte = 0x8F - // Enables clock until D5 is high or low. Used with JTAG. - clockUntilHigh byte = 0x94 - clockUntilLow byte = 0x95 - // , , in 8 multiples. - clockUntilHighLong byte = 0x9C - clockUntilLowLong byte = 0x9D - // Enables adaptive clocking. Used with JTAG. - // - // This causes the controller to wait for D7 signal state as an ACK. - clockAdaptive byte = 0x96 - // Disables adaptive clocking. - clockNormal byte = 0x97 - - // CPU mode. - // - // Access the device registers like a memory mapped device. - // - // , - cpuReadShort byte = 0x90 - // , , - cpuReadFar byte = 0x91 - // , , - cpuWriteShort byte = 0x92 - // , , , - cpuWriteFar byte = 0x91 - - // Buffer operations. - // - // Flush the buffer back to the host. - flush byte = 0x87 - // Wait until D5 (JTAG) or I/O1 (CPU) is high. Once it is detected as - // high, the MPSSE engine moves on to process the next instruction. - waitHigh byte = 0x88 - waitLow byte = 0x89 -) - -// setupMPSSE sets the device into MPSSE mode. -// -// This requires a f232h, ft2232, ft2232h or a ft4232h. -func (d *device) setupMPSSE() error { - // http://www.ftdichip.com/Support/Documents/AppNotes/AN_255_USB%20to%20I2C%20Example%20using%20the%20FT232H%20and%20FT201X%20devices.pdf - // Pre-state: - // - Write EEPROM i.IsFifo = true so the device DBus is started in tristate. - - // Try to verify the MPSSE controller without initializing it first. This is - // the 'happy path', which enables reusing the device is its current state - // without affecting current GPIO state. - if d.mpsseVerify() != nil { - // Do a full reset. Just trying to set the MPSSE controller will - // likely not work. That's a layering violation (since the retry with reset - // is done in driver.go) but we've survived worse things... - // - // TODO(maruel): This is not helping in practice, this need to be fine - // tuned. - if err := d.reset(); err != nil { - return err - } - if err := d.setupCommon(); err != nil { - return err - } - if err := d.setBitMode(0, bitModeMpsse); err != nil { - return err - } - if err := d.mpsseVerify(); err != nil { - return err - } - } - - // Initialize MPSSE to a known state. - // Reset the clock since it is impossible to read back the current clock rate. - // Reset all the GPIOs are inputs since it is impossible to read back the - // state of each GPIO (if they are input or output). - cmd := []byte{ - clock30MHz, clockNormal, clock2Phase, internalLoopbackDisable, - gpioSetC, 0x00, 0x00, - gpioSetD, 0x00, 0x00, - } - if err := d.writeAll(cmd); err != nil { - return err - } - // Success!! - return nil -} - -// mpsseVerify sends an invalid MPSSE command and verifies the returned value -// is incorrect. -// -// In practice this takes around 2ms. -func (d *device) mpsseVerify() error { - var b [16]byte - for _, v := range []byte{0xAA, 0xAB} { - // Write a bad command and ensure it returned correctly. - // Unlike what the application note proposes, include a flush op right - // after. Without the flush, the device will only flush after the delay - // specified to SetLatencyTimer. The flush removes this unneeded wait, - // which enables increasing the delay specified to SetLatencyTimer. - b[0] = v - b[1] = flush - if err := d.writeAll(b[:2]); err != nil { - return fmt.Errorf("d2xx: mpsseVerify: %v", err) - } - // Sometimes, especially right after a reset, the device spews a few bytes. - // Discard them. This significantly increases the odds of a successful - // initialization. - p, e := d.h.d2xxGetQueueStatus() - if e != 0 { - return toErr("Read/GetQueueStatus", e) - } - for p > 2 { - l := int(p) - 2 - if l > len(b) { - l = len(b) - } - // Discard the overflow bytes. - if err := d.readAll(b[:l]); err != nil { - return fmt.Errorf("d2xx: mpsseVerify: %v", err) - } - p -= uint32(l) - } - // Custom implementation, as we want to flush any stray byte. - if err := d.readAll(b[:2]); err != nil { - return fmt.Errorf("d2xx: mpsseVerify: %v", err) - } - // 0xFA means invalid command, 0xAA is the command echoed back. - if b[0] != 0xFA || b[1] != v { - return fmt.Errorf("d2xx: mpsseVerify: failed test for byte %#x: %#x", v, b) - } - } - return nil -} - -// - -// mpsseRegRead reads the memory mapped registers from the device. -func (d *device) mpsseRegRead(addr uint16) (byte, error) { - // Unlike most other operations, the uint16 byte order is , . - b := [...]byte{cpuReadFar, byte(addr >> 8), byte(addr), flush} - if err := d.writeAll(b[:]); err != nil { - return 0, err - } - err := d.readAll(b[:1]) - return b[0], err -} - -// mpsseClock sets the clock at the closest value and returns it. -func (d *device) mpsseClock(f physic.Frequency) (physic.Frequency, error) { - // TODO(maruel): Memory clock and skip if the same value. - clk := clock30MHz - base := 30 * physic.MegaHertz - div := base / f - if div >= 65536 { - clk = clock6MHz - base /= 5 - div = base / f - if div >= 65536 { - return 0, errors.New("d2xx: clock frequency is too low") - } - } - b := [...]byte{clk, clockSetDivisor, byte(div - 1), byte((div - 1) >> 8)} - return base / div, d.writeAll(b[:]) -} - -// mpsseTxOp returns the right MPSSE command byte for the stream. -func mpsseTxOp(w, r bool, ew, er gpio.Edge, lsbf bool) byte { - op := byte(0) - if lsbf { - op |= dataLSBF - } - if w { - op |= dataOut - if ew == gpio.FallingEdge { - op |= dataOutFall - } - } - if r { - op |= dataIn - if er == gpio.FallingEdge { - op |= dataInFall - } - } - return op -} - -// mpsseTx runs a transaction on the clock on pins D0, D1 and D2. -// -// It can only do it on a multiple of 8 bits. -func (d *device) mpsseTx(w, r []byte, ew, er gpio.Edge, lsbf bool) error { - l := len(w) - if len(w) != 0 { - // TODO(maruel): This is easy to fix by daisy chaining operations. - if len(w) > 65536 { - return errors.New("d2xx: write buffer too long; max 65536") - } - } - if len(r) != 0 { - if len(r) > 65536 { - return errors.New("d2xx: read buffer too long; max 65536") - } - if l != 0 && len(r) != l { - return errors.New("d2xx: mismatched buffer lengths") - } - l = len(r) - } - // The FT232H has 1Kb Tx and Rx buffers. So partial writes should be done. - // TODO(maruel): Test. - - // flushBuffer can be useful if rbits != 0. - op := mpsseTxOp(len(w) != 0, len(r) != 0, ew, er, lsbf) - cmd := []byte{op, byte(l - 1), byte((l - 1) >> 8)} - cmd = append(cmd, w...) - if len(r) != 0 { - cmd = append(cmd, flush) - } - if err := d.writeAll(cmd); err != nil { - return err - } - if len(r) != 0 { - err := d.readAll(r) - return err - } - return nil -} - -// mpsseTxShort runs a transaction on the clock pins D0, D1 and D2 for a byte -// or less: between 1 and 8 bits. -func (d *device) mpsseTxShort(w byte, wbits, rbits int, ew, er gpio.Edge, lsbf bool) (byte, error) { - op := byte(dataBit) - if lsbf { - op |= dataLSBF - } - l := wbits - if wbits != 0 { - if wbits > 8 { - return 0, errors.New("d2xx: write buffer too long; max 8") - } - op |= dataOut - if ew == gpio.FallingEdge { - op |= dataOutFall - } - } - if rbits != 0 { - if rbits > 8 { - return 0, errors.New("d2xx: read buffer too long; max 8") - } - op |= dataIn - if er == gpio.FallingEdge { - op |= dataInFall - } - if l != 0 && rbits != l { - return 0, errors.New("d2xx: mismatched buffer lengths") - } - l = rbits - } - b := [3]byte{op, byte(l - 1)} - cmd := b[:2] - if wbits != 0 { - cmd = append(cmd, w) - } - if rbits != 0 { - cmd = append(cmd, flush) - } - if err := d.writeAll(cmd); err != nil { - return 0, err - } - if rbits != 0 { - err := d.readAll(b[:1]) - return b[0], err - } - return 0, nil -} - -func (d *device) mpsseCBus(mask, value byte) error { - b := [...]byte{gpioSetC, value, mask} - return d.writeAll(b[:]) -} - -// mpsseDBus operates on 8 GPIOs at a time D0~D7. -// -// Direction 1 means output, 0 means input. -func (d *device) mpsseDBus(mask, value byte) error { - b := [...]byte{gpioSetD, value, mask} - return d.writeAll(b[:]) -} - -func (d *device) mpsseCBusRead() (byte, error) { - b := [...]byte{gpioReadC, flush} - if err := d.writeAll(b[:]); err != nil { - return 0, err - } - if err := d.readAll(b[:1]); err != nil { - return 0, err - } - return b[0], nil -} - -func (d *device) mpsseDBusRead() (byte, error) { - b := [...]byte{gpioReadD, flush} - if err := d.writeAll(b[:]); err != nil { - return 0, err - } - if err := d.readAll(b[:1]); err != nil { - return 0, err - } - return b[0], nil -} - -// - -// gpiosMPSSE is a slice of 8 GPIO pins driven via MPSSE. -// -// This permits keeping a cache. -type gpiosMPSSE struct { - // Immutable. - h *device - cbus bool // false if D bus - pins [8]gpioMPSSE - - // Cache of values - direction byte - value byte -} - -func (g *gpiosMPSSE) init(name string) { - s := "D" - if g.cbus { - s = "C" - } - // Configure pulls; pull ups are 75kΩ. - // http://www.ftdichip.com/Support/Documents/AppNotes/AN_184%20FTDI%20Device%20Input%20Output%20Pin%20States.pdf - // has a good table. - // D0, D2 and D4 go in high impedance before going into pull up. - // TODO(maruel): The pull on CBus depends on EEPROM! - for i := range g.pins { - g.pins[i].a = g - g.pins[i].n = name + "." + s + strconv.Itoa(i) - g.pins[i].num = i - g.pins[i].dp = gpio.PullUp - } - if g.cbus { - // That's just the default EEPROM value. - g.pins[7].dp = gpio.PullDown - } -} - -func (g *gpiosMPSSE) in(n int) error { - if g.h == nil { - return errors.New("d2xx: device not open") - } - g.direction = g.direction & ^(1 << uint(n)) - if g.cbus { - return g.h.mpsseCBus(g.direction, g.value) - } - return g.h.mpsseDBus(g.direction, g.value) -} - -func (g *gpiosMPSSE) read() (byte, error) { - if g.h == nil { - return 0, errors.New("d2xx: device not open") - } - var err error - if g.cbus { - g.value, err = g.h.mpsseCBusRead() - } else { - g.value, err = g.h.mpsseDBusRead() - } - return g.value, err -} - -func (g *gpiosMPSSE) out(n int, l gpio.Level) error { - if g.h == nil { - return errors.New("d2xx: device not open") - } - g.direction = g.direction | (1 << uint(n)) - if l { - g.value |= 1 << uint(n) - } else { - g.value &^= 1 << uint(n) - } - if g.cbus { - return g.h.mpsseCBus(g.direction, g.value) - } - return g.h.mpsseDBus(g.direction, g.value) -} - -// - -// gpioMPSSE is a GPIO pin on a FTDI device driven via MPSSE. -// -// gpioMPSSE implements gpio.PinIO. -// -// It is immutable and stateless. -type gpioMPSSE struct { - a *gpiosMPSSE - n string - num int - dp gpio.Pull -} - -// String implements pin.Pin. -func (g *gpioMPSSE) String() string { - return g.n -} - -// Name implements pin.Pin. -func (g *gpioMPSSE) Name() string { - return g.n -} - -// Number implements pin.Pin. -func (g *gpioMPSSE) Number() int { - return g.num -} - -// Function implements pin.Pin. -func (g *gpioMPSSE) Function() string { - s := "Out/" - m := byte(1 << uint(g.num)) - if g.a.direction&m == 0 { - s = "In/" - g.a.read() - } - return s + gpio.Level(g.a.value&m != 0).String() -} - -// Halt implements gpio.PinIO. -func (g *gpioMPSSE) Halt() error { - return nil -} - -// In implements gpio.PinIn. -func (g *gpioMPSSE) In(pull gpio.Pull, e gpio.Edge) error { - if e != gpio.NoEdge { - // We could support it on D5. - return errors.New("d2xx: edge triggering is not supported") - } - if pull != g.dp && pull != gpio.PullNoChange { - // TODO(maruel): This needs to be redone: - // - EEPROM values FT232hCBusTristatePullUp and FT232hCBusPwrEnable can be - // used to control individual CBus pins. - // - dataTristate enables gpio.Float when set to output High, but I don't - // know if it will enable reading the value (?). This needs to be - // confirmed. - return fmt.Errorf("d2xx: pull %s is not supported; try %s", pull, g.dp) - } - return g.a.in(g.num) -} - -// Read implements gpio.PinIn. -func (g *gpioMPSSE) Read() gpio.Level { - v, _ := g.a.read() - return gpio.Level(v&(1< physic.GigaHertz { - return nil, fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 30MHz", f) - } - if f > 30*physic.MegaHertz { - // TODO(maruel): Figure out a way to communicate that the speed was lowered. - // https://github.com/google/periph/issues/255 - f = 30 * physic.MegaHertz - } - if f < 100*physic.Hertz { - return nil, fmt.Errorf("d2xx: invalid speed %s; minimum supported clock is 100Hz; did you forget to multiply by physic.MegaHertz?", f) - } - if bits&7 != 0 { - return nil, errors.New("d2xx: bits must be multiple of 8") - } - if bits != 8 { - return nil, errors.New("d2xx: implement bits per word above 8") - } - - s.c.f.mu.Lock() - defer s.c.f.mu.Unlock() - s.c.noCS = m&spi.NoCS != 0 - s.c.halfDuplex = m&spi.HalfDuplex != 0 - s.c.lsbFirst = m&spi.LSBFirst != 0 - m &^= spi.NoCS | spi.HalfDuplex | spi.LSBFirst - if s.c.halfDuplex { - return nil, errors.New("d2xx: spi.HalfDuplex is not yet supported (implementing wouldn't be too hard, please submit a PR") - } - if m < 0 || m > 3 { - return nil, errors.New("d2xx: unknown spi mode") - } - s.c.edgeInvert = m&1 != 0 - s.c.clkActiveLow = m&2 != 0 - if s.maxFreq == 0 || f < s.maxFreq { - // TODO(maruel): We could set these only *during* the SPI operation, which - // would make more sense. - if _, err := s.c.f.h.mpsseClock(f); err != nil { - return nil, err - } - s.maxFreq = f - } - s.c.resetIdle() - if err := s.c.f.h.mpsseDBus(s.c.f.dbus.direction, s.c.f.dbus.value); err != nil { - return nil, err - } - s.c.f.usingSPI = true - return &s.c, nil -} - -// LimitSpeed implements spi.Port. -func (s *spiMPSEEPort) LimitSpeed(f physic.Frequency) error { - if f > physic.GigaHertz { - return fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 30MHz", f) - } - if f > 30*physic.MegaHertz { - f = 30 * physic.MegaHertz - } - if f < 100*physic.Hertz { - return errors.New("d2xx: minimum supported clock is 100Hz; did you forget to multiply by physic.MegaHertz?") - } - s.c.f.mu.Lock() - defer s.c.f.mu.Unlock() - if s.maxFreq != 0 && s.maxFreq <= f { - return nil - } - s.maxFreq = f - // TODO(maruel): We could set these only *during* the SPI operation, which - // would make more sense. - _, err := s.c.f.h.mpsseClock(s.maxFreq) - return err -} - -// CLK returns the SCK (clock) pin. -func (s *spiMPSEEPort) CLK() gpio.PinOut { - return s.c.CLK() -} - -// MOSI returns the SDO (master out, slave in) pin. -func (s *spiMPSEEPort) MOSI() gpio.PinOut { - return s.c.MOSI() -} - -// MISO returns the SDI (master in, slave out) pin. -func (s *spiMPSEEPort) MISO() gpio.PinIn { - return s.c.MISO() -} - -// CS returns the CSN (chip select) pin. -func (s *spiMPSEEPort) CS() gpio.PinOut { - return s.c.CS() -} - -type spiMPSEEConn struct { - // Immutable. - f *FT232H - - // Initialized at Connect(). - edgeInvert bool // CPHA=1 - clkActiveLow bool // CPOL=1 - noCS bool // CS line is not changed - lsbFirst bool // Default is MSB first - halfDuplex bool // 3 wire mode -} - -func (s *spiMPSEEConn) String() string { - return s.f.String() -} - -func (s *spiMPSEEConn) Tx(w, r []byte) error { - var p = [1]spi.Packet{{W: w, R: r}} - return s.TxPackets(p[:]) -} - -func (s *spiMPSEEConn) Duplex() conn.Duplex { - // TODO(maruel): Support half if there's a need. - return conn.Full -} - -func (s *spiMPSEEConn) TxPackets(pkts []spi.Packet) error { - // Verification. - for _, p := range pkts { - if p.KeepCS { - return errors.New("d2xx: implement spi.Packet.KeepCS") - } - if p.BitsPerWord&7 != 0 { - return errors.New("d2xx: bits must be a multiple of 8") - } - if p.BitsPerWord != 0 && p.BitsPerWord != 8 { - return errors.New("d2xx: implement spi.Packet.BitsPerWord") - } - if err := verifyBuffers(p.W, p.R); err != nil { - return err - } - } - s.f.mu.Lock() - defer s.f.mu.Unlock() - const clk = byte(1) << 0 - const mosi = byte(1) << 1 - const miso = byte(1) << 2 - const cs = byte(1) << 3 - s.resetIdle() - idle := s.f.dbus.value - start1 := idle - if !s.noCS { - start1 &^= cs - } - // In mode 0 and 2, start2 is not needed. - start2 := start1 - stop := idle - if s.edgeInvert { - // This is needed to 'prime' the clock. - start2 ^= clk - // With mode 1 and 3, keep the clock steady while CS is being deasserted to - // not create a spurious clock. - stop ^= clk - } - ew := gpio.FallingEdge - er := gpio.RisingEdge - if s.edgeInvert { - ew, er = er, ew - } - if s.clkActiveLow { - // TODO(maruel): Not sure. - ew, er = er, ew - } - - // FT232H claims 512 USB packet support, so to reduce the chatter over USB, - // try to make all I/O be aligned on this amount. This also removes the need - // for heap usage. The idea is to always trail reads by one buffer. This is - // fine as the device has 1024 byte read buffer. Operations look like this: - // W, W, R, W, R, W, R, R - // This enables reducing the I/O gaps between USB packets as the device is - // always busy with operations. - var buf [512]byte - cmd := buf[:0] - keptCS := false - - // Loop, without increasing the index. - for _, p := range pkts { - if len(p.W) == 0 && len(p.R) == 0 { - continue - } - // TODO(maruel): s.halfDuplex. - - if !keptCS { - for i := 0; i < 5; i++ { - cmd = append(cmd, gpioSetD, idle, s.f.dbus.direction) - } - for i := 0; i < 5; i++ { - cmd = append(cmd, gpioSetD, start1, s.f.dbus.direction) - } - } - if s.edgeInvert { - // This is needed to 'prime' the clock. - for i := 0; i < 5; i++ { - cmd = append(cmd, gpioSetD, start2, s.f.dbus.direction) - } - } - op := mpsseTxOp(len(p.W) != 0, len(p.R) != 0, ew, er, s.lsbFirst) - - // Do an I/O loop. We can mutate p here because it is a copy. - // TODO(maruel): Have the pipeline cross the packet boundary. - if len(p.W) == 0 { - // Have the write buffer point to the read one. This saves from - // allocating memory. The side effect is that it will write whatever - // happened to be in the read buffer. - p.W = p.R[:] - } - pendingRead := 0 - for len(p.W) != 0 { - // op, sizelo, sizehi. - chunk := len(buf) - 3 - len(cmd) - if l := len(p.W); chunk > l { - chunk = l - } - cmd = append(cmd, op, byte(chunk-1), byte((chunk-1)>>8)) - cmd = append(cmd, p.W[:chunk]...) - p.W = p.W[chunk:] - if _, err := s.f.h.write(cmd); err != nil { - return err - } - cmd = buf[:0] - - // TODO(maruel): Read 62 bytes at a time? - // Delay reading by 512 bytes. - if pendingRead >= 512 { - if len(p.R) != 0 { - // Align reads on 512 bytes exactly, aligned on USB packet size. - if err := s.f.h.readAll(p.R[:512]); err != nil { - return err - } - p.R = p.R[512:] - pendingRead -= 512 - } - } - pendingRead += chunk - } - // Do not forget to read whatever is pending. - // TODO(maruel): Investigate if a flush helps. - if len(p.R) != 0 { - // Send a flush to not wait for data. - cmd = append(cmd, flush) - if _, err := s.f.h.write(cmd); err != nil { - return err - } - cmd = buf[:0] - if err := s.f.h.readAll(p.R); err != nil { - return err - } - } - // TODO(maruel): Inject this in the write if it fits (it will generally - // do). That will save one USB I/O, which is not insignificant. - keptCS = p.KeepCS - if !keptCS { - cmd = append(cmd, flush) - for i := 0; i < 5; i++ { - cmd = append(cmd, gpioSetD, stop, s.f.dbus.direction) - } - for i := 0; i < 5; i++ { - cmd = append(cmd, gpioSetD, idle, s.f.dbus.direction) - } - if _, err := s.f.h.write(cmd); err != nil { - return err - } - cmd = buf[:0] - } - } - return nil -} - -// CLK returns the SCK (clock) pin. -func (s *spiMPSEEConn) CLK() gpio.PinOut { - return s.f.D0 -} - -// MOSI returns the SDO (master out, slave in) pin. -func (s *spiMPSEEConn) MOSI() gpio.PinOut { - return s.f.D1 -} - -// MISO returns the SDI (master in, slave out) pin. -func (s *spiMPSEEConn) MISO() gpio.PinIn { - return s.f.D2 -} - -// CS returns the CSN (chip select) pin. -func (s *spiMPSEEConn) CS() gpio.PinOut { - return s.f.D3 -} - -// resetIdle sets D0~D3. D0, D1 and D3 are output but only touch D3 is CS is -// used. -func (s *spiMPSEEConn) resetIdle() { - const clk = byte(1) << 0 - const mosi = byte(1) << 1 - const miso = byte(1) << 2 - const cs = byte(1) << 3 - if !s.noCS { - s.f.dbus.direction &= 0xF0 - s.f.dbus.direction |= cs - s.f.dbus.value &= 0xF0 - s.f.dbus.value |= cs - } else { - s.f.dbus.value &= 0xF8 - s.f.dbus.direction &= 0xF8 - } - s.f.dbus.direction |= mosi | clk - if s.clkActiveLow { - // Clock idles high. - s.f.dbus.value |= clk - } -} - -// - -// spiSyncPort is an SPI port over a FTDI device in synchronous bit-bang mode. -type spiSyncPort struct { - c spiSyncConn - - // Mutable. - maxFreq physic.Frequency -} - -func (s *spiSyncPort) Close() error { - s.c.f.mu.Lock() - s.c.f.usingSPI = false - s.maxFreq = 0 - s.c.edgeInvert = false - s.c.clkActiveLow = false - s.c.noCS = false - s.c.lsbFirst = false - s.c.halfDuplex = false - s.c.f.mu.Unlock() - return nil -} - -func (s *spiSyncPort) String() string { - return s.c.f.String() -} - -const ft232rMaxSpeed = 3 * physic.MegaHertz - -// Connect implements spi.Port. -func (s *spiSyncPort) Connect(f physic.Frequency, m spi.Mode, bits int) (spi.Conn, error) { - if f > physic.GigaHertz { - return nil, fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 1.5MHz", f) - } - if f > ft232rMaxSpeed/2 { - // TODO(maruel): Figure out a way to communicate that the speed was lowered. - // https://github.com/google/periph/issues/255 - f = ft232rMaxSpeed / 2 - } - if f < 100*physic.Hertz { - return nil, fmt.Errorf("d2xx: invalid speed %s; minimum supported clock is 100Hz; did you forget to multiply by physic.MegaHertz?", f) - } - if bits&7 != 0 { - return nil, errors.New("d2xx: bits must be multiple of 8") - } - if bits != 8 { - return nil, errors.New("d2xx: implement bits per word above 8") - } - - s.c.f.mu.Lock() - defer s.c.f.mu.Unlock() - s.c.noCS = m&spi.NoCS != 0 - s.c.halfDuplex = m&spi.HalfDuplex != 0 - s.c.lsbFirst = m&spi.LSBFirst != 0 - m &^= spi.NoCS | spi.HalfDuplex | spi.LSBFirst - if s.c.halfDuplex { - return nil, errors.New("d2xx: spi.HalfDuplex is not yet supported (implementing wouldn't be too hard, please submit a PR") - } - if m < 0 || m > 3 { - return nil, errors.New("d2xx: unknown spi mode") - } - s.c.edgeInvert = m&1 != 0 - s.c.clkActiveLow = m&2 != 0 - if s.maxFreq == 0 || f < s.maxFreq { - if err := s.c.f.SetSpeed(f * 2); err != nil { - return nil, err - } - s.maxFreq = f - } - // D0, D2 and D3 are output. D4~D7 are kept as-is. - const mosi = byte(1) << 0 // TX - const miso = byte(1) << 1 // RX - const clk = byte(1) << 2 // RTS - const cs = byte(1) << 3 // CTS - mask := mosi | clk | cs | (s.c.f.dmask & 0xF0) - if err := s.c.f.setDBusMaskLocked(mask); err != nil { - return nil, err - } - // TODO(maruel): Combine both following calls if possible. We'd shave off a - // few ms. - if !s.c.noCS { - // CTS/SPI_CS is active low. - if err := s.c.f.dbusSyncGPIOOutLocked(3, gpio.High); err != nil { - return nil, err - } - } - if s.c.clkActiveLow { - // RTS/SPI_CLK is active low. - if err := s.c.f.dbusSyncGPIOOutLocked(2, gpio.High); err != nil { - return nil, err - } - } - s.c.f.usingSPI = true - return &s.c, nil -} - -// LimitSpeed implements spi.Port. -func (s *spiSyncPort) LimitSpeed(f physic.Frequency) error { - if f > physic.GigaHertz { - return fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 1.5MHz", f) - } - if f < 100*physic.Hertz { - return fmt.Errorf("d2xx: invalid speed %s; minimum supported clock is 100Hz; did you forget to multiply by physic.MegaHertz?", f) - } - s.c.f.mu.Lock() - defer s.c.f.mu.Unlock() - if s.maxFreq != 0 && s.maxFreq <= f { - return nil - } - if err := s.c.f.SetSpeed(f * 2); err == nil { - s.maxFreq = f - } - return nil -} - -// CLK returns the SCK (clock) pin. -func (s *spiSyncPort) CLK() gpio.PinOut { - return s.c.CLK() -} - -// MOSI returns the SDO (master out, slave in) pin. -func (s *spiSyncPort) MOSI() gpio.PinOut { - return s.c.MOSI() -} - -// MISO returns the SDI (master in, slave out) pin. -func (s *spiSyncPort) MISO() gpio.PinIn { - return s.c.MISO() -} - -// CS returns the CSN (chip select) pin. -func (s *spiSyncPort) CS() gpio.PinOut { - return s.c.CS() -} - -type spiSyncConn struct { - // Immutable. - f *FT232R - - // Initialized at Connect(). - edgeInvert bool // CPHA=1 - clkActiveLow bool // CPOL=1 - noCS bool // CS line is not changed - lsbFirst bool // Default is MSB first - halfDuplex bool // 3 wire mode -} - -func (s *spiSyncConn) String() string { - return s.f.String() -} - -func (s *spiSyncConn) Tx(w, r []byte) error { - var p = [1]spi.Packet{{W: w, R: r}} - return s.TxPackets(p[:]) -} - -func (s *spiSyncConn) Duplex() conn.Duplex { - // TODO(maruel): Support half if there's a need. - return conn.Full -} - -func (s *spiSyncConn) TxPackets(pkts []spi.Packet) error { - // We need to 'expand' each bit 2 times * 8 bits, which leads - // to a 16x memory usage increase. Adds 5 samples before and after. - totalW := 0 - totalR := 0 - for _, p := range pkts { - if p.KeepCS { - return errors.New("d2xx: implement spi.Packet.KeepCS") - } - if p.BitsPerWord&7 != 0 { - return errors.New("d2xx: bits must be a multiple of 8") - } - if p.BitsPerWord != 0 && p.BitsPerWord != 8 { - return errors.New("d2xx: implement spi.Packet.BitsPerWord") - } - if err := verifyBuffers(p.W, p.R); err != nil { - return err - } - // TODO(maruel): Correctly calculate offsets. - if len(p.W) != 0 { - totalW += 2 * 8 * len(p.W) - } - if len(p.R) != 0 { - totalR += 2 * 8 * len(p.R) - } - } - - // Create a large, single chunk. - var we, re []byte - if totalW != 0 { - totalW += 10 - we = make([]byte, 0, totalW) - } - if totalR != 0 { - totalR += 10 - re = make([]byte, totalR) - } - const mosi = byte(1) << 0 // TX - const miso = byte(1) << 1 // RX - const clk = byte(1) << 2 // RTS - const cs = byte(1) << 3 // CTS - - s.f.mu.Lock() - defer s.f.mu.Unlock() - - // https://en.wikipedia.org/wiki/Serial_Peripheral_Interface#Data_transmission - - csActive := s.f.dvalue & s.f.dmask & 0xF0 - csIdle := csActive - if !s.noCS { - csIdle = csActive | cs - } - clkIdle := csActive - clkActive := clkIdle | clk - if s.clkActiveLow { - clkActive, clkIdle = clkIdle, clkActive - csIdle |= clk - } - // Start of tx; assert CS if needed. - we = append(we, csIdle, clkIdle, clkIdle, clkIdle, clkIdle) - for _, p := range pkts { - if len(p.W) == 0 && len(p.R) == 0 { - continue - } - // TODO(maruel): s.halfDuplex. - for _, b := range p.W { - for j := uint(0); j < 8; j++ { - // For each bit, handle clock phase and data phase. - bit := byte(0) - if !s.lsbFirst { - // MSBF - if b&(0x80>>j) != 0 { - bit = mosi - } - } else { - // LSBF - if b&(1<> uint(j) - } else { - // LSBF - b |= 1 << uint(j) - } - } - } - p.R[i] = b - } - } - return nil -} - -// CLK returns the SCK (clock) pin. -func (s *spiSyncConn) CLK() gpio.PinOut { - return s.f.D2 // RTS -} - -// MOSI returns the SDO (master out, slave in) pin. -func (s *spiSyncConn) MOSI() gpio.PinOut { - return s.f.D0 // TX -} - -// MISO returns the SDI (master in, slave out) pin. -func (s *spiSyncConn) MISO() gpio.PinIn { - return s.f.D1 // RX -} - -// CS returns the CSN (chip select) pin. -func (s *spiSyncConn) CS() gpio.PinOut { - return s.f.D3 // CTS -} - -// - -func verifyBuffers(w, r []byte) error { - if len(w) != 0 { - if len(r) != 0 { - if len(w) != len(r) { - return errors.New("d2xx: both buffers must have the same size") - } - } - // TODO(maruel): When the buffer is >64Kb, cut it in parts and do not - // request a flush. Still try to read though. - if len(w) > 65536 { - return errors.New("d2xx: maximum buffer size is 64Kb") - } - } else if len(r) != 0 { - // TODO(maruel): Remove, this is not a problem. - if len(r) > 65536 { - return errors.New("d2xx: maximum buffer size is 64Kb") - } - } - return nil -} - -var _ spi.PortCloser = &spiMPSEEPort{} -var _ spi.Conn = &spiMPSEEConn{} -var _ spi.PortCloser = &spiSyncPort{} -var _ spi.Conn = &spiSyncConn{} diff --git a/hostextra/d2xx/test.sh b/hostextra/d2xx/test.sh deleted file mode 100755 index a491258..0000000 --- a/hostextra/d2xx/test.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -# Copyright 2017 The Periph Authors. All rights reserved. -# Use of this source code is governed under the Apache License, Version 2.0 -# that can be found in the LICENSE file. - -# Builds the package on multiple OSes to confirm it builds fine. -# -# It is recommended to use the -i flag so subsequent runs are much faster. - -set -eu - -cd `dirname $0` - -OPT=$* - -function build { - echo "Testing on $1/$2" - GOOS=$1 GOARCH=$2 go build $OPT -} - -build darwin amd64 -build linux amd64 -build linux arm -build linux 386 -build windows amd64 diff --git a/hostextra/d2xx/uart.go b/hostextra/d2xx/uart.go deleted file mode 100644 index 374cc0d..0000000 --- a/hostextra/d2xx/uart.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2017 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// This functionality requires MPSSE *or* a FT242R. - -package d2xx diff --git a/hostextra/doc.go b/hostextra/doc.go deleted file mode 100644 index b22e0fd..0000000 --- a/hostextra/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -// Package hostextra is obsolete. -// -// Please use https://periph.io/x/host/v3 (or later) directly. -package hostextra diff --git a/hostextra/hostextra.go b/hostextra/hostextra.go deleted file mode 100644 index c34e1ea..0000000 --- a/hostextra/hostextra.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -package hostextra - -import ( - _ "periph.io/x/extra/hostextra/d2xx" - "periph.io/x/periph" - "periph.io/x/periph/host" -) - -// Init calls host.Init(), which calls periph.Init() and returns it as-is. -// -// The difference with host.Init() and periph.Init() is that hostextra.Init() -// includes more drivers, the drivers that either depend on third party -// packages or on cgo. -// -// Since host.Init() is used, all drivers in periph.io/x/periph/host are also -// automatically loaded. -func Init() (*periph.State, error) { - return host.Init() -} diff --git a/hostextra/hostextra_test.go b/hostextra/hostextra_test.go deleted file mode 100644 index 67eb4ef..0000000 --- a/hostextra/hostextra_test.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2018 The Periph Authors. All rights reserved. -// Use of this source code is governed under the Apache License, Version 2.0 -// that can be found in the LICENSE file. - -package hostextra - -import ( - "testing" -) - -func TestInit(t *testing.T) { - if _, err := Init(); err != nil { - t.Fatalf("failed to initialize periph: %v", err) - } -}