commit d8bfe027e31f8166de0a6e93c2b40983de183596
Author: Justin Hammond <fish@arm64-1.dmz.dynam.ac>
Date:   Tue Sep 21 22:23:16 2021 +0800

    Initial Commit

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