-
I thought this would be a longer repair log but it's going to be really quick.
I got a PS350 off eBay for a decent price (made an offer and was accepted)
Listing stated for parts/not working. transformer loose inside unable to test.
This is the only image I had before the repairs
(https://drive.google.com/uc?id=0B0n5ltUlE8YHdy1hdHlpZlBvdGM)
I I got it and indeed something was loose inside. I opened it open and barely hanging on was the large 2amp 750uH Inductor
I did not do any kind of power test at this point for safety reasons.
(https://drive.google.com/uc?id=0B0n5ltUlE8YHWjVMM2F5cDlERG8)
This was the bad boy
(https://drive.google.com/uc?id=0B0n5ltUlE8YHTE1KTk1tb0ZfYmM)
I removed it completely and tested it on the LCR meter and it measure at 775uH and everything else was in spec so it was good but the legs were busted. I found and ordered a replacement (Part # is HL-20154/AB from hurricaneelectronics.com.) then thought since it was measuring high anyways I could try un-winding the legs 1/2 turn to lengthen them. which I did. trimmed to length and cleaned the ends and measured it at 749.3uH (can't beat that) put it back in and gave it the power on test.
It came to life.
(https://drive.google.com/uc?id=0B0n5ltUlE8YHTG8wa2NDYTZTRTQ)
so now it was powering up. I did some quick tests and thing looked ok but there where several switch issues.
on the rear the Set/Mon switch was busted so I replaced it
this is the switch I replaced
(https://drive.google.com/uc?id=0B0n5ltUlE8YHckUxUndHNmhVZTQ)
and this is new one in place
(https://drive.google.com/uc?id=0B0n5ltUlE8YHOUZCX3V5MEw2Mnc)
next I found the front panel Off/On/Trip switch was not functioning correctly in the off position. ie. once the HV output was enabled it could not be disabled via the switch. only a power off or a condition which tripped a limit would disable the output
in this image it is the black switch on the left
(https://drive.google.com/uc?id=0B0n5ltUlE8YHSlVselBSYmt5OEk)
I removed the switch to properly test is and indeed the off position was always open. the momentary switch part worked fine so you could enable the output.
this is the switch from the back side. removing it was easy but the front panel had to be removed to make it easier to work with.
(https://drive.google.com/uc?id=0B0n5ltUlE8YHSGhLczkya1FyOUE)
this switch is a Marquardt 1808.0202 6A IP40 Momentary Rocker Switch SPDT On-Off(On). finding this one was a pain and only found it in the UK. so again I ordered the part then figured I would try repairing the switch (something I've not done successfully before)
so I opened it up and the contacts where crusted. I pulled the center rocker bar (don't know correct name for it) out and sprayed the whole thing in contact cleaner. let it set for a bit the used a q-tip to get in there and get that crusty stuff out. after not to long a time I got the contacts looking pretty good and after reassembling the switch was surprised it worked (meaning it moved to each position correctly, which is usually where I've gone wrong. I put it on the meter and tested each position and they all worked now. So I put the switch back in.
While i had it opened I noticed 3 chips where not populated.
(https://drive.google.com/uc?id=0B0n5ltUlE8YHRW1RMUxXbWV2aDQ)
these are the GPIB interface chips including the
TMS9914A
75160A
75161A
on the back you see that Opt 01 is installed but these chips and the GPIB connector are not there
(https://drive.google.com/uc?id=0B0n5ltUlE8YHVWtaVWFUbklKS2c)
I located the IC's on ebay and ordered them. and I found a GBIP connector with break/out board that will allow me to wire up the 24 pin ribbon correctly I hope and restore the GPIB interface
so now that all that was done I gave it a power on and Low and HV test
this is at 50V
(https://drive.google.com/uc?id=0B0n5ltUlE8YHTVVaM0lEQnhiNEE)
Now shown is my meter reading 50V also so it was working find at a low voltage.
next I hooked up a 1000:1 HV Probe to my meter and connected to the output of the PS350 and programmed in 5000V
after hearing the static sound of it charging up I read 4.996V on the meter so I was getting 4996V out of this supply. :-+
(https://drive.google.com/uc?id=0B0n5ltUlE8YHeFJKNXZFUC00Y0k)
The front switch now worked and I could now turn off the HV output.
I checked more voltage settings and all where within tolerances.
A few final clean up items. the main board needs a good cleaning off which I have yet to do.
I repaired the case and cleaned it up also
which you may have noticed in the front pictures
here's a side photo as well
(https://drive.google.com/uc?id=0B0n5ltUlE8YHY1VRSXBmQ2dvSUU)
all the screws were rusted so I took some fine sand paper to them and cleaned it off the a ultra black paint marker and restored the color to them. I had to repair the front face as it was bent badly and the rear of the case was bent also which I repaired.
I think I can call this fixed, it was a easy repair really
I also did find the schematics for it so have them as a reference.
Standford wants $100 for the hard copy of the manual with schematics for those wanting original. you can order on their site www.thinksrs.com (http://www.thinksrs.com)
hope you enjoyed this even though I forgot the before photos.
Sandra
-
That unit must have been abused. Mechanical damage on the inside, back and front. Maybe shipped loose in a box and knocked around? Dropped multiple times? Seems very smart to me to treat a HV power supply that way :P.
-
good question and very probable. I will say it arrived to me packed very well with a hard foam all around and it was centered in the shipping box which was oversized.
but i agree, who ever owned it or worked on it (though I see no signs of anyone working on it) was very rough on it.
-
:-+ nice repair and nice photos 8)
enjoy new gear :-DMM
-
Nice writing and pictures. Thanks for sharing.
Roberto
-
So now that the Unit is working I'm going to get the GPIB interface going again as I stated.
I've ordered and installed the following components.
TMS9914A
75160A
75161A
GPIB Connector
After installing it seems it doesn't work. I get a Err5 when trying to set the GPIB Address
this is not good. so apparently my thought that this unit had GPIB was incorrect. so onto making work anyways.
there was a similar route taken for a PS310 posted here
https://www.eevblog.com/forum/testgear/srs-ps310-rom-code-supports-gpib-option-needed/25/ (https://www.eevblog.com/forum/testgear/srs-ps310-rom-code-supports-gpib-option-needed/25/)
referring to this post I have a PS350 V1.40 rom dump and soon as I get a 2764 EPROM(Maybe Replace with a 28C64 ) I'll burn one and install which should get me GPIB. however I'll loose my calibration value's and is the point of this. to identify the calibration value and if possible figure how to calculate them to improve the calibration.
so first thing I've done is look further at all the IO/MEMORY and other stuff and adding more information to it and more to come as I want to document the EPROM and SRAM addresses.
updated with more details
MEMORY ADDRESS OF EPROM: 0000~1FFF (PROGRAM SPACE:8KB,ST M2764A)
SRAM: 4000~47FF (DATA SPACE:2KB,HITACHI HM6116)
IRQ_ROUTIINE: 0038h
SOURCE: SHEET 6
CLK->(U610)->TIMER @ 976.56hz/0.001024ms (4Mhz/4096(U610)74HC4020)
GPIB
SRAM ADDRESSES:
SRAM_MISC = 413AH
SRAM_STATUS1 = NA
SRAM_STATUS2 = 401CH
EPROM ADDRESSES:
193BH GPIB COMMAND
1F9EH
19FAH 000019fah: F3 CD D5 11 FB 0E 00 C3 D4 15 CD 9D 17 C2 FD 17 ; óÍÕ.û..ÃÔ.Í.Âý.
00001a0ah: 21 8D 1F 11 3C 41 01 09 00 ED B0 ; !..<A...í°
1F7BH 00001f7bh: 5A 31 33 34 ; Z134
1F7FH EPROM_VERSION_NUMBER 00001f7fh: 31 2E 33 34 ; 1.34
1F83H 00001f83h: 88 13 88 13 82 14 82 14 64 00 ; ˆ.ˆ.‚.‚.d.
1F85H
1F8DH 00001f8dh: 00 00 88 13 82 14 82 14 00 00 00 00 00 00 00 00 ; ..ˆ.‚.‚.........
00001f9dh: 0E 48 0D ; .H.
1FA0H 00001fa0h: AC 09 E4 55 0B 52 C4 09 54 52 54 52 BC 09 19 52 ; ¬.äU.RÄ.TRTR¼..R
00001fb0h: 53 4E BB 09 28 52 55 4E AC 09 E6 BF E2 C1 BD 09 ; SN».(RUN¬.æ¿âÁ½.
00001fc0h: E0 C1 E4 C3 00 00 93 43 93 43 A6 09 96 55 F6 51 ; àÁäÃ..“C“C¦.–UöQ
00001fd0h: C4 09 54 52 54 52 D1 09 31 51 30 4D D0 09 52 51 ; Ä.TRTRÑ.1Q0MÐ.RQ
00001fe0h: 22 4D A6 09 12 C0 E2 C1 D2 09 78 C2 84 C4 00 00 ; "M¦..ÀâÁÒ.x„Ä..
00001ff0h: 93 43 93 43 00 00 76 CA 00 00 76 CA ; “C“C..vÊ..vÊ
1FFCH EPROM_SERIAL_NUMBER 00001ffch: 31 31 33 37 ; 1137
00001935h: 44 41 43 BE 1C 00 43 4C 53 6A 1A 45 53 45 3C 1E ; DAC¾..CLSj.ESE<.
00001945h: 45 53 52 AE 1E 49 44 4E B0 19 50 53 43 72 1E 52 ; ESR®.IDN°.PSCr.R
00001955h: 43 4C 5A 1D 52 53 54 4E 1A 53 41 56 35 1D 53 52 ; CLZ.RSTN.SAV5.SR
00001965h: 45 06 1E 53 54 42 08 1F 00 56 4F 46 14 1A 56 4F ; E..STB...VOF..VO
00001975h: 4E 24 1A 00 4C 49 4D 7F 1B 4F 55 54 7E 1C 54 52 ; N$..LIM.OUT~.TR
00001985h: 50 EE 1B 00 4D 4F 44 9E 1C 00 43 4C 52 3B 1A 4D ; Pî..MODž..CLR;.M
00001995h: 4F 44 FF 1C 00 4C 49 4D 06 1B 4F 55 54 5D 1C 53 ; ODÿ..LIM..OUT].S
000019a5h: 45 54 87 1A 00 4F 52 44 77 1D 00 ; ET‡..ORDw..
GPIB
DAC CLS ESE ESR
IDN PSC RCLZ RSTN
SAV5 SRE STB VOF
VON LIM OUT TRP
MOD CLR MOD LIM
OUT SET ORD
I/O ADDRESSES:
U504 (A3-A5 -> A-C, A6-G1, WR->!G2A, IORQ->!G2B )
40H: SPARE
48H:-SETS -> U407/U408
------------------------------
BIT0: U407A /
BIT1: U407B /
BIT2: U408A / ANALOG_VOLTAGE
BIT3: U408B / I_OUT_MONITOR
BIT4: U408C / CV_SET
BIT5: U408D / DV_LIM
BIT6: U407C / I_LIM
BIT7: U407D / I_TRIP
------------------------------
50H:-DAC
50H DAC_LOW_NIBBLE
51H DAC_MID_NIBBLE
52H DAC_HIGH_NIBBLE
53H DAC_LOAD
58H:-LED
------------------------------
BIT0: U611 L0
BIT1: U611 L1
BIT2: U611 L2
BIT3: U611 -AD0
BIT4: U611 -AD1
BIT5: U611 -AD2
BIT6: U611 -IO
BIT7: U611 UNUSED
------------------------------
60H:-SEGB U606
------------------------------
BIT0: EDP
BIT1: EG
BIT2: EF
BIT3: EE
BIT4: ED
BIT5: EC
BIT6: EB
BIT7: EA
------------------------------
68H:-SEGA U609
------------------------------
BIT0: ODP
BIT1: OG
BIT2: OF
BIT3: OE
BIT4: OD
BIT5: OC
BIT6: OB
BIT7: OA
------------------------------
70H:-STROBE (STROB0-STROB5 LED) (STROB2-4 KEYBOARD SCAN OUT)
------------------------------
BIT0: STROB0 (LED)
BIT1: STROB1 (LED)
BIT2: STROB2 (LED,KBD)
BIT3: STROB3 (LED,KBD)
BIT4: STROB4 (LED,KBD)
BIT5: STROB5 (LED)
BIT6: STROB6 ()
BIT7: STROB7 ()
------------------------------
78H: MISC -> (U507,74HC374 OCTAL D-TYPE FLIP-FLOP) >CLK
------------------------------
BIT0: -SHUTDOWN
BIT1: UPOK
BIT2: -FLAG_RESET
BIT3: -TIMER_RESET
BIT4: (SPARE)
BIT5: -POS
BIT6: -NEG
BIT7: FILTER
------------------------------
U505 (A3-A5 -> A-C, !M1->G1, A6->!G2A, IORQ->!G2B )
00H: SPARE
08H: SPARE
10H: SPARE
18H: SPARE
20H: STATUS1
------------------------------
BIT0: COMPARE
BIT1: I_FAULT
BIT2: CUR_LIM
BIT3: PRI_FAULT
BIT4: V_FAULT
BIT5: TIMER
BIT6: J504
BIT7: GND
------------------------------
28H: STATUS2
------------------------------
BIT0: HV_ON
BIT1: HV_OFF
BIT2: J501
BIT3: J502
BIT4: GND
BIT5: GND
BIT6: GND
BIT7: GND
------------------------------
30H: -KBD
------------------------------
BIT0: KBD0
BIT1: KBD1
BIT2: KBD2
BIT3: KBD3
BIT4: KBD4
BIT5: KBD5
BIT6: KBD6
BIT7: KBD7
key press display
01 Man
02 GPIB
03 left-arrow
04 Right arrow
05 up-arrow
06 down-arrow
07 Enter
08 Select
09 STO
10 RCL
11 CLR
12 .
13 0
14 7
15 4
16 1
17 8
18 5
19 2
20 9
21 6
22 3
------------------------------
38H: -GPIB
------------------------------
READ
38H GPIB_INT_STATUS_0
BIT0: INT0 (1 WHEN STATUS 1 BIT SET)
BIT1: INT1 (1 WHEN BITS 2-7 OF STATUS 0 SET)
BIT2: BI (BYTE IN)
BIT3: BO (BYTE OUT)
BIT4: END (LAST BYTE RECEIVED)
BIT5: SPAS (RSV1/2 SERVICE REQUEST)
BIT6: RCL (REMOTE/LOCAL CHANGE)
BIT7: MAC (ADDRESS CHANGE)
39H GPIB_INT_STATUS_1
BIT0: GET (GROUP EXECUTE TRIGGER)
BIT1: ERR (ERROR)
BIT2: UNC (UNRECOGNIZED COMMAND)
BIT3: APT (ADDRESS PASS THROUGH)
BIT4: DCAS (DEVICE CLEAR ACTIVE STATE)
BIT5: MA (MY ADDRESS)
BIT6: SRQ (SERVICE REQUEST)
BIT7: IFC (INTERFACE CLEAR)
3AH GPIB_ADDRESS_STATUS
BIT0: REM
BIT1: LLO
BIT2: ATN
BIT3: LPAS
BIT4: TPAS
BIT5: LADS
BIT6: TADS
BIT7: ULPA
3BH GPIB_BUS_STATUS
3EH GPIB_CMD_PASS_THRU
3FH GPIB_DATA_IN
WRITE
38H GPIB_INT_MASK_0
39H GPIB_INT_MASK_1
3BH GPIB_AUXILIARY_CMD
3CH GPIB_ADDRESS
3DH GPIB_SERIAL_POLL
3EH GPIB_PARALLEL_POLL
3FH GPIB_DATA_OUT
------------------------------
I've also started running thru the disassembly and trying to figure things out so I can figure which are the calibration locations
one thing I do know is they copied allot of stuff from EPROM to SRAM then work from the SRAM location while running
some basics
0038H is the start of the IRQ service routine, timer driven mainly checks STATUS1 and handles KBD and GPIB
below is not the complete routine, just the start of it
0028 0038 08 IRQ_SERVICE: EX AF,AF' ; ENTRY POINT FOR IRQ SERVICE ROUTINE
0029 0039 DB 20 IN A,(STATUS1) ; READ STATUS1
0030 003B CB 6F BIT 5,A ; TEST IF BIT 5 SET IN STATUS1 WHICH IS THE TIMER BIT
0031 003D 28 06 JR Z,TIMER_EVENT ; IF TIMER EVENT JUMP TO TIMER_EVENT
0032 003F CD BB 0E CALL IRQ_SERVICE_1 ; TBD
0033 0042 08 EX AF,AF'
0034 0043 FB EI ; ENABLE INTERUPTS
0035 0044 C9 RET ; RETURN FROM IRQ
0036 0045 D9 TIMER_EVENT: EXX
0037 0046 DB 38 IN A,(GPIB_INT_STATUS_0) ; A GETS GPIB_INT_STATUS_0
0038 0048 47 LD B,A ; COPY A -> B
0039 0049 DB 39 IN A,(GPIB_INT_STATUS_1) ; A GETS GPIB_INT_STATUS_1
0040 004B CB 5F BIT 3,A ; TEST BIT 3 (Address Pass Through) IN GPIB_INT_STATUS_1 IS SET
0041 004D C2 11 13 JP NZ,L0006 ; JUMP L0006 IF NOT ZERO
0042 0050 CB 50 BIT 2,B ; TEST BIT 2 (Byte In) IN GPIB_INT_STATUS_0 IS SET
0043 0052 C2 09 13 JP NZ,L0007 ; JUMP TO L0007 IF NOT ZERO
0044 0055 CB 68 L0256: BIT 5,B ; TEST BIT 5 (SPAS) IN GPIB_INT_STATUS_0 IS SET
0045 0057 C2 1E 13 JP NZ,L0008 ; JUMP TO L0008 IF NOT ZERO
0046 005A CB 60 BIT 4,B ; TESST BIT 5 (END) OF GPIB_INT_STATUS_0 IS SET (LAST BYTE RECEIVED)
0047 005C 28 03 JR Z,L0009 ; JUMP TO L0009 IF ZERO
0048 005E C3 59 13 JP L0010 ; JUMP TO L0010 UNCONDITIONALLY
0049 0061 D9 L0009: EXX
0050 0062 08 EX AF,AF'
0051 0063 FB EI ; ENABLE INTERRUPTS
0052 0064 C9 RET ; RETURN
I have a EPROM coming to burn the 1.40 version in. mine is a 1.34 version currently so comparing directly won't help allot
now if anyone has a V1.40 without GPIB support they can share that would be great.
too me so far it looks like the area from 1F83H-1FFC may contain calibration data and may be only part needed to copy to maintain calibration.
but I want to look and find the details so we can calibrate without sending back to SSR.
-
I received my EPROM and burned a replacement changing only the Serial Number at the end and that worked fine to enable my GPIB change.
I discovered my Agilent 82357B wasn't working looking like it might have blown a 75160B/75162B inside. I have both coming.
I have a cheapy ebay unit that only works with it's own software so was able to verify the GPIB interface was working so that's fixed
My calibration was off. at 5Kv it was reading 4991V and it also didn't go as low. prior to change i was down at the 25V range (though spec is 50V) after the EPROM change it's sitting at 35V but reading 40V on the DMM.
So I copied the memory area starting at 1FA0 also this time
1FA0H 00001fa0h: AC 09 E4 55 0B 52 C4 09 54 52 54 52 BC 09 19 52 ; ¬.äU.RÄ.TRTR¼..R
00001fb0h: 53 4E BB 09 28 52 55 4E AC 09 E6 BF E2 C1 BD 09 ; SN».(RUN¬.æ¿âÁ½.
00001fc0h: E0 C1 E4 C3 00 00 93 43 93 43 A6 09 96 55 F6 51 ; àÁäÃ..“C“C¦.–UöQ
00001fd0h: C4 09 54 52 54 52 D1 09 31 51 30 4D D0 09 52 51 ; Ä.TRTRÑ.1Q0MÐ.RQ
00001fe0h: 22 4D A6 09 12 C0 E2 C1 D2 09 78 C2 84 C4 00 00 ; "M¦..ÀâÁÒ.x„Ä..
00001ff0h: 93 43 93 43 00 00 76 CA 00 00 76 CA ; “C“C..vÊ..vÊ
in addition to the serial number and burned another EPROM. Loaded it up and my cal values where back
so in that block is indeed where the calibration values are stored. this is good.
I'm thinking this bit of code copies the calibration values to SRAM @ 413CH
0066 007A 01 11 00 L0011: LD BC,0011H ; TRANSFER 17 BYTES
0067 007D 21 8D 1F LD HL,1F8DH ; FROM EPROM
0068 0080 11 3C 41 LD DE,413CH ; TO SRAM @ 413C
0069 0083 ED B0 LDIR ; MOVE FROM 1F8D TO 413C
if so the 1F8D thru 1F9E contain the calibration values
00001f8dh: 00 00 88 13 82 14 82 14 00 00 00 00 00 00 00 00 ; ..ˆ.‚.‚.........
00001f9dh: 0E 48 ; .H
I'll try another burn of the EPROM without this section to see if I do or do not have calibration values next.
oh, I do have a few 28C64's coming soon. I'll replace the 27C64 with one of these and if that works well and no reason I know it won't I'll be able to reflash it instead of UV erasing which will make things easier to play with
-
So I tried to remove this section
replacing
00001f8dh: 00 00 88 13 82 14 82 14 00 00 00 00 00 00 00 00 ; ..ˆ.‚.‚.........
00001f9dh: 0E 48 ; .H
with
00001f8dh: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ..ˆ.‚.‚.........
00001f9dh: 00 00 ; .H
Then powered up with CLR pressed to restore default from the EPROM and then measured at
50V
500V
5000V
Comparing to the values prior this I noticed no difference so (a few millivolts was about it)
So unless the calibration range is so small then these are not the calibration values
On to more searching
-
For a device that is specified as 0.01% of value + 0.05% of range accurate, or +/- 3V for 5 kV, I find it hard to believe that the adjustment range is only a few millivolts. Unless your device happens to be at the very bottom end of its adjustment range, my money is that these are indeed not the calibration values. Either that or it is using values from an alternate location because of a failed checksum (hard to believe with EPROM).
I have seen primary cal values in battery-backed SRAM and backup copies in EEPROM, but I do not see the point of having two copies in the same EPROM.
I am guessing these devices can not do any kind of adjustment through GPIB so you could at least see the SRAM locations that were modified? Adjustment probably exists of measuring a bunch of values and then burning these values into an EPROM. Sounds like a messy way of adjustment.
-
There are other values copied from the EPROM to SRAM so I'm going to look at those and see if they effect anything. I so make sure to either hold CLR when powering on to restore defaults so it copies from EPROM to SRAM the new values or do a RCL 0 to restore factory defaults.
looking at what looks looks to be the GPIB command area there is this
193BH GPIB COMMAND 00001935h: 44 41 43 BE 1C 00 43 4C 53 6A 1A 45 53 45 3C 1E ; DAC¾..CLSj.ESE<.
00001945h: 45 53 52 AE 1E 49 44 4E B0 19 50 53 43 72 1E 52 ; ESR®.IDN°.PSCr.R
00001955h: 43 4C 5A 1D 52 53 54 4E 1A 53 41 56 35 1D 53 52 ; CLZ.RSTN.SAV5.SR
00001965h: 45 06 1E 53 54 42 08 1F 00 56 4F 46 14 1A 56 4F ; E..STB...VOF..VO
00001975h: 4E 24 1A 00 4C 49 4D 7F 1B 4F 55 54 7E 1C 54 52 ; N$..LIM.OUT~.TR
00001985h: 50 EE 1B 00 4D 4F 44 9E 1C 00 43 4C 52 3B 1A 4D ; Pî..MODž..CLR;.M
00001995h: 4F 44 FF 1C 00 4C 49 4D 06 1B 4F 55 54 5D 1C 53 ; ODÿ..LIM..OUT].S
000019a5h: 45 54 87 1A 00 4F 52 44 ; ET‡..ORD
the DAC and ORD would appear to be commands. I tried variations on the DAC command like DAC? A-Z[DAC]? *DAC? all resulted in a time out. I need to understand the command parser better and maybe can figure out how they the calibration. the websites states it's calibrated in a automated setup. now that doesnt' mean it's over GPIB though. they may plug in a calibration device in-place of the z80 and get the DAC values then assemble the EPROM with those values or have a EPROM they use just to calibrate the unit.
ultimately is looks like it is just a offset to the DAC so finding that in the code would help. for me last time I did z80 stuff was in the late 80's
I'm using a z80 simulator on the EPROM code to examine things. nice thing is I get what the SRAM looks like also. they do all the work out of the sram after things are copied in.
I'm happy to post the simulation files and SRAM dump of anyone is interested.
-
Great post. What simulator are you using?
TonyG
-
I am using this one "Z80 Simulator IDE v10.36" from http://www.oshonsoft.com/ (http://www.oshonsoft.com/)
Attached are the memory dump and sim file along with my bin file and most recent update to the disassembly
I had to zip them to attach them
-
That was definitely a "DON'T turn it on before taking it apart" type of repair! :-BROKE :-+
-
Did a bit of digging in the rom/ram dump you posted. The data at 0x191C looks indeed like a GPIB command table. The structure is a bit odd:
ROM:191C db '$'
ROM:191D dw 1935h
ROM:191F db '*'
ROM:1920 dw 193Bh
ROM:1922 db 'H'
ROM:1923 dw 196Eh
ROM:1925 db 'I'
ROM:1926 dw 1979h
ROM:1928 db 'S'
ROM:1929 dw 1989h
ROM:192B db 'T'
ROM:192C dw 198Fh
ROM:192E db 'V'
ROM:192F dw 199Ah
ROM:1931 db 'W'
ROM:1932 dw 19AAh
ROM:1934 db 0
ROM:1935 db 44h ; D
ROM:1936 db 41h ; A
ROM:1937 db 43h ; C
ROM:1938 dw 1CBEh
ROM:193A db 0
ROM:193B db 43h ; C
ROM:193C db 4Ch ; L
ROM:193D db 53h ; S
ROM:193E dw 1A6Ah
ROM:1940 db 45h ; E
ROM:1941 db 53h ; S
ROM:1942 db 45h ; E
ROM:1943 dw 1E3Ch
ROM:1945 db 45h ; E
ROM:1946 db 53h ; S
ROM:1947 db 52h ; R
ROM:1948 dw 1EAEh
ROM:194A db 49h ; I
ROM:194B db 44h ; D
ROM:194C db 4Eh ; N
ROM:194D dw 19B0h
ROM:194F db 50h ; P
ROM:1950 db 53h ; S
ROM:1951 db 43h ; C
ROM:1952 dw 1E72h
ROM:1954 db 52h ; R
ROM:1955 db 43h ; C
ROM:1956 db 4Ch ; L
ROM:1957 dw 1D5Ah
ROM:1959 db 52h ; R
ROM:195A db 53h ; S
ROM:195B db 54h ; T
ROM:195C dw 1A4Eh
ROM:195E db 53h ; S
ROM:195F db 41h ; A
ROM:1960 db 56h ; V
ROM:1961 dw 1D35h
ROM:1963 db 53h ; S
ROM:1964 db 52h ; R
ROM:1965 db 45h ; E
ROM:1966 dw 1E06h
ROM:1968 db 53h ; S
ROM:1969 db 54h ; T
ROM:196A db 42h ; B
ROM:196B dw 1F08h
ROM:196D db 0
ROM:196E db 56h ; V
ROM:196F db 4Fh ; O
ROM:1970 db 46h ; F
ROM:1971 dw 1A14h
ROM:1973 db 56h ; V
ROM:1974 db 4Fh ; O
ROM:1975 db 4Eh ; N
ROM:1976 dw 1A24h
ROM:1978 db 0
ROM:1979 db 4Ch ; L
ROM:197A db 49h ; I
ROM:197B db 4Dh ; M
ROM:197C dw 1B7Fh
ROM:197E db 4Fh ; O
ROM:197F db 55h ; U
ROM:1980 db 54h ; T
ROM:1981 dw 1C7Eh
ROM:1983 db 54h ; T
ROM:1984 db 52h ; R
ROM:1985 db 50h ; P
ROM:1986 dw 1BEEh
ROM:1988 db 0
ROM:1989 db 4Dh ; M
ROM:198A db 4Fh ; O
ROM:198B db 44h ; D
ROM:198C dw 1C9Eh
ROM:198E db 0
ROM:198F db 43h ; C
ROM:1990 db 4Ch ; L
ROM:1991 db 52h ; R
ROM:1992 dw 1A3Bh
ROM:1994 db 4Dh ; M
ROM:1995 db 4Fh ; O
ROM:1996 db 44h ; D
ROM:1997 dw 1CFFh
ROM:1999 db 0
ROM:199A db 4Ch ; L
ROM:199B db 49h ; I
ROM:199C db 4Dh ; M
ROM:199D dw 1B06h
ROM:199F db 4Fh ; O
ROM:19A0 db 55h ; U
ROM:19A1 db 54h ; T
ROM:19A2 dw 1C5Dh
ROM:19A4 db 53h ; S
ROM:19A5 db 45h ; E
ROM:19A6 db 54h ; T
ROM:19A7 dw 1A87h
ROM:19A9 db 0
ROM:19AA db 4Fh ; O
ROM:19AB db 52h ; R
ROM:19AC db 44h ; D
ROM:19AD dw 1D77h
ROM:19AF db 0
The data at the top contains the first character (e.g. '*' at 191F) and a reference to an array of:
struct {
char cmd[3];
void *addr;
}
Terminated by a 00. For '*', cmd would be CLS, IDN, etc. The complete list:
$DAC
*CLS
*ESE
*ESR
*IDN
*PSC
*RCL
*RST
*SAV
*SRE
*STB
HVOF
HVON
ILIM
IOUT
ITRP
SMOD
TCLR
TMOD
VLIM
VOUT
VSET
WORD
The *addr are code references that will presumably take the desired action. Parsing seem to take place around 1587:
ROM:1587 parse_gpib_commands: ; CODE XREF: read_gpib_key+ACp
ROM:1587 ; parse_gpib_commands+E4j
ROM:1587 ld a, (word_40EB)
ROM:158A and a
ROM:158B ret z
ROM:158C call sub_17D0
ROM:158F call sub_17F1
ROM:1592 ld c, 0
ROM:1594 jp z, loc_161B
ROM:1597 call sub_181B
ROM:159A ld b, a
ROM:159B ld c, 1
ROM:159D ld hl, 191Ch ; data_gpib_commands
ROM:15A0
ROM:15A0 loc_15A0: ; CODE XREF: parse_gpib_commands+24j
ROM:15A0 ld a, (hl)
ROM:15A1 inc hl
ROM:15A2 and a
ROM:15A3 jp z, end_of_string
ROM:15A6 cp b
ROM:15A7 jr z, loc_15AD
ROM:15A9 inc hl
ROM:15AA inc hl
ROM:15AB jr loc_15A0
A cursory look at the code at 1cbe (referenced by $DAC) suggests that it does not accept $DAC?, but expects a value:
ROM:1CBE call check_question_mark
ROM:1CC1 jp z, syntax_error
ROM:1CC4 ld hl, 1
ROM:1CC7 ld a, 0
ROM:1CC9 call sub_1851
ROM:1CCC jp nz, end_of_string
ROM:1CCF push hl
ROM:1CD0 call sub_17E7
ROM:1CD3 pop hl
ROM:1CD4 jp nz, syntax_error
ROM:1CD7 ld c, 0
ROM:1CD9 bit 0, l
ROM:1CDB jr z, loc_1CF8
ROM:1CDD ld hl, 0
ROM:1CE0 ld a, (byte_412D)
ROM:1CE3 or a
ROM:1CE4 jr z, loc_1CE8
ROM:1CE6 set 7, h
I have not looked into what it does with this value yet.
-
@alm
Wow, you're far better at this than I am. Thank you.
That shed a bunch of light on things.
the not supporting $DAC? makes sense since the DAC can not be read. they would have to Save the current DAC value and return it and guess they didn't need that feature to calibrate.
given that setting the DAC maybe possible what I imagine they do then is basically (and crudely)
HVON
FOR TEST_VALUE IN 50,1000,2000,3000,4000,5000 < just random values but they would have fixed test points
DO
VSET TEST_VALUE
READ OUTPUT VOLTAGE
COMPARE TEST_VALUE TO OUTPUT
IF IN SPEC SAVE TEST_VALUE, OFFSET AND NEXT VALUE
ELSE $DAC +/-OFFSET
LOOP BACK TO READ
DONE
HVOFF
then they would write those offsets to EPROM.
kind of a clunky way of doing it but given the hardware here the only way that would work reliably I think. they could write to sram for cal but if your battery died you'd loose cal and with not battery monitor they can't alert you to change the battery.
-
I also got through a repair of one PS350 recently and done the GPIB upgrade trough a donors ROM. In the progress, I also loosen my calibration but luckily, it’s not so much off. But a possibility to calibrate it would be great.
Below the attached ROMs I have both V1.4 but quite different when I did the compare (GPIB vs Non-GPIB version), maybe they will help you to figure out where the calibration locations are more quicklly.
-
given that setting the DAC maybe possible what I imagine they do then is basically (and crudely)
[...]
I agree that it would probably be something like that (if they wanted to reduce calibration time, they would use some sort of binary search or interpolation for finding the offset).
Looks to me like WORD takes two comma-separated numbers that somehow may affect either vset, vlim, ilim or itrp. WORD? is also implemented and takes a single number. I believe the first parameter selects vset, vlim, ilim or itrp. Not sure what the point of this command is.
This looks to me like it might be subtracting calibration offsets. Depending on the value of port 0x28 bit 2 (J501 according to your earlier post, a calibration jumper? model indicator?), it uses 4026 or 4026+2A as base address. Then it does some math that as far as I can tell boils down to the parameter number (0..3) * 6. By my reading (which may very well be wrong), the first of the three words is an offset that is subtracted from the set voltage. Depending on the polarity of the result of this subtraction, it will either pick the second or third word and do something that looks like multiplication with it. If my analysis is correct, the calibration constants would live in 0x4026 up to something like 0x4082. Figuring out how the constants affect the DAC value should not be difficult by a more careful reading of the code.
; a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
ROM:08FD loc_8FD: ; CODE XREF: check_limits+Ej
ROM:08FD push af
ROM:08FE ld a, (var_status2)
ROM:0901 bit 2, a
ROM:0903 ld hl, byte_4026
ROM:0906 jr z, loc_90B
ROM:0908 ld hl, byte_4026+2Ah
ROM:090B
ROM:090B loc_90B: ; CODE XREF: check_limits+2Bj
ROM:090B pop af ; a = param { 0..3 } << 1, e = a << 1, bc = var_vset
ROM:090C rlca
ROM:090D add a, e
ROM:090E ld e, a
ROM:090F add hl, de
ROM:0910 ld e, (hl)
ROM:0911 inc hl
ROM:0912 ld d, (hl)
ROM:0913 inc hl
ROM:0914 push hl
ROM:0915 ld h, b
ROM:0916 ld l, c
ROM:0917 or a
ROM:0918 sbc hl, de
ROM:091A pop de
ROM:091B jr c, loc_91F
ROM:091D inc de
ROM:091E inc de
ROM:091F
ROM:091F loc_91F: ; CODE XREF: check_limits+40j
ROM:091F ld a, 0
ROM:0921 call c, cpl_word ; hl = -hl
ROM:0921 ; a = 1
ROM:0924 ex de, hl
ROM:0925 ld c, (hl)
ROM:0926 inc hl
ROM:0927 ld b, (hl)
ROM:0928 ld (byte_40E6), a
ROM:092B pop af
ROM:092C push af
ROM:092D push bc
ROM:092E ld hl, 99Fh
ROM:0931 add a, l
ROM:0932 ld l, a
ROM:0933 jr nc, loc_936
ROM:0935 inc h
ROM:0936
ROM:0936 loc_936: ; CODE XREF: check_limits+58j
ROM:0936 ld a, (hl)
ROM:0937 cp 0
ROM:0939 jr z, loc_942
ROM:093B ld b, a
ROM:093C
ROM:093C loc_93C: ; CODE XREF: check_limits+65j
ROM:093C sla e
ROM:093E rl d
ROM:0940 djnz loc_93C
This appears to be the code responsible for copying:
ROM:0094 ld bc, 5Ch ; '\'
ROM:0097 ld hl, unk_1FA0
ROM:009A ld de, byte_4026
ROM:009D ldir
$DAC seems to control the VSET DAC directly, ignoring any calibration constant or voltage setting (as expected). It does not appear to affect the other DACs like VLIM, ILIM and ITRP. So the calibration procedure would be something like:
For DAC_VALUE in 0x0 0x7F 0x7FF 0x7FFF 0x807F 0x87FF 0xFFFF ; for a 16-bit DAC
$DAC DAC_VALUE
Measure voltage
Store DAC_VALUE, voltage
Then fit two linear functions of the form voltage -> DAC_VALUE for positive and negative voltages.
Seems like it should be doable if you know the syntax of $DAC and the exact meaning of the constants. It will probably involve a lot of EPROM erase/flash cycles, however. Have you considered converting it to EEPROM? ;)
Let me know if all this makes sense and if it matches reality. I am not very familiar with Z80 assembly (had to keep the Z80 family CPU user manual open), and neither do I have access to one of these units, so I could easily be way off. There are definitely a few spots where I do not see how the code can do anything useful. I did go through a decent fraction of the code and have labeled a bunch of functions and variables. Especially around the GPIB commands and the DAC stuff.
-
J501/J502/J503 monitor the polarity switch on the back of the supply. J501 would tell it is operating in POSITIVE, the pin is pulled high normally so a LOW would indicate Positive
J504 monitors the SET/MONITOR switch on the back of the supply. a HIGH should be SET, a LOW should be MONITOR
That word command may be how they read and/or set the each of those parms manually. perhaps part of their calibration process?
i'll try some commands to both $DAC and WORD and see what i get.
Sounds like WORD would be WORD? 1
FYI, the DAC used is a 12bit DAC
I have some 28C64's on the way ;)
appreciate all your assistance here. it's been very helpfull and seems to be right on.
if you are correct about the calibration values being in the 4026h range then this bit of code copies from EPROM to SRAM
0079 0094 01 5c 00 ld bc,005ch ; transfer 5c bytes
0080 0097 21 a0 1f ld hl,1fa0h ; from eprom
0081 009a 11 26 40 ld de,4026h ; to sram @ 4026
0082 009d ed b0 ldir ; do the transfer
this is the block of data being copied
1FA0H 00001fa0h: AC 09 E4 55 0B 52 C4 09 54 52 54 52 BC 09 19 52 ; ¬.äU.RÄ.TRTR¼..R
00001fb0h: 53 4E BB 09 28 52 55 4E AC 09 E6 BF E2 C1 BD 09 ; SN».(RUN¬.æ¿âÁ½.
00001fc0h: E0 C1 E4 C3 00 00 93 43 93 43 A6 09 96 55 F6 51 ; àÁäÃ..“C“C¦.–UöQ
00001fd0h: C4 09 54 52 54 52 D1 09 31 51 30 4D D0 09 52 51 ; Ä.TRTRÑ.1Q0MÐ.RQ
00001fe0h: 22 4D A6 09 12 C0 E2 C1 D2 09 78 C2 84 C4 00 00 ; "M¦..ÀâÁÒ.x„Ä..
00001ff0h: 93 43 93 43 00 00 76 CA 00 00 76 CA ; “C“C..vÊ..vÊ
-
Just did the compare of two different V1.4 EPROMS.
The differences start from 0x01FA0 all the way to the end. So this all plays along with what has been discoverd so far by alm and smgvbest
(https://www.eevblog.com/forum/repair/quick-repair-standford-research-ps350-5kv-5ma-(fixed)/?action=dlattach;attach=336753;image)
-
Okay, then the two blocks are obviously for the negative and positive polarity. The first block would be used if J501 is low (positive polarity), and the second block for negative polarity. The use second or third word depends on the polarity of vset - word1. If this is negative, then the second word is used. Otherwise the second word is skipped and the third word is used. The result is fed in this function that I can not completely figure out:
ROM:08A1 ; de = intermediate dac value (= word1 - vset)
ROM:08A1 ; hl = calib word 2 or 3
ROM:08A1
ROM:08A1 some_calc_hl_de: ; CODE XREF: check_limits+69p
ROM:08A1 ; sub_A39+3Bp ...
ROM:08A1 ld c, l
ROM:08A2 ld b, h
ROM:08A3 ld hl, 0
ROM:08A6 ld a, 10h
ROM:08A8
ROM:08A8 loc_8A8: ; CODE XREF: some_calc_hl_de+16j
ROM:08A8 sla l
ROM:08AA rl h
ROM:08AC rl e
ROM:08AE rl d
ROM:08B0 jr nc, loc_8B6
ROM:08B2 add hl, bc
ROM:08B3 jr nc, loc_8B6
ROM:08B5 inc de
ROM:08B6
ROM:08B6 loc_8B6: ; CODE XREF: some_calc_hl_de+Fj
ROM:08B6 ; some_calc_hl_de+12j
ROM:08B6 dec a
ROM:08B7 jr nz, loc_8A8
ROM:08B9 ret
ROM:08B9 ; End of function some_calc_hl_de
Clearly the intermediate calibration value (word1 - vset) is added to an accumulator up to 0x10 times, depending on the value of word 2 / 3. Plus a bunch of bit shifting. Does anyone recognize this as a common mathematical function? Anyway, word 2 / 3 does seem some kind of multiplier/exponent. It presumably translates the signed 16-bit value to an unsigned 12-bit value.
This is the context of that function call. It comes immediately after the block I posted in my previous post:
ROM:0942 loc_942: ; CODE XREF: check_limits+5Ej
ROM:0942 pop hl
ROM:0943 push de
ROM:0944 call some_calc_hl_de ; in:
ROM:0944 ; de = intermediate dac value
ROM:0944 ; hl = calib word 2 or 3
ROM:0944 ; out:
ROM:0944 ; hl = result
ROM:0944 ; de = ???
ROM:0947 bit 7, h
ROM:0949 jr z, loc_94C
ROM:094B inc de
ROM:094C
ROM:094C loc_94C: ; CODE XREF: check_limits+6Ej
ROM:094C pop hl
ROM:094D add hl, de
ROM:094E ld a, (byte_40E6)
ROM:0951 bit 0, a
ROM:0953 jr z, loc_957
ROM:0955 set 7, h
ROM:0957
ROM:0957 loc_957: ; CODE XREF: check_limits+78j
ROM:0957 pop af
ROM:0958 ret
So after the operation the result hl is ignored, and the result de is added to (word1 - vset).
There may be some other data in there: by my math the four blocks of six bytes should only take 0x18 bytes, yet the second block starts at +0x2a (at 0x1fca). There does appear data between 0x1fb8 and 0x1fca. Is my understanding wrong? Or is this data really not used? If the second block is also 0x2a bytes long, it should stop at 0x1ff4, yet it copies until 0x1ffc.
This code appears to check an additional parameter block at 0x099F. This is a four byte block of zeroes in Sandra's ROM dump. This appears to indicate the number of iterations of the loop at 0x093c. So this could be an additional linearity correction or something (maybe used for different ranges, e.g. 5 kV vs 10 kV models). Though the different location in the firmware and the fact that it is not copied to RAM seems odd for calibration, and seems to argue for different models.
ROM:092E ld hl, unk_99F
ROM:0931 add a, l
ROM:0932 ld l, a
ROM:0933 jr nc, loc_936
ROM:0935 inc h
ROM:0936
ROM:0936 loc_936: ; CODE XREF: check_limits+58j
ROM:0936 ld a, (hl)
ROM:0937 cp 0
ROM:0939 jr z, loc_942
ROM:093B ld b, a
ROM:093C
ROM:093C loc_93C: ; CODE XREF: check_limits+65j
ROM:093C sla e
ROM:093E rl d
ROM:0940 djnz loc_93C
ROM:0942
ROM:0942 loc_942:
Actually, on second thought, it looks like WORD? can query words from the calibration RAM:
ROM:1DE5 parse_word?: ; CODE XREF: ROM:1D7Aj
ROM:1DE5 ld hl, 2Dh ; '-'
ROM:1DE8 call get_gpib_num3
ROM:1DEB jp nz, end_of_string
ROM:1DEE push hl
ROM:1DEF call gpib_check_end_command
ROM:1DF2 pop hl
ROM:1DF3 jp nz, syntax_error
ROM:1DF6 ld de, byte_4026
ROM:1DF9 ex de, hl
ROM:1DFA add hl, de
ROM:1DFB add hl, de
ROM:1DFC ld e, (hl)
ROM:1DFD inc hl
ROM:1DFE ld d, (hl)
ROM:1DFF ex de, hl
ROM:1E00 call sub_1878
ROM:1E03 jp end_of_string
The initial hl is the max input it accepts. So it expects a decimal integer up to 0x2d (45). And it adds this address twice to 0x4026. By my math that puts it two bytes short from the 0x5c bytes copied at 0x94. Either that or I made an off-by-one error. sub_1878 looks GPIB related, so may very well send a response back. I was also wrong about the WORD write. It appears to write the calibration RAM, and then changes the DAC setting to match the new calibration value. That was I was confused about it settings a value: it does call set_control value, but only to update the DAC with the new calibration constants. This is the complete code:
ROM:1D77 parse_word:
ROM:1D77 call check_question_mark
ROM:1D7A jp z, parse_word?
ROM:1D7D ld hl, 2Dh ; '-'
ROM:1D80 call get_gpib_num3
ROM:1D83 jp nz, end_of_string
ROM:1D86 ld (var_temp_word_address), hl
ROM:1D89 call check_comma
ROM:1D8C jp nz, syntax_error
ROM:1D8F ld hl, 0FFFFh
ROM:1D92 call get_gpib_num3
ROM:1D95 jp nz, end_of_string
ROM:1D98 push hl
ROM:1D99 call gpib_check_end_command
ROM:1D9C pop hl
ROM:1D9D jp nz, syntax_error
ROM:1DA0 ld de, calibration_ram
ROM:1DA3 ld bc, (var_temp_word_address)
ROM:1DA7 ex de, hl
ROM:1DA8 add hl, bc
ROM:1DA9 add hl, bc
ROM:1DAA ld (hl), e
ROM:1DAB inc hl
ROM:1DAC ld (hl), d
ROM:1DAD ld a, c
ROM:1DAE cp 0Ch
ROM:1DB0 jr c, loc_1DBA
ROM:1DB2 sub 15h
ROM:1DB4 jr c, loc_1DE0
ROM:1DB6 cp 0Ch
ROM:1DB8 jr nc, loc_1DE0
ROM:1DBA
ROM:1DBA loc_1DBA: ; CODE XREF: ROM:1DB0j
ROM:1DBA cp 3
ROM:1DBC jr nc, loc_1DC5
ROM:1DBE ld a, 0
ROM:1DC0 call set_control_value ; a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
ROM:1DC3 jr loc_1DE0
ROM:1DC5 ; ---------------------------------------------------------------------------
ROM:1DC5
ROM:1DC5 loc_1DC5: ; CODE XREF: ROM:1DBCj
ROM:1DC5 cp 6
ROM:1DC7 jr nc, loc_1DD0
ROM:1DC9 ld a, 1
ROM:1DCB call set_control_value ; a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
ROM:1DCE jr loc_1DE0
ROM:1DD0 ; ---------------------------------------------------------------------------
ROM:1DD0
ROM:1DD0 loc_1DD0: ; CODE XREF: ROM:1DC7j
ROM:1DD0 cp 9
ROM:1DD2 jr nc, loc_1DDB
ROM:1DD4 ld a, 2
ROM:1DD6 call set_control_value ; a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
ROM:1DD9 jr loc_1DE0
ROM:1DDB ; ---------------------------------------------------------------------------
ROM:1DDB
ROM:1DDB loc_1DDB: ; CODE XREF: ROM:1DD2j
ROM:1DDB ld a, 3
ROM:1DDD call set_control_value ; a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
ROM:1DE0
ROM:1DE0 loc_1DE0: ; CODE XREF: ROM:1DB4j
ROM:1DE0 ; ROM:1DB8j ...
ROM:1DE0 ld c, 0
ROM:1DE2 jp end_of_string
So if my theory is correct, WORD? 0 should return 0x09AC (probably as decimal and possibly in different endianess). WORD 0,256 should change the value at 0x4026 and WORD? 0 after that should return 256. Basically a peek and poke, but only for the calibration memory. If this works, then it would make reverse-engineering the calibration parameters a whole lot faster and save a lot of wear and tear on the EEPROM burner.
-
I have tested and the PS350 behaves as ALM has described.
WORD? <0..45> fetches data from RAM that is read at boot time from EPROM location "0x1FA0" and up to "0x1FFB" just up to the serial number.
WORD <0..45>,<0..65535> writes to same calibration section in RAM. After a power cycle values return to what is stored in EPROM.
I have made a map from what was discovered up to now.
(http://i.imgur.com/ya2ad1L.png)
-
Thanks for confirming my theory!
-
Thanks, I was about to post the same
before I forget, I got the 28C64's today. I'll flash one and verify everything is good. then no more UV eraser needed.
Burning the 28C64B in the minipro
(https://drive.google.com/uc?id=0B0n5ltUlE8YHcVNWTXBjd1gyTTg)
old EPROM in the unit
(https://drive.google.com/uc?id=0B0n5ltUlE8YHQnVSSER3ekNRYkk)
new 28C64B in place
(https://drive.google.com/uc?id=0B0n5ltUlE8YHZ00tWm9tb2IyOGc)
finishing touch, a nice shinny new label
(https://drive.google.com/uc?id=0B0n5ltUlE8YHX29UaW81cTY3S00)
powering on all looks good.
(https://drive.google.com/uc?id=0B0n5ltUlE8YHZXVfdkE3TGh3QWs)
no more UV Erasing the EPROM :-+
Now, onto the topic at hand
Here's the actual values read from my unit and they match the 1FA0-1FFB area of ROM
WORD? # VALUE ROMHEX
0 2476 AC09
1 21988 E455
2 21003 0B52
3 2500 C409
4 21076 5452
5 21076 5452
6 2492 BC09
7 21017 1952
8 20051 534E
9 2491 BB09
10 21032 2852
11 20053 554E
12 2476 AC09
13 49126 E6BF
14 49634 E2C1
15 2493 BD09
16 49632 E0C1
17 50148 E4C3
18 0 0000
19 17299 9343
20 17299 9343
21 2470 A609
22 21910 9655
23 20982 F651
24 2500 C409
25 21076 5452
26 21076 5452
27 2513 D109
28 20785 3151
29 19760 304D
30 2512 D009
31 20818 5251
32 19746 224D
33 2470 A609
34 49170 12C0
35 49634 E2C1
36 2514 D209
37 49784 78C2
38 50308 84C4
39 0 0000
40 17299 9343
41 17299 9343
42 0 0000
43 51830 76CA
44 0 0000
45 51830 76CA
based on we now know the WORD command writes to SRAM my guess now this is how they calibrate the unit.
they probably stick a EPROM in with no cal values in it (ie 1FA0-1FFB = 00)
run various tests and program SRAM until it is cal'd.
read out those values and burn into the units EPROM
I guess the next thing is to figure out what they impact and what the calibration values are
are all 46 values for voltage only or are there other calibration values.
also note the DAC is used in a successive approximation ADC with 13bit resolution via U402A(integrator), U404(comparitor) and U409(analog switch which chooses VMON,IMON and the external Analog Volt input) and the U410(DAC) when the comparitor trips it sets the COMPARE bit[0] in STATUS1
Would it maybe be good to look at the VSET to figure out when and where they use the calibration values?
-
here's an update. I did a WORD 0,0 and wow what a change
at 0v actual volt was ~2400V
at 3000V it ran to 5600V (this is interested)
so just changing the first byte has major impact
I then did a WORD 0,2476 and everything was back to normal
I then tried word 0,2477 and at 50V i got 48.4 which means the higher value actually lowered the output
I then tried word 0,2475 and at 50V I got 50.2V then shows for word 0 a value change of 2 has a 0.8v swing
next I tried setting word 1 to 0 with word 0 back to normal
with the word 00 at 0v I had ~650V on the DMM
everything below 3000V was scewed. above 3000V things where basicaly normal
I'l do more checking and will actually need to try to find at which values does each word have effect.
short of tring to figure out the code now that we know where cal values are
-
no more UV Erasing the EPROM :-+
Yay!
I added the meaning of the calibration values based on my current understanding of the code (what I posted earlier):
WORD? # VALUE ROMHEX
0 2476 AC09 ; +pol vset offset
1 21988 E455 ; +pol vset exponent/multiplier/non-linear parameter if vset < word0
2 21003 0B52 ; +pol vset exponent/multiplier/non-linear parameter if vset >= word0
3 2500 C409 ; +pol vlim offset
4 21076 5452 ; +pol vlim exponent/multiplier/non-linear parameter if vlim < word3
5 21076 5452 ; +pol vlim exponent/multiplier/non-linear parameter if vlim >= word3
6 2492 BC09 ; +pol ilim offset
7 21017 1952 ; +pol ilim exponent/multiplier/non-linear parameter if ilim < word6
8 20051 534E ; +pol ilim exponent/multiplier/non-linear parameter if ilim >= word6
9 2491 BB09 ; +pol itrp offset
10 21032 2852 ; +pol itrp exponent/multiplier/non-linear parameter if itrp < word9
11 20053 554E ; +pol itrp exponent/multiplier/non-linear parameter if itrp >= word9
12 2476 AC09
13 49126 E6BF
14 49634 E2C1
15 2493 BD09
16 49632 E0C1
17 50148 E4C3
18 0 0000
19 17299 9343
20 17299 9343
21 2470 A609 ; -pol vset offset
22 21910 9655 ; -pol vset exponent/multiplier/non-linear parameter if vset < word21
23 20982 F651 ; -pol vset exponent/multiplier/non-linear parameter if vset >= word21
24 2500 C409 ; -pol vlim offset
25 21076 5452 ; -pol vlim exponent/multiplier/non-linear parameter if vlim < word24
26 21076 5452 ; -pol vlim exponent/multiplier/non-linear parameter if vlim >= word24
27 2513 D109 ; -pol ilim offset
28 20785 3151 ; -pol ilim exponent/multiplier/non-linear parameter if ilim < word27
29 19760 304D ; -pol ilim exponent/multiplier/non-linear parameter if ilim >= word27
30 2512 D009 ; -pol itrp offset
31 20818 5251 ; -pol itrp exponent/multiplier/non-linear parameter if itrp < word30
32 19746 224D ; -pol itrp exponent/multiplier/non-linear parameter if itrp >= word30
33 2470 A609
34 49170 12C0
35 49634 E2C1
36 2514 D209
37 49784 78C2
38 50308 84C4
39 0 0000
40 17299 9343
41 17299 9343
42 0 0000
43 51830 76CA
44 0 0000
45 51830 76CA
However, this does not account for approximately half of the calibration memory, so either there is some unused data in there, or my analysis is incomplete. The data looks very similar to the values that I can account for, so it does not look like unused memory to me. I welcome any pointers to where I am wrong. I believe I posted all relevant code, but I am also happy to post a complete listing file.
It might be interesting to zero each set of six bytes using WORD and see if indeed zeroing the first set of bytes only affects the set voltage, the second set only affects the limit, etc. I saw no sign of a checksum on the calibration data apart from a possible checksum for the whole ROM.
based on we now know the WORD command writes to SRAM my guess now this is how they calibrate the unit.
they probably stick a EPROM in with no cal values in it (ie 1FA0-1FFB = 00)
run various tests and program SRAM until it is cal'd.
read out those values and burn into the units EPROM
I would expect them to indeed calibrate with some sort of identity value of the calibration parameters (if there is a multiplier in there, you probably do not want to zero it :P). $DAC appeared to only affect the VSET DAC, which would make it useless for VLIM/ILIM/ITRP calibration. However, the VSET calibration is by far the most critical, so maybe they use a more complicated algorithm similar to what I proposed earlier (try a range of DAC values and fit a curve to the corresponding output voltages), and a simpler two-point calibration for the less critical parameters.
Would it maybe be good to look at the VSET to figure out when and where they use the calibration values?
VSET is not very interesting. It starts at 0x1a87. First it does some parsing and error checking (e.g. does the sign of the value match the polarity setting on the front panel, status2 bit 2, checks that abs(vset) <= vlim). Then the actual work:
ROM:1ABF ld (var_vset), de ; store value for set_control_value
ROM:1AC3 ld a, 0 ; select vset parameter
ROM:1AC5 call set_control_value ; a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
After that some housekeeping (updating variables I have not figured out the meaning of), but no I/O or other interesting stuff. var_vset is a block of four words:
ROM:413C var_vset: dw 0 ; DATA XREF: ROM:03F4r
ROM:413C ; apply_calib_consts+5o ...
ROM:413E var_vlim: dw 1388h ; DATA XREF: ROM:03E7r
ROM:413E ; reset_stuff+56r ...
ROM:4140 var_ilim: dw 1482h ; DATA XREF: ROM:1BA8w
ROM:4140 ; ROM:1BBFr ...
ROM:4142 var_itrp: dw 1482h ; DATA XREF: ROM:1C17w
ROM:4142 ; ROM:1C2Er ...
set_control_value is the real meat. It is called by the VSET/VLIM/ISET/ITRP commands, and the WORD command (hence my initial guess that WORD was setting parameters). This is the interesting part, the rest is more of the same and some housekeeping (like keeping track for the function that sets the DAC which parameter was changed and updating some status variables):
ROM:0959 ; a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
ROM:0959
ROM:0959 set_control_value: ; CODE XREF: ROM:0425p
ROM:0959 ; reset_stuff+6Cp ...
ROM:0959 call conv_value_to_dac ; in: a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
ROM:0959 ; out: hl (dac value corresponding to the set value based on calibration constants)
ROM:095C di
ROM:095D cp 0
ROM:095F jr nz, set_vlim
ROM:0961 ld (var_dac_vset), hl ; set_vset
ROM:0964 ld hl, byte_401A
ROM:0967 bit 7, (hl)
ROM:0969 jr z, set_done
ROM:096B ld hl, byte_40E5
ROM:096E set 0, (hl)
ROM:0970 ld hl, byte_401A
ROM:0973 res 0, (hl)
ROM:0975 jr set_done
ROM:0977 ; ---------------------------------------------------------------------------
ROM:0977
ROM:0977 set_vlim: ; CODE XREF: set_control_value+6j
ROM:0977 cp 1
ROM:0979 jr nz, set_ilim
ROM:097B ld (var_dac_vlim), hl
ROM:097E jr set_done
It first calls the function conv_value_to_dac (more on that later), and then stores the result from conv_value_to_dac in the appropriate memory location (0x4094 to 0x40a3, non-consecutive). It also stores which value it modified. The DAC function (run from timer interrupt) checks these variables, and based on that figures out which values to send to the DAC. Now for conv_value_to_dac:
ROM:08DB ; in: a = { 0: vset, 1: vlim, 2: ilim, 3: itrp }
ROM:08DB ; out: hl (dac value corresponding to the set value based on calibration constants)
ROM:08DB
ROM:08DB conv_value_to_dac: ; CODE XREF: set_control_valuep
ROM:08DB push af
ROM:08DC rlca
ROM:08DD ld e, a
ROM:08DE ld d, 0
ROM:08E0 ld hl, var_vset
ROM:08E3 add hl, de ; figure out where to find the input data
ROM:08E4 ld c, (hl) ; load input data in bc
ROM:08E5 inc hl
ROM:08E6 ld b, (hl)
ROM:08E7 cp 2
ROM:08E9 jr nz, find_calib_ram
ROM:08EB ld hl, (vlim_max_input) ; only for vlim
ROM:08EE push de
ROM:08EF push bc
ROM:08F0 push af
ROM:08F1 ld de, 0Ah
ROM:08F4 call find_hl_magnitude ; input: de = usually 0x0a, hl = ?
ROM:08F4 ; out: hl = 16 - log2(hl) + log2(de) (approximately)
ROM:08F7 pop af
ROM:08F8 pop bc
ROM:08F9 pop de
ROM:08FA add hl, bc
ROM:08FB ld b, h
ROM:08FC ld c, l
ROM:08FD
ROM:08FD find_calib_ram: ; CODE XREF: conv_value_to_dac+Ej
ROM:08FD push af
ROM:08FE ld a, (var_status2)
ROM:0901 bit 2, a
ROM:0903 ld hl, calibration_ram
ROM:0906 jr z, apply_calib_con1
ROM:0908 ld hl, calibration_ram+2Ah
ROM:090B
ROM:090B apply_calib_con1: ; CODE XREF: conv_value_to_dac+2Bj
ROM:090B pop af ; a = param { 0..3 } << 1, e = a << 1, bc = var_vset
ROM:090C rlca
ROM:090D add a, e
ROM:090E ld e, a
ROM:090F add hl, de
ROM:0910 ld e, (hl)
ROM:0911 inc hl
ROM:0912 ld d, (hl)
ROM:0913 inc hl
ROM:0914 push hl
ROM:0915 ld h, b
ROM:0916 ld l, c
ROM:0917 or a
ROM:0918 sbc hl, de
ROM:091A pop de
ROM:091B jr c, apply_calib_con2_or_3 ; figure out if we use the 2nd or 3rd calib word
ROM:091D inc de
ROM:091E inc de
ROM:091F
ROM:091F apply_calib_con2_or_3: ; CODE XREF: conv_value_to_dac+40j
ROM:091F ld a, 0
ROM:0921 call c, cpl_word ; hl = -hl
ROM:0921 ; a = 1
ROM:0924 ex de, hl
ROM:0925 ld c, (hl)
ROM:0926 inc hl
ROM:0927 ld b, (hl)
ROM:0928 ld (var_status_thing), a
ROM:092B pop af
ROM:092C push af
ROM:092D push bc
ROM:092E ld hl, byte_99F
ROM:0931 add a, l
ROM:0932 ld l, a
ROM:0933 jr nc, loc_936
ROM:0935 inc h
ROM:0936
ROM:0936 loc_936: ; CODE XREF: conv_value_to_dac+58j
ROM:0936 ld a, (hl)
ROM:0937 cp 0
ROM:0939 jr z, loc_942
ROM:093B ld b, a
ROM:093C
ROM:093C loc_93C: ; CODE XREF: conv_value_to_dac+65j
ROM:093C sla e
ROM:093E rl d
ROM:0940 djnz loc_93C
ROM:0942
ROM:0942 loc_942: ; CODE XREF: conv_value_to_dac+5Ej
ROM:0942 pop hl
ROM:0943 push de
ROM:0944 call some_calc_hl_de ; in:
ROM:0944 ; de = intermediate dac value
ROM:0944 ; hl = calib word 2 or 3
ROM:0944 ; out:
ROM:0944 ; hl = result
ROM:0944 ; de = ???
ROM:0947 bit 7, h
ROM:0949 jr z, loc_94C
ROM:094B inc de
ROM:094C
ROM:094C loc_94C: ; CODE XREF: conv_value_to_dac+6Ej
ROM:094C pop hl
ROM:094D add hl, de
ROM:094E ld a, (var_status_thing)
ROM:0951 bit 0, a
ROM:0953 jr z, loc_957
ROM:0955 set 7, h
ROM:0957
ROM:0957 loc_957: ; CODE XREF: conv_value_to_dac+78j
ROM:0957 pop af
ROM:0958 ret
This is the entire function. I have discussed my analysis of a fair amount of the code in previous posts. My analysis of find_hl_magnitude (at 0x08ba) is new and preliminary, but is only relevant for vlim. Could be a form of rounding to order of magnitude (it tries to shift left hl until hl > de). Then it retrieves the calibration word1 (what I call offset) and subtracts it from the set value. If this result is negative, the second word is used for the subsequent calculation, otherwise the third word. Regardless of the polarity, it inverts the polarity (two's complement). Lets call this result the intermediate dac value. The block at 0x93c is skipped unless the values at 0x99f are non-zero (they are not in this dump).
Then the second or third word go into the creatively named some_calc_hl_de function that I posted earlier and suggested it is some sort of non-linear function (any insights would be appreciated!). I am not familiar with math in assembly on micros without multiplier, so I do not recognize this algorithm. I could do some digging or try to run it in a simulator to see what it does I guess. Let me know if you want me to dive into that.
Then it discards one of the result (16 bit * 16 bit multiply that discards the lower 16 bits?), and adds this to the intermediate dac value. Then it sets bit 7 based on a status variable, and that is the result that will be sent to the DAC. I have not looked into the details of that, but I know it happens in the function at 0x0ebb, which is called from the interrupt handler.
-
here's an update. I did a WORD 0,0 and wow what a change
at 0v actual volt was ~2400V
at 3000V it ran to 5600V (this is interested)
Seems definitely an offset.
I then tried word 0,2477 and at 50V i got 48.4 which means the higher value actually lowered the output
Which matches my observation that it is subtracted from vset.
next I tried setting word 1 to 0 with word 0 back to normal
with the word 00 at 0v I had ~650V on the DMM
everything below 3000V was scewed. above 3000V things where basicaly normal
This matches my observation that word1 is used if vset < word0. We established that word0 corresponded to something like 2.5 kV, so it makes sense that word1 is used for values below 2.5 kV. If you were to change word2, I would expect the values above 2.5 kV to be messed up.
I'l do more checking and will actually need to try to find at which values does each word have effect.
short of tring to figure out the code now that we know where cal values are
I disagree. I think analyzing the code is the easier route, but obviously we should double check with the real equipment. For example, do you see any effect in any mode/polarity if you set word 12 to 0? The value of word 12 is identical to word 0 (suggesting a vset offset to me), but according to my analysis it should never be used.
Especially if I am right that there are two non-linear parameters that affect vset, I think that black box reverse-engineering will require a large number of points to establish the response (although I imagine you could brute-force it with a voltage PS350 and a voltmeter both under computer control). I believe we have narrowed down the code that it is responsible (see my previous), and it is just a matter of studying that code in more detail.
My current theory is that for vset, the dac value is:
\[
dac(v_{set}) = \left\{
\begin{array}{ll}
f(word_0-v_{set}, word_1) & : v_{set} < word_0\\
f(word_0-v_{set}, word_2) & : v_{set} >= word_0
\end{array}
\right.
\]
Where f(x,y) might be a multiply or something similar.
-
I have been playing around on my PS350 and I can confirm they use three point calibration for all parameters and positive and negative polarity separate what comes out from what alm has identified in the code and smgvbest tested.
This way they can compensate for some degree of system nonlinearity. In theory you could run the DAC from 0 to full scale and see where the ideal mid-point would be and then compensate with W1,W2 factors but what it seems from all calibrations available to me they just set the midscale first with W0 offset and then compensate for the values below and above.
I have made a small graphic to illustrate after confirming on the instrument itself what they do. It’s just an illustration of alms equations:
(http://i.imgur.com/Hsrueoi.png)
One additional thing I did find out is what that W12...17 are. They calibrate the read back voltage value that is shown on display and read back over GPIB with VOUT, IOUT:
W12 +pol voltage readback display offset
W13 +pol voltage readback display scale if vset < W12
W14 +pol voltage readback display scale if vset >= W12
W15 +pol current readback display offset
W16 +pol current readback display scale if vset < W15
W17 +pol current readback display scale if vset >= W15
I have also been able to calibrate my PS350 voltage set and read back in this way quite successfully up to now, for current I have to build some custom high voltage resistors to make the calibration.
The procedure i used so far:
- Set Vset to 2500V
- Modify W0 until reference DMM reads 2500V
- Set Vset to 100V
- Modify W1 until reference DMM reads 100V
- Set Vset to 4500V
- Modify W2 until reference DMM reads 4500V
- Set Vset to 2500V
- Modify W12 until PS350 display reads 2500V
- Set Vset to 100V
- Modify W13 until PS350 display reads 100V
- Set Vset to 4500V
- Modify W14 until PS350 display reads 4500V
One thing to watch out the last digit of the scale values is strange it seems as it determines the sign of the multiplayer or something as if changing it from 49560 to 49561 screws up the display completely but in steps of +/-10 its ok (Tested on W13). Probably it’s the same for all other factors I have not checked.
-
Wow, I get up and what wonderful posts to wake up too.
I'd still love to match this with the actual code as @alm mentions. if he is willing to continue to assist (your disassembly skills exceed mine) that would be great.
@Dexter2 thank you so much for your checks.
tasks as I see them are
1. Continue looking at code to verify all calibration options.
2. Verify calibration options (testing at DUT)
3. Develop and test manual calibration procedure (for VSET looks like this may be done)
4. Develop and test automated calibration procedure (python or perl code preferred as not everyone has other tools)
is anyone interested in #4?
there is a possibility of extending the range of the unit beyond 5Kv but to do safely we'd have to hack not only the firmware but the HV section. some components are not rated more than 6Kv (C5 & C8) while components in the cockcroft multiplier are rated at 4Kv (C1-C4)
any one interested in pursing that or call it quits with the calibration?
-
I managed to fully calibrate my unit (except the ITRIP and VLIM). Only need to burn the new EPROM now (hope there are no CRC checks)
I also made a small crude program with it you can quicklly change parameters and get the calibration for Voltage/Current done. So it does not calculate anything it it just a quick tool to do it by hand and to modify the Firmware at the end. Program is in LabView. To keep it simple the GPIB interface is initialized trough niMAX.
(http://i.imgur.com/49KtqV4.png)
And for the end the new memory map. Still a few locations are unknown. Any Ideas?
(http://i.imgur.com/rAZtPW2.png)
-
I have been playing around on my PS350 and I can confirm they use three point calibration for all parameters and positive and negative polarity separate what comes out from what alm has identified in the code and smgvbest tested.
Thanks for doing these tests!
This way they can compensate for some degree of system nonlinearity. In theory you could run the DAC from 0 to full scale and see where the ideal mid-point would be and then compensate with W1,W2 factors but what it seems from all calibrations available to me they just set the midscale first with W0 offset and then compensate for the values below and above.
That is obviously the fastest way, and may be sufficient depending on the INL of the system and the specifications. It could be that they do a linearity test as part of the performance verification, but we'll never know without a calibration procedure (beyond 'no user serviceable components inside'). Obviously offset and gain is also the extent of the adjustment in purely analog power supplies with trimmers, but I could see a high-voltage having a more sophisticated scheme because of possible voltage coefficients. Too bad they do not even publish an incoming test or procedure to verify the performance against published specifications like some other manufacturers.
One additional thing I did find out is what that W12...17 are. They calibrate the read back voltage value that is shown on display and read back over GPIB with VOUT, IOUT:
Thanks! That makes sense. I have not looked at the readout display at all. Now that you mention it, I should search for the address of word 12 and will likely find the readout code.
I have also been able to calibrate my PS350 voltage set and read back in this way quite successfully up to now, for current I have to build some custom high voltage resistors to make the calibration.
Nice! I wonder about doing VLIM. There are software checks that limit VSET < VLIM which may prove an obstacle to testing the analog (crowbar?) circuit. Maybe deliberately programming W0-2 or W21-23 to be x% high?
One thing to watch out the last digit of the scale values is strange it seems as it determines the sign of the multiplayer or something as if changing it from 49560 to 49561 screws up the display completely but in steps of +/-10 its ok (Tested on W13). Probably it’s the same for all other factors I have not checked.
Interesting, I will see if I can find out anything in the code.
I'd still love to match this with the actual code as @alm mentions. if he is willing to continue to assist (your disassembly skills exceed mine) that would be great.
Sure, I will do some digging in some of the points Dexter2 raised. Let me know if you have additional questions that could be answered from the code.
is anyone interested in #4?
I am interested, but given my lack of access to the equipment (or plans to acquire one), I think my help would be limited to suggesting algorithms.
there is a possibility of extending the range of the unit beyond 5Kv but to do safely we'd have to hack not only the firmware but the HV section. some components are not rated more than 6Kv (C5 & C8) while components in the cockcroft multiplier are rated at 4Kv (C1-C4)
any one interested in pursing that or call it quits with the calibration?
There appears to be support for a multiplier for VSET (for lower voltage ranges) through 0x099f (I plan to check the PS310 firmware from the other thread to see if it has non-zero values as I would expect). Not a divider, though it would not be difficult to add to the set and the readout circuits. For the set circuits, it might be as easy as shifting right in the multiplier loop instead of left.
And for the end the new memory map. Still a few locations are unknown. Any Ideas?
I will find the readout code and see if I can find a third readout calibration factor.
-
Just re-burned my EPROM. Works without problems no CRC checks :clap:.
Only one thing to watch out. To calibrate voltage you need a high voltage probe I used a HAMEG 50kV high voltage probe connected to a calibrated 10Meg input resistance DMM. The problem is as it seems these probes are not to precise, so before doing calibration determine the exact factor for the high voltage probe dont take the 1:1000 for granted it could be quite some % off.
-
Some DMMs have some variation in their input resistance (some even go to 10 GOhm). Also, I imagine a 50 kV probe might be adjusted for the end of its range (like the SR calibration, apparently ;)). Due to voltage coefficients, the division ratio may not be all that flat across its voltage range. I can see how that would make checking linearity of the power supply tricky without another HV source.
-
1. Continue looking at code to verify all calibration options.
2. Verify calibration options (testing at DUT)
3. Develop and test manual calibration procedure (for VSET looks like this may be done)
4. Develop and test automated calibration procedure (python or perl code preferred as not everyone has other tools)
For me getting the calibration done is enaugh im happy. But would be interested in the unknown locations that we have not jet uncovered.
I know my calibration assist program is not in a free lauguage but it was the quickest i could make one as i use LabView all the time. I think National Instrument also has a LabView 45day free full working trial if you want to play with it. If required i can make an executable you would then only need to download a free runtime engine to get it working. To automate the software more it would be possible to read in the offset and the two factors, read values from a external DMM in all three calibration points for all parameters and then calculate the new factors but it probablly does not make sense for a home calibration.
-
Just a quick note as i did not write any instructions for the calibration program. First you calibrate all the wanted factors then you read out the calibration memory with "Read calibration memory". Next open your original BIN of the whole EPROM content and than just press write new EPROM. The software generates the new BIN ready to be written into the EPROM.
-
Updated the table alm created with locations for readback calibration below.
WORD? # VALUE ROMHEX
0 2476 AC09 ; +pol vset offset
1 21988 E455 ; +pol vset exponent/multiplier/non-linear parameter if vset < word0
2 21003 0B52 ; +pol vset exponent/multiplier/non-linear parameter if vset >= word0
3 2500 C409 ; +pol vlim offset
4 21076 5452 ; +pol vlim exponent/multiplier/non-linear parameter if vlim < word3
5 21076 5452 ; +pol vlim exponent/multiplier/non-linear parameter if vlim >= word3
6 2492 BC09 ; +pol ilim offset
7 21017 1952 ; +pol ilim exponent/multiplier/non-linear parameter if ilim < word6
8 20051 534E ; +pol ilim exponent/multiplier/non-linear parameter if ilim >= word6
9 2491 BB09 ; +pol itrp offset
10 21032 2852 ; +pol itrp exponent/multiplier/non-linear parameter if itrp < word9
11 20053 554E ; +pol itrp exponent/multiplier/non-linear parameter if itrp >= word9
12 2476 AC09 ; +pol voltage readback display offset0
13 49126 E6BF ; +pol voltage readback display scale if VOUT < Word12
14 49634 E2C1 ; +pol voltage readback display scale if VOUT >= Word12
15 2493 BD09 ; +pol current readback display offset
16 49632 E0C1 ; +pol current readback display scale if IOUT < Word15
17 50148 E4C3 ; +pol current readback display scale if IOUT >= Word15
18 0 0000
19 17299 9343 ; **unknown**
20 17299 9343 ; **unknown**
21 2470 A609 ; -pol vset offset
22 21910 9655 ; -pol vset exponent/multiplier/non-linear parameter if vset < word21
23 20982 F651 ; -pol vset exponent/multiplier/non-linear parameter if vset >= word21
24 2500 C409 ; -pol vlim offset
25 21076 5452 ; -pol vlim exponent/multiplier/non-linear parameter if vlim < word24
26 21076 5452 ; -pol vlim exponent/multiplier/non-linear parameter if vlim >= word24
27 2513 D109 ; -pol ilim offset
28 20785 3151 ; -pol ilim exponent/multiplier/non-linear parameter if ilim < word27
29 19760 304D ; -pol ilim exponent/multiplier/non-linear parameter if ilim >= word27
30 2512 D009 ; -pol itrp offset
31 20818 5251 ; -pol itrp exponent/multiplier/non-linear parameter if itrp < word30
32 19746 224D ; -pol itrp exponent/multiplier/non-linear parameter if itrp >= word30
33 2470 A609 ; -pol voltage readback display offset
34 49170 12C0 ; -pol voltage readback display scale if |VOUT| < Word33
35 49634 E2C1 ; -pol voltage readback display scale if |VOUT| >= Word33
36 2514 D209 ; -pol current readback display offset
37 49784 78C2 ; -pol current readback display scale if |IOUT| < Word36
38 50308 84C4 ; -pol current readback display scale if |IOUT| >= Word36
39 0 0000
40 17299 9343 ; **unknown**
41 17299 9343 ; **unknown**
42 0 0000
43 51830 76CA ; **unknown**
44 0 0000
45 51830 76CA ; **unknown**
EPROM values are based on Sandra's EPROM and are helpfull for orientation.
The locations first thought to be model specific that turned out to be calibration factors for VLIM are probablly even not calibrated in factory and are just preset with default values as they are all the same for all EPROMs. So if you want to have the unit preset to default initial values to calculate the calibration factors for voltage/current set/readback afterwards this probablly are the initial ones. Offset:2500 Scale:21076.
-
The VLIM / ITRP values obviously do not need to be very accurate, it may very well be that they are the same within a certain model (although this does not seem to be the case for ITRP). This is the calibration data from a PS310 1.4 rom from the older thread:
0. 6C 02
1. 1D 54
2. 56 53
3. 71 02
4. 54 52
5. 54 52
Note the different offset (W3). The slope appears to be the same.
-
Thanks! That makes sense. I have not looked at the readout display at all. Now that you mention it, I should search for the address of word 12 and will likely find the readout code.
I found the code. The function that does this starts at 0x0a39. I am still investigating the details, but similar to the settings I see three sets three words. Calculation with the three words looks fairly similar to the setting. I am not sure yet what the third set of three words refers to yet, I will have to look at the ADC code in more detail.
It involves a checksum (bytewise XOR) over a bunch of bitfields that are modified at various places. By toggling bits in the bitfields, it turns off bits in the checksum. The program relies on the checksum to tell which value to update. I need to identify all variables and trace where they are being updated and what they mean.
There appears to be support for a multiplier for VSET (for lower voltage ranges) through 0x099f (I plan to check the PS310 firmware from the other thread to see if it has non-zero values as I would expect). [...]
I checked the PS310 1.4 (without GPIB) firmware from the previous thread Sandra linked to, and indeed the block of four bytes (located at a slightly different address) is non zero:
ROM:095C unk_95C: db 2 ; DATA XREF: sub_898+53o
ROM:095D db 2
ROM:095E db 1
ROM:095F db 1
This would scale the values sent to the DAC so the smaller voltage range would still correspond to full scale on the DAC. Though it appears that current values are also scaled up. I wonder if there is a separate block for readout, or that they just change the readout calibration constants to match? I am not sure if figuring this out is really a priority, but it at least it confirms my theory that the parameters at 0x99F (0x95C in the PS310 firmware) are model-specific.
And for the end the new memory map. Still a few locations are unknown. Any Ideas?
I will find the readout code and see if I can find a third readout calibration factor.
See above. Working on it.
Other thing I noticed. Sandra (and the schematic) has U507 Q4 as NC, but this code (that appears to shutdown the supply in case of I_FAULT, PRI_FAULT or V_FAULT), sets it:
ROM:0D42 shutdown: ; CODE XREF: sub_D94+15p
ROM:0D42 ; sub_D94+57p ...
ROM:0D42 ld hl, port_78h_value
ROM:0D45 set 4, (hl) ; spare???
ROM:0D47 res 0, (hl) ; set -shutdown low
ROM:0D49 ld a, (port_78h_value)
ROM:0D4C out (78h), a ; set misc switches (u507)
Old code? different model? Error in schematic?
Does anyone know what J504 (status1 bit 6) connects to? My copy of the schematics is not searchable, and a quick scan through the schematic pages did not reveal anything. There is a function at 0x108c that checks it and shuts down the power and sets the voltage to zero if it is high. Could be another fault or interlock indicator?
Does anyone know what port 0x3a is connected to? It is reading from it in a function that also writes to the display (for now named something_display :P):
ROM:01C9 loc_1C9: ; CODE XREF: sub_15D+66j
ROM:01C9 in a, (3Ah)
ROM:01CB bit 7, a
ROM:01CD jp z, loc_227
ROM:01D0 set 1, c
ROM:01D2 jp loc_227
Appears to be related to editing values on the display, so could be keyboard or display.
-
here's the details on port 3Ah and the 20h bit 6 which is the rear panel switch to select between monitor mode or set mode for the V_MON/I_MON connectors on the back
this is my most current port and address map
MEMORY ADDRESS OF EPROM: 0000~1FFF (PROGRAM SPACE:8KB,ST M2764A)
SRAM: 4000~47FF (DATA SPACE:2KB,HITACHI HM6116)
IRQ_ROUTIINE: 0038h
SOURCE: SHEET 6
CLK->(U610)->TIMER @ 976.56hz/0.001024ms (4Mhz/4096(U610)74HC4020)
GPIB
SRAM ADDRESSES:
SRAM_MISC = 413AH
SRAM_STATUS1 = NA
SRAM_STATUS2 = 401CH
EPROM ADDRESSES:
*IDN? STRING 000019fah: 53 74 61 6E 66 6F 72 64 52 65 73 65 61 72 63 68 ; StanfordResearch
00001a0ah: 53 79 73 74 65 6D 73 2C 50 53 ; Systems,PS
191CH GPIB OFFSETS TABLE 0000191ch: 24 35 19 2A 3B 19 48 6E 19 49 79 19 53 89 19 54 ; $5.*;.Hn.Iy.S‰.T
CMD CHAR+OFFSET 0000192ch: 8F 19 56 9A 19 57 AA 19 00 ; .Vš.Wª..
193BH GPIB COMMAND 00001935h: 44 41 43 BE 1C 00 43 4C 53 6A 1A 45 53 45 3C 1E ; DAC¾..CLSj.ESE<.
CMD+OFFSET+00H 00001945h: 45 53 52 AE 1E 49 44 4E B0 19 50 53 43 72 1E 52 ; ESR®.IDN°.PSCr.R
00001955h: 43 4C 5A 1D 52 53 54 4E 1A 53 41 56 35 1D 53 52 ; CLZ.RSTN.SAV5.SR
00001965h: 45 06 1E 53 54 42 08 1F 00 56 4F 46 14 1A 56 4F ; E..STB...VOF..VO
00001975h: 4E 24 1A 00 4C 49 4D 7F 1B 4F 55 54 7E 1C 54 52 ; N$..LIM.OUT~.TR
00001985h: 50 EE 1B 00 4D 4F 44 9E 1C 00 43 4C 52 3B 1A 4D ; Pî..MODž..CLR;.M
00001995h: 4F 44 FF 1C 00 4C 49 4D 06 1B 4F 55 54 5D 1C 53 ; ODÿ..LIM..OUT].S
000019a5h: 45 54 87 1A 00 4F 52 44 ; ET‡..ORD
19FAH 000019fah: F3 CD D5 11 FB 0E 00 C3 D4 15 CD 9D 17 C2 FD 17 ; óÍÕ.û..ÃÔ.Í.Âý.
00001a0ah: 21 8D 1F 11 3C 41 01 09 00 ED B0 ; !..<A...í°
1F7BH 00001f7bh: 5A 31 33 34 ; Z134
1F7FH EPROM_VERSION_NUMBER 00001f7fh: 31 2E 33 34 ; 1.34
1F83H 00001f83h: 88 13 88 13 82 14 82 14 64 00 ; ˆ.ˆ.‚.‚.d.
1F8DH 00001f8dh: 00 00 88 13 82 14 82 14 00 00 00 00 00 00 00 00 ; ..ˆ.‚.‚.........
00001f9dh: 0E 48 0D ; .H.
1FA0H EPROM_CAL_DATA 00001fa0h: AC 09 E4 55 0B 52 C4 09 54 52 54 52 BC 09 19 52 ; ¬.äU.RÄ.TRTR¼..R
00001fb0h: 53 4E BB 09 28 52 55 4E AC 09 E6 BF E2 C1 BD 09 ; SN».(RUN¬.æ¿âÁ½.
00001fc0h: E0 C1 E4 C3 00 00 93 43 93 43 A6 09 96 55 F6 51 ; àÁäÃ..“C“C¦.–UöQ
00001fd0h: C4 09 54 52 54 52 D1 09 31 51 30 4D D0 09 52 51 ; Ä.TRTRÑ.1Q0MÐ.RQ
00001fe0h: 22 4D A6 09 12 C0 E2 C1 D2 09 78 C2 84 C4 00 00 ; "M¦..ÀâÁÒ.x„Ä..
00001ff0h: 93 43 93 43 00 00 76 CA 00 00 76 CA ; “C“C..vÊ..vÊ
1FFCH EPROM_SERIAL_NUMBER 00001ffch: 31 31 33 37 ; 1137
GPIB
DAC/$DAC CLS/*CLS ESE/*ESE ESR/*ESR
IDN/*IDN PSC/*PSC RCLZ/*RCL RSTN/*RST
SAV/*SAV SRE/*SRE STB/*STB VOF/HVOF
VON/HVON LIM/ILIM OUT/IOUT TRP/ITRP
MOD/SMOD CLR/TCLR MOD/TMOD LIM/VLIM
OUT/VOUT SET/VSET ORD/WORD
I/O ADDRESSES:
U504 (A3-A5 -> A-C, A6-G1, WR->!G2A, IORQ->!G2B )
40H: SPARE
48H:-SETS -> U407/U408
------------------------------
BIT0: U407A / GND->U405.3
BIT1: U407B / U410.RF -> U405.3
BIT2: U408A / ANALOG_VOLTAGE
BIT3: U408B / I_OUT_MONITOR
BIT4: U408C / CV_SET
BIT5: U408D / DV_LIM
BIT6: U407C / I_LIM
BIT7: U407D / I_TRIP
------------------------------
50H:-DAC U410 12BIT DAC AD7542
50H DAC_LOW_NIBBLE
51H DAC_MID_NIBBLE
52H DAC_HIGH_NIBBLE
53H DAC_LOAD
58H:-LED U611 74HC374
------------------------------
BIT0: L0
BIT1: L1
BIT2: L2
BIT3: -AD1/V_MON
BIT4: -AD2/I_MON
BIT5: -AD3/ANALOG_VOLTAGE_IN
BIT6: -IO
BIT7: UNUSED
------------------------------
60H:-SEGB U606 74HC374
------------------------------
BIT0: EDP
BIT1: EG
BIT2: EF
BIT3: EE
BIT4: ED
BIT5: EC
BIT6: EB
BIT7: EA
------------------------------
68H:-SEGA U609 74HC374
------------------------------
BIT0: ODP
BIT1: OG
BIT2: OF
BIT3: OE
BIT4: OD
BIT5: OC
BIT6: OB
BIT7: OA
------------------------------
70H:-STROBE (STROB0-STROB5 LED) (STROB2-4 KEYBOARD SCAN OUT)
------------------------------
BIT0: STROB0 (LED)
BIT1: STROB1 (LED)
BIT2: STROB2 (LED,KBD)
BIT3: STROB3 (LED,KBD)
BIT4: STROB4 (LED,KBD)
BIT5: STROB5 (LED)
BIT6: STROB6 ()
BIT7: STROB7 ()
------------------------------
78H: MISC -> (U507,74HC374 OCTAL D-TYPE FLIP-FLOP) >CLK
------------------------------
BIT0: -SHUTDOWN
BIT1: UPOK
BIT2: -FLAG_RESET
BIT3: -TIMER_RESET
BIT4: (SPARE)
BIT5: -POS
BIT6: -NEG
BIT7: FILTER
------------------------------
U505 (A3-A5 -> A-C, !M1->G1, A6->!G2A, IORQ->!G2B )
00H: SPARE
08H: SPARE
10H: SPARE
18H: SPARE
[b]20H: STATUS1 U506->74HC244
------------------------------
BIT0: COMPARE
BIT1: I_FAULT
BIT2: CUR_LIM
BIT3: PRI_FAULT
BIT4: V_FAULT
BIT5: TIMER
BIT6: -J504/SET_MONITOR_SW
BIT7: GND[/b]
------------------------------
28H: STATUS2 U512->74HC244
------------------------------
BIT0: HV_ON
BIT1: HV_OFF
BIT2: J501/-HV_SW_POS
BIT3: J502/-HV_SW_NEG
BIT4: GND
BIT5: GND
BIT6: GND
BIT7: GND
------------------------------
30H: -KBD
------------------------------
BIT0: KBD0
BIT1: KBD1
BIT2: KBD2
BIT3: KBD3
BIT4: KBD4
BIT5: KBD5
BIT6: KBD6
BIT7: KBD7
key press display
01 Man
02 GPIB
03 left-arrow
04 Right arrow
05 up-arrow
06 down-arrow
07 Enter
08 Select
09 STO
10 RCL
11 CLR
12 .
13 0
14 7
15 4
16 1
17 8
18 5
19 2
20 9
21 6
22 3
------------------------------
38H: -GPIB
------------------------------
READ
38H GPIB_INT_STATUS_0
BIT0: INT0 (1 WHEN STATUS 1 BIT SET)
BIT1: INT1 (1 WHEN BITS 2-7 OF STATUS 0 SET)
BIT2: BI (BYTE IN)
BIT3: BO (BYTE OUT)
BIT4: END (LAST BYTE RECEIVED)
BIT5: SPAS (RSV1/2 SERVICE REQUEST)
BIT6: RCL (REMOTE/LOCAL CHANGE)
BIT7: MAC (ADDRESS CHANGE)
39H GPIB_INT_STATUS_1
BIT0: GET (GROUP EXECUTE TRIGGER)
BIT1: ERR (ERROR)
BIT2: UNC (UNRECOGNIZED COMMAND)
BIT3: APT (ADDRESS PASS THROUGH)
BIT4: DCAS (DEVICE CLEAR ACTIVE STATE)
BIT5: MA (MY ADDRESS)
BIT6: SRQ (SERVICE REQUEST)
BIT7: IFC (INTERFACE CLEAR)
[b]3AH GPIB_ADDRESS_STATUS
BIT0: REM
BIT1: LLO
BIT2: ATN
BIT3: LPAS
BIT4: TPAS
BIT5: LADS
BIT6: TADS
BIT7: ULPA[/b]
3BH GPIB_BUS_STATUS
3EH GPIB_CMD_PASS_THRU
3FH GPIB_DATA_IN
WRITE
38H GPIB_INT_MASK_0
39H GPIB_INT_MASK_1
3BH GPIB_AUXILIARY_CMD
3CH GPIB_ADDRESS
3DH GPIB_SERIAL_POLL
3EH GPIB_PARALLEL_POLL
3FH GPIB_DATA_OUT
------------------------------
-
Just want to say thank you, I am enjoying the show here.
I am impressed how the eevblog sometime sets up a wonderful skilled team to solve the EE problems.
:-+
-
I know my calibration assist program is not in a free language but it was the quickest i could make one as i use LabView all the time. I think National Instrument also has a LabView 45day free full working trial if you want to play with it. If required i can make an executable you would then only need to download a free runtime engine to get it working. To automate the software more it would be possible to read in the offset and the two factors, read values from a external DMM in all three calibration points for all parameters and then calculate the new factors but it probably does not make sense for a home calibration.
No problem and thank you for doing this so quick.
The trial is 7 days but it says you can extend 45 day inside the product. (yes I downloaded it :) )
I did play with the 1st three offsets and now my unit is <1V of target value full scale.
will play with rest as I have time.
-
I think you might want to add 0x99F (in your PS350 firmware) as four bytes that define a multiplier for the current/voltage scales, since I verified them to be different between the PS310 and PS350. This is how I described it in my listing:
; Four byte array that defines exponents for scale adjustment for vset/vlim/ilim/itrp: input values are multiplied by 2^n after subtracting the offset but before applying the other calibration parameter.
This would mean the voltages were multiplied by four and the current by two to map to the DAC values according to the PS310 dump I looked at. This exactly matches the 1.25 kV vs 5 kV voltage range. I am guessing they use an 8x lower value shunt resistor to compensate for the increased current (20 mA / 8 * 2 = 5 mA).
Any idea what the relevance of ulpa (last LSB of address recognized by TMS9914, 0x3a bit 7) is? There is one function (at 0x674) that checks it (and some other variables) to decide to execute RTL through gpib_rtl (aux command 0x7):
ROM:06C6 in a, (3Ah)
ROM:06C8 bit 7, a
ROM:06CA jr z, loc_6DA
ROM:06CC bit 6, a
ROM:06CE jr z, loc_6D1
ROM:06D0 ret
ROM:06D1 ; ---------------------------------------------------------------------------
ROM:06D1
ROM:06D1 loc_6D1: ; CODE XREF: gpib_something_rtl+5Aj
ROM:06D1 ld a, 3
ROM:06D3 cp b
ROM:06D4 jr nz, locret_6D9
ROM:06D6 call gpib_rtl
The only thing I can come up with is a special GPIB address to configure it as talk-only, but I could find no mention of it in the manual. What other significance could the LSB have, since the address could be both odd and even? Or am I missing something about GPIB? I am reasonably familiar with using GPIB, but have never implemented a GPIB device.
I have now pretty much figured out the main loop. The IRQ handler at 0x38 will update the DACs, handle some GPIB and eventually jump back to it unless it encounters a (presumably fatal) error:
ROM:00E3 main_loop: ; CODE XREF: sub_C3+1Bj
ROM:00E3 ; irq_service+C1j ...
ROM:00E3 ei
ROM:00E4 call parse_gpib_commands
ROM:00E7 call gpib_something_rtl
ROM:00EA call check_j504
ROM:00ED call update_displays
ROM:00F0 call upd_settings_checksum
ROM:00F3 call do_readouts
ROM:00F6 call display_readout
ROM:00F9 jp main_loop
Obviously the gpib_something_rtl is still unclear, which is where the snippet posted above came from.
-
This is the definition of the ULPA bit
This bit shows the LSB of the last address recognized by the TMS9914A
this is a bit further explaination of it
The' edpa' bit is used to enable the dual addressing mode of the TMS9914A. It causes the LSB of the address to be
ignored by the address comparator giving two consecutive primary addresses for the device. The address by which
the TMS9914A was selected is indicated by the 'ulpa' bit of the Address Status Register.
ah, I just noticed by the schematic they attached the D0-D7 to the TMS9914A in reverse ie. D0->D7, D7->D0 (see attached)
so if that is true then bit 7 is not ULPA but is REM
and REM is
The device is in the remote state
-
Ah, that explains it! Checking REM before GTL makes complete sense. I guess they reversed the connection because the TMS9914A seems backward itself (D7 is the LSB). So now the MSB on the Z80 is also the MSB on the TMS9914A. I had actually already assumed that was the case (D0 connected to the LSB) without checking the schematic when decoding the command (GTL = 0x7).
-
I need to update my portmap to flip these bits around to match.
-
Here's my updated port/memory map with the GPIB BIT Order fliped
and just because I'm still looking at things.
And the switching frequency of the 555 timer driving the HV transformer is ~39.925Khz
this is fed into a flipflop then out to 2 3-Input NAND gates to drive the GATE of the 2 IFR532's
level is set via the VDRIVE signal to the COMMON of the transformer. The HVOFF signal disables the output of the 2 NAND gates thus disabling the HV output.
MEMORY ADDRESS OF EPROM: 0000~1FFF (PROGRAM SPACE:8KB,ST M2764A)
SRAM: 4000~47FF (DATA SPACE:2KB,HITACHI HM6116)
IRQ_ROUTIINE: 0038h
SOURCE: SHEET 6
CLK->(U610)->TIMER @ 976.56hz/0.001024ms (4Mhz/4096(U610)74HC4020)
GPIB
U201 -> 555 TIMER -> PIN 3
SWITCHING FREQ = 39.925Khz FOR HV TRANSFORMER
SRAM ADDRESSES:
SRAM_MISC = 413AH
SRAM_STATUS1 = NA
SRAM_STATUS2 = 401CH
EPROM ADDRESSES:
*IDN? STRING 000019fah: 53 74 61 6E 66 6F 72 64 52 65 73 65 61 72 63 68 ; StanfordResearch
00001a0ah: 53 79 73 74 65 6D 73 2C 50 53 ; Systems,PS
191CH GPIB OFFSETS TABLE 0000191ch: 24 35 19 2A 3B 19 48 6E 19 49 79 19 53 89 19 54 ; $5.*;.Hn.Iy.S‰.T
CMD CHAR+OFFSET 0000192ch: 8F 19 56 9A 19 57 AA 19 00 ; .Vš.Wª..
193BH GPIB COMMAND 00001935h: 44 41 43 BE 1C 00 43 4C 53 6A 1A 45 53 45 3C 1E ; DAC¾..CLSj.ESE<.
CMD+OFFSET+00H 00001945h: 45 53 52 AE 1E 49 44 4E B0 19 50 53 43 72 1E 52 ; ESR®.IDN°.PSCr.R
00001955h: 43 4C 5A 1D 52 53 54 4E 1A 53 41 56 35 1D 53 52 ; CLZ.RSTN.SAV5.SR
00001965h: 45 06 1E 53 54 42 08 1F 00 56 4F 46 14 1A 56 4F ; E..STB...VOF..VO
00001975h: 4E 24 1A 00 4C 49 4D 7F 1B 4F 55 54 7E 1C 54 52 ; N$..LIM.OUT~.TR
00001985h: 50 EE 1B 00 4D 4F 44 9E 1C 00 43 4C 52 3B 1A 4D ; Pî..MODž..CLR;.M
00001995h: 4F 44 FF 1C 00 4C 49 4D 06 1B 4F 55 54 5D 1C 53 ; ODÿ..LIM..OUT].S
000019a5h: 45 54 87 1A 00 4F 52 44 ; ET‡..ORD
19FAH 000019fah: F3 CD D5 11 FB 0E 00 C3 D4 15 CD 9D 17 C2 FD 17 ; óÍÕ.û..ÃÔ.Í.Âý.
00001a0ah: 21 8D 1F 11 3C 41 01 09 00 ED B0 ; !..<A...í°
1F7BH 00001f7bh: 5A 31 33 34 ; Z134
1F7FH EPROM_VERSION_NUMBER 00001f7fh: 31 2E 33 34 ; 1.34
1F83H 00001f83h: 88 13 88 13 82 14 82 14 64 00 ; ˆ.ˆ.‚.‚.d.
1F8DH 00001f8dh: 00 00 88 13 82 14 82 14 00 00 00 00 00 00 00 00 ; ..ˆ.‚.‚.........
00001f9dh: 0E 48 0D ; .H.
1FA0H EPROM_CAL_DATA 00001fa0h: AC 09 E4 55 0B 52 C4 09 54 52 54 52 BC 09 19 52 ; ¬.äU.RÄ.TRTR¼..R
00001fb0h: 53 4E BB 09 28 52 55 4E AC 09 E6 BF E2 C1 BD 09 ; SN».(RUN¬.æ¿âÁ½.
00001fc0h: E0 C1 E4 C3 00 00 93 43 93 43 A6 09 96 55 F6 51 ; àÁäÃ..“C“C¦.–UöQ
00001fd0h: C4 09 54 52 54 52 D1 09 31 51 30 4D D0 09 52 51 ; Ä.TRTRÑ.1Q0MÐ.RQ
00001fe0h: 22 4D A6 09 12 C0 E2 C1 D2 09 78 C2 84 C4 00 00 ; "M¦..ÀâÁÒ.x„Ä..
00001ff0h: 93 43 93 43 00 00 76 CA 00 00 76 CA ; “C“C..vÊ..vÊ
1FFCH EPROM_SERIAL_NUMBER 00001ffch: 31 31 33 37 ; 1137
GPIB
DAC CLS/*CLS ESE/*ESE ESR/*ESR
IDN/*IDN PSC/*PSC RCLZ/*RCL RSTN/*RST
SAV/*SAV SRE/*SRE STB/*STB VOF/HVOF
VON/HVON LIM/ILIM OUT/IOUT TRP/ITRP
MOD/SMOD CLR/TCLR MOD/TMOD LIM/VLIM
OUT/VOUT SET/VSET ORD
I/O ADDRESSES:
U504 (A3-A5 -> A-C, A6-G1, WR->!G2A, IORQ->!G2B )
40H: SPARE
48H:-SETS -> U407/U408
------------------------------
BIT0: U407A / GND->U405.3
BIT1: U407B / U410.RF -> U405.3
BIT2: U408A / ANALOG_VOLTAGE
BIT3: U408B / I_OUT_MONITOR
BIT4: U408C / CV_SET
BIT5: U408D / DV_LIM
BIT6: U407C / I_LIM
BIT7: U407D / I_TRIP
------------------------------
50H:-DAC U410 12BIT DAC AD7542
50H DAC_LOW_NIBBLE
51H DAC_MID_NIBBLE
52H DAC_HIGH_NIBBLE
53H DAC_LOAD
58H:-LED U611 74HC374
------------------------------
BIT0: L0
BIT1: L1
BIT2: L2
BIT3: -AD1/V_MON
BIT4: -AD2/I_MON
BIT5: -AD3/ANALOG_VOLTAGE_IN
BIT6: -IO
BIT7: UNUSED
------------------------------
60H:-SEGB U606 74HC374
------------------------------
BIT0: EDP
BIT1: EG
BIT2: EF
BIT3: EE
BIT4: ED
BIT5: EC
BIT6: EB
BIT7: EA
------------------------------
68H:-SEGA U609 74HC374
------------------------------
BIT0: ODP
BIT1: OG
BIT2: OF
BIT3: OE
BIT4: OD
BIT5: OC
BIT6: OB
BIT7: OA
------------------------------
70H:-STROBE (STROB0-STROB5 LED) (STROB2-4 KEYBOARD SCAN OUT)
------------------------------
BIT0: STROB0 (LED)
BIT1: STROB1 (LED)
BIT2: STROB2 (LED,KBD)
BIT3: STROB3 (LED,KBD)
BIT4: STROB4 (LED,KBD)
BIT5: STROB5 (LED)
BIT6: STROB6 ()
BIT7: STROB7 ()
------------------------------
78H: MISC -> (U507,74HC374 OCTAL D-TYPE FLIP-FLOP) >CLK
------------------------------
BIT0: -SHUTDOWN
BIT1: UPOK
BIT2: -FLAG_RESET
BIT3: -TIMER_RESET
BIT4: (SPARE)
BIT5: -POS
BIT6: -NEG
BIT7: FILTER
------------------------------
U505 (A3-A5 -> A-C, !M1->G1, A6->!G2A, IORQ->!G2B )
00H: SPARE
08H: SPARE
10H: SPARE
18H: SPARE
20H: STATUS1 U506->74HC244
------------------------------
BIT0: COMPARE
BIT1: I_FAULT
BIT2: CUR_LIM
BIT3: PRI_FAULT
BIT4: V_FAULT
BIT5: TIMER
BIT6: -J504/SET_MONITOR_SW
BIT7: GND
------------------------------
28H: STATUS2 U512->74HC244
------------------------------
BIT0: HV_ON
BIT1: HV_OFF
BIT2: J501/-HV_SW_POS
BIT3: J502/-HV_SW_NEG
BIT4: GND
BIT5: GND
BIT6: GND
BIT7: GND
------------------------------
30H: -KBD
------------------------------
BIT0: KBD0
BIT1: KBD1
BIT2: KBD2
BIT3: KBD3
BIT4: KBD4
BIT5: KBD5
BIT6: KBD6
BIT7: KBD7
key press display
01 Man
02 GPIB
03 left-arrow
04 Right arrow
05 up-arrow
06 down-arrow
07 Enter
08 Select
09 STO
10 RCL
11 CLR
12 .
13 0
14 7
15 4
16 1
17 8
18 5
19 2
20 9
21 6
22 3
------------------------------
38H: -GPIB
------------------------------
READ
38H GPIB_INT_STATUS_0
BIT0: MAC (ADDRESS CHANGE)
BIT1: RCL (REMOTE/LOCAL CHANGE)
BIT2: SPAS (RSV1/2 SERVICE REQUEST)
BIT3: END (LAST BYTE RECEIVED)
BIT4: BO (BYTE OUT)
BIT5: BI (BYTE IN)
BIT6: INT1 (1 WHEN BITS 2-7 OF STATUS 0 SET)
BIT7: INT0 (1 WHEN STATUS 1 BIT SET)
39H GPIB_INT_STATUS_1
BIT0: IFC (INTERFACE CLEAR)
BIT1: SRQ (SERVICE REQUEST)
BIT2: MA (MY ADDRESS)
BIT3: DCAS (DEVICE CLEAR ACTIVE STATE)
BIT4: APT (ADDRESS PASS THROUGH)
BIT5: UNC (UNRECOGNIZED COMMAND)
BIT6: ERR (ERROR)
BIT7: GET (GROUP EXECUTE TRIGGER)
3AH GPIB_ADDRESS_STATUS
BIT0: ULPA
BIT1: TADS
BIT2: LADS
BIT3: TPAS
BIT4: LPAS
BIT5: ATN
BIT6: LLO
BIT7: REM
3BH GPIB_BUS_STATUS
3EH GPIB_CMD_PASS_THRU
3FH GPIB_DATA_IN
WRITE
38H GPIB_INT_MASK_0
39H GPIB_INT_MASK_1
3BH GPIB_AUXILIARY_CMD
3CH GPIB_ADDRESS
3DH GPIB_SERIAL_POLL
3EH GPIB_PARALLEL_POLL
3FH GPIB_DATA_OUT
------------------------------
-
Other thing I noticed. Sandra (and the schematic) has U507 Q4 as NC, but this code (that appears to shutdown the supply in case of I_FAULT, PRI_FAULT or V_FAULT), sets it:
Code: [Select]
ROM:0D42 shutdown: ; CODE XREF: sub_D94+15p
ROM:0D42 ; sub_D94+57p ...
ROM:0D42 ld hl, port_78h_value
ROM:0D45 set 4, (hl) ; spare???
ROM:0D47 res 0, (hl) ; set -shutdown low
ROM:0D49 ld a, (port_78h_value)
ROM:0D4C out (78h), a ; set misc switches (u507)
Old code? different model? Error in schematic?
Going to research this one and see if anything is going on Q4. Will update.
Looked on the scope and Q4 goes Low when the HV switch is flipped to on. it goes high when the HV switch is off.
I set the VLIM to 100V and tried going past it. got the ERR on the display but no activity on Q4
Some tracing done. Q4 goes over to U613D which is a MPQ2222 on Pin 13 which is the Base thru a 10K resistor.
schematic shows the emitter and base tied together however they are not, Pin 12 is tied to gnd. Pin 14 I need to trace now
Going to double check this as pin 14 appears to go to U404 Pin 8 which is +15v
yep. it goes to U404->8
but also thru D103 then I so far am loosing it under N601 (resistor network)
Added work in progress schematic below.
-
So clearly the schematic is wrong. I am not sure if this is anything important, it just struck me as odd that the firmware was toggling outputs that were supposedly NC. The diode looks like an OR construction to me, e.g. pulling base current away from somewhere in case of a fault. A shutdown signal of sorts. That would also explain why I saw the line being turned on in relation to fault signals together with /shutdown.
Do you have any idea what the point of U407A (controlled from U411 Q0) is? It looks like to me like it would short the inputs of U405 through R414. I guess the dot that connects U407A.2 to U402B.7 and R414 should not be there?
-
Updated table based on Dexter2's table:
WORD? # VALUE ROMHEX
0 2476 AC09 ; +pol vset offset
1 21988 E455 ; +pol vset exponent/multiplier/non-linear parameter if vset < word0
2 21003 0B52 ; +pol vset exponent/multiplier/non-linear parameter if vset >= word0
3 2500 C409 ; +pol vlim offset
4 21076 5452 ; +pol vlim exponent/multiplier/non-linear parameter if vlim < word3
5 21076 5452 ; +pol vlim exponent/multiplier/non-linear parameter if vlim >= word3
6 2492 BC09 ; +pol ilim offset
7 21017 1952 ; +pol ilim exponent/multiplier/non-linear parameter if ilim < word6
8 20051 534E ; +pol ilim exponent/multiplier/non-linear parameter if ilim >= word6
9 2491 BB09 ; +pol itrp offset
10 21032 2852 ; +pol itrp exponent/multiplier/non-linear parameter if itrp < word9
11 20053 554E ; +pol itrp exponent/multiplier/non-linear parameter if itrp >= word9
12 2476 AC09 ; +pol voltage readback display offset0
13 49126 E6BF ; +pol voltage readback display scale if VOUT < Word12
14 49634 E2C1 ; +pol voltage readback display scale if VOUT >= Word12
15 2493 BD09 ; +pol current readback display offset
16 49632 E0C1 ; +pol current readback display scale if IOUT < Word15
17 50148 E4C3 ; +pol current readback display scale if IOUT >= Word15
18 0 0000 ; +pol external analog_voltage_in display offset
19 17299 9343 ; +pol external_analog_voltage_in scale (possibly never used)
20 17299 9343 ; +pol external_analog_voltage_in scale
21 2470 A609 ; -pol vset offset
22 21910 9655 ; -pol vset exponent/multiplier/non-linear parameter if vset < word21
23 20982 F651 ; -pol vset exponent/multiplier/non-linear parameter if vset >= word21
24 2500 C409 ; -pol vlim offset
25 21076 5452 ; -pol vlim exponent/multiplier/non-linear parameter if vlim < word24
26 21076 5452 ; -pol vlim exponent/multiplier/non-linear parameter if vlim >= word24
27 2513 D109 ; -pol ilim offset
28 20785 3151 ; -pol ilim exponent/multiplier/non-linear parameter if ilim < word27
29 19760 304D ; -pol ilim exponent/multiplier/non-linear parameter if ilim >= word27
30 2512 D009 ; -pol itrp offset
31 20818 5251 ; -pol itrp exponent/multiplier/non-linear parameter if itrp < word30
32 19746 224D ; -pol itrp exponent/multiplier/non-linear parameter if itrp >= word30
33 2470 A609 ; -pol voltage readback display offset
34 49170 12C0 ; -pol voltage readback display scale if |VOUT| < Word33
35 49634 E2C1 ; -pol voltage readback display scale if |VOUT| >= Word33
36 2514 D209 ; -pol current readback display offset
37 49784 78C2 ; -pol current readback display scale if |IOUT| < Word36
38 50308 84C4 ; -pol current readback display scale if |IOUT| >= Word36
39 0 0000 ; -pol external analog_voltage_in offset
40 17299 9343 ; -pol external_analog_voltage_in scale (possibly never used)
41 17299 9343 ; -pol external_analog_voltage_in scale
42 0 0000 ; related to var_strange_scaled
43 51830 76CA ; related to var_strange_scaled
44 0 0000 ; related to var_strange_scaled
45 51830 76CA ; related to var_strange_scaled
I am fairly sure the unassigned three words for readout are about scaling the external analog input voltage on J401 to the true set voltage (i.e. 10 V = 2.5 kV). Not sure about the exact math. Since the offset is 0, I imagine the second word (if Vin < 0) is never used, but I could be wrong. I would like confirmation that changing W18/19/20 and W39/40/41 affects the analog remote voltage programming (possibly not all are effective across the entire range).
Now the last four words that are still unassigned. I have found the code that references them. In the function that I call do readouts at 0x9a3 (does the successive approximation and applies calibration factors to the results) there are two blocks like this:
ROM:09D0 call read_adcs ; in: hl = output word
ROM:09D0 ; out: (hl) = adc result
ROM:09D3 ld a, 1
ROM:09D5 call convert_readouts ; a = { 0: vmon, 1: imon, 2: analog v_in }
ROM:09D5 ;
ROM:09D8 ld c, 2
ROM:09DA call convert_readouts_strange ; c = { 0, 2 }
Analog switches were set in an earlier subroutine (to allow for settling time). read_adcs does the successive approximation through the DAC and returns the result. convert_readouts using the display calibration factors identified by Dexter2 and stores them in memory where the display routines can find them (around 0x40df).
Now for the aptly named (by me :P) convert_readouts_strange (0xb43-0xbab). It takes It does something fairly similar to convert_readouts, but it uses the last four calibration words (I have not looked into the exact math) and does further math with the result of convert_readouts (i.e. the value displayed on the display/ sent for GPIB queries). Then it stores the result in the four byte block at 0x409c (var_strange_scaled):
ROM:0B9E pop bc
ROM:0B9F ld b, 0
ROM:0BA1 ld de, var_strange_scaled+2
ROM:0BA4 ex de, hl
ROM:0BA5 or a
ROM:0BA6 sbc hl, bc ; bc = { 0, 2 }
ROM:0BA8 ld (hl), e
ROM:0BA9 inc hl
ROM:0BAA ld (hl), d
ROM:0BAB ret
Looks like 0x409c is derived from i_monitor and 0x409e from v_monitor. The strange part is that this appears to be the only place that references the value. I did not find use of the neigbouring addresses as intermediate value (e.g. ld hl, 409a) either. I imagine there might be some ldi(r) instruction or other pointer arithmetic that covers it. I appreciate any reference to other code outside 0xb43-0xbab that references it or speculation what the point of this might be.
-
So clearly the schematic is wrong. I am not sure if this is anything important, it just struck me as odd that the firmware was toggling outputs that were supposedly NC. The diode looks like an OR construction to me, e.g. pulling base current away from somewhere in case of a fault. A shutdown signal of sorts. That would also explain why I saw the line being turned on in relation to fault signals together with /shutdown.
I would assume the schematic is from and older/newer (though probably older) version than the firmware was written for and so doesn't show this feature.
I will continue to try to trace it down. been distracted by needed household duties and basement water. yuk
Do you have any idea what the point of U407A (controlled from U411 Q0) is? It looks like to me like it would short the inputs of U405 through R414. I guess the dot that connects U407A.2 to U402B.7 and R414 should not be there?
Lets see how well I understand op-amps (and i'm no pro)
U410 is a unipolar DAC so to get the +/-10.24v rails needed we have
R420-R422 set the mid point at U402B so a value of 1000 0000 0000 is Zero Volts which is a current to voltage circuit since the DAC is current output.
U407A/B & U405 forming a voltage inverter to get the +/-10.24v rail and a gain of 1 with the 1000 0000 0000 being the mid point for zero
Turning on Q0 of U411 connections pin 3 of U405 to virtual gnd of the ADC which should invert the output of U405 for the -10.24v
Turning on Q1 of U411 connected pins 3 of U405 to same input as Pin 2 which should make it a voltage follower for the 10.24v?
R413-R414 set it up as a 1x gain amp so R414 is needed
I believe U402D is acting as a non-inverting buffer with a gain of ~1x which feeds the U408 and following SHA circuits which are refreshed every ~28mS
the datasheet for the AD7542 shows a feedback path from the frist opamp to the RFB of U410.16 with a cap between U410.16 and U410.1 as in the schematic.
so from that POV the only different in the AD7542 sample and the SRS implementation is a Resistor missing in the feed back loop
added AD7542 Datasheet, see pg 5 under BiPolar Operation for the example circuit. it is very simulair that what SRS did though not exact.
-
Hi, just repaired my PS350 unit by replacing the completely dead caps C702 and C705 . In photo's and video's here and on YT I see different brand caps used in the low voltage supply. In my unit it they were -unknow to me- Xicon brand caps and replaced these with Rubycons, you might check yours.
Then in the high voltage supply, the -5V in different revisions have swapped the D206 10V zener by a 79L05. That might have been done because of problems or perhaps accuracy? Anyhow, my unit works fine now and is completely in spec :)
Question: the front bezel came with no screws and seems to be imperial thread. Anyone know what type I should look for?
Thanks, also to Sandra for the help!