| Electronics > Repair |
| Quick Repair: Standford Research PS350 5KV 5mA(Fixed but working on calibration) |
| << < (5/11) > >> |
| 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 |
| Message Index |
| Next page |
| Previous page |