robocar-led/vendor/periph.io/x/d2xx/d2xx_posix.go

220 lines
5.5 KiB
Go
Raw Normal View History

2021-09-01 19:41:28 +00:00
// Copyright 2017 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
2021-09-11 18:52:44 +00:00
// +build cgo
2021-09-01 19:41:28 +00:00
// +build !windows
2021-09-11 18:52:44 +00:00
// +build !no_d2xx
2021-09-01 19:41:28 +00:00
package d2xx
/*
#include "third_party/ftd2xx.h"
#include <stdlib.h>
*/
import "C"
import (
"unsafe"
)
// Available is true if the library is available on this system.
const Available = true
// Library functions.
func version() (uint8, uint8, uint8) {
var v C.DWORD
C.FT_GetLibraryVersion(&v)
return uint8(v >> 16), uint8(v >> 8), uint8(v)
}
func createDeviceInfoList() (int, Err) {
var num C.DWORD
e := C.FT_CreateDeviceInfoList(&num)
return int(num), Err(e)
}
func open(i int) (Handle, Err) {
var h C.FT_HANDLE
e := C.FT_Open(C.int(i), &h)
if uintptr(h) == 0 && e == 0 {
// 18 means FT_OTHER_ERROR. Kind of a hack but better than panic.
e = 18
}
return handle(h), Err(e)
}
func (h handle) Close() Err {
return Err(C.FT_Close(h.toH()))
}
func (h handle) ResetDevice() Err {
return Err(C.FT_ResetDevice(h.toH()))
}
func (h handle) GetDeviceInfo() (uint32, uint16, uint16, Err) {
var dev C.FT_DEVICE
var id C.DWORD
if e := C.FT_GetDeviceInfo(h.toH(), &dev, &id, nil, nil, nil); e != 0 {
return unknown, 0, 0, Err(e)
}
return uint32(dev), uint16(id >> 16), uint16(id), 0
}
func (h handle) EEPROMRead(devType uint32, ee *EEPROM) Err {
var manufacturer [64]C.char
var manufacturerID [64]C.char
var desc [64]C.char
var serial [64]C.char
eepromVoid := unsafe.Pointer(&ee.Raw[0])
hdr := ee.asHeader()
// There something odd going on here.
//
// On a ft232h, we observed that hdr.DeviceType MUST NOT be set, but on a
// ft232r, it MUST be set. Since we can't know in advance what we must use,
// just try both. ¯\_(ツ)_/¯
hdr.DeviceType = devType
if e := C.FT_EEPROM_Read(h.toH(), eepromVoid, C.DWORD(len(ee.Raw)), &manufacturer[0], &manufacturerID[0], &desc[0], &serial[0]); e != 0 {
// FT_INVALID_PARAMETER
if e == 6 {
hdr.DeviceType = 0
e = C.FT_EEPROM_Read(h.toH(), eepromVoid, C.DWORD(len(ee.Raw)), &manufacturer[0], &manufacturerID[0], &desc[0], &serial[0])
}
if e != 0 {
return Err(e)
}
}
ee.Manufacturer = C.GoString(&manufacturer[0])
ee.ManufacturerID = C.GoString(&manufacturerID[0])
ee.Desc = C.GoString(&desc[0])
ee.Serial = C.GoString(&serial[0])
return 0
}
func (h handle) EEPROMProgram(ee *EEPROM) Err {
// len(manufacturer) + len(desc) <= 40.
/*
var cmanu [64]byte
copy(cmanu[:], ee.manufacturer)
var cmanuID [64]byte
copy(cmanuID[:], ee.manufacturerID)
var cdesc [64]byte
copy(cdesc[:], ee.desc)
var cserial [64]byte
copy(cserial[:], ee.serial)
*/
cmanu := C.CString(ee.Manufacturer)
defer C.free(unsafe.Pointer(cmanu))
cmanuID := C.CString(ee.ManufacturerID)
defer C.free(unsafe.Pointer(cmanuID))
cdesc := C.CString(ee.Desc)
defer C.free(unsafe.Pointer(cdesc))
cserial := C.CString(ee.Serial)
defer C.free(unsafe.Pointer(cserial))
if len(ee.Raw) == 0 {
return Err(C.FT_EEPROM_Program(h.toH(), unsafe.Pointer(uintptr(0)), 0, cmanu, cmanuID, cdesc, cserial))
}
return Err(C.FT_EEPROM_Program(h.toH(), unsafe.Pointer(&ee.Raw[0]), C.DWORD(len(ee.Raw)), cmanu, cmanuID, cdesc, cserial))
}
func (h handle) EraseEE() Err {
return Err(C.FT_EraseEE(h.toH()))
}
func (h handle) WriteEE(offset uint8, value uint16) Err {
return Err(C.FT_WriteEE(h.toH(), C.DWORD(offset), C.WORD(value)))
}
func (h handle) EEUASize() (int, Err) {
var size C.DWORD
if e := C.FT_EE_UASize(h.toH(), &size); e != 0 {
return 0, Err(e)
}
return int(size), 0
}
func (h handle) EEUARead(ua []byte) Err {
var size C.DWORD
if e := C.FT_EE_UARead(h.toH(), (*C.UCHAR)(unsafe.Pointer(&ua[0])), C.DWORD(len(ua)), &size); e != 0 {
return Err(e)
}
if int(size) != len(ua) {
return 6 // FT_INVALID_PARAMETER
}
return 0
}
func (h handle) EEUAWrite(ua []byte) Err {
if e := C.FT_EE_UAWrite(h.toH(), (*C.UCHAR)(&ua[0]), C.DWORD(len(ua))); e != 0 {
return Err(e)
}
return 0
}
func (h handle) SetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) Err {
v := C.UCHAR(0)
if eventEn {
v = 1
}
w := C.UCHAR(0)
if errorEn {
w = 1
}
return Err(C.FT_SetChars(h.toH(), C.UCHAR(eventChar), v, C.UCHAR(errorChar), w))
}
func (h handle) SetUSBParameters(in, out int) Err {
return Err(C.FT_SetUSBParameters(h.toH(), C.DWORD(in), C.DWORD(out)))
}
func (h handle) SetFlowControl() Err {
return Err(C.FT_SetFlowControl(h.toH(), C.FT_FLOW_RTS_CTS, 0, 0))
}
func (h handle) SetTimeouts(readMS, writeMS int) Err {
return Err(C.FT_SetTimeouts(h.toH(), C.DWORD(readMS), C.DWORD(writeMS)))
}
func (h handle) SetLatencyTimer(delayMS uint8) Err {
return Err(C.FT_SetLatencyTimer(h.toH(), C.UCHAR(delayMS)))
}
func (h handle) SetBaudRate(hz uint32) Err {
return Err(C.FT_SetBaudRate(h.toH(), C.DWORD(hz)))
}
func (h handle) GetQueueStatus() (uint32, Err) {
var v C.DWORD
e := C.FT_GetQueueStatus(h.toH(), &v)
return uint32(v), Err(e)
}
func (h handle) Read(b []byte) (int, Err) {
var bytesRead C.DWORD
e := C.FT_Read(h.toH(), C.LPVOID(unsafe.Pointer(&b[0])), C.DWORD(len(b)), &bytesRead)
return int(bytesRead), Err(e)
}
func (h handle) Write(b []byte) (int, Err) {
var bytesSent C.DWORD
e := C.FT_Write(h.toH(), C.LPVOID(unsafe.Pointer(&b[0])), C.DWORD(len(b)), &bytesSent)
return int(bytesSent), Err(e)
}
func (h handle) GetBitMode() (byte, Err) {
var s C.UCHAR
e := C.FT_GetBitMode(h.toH(), &s)
return uint8(s), Err(e)
}
func (h handle) SetBitMode(mask, mode byte) Err {
return Err(C.FT_SetBitMode(h.toH(), C.UCHAR(mask), C.UCHAR(mode)))
}
func (h handle) toH() C.FT_HANDLE {
return C.FT_HANDLE(h)
}