HP 16500C Notes

This file is part of OpenGPIB.
 For details, see http://opengpib.sourceforge.net

 Copyright (C) 2008-2009 Doug Springer <gpib a t rickyrockrat d o t net>
  
    OpenGPIB is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 3
    as published by the Free Software Foundation. Note that permission
    is not granted to redistribute this program under the terms of any
    other version of the General Public License.

    OpenGPIB is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with OpenGPIB.  If not, see <http://www.gnu.org/licenses/>.
   
    The License should be in the file called COPYING.



The HP16500C manuals do not describe the configuration data stream. These notes describe some of the reverse-engineering done to figure out the fields in the configuration data returned from the :SYSTEM:SETUP?
command.

The data stream begins as a block (as described in the programming manual). Here is an example file dump of the start of the config file. Sections are cut out that are not yet decoded.

          0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F
00000000  23 38 30 30  32 32 30 31  36 30 43 4f  4e 46 49 47   #800220160CONFIG
00000010  20 20 20 20  02 22 00 00  80 c8 4d 41  43 48 49 4e       ."....MACHIN
00000020  45 20 31 20  00 00 00 00  00 01 00 00  00 00 00 00   E 1 ............
00000030  00 00 00 00  00 02 ff ff  ff ff 00 20  00 06 00 20   ........... ...
00000040  00 06 00 66  00 00 00 2a  aa aa ff ff  ff ff ff ff   ...f...*........
00000050  ff ff ff ff  ff ff ff ff  ff ff 4d 41  43 48 49 4e   ..........MACHIN
00000060  45 20 32 20  00 00 00 00  00 00 00 00  00 00 00 00   E 2 ............
00000070  00 00 00 00  00 02 ff ff  ff ff 00 20  00 18 00 20   ........... ...
00000080  00 18 00 78  00 00 00 2a  aa aa ff ff  ff ff ff ff   ...x...*........
00000090  ff ff ff ff  ff ff ff ff  ff ff 00 00  00 04 00 1f   ................
000000a0  ff e0 00 00  00 00 00 00  00 00 00 00  00 00 00 00   ................

00000270  ff ff 00 00  00 00 00 00  00 00 00 00  01 4a ff ff   .............J..
00000280  ff ff 00 00  00 00 00 00  00 00 00 00  00 64 ff ff   .............d..
00000290  ff ff 00 00  43 4c 4b 20  20 20 00 00  00 00 00 af   ....CLK   ......
000002a0  df 30 00 00  00 00 01 01  01 37 44 49  4f 31 20 20   .0.......7DIO1 
000002b0  00 00 00 01  00 af df 3c  00 00 00 00  01 01 02 37   .......<.......7
000002c0  44 49 4f 32  20 20 00 00  00 01 00 af  df 48 00 00   DIO2  .......H..
000002d0  00 00 01 01  03 37 52 2f  4c 20 20 20  00 00 00 01   .....7R/L   ....
000002e0  00 af df 54  00 00 00 00  01 00 04 37  50 4f 4c 20   ...T.......7POL
000002f0  20 20 00 00  00 01 00 af  df 60 00 00  00 00 01 01     .......`......
00000300  05 37 4c 44  20 20 20 20  00 00 00 01  00 af df 6c   .7LD    .......l
00000310  00 00 00 00  01 01 06 37  30 45 20 20  20 20 00 00   .......70E    ..


Looking at the dump above, you can clearly see the two machine names, so that's pretty obvious.  
Byte 29 tells us this machine 1 is in timing mode.  Byte 31 tells us we are using full channel mode.
For some reason, the pod assignment map (3D, 41, and 43) is duplicated places (at least in the timing mode I tested). It tells us pod 1/2 is assigned to machine 1. You'll note that machine 2 has pod 3/4 assigned to it, but since it is off, the point is moot.

Here is the C structure for the two machine entries above:

#define POD_INFO_A1 0x02
#define POD_INFO_A2 0x04
#define POD_INFO_A3 0x08
#define POD_INFO_A4 0x10
/**10 bytes  */
struct pod_assignment {
    uint8 unknown1[3];
    uint8 pod_info0; /**pod_info0 and 1 always seem to be equal to each other No pods=0 */
    uint8 unknown2[3];
    uint8 pod_info1;
    uint8 unknown3;
    uint8 pod_info2; /**this is 0x06 with no pods assigned to either analyzer, 0x66 if pod1/2, 0x78 if pod 3/4, 0x1E if pod1,2,3,4.  */
}__attribute__((__packed__));   
/**defines for the mode byte below  */
#define MACHINE_MODE_OFF         0
#define MACHINE_MODE_TIMING 1
#define MACHINE_MODE_STATE    2
#define MACHINE_MODE_CMP_SPA 3
/*defines for mode2 below */
#define MACHINE_MODE2_FULL 0
#define MACHINE_MODE2_HALF 1
/*64 bytes per machine config*/

struct machine_config {
    char name[11];
    uint8 unknown3[4];
    uint8 mode;    /**0=off,1=timing,2=state,3=statecompare or SPA  */
    uint8 unknown4[7];
    uint8 mode2;     /*0=fullchannel, 1=half channel*/
    uint8 unknown5[8];
    struct pod_assignment assign;
    uint8    un[22];
}__attribute__((__packed__));   



The label sections begin at 294. If you look at just this section (22 bytes per line):

43 4C 4B 20 20 20 00 00 00 00 00 AF DF 30 00 00 00 00 01 01 01 37
44 49 4F 31 20 20 00 00 00 01 00 AF DF 3C 00 00 00 00 01 01 02 37

|Label              |         B P       ADDR                   B  E  S

 You will see that it starts with a label name that is always 6 bytes. The above above bits are as follows:
B=#bits (lines) for this signal - it seems to be repeated twice, so I assume one means something else.
E=enabled
S=Sequence #
ADDR is an offset further into the code to the bit positions. After *much* scrounging about, I came up with this formula: Take the address here (i.e. AFDF30) subtract AF6BFC from it and you get the real absolute (i.e. beginning of file) offset.

At this address you will find the following bit fields

00 00 00 00 00 00 00 00 00 00 00 00
?J ?? H4L  H3L H2L  H1L ????

Decoding, I suspect the top 2 bytes are the clock. The J is for J Clock. The H4L means High byte Low byte for pod 4.

Here are the C structures  and defines for this:


#define LABEL_RECORD_LEN 22
#define LABEL_MAP_LEN 12
#define POD_ARRAYSIZE 10

struct label_map {
    /**offset 0= hi byte.  */
    uint8 clk_pods[POD_ARRAYSIZE]; /**0 and 1 index are clk, 2 idx is hi byte of pod4  */
    uint8 unknown;
}__attribute__((__packed__));   

T
struct labels {
    char name[6];
    uint8 unknown1[3];
    uint8 polarity;
    uint8 unknown2;
    uint8 strange_offset;
    uint16 strange_offsetlo;
    uint8 unknown3[4];
    uint8 bits;
    uint8 enable;
    uint8 sequence;
    uint32 actual_offset;
    struct label_map map;
}__attribute__((__packed__));