HP 3457A multimeter LCD display protocolAs several of you asked for it, this is the protocol of the HP LCD display
- Electrical lines description
A 34 pin HE10 connector is used on the HP 3457A digital motherboard (same as those used for the 3.5" floppy drives). The ribbon cable attached is cut in two parts: pins 1 to 16 for the keyboard and pins 17 to 32 for the LCD display (pins 33 and 34 are NC).
Below is the pinout and the description of the LCD part of this HE10 connector.
(NC) 17|18 (V3V: power supply for the LCD)
(instruction line: ISA) 19|20 (V2V: power supply for the LCD)
(1 = read data on ISA / 0 = read data on INA: SYNC) 21|22 (V1V: power supply for the LCD)
(NC) 23|24 (GND)
(data line: INA) 25|26 (OS1: for internal oscillator of the LCD display ; connected to a 470pF capacitor on the motherboard)
(second clock, same as O1 with a small delay: 02) 27|28 (NC)
(clock: 01) 29|30 (NC)
(global chip select: PWO) 31|32 (VCC: +5V with a serial resistor of 1k on the motherboard)
(NC) 33|34 (NC)
So this is a serial synchronous transmission, and for us there are 5 interesting lines: PWO, 02 clk, SYNC, ISA and INA. With these lines we are able to completely decode the protocol of the LCD display. (note: O1 and O2 clocks are exactly the same, but the O2 line is 6µs late compared to O1. We will use rising edge of O2 clock to sample the data, because it has the best timing (middle of each data bit)).
Note: the pinout of the DIL connector (LCD end of the ribbon cable) is given on my schematic that I will publish soon. Basically, pin 17 of the HE10 goes to pin 1 of the DIL support, pin 18 on pin 2, ... and pin 32 on pin 16!
Let's observe a capture of a full frame (once received, this frame will display the above text "BEEP,-99999.1_", with two annunciators lit : "SMPL" & "MATH"):
Description of each line:PWO: this is the global chip select, when at level "1", the LCD display is selected and must read the data.
CLK 02: this is the clock for the data received on ISA and INA lines. Max clock frequency is 55kHz (may be less, I guess it depends on the processor load).
SYNC: this line is at level "1" when the data must be read on ISA line / at level "0" when the data must be read on INA line. On the above screenshot, the SYNC line goes "high" 7 times, meaning there are 7 instructions sent on ISA line
ISA: this line sends the instructions to the LCD display, I have found 7 types of instructions:
- 0x3F0: select the LCD display (1 byte)
- 0x2E0: ?
- 0x320: toggle display ON/OFF
- 0x2F0: annunciators ON/OFF ("SMPL", "REM", "SRQ", "ADRS", "AC+DC", "4W", "AZOFF", "MRNG", "MATH", "REAR", "ERR", "SHIFT") (2 bytes)
- 0x028: write A registers (6 bytes)
- 0x068: write B registers (6 bytes)
- 0x0A8: write C registers (6 bytes)
INA: this line sends the data to the LCD display (eg the values to display on the digits)
Chip Select: is not a line from the motherboard, it is generated by my board with a bit of logic (we will see why later)
Let's zoom on the complete frame:
complete frame (very large image)We can see 7 instructions sent on the
ISA line in this order: 0x3F0, 0x2E0, 0x320, 0x2F0, 0x0A8, 0x028, 0x068. Some frame will have less instructions, in fact, only the data that change are re-transmitted (if you press the "SINGLE" button of the DMM, the data are sent once to the LCD display, then nothing changes, so nothing is transmitted anymore (to be exact, when nothing changes, the data are retransmitted each 2 minutes or so).
Below is a screenshot of two successive frames, one has 7 instructions, the following only has 4 instructions, because only the annunciator changed:
The
INA line shows the data that follow each instruction. In the following section we will describe the useful sections more in-depth.
- Examining the first instruction: 0x3F0 = select the display
General info about the transmission:- Each bit are transmitted reverse, ie the bit 0 (= Least Significant Bit) of a register is sent first ...
- The same apply for the digits: digit 12 (the last one) is transmitted first ...
Let's observe the first instruction received on the above complete frame: 0x3F0:
The doc I found says this instruction is to select the display, and the display is selected when the data received on INA line is 0xFD. Let's verify!
Let's check the
instruction between C1 and C2 markers first: remember that instructions are sent on
ISA line when SYNC line is at level "1". On the above screenshot, we can see that we received these bits:
0000111111 (10 bits).
Also remember that the bits are sent in reverse order, so once reordered, the data on ISA line is:
1111110000 = 0x3F0 = select the LCD display command
Now we are going to check the
data between A1 and A2 markers: remember that data are sent on
INA line when SYNC line is at level "0". On the above screenshot, we can see that we received these bits:
10111111 (8 bits).
Also remember that the bits are sent in reverse order, so once reordered, the data on INA line is:
11111101 = 0xFD = select the LCD display value
What about the
bits received between C2 and A1 markers ? (two clock pulses)
There are
always these two bits, whatever the line (ISA or INA), and they are always 0. The useful data always starts after these 2 bits, and are then sent on a multiple of 8 bits.
In other words, each transmission of data starts with a 10 bits set, followed by n 8 bits sets. But since the first 2 bits are always 0, we can ignore them and consider that the data are only composed of 8 bits sets.
Ignoring these 2 bits is not an easy task for the microcontroller, because it is not designed to receive a variable length of data on the SPI bus
For this reason, I have added a bit of logic (two D flip-flop to delay the
SYNC signal and an XOR gate to generate my
"Chip Select"). With this logic, I am able to decode directly the data from the HP 3457A using the hardware SPI module from the Atmel microcontroller (the
"Chip Select" line directly drives the CS input of the Atmel: the CS input is only enabled when at logic level "0"
).
Ok, I hope you have understood how the frame is built, so now let's decode the interesting part of the frame: the data sent to the digits
We will ignore the useless (for the mod) instructions (0x2F0, ...) and we will decode the 0x028 / 0x068 / 0x0A8 instructions. There are 3 registers of 6 bytes each = 18 bytes in total to describe the 12 chars of the display + the punctuation. Each register is set by one instruction received on ISA line: 0x028 for register A, 0x068 for register B and 0x0A8 for register C.
This screenshot shows the complete decoding of the
0x028 command (values for register A), up to the next command
0x068.
The principle for decoding this instruction is exactly the same as for the "First instruction: 0x3F0", so refer to this section to understand it
The data set received for register A is (hexadecimal): 1F 99 99 D9 50 25
Note that there are 6 more bytes transmitted after these 6 bytes, but they are
always 0, so we don't bother to retrieve and decode them (I don't know the purpose of these bytes).
This is screenshot for 0x068 command = values for register B:
The exact same principle applies to decode it, and the data set received is: 31 37 33 23 0D 00
Similarly, the register C (0xA8 command) will decode as: 00 00 00 00 00 00
Ok, so "BEEP,-99999.1_" is displayed on the screen, and we have 3 registers, containing the following values ... how to match them?
reg A = 1F 99 99 D9 50 25
reg B = 31 37 33 23 0D 00
reg C = 00 00 00 00 00 00
After much research for "HP LCD charset" and other similar things, I ended-up finding this little treasure: the complete doc of a ROM for the HP41C! This is a calculator that contains a LCD display with a similar protocol as the one used on the DMM ; thanks HP for the good consistency between the products
This is here:
http://www.series80.org/Misc/ZenROM.pdfThe most interesting info are on page 115 and following (section 8.2 "Display handling"):
- description of the format of the frames
- description of the instructions (some are missing, like the 0x2E0, but it's enough to understand the protocol)
- and the most interesting: the HP character set for the LCD display!
Below is a reproduction of this charset, with the value for each char (eg, char 'X' has value "0x18")
Each byte of register A contains 4 LSB bits for each digit (meaning there are the LSB part of 2 digits in each byte)
Similarly, each byte of register B contains 2 MSB bits for 2 digits and 2 bits for the punctuation of 2 digits
And, each byte of register C contains the Extended bit for 2 digits.
Below is a table that represents the 6 bytes received for each registers (A, B & C), and the matching digits data.
----------------------------------------------------------------------------------------------------------------------
|Byte nr received | 1 | 2 | 3 | 4 | 5 | 6 |
----------------------------------------------------------------------------------------------------------------------
|Digit number | 11 | 12 | 9 | 10 | 7 | 8 | 5 | 6 | 3 | 4 | 1 | 2 |
----------------------------------------------------------------------------------------------------------------------
Char value is given by retrieving the following bits from register A, B & C:
(The first line represents the 7 bits of the char value ; this value directly matches the HP charset showed above)
(The second and third line show which register and bit needs to be read to retrieve the char value. Eg, "RegB3_bit1" means Register B, byte 3, bit 1)
------------------------------------------------------------------------------------------------------------------------------
| bit number for one char | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
------------------------------------------------------------------------------------------------------------------------------
| pos in the reg. for even digits | RegCn_bit0 | RegBn_bit1 | RegBn_bit0 | RegAn_bit3 | RegAn_bit2 | RegAn_bit1 | RegAn_bit0 |
------------------------------------------------------------------------------------------------------------------------------
| pos in the reg. for odd digits | RegCn_bit4 | RegBn_bit5 | RegBn_bit4 | RegAn_bit7 | RegAn_bit6 | RegAn_bit5 | RegAn_bit4 |
------------------------------------------------------------------------------------------------------------------------------
Lets apply this table to our example. Remember we got these values in the registers:
reg A = 1F 99 99 D9 50 25
reg B = 31 37 33 23 0D 00
reg C = 00 00 00 00 00 00
So if we want to
decode digit 4 for example, using the first table, we know that digit 4 data are stored in byte number 5:
Digit 4 data are 50 (reg A), 0D (reg B), 00 (reg C). Written in binary, this is:
01010000 (reg A), 00001101 (reg B), 00000000 (reg C)
Now we use the second table to decode the char ; digit 4 is an even number, so decoding is done using these bits:
| RegC_bit0 | RegB_bit1 | RegB_bit0 | RegA_bit3 | RegA_bit2 | RegA_bit1 | RegA_bit0 |
| 0 | 0 | 1 | 0 | 0 | 0 | 0 |
= 0010000 = 0x10
Last, we use the HP charset to see that char 0x10 is the letter 'P', eg what was expected
(forth digit of "BEEP,-99999.1_" text)
The punctuation is transmitted in the register B, using the exact same principle as above.
-------------------------------------------------------------
| bit number for the punctuation | 1 | 0 |
-------------------------------------------------------------
| pos in the reg. for even digits | RegBn_bit3 | RegBn_bit2 |
-------------------------------------------------------------
| pos in the reg. for odd digits | RegBn_bit7 | RegBn_bit6 |
-------------------------------------------------------------
And the charset for the punctuation is this one:
--------------------
|Value | Sign |
--------------------
| 0 | (none) |
| 1 | . (point) |
| 2 | : (colon) |
| 3 | , (comma) |
--------------------
(note: the annunciators are transmitted separately in another instruction)
Lets apply this table to our example. Remember we got these values in the registers:
reg A = 1F 99 99 D9 50 25
reg B = 31 37 33 23 0D 00
reg C = 00 00 00 00 00 00
So if we want to
decode punctuation for digit 10 for example, using the first table, we know that digit 10 data are stored in byte number 2:
So, digit 10 data is 0x37 (reg B) = 00110111 (reg B)
Now we use the punctuation decoding table ; digit 10 is an even number, so decoding is done using these bits:
| RegB_bit3 | RegB_bit2 |
| 0 | 1 |
= 0b01 = 1
Last, we use the charset for the punctuation to see that value 1 corresponds to punctuation '.' (point), eg what we expected
(punctuation for 10
th digit of "BEEP,-99999.1_" text)
Remember, the annunciators are the functions "SMPL", "REM", "SRQ", "ADRS", "AC+DC", "4W", "AZOFF", "MRNG", "MATH", "REAR", "ERR", "SHIFT" below the display.
They are send just after the instruction 0x2F0, like in the screenshot below:
As always, the instruction is between C1 & C2 markers. Decoding the instruction gives 0x2F0, which indicates that the annunciators will follow on
INA line.
Decoding the annunciator is really simple: they are sent on INA line between markers D1 & D2, and there is one bit per annunciator. The only difficulty is that they are written reverse (as always), so the first transmitted bit is the last annunciator.
---------------------------------------------------------------------------------------------------
| annunciator | SMPL | REM | SRQ | ADRS | AC+DC | 4Wo | AZOFF | MRNG | MATH | REAR | ERR | SHIFT |
---------------------------------------------------------------------------------------------------
| bit position | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
---------------------------------------------------------------------------------------------------
Applied to our example, we have bit's positions 4 and 12 which are at level "1", meaning that "MATH" indicator and "SMPL" indicators are ON
- This is the key documentation, starting at page 115, it gives the instructions supported by the display, and the complete charset:
http://www.series80.org/Misc/ZenROM.pdf- This one shows the representation of the HP charset on 14 segments display (the chars are scattered at various places, and some symbols are missing) :
https://www.pungerer.net/pfx/MesPockets/HP/hp41cv/QuickCards/HP41QuickGuideSunthProgA.jpg- The service manual of the HP 3478A for the description of the LCD display lines (page 141, section 7-F-66):
http://www.arimi.it/wp-content/Strumenti/HP/Multimetri/hp-3478a-Service.pdfThat's the end! I have spent a lot of time writing this "spec" ; I hope it will benefit to someone!
Feel free to ask if something is unclear or poorly written ...