Initial check in
This commit is contained in:
@@ -0,0 +1,567 @@
|
||||
// ================================================================================================
|
||||
// TTrinity
|
||||
//
|
||||
// The base class of all trinity boards. Every device returned by the device manager's
|
||||
// "AllocateDevice" is an instance of a TTrinity class, or it's derivates. Every trinity
|
||||
// board have on-board EEPROM and implement the following base functions:
|
||||
//
|
||||
// - I2C bus communication functions
|
||||
// - EEPROM read/write functions
|
||||
// - configuration functions (serial no, etc...)
|
||||
// - firmware download (in case of cypress chip. RX devices ignore this request)
|
||||
//
|
||||
// Because of the mandatory functions, the I2C,EPR do not appear in the "Capabilties"
|
||||
// property !
|
||||
//
|
||||
// To add new Capabilty to a board, see "dev.usb.trinity.consts", "dev.usb.trinity.utils",
|
||||
// and "dev.usb.trinity.types".
|
||||
//
|
||||
// ================================================================================================
|
||||
unit mr.trinity;
|
||||
|
||||
interface
|
||||
uses
|
||||
System.Classes,
|
||||
System.SysUtils,
|
||||
|
||||
mr.dev.usb,
|
||||
mr.trinity.consts,
|
||||
mr.trinity.types,
|
||||
mr.trinity.utils,
|
||||
mr.trinity.pipe0,
|
||||
|
||||
m.eeprom.types,
|
||||
m.cfg.types,
|
||||
m.iic.types,
|
||||
m.jtag.types,
|
||||
m.led.types,
|
||||
m.lcd.types;
|
||||
|
||||
type
|
||||
// -----------------------------------------------------------------------------------
|
||||
// TTrinity
|
||||
// -----------------------------------------------------------------------------------
|
||||
TTrinity = class (TUsbDevice, ITrinity, IIIC, ILCD, ILED, IEEPROM, IJTAG, ICFG)
|
||||
protected
|
||||
fCaps : TCapabilities;
|
||||
fCaps64 : Int64;
|
||||
fSerial : string;
|
||||
fIdentifier : string;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// ITrinity
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
procedure Open; override;
|
||||
|
||||
procedure DownloadFirmware( Filename : string); overload;
|
||||
procedure DownloadFirmware( Stream : TStream); overload;
|
||||
|
||||
procedure DownloadFirmwarePerm( Filename : string); overload;
|
||||
procedure DownloadFirmwarePerm( Stream : TStream); overload;
|
||||
|
||||
// procedure I2CRead( addr: byte; var buffer; length: byte);
|
||||
// procedure I2CWrite( addr: byte; const buffer; length: byte);
|
||||
|
||||
function EEPROMReadPage( page: word; var buffer): boolean;
|
||||
function EEPROMWritePage( page: word; const buffer): boolean;
|
||||
|
||||
function SerialNumber : string;
|
||||
function Capabilities : TCapabilities;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// interface implementor modules
|
||||
// ----------------------------------------------------------------------
|
||||
private
|
||||
fModCFG : ICFG;
|
||||
fModIIC : IIIC;
|
||||
fModEPR : IEEPROM;
|
||||
fModJTAG : IJTAG;
|
||||
fModLCD : ILCD;
|
||||
fModLED : ILED;
|
||||
|
||||
protected
|
||||
property cfg : ICFG read fModCFG implements ICFG;
|
||||
property iic : IIIC read fModIIC implements IIIC;
|
||||
property eeprom : IEEPROM read fModEPR implements IEEPROM;
|
||||
property jtag : IJTAG read fModJTAG implements IJTAG;
|
||||
property lcd : ILCD read fModLCD implements ILCD;
|
||||
property led : ILED read fModLED implements ILED;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// construction / destruction
|
||||
// ----------------------------------------------------------------------
|
||||
public
|
||||
procedure AfterConstruction; override;
|
||||
procedure BeforeDestruction; override;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// properties
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public
|
||||
// property SerialNumber : string read fSerial;
|
||||
// property Capabilities : TCapabilities read fCaps;
|
||||
property Caps : Int64 read fCaps64;
|
||||
end;
|
||||
|
||||
implementation
|
||||
uses
|
||||
Windows, Diagnostics,
|
||||
|
||||
mr.dev.manager,
|
||||
mr.dev.usb.pipe,
|
||||
mr.dev.usb.pipe0,
|
||||
mr.trinity.hex,
|
||||
|
||||
m.cfg,
|
||||
m.iic,
|
||||
m.lcd,
|
||||
m.led,
|
||||
m.jtag,
|
||||
m.eeprom;
|
||||
|
||||
type
|
||||
THeader = packed record
|
||||
command : byte;
|
||||
status : byte;
|
||||
page : word;
|
||||
offset : byte;
|
||||
length : byte;
|
||||
dummy : word;
|
||||
end;
|
||||
|
||||
TEEPROM = packed record
|
||||
header : THeader;
|
||||
data : array [0..31] of byte;
|
||||
end;
|
||||
|
||||
|
||||
{ TTrinity }
|
||||
|
||||
|
||||
|
||||
// @@@: Construction / destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Construction / destruction
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// After Construction
|
||||
// ================================================================================================
|
||||
procedure TTrinity.AfterConstruction;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
fPipe0Class := TTrinityPipe0;
|
||||
|
||||
fModCFG := TmodCFG .Create( self);
|
||||
fModIIC := TmodIIC .Create( self);
|
||||
fModEPR := TmodEEPROM .Create( self);
|
||||
fModLCD := TmodLCD .Create( self);
|
||||
fModLED := TmodLED .Create( self);
|
||||
fModJTAG := TmodJTAG .Create( self);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Before Destruction
|
||||
// ================================================================================================
|
||||
procedure TTrinity.BeforeDestruction;
|
||||
begin
|
||||
inherited
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function TTrinity.Capabilities: TCapabilities;
|
||||
begin
|
||||
result := fCaps
|
||||
end;
|
||||
|
||||
// @@@: Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// ================================================================================================
|
||||
// Open
|
||||
// ================================================================================================
|
||||
procedure TTrinity.Open;
|
||||
var
|
||||
buf: array [0..7] of AnsiChar;
|
||||
cnt: cardinal;
|
||||
i : integer;
|
||||
|
||||
begin
|
||||
inherited;
|
||||
|
||||
if (VendorID = $16d0) and (ProductID = $0712) then
|
||||
begin
|
||||
// ----------------------------------------------------------------------
|
||||
// serial number
|
||||
// ----------------------------------------------------------------------
|
||||
if Pipe0.Transfer( $80, // IN
|
||||
CFG_SERIAL, // Get Serial
|
||||
$00, // Value (not used)
|
||||
$00, // Index (not used)
|
||||
$08, // Length
|
||||
|
||||
@buf, // Buffer to receive data
|
||||
8, // Length of buffer
|
||||
cnt, // Transferred bytes
|
||||
nil) then // Overlapped (not used)
|
||||
begin
|
||||
fSerial := '';
|
||||
|
||||
for i:=0 to 7 do
|
||||
if buf[i] in ['a'..'z','A'..'Z','0'..'9','$','.','_','-']
|
||||
then fSerial := fSerial + string(buf[i])
|
||||
else break
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// capabilities
|
||||
// ----------------------------------------------------------------------
|
||||
if Pipe0.Transfer( $80, // IN
|
||||
CFG_CAPS, // Get Capabilities
|
||||
$00, // Value (not used)
|
||||
$00, // Index (not used)
|
||||
$08, // Length
|
||||
|
||||
@buf, // Buffer to receive data
|
||||
8, // Length of buffer
|
||||
cnt, // Transferred bytes
|
||||
nil) then // Overlapped (not used)
|
||||
begin
|
||||
fCaps64 := PInt64(@buf)^;
|
||||
fCaps := DecodeCapabilities(fCaps64);
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
function TTrinity.SerialNumber: string;
|
||||
begin
|
||||
result := fserial
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Download firmware (file)
|
||||
// ================================================================================================
|
||||
procedure TTrinity.DownloadFirmware(Filename: string);
|
||||
begin
|
||||
with Pipe0 as TTrinityPipe0 do
|
||||
DownloadFirmware( Filename);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Download firmware (stream)
|
||||
// ================================================================================================
|
||||
procedure TTrinity.DownloadFirmware(Stream: TStream);
|
||||
begin
|
||||
with Pipe0 as TTrinityPipe0 do
|
||||
DownloadFirmware( Stream);
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Download firmware permanent (file)
|
||||
// ================================================================================================
|
||||
procedure TTrinity.DownloadFirmwarePerm(Filename: string);
|
||||
var
|
||||
stm: TMemoryStream;
|
||||
|
||||
begin
|
||||
if FileExists(Filename) then
|
||||
begin
|
||||
stm := TMemoryStream.Create;
|
||||
stm.LoadFromFile(Filename);
|
||||
DownloadFirmwarePerm(stm);
|
||||
stm.Free
|
||||
end;
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// Download firmware permanent (stream)
|
||||
// ================================================================================================
|
||||
procedure TTrinity.DownloadFirmwarePerm(Stream: TStream);
|
||||
var
|
||||
addr : word;
|
||||
left : word;
|
||||
|
||||
bidx : byte;
|
||||
didx : byte;
|
||||
|
||||
hex : THexFile;
|
||||
|
||||
page : word;
|
||||
buf : array [0..31] of byte;
|
||||
|
||||
procedure PushByte( data: byte);
|
||||
begin
|
||||
buf[bidx] := data;
|
||||
|
||||
if bidx >= 31 then
|
||||
begin
|
||||
EEPROMWritePage(page,buf);
|
||||
ZeroMemory(@buf,32);
|
||||
|
||||
INC(page);
|
||||
bidx := 0;
|
||||
end
|
||||
|
||||
else
|
||||
INC(bidx)
|
||||
end;
|
||||
|
||||
var
|
||||
cnt : word;
|
||||
|
||||
|
||||
procedure SendBlock( const blk: THexBlock);
|
||||
const
|
||||
CHUNK = 1023;
|
||||
|
||||
var
|
||||
dptr : PByte;
|
||||
|
||||
begin
|
||||
left := blk.BlockLength;
|
||||
addr := blk.Address;
|
||||
dptr := blk.Data;
|
||||
didx := 0;
|
||||
|
||||
while left > 0 do
|
||||
begin
|
||||
if left > CHUNK then
|
||||
begin
|
||||
// push length of block
|
||||
PushByte( HiByte(CHUNK));
|
||||
PushByte( LoByte(CHUNK));
|
||||
|
||||
// push load address of block
|
||||
PushByte( HiByte(addr));
|
||||
PushByte( LoByte(addr));
|
||||
|
||||
cnt := CHUNK;
|
||||
left := left - CHUNK;
|
||||
addr := addr + CHUNK;
|
||||
end
|
||||
|
||||
else begin
|
||||
// push length of block
|
||||
PushByte( HiByte(left));
|
||||
PushByte( LoByte(left));
|
||||
|
||||
// push load address of block
|
||||
PushByte( HiByte(addr));
|
||||
PushByte( LoByte(addr));
|
||||
|
||||
cnt := left;
|
||||
left := 0;
|
||||
end;
|
||||
|
||||
// push data
|
||||
while cnt > 0 do
|
||||
begin
|
||||
PushByte( dptr^);
|
||||
INC(dptr);
|
||||
|
||||
DEC(cnt);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
blk: THexBlock;
|
||||
|
||||
begin
|
||||
hex := THexFile.Create;
|
||||
hex.LoadFromStream(stream);
|
||||
|
||||
// prepare counters
|
||||
page := 0;
|
||||
bidx := 8;
|
||||
|
||||
// prepare first eeprom block.
|
||||
// be careful with the first 8 bytes!!!
|
||||
ZeroMemory( @buf, 32);
|
||||
buf[0] := $c2;
|
||||
buf[7] := $01;
|
||||
|
||||
|
||||
// download blocks
|
||||
// for i:=0 to hex.BlockCount -1 do
|
||||
// SendBlock( hex.Blocks[i]);
|
||||
|
||||
for blk in hex.Blocks do
|
||||
SendBlock(blk);
|
||||
|
||||
// download last block
|
||||
PushByte( $80);
|
||||
PushByte( $01);
|
||||
PushByte( $E6);
|
||||
PushByte( $00);
|
||||
PushByte( $00);
|
||||
|
||||
if bidx > 0 then
|
||||
EEPROMWritePage(page, buf);
|
||||
|
||||
hex.Free
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// EEPROM Read
|
||||
// ================================================================================================
|
||||
function TTrinity.EEPROMReadPage( page: word; var buffer): boolean;
|
||||
var
|
||||
pipe01 : TPipe;
|
||||
pipe81 : TPipe;
|
||||
|
||||
buf : TEEPROM;
|
||||
len : cardinal;
|
||||
|
||||
begin
|
||||
if capEEPROM in fCaps then
|
||||
begin
|
||||
result := false;
|
||||
|
||||
pipe01 := Pipes[$01];
|
||||
pipe81 := Pipes[$81];
|
||||
|
||||
if Assigned( pipe01) and Assigned( pipe81) then
|
||||
begin
|
||||
buf.header.command := EEPROM_RAW or EEPROM_READ;
|
||||
buf.header.page := (LoByte(page) shl 8) + HiByte(page);
|
||||
buf.header.offset := $00;
|
||||
buf.header.length := $20;
|
||||
|
||||
pipe01.Write( buf, sizeof(buf), len);
|
||||
pipe81.Read( buf, sizeof(buf), len);
|
||||
|
||||
CopyMemory(@buffer, @buf.data, 32);
|
||||
end;
|
||||
end
|
||||
|
||||
else
|
||||
raise EInvalidFunction.Create('EEPROM Read');
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// EEPROM Write
|
||||
// ================================================================================================
|
||||
function TTrinity.EEPROMWritePage( page: word; const buffer): boolean;
|
||||
var
|
||||
pipe01 : TPipe;
|
||||
pipe81 : TPipe;
|
||||
|
||||
buf : TEEPROM;
|
||||
len : cardinal;
|
||||
|
||||
begin
|
||||
if capEEPROM in fCaps then
|
||||
begin
|
||||
result := false;
|
||||
pipe01 := Pipes[$01];
|
||||
pipe81 := Pipes[$81];
|
||||
|
||||
if Assigned( pipe01) and Assigned( pipe81) then
|
||||
begin
|
||||
buf.header.command := EEPROM_RAW or EEPROM_WRITE;
|
||||
buf.header.page := (LoByte(page) shl 8) + HiByte(page);
|
||||
buf.header.offset := $00;
|
||||
buf.header.length := $20;
|
||||
|
||||
CopyMemory(@buf.data, @buffer, 32);
|
||||
|
||||
pipe01.Write( buf, sizeof(buf), len);
|
||||
pipe81.Read( buf, sizeof(buf), len);
|
||||
end;
|
||||
end
|
||||
|
||||
else
|
||||
raise EInvalidFunction.Create('EEPROM Write');
|
||||
end;
|
||||
|
||||
// ================================================================================================
|
||||
// I2C Read
|
||||
//
|
||||
// TODO: Must be executed in a thread.
|
||||
// ================================================================================================
|
||||
{
|
||||
procedure TTrinity.I2CRead( addr: byte; var buffer; length: byte);
|
||||
var
|
||||
pipe01 : TPipe;
|
||||
pipe81 : TPipe;
|
||||
|
||||
buf : TEEPROM;
|
||||
len : cardinal;
|
||||
|
||||
begin
|
||||
pipe01 := Pipes[$01];
|
||||
pipe81 := Pipes[$81];
|
||||
|
||||
if length >= 32 then
|
||||
length := 32;
|
||||
|
||||
if Assigned( pipe01) and Assigned( pipe81) then
|
||||
begin
|
||||
buf.header.command := DIR_IN + $20;
|
||||
buf.header.page := 0;
|
||||
buf.header.offset := addr;
|
||||
buf.header.length := length;
|
||||
|
||||
pipe01.Write( buf, sizeof(TEEPROM), len);
|
||||
ZeroMemory( @buf, sizeof(TEEPROM));
|
||||
pipe81.Read( buf, sizeof(TEEPROM), len);
|
||||
|
||||
CopyMemory(@buffer, @buf.data, length)
|
||||
end
|
||||
end;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
// I2C Write
|
||||
// ================================================================================================
|
||||
{
|
||||
procedure TTrinity.I2CWrite(addr: byte; const buffer; length: byte);
|
||||
var
|
||||
pipe01 : TPipe;
|
||||
pipe81 : TPipe;
|
||||
|
||||
buf : TEEPROM;
|
||||
len : cardinal;
|
||||
|
||||
begin
|
||||
pipe01 := Pipes[$01];
|
||||
pipe81 := Pipes[$81];
|
||||
|
||||
if length >= 32 then
|
||||
length := 32;
|
||||
|
||||
if Assigned( pipe01) and Assigned( pipe81) then
|
||||
begin
|
||||
buf.header.command := DIR_OUT + $20;
|
||||
buf.header.page := 0;
|
||||
buf.header.offset := addr;
|
||||
buf.header.length := length;
|
||||
|
||||
CopyMemory(@buf.data, @buffer, length);
|
||||
|
||||
pipe01.Write( buf, sizeof(TEEPROM), len);
|
||||
pipe81.Read( buf, sizeof(THeader), len);
|
||||
end
|
||||
end;
|
||||
}
|
||||
|
||||
initialization
|
||||
RegisterDevice( $04b4, $8613, 0, TTrinity); // cypress vid/pid
|
||||
RegisterDevice( $16d0, $0712, 0, TTrinity); // trinity vid/pid
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user