Author Topic: HP 3478A: How to read/write cal SRAM  (Read 54331 times)

0 Members and 1 Guest are viewing this topic.

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #150 on: March 15, 2024, 02:54:57 pm »

You may want to try a different AR488 firmware version and see if this fixes your problem.

I recently had users of my software getting checksum errors when they tried to read the meter calibration. I found that this was caused by problems with specific AR488 firmware versions. My program works with AR488 0.49.14 but fails with AR488 0.51.18.

I'm very happy to report that the problem has gone away using AR488 V0.49.14

Code: [Select]
Version 12-29-22
Gain encode/decode algorithm thanks to: Steve1515 (EEVblog) and fenugrec (EEVblog).
Windows XP Service Pack 3 Platform ID 2
Config file loaded.
Arduino COM delay 1100ms
Debug ON.
Command delay = 0ms.
Max COM port = 64.
OC:Open COM33 CheckCom.
CheckCom start COM33
CheckCom end CreateFileA COM33
CheckCom port found
CheckCom end CloseHandle COM33
OC:Open COM33 open port.
OC:Open COM33 OK.
CA:Start CheckAdapter on COM33
CA:Check Prologix GPIB adapter. ProVer =:"GPIB"
QS: Send:"++ver" Reply:""
CA:Prologix not found. ++ver retry for Arduino.
CA:Retry ++ver (Arduino boot delay)
-r CA:Retry: Found Prologix adapter (Arduino retry).
CA:Exit checkAdapter on COM33
COM port set to COM33
IG:Start InitGPIB
IG:Find Prologix GPIB adapter.
IG:ProVer srch:"GPIB"
IG:Found Prologix adapter.
IG:set ++mode 1.
IG:set eot_enable 0.
IG:set read timeout:++read_tmo_ms 3000
IG:SetGPIB Address ++addr 23 success.
IG:set EOI 0.
IG:set EOS 0.
IG:Set auto talk mode off: ++auto 0  success.
IGT:QSB result 1
Instrument address set to GPIB 23
3478A using current instrument settings.
3478A connected.
Instrument start
Instrument stop/local
Instrument stop/local
CF:LogPath: Z:\home\david\Downloads\HP3478A\log\:Z:\home\david\Downloads\HP3478A\cfg\
Reading calibration data.
**********
Verify checksums.
@@@BICADLNELM : CkSum = (205 + 50) Checksum OK.
@@@@BIADLALMF : CkSum = (214 + 41) Checksum OK.
@@@@@@ACCA@OG : CkSum = (247 +  8) Checksum OK.
IIIIIEADOCCKC : CkSum = (179 + 76) Checksum OK.
@@@@@@ADLDNML : CkSum = (220 + 35) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.
IIHI@HAEMCEKI : CkSum = (185 + 70) Checksum OK.
IIIF@CALNCOJN : CkSum = (174 + 81) Checksum OK.
IIIIEHALNBAK@ : CkSum = (176 + 79) Checksum OK.
IIIIIE@EEBDKM : CkSum = (189 + 66) Checksum OK.
IIIIIE@EBB@LD : CkSum = (196 + 59) Checksum OK.
IIIIIF@EABEKO : CkSum = (191 + 64) Checksum OK.
IIIIIF@ECL@KH : CkSum = (184 + 71) Checksum OK.
IIIIIFALOOAJ@ : CkSum = (160 + 95) Checksum OK.
IIIIGDBD@EBLC : CkSum = (195 + 60) Checksum OK.
IIIIIGBD@OOJG : CkSum = (167 + 88) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.
IIHI@HBDOLNJE : CkSum = (165 + 90) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.

Reading calibration data complete.
Calibration data checksum valid.
Calibration data saved to:Z:\home\david\Downloads\HP3478A\cfg\HP3478A.cal

I'll study the sketch differences to try and identify the problem, but its not too important for me now.
( I was using latest version 0.51.28 before )
update: the AR488 code appears to have been extensively refactored between the non-working and working versions. it will not be trivial to find the cause of the problem.

hp3478a_utils is now happy with the read calibration too:
Code: [Select]
david@I7MINT:~/Github/hp3478a_utils$ ./hp3478util
************ hp3478util, (c) 2018-2020 fenugrec ************
some missing args.
usage:
***** file input, if applicable
--ascfile -a <filename> ASCII CAL dump
--binfile -b <filename> binary CAL dump (one byte per nibble)
***** action : specify one
-t  test checksums of every record
-p <outfile> create dump with processed bytes (clear 4 higher bits)
-d  dump raw data for every record
david@I7MINT:~/Github/hp3478a_utils$ ./hp3478util -a HP3478A.cal -t
************ hp3478util, (c) 2018-2020 fenugrec ************
entry 0x00: OK (30 mV DC)
entry 0x01: OK (300 mV DC)
entry 0x02: OK (3 V DC)
entry 0x03: OK (30 V DC)
entry 0x04: OK (300 V DC)
entry 0x05: OK ((Not used))
entry 0x06: OK (ACV)
entry 0x07: OK (30 Ohm 2W/4W)
entry 0x08: OK (300 Ohm 2W/4W)
entry 0x09: OK (3 KOhm 2W/4W)
entry 0x0A: OK (30 KOhm 2W/4W)
entry 0x0B: OK (300 KOhm 2W/4W)
entry 0x0C: OK (3 MOhm 2W/4W)
entry 0x0D: OK (30 MOhm 2W/4W)
entry 0x0E: OK (300 mA DC)
entry 0x0F: OK (3A DC)
entry 0x10: OK ((Not used))
entry 0x11: OK (300 mA/3A AC)
entry 0x12: OK ((Not used))
david@I7MINT:~/Github/hp3478a_utils$ ./hp3478util -a HP3478A.cal -d
************ hp3478util, (c) 2018-2020 fenugrec ************
entry # offset (rawgain) gain range
00 000293 14CE5 1.013585 30 mV DC
01 000029 14C1C 1.013606 300 mV DC
02 000000 13310 1.013310 3 V DC
03 999995 14F33 1.013933 30 V DC
04 000000 14C4E 1.013638 300 V DC
05 000000 00000 1.000000 (Not used)
06 998908 15D35 1.014735 ACV
07 999603 1CE3F 1.005829 30 Ohm 2W/4W
08 999958 1CE21 1.005821 300 Ohm 2W/4W
09 999995 05524 1.005524 3 KOhm 2W/4W
0A 999995 05220 1.005220 30 KOhm 2W/4W
0B 999996 05125 1.005125 300 KOhm 2W/4W
0C 999996 053C0 1.005260 3 MOhm 2W/4W
0D 999996 1CFF1 1.005891 30 MOhm 2W/4W
0E 999974 24052 1.024052 300 mA DC
0F 999997 240FF 1.023989 3A DC
10 000000 00000 1.000000 (Not used)
11 998908 24FCE 1.023858 300 mA/3A AC
12 000000 00000 1.000000 (Not used)

Photo shown my adapter.
Thanks everyone for all the help, very much appreciated, David.



Attached image shows difference in read cal using two versions of AR488

« Last Edit: March 15, 2024, 03:16:42 pm by djrm »
 
The following users thanked this post: WaveyDipole

Offline lmester

  • Regular Contributor
  • *
  • Posts: 143
  • Country: us
    • My page
Re: HP 3478A: How to read/write cal SRAM
« Reply #151 on: March 16, 2024, 05:04:50 am »
Here is data from a  user of my program that had the same checksum fail. He also had a checksum fail on the first and third cal entries. That might not be a coincedence. I need to do some more testing and report results to the AR488 author.

2075642-0
 

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #152 on: March 16, 2024, 08:50:19 am »
Here is data from a  user of my program that had the same checksum fail. He also had a checksum fail on the first and third cal entries. That might not be a coincedence. .
There is a bit of a pattern showing.
The third line has an unusual character in the first position, I would expect to see an '@'
The first line checksum is off by one. possibly caused by the wrong character in the 10th position.
The same character appears in the first position of the third line and the 10th position in the first line.

Possible causes are anybody's guess, maybee bad address sent or memory overwriting of received data...
update, just having a look at the AR88 code structure
2075765-0 * Screenshot from 2024-03-16 09-53-55.png (666.19 kB. 1957x1665 - viewed 87 times.)
Kind regards, David.
« Last Edit: March 16, 2024, 09:59:17 am by djrm »
 

Offline lmester

  • Regular Contributor
  • *
  • Posts: 143
  • Country: us
    • My page
Re: HP 3478A: How to read/write cal SRAM
« Reply #153 on: March 16, 2024, 07:50:05 pm »
I just tested with my AR488. Checksum fails on first and third entry when using 0.51.18.

Code: [Select]
AR488 GPIB controller, ver. 0.49.14, 02/03/2021
Reading calibration data.
**********
Verify checksums.
@@@CA@BLLLNLG : CkSum = (199 + 56) Checksum OK.
@@@@CABLLCOLO : CkSum = (207 + 48) Checksum OK.
@@@@@DBLLOELM : CkSum = (205 + 50) Checksum OK.
IIIIIDAEBAOKF : CkSum = (182 + 73) Checksum OK.
@@@@@@AEBMNML : CkSum = (220 + 35) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.
IIIE@BADODEL@ : CkSum = (192 + 63) Checksum OK.
IIII@D@E@MNKG : CkSum = (183 + 72) Checksum OK.
IIIIIA@EDNNJL : CkSum = (172 + 83) Checksum OK.
IIIIII@ECDDKI : CkSum = (185 + 70) Checksum OK.
IIIIII@EABLKE : CkSum = (181 + 74) Checksum OK.
IIIIII@EBBOKA : CkSum = (177 + 78) Checksum OK.
IIIIII@EBMAKD : CkSum = (180 + 75) Checksum OK.
IIIIII@EBDOJO : CkSum = (175 + 80) Checksum OK.
@@@BF@CNOE@MB : CkSum = (210 + 45) Checksum OK.
@@@@BECN@@MMJ : CkSum = (218 + 37) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.
IIIE@BCLCOBKJ : CkSum = (186 + 69) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.

Reading calibration data complete.
Calibration data checksum valid.
Calibration data saved to:D:\HP3478A_6\cfg\HP3478A.cal

#################################################

AR488 GPIB controller, ver. 0.51.18, 26/02/2023
Reading calibration data.
**********
Verify checksums.
@@@CA@BLLGNLG : CkSum = (199 + 51) Checksum Fail.
@@@@CABLLCOLO : CkSum = (207 + 48) Checksum OK.
G@@@@DBLLOELM : CkSum = (205 + 57) Checksum Fail.
IIIIIDAEBAOKF : CkSum = (182 + 73) Checksum OK.
@@@@@@AEBMNML : CkSum = (220 + 35) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.
IIIE@BADODEL@ : CkSum = (192 + 63) Checksum OK.
IIII@D@E@MNKG : CkSum = (183 + 72) Checksum OK.
IIIIIA@EDNNJL : CkSum = (172 + 83) Checksum OK.
IIIIII@ECDDKI : CkSum = (185 + 70) Checksum OK.
IIIIII@EABLKE : CkSum = (181 + 74) Checksum OK.
IIIIII@EBBOKA : CkSum = (177 + 78) Checksum OK.
IIIIII@EBMAKD : CkSum = (180 + 75) Checksum OK.
IIIIII@EBDOJO : CkSum = (175 + 80) Checksum OK.
@@@BF@CNOE@MB : CkSum = (210 + 45) Checksum OK.
@@@@BECN@@MMJ : CkSum = (218 + 37) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.
IIIE@BCLCOBKJ : CkSum = (186 + 69) Checksum OK.
@@@@@@@@@@@OO : CkSum = (255 +  0) Checksum OK.

Reading calibration data complete.
Calibration data not saved. Invalid checksum!
 
The following users thanked this post: WaveyDipole

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #154 on: March 16, 2024, 08:08:05 pm »
I just tested with my AR488. Checksum fails on first and third entry when using 0.51.18.
(note, I changed device ID back to standard 23 from 18 during investigation)

Your data has a very similar pattern to what I've seen.

btw, the program HP3478ACalibration.exe failed with a misleading version error with v0.51.18 though reads calibration successfully with v0.49.14
Code: [Select]
PS C:\Users\David\Downloads\HP3478ACalibration_20200126> .\HP3478ACalibration.exe -f cal.txt -r 18
Reading calibration data from instrument...
ERROR: Failed while reading calibration data from instrument.

Extended Error Information:
Could not communicate with instrument.
PS C:\Users\David\Downloads\HP3478ACalibration_20200126> .\HP3478ACalibration.exe -f cal.txt -r 18
Reading calibration data from instrument...
ERROR: Failed while reading calibration data from instrument.

Extended Error Information:
Invalid GPIB adapter version string.
 

Offline WaveyDipole

  • Frequent Contributor
  • **
  • Posts: 851
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #155 on: March 17, 2024, 11:58:02 am »
I have been keeping an eye on this problem with interest ever since lmester reported it to me on thew AR488 thread. Someone else has now linked this one so I have just been reading up and it is indeed a curious problem. Initially it was suggested this might be related to a code change that resulted in a change to EOI timing. EOI should be signalled with the last character sent and not after it. I am uncertain why that change was made, but this should have been fixed in version 0.51.28. Logic analyzer traces seemed to indicate that the EOI signal is now being generated concurrently with the last character being sent. However, it seems that the problem is still present in 0.51.28 (according to djrm's comment in #150 and lmesters comment on the AR488 thread) so it seems there is something else going on. I also hadn't quite grasped that the problem consistently affects the first and third lines of the output and consistently affects multiple users in exactly the same two lines. That is certainly very odd.

Unfortunately I haven't had a HP3478A to test with for some time, although I appreciate the comparison posted by lmester in post #153. I will investigate further but since I cannot conclusively test, I will have to rely on others being able to do so. I will obviously keep 0.49.14 available in the archive.

David, your observations in #152 are also appreciated. I had noticed however, that in your #136, the wrong character is in position 13. It just so happens that in lmerster's example that the 10th and 13th character are the same but a noteworthy pattern nonetheless. The attnRequired, lonmode and tonmode functions do not come into play in controller mode, but certainly sendToInstrument and read_h will.

I have been trying to refresh my memory on how the dump is generated and found a note that says a W<addr> command is sent to the instrument where <addr> runs from 0 to 255, presumably in a loop. I am assuming that a ++read has to be sent to read each byte in turn? From the dump it would see that a checksum is calculated for every 13 bytes received?

« Last Edit: March 17, 2024, 01:12:17 pm by WaveyDipole »
 

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #156 on: March 17, 2024, 02:32:17 pm »
David, your observations in #152 are also appreciated. I had noticed however, that in your #136, the wrong character is in position 13. It just so happens that in lmerster's example that the 10th and 13th character are the same but a noteworthy pattern nonetheless.
My post #150 has an attachment image showing the bad and good transfers, the data in post #136 has the bad and manually 'corrected' values, I later realised that the error positions were not what I had guessed. clear now? relevant section of image inline below:


I could setup a LA trace on the GPIB lines if it would be any help fixing the problem.
I have now made an additional board to run HP3478ext software, that too is working well now.
 
The following users thanked this post: WaveyDipole

Offline pqass

  • Frequent Contributor
  • **
  • Posts: 726
  • Country: ca
Re: HP 3478A: How to read/write cal SRAM
« Reply #157 on: March 17, 2024, 03:30:27 pm »
I have been trying to refresh my memory on how the dump is generated and found a note that says a W<addr> command is sent to the instrument where <addr> runs from 0 to 255, presumably in a loop. I am assuming that a ++read has to be sent to read each byte in turn? From the dump it would see that a checksum is calculated for every 13 bytes received?

A checksum byte is saved into the cal SRAM when the calibration is saved for each type (DCV,ACV,DCA,ACA,ohms)+range. The W command just reads any addressed byte from that SRAM. The cal SRAM is organzied as 19 records of 13 bytes (11+checksum word). The first record begins at address 01 hex; first byte of the SRAM is ignored.  Three records are unused and there is 8 bytes padding at the end. The checksum word is used to validate the previous 11 bytes of a given record. 

What the control program should be doing is issuing the following command for each SRAM byte requested at the given address:
     W\e\xHH\r++read\r

Where:
      \xHH = byte representing a hex address into a 256 nibble SRAM
      \e = ASCII escape
      \r = ASCII carriage return

Same command as hex:   (hh is the address byte)
57 1B hh 0D 2B 2B 72 65 61 64 0D

But these are the problem commands:
57 1b 0a 0d 2b 2b 72 65 61 64 0d
57 1b 1b 0d 2b 2b 72 65 61 64 0d

It's interesting that the 3rd byte, what should be an unmolested address, happens to be a control code. Hmmm....      Check the escape logic Wavey.
« Last Edit: April 02, 2024, 04:56:13 pm by pqass »
 
The following users thanked this post: WaveyDipole

Offline m k

  • Super Contributor
  • ***
  • Posts: 2009
  • Country: fi
Re: HP 3478A: How to read/write cal SRAM
« Reply #158 on: March 17, 2024, 05:05:16 pm »
My first thought was a corrupted memory where variable width is too narrow.
But maybe it has something to do with values under 0x20.
Advance-Aneng-Appa-AVO-Beckman-Data Tech-Fluke-General Radio-H. W. Sullivan-Heathkit-HP-Kaise-Kyoritsu-Leeds & Northrup-Mastech-REO-Simpson-Sinclair-Tektronix-Tokyo Rikosha-Triplett-YFE
(plus lesser brands from the work shop of the world)
 

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #159 on: March 17, 2024, 05:11:01 pm »
I have now run a pulseview gpib trace and can see missing address bytes in the read commands.
trace is taken when running read cal with HP3478A Control with AR488 V0.51.28

Maybe easier to see in this view:

« Last Edit: March 17, 2024, 05:14:32 pm by djrm »
 
The following users thanked this post: WaveyDipole

Offline lmester

  • Regular Contributor
  • *
  • Posts: 143
  • Country: us
    • My page
Re: HP 3478A: How to read/write cal SRAM
« Reply #160 on: March 17, 2024, 05:27:38 pm »
My code uses the Prologix W command to send the cal RAM address (0-255). It also uses the escape sequence when the address is a Prologix reserved character <CR><LF><ESC> and +.

It does look like there is a problem with the binary write or escape sequence logic.


Code: [Select]
print #main.Terminal,"Reading calibration data."
print #comm,"D2READING CAL"        '"READING CAL" message on meter display


call sleep 10 'Fix for "John AR488" Firmware


y=0
for x = 0 to 255 'Read 256 nibbles

    cp$=chr$(x)

    '<ESC> sequence to send reserved binary chars to Prologix adapter

    select case x

        case 13 '<CR>
        cp$=esc$+cp$

        case 10 '<LF>
        cp$=esc$+cp$

        case 27 '<ESC>
        cp$=esc$+cp$

        case 43 '"+"
        cp$=esc$+cp$

    end select

    'Read instrument config data. Each char contains one nibble.
    ICal$(x)=QuerySERB$("W"+cp$,cr$,1,1)
    if len(ICal$(x))<>1 then
       if DBug then print #main.Terminal,"RC:Fail query W :";ICal$(x);" Len:";len(ICal$(x))
       print #main.Terminal,"Instrument com fail."
       if handle$ <> "NoSave" then
            notice "Instrument com fail. Calibration not read."
       else
           notice "Instrument com fail during calibration data backup!"
       end if         
       InstOK=0:goto [CalAbort] 'Instrument com fail
    end if

    y=y+1:if y>24 then print #main.Terminal,"*";:y=0


next x

'print #main.Terminal,":";ICal$(0);":";asc(ICal$(0)) 'Test for Girlando 0x00 binary send bug

print #main.Terminal,cr$;"Verify checksums."

CRSum=1 'init read data checsum is valid

for x = 0 to 18 'Checksum for 19 cal entries

    cs=0 'Checksum
    for y= 0 to 10 '11 nibbles data in each entry
        nib=asc(ICal$((x*13)+y+1))
        nib=nib and 15 'mask hi nibble
        print #main.Terminal,ICal$((x*13)+y+1);
        cs=cs+nib
        cs=cs and 255 'Truncate to 8 bits
    next y
    dcs=cs

    nib=asc(ICal$((x*13)+12))
    nib=nib and 15 'mask hi nibble
    print #main.Terminal,ICal$((x*13)+12);
    nib=nib * 16 'Shift left 4 bits
    cs=cs+nib
    cs=cs and 255 'Truncate to 8 bits
    nibh=nib

    nib=asc(ICal$((x*13)+13))
    nib=nib and 15 'mask hi nibble
    print #main.Terminal,ICal$((x*13)+13);" : CkSum = (";
    print #main.Terminal,nib+nibh;" ";
    cs=cs+nib
    cs=cs and 255 'Truncate to 8 bits
    if dcs>10 then 'Format text
        print #main.Terminal,"+ ";dcs;") ";
    else
        print #main.Terminal,"+  ";dcs;") ";
    end if   
    if cs=255 then
        print #main.Terminal,"Checksum OK."
    else
        if x=5 or x=16 or x=18 then
            print #main.Terminal,"Checksum fail unused loc-ignore."   
       else       
           print #main.Terminal,"Checksum Fail."
           CRSum=0  'Checksum fail
       end if   
    end if

next x


    print #main.Terminal,cr$;
    print #main.Terminal,"Reading calibration data complete."


    if CRSum=1 then
        print #main.Terminal,"Calibration data checksum valid."
'        if handle$<> "NoSave" then '
            print #main.Terminal,"Calibration data saved to:";CalFileU$
            open CalFileU$ for output as #5
            for x = 0 to 255
                print #5,ICal$(x);
            next x
            close #5
'        end if
    else
        if handle$<> "NoSave" then
          print #main.Terminal,"Calibration data not saved. Invalid checksum!"
          notice "Calibration data not saved. invalid checksum!"
        else
          print #main.Terminal,"Invalid checksum during calibration data read!"
          notice "Invalid checksum during calibration data backup!"
        end if           
    end if   








'====================================================

function QuerySERB$(icmd$,irsp$,blen,timeout)

'This function sends a command, then waits for a response or timeout
'Allows blen # of binary chars to be retrieved.
'icmd$ = command to send
'irsp$ = expected response
'blen  = binary data flag >0 = number of expected bytes
'timeout = # seconds to abort (ms resolution)

    if icmd$<>"" then if lof(#comm) > 0 then rs$ = input$(#comm, lof(#comm)) 'Flush buffer
    if icmd$<>"" then print #comm,icmd$   'Send command if present
    if VTD>0 then call sleep VTD 'Time delay for Arduino adapter
'    if DBug then  print #main.Terminal,"QuerySERB: READ EOI"

    if blen>0 then
        print #comm,"++read eoi"  'Request response wait for EOI
'        if DBug then  print #main.Terminal,"QuerySERB:++read eoi"
    else
        print #comm,"++read eoi"
'   in QueryserB Girlando adapter chokes on this:
'   just use read eoi for now
'        print #comm,"++read ";asc(right$(irsp$,1)) 'Request response no EOI wait for last char in irsp$
'        if DBug then  print #main.Terminal,"QuerySERB:++read "; asc(right$(irsp$,1));":"
    end if
   
'    if DBug then  print #main.Terminal,"QuerySERB: READ EOIx"
    ok = 0              'Start with error flag set
    dl=0                'Binary data length
    er$ = ""            'Instrument response
    RTimeS=time$("ms")  'Init the timer
    while ETime(RTimeS) < (timeout*1000) and ok = 0
        if lof(#comm) > 0 then
            rs$ = input$(#comm, lof(#comm))
            er$ = er$ + rs$
            dl=len(er$)
            if blen<>0  then
            'Use length if length > 0
                if dl>=blen then ok=1       'Got all # bytes?
            else
                'Use ASCII terminator if length = 0
                if instr(er$,irsp$) > 0 then ok = 1 'Found terminating string?
            end if
        RTimeS=time$("ms") 'Init the timer
        end if
        call sleep 1   'Don't be a CPU hog
    wend
'   if counter >0 then print #main.Terminal, "RespQS$: ";counter
     QuerySERB$=er$  'Return string
    if ok = 0 then QuerySERB$=""  'Return null for error
   
'    if DBug then  print #main.Terminal,"QuerySERB Send:";qt$;icmd$;qt$;"QSB Reply:";qt$;er$;qt$;"QSB Delay:";VTD;"ms"
'    if DBug then
'     for n=1 to len(er$):print #main.Terminal, asc(mid$(er$,n,1));"%";:next
'    end if

    if lof(#comm) > 0 then er$ = input$(#comm, lof(#comm)) 'Clear any remaining from buffer
end function


 
The following users thanked this post: WaveyDipole

Offline WaveyDipole

  • Frequent Contributor
  • **
  • Posts: 851
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #161 on: March 17, 2024, 06:05:20 pm »
Thanks Luke. Yes, that also occurred to me when I realised that the first character position in row 3 is the 27th character. So we have the 10th, 13th and 27th characters that are suspect. When looking at how the calibration values reading routine works I then saw this in your HP3478 code:

Code: [Select]
    select case x

        case 13 '<CR>
        cp$=esc$+cp$

        case 10 '<LF>
        cp$=esc$+cp$

        case 27 '<ESC>
        cp$=esc$+cp$

        case 43 '"+"
        cp$=esc$+cp$

    end select

Coincidence? The character codes of the characters that are correctly being escaped in your code seem to coincide with the character positions that are incorrect in the cal data output, except maybe character position 43?

The output shown in #157 is very interesting. Thank you David. You have highlighted the lines with the W command (hex 0x57). One can then see the <addr> byte followed by CRLF (0x0d, 0x0a), except in the 10th and 13th request where we only see CRLF. I am curious whether then same is true in the block for address 43 (0x2b).

Now I need to have a look at my code and figure out what the problem is, but I agree, its likely related to the escaping of certain characters.
« Last Edit: March 17, 2024, 06:18:32 pm by WaveyDipole »
 

Offline WaveyDipole

  • Frequent Contributor
  • **
  • Posts: 851
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #162 on: March 17, 2024, 07:09:53 pm »
Does the cal data reading process set ++eoi 1? Could someone run a test reading the cal data with ++eoi 1 set please and post whether they get a successful read or the same result?
« Last Edit: March 17, 2024, 07:25:43 pm by WaveyDipole »
 

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #163 on: March 17, 2024, 08:31:14 pm »
Does the cal data reading process set ++eoi 1? Could someone run a test reading the cal data with ++eoi 1 set please and post whether they get a successful read or the same result?
Greetings,
 
T
I see in the console that the hp3478.exe program sends a "++eoi 0" command at startup, If I manually send "++eoi 1" afterthe program has started from another shell then a subsequent read of the cal setting succeeds.

hth David

 
The following users thanked this post: WaveyDipole

Offline fenugrec

  • Regular Contributor
  • *
  • Posts: 217
  • Country: ca
Re: HP 3478A: How to read/write cal SRAM
« Reply #164 on: March 17, 2024, 09:08:25 pm »
Am I reading correctly that you guys are sending (as seen on GPIB)  W \r <addr> \n ?

In my code (uses NI libs, tested once or twice on a DOS machine), I was doing " W <addr> \n", in other words no \r at all :

Code: [Select]
cmd[0]='W';
cmd[2]='\n';
for (idx=0; idx < CALSIZE; idx++) {
cmd[1] = (uint8_t) idx;
ibwrt(Dev, cmd, 3);
if (ibsta & ERR) {
printf("wrt problem @ 0x%X\n", idx);
goto badexit;
}

ibrd(Dev, &buf[idx], 1);

It sure looks like there may be some escaping problems in AR488 but removing the \r entirely may help on unpatched firmware ? (cannot test myself)

https://github.com/fenugrec/hp3478a_utils/blob/master/hp3478util.c#L429
 

Offline pqass

  • Frequent Contributor
  • **
  • Posts: 726
  • Country: ca
Re: HP 3478A: How to read/write cal SRAM
« Reply #165 on: March 17, 2024, 09:09:14 pm »
So I ran an experiment...   
I enabled the cal screw on the faceplate and issued this command:
       echo -en "X\e\x0a\x41\r++read\r" >>/dev/ttyUSB0

My good cal was changed from (5th record beginning from hex address 35):

Code: [Select]
$ ./verify.sh pqass.cal
...
000035 49 49 49 49 49 49 42 45 43 4e 4d 4a 44  >IIIIIIBECNMJD< 04: raw_offset=999999 raw_gain=253ed offset=-000001 gain=1.025277 crc=ff  300 V DC
...

to failed record (crc!=ff):

Code: [Select]
$ ./verify.sh /tmp/pqass.redo.cal
...
000035 49 49 49 49 49 49 42 45 43 4e 4d 4a 4d  >IIIIIIBECNMJM< 04: raw_offset=999999 raw_gain=253ed offset=-000001 gain=1.025277 crc=108  300 V DC
...

The difference just happens to be the last (checksum) byte of the record.

What I think happened is the "if (cfg.eoi)...else"  branch (see code below) suppressed the 0A (hex) address byte I was targeting and instead used the next byte 41 (hex) as an address instead with the following byte \r or 0D (hex) as the byte to save at that address.   CORRECTION: the \r would have been suppressed too. Hmmm...   I don't know why exactly a D (hex) was saved but it definitely skipped the first 0A address byte because it changed the byte at 41 (hex)!   CORRECTION to the CORRECTION: the second \r is from when the buffer is split; the 1st half being the X<addr><value> but the <value> is truncated.  ie. the meter is using the end of line marker as the value to save.

The SRAM is really only 4 bits wide so upon readback the meter just puts a 4 (hex) in the upper nibble, hence it returned "M" which is 4D (hex).

From GPIBbus.cpp version 0.51.18:
Code: [Select]
void GPIBbus::sendData(char *data, uint8_t dsize) {
...
  // Write the data string
  for (int i = 0; i < dsize; i++) {
    // If EOI asserting is on
    if (cfg.eoi) {
      // Send all characters
      err = writeByte(data[i], NO_EOI);
    } else {
      // Otherwise ignore non-escaped CR, LF and ESC
      if ((data[i] != CR) && (data[i] != LF) && (data[i] != ESC)) err = writeByte(data[i], NO_EOI);
    }
   
#ifdef DEBUG_GPIBbus_SEND
    DB_RAW_PRINT(data[i]);
#endif

    if (err) break;
  }
...


So how does this differ from AR488.ino 0.49.14:

Code: [Select]
void gpibSendData(char *data, uint8_t dsize) {
...
  for (int i = 0; i < dsize; i++) {
    // If EOI asserting is on
    if (AR488.eoi) {
      // Send all characters
      err = gpibWriteByte(data[i]);
    } else {
      // Otherwise ignore non-escaped CR, LF and ESC
      if ((data[i] != CR) || (data[i] != LF) || (data[i] != ESC)) err = gpibWriteByte(data[i]);
    }
#ifdef DEBUG3
    dbSerial->print(data[i]);
#endif
    if (err) break;
  }
...

For 0.51.18, Wavey "fixed" the
Code: [Select]
if ((data[i] != CR) || (data[i] != LF) ||  ... code given that this will always return true.
« Last Edit: March 17, 2024, 09:40:53 pm by pqass »
 
The following users thanked this post: WaveyDipole

Offline WaveyDipole

  • Frequent Contributor
  • **
  • Posts: 851
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #166 on: March 17, 2024, 10:07:18 pm »
pqass, you kind of beat me to it, but yes, that is the explanation!

I see in the console that the hp3478.exe program sends a "++eoi 0" command at startup, If I manually send "++eoi 1" after the program has started from another shell then a subsequent read of the cal setting succeeds.

hth David

Thank you for test that and the result is as I suspected. It confirms what the problem is.

In order to explain, it is necessary to consider the command sequence that is being sent to the meter in order to retrieve the cal data. To recap the command is:

W<addr>, where <addr> is a single byte containing the memory address of the nibble to be read. Mark that. This is binary data, not text. The data is then followed by CRLF as a "line terminator" because ++eos is set to its default setting.

Now here is the (now repeated) code from 0.49.14 which sends the data:

Code: [Select]
  // Write the data string
  for (int i = 0; i < dsize; i++) {
    // If EOI asserting is on
    if (AR488.eoi) {
      // Send all characters
      err = gpibWriteByte(data[i]);
    } else {
      // Otherwise ignore non-escaped CR, LF and ESC
      if ((data[i] != CR) || (data[i] != LF) || (data[i] != ESC)) err = gpibWriteByte(data[i]);
    }
    if (err) break;
  }

I have removed the debug bit for clarity. We have a loop processing the buffer called data which contains the characters to be sent. In this case, the buffer contains 2 bytes: 0x57 and the <addr> byte, the terminators having been removed at the parsing stage. Note that if ++eoi is set to 1 (EOI asserting is on), then all characters in the buffer are written to GPIB. This is followed by terminators being added on according to to ++eos setting with EOI being signaled on the last character sent.

However, if ++eoi is 0, then the 'else' clause comes into play. In this case, CR, LF and ESC characters are ignored. Why? Because if we are using CR, LF or CRLF as terminators without EOI, then we assume this to be a line of text which should not contain any additional terminator characters except those at its end. Nor should it contain an Escape (hex 0x27) character. However, if we take, for example address 10, we get the sequence: 0x57, 0x0A, then the 0x0A gets filtered but we still get the terminators added on according to the ++eos setting, so what actually gets sent is 0x57, 0x0D, 0x0A. The same would happen for address 13 and address 27.

The problem with the above line is that each condition had been or'ed by mistake. This means that only one of the three conditions needed to be met in order for the statement to evaluate to true. This would result in any unexpected terminators or escape character being sent regardless. The error was corrected in later code by and'ing the conditions and changing the line to:

Code: [Select]
      if ((data[i] != CR) && (data[i] != LF) && (data[i] != ESC)) state = writeByte(data[i], NO_EOI);
Now, as intended, all three conditions must be met for the statement to evaluate to true and for the byte to be sent over GPIB. In short, the filtering now works as intended. The write command is slightly different in the restructured code but the effect is the same. Any unfiltered byte is written to the GPIB bus without using EOI and terminators are added at the end of the transmitted sequence.

The inadvertent consequence of fixing this error has resulted in the behavioral change that has been observed here. In 0.49.14, addresses 0x10, 0x13 and 0x27 will have been sent regardless so reading the cal data worked correctly. In later fixed versions, those characters are no longer sent in text mode so they are omitted and we get an erroneous reading for those addresses. Address 43 (corresponding to the + character) is not affected.

The question that now arises how to deal with this appropriately. On the one hand filtering could be removed so that all characters sent regardless. On the other hand, because we are dealing with bytes rather than ASCII text, ought we to be treating the data as binary and therefore having the HP3478A set to using EOI only as terminator and the AR488 set with ++eoi 1 and ++eos 3 (no terminator characters)? It looks like the meter ignores the trailing CRLF anyway, so perhaps ++eoi 1 and leaving the meter as is would be sufficient? I am open to suggestion and perhaps will also need to re-consider whether the filtering really is necessary or whether it is more of a hindrance and should be removed.
« Last Edit: March 17, 2024, 10:34:30 pm by WaveyDipole »
 

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #167 on: March 17, 2024, 10:18:23 pm »
Am I reading correctly that you guys are sending (as seen on GPIB)  W \r <addr> \n ?
The trace I made shows (#159) W<addr>\r\n but in some cases the <addr> is missed out and the subsequent \r gets interpreted as the address.
David.
« Last Edit: March 17, 2024, 10:27:18 pm by djrm »
 

Offline fenugrec

  • Regular Contributor
  • *
  • Posts: 217
  • Country: ca
Re: HP 3478A: How to read/write cal SRAM
« Reply #168 on: March 17, 2024, 10:34:28 pm »
On the one hand filtering could be removed so that all characters sent regardless. On the other hand, because we are dealing with bytes rather than ASCII text, ought we to be treating the data as binary and therefore using ++eoi 1? I am open to suggestion and perhaps will need to consider whether the filtering really is necessary.

As I recall (haven't worked on this in 3y), the prologix docs had a few grey areas wrt terminations. Here's how I interpreted and implemented in my firmware :

1- filter incoming bytes from host :
 - skip (don't change) escaped chars
 - convert unescaped \r to \n,
 - interpret \n as "end of chunk" and mark it.
There may thus be two \n in a row after a conversion from \r to \n, but that is not a problem in later steps

2- parse chunks as either command or data, un-escaping as required.

3- if data, send on bus with EOS and EOI as required (There is no ambiguity on which chars must be sent on the bus, vs chunk termination from host)
« Last Edit: March 17, 2024, 10:46:52 pm by fenugrec »
 

Offline pqass

  • Frequent Contributor
  • **
  • Posts: 726
  • Country: ca
Re: HP 3478A: How to read/write cal SRAM
« Reply #169 on: March 17, 2024, 10:40:40 pm »
So what to do if EOI isn't on - that is, rely on \r or \n (or combo), whatever eos is set to, to signal an end of message.
Stripping \r \n \e is currently a silent error since it can have side-effects to commands that accept binary data.

How do you currently treat fatal errors like bus problems to control programs?  Do you send error messages back?
I think I recall seeing errors returned If verbose mode is on.  Maybe you can return a message to say "\r \n \e were stripped, use eoi=1".
At least if the user turns on verbose mode then he'll see it.
 

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #170 on: March 17, 2024, 11:05:10 pm »
The question that now arises how to deal with this appropriately. On the one hand filtering could be removed so that all characters sent regardless. On the other hand, because we are dealing with bytes rather than ASCII text, ought we to be treating the data as binary and therefore having the HP3478A set to using EOI only as terminator and the AR488 set with ++eoi 1 and ++eos 3 (no terminator characters)? It looks like the meter ignores the trailing CRLF anyway, so perhaps ++eoi 1 and leaving the meter as is would be sufficient? I am open to suggestion and perhaps will also need to re-consider whether the filtering really is necessary or whether it is more of a hindrance and should be removed.

I have limited experience of GPIB (now on my third day) but expecting a change in the reader programs eoi setting is a separate issue to fixing the bug. The old interface worked ok  and the new one will with the bug corrected, the meter doesn't seem to care about the eoi setting. I'd be happy to use the new software with the bug corrected without any other changes.

Kind regards, David.
 
The following users thanked this post: WaveyDipole

Offline lmester

  • Regular Contributor
  • *
  • Posts: 143
  • Country: us
    • My page
Re: HP 3478A: How to read/write cal SRAM
« Reply #171 on: March 18, 2024, 04:32:19 am »
I have a real Prologix adapter. I did some testing with this adapter. I can properly read cal data with EOI 1 or EOI 0.  The AR488 adapter only reads cal properly with EOI 1.

Is it better to exactly match the behavior of the Prologix adapter or keep AR488 how it's operating now?

I would say match the behavior of the Prologix adapter since AR488 is a replacement for the Prologix.

 
The following users thanked this post: WaveyDipole

Offline m k

  • Super Contributor
  • ***
  • Posts: 2009
  • Country: fi
Re: HP 3478A: How to read/write cal SRAM
« Reply #172 on: March 18, 2024, 12:11:05 pm »
Back in the day with ASCII terminals CRLF (\r\n) was not a problem, both characters were needed.

I'd say that keep everything that would be sent to controller from the device, so GPIB side.
And remove everything extra from non GPIB side.

488.1 is not defining any special characters for devices.
EOS is just one that is defined on top of that.
So if device is sending CRLF then that is how it should be.

Tek 492P GPIB Concepts is using words "can" and "may" when dealing with EOI.
So more like an option.
Advance-Aneng-Appa-AVO-Beckman-Data Tech-Fluke-General Radio-H. W. Sullivan-Heathkit-HP-Kaise-Kyoritsu-Leeds & Northrup-Mastech-REO-Simpson-Sinclair-Tektronix-Tokyo Rikosha-Triplett-YFE
(plus lesser brands from the work shop of the world)
 
The following users thanked this post: WaveyDipole

Offline djrm

  • Contributor
  • Posts: 41
  • Country: gb
Re: HP 3478A: How to read/write cal SRAM
« Reply #173 on: March 18, 2024, 12:25:36 pm »
I have edited AR488 version 0.51.28 to revert the eoi testing to use && as suggested (line 700 in AR488_GPIBus.cpp) and the new firmware works now with HP3478ACalibration.exe and HP3478A.exe
I have noticed that under wine HP3478ACalibration.exe doesn't work as well as AR488 version 0.49 does, an error reading the version string nearly always occurs. (but not in WIndows)
hth David.
 

Offline m k

  • Super Contributor
  • ***
  • Posts: 2009
  • Country: fi
Re: HP 3478A: How to read/write cal SRAM
« Reply #174 on: March 18, 2024, 12:47:04 pm »
I'm like almost having a recollection where something had a selector between versions 1 and 2.
Was it a hardware or software thing, can't say.
But no doubt, different style of EOI would require some action.
Advance-Aneng-Appa-AVO-Beckman-Data Tech-Fluke-General Radio-H. W. Sullivan-Heathkit-HP-Kaise-Kyoritsu-Leeds & Northrup-Mastech-REO-Simpson-Sinclair-Tektronix-Tokyo Rikosha-Triplett-YFE
(plus lesser brands from the work shop of the world)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf