Panda Server¶
The Panda socket server provides a bridge between the register interface to the FPGA firmware controlling the Panda hardware and users and other software. The interface provided by this server is designed to be simple and robust.
The Panda firmware is structured into numerous functional blocks, with each block configured via a number of fields. This structure is directly reflected in the functional interface provided by this server: most commands read or write specific fields.
The socket server publishes two socket end points, one for configuration control the other for streamed data capture. The configuration control socket accepts simple ASCII commands and returns all data in readable ASCII format. The data capture socket supports no commands and simply streams captured data in a lightly structured binary format.
Configuration Interface¶
Configuration commands are sent as newline (ASCII character 0x0A) terminated strings and all responses are also newline terminated. Three basic forms of command are accepted:
- Query commands.
- These commands must be terminated by a single
?
character. The three possible responses are: an error message, a single value, or a list of values. - Assignment commands.
- These commands contain an
=
character, and are used for assigning values to fields. The two possible responses are an error message orOK
. - Table assignment.
- Any command containing a
<
character (not preceded by?
or=
) is a table assignment command. The initial command may be followed by any number of lines of text, and must be terminated by an empty line. The two possible responses are an error message orOK
.
The four possible responses are:
ERR
error-message- An error response is always sent as
ERR
followed by an error message. OK
- Successful completion of either form of assignment command generates the
OK
response. OK =
value- Successful completion of a query command returning a single value returns
the value preceded by
OK =
. - Multi-line response
- Successful completion of a query command returning multiple values returns
each value on a line by itself starting with
!
and ends the sequence with a line containing only.
.
Example Commands¶
In the examples below, the command sent is shown preceded by <
and the
response with >
: this is the syntax used by the helper tool
simulation/tcp_client.py
:
Simple server identification command including version information:
< *IDN?
> OK =PandA SW: 330bd94-dirty FPGA: 0.1.9 d1275f61 00000000
Interrogate list of fields provided by the TTLIN
block:
< TTLIN.*?
> !VAL 0 bit_out
> !TERM 1 param enum
> .
Interrogate input termination for TTLIN1
:
< TTLIN1.TERM?
> OK =High-Z
Set input termination:
< TTLIN1.TERM=50-Ohm
> OK
Streaming Capture Interface¶
All bit and position values received and generated by PandA can be captured on an internally generated trigger and streamed to a data capture port. A variety of data capture, processing, and delivery options can be selected.
Building¶
Before running make
first copy the file CONFIG.example
to CONFIG
and
edit according to your needs. If you wish to build the server or the driver
then a Zynq cross-compiler will be needed, and if you wish to build the driver
then a pre-build kernel will be needed – for this reference PandABlocks-rootfs and build the kernel
target.
The panda-server Makefile supports four main build targets:
driver
- This builds the kernel driver required by the target server to communicate
with the FPGA hardware. This target can only be built if the cross-compiler
is on the path or
BINUTILS_DIR
has been configured inCONFIG
to point to the directory containing the cross-compiler, and ifKERNEL_DIR
has been set to the location of a cross-build of the kernel previously generated byPandABlocks-rootfs
. The built driver is placed in$(BUILD_DIR)/driver/panda.ko
. server
- This builds the PandA socket server to run on the target Zynq system.
This target can only be built if the cross-compiler is installed as for
driver
, but there is no dependency on the kernel build. The built server is placed in$(BUILD_DIR)/server/server
. sim_server
- This builds the simulation version version of the PandA socket server. To
run the server run the script
simserver
in the root directory. docs
- This builds the documentation and places the results in
$(BUILD_DIR)/docs/html
.
Command Interface¶
The default server port for the command interface is port 8888. All commands and responses are in ASCII with lines separated with newline characters (ASCII character 0x0A).
All commands can be grouped into three forms (query, assignment, table assignment) and two targets (system and fields). There exactly four possible response formats (ok, ok with value, error, multiple value). This section describes this command interface.
The three basic command forms are:
Name | Format | Description |
---|---|---|
Query | target? |
Interrogates target for current value, can return error, single value or a list of multiple values. |
Assignment | target= value |
Updates target with given value, can return error or success. |
Table | target< format |
Command may be followed by lines of text, must be terminated by blank line. |
The four basic command responses are:
Name | Format | Description |
---|---|---|
Success | OK |
Returned assignment and table commands to report successful update. |
Value | OK = value |
Successful return of single value from query command. |
Error | ERR error |
Error string returned on any command failure |
Multi value | ! value. |
Any number of values can be returned, each
preceded by ! , and finally . by
itself indicates end of input. |
Command forms and their possible responses:
Form | Responses |
---|---|
Query | Error, Value, Multi value |
Assignment | Error, Success |
Table | Error, Success |
Each individual query target will either return a single value or multi-value, as documented below.
Finally, there are two basic types of target: configuration commands and system commands.
Configuration Commands¶
The entire hardware interface to PandA is structured into “blocks” and “fields”, and each field may have a number of “attributes” depending on the field type. This structure is reflected in the form of configuration commands which are tabulated below:
Command Syntax | Description |
block[number]. field? |
Return current value of field. |
block[number]. field= value |
Assign value to field. |
block[number]. field< [< ][B ] |
Write table data to field. |
block[number]. field. attr? |
Return current value of field attribute. |
block[number]. field. attr= value |
Assign value to field attribute. |
block[number].*? |
Returns list of fields. |
block[number]. field.*? |
Returns list of field attributes. |
In all of these commands the number after the block is optional if there is only
one instance of that block, and is ignored for the two .*?
commands. See
the description of the .TABLE
fields for an explanation of the optional
format characters in the table write command.
System Commands¶
All system commands are prefixed with a leading *
character. The simplest
command is *IDN?
which returns a system identification string:
< *IDN?
> OK =PandA SW: 330bd94-dirty FPGA: 0.1.9 d1275f61 00000000
The available system commands are tabulated here and listed in more detail below:
Command | Description |
*IDN? |
Device identification. |
*ECHO string? |
Echo. |
*WHO? |
List connected clients. |
*BLOCKS? |
List device blocks. |
*DESC. block. field[. attr]? *DESC. block. field[]. subfield? |
Show description for field, attribute, or table subfield. |
*ENUMS. block. field[. attr]? *ENUMS. block. field[]. subfield? |
List enumerations for field, attribute, or table subfield. |
*CHANGES [. group]? |
Report changes to values. group can be
any of CONFIG , BITS , POSN ,
READ , ATTR , or TABLE . |
*CHANGES [. group]= [E | S ] |
Reset reported changes, group as above. |
*CAPTURE? |
Report fields configured for capture. |
*CAPTURE.*? |
List all fields that can be captured. |
*CAPTURE. name? |
Interrogate capture options, name can be
OPTIONS or ENUMS . |
*CAPTURE= |
Reset data capture. |
*POSITIONS? |
Enumerate possible capture positions. |
*BITS? |
Enumerate possible bit bus positions. |
*VERBOSE= value |
Control command logging. |
*PCAP. field? |
Special position capture status fields.
field can be any of STATUS ,
CAPTURED , or COMPLETION . |
*PCAP. field= |
Position capture actions. field can be
either ARM , or DISARM . |
*SAVESTATE= |
Triggers immediate save to file of the persistence file state. |
*CLOCK_FREQ? |
Returns currently configured system clock frequency |
*IDN?
Returns system identification string, for example the following:
OK =PandA SW: 1.1 FPGA: 0.1.9 d1275f61 00000000 rootfs: PandA 1.1
The first field after “PandA” is the software version, the second field is the FPGA version, the third the firmware build number, and the fourth field identifies the supporting firmware. The final fields (prefixed
rootfs:
) identify the underlying system on which the server is running.Note that the
rootfs:
identification is new to version 1.1 of PandA.*ECHO string?
Returns string back to caller. Not terribly useful. Note that the echoed string cannot contain any of
?
,=
or<
characters, as this would cause the command to be mistaken for another command format! Example usage:< *ECHO This is a test? > OK =This is a test
*WHO?
Returns list of client connections, for example:
< *WHO? > !2015-12-04T14:30:40.403Z config 127.0.0.1:34185 > .
The first field is the time the connection was made, the second field is either
config
ordata
depending on whether the configuration or data port is connected, and the third field is the remote IP address and socket.*BLOCKS?
Returns a list of all the top level blocks in the system. The order in which the blocks is returned is somewhat arbitrary. For example (here the list has been shortened in the middle):
< *BLOCKS? > !TTLIN 6 > !OUTENC 4 ... > !CLOCKS 1 > !BITS 1 > !QDEC 4 > .
Block and field commands can be used to interrogate each block. The number after each block records the number of instances of each block.
*DESC.
block?
*DESC.
block.
field?
*DESC.
block.
field.
attr?
*DESC.
block.
field[].
subfield?
Returns description string for specified block, field, attribute, or table subfield eg:
< *DESC.TTLIN? > OK =TTL input < *DESC.TTLIN.TERM? > OK =Select TTL input termination < *DESC.TTLIN.TERM.INFO? > OK =Class information for field
*ENUMS.
block.
field?
*ENUMS.
block.
field.
attr?
*ENUMS.
block.
field[].
subfield?
Returns list of enumerations for given field, attribute, or table subfield, if appropriate.
*CHANGES?
*CHANGES.CONFIG?
*CHANGES.BITS?
*CHANGES.POSN?
*CHANGES.READ?
*CHANGES.ATTR?
*CHANGES.TABLE?
Reports changes to the appropriate group of values. Changes are reported since the last request on the connection, and on the first request the current value for every field will be reported. The
*CHANGES?
command reports changes for all groups, otherwise one of the following groups can be selected:
CONFIG Configuration settings BITS Bits on the system bus POSN Positions READ Polled read values ATTR Attributes (included capture enable flags) TABLE Table changes For example:
< *CHANGES.CONFIG? > !TTLIN1.TERM=High-Z > !TTLIN2.TERM=50-Ohm > !TTLIN3.TERM=High-Z ... > !QDEC2.B=TTLIN1.VAL > !QDEC3.B=TTLIN1.VAL > !QDEC4.B=TTLIN1.VAL > .Here 804 (at the time of writing) lines have been deleted from the transcript! Now if we repeat the call we see that no further changes have happened until something is actually changed:
< *CHANGES.CONFIG? > . < TTLOUT4.VAL=TTLIN3.VAL > OK < *CHANGES.CONFIG? > !TTLOUT4.VAL=TTLIN3.VAL > .Note that for tables only the fact that the table has changed is shown, no attempt is made to show the current table value:
< *CHANGES.TABLE? > !PCOMP1.TABLE< > !PCOMP2.TABLE< > !PCOMP3.TABLE< > !PCOMP4.TABLE< > !PGEN1.TABLE< > !PGEN2.TABLE< > !SEQ1.TABLE< > !SEQ2.TABLE< > !SEQ3.TABLE< > !SEQ4.TABLE< > .
*CHANGES=
[E
| S
]*CHANGES.CONFIG=
[E
| S
]*CHANGES.BITS=
[E
| S
]*CHANGES.POSN=
[E
| S
]*CHANGES.READ=
[E
| S
]*CHANGES.ATTR=
[E
| S
]*CHANGES.TABLE=
[E
| S
]These commands reset the change information for the corresponding group of information so that only changes occuring after the reset are reported, or so that all changes are reported. If
=
or=E
(for End) is specified then only new changes are reported, if=S
(for Start) then change reporting is reset to the start as for a new connection. For example:< TTLIN1.TERM=50-Ohm > OK < *CHANGES= > OK < *CHANGES.CONFIG? > .
*CAPTURE?
- This returns a list of all positions and bit masks that will be written to
the data capture port. This list is controlled by setting the
.CAPTURE
attribute on the corresponding position fields. *CAPTURE.*?
- This returns a list of all fields that can be configured for capture. This
includes all
pos_out
andext_out
fields. *CAPTURE.OPTIONS?
- Lists the available capture options for
pos_out
fields. The available options are “Value”, “Diff”, “Sum”, “Mean, “Min”, “Max”, “StdDev”. Availability of the last option “StdDev” depends on the FPGA configuration. *CAPTURE.ENUMS?
- Generates a curated list of capture option selections. This is designed to
be used for presenting lists of available capture options as an enumeration.
Returns the same as calling
*ENUMS.
name.
field.CAPTURE?
on anypos_out
field. *CAPTURE=
- This resets all
.CAPTURE
flags to zero so that no data will be captured. *POSITIONS?
- This command lists all available position capture fields in order.
*BITS?
- This command lists all available bit bus positions, but not including the
special values
ZERO
andONE
. *VERBOSE=
value- If
*VERBOSE=1
is set then every command will be echoed to the server’s log. Set*VERBOSE=0
to restore normal quiet behaviour.
*PCAP.STATUS?
*PCAP.CAPTURED?
*PCAP.COMPLETION?
Interrogates status of position capture:
STATUS Returns string with three fields: “Busy” or “Idle”, followed by the number of connected readers, and the number taking data. CAPTURED Returns number of samples captured in the current or most recent data capture. COMPLETION Returns completion status from most recent data capture, as listed in the table below. The completion codes have the following meaning:
Busy Capture in progress. Ok Capture completed without error or intervention. Disarmed Capture was manually disarmed by *PCAP.DISARM=
command.Framing error Data capture framing error, probably due to incorrectly configured capture. DMA data error Internal data error, should not occur. Driver data overrun Data capture too fast, internal buffers overrun. Can also occur if PandA processor overloaded.
*PCAP.ARM=
*PCAP.DISARM=
Top level capture control:
ARM Initiates data capture. Will fail if capture already in progress, or no fields configured for capture. DISARM Halts ongoing data capture.
*SAVESTATE=
- Updates the persistence state file (as configured on the command line when
launched) with the current state. Returns after a file system
sync
call, so it is safe to power-off the system after this command has completed. *CLOCK_FREQ?
- Returns currently configured FPGA clock frequency as used to convert between times in natural units and times in clock ticks.
Blocks, Fields and Attributes¶
The set of hardware blocks can be interrogated with the *BLOCKS?
command:
< *BLOCKS?
> !TTLIN 6
> !OUTENC 4
> !PCAP 1
> !PCOMP 4
> !TTLOUT 10
> !ADC 8
> !DIV 4
> !INENC 4
> !SLOW 1
> !PGEN 2
> !LVDSIN 2
> !POSITIONS 1
> !POSENC 4
> !SEQ 4
> !PULSE 4
> !SRGATE 4
> !LUT 8
> !LVDSOUT 2
> !COUNTER 8
> !ADDER 1
> !CLOCKS 1
> !BITS 1
> !QDEC 4
> .
For each block the number after the block tells us how many instances there are
of the block. Each block is controlled and interrogated through a number of
fields, and the block.*?
command can be used to interrogate the list of
fields:
< TTLIN.*?
> !VAL 1 bit_out
> !TERM 0 param enum
> .
This tells us that block TTLIN
has two fields, TTLIN.VAL
and
TTLIN.TERM
. The first field after the field name is a sequence number for
user interface display, and the rest of each response describes the “type” of
the field. In this case we see that TTLIN.VAL
is a bit_out
field, which
means can be used for bit data capture and can be connected to any param
bit_mux
field as a data source.
Each field has one or more attributes depending on the field type. The list of
attributes can be interrogated with the block.
field.*?
command:
< TTLIN.VAL.*?
> !CAPTURE_WORD
> !OFFSET
> !INFO
> .
< TTLIN.TERM.*?
> !INFO
> .
All fields have the .INFO
attribute, which just repeats the type information
already reported, eg TTLIN1.VAL.INFO?
returns bit_out
(note that a block
number must be specified when interrogating fields and attributes).
Field Types¶
Each field type determines the set of attributes available for the field. The types and their attributes are documented below.
Field type | Description |
---|---|
param subtype |
Configurable parameter. The subtype determines the precise behaviour and the available attributes. |
read subtype |
A read only hardware field, used for monitoring status. Again, subtype determines available attributes. |
write subtype |
A write only field, subtype determines possible values and attributes. |
time |
Configurable timer parameter. |
bit_out |
Bit output, can be configured as bit input for bit_mux
fields. |
pos_out |
Position output, can be configured for data capture and as
position input for pos_mux fields. |
ext_out extra |
Extended output values, can be configured for data capture, but not available on position bus. |
bit_mux |
Bit input with configurable delay. |
pos_mux |
Position input multiplexer selection. |
table |
Table data with special access methods. |
param
subtype- All fields of this type contribute to the
*CHANGES.PARAM
change group and are used to configure the behaviour of the corresponding block. Fields of this type are used for input configuration and other behavioural settings. read
subtype- All fields of this type contribute to the
*CHANGES.READ
change group, but are only checked when either the field is read or the change group is polled. Fields of this type are used for monitoring the internal status of a block, and they cannot be written to. write
subtypeFields of this type can only be written and are used for immediate actions on a block. The
action
subtype is used to support actions without any parameters, for example the following command forces a soft reset on the given pulse block:< PULSE1.FORCE_RESET= > OK
time
Fields of this type are used for configuring delays. They also contribute to
*CHANGES.PARAM
. The following attributes are supported by fields of this type:UNITS
- This attribute can be set to any of the strings
min
,s
,ms
, orus
, and is used to interpret how values read and written to the field are interpreted. RAW
- This attribute can be read or written to report or set the delay in FPGA ticks.
MIN
- This reports the minimum valid value for this field in the currently selected units.
The
UNITS
attribute determines how numbers read or written to the field are interpreted. For example:< PULSE1.DELAY.UNITS=s > OK < PULSE1.DELAY=2.5 > OK < PULSE1.DELAY.RAW? > OK =312500000 < PULSE1.DELAY.UNITS=ms > OK < PULSE1.DELAY? > OK =2500
Note that changing
UNITS
doesn’t change the delay, only how it is reported and interpreted.bit_out
Fields of this type are used for block outputs which contribute to the internal bit system bus, and they contribute to the
*CHANGES.BITS
change group. They can be captured via the appropriatePCAP.BITS
n block as reported by theCAPTURE_WORD
attribute.The following attributes are supported by fields of this type:
CAPTURE_WORD
- This identifies which
pos_out
value can be used to capture this bit. OFFSET
- This is the bit offset into the captured word of this particular bit.
For example:
< TTLIN1.VAL.CAPTURE_WORD? > OK =PCAP.BITS0 < TTLIN1.VAL.OFFSET? > OK =2
This tells us that if
PCAP.BITS0
is captured thenTTLIN1.VAL
can be read as bit 2 of this word, counting from the least significant bit.The field itself can be read to return the current value of the bit.
pos_out
Fields of this type are used for block outputs which contribute to the internal position bus, and they contribute to the
*CHANGES.POSN
change group. The following attributes support capture control:CAPTURE
This can be set to manage capture of this field. One of the following enumeration values can be written to this field:
Value Description No Capture is disabled for this field. Value The value at the time of trigger will be captured. Diff The difference of values is captured. Sum The sum of all valid values is captured. This is a 64-bit value, and may be further scaled if PCAP.SHIFT_SUM
is set.Mean The average of all valid values is captured. Min The minimum of all valid values is captured. Max The maximum of all valid values is captured. Min Max Both minimum and maximum values are captured. Min Max Mean All three values, minimum, maximum, average are captured.
The following attributes support formatting of the field when reading it: the current value is returned subject to the formatting rules described below.
OFFSET
,SCALE
- These numbers can be set to configure the conversion from the underlying
position to the value captured when scaling is enabled and read from the
SCALED
attribute. UNITS
- This field can be set to any UTF-8 string, and is provided for the convenience of the user interface and is returned as part of the data capture heading.
SCALED
This returns the scaled value computed as
value * scale + offset
ext_out
extraFields of this type represent values that can be captured but which are not present on the position bus. These fields also support one capture control field:
CAPTURE
As for
pos_out
, can be set to control capture of this field:Value Description No This field will not be captured. Value This field will be captured.
The extra field determines the detailed behaviour of this field, and will be one of the following values:
extra value Description timestamp
Timestamps in clock ticks with optional scaling to seconds on data capture. samples
Special internal field for counting captured samples. bits
Used to implement bit-bus readout fields. Fields of this sub-type implement an extra BITS
field.Fields of type
ext_out bits
implement an extra attribute:BITS
- This returns a list of all bit fields associated with this field. Fields of this type can be used to capture a snapshot of the bit bus at the trigger time.
bit_mux
Bit input selectors for blocks. Each of these fields can be set to the name of a corresponding
bit_out
field, for example:< TTLOUT1.VAL=TTLIN1.VAL > OK
There are two attributes:
DELAY
- This can be set to any value between 0 and
MAX_DELAY
to delay the bit input to the block by the specified number of clock ticks. MAX_DELAY
- This returns the maximum delay that can be set for this input.
pos_mux
Position input selectors for blocks. Each of these fields can be set to the name of a corresponding
pos_out
field, for example:< ADDER1.INPA=ADC2.OUT > OK
table
Values of this type are used for long tables of numbers. This server imposes no structure on these values apart from treating them as an array of 32-bit integers.
Tables values are written with the special
<
syntax:block number .
field<
Normal table write, overwrite table block number .
field<<
Normal table write, append to table block number .
field<B
Base-64 table write, overwrite table block number .
field<<B
Base-64 table write, append to table For “normal” table writes the data is sent as a sequence of decimal numbers in ASCII, and the whole sequence must be terminate by an empty blank line. For base-64 writes the data is sent in base-64 format, for example:
< SEQ3.TABLE<B < TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1 < > OK < SEQ3.TABLE.LENGTH? > OK =12
Note that when data is sent in base-64 format, each individual line must encode a multiple of four bytes, otherwise the write will be rejected.
The following attributes are provided by this field type:
MAX_LENGTH
- This is the maximum number of 32-bit words which can be stored in the table.
LENGTH
- This is the current number of words in the table.
B
- This read-only attribute returns the content of the table in base-64.
FIELDS
This returns a list of strings which can be used to interpret the content of the table. Each line returned is of the following format:
left:right field-name subtype
Here left and right are bit field indices into a single table row, consisting of a number of 32-bit words concatenated (in little-endian order) with bits numbered from 0 in the least significant position up to 32*
ROW_WORDS
-1, and left >= right. The name of the field is given by field-name, and subtype can be one ofint
,uint
, orenum
. If subtype isenum
then the list of enums can be interrogated through the command*ENUMS.block.table[].field?
where block, table, field are appropriate names.
ROW_WORDS
- Returns the number of 32-bit words in a single row of the table. This
can be used to help interpret the
FIELDS
result.
Field Sub-Types¶
The following field sub-types can be used for param
, read
and write
fields.
uint
[max-value]This is the most basic type: the value read or written is an unsigned 32-bit number. There is one fixed attribute:
MAX
- This returns the maximum value that can be written to this field.
int
- Similar to
uint
, but signed, and there is no upper limit on the value. scalar
scale [offset [units]]Floating point values can be read or written, and are converted from and to the underlying signed integer type via the equations below:
value = scale * raw + offsetraw = (value - offset) / scaleThe following attributes are supported:
UNITS
- Returns the configured units string.
RAW
- Returns the underlying unconverted integer value.
SCALE
- Returns the configured scaling factor.
OFFSET
- Returns the configured scaling offset.
bit
- A value which is 0 or 1, there are no extra attributes.
action
- A value which cannot be read and always writes as 0. Only useful for
write
fields. lut
This field sub-type is used for the 5-input lookup table function calculation field. This field can be set to any valid logical expression generated from inputs
A
toE
using the standard operators&
,|
,^
,~
,?:
from C together with=
for equality and=>
for implication (A=>B
abbreviates~A|B
). All operations have C precedence,=
has the same precedence as==
in C, and=>
has precedence between|
and?:
.The following attribute is supported:
RAW
- This returns the corresponding lookup table assignment as a 32-bit number.
For example:
< LUT2.FUNC=A=>B?C:D > OK < LUT2.FUNC? > OK =A=>B?C:D < LUT2.FUNC.RAW? > OK =0xF0CCF0F0
enum
Enumeration fields define a list of valid strings which can be written to the field. To interrogate the list of valid enumeration values use the
*ENUMS
command, for example:< *ENUMS.TTLIN1.TERM? > !High-Z > !50-Ohm > .
time
Converts between time in specified units and time in FPGA clock ticks. The following attributes are supported:
UNITS
- This attribute can be set to any of the strings
min
,s
,ms
, orus
, and is used to interpret how values read and written to the field are interpreted. RAW
- This attribute can be read or written to report or set the delay in FPGA ticks.
Summary of Sub-Types¶
Sub-type | Attributes | Description |
---|---|---|
uint | MAX | Possibly bounded 32-bit unsigned integer value |
int | Unbounded 32-bit signed integer value | |
scalar | RAW, UNITS, SCALE, OFFSET | Scaled signed floating point value |
bit | Bit: 0 or 1 | |
action | Write only, no value | |
lut | RAW | 5 input lookup table logical formula |
enum | LABELS | Enumeration selection |
time | RAW, UNITS | Time intervals converted to FPGA ticks |
Summary of Attributes¶
Field (sub)type | Attribute | Description | R | W | C | M |
---|---|---|---|---|---|---|
(all) | INFO | Returns type of field | R | |||
uint | MAX | Maximum allowed integer value | R | |||
scalar | RAW | Underlying integer value | R | W | ||
UNITS | Configured units for scalar | R | ||||
SCALE | Configured scaling factor for scalar | R | ||||
OFFSET | Configured scaling offset for scalar | R | ||||
lut | RAW | Computed Lookup Table 32-bit value | R | |||
time | UNITS | Units and scaling selection for time | R | W | C | |
RAW | Raw time in FPGA clock cycles | R | W | |||
MIN | Minimum valid setting (for type only) | R | ||||
bit_out | CAPTURE_WORD | Capturable word containing this bit | R | |||
OFFSET | Offset of this bit in captured word | R | ||||
bit_mux | DELAY | Bit input delay in FPGA ticks | R | W | C | |
MAX_DELAY | Maximum valid delay | R | ||||
pos_out | CAPTURE | Position capture control | R | W | C | |
OFFSET | Position offset | R | W | C | ||
SCALE | Position scaling | R | W | C | ||
UNITS | Position units | R | W | C | ||
SCALED | Position after applying scaling | R | ||||
ext_out bits | BITS | List of bit_out fields | R | M | ||
table | MAX_LENGTH | Maximum table row count | R | |||
LENGTH | Current table row count | R | ||||
B | Table data in base-64 | R | M | |||
FIELDS | Table field descriptions | R | M | |||
ROW_WORDS | Number of words in a table row | R |
- Key:
R: Attribute can be read W: Attribute can be written C: Attribute contributes to *CHANGES.ATTR
change setM: Attribute returns multiple value result.
Data Capture¶
Capture Configuration¶
Both pos_out
and ext_out
fields can be configured for data capture
through the data capture port by setting the appropriate value in the
CAPTURE
attribute. The possible capture settings depend on the field type
as follows:
pos_out
Value Description No Capture is disabled for this field. Value The value at the time of trigger will be captured. Diff The difference of values is captured. Sum The sum of all valid values is captured. This is a 64-bit value, and may be further scaled if PCAP.SHIFT_SUM
is set.Mean The average of all valid values is captured. Min The minimum of all valid values is captured. Max The maximum of all valid values is captured. Min Max Both minimum and maximum values are captured. Min Max Mean All three values, minimum, maximum, average are captured. ext_out
Value Description No This field will not be captured. Value This field will be captured.
Data Capture Port¶
The default server port for the data interface is port 8889. The initial exchange is in ASCII with newline separated lines, subsequent data communication is as selected in the initial connection.
Data capture proceeds as follows:
- Connection to the data server port, default 8889.
- Send capture options string followed by newline. The newline character is mandatory.
- The server will respond with
OK
unless there was an error parsing the capture options, or if theNO_STATUS
option was specified. If there was an error then the server responds withERR
followed by an error message and the connection is closed. - The server will now ignore all further input from the client, and the
connection will pause until data capture is started via the
*PCAP.ARM=
command. - At the beginning of a round of data capture or “experiment”, a header
detailing the data to be sent and data format is sent in ASCII followed by
an empty line. If
NO_HEADER
was selected then the header and blank line are omitted. - Captured data is sent in the requested format until the experiment is
complete (either internally disarmed or disarmed via the
*PCAP.DISARM=
command), or there is a communication problem. - At the end of the experiment a completion code is sent as a single line in
ASCII starting with
END
, unlessNO_STATUS
was specified. - Unless
ONE_SHOT
was specified the server will pause until the next experiment (step 4).
Capture Options¶
A line of capture options must be sent after initial connection before any data will be sent. This is a list of any of the following options separated by whitespace ending with a newline character.
ASCII | Specifies that data is to be sent as ASCII numbers. | 1 | D |
BASE64 | Binary data will be sent as a stream of base64 strings. | 1 | |
FRAMED | Binary data is sent as a sequence of sized frames. | 1 | |
UNFRAMED | Binary data is sent as a raw stream of bytes. | 1 | R |
SCALED | All scalable data is scaled and sent as doubles. | 2 | D |
RAW | The captured binary data is sent without processing. | 2 | |
NO_HEADER | The data header is omitted. | R | |
NO_STATUS | The connection and end of experiment status strings are omitted. | R | |
ONE_SHOT | Only one experiment will be transmitted. | R | |
XML | The header will be sent in XML format. | ||
BARE | Selects UNFRAMED RAW NO_HEADER NO_STATUS ONE_SHOT |
||
DEFAULT | Default options. | D |
- Key:
D: Default option if no other option specified. R: Options selected in response to BARE
option.1: Data transmission formats, one of these will be selected. 2: Data processing formats, one of these will be selected.
Data Transport Formatting¶
Note that all binary data is sent with the lowest order byte first.
ASCII
- Each value is formatted as an ASCII number, and transmitted with one line per captured sample.
BASE64
- The stream of binary data is converted to base64 strings and transmitted as a series of lines until the experiment is complete. Each base64 string is preceded by a single space, so the end of the stream is easy to identify.
FRAMED
- In
FRAMED
mode the captured binary data is sent in blocks of unpredictable size. Each block is preceded by 8 bytes. The first four bytes areBIN
followed by space, the remainind four bytes are the length of the data block in bytes including the 8 byte header. UNFRAMED
- In
UNFRAMED
mode the captured binary data is sent as is. In this mode it is difficult or impossible to reliably detect the end of the data stream, so normally this is best combined withNO_STATUS
andONE_SHOT
.
Data Header¶
At the beginning of each experiment the following information is sent:
arm_time | UTC Timestamp sampled in correspondence of the ARM command |
missed | Number of samples missed by late data port connection. |
process | Data processing option: Scaled, Unscaled, or Raw. |
format | Data delivery formatting: ASCII, Base64, Framed, or Unframed. |
sample_bytes | Number of bytes in one sample unless format is ASCII . |
fields | Information about each captured field. |
For each field the following information is sent:
name | Name of captured field. | |
type | Data type of transmitted field after data processing. | |
capture | Value of CAPTURE field used to enable this field. |
|
scale | Scaling factor if scaled field. | S |
offset | Offset if scaled field. | S |
units | Units string if scaled field. | S |
- Key:
S: Only present if scaled field
If the XML
option is selected the header is structured as a single
header
element containing data
and fields
elements.
The type
field can be one of the following strings:
String | Bytes | Description |
---|---|---|
int32 | 4 | Used for scalable values sent in unscaled modes. |
uint32 | 4 | Used for bit masks. |
int64 | 8 | Used for raw ADC mean and unscaled 48-bit encoder data. |
double | 8 | Used for all scaled values when SCALED selected. |
Experiment Completion¶
At the end of each capture experiment a single line is sent, eg:
END 10 Ok
This specifies the number of samples sent and gives a completion code, which can be one of the following values:
Ok | Experiment completed without intervention. |
Disarmed | Experiment manually completed by *PCAP.DISARM= command. |
Early disconnect | Client disconnect detected. |
Data overrun | Client not taking data quickly or network congestion, internal buffer overflow. |
Framing error | Triggers too fast for configured data capture. |
Driver data overrun | Probable CPU overload on PandA, should not occur. |
DMA data error | Data capture too fast for memory bandwidth. |
High performance mode¶
To get the highest performance, use FRAMED RAW
mode. This activates a
special passthrough mode which avoids copying memory as much as possible. In
tests it has been capable of sustaining 60MBytes/s when panda-webcontrol is not
installed. The downside to this mode is that if capture fails for any reason,
then the last Framed block of data that the server sent should be discarded as
it will have been corrupted while being sent.
Examples¶
Some examples of data capture for different options follow:
Default:
arm_time: 2021-05-26T10:34:06.133Z
missed: 0
process: Scaled
format: ASCII
fields:
PCAP.CAPTURE_TS double Trigger
COUNTER1.OUT double Triggered scale: 1 offset: 0 units:
COUNTER2.OUT double Triggered scale: 1 offset: 0 units:
PGEN1.OUT double Triggered scale: 1 offset: 0 units:
1e-06 0 0 262143
3e-06 0 0 262142
5e-06 0 0 262141
7e-06 0 0 262140
9e-06 0 0 262139
END 5 Ok
BASE64
:
arm_time: 2021-05-26T10:34:06.133Z
missed: 0
process: Scaled
format: Base64
sample_bytes: 32
fields:
PCAP.CAPTURE_TS double Trigger
COUNTER1.OUT double Triggered scale: 1 offset: 0 units:
COUNTER2.OUT double Triggered scale: 1 offset: 0 units:
PGEN1.OUT double Triggered scale: 1 offset: 0 units:
ju21oPfGsD4AAAAAAAAAAAAAAAAAAAAAAAAAAPj/D0FU5BBxcyrJPgAAAAAAAAAAAAAAAAAAAAAA
AAAA8P8PQfFo44i1+NQ+AAAAAAAAAAAAAAAAAAAAAAAAAADo/w9BuF8+WTFc3T4AAAAAAAAAAAAA
AAAAAAAAAAAAAOD/D0E/q8yU1t/iPgAAAAAAAAAAAAAAAAAAAAAAAAAA2P8PQQ==
END 5 Ok
XML
:
<header>
<data arm_time="2021-05-26T10:35:06.107Z" missed="0" process="Scaled" format="ASCII" />
<fields>
<field name="PCAP.CAPTURE_TS" type="double" capture="Trigger" />
<field name="COUNTER1.OUT" type="double" capture="Triggered" scale="1"
offset="0" units="" />
<field name="COUNTER2.OUT" type="double" capture="Triggered" scale="1"
offset="0" units="" />
<field name="PGEN1.OUT" type="double" capture="Triggered" scale="1" offset="0"
units="" />
</fields>
</header>
1e-06 0 0 262143
3e-06 0 0 262142
5e-06 0 0 262141
7e-06 0 0 262140
9e-06 0 0 262139
END 5 Ok
Building and Configuring Panda Server¶
Setting up the build for the Panda Socket Server requires configuring a number
of dependencies and creating a suitable CONFIG
file in the root directory so
that they can be found.
Dependencies¶
The following dependencies must be configured before any part of the server can be built.
- Zynq cross-compiler toolchain
- This can be downloaded as part of the Xilinx Vivado build environment for working with Zynq, or probably any ARMv7-A cross-compiler can be used. This is needed to build all applications running on Panda.
- PandABlocks-FPGA
- This part of the Panda project must be available before the server can be built, as it contains a configuration file defining the low level register interface to the Panda firmware.
- PandABlocks-rootfs
- This part of the Panda project is required in order to provide a working kernel build tree, and to provide the zpkg build tool.
Setting up the CONFIG
file¶
Start by copying the file CONFIG.example
to CONFIG
in the base
directory, and edit the file by commenting out lines as appropriate and editing
them.
The following symbols must be set to point to the appropriate dependencies:
BINUTILS_DIR
- If the Zynq cross-compiler toolchain is not on the path, this must be set in order to build the kernel module and the target build. This symbol is not required for building the simulation server or the documentation.
KERNEL_DIR
- In order to build the kernel module, this symbol must be pointed to the kernel build tree generated by the PandABlocks-roots build.
PANDA_ROOTFS
- The zpkg build tool is found here.
The following symbols can all be left at their default values:
BUILD_DIR
- This configures where the built files will be placed.
PYTHON
- This configures which Python interpreter will be used for building.
SPHINX_BUILD
- The sphinx-build Python script used for building the documentation.
DEFAULT_TARGETS
- This determines which makefile targets are generated when
make
is run without specifying a particular target, or whenmake default
is run.
Build Targets¶
The following build targets for the top level makefile are useful:
default
- Builds all the targets specified by
$(DEFAULT_TARGETS)
, by default this list is:driver
,server
,sim_server
,docs
,zpkg
. driver
- Builds the kernel driver module.
server
- Builds the server version to run on Panda.
sim_server
- Builds a simulation version of the server to run on the local PC.
docs
- Builds the documentation.
zpkg
- Builds the final
panda-server
zpgk file. clean
- Removes the entire
$(BUILD_DIR)
directory.
Generated Files¶
In the $(BUILD_DIR)
directory the following subdirectories and files will be
found. In practice the .zpg
file and html/
directory will be wanted.
driver/
- The kernel module required for hardware access is built here.
server/
sim_server/
These two directories are used to build the server to run on Panda, and a simulation server to run on the local PC.
html/
- The documentation is built in html format in this directory.
panda-server@
version.zpg
zpkg-panda-server/
A zpkg for the server is built here.
Configuration Files¶
On startup the Panda Server loads its configuration from three files:
config
, registers
, description
. These are loaded from the
config_d
directory in build directory when running the basic simulation, and
on Panda the configuration files are loaded from /opt/share/panda/config_d
.
The syntax of each configuration file is documented here. The format of each field definition closely follows the format documented in Blocks, Fields and Attributes.
The three files have the following distinct functions.
File | Description |
---|---|
config |
Configuration: defines list of blocks, fields in each block, and the behaviour of each field. |
registers |
Registers: for each block and field defines the associated register offsets. |
description |
Description: optionally defines a description string for each block and field. |
All files have a common structure and indentation is used for structure.
Comments begin with #
, blocks are identified by their name in the first
column, and fields are listed at the next level of indentation.
Configuration file config
¶
This file defines all of the blocks and fields available to this instance of Panda and is processed first.
The syntax of a block definition is:
block-name [ "[" count "]" ]
[ field-definition ]*
This means that a block definition consists of a block-name, which can be any word used to name the block, optionally followed by a block count enclosed in square brackets, followed by any number of indented field-definitions.
The syntax of a field definition is:
field-name field-type [ field-type-data ]
The field-name names the field, the field-type is a single word from the list documented below, and the field-type-data depended on the field type as documented.
The field type determines the basic function of the field, what actions can be performed on the field, and how the field interacts with the hardware. Typically each field corresponds to a single register or function of the block.
Many field type have an associated field subtype which is used to convert between the values show to the user of the server and the values written to or read from registers.
Field type¶
The following field types are defined.
Field | |
---|---|
param field-subtype [ = value ] |
|
read field-subtype |
|
write field-subtype |
|
time [ > min_value ] |
|
bit_out |
|
pos_out [ scale [ offset [ units ]]] |
|
ext_out ( timestamp | samples | bits group ) |
|
bit_mux [ = value ] |
|
pos_mux |
|
table |
param
field-subtype [=
value ]- A
param
field is used to define a single 32-bit value written to a register. The field-subtype must be specified. Optionally an initial value (only relevant when no state file has been loaded) can be specified. In this case the initial value is read as a raw unsigned integer which is written directly to the hardware on startup. read
field-subtype- A
read
field is used for read-only registers. The field-subtype must be specified. write
field-subtype- A
write
field is used for write-only registers which trigger immediate actions on a block. The field-subtype must be specified, and the action subtype is useful forwrite
fields which take no data. time
[>
min_value ]Time fields behave like
param
fields, but need special treatment because the underlying value is 64-bits and so two registers need to be written.If desired a minimum valid value can be specified as min_value. This will prevent the writing of values less than this value and can be read as the
.MIN
attribute.bit_out
- This identifies an output bit.
pos_out
[ scale [ offset [ units ]]]- This identifies a position bus output. Optionally default values for the scale, offset, and units fields can be specified in the config file. Note that these are only effective when there is no persistence file to load.
ext_out
ext-extraThis identifies an entry on the extension bus which needs special treatment. The ext-extra field must be one of the following values:
ext-extra Description timestamp
Capture timestamp as a 64-bit value samples
Captures sample count for data capture. bits
groupDefines fields which allow the bit bus to be captured. The group number identifies which 32-bit group of 128 bits is captured.
bit_mux
[ =
value ]pos_mux
These two are configuration settings for selecting inputs, and behave likeparam
fields. As forparam
a default value can be assigned tobit_mux
, but the only useful value is 129 (ONE
).
table
[ row-words ]- Tables are treated specially.
Field subtype¶
The following field subtype can follow a param
, read
or write
field
type:
Type | |
---|---|
uint [ max-value ] |
|
int |
|
scalar scale [ offset [ units ]] |
|
bit |
|
action |
|
lut |
|
enum |
|
position |
|
time |
Note that enum
must be followed by indented lines each consisting of a
number followed by a string: the string is the enumeration value written to
the user, the number is the value written to the register.
Register file registers
¶
This file defines the register assignments for each block and register. The
body of this file should contain a sequencer of block and field definitions
repeating the config
file, except that the field type specification is
replaced by a type specific register definition.
So a block definition is:
block-name { [ "S" ] block-register | "X" } [ extension-module ]
[ field-definition ]*
If the block-register number is prefixed with S
then the same block
register number can be shared with multiple blocks: this allows a single
hardware implementation to be presented as multiple software blocks. If X
is used instead of specifying block-register then no fields can use registers,
so must be extension fields with no register linkage.
The register number can be followed by an extension-module which is used to identify this block to the extension server, and will enable use of the extension register syntax defined below.
A field definition is:
field-definition = field-name register-specification
where register-specification depends on the associated field type as follows:
Class | Register syntax |
---|---|
param |
register | write-extension |
read |
register | read-extension |
write |
register | write-extension |
time |
low-register high-register |
bit_out |
( bit-index )N |
pos_out |
( pos-index )N |
ext_out timestamp |
ext-index ext-index |
ext_out other |
ext-index |
bit_mux |
register |
pos_mux |
register |
table |
short size init-reg fill-reg length-reg |
table |
long 2^ size base-reg length-reg |
where the syntax (...)N
means that the given register number is repeated N
times where N is the number of instances of the block. See below for an
explanation of read-extension and write-extension.
Extension register syntax¶
If the extension server is enabled (with the -X
command line option on the
server) and if an extension module has been loaded as part of the block
specification then param
, read
, and write
subtypes can all be
redirected to the extension server using the read-extension and
write-extension syntax:
read-extension = [ read-reg ]* "X" field-spec
write-extension = [ read-reg ]* [ "W" [ write-reg ]* ] "X" field-spec
In this syntax field-spec is passed through to the associated extension-module to create the binding between this field and the extension server. The specified read-regs and write-regs will be used when processing this field.
See Extension Server for more details on extension fields.
Description file description
¶
The entire content of the description file is optional. The basic syntax is:
block-name block-description
[ field ]*
where field is:
field-name field-description
and the description is any newline terminated string in UTF-8 format.
Extension Server¶
The extension server is used to implement custom fields. The extension server runs alongsize the Panda socket server and supports the loading of Python modules with a lightweight remote procedure calling interface from the socket server.
As described in Configuration Files, individual read, write, param fields can be specified to take their values from and write to the extension register. At the same time, these extension read and write operations can be linked to hardware registers.
The extension server is started alongside the socket server, and on PandA looks
in /opt/share/panda-fpga/extensions
for extension module files. During
development any Python module can be specified as a container for extension
sub-modules.
Connections from the socket server to the extension server are established while
reading the registers file. Firstly, if a block has an extension module
specified then this module is loaded from the extensions directory and is
associated with the block. Next, each extension field is processing by calling
the appropriate parse_read()
or parse_write()
methods.
Depending on the register configuration any number of hardware block registers can be read or written during processing of an extension field.
Extension Modules¶
Each extension module must export a class constructor named Extension. This takes one argument and must support two methods parse_read and parse_write
-
class
Extension
(count)¶ This class must be defined by each extension module. The class will be instantiated in response to loading a block register definition of the form:
block-name [ "S" ] block-register extension-module
The parameter count is set to the number of instances specified for the block in the config file. This class must provide the following methods, as appropriate, to support read and write register fields:
-
parse_read
(field_spec)¶ This is called in response to a read-extension line in the register file of the form:
[ read-reg ]* "X" field-spec
The field-spec is passed as a string to
parse_read()
, and this method must return a callable of the following form:-
value = read_register(block_num, read_reg1, ..., read_regN)
The first argument block_num is the number of the block instance being called (starting from 0), and is guaranteed to be less than count as passed to the
Extension
constructor.The remaining read_reg1 … read_regN argument must match the number of arguments specified in the read-reg block of the register file. These will be populated by reading the corresponding block hardware registers before this function is called.
The value returned must be a single integer, this is the value returned when reading this field.
-
-
parse_write
(field_spec)¶ This is called in response to a write-extension line in the register file of the form:
[ read-reg ]* [ "W" [ write-reg ]* ] "X" field-spec
As for
parse_read()
, field-spec is passed as the argument, and a callable must be returned, of the following form:-
(write_reg1, ..., write_regM) = write_register(block_num, value, read_reg1, ..., read_regN)
The first argument block_num is the number of the block instance being called (starting from 0), and is guaranteed to be less than count as passed to the
Extension
constructor.The second argument value is the value written to this field.
The remaining read_reg1 … read_regN argument must match the number of arguments specified in the read-reg block of the register file. These will be populated by reading the corresponding block hardware registers before this function is called.
The value returned must be a tuple of integers matching the write-reg block of the register file. The returned values will be written to the specified hardware registers after processing this function. This defines the action of writing this field.
-
-
Injected Values¶
Every extension module will have two support values injected into the module when the module is loaded into the server. These are available to help with the implementation of extensions.
-
class
ServerError
(Exception)¶ Read and write methods should use this exception to report errors. Exceptions of this type are treated specially and are reported as normal read or write errors.
-
class
ExtensionHelper
¶ This can be used inside an extension module to create extension support for individual fields. Pass a block constructor (that must take one argument, the block index) which implements set_ and get_ methods as appropriate, and this helper will implement the approprate Extension support.
Use this inside the extension module thus:
class MyBlock: def __init__(self, n): ... def get_field(self, *regs): ... return value def set_field(self, value, *regs): ... return new_regs def Extension(count): return ExtensionHelper(MyBlock, count)
Starting Panda Server¶
The Panda socket server is normally automatically started at boot time or when
the zpkg-daemon
script is run. The server is started and stopped by the
script etc/panda-server
installed in /opt/etc/init.d
.
The server can optionally be started from the command line, in which case the following arguments are supported:
-h
- This option shows the help text for server, listing all the available command line options.
-p
port- This specifies the socket port to be used for configuration commands. The default value is 8888.
-d
port- This specifies the socket port to be used for data capture. The default value is 8889.
-R
- This can be specified to allow socket reuse via the
SO_REUSEADDR
socket option. -c
config-dir- This specifies the directory where the
config
,registers
, anddescription
files will be loaded from. This argument must be specified. -f
persistence-file- This specifies where the persistence state will be loaded from on startup
and saved during operation. See the
-t
option below for notes on how this file is updated. If this is not specified then the persistence state will not be saved. -t
[poll] [“:” [holdoff] [“:” backoff]]This option sets three parameters (in seconds) controlling the pacing of writes to the persistence file. The behaviour of the system is as follows: every poll seconds the internal state of the server is checked for configuration changes. If a configuration change is checked then there is a pause of a further holdoff seconds before the updated state is written. Finally, there is a pause of backoff seconds before polling for internal changes resumes.
Default values are: poll = 2, holdoff = 10, backoff = 60. The somewhat complex syntax show above allows all or any of these values to be set with a single
-t
option. For example,-t:20
specifies holdoff = 20, other values unchaged.The intention of this timed behaviour is to reduce file write impact while still keeping on top of changes. With default settings all parameters will be written to the persistence file within 72 seconds.
-D
- This option requests that the server is run as a daemon. This is the normal mode of operation when running as a server, but is generally omitted for debug.
-p
pid-file- If specified the given file is written with the process ID of the server, and will be deleted on exit.
-T
- This mode is used for config file validation only: the server exits immediately after loading configuration files.
-M
MAC-list- If specified then the given file is used to initialise up to four MAC
address registers. The file consists of any number of comment
lines (comment lines start with
#
in the first column) together with four MAC address lines, each of which is either blank (newline\n
only) or is a six octet MAC address written as 2 digit hex numbers separated by colons. -X
port- If specified the server will attempt to connect to an extension server running locally and serving on the specified port.
Supporting Documentation¶
Useful Tools¶
There are a number of useful tools in the python
directory.
sim_server
- This is run as part of the top level
simserver
script to provide emulation of the Panda hardware. The version of this tool provided with the server is very basic, for a more functional emulation use the corresponding tool in the PandaFPGA project. tcp_client
[server [port]]- This tool connects to the Panda server configuration port and helps with sending and receiving configuration commands.
save-state
server file- This saves the entire configuration state for the given Panda to the given file.
load-state
server file- This writes the given configuration file to the Panda.
Panda Status LEDs¶
Two LEDs on Panda show a rough indication of the current status of Panda. There are two LEDs, STA (status) and DIA (diagnostic); the status LED is green and is used to indicate normal activity, the diagnostic LED is red and is used to indicate various fault conditions.
The table below shows the possible LED indicators and their meaning:
Mnemonic | DIA | STA | Meaning |
---|---|---|---|
- | Off | Off | System not running |
BOOTING | Off | Blink | Panda booting |
SYSTEM_OK | Off | On | Panda running ok |
ATTENTION | Blink | Off | User attention required |
NW_ERR | Blink | Blink | Network problem detected |
- | Blink | On | (not used, should not occur) |
ZPKG_ERR | On | Off | Problem loading installed package |
SYSTEM_ERR | On | Blink | System error |
- | On | On | (not used, should not occur) |
The detailed meaning of these conditions is described below.
- BOOTING
- The system is currently booting. Unless a new image is being configured this should only take a few seconds, but during image installation this can take a few minutes.
- SYSTEM_OK
- Booting has completed and the system is running normally.
- ATTENTION
- User attention is required. Either a fresh installating is prompting for a MAC address, or no system packages have been installed. Connect a serial port in the first case, connect to the administration web page on port 8080 in the second case.
- NW_ERR
A network error has been detected.
This function is not currently implemented.
- ZPKG_ERR
- An installed package has failed to start. Try power-cycling Panda first, if that fails check the logs and the serial port for relevant diagnostic messages.
- SYSTEM_ERR
An internal system error has been detected.
This function is not currently implemented.