| Electronics > Repair |
| HP 3478A: How to read/write cal SRAM |
| << < (33/41) > >> |
| lmester:
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: ---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 --- End code --- |
| WaveyDipole:
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 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 --- End code --- 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. |
| WaveyDipole:
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? |
| djrm:
--- Quote from: WaveyDipole 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? --- End quote --- 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 |
| fenugrec:
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: --- 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); --- End code --- 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 |
| Navigation |
| Message Index |
| Next page |
| Previous page |