diff --git a/Makefile b/Makefile index c4a2b2b..f72d5f8 100644 --- a/Makefile +++ b/Makefile @@ -29,3 +29,15 @@ DIRS += iocBoot UNINSTALL_DIRS += $(INSTALL_LOCATION)/opi include $(TOP)/configure/RULES_TOP + +sphinx: + $(MAKE) -C documentation html + +sphinx-clean: + $(MAKE) -C documentation html clean + +sphinx-commit: sphinx + touch documentation/_build/html/.nojekyll + ./commit-gh.sh documentation/_build/html + +.PHONY: sphinx sphinx-commit sphinx-clean diff --git a/commit-gh.sh b/commit-gh.sh new file mode 100755 index 0000000..3e97f83 --- /dev/null +++ b/commit-gh.sh @@ -0,0 +1,45 @@ +#!/bin/sh +set -e -x +# Usage: commit-gh +# +# Creates a commit containing only the files in the sub-directory provided as an argument +# +# Does not disturb the working copy or index + +[ -d "$1" ] || exit 1 + +# Commit to this branch +BRANCH=refs/heads/gh-pages + +# Use the main branch description as the gh-pages commit message +MSG=`git describe --tags --always` + +# Scratch space +TDIR=`mktemp -d -p $PWD` + +# Automatic cleanup of scratch space +trap 'rm -rf $TDIR' INT TERM QUIT EXIT + +export GIT_INDEX_FILE="$TDIR/index" + + +# Add listed files to a new (empty) index +find "$1" -type f -print0 | xargs -0 git update-index --add + +# Write the index into the repo, get tree hash +TREE=`git write-tree --prefix="$1"` + +echo "TREE $TREE" +git cat-file -p $TREE + +# Create a commit with our new tree +# Reference current branch head as parent (if any) +CMT=`git commit-tree -m "$MSG" $TREE` + +echo "COMMIT $CMT" +git cat-file -p $CMT + +# Update the branch with the new commit tree hash +git update-ref $BRANCH $CMT + +echo "Done" diff --git a/documentation/devsup.rst b/documentation/devsup.rst index f32281f..3ee9dec 100644 --- a/documentation/devsup.rst +++ b/documentation/devsup.rst @@ -1,84 +1,151 @@ Device Support ============== -The format of all INP/OUT link fields is: "key=value key2=value2". -Allowed keys are: - -* name= -* reg= -* offset= -* step= -* wait= -* rbv= -* mask= -* value= -* retry= -* scale= (only for aai/aao w/ FTVL=DOUBLE) - -All INP/OUT links must specify a Device name with 'name='. -Use of other keys is described in the following. - -The Device Supports used only in feed_base.template are not described. - -The Device Supports provided by feed.dbd are as follows. - -Register Write -~~~~~~~~~~~~~~ - -To write value(s) to a Device register. :: - - record(longout, "...") { - ... - record(ao, "...") { - ... - record(aao, "...") { - field(DTYP, "FEED Register Write") - field(OUT , "@name= reg=") - # optional in OUT - # offset=0 Index in register from which a (first) value taken - # wait=true Whether to delay completion until the write is acknowledged by the device. - # step=1 With aao, increment of Index between array elements - } +Overview +-------- -Register Read -~~~~~~~~~~~~~ +The FEED driver for EPICS does not require an explicit instance creation +step. Instead instances are created lazily on first usage. The Device IP +address is set, and may be changed, through a record with +``field(DTYP, "FEED Set Address")``. -To read value(s) to a Device register. :: +See the installed ``feed.dbd`` for the authoritative list of +Device Supports and IOCsh variables. - record(longin, "...") { - ... - record(ai, "...") { - ... - record(aai, "...") { - field(DTYP, "FEED Register Read") - field(INP , "@name= reg=") - # optional in OUT - # offset=0 Index in register from which a (first) value taken - # wait=true Whether to read a value from the Device, or use the previous read value. - # rbv=false Whether to copy the most recently read value (false) or most recently written (true) - # step=1 With aai, increment of Index between array elements - } +IOC Shell Variables +------------------- -Register Watch -~~~~~~~~~~~~~~ +- ``int feedNumInFlight`` The number of concurrent requests which will + be made to any one device. Default 1. +- ``double feedTimeout`` Timeout in seconds for an individual + request/reply exchange. Default 1.0 +- ``int feedUDPHeaderSize`` Size in byte of transport layer headers. + Used only in estimated bandwidth calculations. Default 42. +- ``int feedUDPPortNum`` The default UDP port number. The default for + this default is ``50006``. -To periodically poll a status register until "current & == ". +INP / OUT link format +--------------------- -Every "" seconds the register is read and compared. -Record processing does not complete until the condition is true, or a timeout occurs. :: +All FEED device supports expect ``INP`` or ``OUT`` to be prefixed by +``@``. aka. ``INST_IO`` followed by a space separated list of +``key=value`` pairs. Only ``name=`` is required by all ``DTYP``. See +below for which keys are understood by which ``DTYP``. - record(bo, "...") { - field(DTYP, "FEED Register Watch") - field(OUT , "@name= reg= retry= mask= value=") - # offset=0 Index in register from which a (first) value taken - } +Valid keys are: + +- ``name=`` The Instance name. Must be unique within an IOC process. +- ``reg=`` Register name. Must match key in Device JSON blob. +- ``offset=`` Array registers only. Offset of first word accessed. + Default ``0``. +- ``step=`` Array registers only. Number of words between accesses. + Default ``1``. +- ``scale=`` Multiplier used for ``aai``/``aao`` with ``FTVL`` set to + ``DOUBLE``. Default ``1.0``. +- ``wait=`` Boolean. See below. +- ``rbv=`` Boolean. Input records only. ``false`` (default), use value + from previous read op. ``true``, use value from previous write + (combine with ``I/O Intr`` for readback of setting) +- ``signal=`` “signal” name in IOC JSON blob. Omitted when not set. +- ``meta=``. Boolean. Update record meta-data fields from Device JSON + when entering Running state. Default ``false``. +- ``mask=``, ``value=``, ``retry=``. See Register Watch device support + +TPRO Debugging +-------------- + +FEED Device Supports where ``TPRO > 1`` will log extra information. + +Register access +--------------- + +Each record with a register Read or Write device support will enqueue a +request for a remote read or write operation on all addresses of the +named (by string) register. + +Internally, the FEED driver will manage batching of pending requests +into UDP packets. + +FEED Register Read +~~~~~~~~~~~~~~~~~~ + +Supported for record types: longin, ai (RVAL), mbbi (RVAL), and aai. + +Asynchronous device support when ``wait=true`` (default), initiate +register read. Synchronous when ``wait=false``, read from local cache. + +On scan, request read of the named register. Processing completes on +success, with updated VAL/RVAL, or an ``INVALID`` alarm on timeout. + +When ``SCAN`` set to ``I/O Intr``, record will be processed when after +the named register has been read for any reason (eg. some other record) +using the value returned by that operation. Or an ``INVALID`` alarm on +timeout. + +For ``aai`` record type. Supported ``FTVL`` are: ``CHAR``, ``UCHAR``, +``SHORT``, ``USHORT``, ``LONG``, ``ULONG``, or ``DOUBLE``. Link options +``offset=`` and/or ``step=`` allow slicing of array registers. When +``FTVL`` is ``DOUBLE``, link option ``scale=`` multiplier is used. + +:: -Sync -~~~~ + # poll the required HELLO register + record(longin, "$(PREF)HELLO-I") { + field(DTYP, "FEED Register Read") + field(INP , "@name=$(NAME) reg=HELLO") + field(SCAN, "2 second") + } + record(aai, "$(PREF)FW_ROM") { + field(DTYP, "FEED Register Read") + field(INP , "@name=$(NAME) reg=ROM") + field(SCAN, "I/O Intr") + field(FTVL, "LONG") + field(NELM, "2048") + } + +FEED Register Write +~~~~~~~~~~~~~~~~~~~ + +Supported for record types: longout, ao (RVAL), mbbo (RVAL), and aao. + +Asynchronous device support when ``wait=true`` (default), wait for +register write operation to complete. Synchronous when ``wait=false``, +initiate write and immediately continue. + +On scan, request write of the named register. Processing completes on +success, with updated VAL/RVAL, or an ``INVALID`` alarm on timeout. + +When ``FTVL`` is ``DOUBLE``, link option ``scale=`` multiplier is used. + +:: + + record(longout, "$(BASE)$(N)") { + field(DTYP, "FEED Register Write") + field(OUT , "@name=$(NAME) reg=$(REG)") + } + +bo / FEED Register Watch +~~~~~~~~~~~~~~~~~~~~~~~~ + +Special repeated read operation to poll for bit field register. + +Once initiated, polls until success or device timeout. + +:: + + # wait for value & $(RDY_MASK) == $(RDY_MASK) for reg $(RDY_REG) + record(bo, "$(BASE)$(N)") { + field(DTYP, "FEED Register Watch") + field(OUT , "@name=$(NAME) retry=$(RETRY=0.1) reg=$(RDY_REG) mask=$(RDY_MASK) value=$(RDY_MASK)") + } + + +FEED Sync +~~~~~~~~~ The special DTYP="FEED Sync" support exists to allow sequencing during (re)connection. This asynchronous record will complete processing after every in-progress register read/write -can completed (or timed out). :: +has completed (or timed out). :: record(longin, "$(BASE)Init3_") { field(DTYP, "FEED Sync") @@ -115,25 +182,180 @@ paramter for "$(P)-I". :: Currently only the offset, step=, and scale= parameters may be override via the Signals mechanism. -Status Monitoring ------------------ +Drive Instance control/status +----------------------------- + +See ```feed_base.template`` `__ for the +recommended starting set of device control and status records. + +longout / FEED Debug +~~~~~~~~~~~~~~~~~~~~ + +Sets the instance debug printing mask. + +:: + + record(longout, "$(PREF)DEBUG") { + field(DTYP, "FEED Debug") + field(OUT , "@name=$(NAME)") + } + +stringout / FEED Force Error +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Force the instance into the latching Error state. The driver will stop +all communication attempts until forced out of the error state by +(re)setting the IP address. + +:: + + record(stringout, "$(PREF)HALT_") { + field(DTYP, "FEED Force Error") + field(OUT , "@name=$(NAME)") + } + +stringout / FEED Set Address +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Set the instance IP address and port. + +:: + + record(stringout, "$(PREF)IPADDR") { + field(DTYP, "FEED Set Address") + field(OUT , "@name=$(NAME)") + } + +mbbi / FEED State +~~~~~~~~~~~~~~~~~ + +Instance “connection” state. + +- 0, ``Error`` Latching error state. No communition attempted until + reset (by setting IP address) +- 1, ``Idle``. Not latching. Not “connected” and no IP address set. +- 2, ``Searching``. Not “connected”, periodically probing for device +- 3, ``Inspecting``. Reading out and processing ROM image +- 4, ``Running``. Normal operation + +:: + + record(mbbi, "$(PREF)STATUS") { + field(DTYP, "FEED State") + field(INP , "@name=$(NAME)") + } + +longin / FEED On Connect +~~~~~~~~~~~~~~~~~~~~~~~~ + +Processed on transition into Running state. + +:: + + record(longin, "$(BASE)$(N)") { + field(DTYP, "FEED On Connect") + field(INP , "@name=$(NAME)") + field(SCAN, "I/O Intr") + } + +aai / FEED Error +~~~~~~~~~~~~~~~~ + +``FTVL=CHAR`` holds most recent error message string. + +:: + + record(aai, "$(PREF)LAST_ERROR") { + field(DTYP, "FEED Error") + field(INP , "@name=$(NAME)") + field(SCAN, "I/O Intr") + field(FTVL, "CHAR") + field(NELM, "256") + } + +longin / FEED Counter +~~~~~~~~~~~~~~~~~~~~~ + +Poll diagnostic counter by numeric index. + +- 0, UDP packets sent to device +- 1, UDP packets received from device +- 2, UDP packets ignored (eg. malformed) +- 3, Timeouts occurred +- 4, Internal driver errors occurred +- 5, Sequence number of next request +- 6, Bytes received from device, including estimate of transport + protocol overhead. + +:: + + record(longin, "$(PREF)$(N)") { + field(DTYP, "FEED Counter") + field(INP , "@name=$(NAME) offset=$(INDEX)") + } + +ai / FEED RTT +~~~~~~~~~~~~~ + +Average round trip time between last 100 requests and replies. + +:: + + record(ai, "$(PREF)RTT") { + field(DTYP, "FEED RTT") + field(INP , "@name=$(NAME)") + } + +aai / FEED JBlob +~~~~~~~~~~~~~~~~ + +zlib compressed JSON blob. “offset” 0 is the IOC description blob, +“offset” 1 is a copy of most recent Device blob. + +:: + + record(aai, "$(PREF)JINFO") { + field(DTYP, "FEED JBlob") + field(INP , "@name=$(NAME) offset=0") + field(SCAN, "I/O Intr") + field(FTVL, "CHAR") + field(NELM, "16000") + } + record(aai, "$(PREF)JSON") { + field(DTYP, "FEED JBlob") + field(INP , "@name=$(NAME) offset=1") + field(SCAN, "I/O Intr") + field(FTVL, "CHAR") + field(NELM, "16000") + } + +aai / FEED ROM Info +~~~~~~~~~~~~~~~~~~~ + +Information by numeric index from Device ROM image. + +- 0, Application description string +- 2, Application Git revision hash + +:: + + record(aai, "$(PREF)$(NAME)") { + field(DTYP, "FEED ROM Info") + field(INP , "@name=$(NAME) offset=$(INDEX)") + field(SCAN, "I/O Intr") + field(FTVL, "CHAR") + field(NELM, "256") + } -Basic status is reported through the "$(PREF)State-Sts" record. -This will show the current state of the device state machine: -* Error - Internal software fault occurs. Write "$(PREF)Rst-Cmd" to clear. -* Idle - No IP address set with "$(PREF)Addr-SP" -* Searching - Waiting for initial response from Device -* Inspecting - Downloading ROM -* Running - Normal operating mode +longout / FEED Hack lp:1745039 +------------------------------ +Workaround for bug in epics-base < 7.0.2 when chaining asynchronous +records. A no-op when built with >= 7.0.2 -Counters -~~~~~~~~ +https://bugs.launchpad.net/epics-base/+bug/1745039 -A number of event counters are provided. -These include number of packets sent and received, as well as number of timeouts. -Counters are exposed through records in 'feed_base.template' and by 'dbior'. dbior ~~~~~ diff --git a/documentation/index.rst b/documentation/index.rst index 5849158..d38dbeb 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -1,16 +1,8 @@ -.. LBNL Embedded Ethernet Protocol (LEEP) documentation master file, created by - sphinx-quickstart on Thu Jan 18 18:36:56 2018. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to LEEP documentation! +Welcome to FEED documentation! ============================== -Documentation for the LBNL Embedded Ethernet Protocol (LEEP) -interface python module. - -This module communicates with LEEP device either directly, -or mediated by an EPICS IOC via the Channel Access protocol. +Documentation for the EPICS driver and python module +for interacting using the LBNL Embedded Ethernet Protocol (LEEP). Contents: @@ -21,6 +13,7 @@ Contents: devsup usage api + proto Indices and tables ================== diff --git a/documentation/proto.rst b/documentation/proto.rst new file mode 100644 index 0000000..7d216ec --- /dev/null +++ b/documentation/proto.rst @@ -0,0 +1,312 @@ +.. role:: raw-latex(raw) + :format: latex +.. + +Protocol +======== + +LBNL Embedded Ethernet Protocol is +A Request/Reply style protocol using UDP on port 50006. A Device +(Server) receives Requests on port 50006 and responds to each valid +Request with a single Reply. + +Requests and Replies act on 32-bit registers in a 64MB address space. +The 24-bit Address field acts as the upper bits of a 26-bit address. + +UDP Message Format +------------------ + +.. raw:: html + +
+              0       1         2         3
+         +--------+--------+--------+--------+
+      00 |              Header...            |
+         +--------+--------+--------+--------+
+      04 |           ...Header               |
+         +--------+--------+--------+--------+
+      08 |  Bits  |      Address 1           |
+         +--------+--------+--------+--------+
+      0C |             Data 1                |
+         +--------+--------+--------+--------+
+      10 |  Bits  |      Address 2           |
+         +--------+--------+--------+--------+
+      14 |             Data 2                |
+         +--------+--------+--------+--------+
+      18 |  Bits  |      Address 3           |
+         +--------+--------+--------+--------+
+      1C |             Data 3                |
+         +--------+--------+--------+--------+
+         ...  Repeat Bits/Address/Data
+   
+ +Request and Reply messages have the same format. Each UDP message, +request or reply, is composed of a 8 byte header followed by between 3 +and 127 address/data pairs. Total message size *must* be at least 32 +bytes. The real maximum limit is the ethernet MTU less transport +protocol headers. For the default 1500 bytes and UDP/IPv4 (42 header +bytes) this is 1456 bytes of UDP payload. Messages size *should* be a +multiple of 8 bytes. Recipients *must* truncate messages to a multiple +of 8 bytes. + +Message fields are in Most Significant Byte first (MSB or network) byte +order. + +It is *suggested* to pad messages shorter than 32 bytes with reads of +address 0. + +Message Fields +-------------- + +Header +~~~~~~ + +Echoed without modification from Request to Reply. May be assigned +arbitrarily by a Requester to aid in Reply processing. + +Bits +~~~~ + +This 1 byte field selects the operation in which the Address and Data. + +- 0x10 This bit is *set* for a *Read* operation, and + *cleared* for a *Write*. This bit is echoed in a Reply. + +- 0xef The remaining 7 bits are not currently used and should be zeroed + in Requests and ignored in Replies. + +Address +~~~~~~~ + +This 3 byte (24 bit) address selects 4 bytes in the 64MB device address +space. + +For example, address 0 selects bytes 0-3 while address 1 selects bytes +4-7. + +MSB order. + +Data +~~~~ + +When Bits[4] is set (Read operation) this field is ignored in Requests +and filled in for Replies. + +When Bits[4] is clear (Write operation) this field contains the value to +be written, which is *echoed* in Replies. + +To read back the actual value of a register after a write operation, a +Read operation with the same address may be added following a Write +within the same message. + +Example message +--------------- + +Request + +.. raw:: html + +
+    00 | 6c656570 89abcdef 
+    08 | 01000000 00000000
+    10 | 00010000 12345678
+    18 | 01010000 00000000
+   
+ +This Request consists of: + +- Arbitrarily chosen Header of 0x6c65657089abcdef +- A read of address 0 (data ignored) +- A write of address 0x10000 with data value 0x12345678. +- A read of address 0x10000 (data ignored) + +A corresponding Reply might be: + +.. raw:: html + +
+    00 | 6c656570 89abcdef 
+    08 | 01000000 48656c6c
+    10 | 00010000 12345678
+    18 | 01010000 00345678
+   
+ +- Header echoed from Request +- Address 0 reads 0x48656c6c +- A write of address 0x10000 with 0x12345678 is echoed. +- Address 0x10000 reads 0x00345678 (perhaps due to truncation) + +Required Registers +------------------ + +0x000000 - 0x000003 +~~~~~~~~~~~~~~~~~~~ + +The first 4 registers will read back the 16 byte constant value “Hello +World!:raw-latex:`\r\n`:raw-latex:`\r\n`”. + +.. raw:: html + +
+   00 | 48656c6c 6f20576f 726c6421 0d0a0d0a
+   
+ +0x000800 - 0x000fff +~~~~~~~~~~~~~~~~~~~ + +These 2048 registers access static configuration data. See section +Configuration ROM. + +If 0x800 has a zero (0) value, then the altnerate ROM location should be +used. + +Alternate ROM location +~~~~~~~~~~~~~~~~~~~~~~ + +Consists of 16384 registers 0x004000 - 0x007fff containing static +configuration data. See section Configuration ROM. + +Configuration ROM Format +------------------------ + +The register range 0x800 - 0xfff holds static data describing the +device. In each 4 byte register, only the 2 lower bytes are used. + +The ROM holds a series of variable length records concatenated together. +Each record begins with a 2 byte Descriptor consisting of a type code in +the upper 2 bits (T), and a 14 bit length (L). The length has units of 4 +byte *registers*. + +.. raw:: html + +
+              0       1         2         3
+         +--------+--------+--------+--------+--------
+      00 |    0   |    0   |TTLLLLLL|LLLLLLLL| Data...
+         +--------+--------+--------+--------+--------
+   
+ +Type 0 +~~~~~~ + +Indicates the end of the ROM. + +Type 1 +~~~~~~ + +The bytes following the Descriptor are an ASCII string. + +When multiple Type 1 headers are encountered, they *must* be interpreted +as: + +1. Label of firmware + +Additional instances may be ignored. + +Type 2 +~~~~~~ + +The bytes following the Descriptor are a variable length integer (in +MSB). + +A length of 10 (20 bytes valid data) is interpreted as a SHA1 hash. + +When multiple Type 2 headers are encountered, they *must* be interpreted +as: + +1. A Hash of the JSON text. +2. Git revision of firmware + +Additional instances may be ignored. + +Type 3 +~~~~~~ + +The bytes following the Descriptor are a zlib compressed (cf. RFC’s +1950, 1951, and 1952) string in the JSON format. This is described in +the JSON Information section. + +Example +~~~~~~~ + +.. raw:: html + +
+    00 | 00004003 00004865 00006c6c 00006f00
+    10 | 00000000
+   
+ +Contains: + +- Type 1 Descriptor with length 3 holding the string “Hello\0”. +- Type 0 Descriptor indicating end of ROM + +JSON Information +---------------- + +The JSON blob encoded in the Configuration ROM will contain a Object +(aka. mapping or dictionary). The keys of this dictionary are symbolic +register names, with the exception of a special name “**metadata**” +which is used to hold device wide information. + +The value associated with each register is also an Object containing the +keys: + +“access”:“r” \| “w” \| “rw” +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Note whether the register may be read and/or written. + +“base_addr”: Number +~~~~~~~~~~~~~~~~~~~ + +The (first) Address of this register. + +“addr_width”: Number +~~~~~~~~~~~~~~~~~~~~ + +Determines number of Addresses which constitute this register. Number of +Addresses is 2 to the power of addr_width. + +:: + + naddrs = 1u< - 0 1 2 3 - +--------+--------+--------+--------+ - 00 | Header... | - +--------+--------+--------+--------+ - 04 | ...Header | - +--------+--------+--------+--------+ - 08 | Bits | Address 1 | - +--------+--------+--------+--------+ - 0C | Data 1 | - +--------+--------+--------+--------+ - 10 | Bits | Address 2 | - +--------+--------+--------+--------+ - 14 | Data 2 | - +--------+--------+--------+--------+ - 18 | Bits | Address 3 | - +--------+--------+--------+--------+ - 1C | Data 3 | - +--------+--------+--------+--------+ - ... Repeat Bits/Address/Data - - -Request and Reply messages have the same format. -Each UDP message, request or reply, is composed of a 8 byte header followed by between 3 and 127 address/data pairs. -Total message size _must_ be at least 32 bytes. -The real maximum limit is the ethernet MTU less transport protocol headers. -For the default 1500 bytes and UDP/IPv4 (42 header bytes) this is 1456 bytes of UDP payload. -Messages size _should_ be a multiple of 8 bytes. -Recipients _must_ truncate messages to a multiple of 8 bytes. - -Message fields are in Most Significant Byte first (MSB or network) byte order. - -It is _suggested_ to pad messages shorter than 32 bytes with reads of address 0. - -## Message Fields - -### Header - -Echoed without modification from Request to Reply. -May be assigned arbitrarily by a Requester to aid in Reply processing. - -### Bits - -This 1 byte field selects the operation in which the Address and Data. - -* 0x10 This least significant bit is _set_ for a _Read_ operation, and _cleared_ for a _Write_. This bit is echoed in a Reply. - -* 0xef The remaining 7 bits are not currently used and should be zeroed in Requests and ignored in Replies. - -### Address - -This 3 byte (24 bit) address selects 4 bytes in the 64MB device address space. - -For example, address 0 selects bytes 0-3 while address 1 selects bytes 4-7. - -MSB order. - -### Data - -When Bits[4] is set (Read operation) this field is ignored in Requests and filled in for Replies. - -When Bits[4] is clear (Write operation) this field contains the value to be written, which is _echoed_ in Replies. - -To read back the actual value of a register after a write operation, a Read operation with the same address may be added following a Write within the same message. - -## Example message - -Request - -
- 00 | 6c656570 89abcdef 
- 08 | 01000000 00000000
- 10 | 00010000 12345678
- 18 | 01010000 00000000
-
- -This Request consists of: - -* Arbitrarily chosen Header of 0x6c65657089abcdef -* A read of address 0 (data ignored) -* A write of address 0x10000 with data value 0x12345678. -* A read of address 0x10000 (data ignored) - -A corresponding Reply might be: - -
- 00 | 6c656570 89abcdef 
- 08 | 01000000 48656c6c
- 10 | 00010000 12345678
- 18 | 01010000 00345678
-
- -* Header echoed from Request -* Address 0 reads 0x48656c6c -* A write of address 0x10000 with 0x12345678 is echoed. -* Address 0x10000 reads 0x00345678 (perhaps due to truncation) - -## Required Registers - -### 0x000000 - 0x000003 - -The first 4 registers will read back the 16 byte constant value "Hello World!\r\n\r\n". - -
-00 | 48656c6c 6f20576f 726c6421 0d0a0d0a
-
- -### 0x000800 - 0x000fff - -These 2048 registers access static configuration data. -See section Configuration ROM. - -If 0x800 has a zero (0) value, then the altnerate ROM location -should be used. - -### Alternate ROM location - -Consists of 16384 registers 0x004000 - 0x007fff -containing static configuration data. -See section Configuration ROM. - -## Configuration ROM Format - -The register range 0x800 - 0xfff holds static data describing the device. -In each 4 byte register, only the 2 lower bytes are used. - -The ROM holds a series of variable length records concatenated together. -Each record begins with a 2 byte Descriptor consisting of a type code in the upper 2 bits (T), and a 14 bit length (L). -The length has units of 4 byte _registers_. - -
-           0       1         2         3
-      +--------+--------+--------+--------+--------
-   00 |    0   |    0   |TTLLLLLL|LLLLLLLL| Data...
-      +--------+--------+--------+--------+--------
-
- -### Type 0 - -Indicates the end of the ROM. - -### Type 1 - -The bytes following the Descriptor are an ASCII string. - -When multiple Type 1 headers are encountered, they _must_ be interpreted as: - -1. Label of firmware - -Additional instances may be ignored. - -### Type 2 - -The bytes following the Descriptor are a variable length integer (in MSB). - -A length of 10 (20 bytes valid data) is interpreted as a SHA1 hash. - -When multiple Type 2 headers are encountered, they _must_ be interpreted as: - -1. A Hash of the JSON text. -2. Git revision of firmware - -Additional instances may be ignored. - -### Type 3 - -The bytes following the Descriptor are a zlib compressed (cf. RFC's 1950, 1951, and 1952) string in the JSON format. -This is described in the JSON Information section. - -### Example - -
- 00 | 00004003 00004865 00006c6c 00006f00
- 10 | 00000000
-
- -Contains: - -* Type 1 Descriptor with length 3 holding the string "Hello\0". -* Type 0 Descriptor indicating end of ROM - -## JSON Information - -The JSON blob encoded in the Configuration ROM will contain a Object (aka. mapping or dictionary). -The keys of this dictionary are symbolic register names, -with the exception of a special name "__metadata__" which is used -to hold device wide information. - -The value associated with each register is also an Object containing the keys: - -### "access":"r" | "w" | "rw" - -Note whether the register may be read and/or written. - -### "base_addr": Number - -The (first) Address of this register. - -### "addr_width": Number - -Determines number of Addresses which constitute this register. -Number of Addresses is 2 to the power of addr_width. - -``` - naddrs = 1u<