TCPIP device Gen4

Introduced in version 3.8.1

Partially implemented; the complete Gen4 interface is planned for version 4.

TCPIP device Gen4 is a TCPIP interface between SpecMan4EPR and compatible TCPIP server. All functions of SpecMan4EPR are streamed to this device. TCPIP device Gen4 allows to write custom device code. Current function of this driver is to study SpecMan-device interface.

TCPIP device connects to a server, retrieve device description and control the communication.

The exchange protocol has two packet types and two modes - with handshake and without. The simple packet delivers a value of a single property. Large packet transfers a buffer with data. The exchange with handshake forces SpecMan4EPR to wait for device's response.

The TCPIP driver can be only partially configured using Device Configuration dialog. The presence of device properties is defined by setting corresponding entries in the device section of Device Configuration (CFG)

Packet structure (LSB first)
Field Format Description
Property number int32 Negative values are special commands, 0...n are regular properties
Flags uint32 LSB: data type. empty = 0, int32 = 1, float32 = 2, double64 = 3, string = 4, binary = 5,
error = 100, device object = 101,
int32 array = 11, double32 array = 12, float32 array = 13.
MSB: protocol. dfNoFlags = 0x00, dfHandshake = 0x40 timely response is requested, dfGetDataCommand - transient data return.
Size uint64 Size of the buffer
Checksum uint16 Checksum for first 16 bytes. MSB: add even bytes. LSB: add odd bytes.
Buffer n bytes Payload. For data types 0 and 1 must be 4. For array types: dimensions (int32*6) array sizeof(type)*product of dims

 

Communication protocol. SM: SpecMan4EPR (client). DEV: device (server). P = Packet. Arguments: (PropertyNumber, Flag, Value), dfFormat is any of int32, float32, double64, string, dfArray is any of array formats
Operation Actions
Initialization

SM->DEV: P(-500, dfHandshake|empty).

DEV->SM: P(-500, dfHandshake, 1 - ready, 0 - not ready).

DEV->SM: P(-600, device object, all device components: properties, config keys etc).

DEV->SM: P(-601, int32, device status) optional

De-Initialization

SM->DEV: SP(-501, dfNoFlag|empty).

Send value (with handshake)

SM->DEV: SP(Property Number, dfHandshake|dfFormat, Value).

DEV->SM: SP(Property Number, dfHandshake|dfFormat, Return Value).

Send value (EOP - end of programming)

SM->DEV: P(Property Number 1, dfNoFlags|dfFormat, Value).

SM->DEV: P(Property Number 2, dfNoFlags|dfFormat, Value).

SM->DEV: P(-1102, dfHandshake|empty) - initiate action.

DEV->SM: P(-1102, dfHandshake|empty).

Get value (with handshake)

SM->DEV: P(Property Number, dfHandshake|empty).

DEV->SM: P(Property Number, dfHandshake|dfFormat, Return Value).

SM: Value is received.

Pulse

SM->DEV: P(-1105, binary, Payload)

StartOfSequence

SM->DEV: P(-1106, binary, Payload)

EndOfSequence

SM->DEV: P(-1107, binary, Payload)

dcSendProgram2Device

SM->DEV: P(-1101, binary, Payload)

Acquisition protocol

SM->DEV: P(-1005, binary, Trace|TriggerPerSequence|Triggers|Shots(int32x4)).

Transient array

SM->DEV: P(-1000, empty). Arm.

DEV->SM: P(Property Number, dfArray|dfGetDataCommand, Array) - when ready.

 

Device object (-600)

During initialization the device returns its description in packet P(-600, device object). The payload is a UTF-8 JSON document. An empty payload (or {}) means the device exposes no components. The document has three optional arrays, properties, configKeys and channels.

Each property entry has a field (the property name) and a definition string. The full property is formed as "<field>, <definition>" and parsed exactly like a Dummy device property definition (see Device Configuration): <unit>, <access>, <protocol>, <increment>, <min_increment>, <significant digits>, <minvalue>, <maxvalue>. Access is one of read/write/rwrite/wread/aread/awrite/arwrite/awread/a; protocol is nohshake or hshake. Value fields accept SI-prefixed units (e.g. 1MHz). For a select property leave the unit empty and list the choices after the protocol.

Each config-key entry has key, default and help.

Each channels entry defines one pulse output of the built-in pulse engine. An entry is either a plain string (the channel name) or an object { "name", "cap" } where cap is the trace capacity in points (default 1024). The order of the array is significant: a channel's index is its bit position in the program word sent on dcSendProgram2Device. A synchronization helper output named Sync is appended automatically when at least one channel is declared.

{
  "properties": [
    { "field": "Frequency",
      "definition": "Hz, rw, nohshake, 1MHz, 1Hz, 0, 0, 10GHz" },
    { "field": "Mode",
      "definition": ", write, nohshake, CW, Pulse" }
  ],
  "configKeys": [
    { "key": "Range", "default": "1", "help": "measurement range" }
  ],
  "channels": [
    "Ch0", "Ch1",
    { "name": "TWT", "cap": 4096 }
  ]
}

 

Pulse program (-1101)

When the device declares channels the driver runs a software-trigger pulse engine. On dcSendProgram2Device it uploads the whole sequence as a UTF-8 JSON binary payload: dwell (board clock period, s) and a sequence array. Each sequence event carries flags (the output word, one bit per channel, decimal) and length (duration in dwell units). To keep the packet small, inst and data are omitted when they are zero, so a plain delay is just { "flags", "length" }.

Sequence event instructions (inst)
instMeaningdata
0 (omitted)continue: hold flags for length clocks
1stop: end of program
2repeat: begin a loopnumber of repetitions
3goto: jump back to the loop starttarget event address (index in sequence)
8wait for external trigger

A missing data is read as 0.

A missing length is read as 1.

{ "dwell": 4e-9,
  "sequence": [
    { "flags": 0, "inst": 2, "data": 100},
    { "flags": 1, "length": 25 },
    { "flags": 0, "length": 50 },
    { "flags": 1, "length": 25 },
    { "flags": 0, "inst": 3, "data": 0 },
    { "flags": 0, "inst": 1}
  ]
}