mirror of
https://github.com/Fishwaldo/go-dcdc200.git
synced 2025-03-15 11:31:22 +00:00
Reorg, Update Tests and Github Actions (#2)
* Reorg, Update Tests and Github Actions * Install libusb and only test on ubuntu
This commit is contained in:
parent
334ea05709
commit
49bc92fa8d
14 changed files with 682 additions and 467 deletions
56
.github/workflows/build.yml
vendored
56
.github/workflows/build.yml
vendored
|
@ -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 }}'
|
||||
|
|
16
.github/workflows/lint.yml
vendored
16
.github/workflows/lint.yml
vendored
|
@ -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
|
113
cmd/main.go
113
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
|
||||
}
|
||||
}
|
||||
|
|
6
codecov.yml
Normal file
6
codecov.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: auto
|
||||
threshold: 10%
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by "stringer -type=DcdcModet"; DO NOT EDIT.
|
||||
|
||||
package dcdc200
|
||||
package dcdcusb
|
||||
|
||||
import "strconv"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by "stringer -type=DcdcStatet"; DO NOT EDIT.
|
||||
|
||||
package dcdc200
|
||||
package dcdcusb
|
||||
|
||||
import "strconv"
|
||||
|
||||
|
|
357
dcdcusb.go
Executable file
357
dcdcusb.go
Executable file
|
@ -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))
|
||||
}
|
|
@ -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)
|
||||
}
|
26
dcdcusbexample_test.go
Normal file
26
dcdcusbexample_test.go
Normal file
|
@ -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()
|
||||
}
|
132
definitions.go
132
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
|
||||
|
|
34
doc.go
Normal file
34
doc.go
Normal file
|
@ -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
|
5
go.mod
5
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
|
||||
)
|
||||
|
|
59
go.sum
59
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=
|
||||
|
|
280
usbif.go
280
usbif.go
|
@ -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))
|
||||
}
|
Loading…
Add table
Reference in a new issue