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)
| 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 |
| 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 }
]
}
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" }.
inst | Meaning | data |
|---|---|---|
| 0 (omitted) | continue: hold flags for length clocks | — |
| 1 | stop: end of program | — |
| 2 | repeat: begin a loop | number of repetitions |
| 3 | goto: jump back to the loop start | target event address (index in sequence) |
| 8 | wait 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}
]
}

