Electronics > Repair
Quick Repair: Standford Research PS350 5KV 5mA(Fixed but working on calibration)
Dexter2:
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.
alm:
Thanks for confirming my theory!
smgvbest:
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
old EPROM in the unit
new 28C64B in place
finishing touch, a nice shinny new label
powering on all looks good.
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
--- Code: ---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
--- End code ---
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?
smgvbest:
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
alm:
--- Quote from: smgvbest on July 31, 2017, 11:37:09 pm ---no more UV Erasing the EPROM :-+
--- End quote ---
Yay!
I added the meaning of the calibration values based on my current understanding of the code (what I posted earlier):
--- Code: ---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
--- End code ---
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.
--- Quote from: smgvbest on July 31, 2017, 11:37:09 pm ---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
--- End quote ---
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.
--- Quote from: smgvbest on July 31, 2017, 11:37:09 pm ---Would it maybe be good to look at the VSET to figure out when and where they use the calibration values?
--- End quote ---
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:
--- Code: ---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 }
--- End code ---
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:
--- Code: ---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 ...
--- End code ---
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):
--- Code: ---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
--- End code ---
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:
--- Code: ---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
--- End code ---
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.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version