diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 234a3b5..51d165f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,12 @@ -on: [ push, pull_request ] +on: + push: + branches: [main] + pull_request: + branches: [main] +permissions: + # Goreadme needs permissions to update pull requests comments and change contents. + pull-requests: write + contents: write name: Build jobs: test: @@ -13,14 +21,13 @@ jobs: uses: actions/setup-go@v1 with: go-version: ${{ matrix.go-version }} - - name: Install libusb-1.0-0-dev - run: sudo apt-get install libusb-1.0-0-dev - name: Checkout code uses: actions/checkout@v1 + - name: Install libusb-1.0-0-dev + run: sudo apt-get install libusb-1.0-0-dev - name: Run tests - run: go test -v -race - - coverage: + run: go test -v -race ./... + codecov: runs-on: ubuntu-latest needs: test steps: @@ -29,11 +36,38 @@ jobs: uses: actions/setup-go@v1 with: go-version: 1.16.x - - name: Install libusb-1.0-0-dev - run: sudo apt-get install libusb-1.0-0-dev - name: Checkout code uses: actions/checkout@v1 + - name: Install libusb-1.0-0-dev + run: sudo apt-get install libusb-1.0-0-dev - name: Run tests - run: go test -v -race -covermode=atomic -coverprofile=coverage.txt - - name: Upload coverage to Codecov - run: bash <(curl -s https://codecov.io/bash) + run: go test -v -race -covermode=atomic -coverprofile=coverage.out ./... + - name: CodeCov + uses: codecov/codecov-action@v2 + lint: + name: Lint project using GolangCI Lint + runs-on: ubuntu-latest + needs: test + steps: + - name: Check out code into the Go module directory + uses: actions/checkout@v1 + - name: GolangCI-Lint Action + uses: golangci/golangci-lint-action@v2.5.2 + with: + version: latest + only-new-issues: true + args: --issues-exit-code=0 + goreadme: + runs-on: ubuntu-latest + needs: [codecov, lint] + steps: + - name: Check out repository + uses: actions/checkout@v2 + - name: Update readme according to Go doc + uses: posener/goreadme@v1 + with: + badge-codecov: 'true' + badge-godoc: 'true' + email: 'justin@dynam.ac' + title: 'Go-DCDCUSB' + github-token: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index f1a4fd7..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,16 +0,0 @@ -on: [ push, pull_request ] -name: Linter -jobs: - lint: - name: Lint project using GolangCI Lint - runs-on: ubuntu-latest - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v1 - - - name: GolangCI-Lint Action - uses: golangci/golangci-lint-action@v2.5.2 - with: - version: latest - only-new-issues: true - args: --issues-exit-code=0 diff --git a/cmd/main.go b/cmd/main.go index b9d7ffc..be793d1 100755 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,42 +1,42 @@ -// Copyright 2013 Google Inc. All rights reserved. -// Copyright 2016 the gousb Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* +MIT License + +Copyright (c) 2021 Justin Hammond + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ -// lsusb lists attached USB devices. package main import ( "context" - "flag" - "fmt" "log" "time" "github.com/Fishwaldo/go-dcdc200" - "github.com/google/gousb" - "github.com/google/gousb/usbid" ) -var ( - debug = flag.Int("debug", 0, "libusb debug level (0..3)") -) func main() { - test() - - dc := dcdc200.Dcdc200{} - if ok, err := dc.Scan(); ok != true { + dc := dcdcusb.DcDcUSB{} + dc.Init() + if ok, err := dc.Scan(); !ok { log.Fatalf("Scan Failed: %v", err) return } @@ -49,64 +49,3 @@ func main() { } dc.Close() } - -func test() { - flag.Parse() - - // Only one context should be needed for an application. It should always be closed. - ctx := gousb.NewContext() - defer ctx.Close() - - // Debugging can be turned on; this shows some of the inner workings of the libusb package. - ctx.Debug(*debug) - - // OpenDevices is used to find the devices to open. - devs, err := ctx.OpenDevices(func(desc *gousb.DeviceDesc) bool { - // The usbid package can be used to print out human readable information. - fmt.Printf("%03d.%03d %s:%s %s\n", desc.Bus, desc.Address, desc.Vendor, desc.Product, usbid.Describe(desc)) - fmt.Printf(" Protocol: %s\n", usbid.Classify(desc)) - - // The configurations can be examined from the DeviceDesc, though they can only - // be set once the device is opened. All configuration references must be closed, - // to free up the memory in libusb. - for _, cfg := range desc.Configs { - // This loop just uses more of the built-in and usbid pretty printing to list - // the USB devices. - fmt.Printf(" %s:\n", cfg) - for _, intf := range cfg.Interfaces { - fmt.Printf(" --------------\n") - for _, ifSetting := range intf.AltSettings { - fmt.Printf(" %s\n", ifSetting) - fmt.Printf(" %s\n", usbid.Classify(ifSetting)) - for _, end := range ifSetting.Endpoints { - fmt.Printf(" %s\n", end) - } - } - } - fmt.Printf(" --------------\n") - } - - // After inspecting the descriptor, return true or false depending on whether - // the device is "interesting" or not. Any descriptor for which true is returned - // opens a Device which is retuned in a slice (and must be subsequently closed). - return false - }) - - // All Devices returned from OpenDevices must be closed. - defer func() { - for _, d := range devs { - d.Close() - } - }() - - // OpenDevices can occasionally fail, so be sure to check its return value. - if err != nil { - log.Fatalf("list: %s", err) - } - - for _, dev := range devs { - // Once the device has been selected from OpenDevices, it is opened - // and can be interacted with. - _ = dev - } -} diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..9ec6066 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,6 @@ +coverage: + status: + project: + default: + target: auto + threshold: 10% diff --git a/dcdcmodet_string.go b/dcdcmodet_string.go index 51f56cf..12c4e7d 100644 --- a/dcdcmodet_string.go +++ b/dcdcmodet_string.go @@ -1,6 +1,6 @@ // Code generated by "stringer -type=DcdcModet"; DO NOT EDIT. -package dcdc200 +package dcdcusb import "strconv" diff --git a/dcdcstatet_string.go b/dcdcstatet_string.go index 0884b3d..a22f364 100644 --- a/dcdcstatet_string.go +++ b/dcdcstatet_string.go @@ -1,6 +1,6 @@ // Code generated by "stringer -type=DcdcStatet"; DO NOT EDIT. -package dcdc200 +package dcdcusb import "strconv" diff --git a/dcdcusb.go b/dcdcusb.go new file mode 100755 index 0000000..294aaa8 --- /dev/null +++ b/dcdcusb.go @@ -0,0 +1,357 @@ +/* +MIT License + +Copyright (c) 2021 Justin Hammond + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package dcdcusb + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/Fishwaldo/go-logadapter" + "github.com/Fishwaldo/go-logadapter/loggers/std" + "github.com/google/gousb" +) +// Main Structure for the DCDCUSB Communications +type DcDcUSB struct { + ctx *gousb.Context + dev *gousb.Device + intf *gousb.Interface + done func() + log logadapter.Logger + initOnce sync.Once +} + +// Represents the Settings for Off and Hardoff Delays when power is lost +type TimerConfigt struct { + // After Ignition Lost, this the time waiting till we toggle the Power Switch I/F + OffDelay time.Duration `json:"off_delay,omitempty"` + // After the Power Switch I/F is toggled, this is the delay before we cut power + HardOff time.Duration `json:"hard_off,omitempty"` +} + +// Status of Various Peripherals +type Peripheralst struct { + // ?? + OutSwVin bool `json:"out_sw_vin,omitempty"` + // ?? + OutPsw bool `json:"out_psw,omitempty"` + // ?? + OutStartOutput bool `json:"out_start_output,omitempty"` + // Status of the Onboard Led + OutLed bool `json:"out_led,omitempty"` + // If the VOut is within range. + InVoutGood bool `json:"in_vout_good,omitempty"` +} + +// Overall Status of the DCDCUSB Power Supply +type Params struct { + // What the Vout Setting is configured for + VoutSet float32 `json:"vout_set,omitempty"` + // What Voltage the Config Jumpers are set for VOut + VoutConfig float32 `json:"vout_config,omitempty"` + // The Input Voltage + Vin float32 `json:"vin,omitempty"` + // The Ignition Voltage + Vign float32 `json:"vign,omitempty"` + // What the Actual VOut Voltage is + VoutActual float32 `json:"vout_actual,omitempty"` + // Status of Various Peripherals + Peripherals Peripheralst `json:"peripherals,omitempty"` + // ?? (Not Output Enabled?) + Output bool `json:"output,omitempty"` + // ?? + AuxVIn bool `json:"aux_v_in,omitempty"` + // Firmware Version? + Version string `json:"version,omitempty"` + // State of the Power Supply + State DcdcStatet `json:"state,omitempty"` + // Config Registers (unknown) + CfgRegisters byte `json:"cfg_registers,omitempty"` + // Voltage Flags (Unknown) + VoltFlags byte `json:"volt_flags,omitempty"` + // Timer Flags (Unknown) + TimerFlags byte `json:"timer_flags,omitempty"` + // The configured countdown times for the Timer upon Power Loss + TimerConfig TimerConfigt `json:"timer_config,omitempty"` + // Current Power Loss Debounce Timer + TimerWait time.Duration `json:"timer_wait,omitempty"` + // Current VOut Countdown Timer + TimerVOut time.Duration `json:"timer_v_out,omitempty"` + // Current VAux Countdown timer + TimerVAux time.Duration `json:"timer_v_aux,omitempty"` + // Current Power Switch Toggle Count Down Timer + TimerPRWSW time.Duration `json:"timer_prwsw,omitempty"` + // Current Soft Off Countdown Timer + TimerSoftOff time.Duration `json:"timer_soft_off,omitempty"` + // Current Hard Off Countdown Timer + TimerHardOff time.Duration `json:"timer_hard_off,omitempty"` + // Current Script Position + ScriptPointer byte `json:"script_pointer,omitempty"` + // Current Operating Mode + Mode DcdcModet `json:"mode,omitempty"` +} +// Initialize the DCDCUSB Communications. Should be first function called before any other methods are called +func (dc *DcDcUSB) Init() { + dc.initOnce.Do(func() { + if dc.log == nil { + templogger := stdlogger.DefaultLogger() + templogger.Log.SetPrefix("DCDCUSB") + dc.log = templogger + } + }) + dc.ctx = gousb.NewContext() +} + +// Set a Custom Logger based on https://github.com/Fishwaldo/go-logadapter +// If not set, then the Library will use the Std Library Logger +func (dc *DcDcUSB) SetLogger(log logadapter.Logger) { + dc.log = log +} + +// Set the debug level for the GoUSB Library +func (dc *DcDcUSB) SetUSBDebug(level int) { + if dc.ctx != nil { + dc.ctx.Debug(level) + } +} + +// Scan for a DCDCUSB connection, returns true if found, or false (and optional error) if there +// was a failure setting up communications with it. +func (dc *DcDcUSB) Scan() (bool, error) { + var err error + dc.dev, err = dc.ctx.OpenDeviceWithVIDPID(dcdc200_vid, dcdc200_pid) + if err != nil { + dc.log.Warn("Could Not Open Device: %v", err) + dc.Close() + return false, err + } + if dc.dev == nil { + dc.log.Warn("Can't Find Device") + dc.Close() + return false, nil + } + err = dc.dev.SetAutoDetach(true) + if err != nil { + dc.log.Error("%s.SetAutoDetach(true): %v", dc.dev, err) + } + + confignum, _ := dc.dev.ActiveConfigNum() + dc.log.Trace("Device Config: %s %d", dc.dev.String(), confignum) + // desc, _ := dc.dev.GetStringDescriptor(1) + // manu, _ := dc.dev.Manufacturer() + // prod, _ := dc.dev.Product() + // serial, _ := dc.dev.SerialNumber() + dc.intf, dc.done, err = dc.dev.DefaultInterface() + if err != nil { + dc.log.Error("%s.Interface(): %v", dc.dev, err) + dc.Close() + return false, err + } + dc.log.Trace("Interface: %s", dc.intf.String()) + dc.log = dc.log.With("Device", dc.intf.String()) + return true, nil +} +func (dc *DcDcUSB) Close() { + if dc.intf != nil { + dc.done() + dc.intf.Close() + } + if dc.dev != nil { + dc.dev.Close() + } + if dc.ctx != nil { + dc.ctx.Close() + } +} + +// Gets All current Params from the DCDCUSB power Supply. +// Set a Timeout/Deadline Context to cancel slow calls +func (dc *DcDcUSB) GetAllParam(ctx context.Context) { + if dc.intf == nil { + dc.log.Warn("Interface Not Opened") + return + } + outp, err := dc.intf.OutEndpoint(0x01) + if err != nil { + dc.log.Warn("Can't Get OutPoint: %s", err) + return + } + //log.Printf("OutEndpoint: %v", outp) + var send = make([]byte, 24) + send[0] = cmdGetAllValues + //send = append(send, 0) + //log.Printf("About to Send %v", send) + len, err := outp.WriteContext(ctx, send) + if err != nil { + dc.log.Warn("Cant Send GetAllValues Command: %s (%v) - %d", err, send, len) + return + } + //log.Printf("Sent %d Bytes", len) + inp, err := dc.intf.InEndpoint(0x81) + if err != nil { + dc.log.Warn("Can't Get OutPoint: %s", err) + return + } + //log.Printf("InEndpoint: %v", inp) + + var recv = make([]byte, 24) + len, err = inp.ReadContext(ctx, recv) + if err != nil { + dc.log.Warn("Can't Read GetAllValues Command: %s", err) + return + } + //log.Printf("Got %d Bytes", len) + dc.log.Trace("Got %v", recv) + dc.parseAllValues(recv, len) +} + +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 +//ignition connect: 2021/09/20 15:51:38 Got [130 133 7 76 75 43 27 133 215 251 1 0 0 0 0 0 0 0 0 3 68 0 0 167] +//ignition connect2 2021/09/20 15:52:14 Got [130 133 7 76 75 44 27 133 215 251 1 0 0 0 0 0 0 0 0 3 32 0 0 167] +//ignition disconnect: 2021/09/20 15:50:39 Got [130 133 8 76 0 43 27 133 205 251 1 0 0 0 0 0 0 0 0 3 127 0 0 167] +// 2021/09/20 16:12:54 Got [130 133 8 76 0 44 25 133 205 251 1 0 0 0 0 0 0 0 0 0 0 0 0 167] +// 2021/09/20 16:12:56 Got [130 133 16 76 0 44 27 133 205 247 1 0 0 0 0 0 0 0 0 0 0 0 59 167] +// 2021/09/20 16:13:54 Got [130 133 16 76 0 44 9 133 205 247 1 0 0 0 0 0 0 0 0 0 0 0 0 167] +func (dc *DcDcUSB) parseAllValues(buf []byte, len int) (Params, error) { + switch buf[0] { + case cmdRecvAllValues: + param := Params{} + param.Mode = dc.modeToConst((buf[1] >> 6) & 0x7) + param.VoutConfig = dc.voutConfigtoFloat((buf[1] >> 2) & 0x07) + param.TimerConfig = dc.timerConfigToDuration(buf[1] & 0x03) + param.State = dc.stateToConst(buf[2]) + param.Vin = float32(buf[3]) * float32(0.1558) + param.Vign = float32(buf[4]) * float32(0.1558) + param.VoutActual = float32(buf[5]) * float32(0.1170) + param.Peripherals = dc.peripheralsState(buf[6]) + param.CfgRegisters = buf[7] + param.VoltFlags = buf[8] + param.TimerFlags = buf[9] + param.ScriptPointer = buf[10] + param.Version = fmt.Sprintf("%d.%d", int((buf[23]>>5)&0x07), int(buf[23])&0x1F) + param.TimerWait = dc.convertTime(buf[11:13]) + param.TimerVOut = dc.convertTime(buf[13:15]) + param.TimerVAux = dc.convertTime(buf[15:17]) + param.TimerPRWSW = dc.convertTime(buf[17:19]) + param.TimerSoftOff = dc.convertTime(buf[19:21]) + param.TimerHardOff = dc.convertTime(buf[21:23]) + dc.log.Trace("DCDC Params: %+v\n", param) + return param, nil + } + return Params{}, errors.New("unknown command recieved") +} + +func (dc *DcDcUSB) modeToConst(mode byte) DcdcModet { + switch mode { + case 0: + return Dumb + case 1: + return Script + case 2: + return Automotive + case 3: + return UPS + default: + return Unknown + } +} + +func (dc *DcDcUSB) voutConfigtoFloat(config byte) float32 { + switch config { + case 0: + return float32(12.0) + case 1: + return float32(5.0) + case 2: + return float32(6.0) + case 3: + return float32(9.0) + case 4: + return float32(13.5) + case 5: + return float32(16.0) + case 6: + return float32(19.0) + case 7: + return float32(24.0) + default: + return float32(-1) + } +} + +func (dc DcDcUSB) timerConfigToDuration(config byte) TimerConfigt { + switch config { + case 0: + return TimerConfigt{OffDelay: 0, HardOff: 0} + case 1: + return TimerConfigt{OffDelay: 15 * time.Minute, HardOff: 1 * time.Minute} + case 2: + return TimerConfigt{OffDelay: 5 * time.Second, HardOff: -1} + case 3: + return TimerConfigt{OffDelay: 30 * time.Minute, HardOff: 1 * time.Minute} + case 4: + return TimerConfigt{OffDelay: 5 * time.Second, HardOff: 1 * time.Minute} + case 5: + return TimerConfigt{OffDelay: 15 * time.Minute, HardOff: -1} + case 6: + return TimerConfigt{OffDelay: 1 * time.Minute, HardOff: 1 * time.Minute} + case 7: + return TimerConfigt{OffDelay: 1 * time.Hour, HardOff: -1} + default: + return TimerConfigt{OffDelay: -1, HardOff: -1} + } +} + +func (dc DcDcUSB) stateToConst(state byte) DcdcStatet { + switch state { + case 7: + return StateOk + case 8: + return StateIgnOff + case 16: + return StateHardOffCountdown + default: + return StateUnknown + } +} + +func (dc DcDcUSB) peripheralsState(state byte) Peripheralst { + p := Peripheralst{ + InVoutGood: ((state & 0x01) != 0), + OutLed: ((state & 0x02) != 0), + OutPsw: ((state & 0x04) != 0), + OutStartOutput: ((state & 0x08) != 0), + OutSwVin: ((state & 0x10) != 0), + } + return p +} + +func (dc DcDcUSB) convertTime(raw []byte) time.Duration { + duration := int64(raw[0]) << 8 + duration += int64(raw[1]) + return time.Duration(duration * int64(time.Second)) +} diff --git a/usbif_test.go b/dcdcusb_test.go similarity index 84% rename from usbif_test.go rename to dcdcusb_test.go index 3d0551f..24291cf 100644 --- a/usbif_test.go +++ b/dcdcusb_test.go @@ -1,4 +1,28 @@ -package dcdc200 +/* +MIT License + +Copyright (c) 2021 Justin Hammond + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package dcdcusb import ( "testing" @@ -7,12 +31,13 @@ import ( func TestParseAllValues(t *testing.T) { var test1 = []byte{130, 133, 7, 76, 75, 43, 27, 133, 215, 251, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 68, 0, 0, 167} - dc := Dcdc200{} + dc := DcDcUSB{} + dc.Init() result, err := dc.parseAllValues(test1, 24) if err != nil { t.Fatalf("Error Returned from parseAllValues: %v", err) } - t.Logf("Param %+v", result) +// t.Logf("Param %+v", result) if result.Mode != Automotive { t.Fatalf("Mode is not Automotive") } @@ -35,7 +60,7 @@ func TestParseAllValues(t *testing.T) { if result.VoutActual != float32(5.031) { t.Fatalf("VoutActual is not 5.031") } - res2 := Peripheralst{Out_sw_vin: true, Out_start_output:true, Out_Psw:false, Out_Led:true, In_vout_good: true} + res2 := Peripheralst{OutSwVin: true, OutStartOutput:true, OutPsw:false, OutLed:true, InVoutGood: true} if result.Peripherals != res2 { t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) } @@ -82,12 +107,13 @@ func TestParseAllValues(t *testing.T) { func TestParseAllValues2(t *testing.T) { var test1 = []byte{130, 133, 8, 76, 0, 43, 27, 133, 205, 251, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 127, 0, 0, 167} - dc := Dcdc200{} + dc := DcDcUSB{} + dc.Init() result, err := dc.parseAllValues(test1, 24) if err != nil { t.Fatalf("Error Returned from parseAllValues: %v", err) } - t.Logf("Param %+v", result) +// t.Logf("Param %+v", result) if result.Mode != Automotive { t.Fatalf("Mode is not Automotive") } @@ -110,7 +136,7 @@ func TestParseAllValues2(t *testing.T) { if result.VoutActual != float32(5.031) { t.Fatalf("VoutActual is not 5.031") } - res2 := Peripheralst{Out_sw_vin: true, Out_start_output:true, Out_Psw:false, Out_Led:true, In_vout_good: true} + res2 := Peripheralst{OutSwVin: true, OutStartOutput:true, OutPsw:false, OutLed:true, InVoutGood: true} if result.Peripherals != res2 { t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) } @@ -157,12 +183,13 @@ func TestParseAllValues2(t *testing.T) { func TestParseAllValues3(t *testing.T) { var test1 = []byte{130, 133, 8, 76, 0, 44, 25, 133, 205, 251, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167} - dc := Dcdc200{} + dc := DcDcUSB{} + dc.Init() result, err := dc.parseAllValues(test1, 24) if err != nil { t.Fatalf("Error Returned from parseAllValues: %v", err) } - t.Logf("Param %+v", result) +// t.Logf("Param %+v", result) if result.Mode != Automotive { t.Fatalf("Mode is not Automotive") } @@ -185,7 +212,7 @@ func TestParseAllValues3(t *testing.T) { if result.VoutActual != float32(5.148) { t.Fatalf("VoutActual is not 5.148") } - res2 := Peripheralst{Out_sw_vin: true, Out_start_output:true, Out_Psw:false, Out_Led:false, In_vout_good: true} + res2 := Peripheralst{OutSwVin: true, OutStartOutput:true, OutPsw:false, OutLed:false, InVoutGood: true} if result.Peripherals != res2 { t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) } @@ -231,12 +258,13 @@ func TestParseAllValues3(t *testing.T) { } func TestParseAllValues4(t *testing.T) { var test1 = []byte{130, 133, 16, 76, 0, 44, 27, 133, 205, 247, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 167} - dc := Dcdc200{} + dc := DcDcUSB{} + dc.Init() result, err := dc.parseAllValues(test1, 24) if err != nil { t.Fatalf("Error Returned from parseAllValues: %v", err) } - t.Logf("Param %+v", result) +// t.Logf("Param %+v", result) if result.Mode != Automotive { t.Fatalf("Mode is not Automotive") } @@ -259,7 +287,7 @@ func TestParseAllValues4(t *testing.T) { if result.VoutActual != float32(5.148) { t.Fatalf("VoutActual is not 5.148") } - res2 := Peripheralst{Out_sw_vin: true, Out_start_output:true, Out_Psw:false, Out_Led:true, In_vout_good: true} + res2 := Peripheralst{OutSwVin: true, OutStartOutput:true, OutPsw:false, OutLed:true, InVoutGood: true} if result.Peripherals != res2 { t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) } @@ -306,12 +334,13 @@ func TestParseAllValues4(t *testing.T) { func TestParseAllValues5(t *testing.T) { var test1 = []byte{130, 133, 16, 76, 0, 44, 9, 133, 205, 247, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167} - dc := Dcdc200{} + dc := DcDcUSB{} + dc.Init() result, err := dc.parseAllValues(test1, 24) if err != nil { t.Fatalf("Error Returned from parseAllValues: %v", err) } - t.Logf("Param %+v", result) + //t.Logf("Param %+v", result) if result.Mode != Automotive { t.Fatalf("Mode is not Automotive") } @@ -334,7 +363,7 @@ func TestParseAllValues5(t *testing.T) { if result.VoutActual != float32(5.148) { t.Fatalf("VoutActual is not 5.148") } - res2 := Peripheralst{Out_sw_vin: false, Out_start_output:true, Out_Psw:false, Out_Led:false, In_vout_good: true} + res2 := Peripheralst{OutSwVin: false, OutStartOutput:true, OutPsw:false, OutLed:false, InVoutGood: true} if result.Peripherals != res2 { t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) } diff --git a/dcdcusbexample_test.go b/dcdcusbexample_test.go new file mode 100644 index 0000000..efb9ccc --- /dev/null +++ b/dcdcusbexample_test.go @@ -0,0 +1,26 @@ +package dcdcusb_test + +import ( + "context" + "log" + "time" + + "github.com/Fishwaldo/go-dcdc200" +) + +func Example() { + dc := dcdcusb.DcDcUSB{} + dc.Init() + if ok, err := dc.Scan(); !ok { + log.Fatalf("Scan Failed: %v", err) + return + } + defer dc.Close() + for i := 0; i < 100; i++ { + ctx, cancel := context.WithTimeout(context.Background(), (1 * time.Second)) + dc.GetAllParam(ctx) + cancel() + time.Sleep(1 * time.Second) + } + dc.Close() +} \ No newline at end of file diff --git a/definitions.go b/definitions.go index cebb824..ea496c3 100755 --- a/definitions.go +++ b/definitions.go @@ -1,88 +1,112 @@ -package dcdc200 +/* +MIT License + +Copyright (c) 2021 Justin Hammond + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package dcdcusb const ( - DCDC200_VID = 0x04d8 - DCDC200_PID = 0xd003 + dcdc200_vid = 0x04d8 + dcdc200_pid = 0xd003 ) const ( - StatusOK = 0x00 - StatusErase = 0x01 - StatusWrite = 0x02 - StatusRead = 0x03 - StatusError = 0xFF + statusOK = 0x00 + statusErase = 0x01 + statusWrite = 0x02 + statusRead = 0x03 + statusError = 0xFF ) const ( - CmdGetAllValues = 0x81 - CmdRecvAllValues = 0x82 - CmdOut = 0xB1 - CmdIn = 0xB2 - CmdReadOut = 0xA1 - CmdReadIn = 0xA2 - CmdWriteOut = 0xA3 - CmdWriteIn = 0xA4 - CmdErase = 0xA5 + cmdGetAllValues = 0x81 + cmdRecvAllValues = 0x82 + cmdOut = 0xB1 + cmdIn = 0xB2 + cmdReadOut = 0xA1 + cmdReadIn = 0xA2 + cmdWriteOut = 0xA3 + cmdWriteIn = 0xA4 + cmdErase = 0xA5 ) const ( - MsgInternal = 0xFF - MsgInternalDisconnected = 0x01 + msgInternal = 0xFF + msgInternalDisconnected = 0x01 ) const ( - CmdSetAuxWin = 0x01 - CmdSetPwSwitch = 0x02 - CmdSetOutput = 0x03 - CmdWriteVout = 0x06 - CmdReadVout = 0x07 - CmdIncVout = 0x0C - CmdDecVout = 0x0D - CmdLoadDefaults = 0x0E - CmdScriptStart = 0x10 - CmdScriptStop = 0x11 - CmdSleep = 0x12 - CmdReadRegulatorStep = 0x13 + cmdSetAuxWin = 0x01 + cmdSetPwSwitch = 0x02 + cmdSetOutput = 0x03 + cmdWriteVout = 0x06 + cmdReadVout = 0x07 + cmdIncVout = 0x0C + cmdDecVout = 0x0D + cmdLoadDefaults = 0x0E + cmdScriptStart = 0x10 + cmdScriptStop = 0x11 + cmdSleep = 0x12 + cmdReadRegulatorStep = 0x13 ) const ( - TypeCodeMemory = 0x00 - TypeEepromExternal = 0x01 - TypeEepromInternal = 0x02 - TypeCodeSplash = 0x03 + typeCodeMemory = 0x00 + typeEepromExternal = 0x01 + typeEepromInternal = 0x02 + typeCodeSplash = 0x03 ) const ( - FlashReportEraseMemory = 0xF2 /* AddressLo : AddressHi : AddressUp (anywhere inside the 64 byte-block to be erased) */ - FlashReportReadMemory = 0xF3 /* AddressLo : AddressHi : AddressUp : Data Length (1...32) */ - FlashReportWriteMemory = 0xF4 /* AddressLo : AddressHi : AddressUp : Data Length (1...32) : Data.... */ - KeyBdReportEraseMemory = 0xB2 /* same as F2 but in keyboard mode */ - KeybdReportReadMemory = 0xB3 /* same as F3 but in keyboard mode */ - KeybdReportWriteMemory = 0xB4 /* same as F4 but in keyboard mode */ - KeybdReportMemory = 0x41 /* response to b3,b4 */ + flashReportEraseMemory = 0xF2 /* AddressLo : AddressHi : AddressUp (anywhere inside the 64 byte-block to be erased) */ + flashReportReadMemory = 0xF3 /* AddressLo : AddressHi : AddressUp : Data Length (1...32) */ + flashReportWriteMemory = 0xF4 /* AddressLo : AddressHi : AddressUp : Data Length (1...32) : Data.... */ + keyBdReportEraseMemory = 0xB2 /* same as F2 but in keyboard mode */ + keybdReportReadMemory = 0xB3 /* same as F3 but in keyboard mode */ + keybdReportWriteMemory = 0xB4 /* same as F4 but in keyboard mode */ + keybdReportMemory = 0x41 /* response to b3,b4 */ ) const ( - InReportExtEEData = 0x31 - OutReportExtEERead = 0xA1 - OutReportExtEEWrite = 0xA2 - InReportIntEEData = 0x32 - OutReportIntEERead = 0xA3 - OutReportIntEEWrite = 0xA4 + inReportExtEEData = 0x31 + outReportExtEERead = 0xA1 + outReportExtEEWrite = 0xA2 + inReportIntEEData = 0x32 + outReportIntEERead = 0xA3 + outReportIntEEWrite = 0xA4 ) /* MEASUREMENT CONSTANTS */ const ( - CT_RW = 75 - CT_R1 = 49900 - CT_R2 = 1500 - CT_RP = 10000 + ct_RW = 75 + ct_R1 = 49900 + ct_R2 = 1500 + ct_RP = 10000 ) -const CHECK_CHAR = 0xAA /* used for line/write check */ +const check_char = 0xAA /* used for line/write check */ -const MAX_MESSAGE_CNT = 64 +const max_message_cnt = 64 //go:generate stringer -type=DcdcModet type DcdcModet int diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..dfc1a25 --- /dev/null +++ b/doc.go @@ -0,0 +1,34 @@ +/* +MIT License + +Copyright (c) 2021 Justin Hammond + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/* +Package go-dcdcusb interfaces with the DCDCUSB power supply from mini-box (https://www.mini-box.com/DCDC-USB) +via USB port and allows you to retrive the status of the power supply + +it depends upon GoUSB which in turn depends upon the libusb C library, thus CGO is required for this module + +Please see the GoUSB pages for hints on compiling for platforms other than linux + +*/ +package dcdcusb diff --git a/go.mod b/go.mod index b71748d..34e056f 100755 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/Fishwaldo/go-dcdc200 go 1.17 -require github.com/google/gousb v1.1.1 +require ( + github.com/Fishwaldo/go-logadapter v0.0.2 + github.com/google/gousb v1.1.1 +) diff --git a/go.sum b/go.sum index 1e79240..0ffe503 100755 --- a/go.sum +++ b/go.sum @@ -1,2 +1,61 @@ +github.com/Fishwaldo/go-logadapter v0.0.2 h1:RxFOr+bEDqQ1rPUmjUX5u8fGLCKY0Lyea+9AxDqzaW4= +github.com/Fishwaldo/go-logadapter v0.0.2/go.mod h1:aRbQ8rWdpeD0WWo241ctqgk/yRto8Axg09EkwWiVGK0= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gousb v1.1.1 h1:2sjwXlc0PIBgDnXtNxUrHcD/RRFOmAtRq4QgnFBE6xc= github.com/google/gousb v1.1.1/go.mod h1:b3uU8itc6dHElt063KJobuVtcKHWEfFOysOqBNzHhLY= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/usbif.go b/usbif.go deleted file mode 100755 index 45160ba..0000000 --- a/usbif.go +++ /dev/null @@ -1,280 +0,0 @@ -package dcdc200 - -import ( - "fmt" - "log" - "time" - "context" - "errors" - - "github.com/google/gousb" -) - -type Dcdc200 struct { - ctx *gousb.Context - dev *gousb.Device - intf *gousb.Interface - done func() -} - -type TimerConfigt struct { - OffDelay time.Duration - HardOff time.Duration -} - -type Peripheralst struct { - Out_sw_vin bool - Out_start_output bool - Out_Psw bool - Out_Led bool - In_vout_good bool -} - -type Params struct { - VoutSet float32 - VoutConfig float32 - Vin float32 - Vign float32 - VoutActual float32 - Peripherals Peripheralst - Output bool - AuxVIn bool - Version string - State DcdcStatet - CfgRegisters byte - VoltFlags byte - TimerFlags byte - //Timer int - TimerConfig TimerConfigt - //VoltConfig byte - TimerWait time.Duration - TimerVOut time.Duration - TimerVAux time.Duration - TimerPRWSW time.Duration - TimerSoftOff time.Duration - TimerHardOff time.Duration - ScriptPointer byte - Mode DcdcModet -} - - - -func (dc *Dcdc200) Scan() (bool, error) { - dc.ctx = gousb.NewContext() - dc.ctx.Debug(10) - var err error - dc.dev, err = dc.ctx.OpenDeviceWithVIDPID(DCDC200_VID, DCDC200_PID) - if err != nil { - log.Printf("Could Not Open Device: %v", err) - dc.Close() - return false, err - } - if dc.dev == nil { - log.Printf("Can't Find Device") - dc.Close() - return false, nil - } - err = dc.dev.SetAutoDetach(true) - if err != nil { - log.Fatalf("%s.SetAutoDetach(true): %v", dc.dev, err) - } - - confignum, _ := dc.dev.ActiveConfigNum() - log.Printf("Device Config: %s %d", dc.dev.String(), confignum) -// desc, _ := dc.dev.GetStringDescriptor(1) -// manu, _ := dc.dev.Manufacturer() -// prod, _ := dc.dev.Product() -// serial, _ := dc.dev.SerialNumber() - dc.intf, dc.done, err = dc.dev.DefaultInterface() - if err != nil { - log.Printf("%s.Interface(): %v", dc.dev, err) - dc.Close() - return false, err - } - log.Printf("Interface: %s", dc.intf.String()) - return true, nil -} -func (dc *Dcdc200) Close() { - if dc.intf != nil { - dc.done() - dc.intf.Close() - } - if dc.dev != nil { - dc.dev.Close() - } - if dc.ctx != nil { - dc.ctx.Close() - } -} - -func (dc *Dcdc200) GetAllParam(ctx context.Context) { - if dc.intf == nil { - log.Fatalf("Interface Not Opened") - return - } - outp, err := dc.intf.OutEndpoint(0x01) - if err != nil { - log.Fatalf("Can't Get OutPoint: %s", err) - return; - } - //log.Printf("OutEndpoint: %v", outp) - var send = make([]byte, 24) - send[0] = CmdGetAllValues - //send = append(send, 0) - //log.Printf("About to Send %v", send) - len, err := outp.WriteContext(ctx, send) - if err != nil { - log.Fatalf("Cant Send GetAllValues Command: %s (%v) - %d", err, send, len) - return - } - //log.Printf("Sent %d Bytes", len) - inp, err := dc.intf.InEndpoint(0x81) - if err != nil { - log.Fatalf("Can't Get OutPoint: %s", err) - return; - } - //log.Printf("InEndpoint: %v", inp) - - var recv = make([]byte, 24) - len, err = inp.ReadContext(ctx, recv) - if err != nil { - log.Fatalf("Can't Read GetAllValues Command: %s", err) - return - } - //log.Printf("Got %d Bytes", len) - log.Printf("Got %v", recv) - dc.parseAllValues(recv, len) -} - -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 -//ignition connect: 2021/09/20 15:51:38 Got [130 133 7 76 75 43 27 133 215 251 1 0 0 0 0 0 0 0 0 3 68 0 0 167] -//ignition connect2 2021/09/20 15:52:14 Got [130 133 7 76 75 44 27 133 215 251 1 0 0 0 0 0 0 0 0 3 32 0 0 167] -//ignition disconnect: 2021/09/20 15:50:39 Got [130 133 8 76 0 43 27 133 205 251 1 0 0 0 0 0 0 0 0 3 127 0 0 167] -// 2021/09/20 16:12:54 Got [130 133 8 76 0 44 25 133 205 251 1 0 0 0 0 0 0 0 0 0 0 0 0 167] -// 2021/09/20 16:12:56 Got [130 133 16 76 0 44 27 133 205 247 1 0 0 0 0 0 0 0 0 0 0 0 59 167] -// 2021/09/20 16:13:54 Got [130 133 16 76 0 44 9 133 205 247 1 0 0 0 0 0 0 0 0 0 0 0 0 167] -func (dc *Dcdc200) parseAllValues(buf []byte, len int) (Params, error){ - switch buf[0] { - case CmdRecvAllValues: - param := Params{} - param.Mode = dc.modeToConst((buf[1] >> 6) & 0x7) - param.VoutConfig = dc.voutConfigtoFloat((buf[1] >> 2) & 0x07) - param.TimerConfig = dc.timerConfigToDuration(buf[1] & 0x03) - param.State = dc.stateToConst(buf[2]) - param.Vin = float32(buf[3]) * float32(0.1558) - param.Vign = float32(buf[4]) * float32(0.1558) - param.VoutActual = float32(buf[5]) * float32(0.1170) - param.Peripherals = dc.peripheralsState(buf[6]) - param.CfgRegisters = buf[7] - param.VoltFlags = buf[8] - param.TimerFlags = buf[9] - param.ScriptPointer = buf[10] - param.Version = fmt.Sprintf("%d.%d", int((buf[23] >> 5) & 0x07), int(buf[23]) & 0x1F) - param.TimerWait = dc.convertTime(buf[11:13]) - param.TimerVOut = dc.convertTime(buf[13:15]) - param.TimerVAux = dc.convertTime(buf[15:17]) - param.TimerPRWSW = dc.convertTime(buf[17:19]) - param.TimerSoftOff = dc.convertTime(buf[19:21]) - param.TimerHardOff = dc.convertTime(buf[21:23]) - fmt.Printf("%+v\n", param) - return param, nil - } - return Params{}, errors.New("unknown command recieved") -} - - - -func (dc *Dcdc200) modeToConst(mode byte) (DcdcModet) { - switch mode { - case 0: - return Dumb - case 1: - return Script - case 2: - return Automotive - case 3: - return UPS - default: - return Unknown - } -} - -func (dc *Dcdc200) voutConfigtoFloat (config byte) (float32) { - switch config { - case 0: - return float32(12.0) - case 1: - return float32(5.0) - case 2: - return float32(6.0) - case 3: - return float32(9.0) - case 4: - return float32(13.5) - case 5: - return float32(16.0) - case 6: - return float32(19.0) - case 7: - return float32(24.0) - default: - return float32(-1) - } -} - - - -func (dc Dcdc200) timerConfigToDuration(config byte) (TimerConfigt) { - switch config { - case 0: - return TimerConfigt{OffDelay: 0, HardOff: 0} - case 1: - return TimerConfigt{OffDelay: 15 * time.Minute, HardOff: 1 * time.Minute} - case 2: - return TimerConfigt{OffDelay: 5 * time.Second, HardOff: -1} - case 3: - return TimerConfigt{OffDelay: 30 * time.Minute, HardOff: 1 * time.Minute} - case 4: - return TimerConfigt{OffDelay: 5 * time.Second, HardOff: 1 * time.Minute} - case 5: - return TimerConfigt{OffDelay: 15 * time.Minute, HardOff: -1} - case 6: - return TimerConfigt{OffDelay: 1 * time.Minute, HardOff: 1 * time.Minute} - case 7: - return TimerConfigt{OffDelay: 1 * time.Hour, HardOff: -1} - default: - return TimerConfigt{OffDelay: -1, HardOff: -1} - } -} - -func (dc Dcdc200) stateToConst(state byte) (DcdcStatet) { - switch state { - case 7: - return StateOk - case 8: - return StateIgnOff - case 16: - return StateHardOffCountdown - default: - return StateUnknown - } -} - - - -func (dc Dcdc200) peripheralsState(state byte) (Peripheralst) { - p := Peripheralst { - In_vout_good: ((state & 0x01) != 0), - Out_Led: ((state & 0x02) != 0), - Out_Psw: ((state & 0x04) != 0), - Out_start_output: ((state & 0x08) != 0), - Out_sw_vin: ((state & 0x10) != 0), - } - return p -} - -func (dc Dcdc200) convertTime(raw []byte) (time.Duration) { - duration := int64(raw[0]) << 8 - duration += int64(raw[1]) - return time.Duration(duration * int64(time.Second)) -} \ No newline at end of file