From d8bfe027e31f8166de0a6e93c2b40983de183596 Mon Sep 17 00:00:00 2001 From: Justin Hammond Date: Tue, 21 Sep 2021 22:23:16 +0800 Subject: [PATCH] Initial Commit --- .vscode/launch.json | 15 ++ README.md | 1 + cmd/main.go | 112 +++++++++++++ dcdcmodet_string.go | 36 ++++ dcdcstatet_string.go | 39 +++++ definitions.go | 105 ++++++++++++ go.mod | 12 ++ go.sum | 21 +++ usbif.go | 280 +++++++++++++++++++++++++++++++ usbif_test.go | 380 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 1001 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 README.md create mode 100755 cmd/main.go create mode 100644 dcdcmodet_string.go create mode 100644 dcdcstatet_string.go create mode 100755 definitions.go create mode 100755 go.mod create mode 100755 go.sum create mode 100755 usbif.go create mode 100644 usbif_test.go diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..79f64bd --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "cmd/" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..3f695d7 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# go-dcdcusb200 diff --git a/cmd/main.go b/cmd/main.go new file mode 100755 index 0000000..b9d7ffc --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,112 @@ +// 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. + +// 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 { + 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() +} + +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/dcdcmodet_string.go b/dcdcmodet_string.go new file mode 100644 index 0000000..51f56cf --- /dev/null +++ b/dcdcmodet_string.go @@ -0,0 +1,36 @@ +// Code generated by "stringer -type=DcdcModet"; DO NOT EDIT. + +package dcdc200 + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Dumb-0] + _ = x[Automotive-2] + _ = x[Script-1] + _ = x[UPS-3] + _ = x[Unknown-255] +} + +const ( + _DcdcModet_name_0 = "DumbScriptAutomotiveUPS" + _DcdcModet_name_1 = "Unknown" +) + +var ( + _DcdcModet_index_0 = [...]uint8{0, 4, 10, 20, 23} +) + +func (i DcdcModet) String() string { + switch { + case 0 <= i && i <= 3: + return _DcdcModet_name_0[_DcdcModet_index_0[i]:_DcdcModet_index_0[i+1]] + case i == 255: + return _DcdcModet_name_1 + default: + return "DcdcModet(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/dcdcstatet_string.go b/dcdcstatet_string.go new file mode 100644 index 0000000..0884b3d --- /dev/null +++ b/dcdcstatet_string.go @@ -0,0 +1,39 @@ +// Code generated by "stringer -type=DcdcStatet"; DO NOT EDIT. + +package dcdc200 + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[StateOk-7] + _ = x[StateIgnOff-8] + _ = x[StateHardOffCountdown-16] + _ = x[StateUnknown-255] +} + +const ( + _DcdcStatet_name_0 = "StateOkStateIgnOff" + _DcdcStatet_name_1 = "StateHardOffCountdown" + _DcdcStatet_name_2 = "StateUnknown" +) + +var ( + _DcdcStatet_index_0 = [...]uint8{0, 7, 18} +) + +func (i DcdcStatet) String() string { + switch { + case 7 <= i && i <= 8: + i -= 7 + return _DcdcStatet_name_0[_DcdcStatet_index_0[i]:_DcdcStatet_index_0[i+1]] + case i == 16: + return _DcdcStatet_name_1 + case i == 255: + return _DcdcStatet_name_2 + default: + return "DcdcStatet(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/definitions.go b/definitions.go new file mode 100755 index 0000000..cebb824 --- /dev/null +++ b/definitions.go @@ -0,0 +1,105 @@ +package dcdc200 + +const ( + DCDC200_VID = 0x04d8 + DCDC200_PID = 0xd003 +) + +const ( + 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 +) + +const ( + 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 +) + +const ( + 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 */ +) + +const ( + 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 +) + +const CHECK_CHAR = 0xAA /* used for line/write check */ + +const MAX_MESSAGE_CNT = 64 + +//go:generate stringer -type=DcdcModet +type DcdcModet int + +const ( + Dumb DcdcModet = 0 + Automotive DcdcModet = 2 + Script DcdcModet = 1 + UPS DcdcModet = 3 + Unknown DcdcModet = 255 +) + +//go:generate stringer -type=DcdcStatet +type DcdcStatet int +const ( + StateOk DcdcStatet = 7 + StateIgnOff DcdcStatet = 8 + StateHardOffCountdown DcdcStatet = 16 + StateUnknown DcdcStatet = 255 +) \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100755 index 0000000..1101e2c --- /dev/null +++ b/go.mod @@ -0,0 +1,12 @@ +module github.com/Fishwaldo/go-dcdc200 + +go 1.17 + +require github.com/google/gousb v1.1.1 + +require ( + golang.org/x/mod v0.4.2 // indirect + golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect + golang.org/x/tools v0.1.6 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100755 index 0000000..0ee94e0 --- /dev/null +++ b/go.sum @@ -0,0 +1,21 @@ +github.com/google/gousb v1.1.1 h1:2sjwXlc0PIBgDnXtNxUrHcD/RRFOmAtRq4QgnFBE6xc= +github.com/google/gousb v1.1.1/go.mod h1:b3uU8itc6dHElt063KJobuVtcKHWEfFOysOqBNzHhLY= +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/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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/sync v0.0.0-20190423024810-112230192c58/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-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.6 h1:SIasE1FVIQOWz2GEAHFOmoW7xchJcqlucjSULTL0Ag4= +golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/usbif.go b/usbif.go new file mode 100755 index 0000000..45160ba --- /dev/null +++ b/usbif.go @@ -0,0 +1,280 @@ +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 diff --git a/usbif_test.go b/usbif_test.go new file mode 100644 index 0000000..3d0551f --- /dev/null +++ b/usbif_test.go @@ -0,0 +1,380 @@ +package dcdc200 + +import ( + "testing" + "time" +) + +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{} + result, err := dc.parseAllValues(test1, 24) + if err != nil { + t.Fatalf("Error Returned from parseAllValues: %v", err) + } + t.Logf("Param %+v", result) + if result.Mode != Automotive { + t.Fatalf("Mode is not Automotive") + } + if result.VoutConfig != 5 { + t.Fatalf("VoutCOnfig is not 5") + } + res := TimerConfigt{OffDelay: 15 * time.Minute, HardOff: 1 * time.Minute} + if result.TimerConfig != res { + t.Fatalf("TimerConfig is Not 15/1") + } + if result.State != StateOk { + t.Fatalf("State is Not Correct") + } + if result.Vin != float32(11.8408) { + t.Fatalf("Vin is not 11.8408") + } + if result.Vign != float32(11.685) { + t.Fatalf("Vign is not 11.685") + } + 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} + if result.Peripherals != res2 { + t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) + } + if result.Output != false { + t.Fatalf("Output is not False") + } + if result.AuxVIn != false { + t.Fatalf("AuxVin is not False") + } + if result.Version != "5.7" { + t.Fatalf("Version String is wrong") + } + if result.CfgRegisters != 133 { + t.Fatalf("CfgRegisters is not Correct") + } + if result.VoltFlags != 215 { + t.Fatalf("VoltFlags is not correct") + } + if result.TimerFlags != 251 { + t.Fatalf("TimerFlags is not correct") + } + if result.ScriptPointer != 1 { + t.Fatalf("Scriptpointer is not correct") + } + if result.TimerWait != time.Duration(0) { + t.Fatalf("TimerWait is not Correct") + } + if result.TimerVOut != time.Duration(0) { + t.Fatalf("TimerVOut is not correct") + } + if result.TimerVAux != time.Duration(0) { + t.Fatalf("TimerVAus is not correct") + } + if result.TimerPRWSW != time.Duration(0) { + t.Fatalf("TimerPRWSW is not correct") + } + if result.TimerSoftOff != time.Duration(836 * time.Second) { + t.Fatalf("TimerSoftOff is not correct") + } + if result.TimerHardOff != time.Duration(0) { + t.Fatalf("TimerHardOff is not correct") + } +} + +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{} + result, err := dc.parseAllValues(test1, 24) + if err != nil { + t.Fatalf("Error Returned from parseAllValues: %v", err) + } + t.Logf("Param %+v", result) + if result.Mode != Automotive { + t.Fatalf("Mode is not Automotive") + } + if result.VoutConfig != 5 { + t.Fatalf("VoutCOnfig is not 5") + } + res := TimerConfigt{OffDelay: 15 * time.Minute, HardOff: 1 * time.Minute} + if result.TimerConfig != res { + t.Fatalf("TimerConfig is Not 15/1") + } + if result.State != StateIgnOff { + t.Fatalf("State is Not Correct") + } + if result.Vin != float32(11.8408) { + t.Fatalf("Vin is not 11.8408") + } + if result.Vign != float32(0) { + t.Fatalf("Vign is not 11.685") + } + 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} + if result.Peripherals != res2 { + t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) + } + if result.Output != false { + t.Fatalf("Output is not False") + } + if result.AuxVIn != false { + t.Fatalf("AuxVin is not False") + } + if result.Version != "5.7" { + t.Fatalf("Version String is wrong") + } + if result.CfgRegisters != 133 { + t.Fatalf("CfgRegisters is not Correct") + } + if result.VoltFlags != 205 { + t.Fatalf("VoltFlags is not correct") + } + if result.TimerFlags != 251 { + t.Fatalf("TimerFlags is not correct") + } + if result.ScriptPointer != 1 { + t.Fatalf("Scriptpointer is not correct") + } + if result.TimerWait != time.Duration(0) { + t.Fatalf("TimerWait is not Correct") + } + if result.TimerVOut != time.Duration(0) { + t.Fatalf("TimerVOut is not correct") + } + if result.TimerVAux != time.Duration(0) { + t.Fatalf("TimerVAus is not correct") + } + if result.TimerPRWSW != time.Duration(0) { + t.Fatalf("TimerPRWSW is not correct") + } + if result.TimerSoftOff != time.Duration(895 * time.Second) { + t.Fatalf("TimerSoftOff is not correct") + } + if result.TimerHardOff != time.Duration(0) { + t.Fatalf("TimerHardOff is not correct") + } +} + +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{} + result, err := dc.parseAllValues(test1, 24) + if err != nil { + t.Fatalf("Error Returned from parseAllValues: %v", err) + } + t.Logf("Param %+v", result) + if result.Mode != Automotive { + t.Fatalf("Mode is not Automotive") + } + if result.VoutConfig != 5 { + t.Fatalf("VoutCOnfig is not 5") + } + res := TimerConfigt{OffDelay: 15 * time.Minute, HardOff: 1 * time.Minute} + if result.TimerConfig != res { + t.Fatalf("TimerConfig is Not 15/1") + } + if result.State != StateIgnOff { + t.Fatalf("State is Not Correct") + } + if result.Vin != float32(11.8408) { + t.Fatalf("Vin is not 11.8408") + } + if result.Vign != float32(0) { + t.Fatalf("Vign is not 11.685") + } + 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} + if result.Peripherals != res2 { + t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) + } + if result.Output != false { + t.Fatalf("Output is not False") + } + if result.AuxVIn != false { + t.Fatalf("AuxVin is not False") + } + if result.Version != "5.7" { + t.Fatalf("Version String is wrong") + } + if result.CfgRegisters != 133 { + t.Fatalf("CfgRegisters is not Correct") + } + if result.VoltFlags != 205 { + t.Fatalf("VoltFlags is not correct") + } + if result.TimerFlags != 251 { + t.Fatalf("TimerFlags is not correct") + } + if result.ScriptPointer != 1 { + t.Fatalf("Scriptpointer is not correct") + } + if result.TimerWait != time.Duration(0) { + t.Fatalf("TimerWait is not Correct") + } + if result.TimerVOut != time.Duration(0) { + t.Fatalf("TimerVOut is not correct") + } + if result.TimerVAux != time.Duration(0) { + t.Fatalf("TimerVAus is not correct") + } + if result.TimerPRWSW != time.Duration(0) { + t.Fatalf("TimerPRWSW is not correct") + } + if result.TimerSoftOff != time.Duration(0) { + t.Fatalf("TimerSoftOff is not correct") + } + if result.TimerHardOff != time.Duration(0) { + t.Fatalf("TimerHardOff is not correct") + } +} +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{} + result, err := dc.parseAllValues(test1, 24) + if err != nil { + t.Fatalf("Error Returned from parseAllValues: %v", err) + } + t.Logf("Param %+v", result) + if result.Mode != Automotive { + t.Fatalf("Mode is not Automotive") + } + if result.VoutConfig != 5 { + t.Fatalf("VoutCOnfig is not 5") + } + res := TimerConfigt{OffDelay: 15 * time.Minute, HardOff: 1 * time.Minute} + if result.TimerConfig != res { + t.Fatalf("TimerConfig is Not 15/1") + } + if result.State != StateHardOffCountdown { + t.Fatalf("State is Not Correct") + } + if result.Vin != float32(11.8408) { + t.Fatalf("Vin is not 11.8408") + } + if result.Vign != float32(0) { + t.Fatalf("Vign is not 11.685") + } + 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} + if result.Peripherals != res2 { + t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) + } + if result.Output != false { + t.Fatalf("Output is not False") + } + if result.AuxVIn != false { + t.Fatalf("AuxVin is not False") + } + if result.Version != "5.7" { + t.Fatalf("Version String is wrong") + } + if result.CfgRegisters != 133 { + t.Fatalf("CfgRegisters is not Correct") + } + if result.VoltFlags != 205 { + t.Fatalf("VoltFlags is not correct") + } + if result.TimerFlags != 247 { + t.Fatalf("TimerFlags is not correct") + } + if result.ScriptPointer != 1 { + t.Fatalf("Scriptpointer is not correct") + } + if result.TimerWait != time.Duration(0) { + t.Fatalf("TimerWait is not Correct") + } + if result.TimerVOut != time.Duration(0) { + t.Fatalf("TimerVOut is not correct") + } + if result.TimerVAux != time.Duration(0) { + t.Fatalf("TimerVAus is not correct") + } + if result.TimerPRWSW != time.Duration(0) { + t.Fatalf("TimerPRWSW is not correct") + } + if result.TimerSoftOff != time.Duration(0) { + t.Fatalf("TimerSoftOff is not correct") + } + if result.TimerHardOff != time.Duration(59 * time.Second) { + t.Fatalf("TimerHardOff is not correct") + } +} + +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{} + result, err := dc.parseAllValues(test1, 24) + if err != nil { + t.Fatalf("Error Returned from parseAllValues: %v", err) + } + t.Logf("Param %+v", result) + if result.Mode != Automotive { + t.Fatalf("Mode is not Automotive") + } + if result.VoutConfig != 5 { + t.Fatalf("VoutCOnfig is not 5") + } + res := TimerConfigt{OffDelay: 15 * time.Minute, HardOff: 1 * time.Minute} + if result.TimerConfig != res { + t.Fatalf("TimerConfig is Not 15/1") + } + if result.State != StateHardOffCountdown { + t.Fatalf("State is Not Correct") + } + if result.Vin != float32(11.8408) { + t.Fatalf("Vin is not 11.8408") + } + if result.Vign != float32(0) { + t.Fatalf("Vign is not 11.685") + } + 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} + if result.Peripherals != res2 { + t.Fatalf("Peripherals is not Correct: %+v", result.Peripherals) + } + if result.Output != false { + t.Fatalf("Output is not False") + } + if result.AuxVIn != false { + t.Fatalf("AuxVin is not False") + } + if result.Version != "5.7" { + t.Fatalf("Version String is wrong") + } + if result.CfgRegisters != 133 { + t.Fatalf("CfgRegisters is not Correct") + } + if result.VoltFlags != 205 { + t.Fatalf("VoltFlags is not correct") + } + if result.TimerFlags != 247 { + t.Fatalf("TimerFlags is not correct") + } + if result.ScriptPointer != 1 { + t.Fatalf("Scriptpointer is not correct") + } + if result.TimerWait != time.Duration(0) { + t.Fatalf("TimerWait is not Correct") + } + if result.TimerVOut != time.Duration(0) { + t.Fatalf("TimerVOut is not correct") + } + if result.TimerVAux != time.Duration(0) { + t.Fatalf("TimerVAus is not correct") + } + if result.TimerPRWSW != time.Duration(0) { + t.Fatalf("TimerPRWSW is not correct") + } + if result.TimerSoftOff != time.Duration(0) { + t.Fatalf("TimerSoftOff is not correct") + } + if result.TimerHardOff != time.Duration(0) { + t.Fatalf("TimerHardOff is not correct") + } +} \ No newline at end of file