==========================================================
 HP 34970A Data Acquisition Unit - communication protocol
==========================================================

:Author: David Douard
:Category: Electronics
:Tags: HP, 34970A, DMM, repair, test equipment
:series: HP 34970A repair
:JavaScripts: default.js, WaveDrom.js
	 
In order to build a replacement display for the HP34970A data
acquisition unit, I needed to understand the communication protocol
between the CPU board and the front panel assembly.

General description
===================

The unit is built with four boards:

- A1 is the main bard, with the PSU, the main controller and the floating logic,

- A2 is the front panel with the display and the keypad,

- A3 is the backplane on which I/O modules are plugged,

- A4 is the (optional) internal 6.5 digits DMM.

.. image:: {filename}/images/hp34970a/block_diagram.svg
   :alt: System Block Diagram of the HP34970A.

  
The commnucation between the different system blocks is done with
asynchronous serial links. They use the rather uncommon bit rate of
187500 baud, with a classic 8N1 schema.


The CPU <-> Display Panel communication protocol
================================================

The communication protocol between the main controller (CPU) board and
the display panel (DP) consists in "datagrams" sent using the general
pattern:

- when a device (CPU or DP) wants to take control of the communication
  bus, it sends a ``Start of Transmission`` (SoT) signal (0x66),

- each sent char (but the end of transmission) must be acknowledged
  (ack value may vary),

- at the end of a communication, the initiator send a "End of
  Transmission" (EoT, 0x55). This sent value is not acknowledged.

- the keyboard can interrupt a CPU->DP communication in progress by
  not acknowledge a received byte, but sending a SoT instead of the
  expected ACK value,

- acknowledge values are:

  - 0x99 as a response to the SoT,

  - 0x00 otherise


The CPU->DP transmission protocol looks like:

.. wavedrom::

   { signal: [
     {name: "Rx", wave: "z3x4x4x=x=x|.=x3x", data: ["0x66", "CMD", "LEN", "D0", "D1", "Dn", "0x55"] },
     {name: "Tx", wave: "zx5x5x5x5x5x|.5x.", data: ["0x99", "0x00","0x00", "0x00", "0x00", "0x00"] },
     ]}

Two (or more) datagrams can be transmitted in a single "transmission",
ie. without sending the EoT byte, eg.:

.. wavedrom::

   { signal: [
     {name: "Rx", wave: "z3x4x4x|=x3x4x|3x", 
      data: ["0x66", "0x0C", "0x03", "D3", "0x66", "0x0A", "0x55"] },
     {name: "Tx", wave: "zx5x5x5x|5x5x5x|x", 
      data: ["0x99", "0x00", "0x00", "0x00", "0x99", "0x00"] },
     ]}

     
When the user press a key on the front panel, a slightly simpler "packet transmission" occurs:

.. wavedrom::

   { signal: [
      {name: "Rx", wave: "zz5x5xx", data: ["0x99", "0x00"]},
      {name: "Tx", wave: "z3x4x3x", data: ["0x66", "KP", "0x55"]},
      ]}


Sending data to the main display
================================

The main display consist in 13 17-segments digits, in which the
character is displayed by a main 14-digits, and the punctuation with 3
segments (2 dots and a comma, allowing to represent the signs ".",
",", ":" and ";"). Punctuation signs are also very close to the
preceding chracters.

.. image:: {filename}/images/hp34970a/digit.jpg
   :alt: 17-segments digit of the main display.
	 
The command used to send text to the main display is ``0x00``. The
character ``0x09`` (tabulation) has a special meaning: it marks the
beginning and the end of a part of the text to be displayed darker
than the usual. This is used to emphasis a portion of the displayed
text. Also, as the punctuation signs do not consume a digit, the
displayed text can be larger than 13 characters.


Sending data to the Channels display
====================================

This area only allows to display 3 7-segments digits. The command is
``0x0C``, the payload is thus 3 bytes long.

.. image:: {filename}/images/hp34970a/channel.jpg
   :alt: The display area dedicated to current channel.
   :align: center

Flags
=====

The display also has several flags. Display flags are selected by
sending the ``0x0A`` command. The payload is 4 bytes long.  Each bit
of these 4 bytes represent a flag on the display.

Let's consider the following (we don't represent the acknowledgements here):

.. wavedrom::

   { signal: [
     {name: "Rx", wave: "z344====3x",
      data: ["0x66", "0x0A", "0x04", "F1", "F2", "F3", "F4", "0x55"]}
     ]}

Then the flags I've identified so far are:

.. wavedrom::
   
   { signal: [
   {name: "bit", wave: "z========z", 
    data: ["7", "6", "5", "4", "3", "2", "1", "0"]},

   {name: "F1",  wave: "z=3333333z", 
    data: ["", "HI", "Alarm", "LO", "Channels", "Ch. frame", "Mx+B", "<Bell>"]},
   {name: "F2",  wave: "z===33333z", 
    data: ["", "", "", "4W", "1", "3", "4", "2"]},
   {name: "F3",  wave: "z========z", 
    data: ["", "", "", "", "", "", "", ""]},
   {name: "F4",  wave: "z=3=333==z", 
    data: ["", "CONFIG", "", "MON", "VIEW", "*", "", ""]},
    ],
    config: { hscale: 2 },
    }

     



Keypad
======

Note that the front panel sends a "key press event" and a "key
released event", depending on the value of the bit 7:

:0: key pressed
:1: key released

The bit 8 of the key event byte is set high for the knob.

.. wavedrom::

   {signal: [
   
   {name: "bit", wave: "z========z", 
    data: ["7", "6", "5", "4", "3", "2", "1", "0"]},
   {name: "KP", wave: "z34=.....z", 
    data: ["Knob", "Key", "Key Code"]},
    ],
    config: { hscale: 1 },
    }


The key codes are:

:0x00: View
:0x01: Mon
:0x02: Sto/Rcl
:0x03: Scan
:0x04: Alarm
:0x05: Mx+B
:0x06: Measure
:0x07: Interval
:0x08: Card Reset
:0x09: Close
:0x0A: Open
:0x0B: Read
:0x0C: Shift
:0x0D: Write
:0x0E: Left
:0x0F: Right

:0x10: Advanced
:0x11: Step

For the knob (including the "Knob" bit):
:0x80: Knob left 
:0x81: Knob right 
