robocar-led/vendor/periph.io/x/host/v3/ftdi/eeprom.go

369 lines
14 KiB
Go

// Copyright 2018 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.
package ftdi
import (
"errors"
"fmt"
"unsafe"
)
// EEPROM is the unprocessed EEPROM content.
//
// The EEPROM is in 3 parts: the defined struct, the 4 strings and the rest
// which is used as an 'user area'. The size of the user area depends on the
// length of the strings. The user area content is not included in this struct.
type EEPROM struct {
// Raw is the raw EEPROM content. It excludes the strings.
Raw []byte
// The following condition must be true: len(Manufacturer) + len(Desc) <= 40.
Manufacturer string
ManufacturerID string
Desc string
Serial string
}
// Validate checks that the data is good.
func (e *EEPROM) Validate() error {
// Verify that the values are set correctly.
if len(e.Manufacturer) > 40 {
return errors.New("ftdi: Manufacturer is too long")
}
if len(e.ManufacturerID) > 40 {
return errors.New("ftdi: ManufacturerID is too long")
}
if len(e.Desc) > 40 {
return errors.New("ftdi: Desc is too long")
}
if len(e.Serial) > 40 {
return errors.New("ftdi: Serial is too long")
}
if len(e.Manufacturer)+len(e.Desc) > 40 {
return errors.New("ftdi: length of Manufacturer plus Desc is too long")
}
return nil
}
func (e *EEPROM) AsHeader() *EEPROMHeader {
// sizeof(EEPROMHeader)
if len(e.Raw) < 16 {
return nil
}
return (*EEPROMHeader)(unsafe.Pointer(&e.Raw[0]))
}
// AsFT232H returns the Raw data aliased as EEPROMFT232H.
func (e *EEPROM) AsFT232H() *EEPROMFT232H {
// sizeof(EEPROMFT232H)
if len(e.Raw) < 44 {
return nil
}
return (*EEPROMFT232H)(unsafe.Pointer(&e.Raw[0]))
}
// AsFT2232H returns the Raw data aliased as EEPROMFT2232H.
func (e *EEPROM) AsFT2232H() *EEPROMFT2232H {
// sizeof(EEPROMFT2232H)
if len(e.Raw) < 40 {
return nil
}
return (*EEPROMFT2232H)(unsafe.Pointer(&e.Raw[0]))
}
// AsFT232R returns the Raw data aliased as EEPROMFT232R.
func (e *EEPROM) AsFT232R() *EEPROMFT232R {
// sizeof(EEPROMFT232R)
if len(e.Raw) < 32 {
return nil
}
return (*EEPROMFT232R)(unsafe.Pointer(&e.Raw[0]))
}
// FT232hCBusMux is stored in the FT232H EEPROM to control each CBus pin.
type FT232hCBusMux uint8
const (
// TriSt-PU; Sets in Tristate (pull up) (C0~C6, C8, C9) on 75kΩ.
FT232hCBusTristatePullUp FT232hCBusMux = 0x00
// TXLED#; Pulses low when transmitting data (C0~C6, C8, C9).
FT232hCBusTxLED FT232hCBusMux = 0x01
// RXLED#; Pulses low when receiving data (C0~C6, C8, C9).
FT232hCBusRxLED FT232hCBusMux = 0x02
// TX&RXLED#; Pulses low when either receiving or transmitting data (C0~C6,
// C8, C9).
FT232hCBusTxRxLED FT232hCBusMux = 0x03
// PWREN#; Output is low after the device has been configured by USB, then
// high during USB suspend mode (C0~C6, C8, C9).
//
// Must be used with an external 10kΩ pull up.
FT232hCBusPwrEnable FT232hCBusMux = 0x04
// SLEEP#; Goes low during USB suspend mode (C0~C6, C8, C9).
FT232hCBusSleep FT232hCBusMux = 0x05
// DRIVE1; Drives pin to logic 0 (C0~C6, C8, C9).
FT232hCBusDrive0 FT232hCBusMux = 0x06
// DRIVE1; Drives pin to logic 1 (C0, C5, C6, C8, C9).
FT232hCBusDrive1 FT232hCBusMux = 0x07
// I/O Mode; CBus bit-bang mode option (C5, C6, C8, C9).
FT232hCBusIOMode FT232hCBusMux = 0x08
// TXDEN; Tx Data Enable. Used with RS485 level converters to enable the line
// driver during data transmit. It is active one bit time before the start
// bit up to until the end of the stop bit (C0~C6, C8, C9).
FT232hCBusTxdEnable FT232hCBusMux = 0x09
// CLK30 30MHz clock output (C0, C5, C6, C8, C9).
FT232hCBusClk30 FT232hCBusMux = 0x0A
// CLK15 15MHz clock output (C0, C5, C6, C8, C9).
FT232hCBusClk15 FT232hCBusMux = 0x0B
// CLK7.5 7.5MHz clock output (C0, C5, C6, C8, C9).
FT232hCBusClk7_5 FT232hCBusMux = 0x0C
)
const ft232hCBusMuxName = "FT232hCBusTristatePullUpFT232hCBusTxLEDFT232hCBusRxLEDFT232hCBusTxRxLEDFT232hCBusPwrEnableFT232hCBusSleepFT232hCBusDrive0FT232hCBusDrive1FT232hCBusIOModeFT232hCBusTxdEnableFT232hCBusClk30FT232hCBusClk15FT232hCBusClk7_5"
var fr232hCBusMuxIndex = [...]uint8{0, 24, 39, 54, 71, 90, 105, 121, 137, 153, 172, 187, 202, 218}
func (f FT232hCBusMux) String() string {
if f >= FT232hCBusMux(len(fr232hCBusMuxIndex)-1) {
return fmt.Sprintf("FT232hCBusMux(%d)", f)
}
return ft232hCBusMuxName[fr232hCBusMuxIndex[f]:fr232hCBusMuxIndex[f+1]]
}
// FT232rCBusMux is stored in the FT232R EEPROM to control each CBus pin.
type FT232rCBusMux uint8
const (
// TXDEN; Tx Data Enable. Used with RS485 level converters to enable the line
// driver during data transmit. It is active one bit time before the start
// bit up to until the end of the stop bit (C0~C4).
FT232rCBusTxdEnable FT232rCBusMux = 0x00
// PWREN#; Output is low after the device has been configured by USB, then
// high during USB suspend mode (C0~C4).
//
// Must be used with an external 10kΩ pull up.
FT232rCBusPwrEnable FT232rCBusMux = 0x01
// RXLED#; Pulses low when receiving data (C0~C4).
FT232rCBusRxLED FT232rCBusMux = 0x02
// TXLED#; Pulses low when transmitting data (C0~C4).
FT232rCBusTxLED FT232rCBusMux = 0x03
// TX&RXLED#; Pulses low when either receiving or transmitting data (C0~C4).
FT232rCBusTxRxLED FT232rCBusMux = 0x04
// SLEEP# Goes low during USB suspend mode (C0~C4).
FT232rCBusSleep FT232rCBusMux = 0x05
// CLK48 48Mhz +/-0.7% clock output (C0~C4).
FT232rCBusClk48 FT232rCBusMux = 0x06
// CLK24 24Mhz clock output (C0~C4).
FT232rCBusClk24 FT232rCBusMux = 0x07
// CLK12 12Mhz clock output (C0~C4).
FT232rCBusClk12 FT232rCBusMux = 0x08
// CLK6 6Mhz +/-0.7% clock output (C0~C4).
FT232rCBusClk6 FT232rCBusMux = 0x09
// CBitBangI/O; CBus bit-bang mode option (C0~C3).
FT232rCBusIOMode FT232rCBusMux = 0x0A
// BitBangWRn; CBus WR# strobe output (C0~C3).
FT232rCBusBitBangWR FT232rCBusMux = 0x0B
// BitBangRDn; CBus RD# strobe output (C0~C3).
FT232rCBusBitBangRD FT232rCBusMux = 0x0C
)
const ft232rCBusMuxName = "FT232rCBusTxdEnableFT232rCBusPwrEnableFT232rCBusRxLEDFT232rCBusTxLEDFT232rCBusTxRxLEDFT232rCBusSleepFT232rCBusClk48FT232rCBusClk24FT232rCBusClk12FT232rCBusClk6FT232rCBusIOModeFT232rCBusBitBangWRFT232rCBusBitBangRD"
var ft232rCBusMuxIndex = [...]uint8{0, 19, 38, 53, 68, 85, 100, 115, 130, 145, 159, 175, 194, 213}
func (f FT232rCBusMux) String() string {
if f >= FT232rCBusMux(len(ft232rCBusMuxIndex)-1) {
return fmt.Sprintf("FT232rCBusMux(%d)", f)
}
return ft232rCBusMuxName[ft232rCBusMuxIndex[f]:ft232rCBusMuxIndex[f+1]]
}
// EEPROMHeader is the common header found on FTDI devices.
//
// It is 16 bytes long.
type EEPROMHeader struct {
DeviceType DevType // 0x00 FTxxxx device type to be programmed
VendorID uint16 // 0x04 Defaults to 0x0403; can be changed
ProductID uint16 // 0x06 Defaults to 0x6001 for FT232R, 0x6014 for FT232H, relevant value
SerNumEnable uint8 // 0x07 bool Non-zero if serial number to be used
Unused0 uint8 // 0x08 For alignment.
MaxPower uint16 // 0x0A 0mA < MaxPower <= 500mA
SelfPowered uint8 // 0x0C bool 0 = bus powered, 1 = self powered
RemoteWakeup uint8 // 0x0D bool 0 = not capable, 1 = capable; RI# low will wake host in 20ms.
PullDownEnable uint8 // 0x0E bool Non zero if pull down in suspend enabled
Unused1 uint8 // 0x0F For alignment.
}
// EEPROMFT232H is the EEPROM layout of a FT232H device.
//
// It is 44 bytes long.
type EEPROMFT232H struct {
EEPROMHeader
// FT232H specific.
ACSlowSlew uint8 // 0x10 bool Non-zero if AC bus pins have slow slew
ACSchmittInput uint8 // 0x11 bool Non-zero if AC bus pins are Schmitt input
ACDriveCurrent uint8 // 0x12 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units
ADSlowSlew uint8 // 0x13 bool Non-zero if AD bus pins have slow slew
ADSchmittInput uint8 // 0x14 bool Non-zero if AD bus pins are Schmitt input
ADDriveCurrent uint8 // 0x15 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units
Cbus0 FT232hCBusMux // 0x16
Cbus1 FT232hCBusMux // 0x17
Cbus2 FT232hCBusMux // 0x18
Cbus3 FT232hCBusMux // 0x19
Cbus4 FT232hCBusMux // 0x1A
Cbus5 FT232hCBusMux // 0x1B
Cbus6 FT232hCBusMux // 0x1C
Cbus7 FT232hCBusMux // 0x1D C7 is limited a sit can only do 'suspend on C7 low'. Defaults pull down.
Cbus8 FT232hCBusMux // 0x1E
Cbus9 FT232hCBusMux // 0x1F
FT1248Cpol uint8 // 0x20 bool FT1248 clock polarity - clock idle high (true) or clock idle low (false)
FT1248Lsb uint8 // 0x21 bool FT1248 data is LSB (true), or MSB (false)
FT1248FlowControl uint8 // 0x22 bool FT1248 flow control enable
IsFifo uint8 // 0x23 bool Non-zero if Interface is 245 FIFO
IsFifoTar uint8 // 0x24 bool Non-zero if Interface is 245 FIFO CPU target
IsFastSer uint8 // 0x25 bool Non-zero if Interface is Fast serial
IsFT1248 uint8 // 0x26 bool Non-zero if Interface is FT1248
PowerSaveEnable uint8 // 0x27 bool Suspect on ACBus7 low.
DriverType uint8 // 0x28 bool 0 is D2XX, 1 is VCP
Unused2 uint8 // 0x29
Unused3 uint16 // 0x30
}
func (e *EEPROMFT232H) Defaults() {
// As found on Adafruit device.
e.ACDriveCurrent = 4
e.ADDriveCurrent = 4
e.Cbus0 = FT232hCBusTristatePullUp
e.Cbus1 = FT232hCBusTristatePullUp
e.Cbus2 = FT232hCBusTristatePullUp
e.Cbus3 = FT232hCBusTristatePullUp
e.Cbus4 = FT232hCBusTristatePullUp
e.Cbus5 = FT232hCBusTristatePullUp
e.Cbus6 = FT232hCBusTristatePullUp
e.Cbus7 = FT232hCBusTristatePullUp
e.Cbus8 = FT232hCBusDrive1
e.Cbus9 = FT232hCBusDrive0
}
// EEPROMFT2232H is the EEPROM layout of a FT2232H device.
//
// It is 40 bytes long.
type EEPROMFT2232H struct {
EEPROMHeader
// FT232H specific.
ALSlowSlew uint8 // 0x10 bool non-zero if AL pins have slow slew
ALSchmittInput uint8 // 0x11 bool non-zero if AL pins are Schmitt input
ALDriveCurrent uint8 // 0x12 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units
AHSlowSlew uint8 // 0x13 bool non-zero if AH pins have slow slew
AHSchmittInput uint8 // 0x14 bool non-zero if AH pins are Schmitt input
AHDriveCurrent uint8 // 0x15 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units
BLSlowSlew uint8 // 0x16 bool non-zero if BL pins have slow slew
BLSchmittInput uint8 // 0x17 bool non-zero if BL pins are Schmitt input
BLDriveCurrent uint8 // 0x18 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units
BHSlowSlew uint8 // 0x19 bool non-zero if BH pins have slow slew
BHSchmittInput uint8 // 0x1A bool non-zero if BH pins are Schmitt input
BHDriveCurrent uint8 // 0x1B Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units
AIsFifo uint8 // 0x1C bool non-zero if interface is 245 FIFO
AIsFifoTar uint8 // 0x1D bool non-zero if interface is 245 FIFO CPU target
AIsFastSer uint8 // 0x1E bool non-zero if interface is Fast serial
BIsFifo uint8 // 0x1F bool non-zero if interface is 245 FIFO
BIsFifoTar uint8 // 0x20 bool non-zero if interface is 245 FIFO CPU target
BIsFastSer uint8 // 0x21 bool non-zero if interface is Fast serial
PowerSaveEnable uint8 // 0x22 bool non-zero if using BCBUS7 to save power for self-powered designs
ADriverType uint8 // 0x23 bool
BDriverType uint8 // 0x24 bool
Unused2 uint8 // 0x25
Unused3 uint16 // 0x26
}
// EEPROMFT232R is the EEPROM layout of a FT232R device.
//
// It is 32 bytes long.
type EEPROMFT232R struct {
EEPROMHeader
// FT232R specific.
IsHighCurrent uint8 // 0x10 bool High Drive I/Os; 3mA instead of 1mA (@3.3V)
UseExtOsc uint8 // 0x11 bool Use external oscillator
InvertTXD uint8 // 0x12 bool
InvertRXD uint8 // 0x13 bool
InvertRTS uint8 // 0x14 bool
InvertCTS uint8 // 0x15 bool
InvertDTR uint8 // 0x16 bool
InvertDSR uint8 // 0x17 bool
InvertDCD uint8 // 0x18 bool
InvertRI uint8 // 0x19 bool
Cbus0 FT232rCBusMux // 0x1A Default ft232rCBusTxLED
Cbus1 FT232rCBusMux // 0x1B Default ft232rCBusRxLED
Cbus2 FT232rCBusMux // 0x1C Default ft232rCBusTxdEnable
Cbus3 FT232rCBusMux // 0x1D Default ft232rCBusPwrEnable
Cbus4 FT232rCBusMux // 0x1E Default ft232rCBusSleep
DriverType uint8 // 0x1F bool 0 is D2XX, 1 is VCP
}
func (e *EEPROMFT232R) Defaults() {
// As found on Adafruit device.
e.Cbus0 = FT232rCBusTxLED
e.Cbus1 = FT232rCBusRxLED
e.Cbus2 = FT232rCBusTxdEnable
e.Cbus3 = FT232rCBusPwrEnable
e.Cbus4 = FT232rCBusSleep
e.DriverType = 1
}
//
// DevType is the FTDI device type.
type DevType uint32
const (
DevTypeFTBM DevType = iota // 0
DevTypeFTAM
DevTypeFT100AX
DevTypeUnknown // 3
DevTypeFT2232C
DevTypeFT232R // 5
DevTypeFT2232H
DevTypeFT4232H
DevTypeFT232H // 8
DevTypeFTXSeries
DevTypeFT4222H0
DevTypeFT4222H1_2
DevTypeFT4222H3
DevTypeFT4222Prog
DevTypeFT900
DevTypeFT930
DevTypeFTUMFTPD3A
)
// EEPROMSize returns the size of the EEPROM for this device.
func (d DevType) EEPROMSize() int {
switch d {
case DevTypeFT232H:
// sizeof(EEPROMFT232H)
return 44
case DevTypeFT2232H:
// sizeof(EEPROMFT2232H)
return 40
case DevTypeFT232R:
// sizeof(EEPROMFT232R)
return 32
default:
return 256
}
}
const devTypeName = "FTBMFTAMFT100AXUnknownFT2232CFT232RFT2232HFT4232HFT232HFTXSeriesFT4222H0FT4222H1/2FT4222H3FT4222ProgFT900FT930FTUMFTPD3A"
var devTypeIndex = [...]uint8{0, 4, 8, 15, 22, 29, 35, 42, 49, 55, 64, 72, 82, 90, 100, 105, 110, 120}
func (d DevType) String() string {
if d >= DevType(len(devTypeIndex)-1) {
d = DevTypeUnknown
}
return devTypeName[devTypeIndex[d]:devTypeIndex[d+1]]
}