Files
bds.mr.jtg/src.jtag/jtag.bstream.pas
T
2026-01-08 19:12:06 +01:00

1129 lines
32 KiB
ObjectPascal

unit jtag.bstream;
interface
uses
Classes,
Types,
jtag.svfAstScan,
jtag.svfAstRuntest,
jtag.svfAstState;
type
TjtagBStream = class;
TjtagCepMode = (cmNone, cmRead, cmWrite);
TjtagTapState = (stInvalid, stReset, stIdle, stDrScan, stIrScan,
stDrCapture, stIrCapture, stDrShift, stIrShift, stDrExit1, stIrExit1,
stDrPause, stIrPause, stDrExit2, stIrExit2, stDrUpdate, stIrUpdate);
TjtagOnFullEvent = procedure(Sender: TjtagBStream;
CEPMode: TjtagCepMode) of object;
TjtagOnDumpEvent = procedure( Sender: TjtagBStream; Data: string) of object;
TjtagBStream = class
protected
fBufTDI: array [0 .. 1023] of byte;
fBufTDO: array [0 .. 1023] of byte;
fBufSMASK: array [0 .. 1023] of byte;
fBufMASK: array [0 .. 1023] of byte;
fInitDone: boolean;
fBufferSize: word;
fBuffer: array [0 .. 1023] of byte;
fCursor : word;
fCursorR : word;
fEndDR: TjtagTapState;
fEndIR: TjtagTapState;
fMaskTCK: byte;
fMaskTMS: byte;
fMaskTDI: byte;
fMaskTDO: byte;
fMaskTRST: byte;
fMaskENA: byte;
fMaskPWR: byte;
// current value of the pins
fValTCK: byte;
fValTMS: byte;
fValTDI: byte;
fValTDO: byte;
fValTRST: byte;
fValENA: byte;
fValPWR: byte;
fCEPMode: TjtagCepMode;
fLastCEPMode: TjtagCepMode;
fLastWrite: integer;
// events
fOnFull: TjtagOnFullEvent;
fOnDump: TjtagOnDumpEvent;
// ------------------------------------------------------------
// JTAG TAP state machine
// ------------------------------------------------------------
protected
fState: TjtagTapState;
function FlipByte( Data: byte): byte;
// ------------------------------------------------------------
public
procedure SendBit(TDI: byte; TMS: byte);
procedure SendByte(Value: byte; length: byte; last: boolean = false);
overload;
procedure SendByte(TDI: byte; TDO: byte; SMASK: byte; MASK: byte;
length: word; last: boolean = false); overload;
function ReceiveByte(length: byte): byte;
// ------------------------------------------------------------
// Property handlers
// ------------------------------------------------------------
private
function GetData(i: word): byte;
procedure SetData(i: word; d: byte);
procedure SetState(newState: TjtagTapState);
procedure SetEndDR(Value: TjtagTapState);
procedure SetEndIR(Value: TjtagTapState);
protected
procedure Init(BufferSize: word; TCK: byte; TMS: byte; TDI: byte;
TDO: byte; TRST: byte; ENA: byte; PWR: byte);
public
procedure InitDsoJtag;
procedure InitPrgJtag;
procedure Clear;
procedure Emit;
procedure Pulse(n: cardinal = 1);
procedure Flush;
protected
fBufHIR: array [0 .. 255] of byte;
fBufTIR: array [0 .. 255] of byte;
fBufHDR: array [0 .. 255] of byte;
fBufTDR: array [0 .. 255] of byte;
fLenHIR: integer;
fLenTIR: integer;
fLenHDR: integer;
fLenTDR: integer;
fBitHIR: integer;
fBitTIR: integer;
fBitHDR: integer;
fBitTDR: integer;
procedure SendHTIDR(stmt: TsvfAstScan);
public
procedure Send(stmt: TsvfAstScan); overload;
procedure Send(stmt: TsvfAstRuntest); overload;
procedure Send(stmt: TsvfAstState); overload;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
public
property Size: word read fBufferSize;
property DataSize: word read fCursor;
property Data[i: word]: byte read GetData write SetData;
property CEPMode: TjtagCepMode read fCEPMode write fCEPMode;
property State: TjtagTapState read fState write SetState;
property EndDR: TjtagTapState read fEndDR write SetEndDR;
property EndIR: TjtagTapState read fEndIR write SetEndIR;
property TCK: byte read fValTCK write fValTCK;
property TMS: byte read fValTMS write fValTMS;
property TDI: byte read fValTDI write fValTDI;
property TRST: byte read fValTRST write fValTRST;
property ENA: byte read fValENA write fValENA;
public
property OnFull: TjtagOnFullEvent read fOnFull write fOnFull;
property OnDump: TjtagOnDumpEvent read fOnDump write fOnDump;
end;
implementation
uses
Vcl.Forms,
Windows,
SysUtils;
{ TjtagBStream }
{ TjtagBStream }
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Construction/destruction
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ================================================================================================
// AfterConstruction
// ================================================================================================
procedure TjtagBStream.AfterConstruction;
begin
inherited;
fMaskTCK := 0;
fMaskTMS := 0;
fMaskTDI := 0;
fMaskTDO := 0;
fMaskTRST := 0;
fMaskENA := 0;
fMaskPWR := 0;
fCursor := 0;
fState := stInvalid;
fEndDR := stIdle;
fEndIR := stIdle;
fLastWrite := 0;
fCEPMode := cmNone;
end;
// ================================================================================================
// BeforeDestruction
// ================================================================================================
procedure TjtagBStream.BeforeDestruction;
begin
inherited;
end;
// ================================================================================================
// Init
// ================================================================================================
procedure TjtagBStream.Init(BufferSize: word; TCK, TMS, TDI, TDO, TRST, ENA,
PWR: byte);
begin
fBufferSize := 504;
// if (BufferSize <> 1024) and (BufferSize <> 512)
// then fBufferSize := 1024
// else fBufferSize := BufferSize;
if TCK <> $FF then fMaskTCK := 1 shl TCK else fMaskTCK := 0;
if TMS <> $FF then fMaskTMS := 1 shl TMS else fMaskTMS := 0;
if TDI <> $FF then fMaskTDI := 1 shl TDI else fMaskTDI := 0;
if TDO <> $FF then fMaskTDO := 1 shl TDO else fMaskTDO := 0;
if TRST <> $FF then fMaskTRST := 1 shl TRST else fMaskTRST := 0;
if ENA <> $FF then fMaskENA := 1 shl ENA else fMaskENA := 0;
if PWR <> $FF then fMaskPWR := 1 shl PWR else fMaskPWR := 0;
fInitDone := true;
end;
// ================================================================================================
// InitDsoJtag
// ================================================================================================
procedure TjtagBStream.InitDsoJtag;
begin
Init(256, 0, 1, 3, 7, $FF, $FF, $FF);
end;
// ================================================================================================
// InitPrgJtag
// ================================================================================================
procedure TjtagBStream.InitPrgJtag;
begin
Init(256, 0, 1, 7, 3, 5, 4, 6);
end;
// @@@: JTAG TAP state machine interface ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// JTAG TAP state machine interface
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ================================================================================================
// State
// ================================================================================================
procedure TjtagBStream.SetState(newState: TjtagTapState);
var
i: integer;
rc: boolean;
begin
rc := true;
// -----------------------------------------------------
// xxx -> RESET
// -----------------------------------------------------
if newState = stReset then
for i := 0 to 4 do
SendBit(0, 1)
// -----------------------------------------------------
// IDLE
// -----------------------------------------------------
else if newState = stIdle then
begin
case fState of
stReset:
begin
SendBit(0, 0);
end;
stDrShift, stDrPause, stIrShift, stIrPause:
begin
SendBit(0, 1);
SendBit(0, 1);
SendBit(0, 0);
end;
stDrExit1, stIrExit1:
begin
SendBit(0, 1);
SendBit(0, 0);
end;
else
rc := false;
end;
end
// -----------------------------------------------------
// DRSHIFT
// -----------------------------------------------------
else if newState = stDrShift then
begin
case fState of
stReset:
begin
SendBit(0, 0); // IDLE
SendBit(0, 1); // DRSELECT
SendBit(0, 0); // DRCAPTURE
SendBit(0, 0); // DRSHIFT
end;
stIdle:
begin
SendBit(0, 1); // DRSELECT
SendBit(0, 0); // DRCAPTURE
SendBit(0, 0); // DRSHIFT
end;
stDrPause:
begin
SendBit(0, 1); // DREXIT2
SendBit(0, 0); // DRSHIFT
end;
else
rc := false;
end;
end
// -----------------------------------------------------
// IRSHIFT
// -----------------------------------------------------
else if newState = stIrShift then
begin
case fState of
stReset:
begin
SendBit(0, 0); // IDLE
SendBit(0, 1); // DRSELECT
SendBit(0, 1); // IRSELECT
SendBit(0, 0); // IRCAPTURE
SendBit(0, 0); // IRSHIFT
end;
stIdle:
begin
SendBit(0, 1); // DRSELECT
SendBit(0, 1); // IRSELECT
SendBit(0, 0); // IRCAPTURE
SendBit(0, 0); // IRSHIFT
end;
stIrPause:
begin
SendBit(0, 1); // IREXIT2
SendBit(0, 0); // IRSHIFT
end;
else
rc := false;
end;
end
// -----------------------------------------------------
// DRPAUSE
// -----------------------------------------------------
else if newState = stDrPause then
begin
case fState of
stReset:
begin
SendBit(0, 0); // IDLE
SendBit(0, 1); // DRSELECT
SendBit(0, 0); // DRCAPTURE
SendBit(0, 1); // DREXIT1
SendBit(0, 0); // DRPAUSE
end;
stIdle:
begin
SendBit(0, 1); // DRSELECT
SendBit(0, 0); // DRCAPTURE
SendBit(0, 1); // DREXIT1
SendBit(0, 0); // DRPAUSE
end;
stDrShift:
begin
SendBit(0, 1); // DREXIT1
SendBit(0, 0); // DRPAUSE
end;
else
rc := false;
end;
end
// -----------------------------------------------------
// IRPAUSE
// -----------------------------------------------------
else if newState = stIrPause then
begin
case fState of
stReset:
begin
SendBit(0, 0); // IDLE
SendBit(0, 1); // DRSELECT
SendBit(0, 1); // IRSELECT
SendBit(0, 0); // IRCAPTURE
SendBit(0, 1); // IREXIT1
SendBit(0, 0); // IRPAUSE
end;
stIdle:
begin
SendBit(0, 1); // DRSELECT
SendBit(0, 1); // IRSELECT
SendBit(0, 0); // IRCAPTURE
SendBit(0, 1); // IREXIT1
SendBit(0, 0); // IRPAUSE
end;
stIrShift:
begin
SendBit(0, 1); // IREXIT1
SendBit(0, 0); // IRPAUSE
end;
else
rc := false;
end;
end;
if rc then
fState := newState;
end;
// ================================================================================================
// Pulse
// ================================================================================================
procedure TjtagBStream.Pulse(n: cardinal);
var
i: cardinal;
begin
for i := 0 to n - 1 do
begin
fValTCK := 0;
Emit;
fValTCK := 1;
Emit;
end;
end;
// ================================================================================================
// Emit
// ================================================================================================
procedure TjtagBStream.Emit;
var
b: byte;
begin
b := 0;
if fValTCK <> 0 then
b := b or fMaskTCK;
if fValTMS <> 0 then
b := b or fMaskTMS;
if fValTDI <> 0 then
b := b or fMaskTDI;
if fValTRST <> 0 then
b := b or fMaskTRST;
if fValENA = 0 then
b := b or fMaskENA;
fBuffer[fCursor] := b;
INC(fCursor);
if fCursor > fBufferSize - 1 then
Flush;
end;
// ================================================================================================
// Flush
// ================================================================================================
procedure TjtagBStream.Flush;
begin
if Assigned(fOnFull) then
fOnFull(self, fCEPMode);
fCursor := 0;
fCursorR := 0;
end;
function TjtagBStream.FlipByte(Data: byte): byte;
var
i: integer;
begin
result := 0;
for i:=0 to 7 do
begin
result := result shl 1;
if Data and $01 = $01 then
result := result or $1;
Data := Data shr 1;
end;
end;
// ================================================================================================
// Clear
// ================================================================================================
procedure TjtagBStream.Clear;
var
i: integer;
b: byte;
begin
b := 0;
if fValTCK <> 0 then
b := b or fMaskTCK;
if fValTMS <> 0 then
b := b or fMaskTMS;
if fValTDI <> 0 then
b := b or fMaskTDI;
if fValTRST <> 0 then
b := b or fMaskTRST;
if fValENA <> 0 then
b := b or fMaskENA;
for i := 0 to 1023 do
fBuffer[i] := b;
fCursor := 0;
end;
// ================================================================================================
// SendBit
// ================================================================================================
procedure TjtagBStream.SendBit(TDI: byte; TMS: byte);
begin
fValTDI := TDI;
fValTMS := TMS;
Pulse;
end;
// ================================================================================================
// SendByte
//
// Send entire byte to the device. If 'last' is 1, TMS will be high for the last bit transmitted,
// forcing transition to EXIT1 state. From EXIT1 state the TAP state will be moved to the specified
// end state, automatically.
// ================================================================================================
procedure TjtagBStream.SendByte(Value: byte; length: byte; last: boolean);
var
i: integer;
xtdi: byte;
xtms: byte;
val: byte;
begin
val := Value;
if (length > 0) and (length < 9) then
begin
for i := 0 to length - 1 do
begin
// xtdi := val and $01;
// val := val shr 1;
if val and $80 = $80
then xtdi := 1
else xtdi := 0;
val := val shl 1;
if last and (i = length - 1)
then xtms := 1
else xtms := 0;
SendBit(xtdi, xtms);
end;
if last then
begin
if fState = stDrShift then
begin
fState := stDrExit1;
SetState(fEndDR);
end
else if fState = stIrShift then
begin
fState := stIrExit1;
SetState(fEndIR);
end
end
end
end;
// ================================================================================================
// SendByte
//
// Send entire byte to the device. If 'last' is 1, TMS will be high for the last bit transmitted,
// forcing transition to EXIT1 state. From EXIT1 state the TAP state will be moved to the specified
// end state, automatically.
// ================================================================================================
procedure TjtagBStream.SendByte(TDI: byte; TDO: byte; SMASK: byte; MASK: byte;
length: word; last: boolean = false);
begin
end;
// ================================================================================================
// ReceiveByte
// ================================================================================================
function TjtagBStream.ReceiveByte(length: byte): byte;
var
i: integer;
begin
result := 0;
for i := 0 to length - 1 do
begin
if (fBuffer[fCursorR] and fMaskTDO) <> 0 then
result := result or (1 shl i);
INC(fCursorR, 2);
end;
end;
// @@@: Property Handlers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Property Handlers
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ================================================================================================
// GetData
// ================================================================================================
function TjtagBStream.GetData(i: word): byte;
begin
if i < 1024 then
result := fBuffer[i]
else
result := 0;
end;
// ================================================================================================
// SetData
// ================================================================================================
procedure TjtagBStream.SetData(i: word; d: byte);
begin
if i < 1024 then
fBuffer[i] := d;
// fBuffer[i] := d and fMaskTDO;
fCursor := 0;
end;
// ================================================================================================
// SetEndDR
// ================================================================================================
procedure TjtagBStream.SetEndDR(Value: TjtagTapState);
begin
if Value in [stReset, stIdle, stDrPause] then
fEndDR := Value;
end;
// ================================================================================================
// SetEndIR
// ================================================================================================
procedure TjtagBStream.SetEndIR(Value: TjtagTapState);
begin
if Value in [stReset, stIdle, stIrPause] then
fEndIR := Value;
end;
// @@@: Send SVF statements +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Send SVF statements
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ================================================================================================
// SendHTIDR
// ================================================================================================
procedure TjtagBStream.SendHTIDR(stmt: TsvfAstScan);
var
i: integer;
begin
// -------------------------------------------
// Header Instruction Register
// -------------------------------------------
if stmt.Inst = 'HIR' then
begin
fLenHIR := stmt.LenTDI;
fBitHIR := stmt.Bits;
for i := 0 to fLenHIR - 1 do
fBufHIR[i] := stmt.DataTDI[i]
// if stmt.LenTDI = stmt.LenSMASK
// then for i:=0 to fLenHIR -1 do fBufHIR[i] := stmt.DataTDI[i] and stmt.DataSMASK[i]
// else for i:=0 to fLenHIR -1 do fBufHIR[i] := stmt.DataTDI[i]
end
// -------------------------------------------
// Trailer Instruction Register
// -------------------------------------------
else if stmt.Inst = 'TIR' then
begin
fLenTIR := stmt.LenTDI;
fBitTIR := stmt.Bits;
for i := 0 to fLenTIR - 1 do
fBufTIR[i] := stmt.DataTDI[i]
// if stmt.LenTDI = stmt.LenSMASK
// then for i:=0 to fLenTIR -1 do fBufTIR[i] := stmt.DataTDI[i] and stmt.DataSMASK[i]
// else for i:=0 to fLenTIR -1 do fBufTIR[i] := stmt.DataTDI[i]
end
// -------------------------------------------
// Header Data Register
// -------------------------------------------
else if stmt.Inst = 'HDR' then
begin
fLenHDR := stmt.LenTDI;
fBitHDR := stmt.Bits;
for i := 0 to fLenHDR - 1 do
fBufHDR[i] := stmt.DataTDI[i]
// if stmt.LenTDI = stmt.LenSMASK
// then for i:=0 to fLenHDR -1 do fBufHDR[i] := stmt.DataTDI[i] and stmt.DataSMASK[i]
// else for i:=0 to fLenHDR -1 do fBufHDR[i] := stmt.DataTDI[i]
end
// -------------------------------------------
// Trailer Data Register
// -------------------------------------------
else if stmt.Inst = 'TDR' then
begin
fLenTDR := stmt.LenTDI;
fBitTDR := stmt.Bits;
for i := 0 to fLenTDR - 1 do
fBufTDR[i] := stmt.DataTDI[i]
// if stmt.LenTDI = stmt.LenSMASK
// then for i:=0 to fLenTDR -1 do fBufTDR[i] := stmt.DataTDI[i] and stmt.DataSMASK[i]
// else for i:=0 to fLenTDR -1 do fBufTDR[i] := stmt.DataTDI[i]
end
end;
// ================================================================================================
// SCAN
//
// Note: Scan statements may define TDO values to check the result from the device. The data length
// of these kind of statements must be less then 512 bits. The checking of the result will be
// done in thos routine, because the bstream will be fulshed before data sending, so the
// buffer will contain the data that must be checked. The event handler must fill then data
// buffer with the readed data.
// ================================================================================================
procedure TjtagBStream.Send(stmt: TsvfAstScan);
var
i: integer;
n: integer;
b: integer;
l: boolean;
s: string;
t: string;
x1: byte;
x2: byte;
zm : boolean;
d : boolean;
begin
if (stmt.Inst = 'HIR') or
(stmt.Inst = 'TIR') or
(stmt.Inst = 'HDR') or
(stmt.Inst = 'TDR') then
SendHTIDR(stmt)
// ---------------------------------------------------------------
// SIR
// ---------------------------------------------------------------
else if stmt.Inst = 'SIR' then
begin
// ----------------------------------------
// Move to IRSHIFT
// ----------------------------------------
fCEPMode := cmWrite;
State := stIrShift;
// ----------------------------------------
// If output checking is necessary, then
// first flush the stream.
// All SIR statement that needs checking
// must fit in one package.
// ----------------------------------------
if stmt.LenTDI = stmt.LenTDO then
begin
Flush;
fCEPMode := cmRead;
end;
// ----------------------------------------
// Send HIR
// ----------------------------------------
b := fBitHIR mod 8;
if b = 0 then
b := 8;
for i := 0 to fLenHIR - 1 do
if i <> fLenHIR - 1 then
SendByte(fBufHIR[i], 8)
else
SendByte(fBufHIR[i], b);
// ----------------------------------------
// Send SIR
// ----------------------------------------
b := stmt.Bits mod 8;
if b = 0 then
b := 8;
l := fBitTIR = 0;
n := (stmt.Bits +7) div 8;
// for i := 0 to stmt.LenTDI - 1 do
for i := 0 to n - 1 do
if i <> n - 1
then SendByte(stmt.DataTDI[i], 8)
else SendByte(stmt.DataTDI[i], b, l);
// ----------------------------------------
// Send TIR
// ----------------------------------------
b := fBitTIR mod 8;
if b = 0 then
b := 8;
for i := 0 to fLenTIR - 1 do
if i <> fLenTIR - 1
then SendByte(fBufTIR[i], 8)
else SendByte(fBufTIR[i], b, true);
// ----------------------------------------
if stmt.LenTDI = stmt.LenTDO then
begin
Flush;
// -------------------------------------
// Skip head data
// -------------------------------------
b := fBitHIR mod 8;
if b = 0 then
b := 8;
for i := 0 to fLenHIR - 1 do
if i <> fLenHIR - 1
then ReceiveByte(8)
else ReceiveByte(b);
// -------------------------------------
// Check result
// fBuffer contains the readed data.
// -------------------------------------
for i := 0 to stmt.LenTDI - 1 do
begin
if stmt.LenMASK = stmt.LenTDI then
begin
x1 := ReceiveByte(8) and stmt.DataMASK[i];
x2 := stmt.DataTDO[i] and stmt.DataMASK[i];
end
else
begin
x1 := ReceiveByte(8);
x2 := stmt.DataTDO[i];
end;
s := Format('SIR:[%2.2x, %2.2x]', [x1, x2]);
if Assigned(OnDump) then
OnDump( self, s);
Application.ProcessMessages;
end;
fCEPMode := cmWrite;
end;
end
// ---------------------------------------------------------------
// SDR
// ---------------------------------------------------------------
else if stmt.Inst = 'SDR' then
begin
n := (stmt.Bits +7) div 8;
// ----------------------------------------
// Move to DRSHIFT
// ----------------------------------------
fCEPMode := cmWrite;
State := stDrShift;
// ----------------------------------------
// If output checking is necessary, then
// first flush the stream.
// All SDR statement that needs checking
// can fit in one package.
// ----------------------------------------
if stmt.LenTDI = stmt.LenTDO then
begin
Flush;
fCEPMode := cmRead;
end;
// ----------------------------------------
// Send HDR
// ----------------------------------------
b := fBitHDR mod 8;
if b = 0 then
b := 8;
for i := 0 to fLenHDR - 1 do
if i <> fLenHDR - 1
then SendByte(fBufHDR[i], 8)
else SendByte(fBufHDR[i], b);
// ----------------------------------------
// Send SDR
// ----------------------------------------
b := stmt.Bits mod 8;
if b = 0 then
b := 8;
l := fBitTDR = 0;
// for i := 0 to stmt.LenTDI - 1 do
for i := 0 to n - 1 do
begin
if i <> n - 1
then SendByte(stmt.DataTDI[i], 8)
else SendByte(stmt.DataTDI[i], b, l);
Application.ProcessMessages;
end;
// ----------------------------------------
// Send TDR
// ----------------------------------------
b := fBitTDR mod 8;
if b = 0 then
b := 8;
for i := 0 to fLenTDR - 1 do
if i <> fLenTDR - 1
then SendByte(fBufTDR[i], 8)
else SendByte(fBufTDR[i], b, true);
// ----------------------------------------
// Check result if any
// ----------------------------------------
if (stmt.LenTDI = stmt.LenTDO) and (stmt.LenTDI < 129)then
begin
Flush;
// -------------------------------------
// Skip head data
// -------------------------------------
b := fBitHDR mod 8;
if b = 0 then
b := 8;
for i := 0 to fBitHDR - 1 do
if i <> n - 1
then x1 := ReceiveByte(8)
else x1 := ReceiveByte(b);
// -------------------------------------
// Check result
// fBuffer contains the readed data.
// -------------------------------------
s := '';
t := '';
// -------------------------------------
// If MASK is 0000...00 then don't mask
// the data. In this case, the data must
// be dumped only.
// It is a Read operation without check!
// -------------------------------------
zm := false;
if stmt.LenMASK = stmt.LenTDO then
begin
zm := true;
for i:=0 to n-1 do
if stmt.DataMASK[i] <> 0 then
begin
zm := false;
break;
end;
end;
for i := 0 to n - 1 do
begin
if (stmt.LenSMASK = stmt.LenTDI) and (not zm)
then x1 := ReceiveByte(8) and FlipByte(stmt.DataSMASK[i])
else x1 := ReceiveByte(8);
if (stmt.LenMASK = stmt.LenTDO) and (not zm)
then x2 := stmt.DataTDO[i] and FlipByte(stmt.DataMASK[i])
else x2 := stmt.DataTDO[i];
s := Format('%2.2x',[(x1)]) +s;
t := Format('%2.2x',[(x2)]) +t;
Application.ProcessMessages;
end;
if Assigned(fOnDump) then
begin
// if mask is zero, then simply dump data ...
if zm then
fOnDump( self, s)
// ... else check for difference
else begin
d := false;
for i:=1 to Length(s) do
begin
x1 := ord(s[i]);
x2 := ord(t[i]);
if ((x1 and x2) <> x2) and (x2 <> 0) then
begin
d := true;
break
end;
end;
if d then
begin
fOnDump(self,':: '+t);
fOnDump(self,'>> '+s);
end;
end;
end;
fCEPMode := cmWrite;
end;
Application.ProcessMessages;
end
end;
// ================================================================================================
// RUNTEST
// ================================================================================================
procedure TjtagBStream.Send(stmt: TsvfAstRuntest);
begin
Pulse(StrToInt(stmt.RunCount));
end;
// ================================================================================================
// STATE
// ================================================================================================
procedure TjtagBStream.Send(stmt: TsvfAstState);
var
i: integer;
begin
for i := 0 to stmt.StateCount - 1 do
begin
case stmt.States[i] of
0: State := jtag.bstream.stReset;
1: State := jtag.bstream.stIdle;
end
end;
end;
end.