Add support for Siglent eCal emulation.#31
Conversation
This patch allows a Siglent SVA1032X to calibrate using a LibreCAL. It adds support in the firmware to boot into a Siglent-compatible mode (removes USB MSC, to avoid the instrument's UI trying to write to the disk; adds a very limited USB TMC that knows how to speak the Siglent calibration commands) when Siglent calibration coefficients are present, and the unit has the FUNCTION key held while powering on. We also add a `convert_siglent.py` script, which converts the calibration data stored in the LibreCAL's native Touchstone format to the reverse-engineered header and ZIP+CSV format that a Siglent VNA requires. Some fields in the Siglent header are not fully understood, but they don't seem to make a difference at least on SVA1032X. The calibration appears to provide good results tested against other calibration standards I have lying around, and so the S-parameter conversion for ports 1 and 2 at least are probably correct. Unimplemented is an "ATT" mode, used for the VNA's Confidence Check function; I suspect this may be an attenuator, but without a real Siglent eCal, I can't know for sure, and more to the point, the LibreCAL doesn't have one other than the Through port, so we do not implement it. Signed-off-by: Joshua Wise <joshua@joshuawise.com>
|
Wow, thank you very much! Implementing something like this has crossed my mind, but so far I have not found reliable enough information about the protocol and calibration data of other eCals (and do not own any myself). Maybe I just didn't check thoroughly enough. I am actually very surprised how little changes you had to make to the code (although I am sure that it took a lot of work to get there). I do have an SNA5014A (4 port Siglent VNA), so I can definitely check whether this works on all 4 ports. Looking forward to testing this and I will definitely merge this once I have confirmed that it works. |
|
Yeah, the documentation is definitely not out there ... definitely the easy part was implementing it and the hard part was doing the static analysis. This was the better part of my evenings this week and most of last weekend probably totaling to like 40 or 50 hours of Ghidra time :) If someone actually has one of the real eCals I'd be really interested to see what the actual data format from those things is and see how closely it matches my results. Future work (that is worth enumerating but which I don't really have any intention of doing):
|
Yep, I did a write-up of some of the initial reverse-engineering & emulation here: https://greatscottgadgets.com/2024/11-13-reverse-engineering-a-vna-ecal-interface-with-cynthion/ and the code & EEPROM dumps are here: https://github.com/miek/ecal-reversing For now though, I've been using this script to run the process remotely: https://github.com/miek/vnautils/blob/main/src/vnautils/pna_librecal.py
I suspect it selects a second through path with some attenuation (then after the cal it can then be measured and compared with the stored data as a rough verification). It probably could be the same as |
|
A little bit of progress: My SNA5014A sends *idn? instead of *IDN? (lower case). Your patch does not reply to that, so it claims that the eCal is not valid. By always converting the received command on the USB TMC to upper case I managed to fix that and now it does get detected! Calibration however does not work yet. The VNA loads the data from the eCal and opens the calibration menu but it can not figure out the connection to the eCal. If I set the orientation to "auto" I get an "Unable to orient ECal module" error. If I set it to "manual", I am prompted to select which VNA port is connected to which LibreCAL port but that window looks as if some GUI elements are missing: Here you can see how that dialog is supposed to look like: https://www.youtube.com/watch?v=6vHX0moZUFg&t=1300s Maybe the VNA expects some additional information from the LibreCAL to populate that dialog? I'll keep investigating that further and would love to hear your thoughts on that. |
|
Interesting. Not a surprise that auto orientation doesn't work if it uses the same mechanism as 'confidence check'. Does it send As it turns out SVA1032X doesn't send Sometimes in Siglent land, they hardcode things for model numbers. So you might want to try having your If that doesn't do it, I guess the next steps would either be to pop the main binary from the SNA5000 into a disassembler, or wait until we can get access to a real eCal to dump the header from that. |
No, it does not, there are actually no SL commands at all. There are however obvious other commands to set the port status. Here is the sequence of commands I get when trying to perform a 2-port SOLT calibration (with auto orientation enabled because I still can not select anything on manual mode): I have implemented support for these commands (with ATT setting the standard on that port to The VNA does complete orientation detection and calibrate but the calibration data is all over the place. I have also no idea why it cycles through OPEN, SHORT, LOAD in the order of port A, B, A, D and then finally sets a THRU between A and D. I have ports 1 and 2 of the LibreCAL connected, so I expected it to use A and B only but I guess the auto orientation decided to use A and D (unfortunately it does not show you how it thinks the ports are connected).
That is what I usually do on most projects. But the LibreCAL already uses all pins of the RP2040 and I dropped any UART functionality. I'll definitely need to figure out a better way, but at the moment I have a JLink connected, set breakpoints and inspect variables. A UART output would be really helpful right now.
That was my thought as well. I'll try to come up with some model numbers once I have improved on the debugging situation.
With a bit of luck I still have the binary from my SNA. Can't find it immediately but I definitely dumped that at some point. I won't be much help on the reverse engineering though (by far not enough experience with Ghidra). |
|
I assume at some point in the past you had a relatively lengthy 'loading data...' period, and it skipped it this time because it still has the correct md5 of zip file cached. Definitely try *IDN? replying with model numbers (as well as the header data generated by the python script), and also try experimenting with bytes 0x4E and 0x4F. I think I might have someone who will be able to get a real eCal's data in the next week or so, as well. |
|
I got UART debug output using one of the LEDs now. Still no luck with manual port selection. I tried a replying to *IDN? as I would expect an SEM5014A to do ("Siglent Technologies,SEM5014A,<serial>,<firmware>") but that is apparently not enough.
I am not sure. As far as I remember, the time for loading data was always rather short. Sometimes it is instant, sometimes I see a loading bar for a short time (maybe 1-2 seconds?). It also doesn't seem to load the actual calibration data. With the debug output I have now, I always only see these two commands: Never anything like I tried changing the md5 and the serial number in info.dat and rebooting the VNA but it still does not ask for the zip file. |
|
Changing the md5 (make sure to change both Is there an "ECal Info" box that correctly identifies the serial number, at least? On my SVA1032X, it looks like this: I believe that "Port {A,B,C,D} Connector" are supposed to be populated. How they get their data, though, I don't know... |
|
One thing that you might consider is mapping ATT to THROUGH, modifying |
- handle *IDN? response and SET:PORT commands send by some VNAs - default to emulation mode if files are present (press function to force default mode) - Adjusted script to set number of ports and handle early LibreCALs with partially missing factory data - Add optional logging to LibreCAL firmware - indicate emulation mode by blinking wait/ready LEDs
|
Merged into the new siglent branch. See fa75511 for the changes/improvements I made. This seems to work quite well with my SNA5014A now (as long as I manually assign ports) but I will hold off on merging this into main until I have done more tests (full 4 port calibration and testing whether everything still works with the LibreVNA). Could you please check whether I broke anything for your SVA1032X? If you don't want to compile it yourself you can also use the artifact here. |
Signed-off-by: Joshua Wise <joshua@joshuawise.com>
Signed-off-by: Joshua Wise <joshua@joshuawise.com>
Signed-off-by: Joshua Wise <joshua@joshuawise.com>
…o kick the device into bootloader mode without pressing buttons Signed-off-by: Joshua Wise <joshua@joshuawise.com>
|
I added support for ATT (as a clone of THRU, since we don't have an attenuator to mux in) and it seems to make the confidence check thing work. I wonder if that'll make your auto-assign work? |
|
Thanks for the review and for cleaning up after me ;) I'll run some more tests later today and report back |
|
Merged into the siglent branch again (together with unrelated bug fixes). After some more testing I think this works absolutely flawlessly:
Well, there is one flaw but that is more on Siglent: My LibreCAL is missing P34_THRU coefficients above 7.9 GHz (this was an early bug in the factory calibration procedure). This means that all other Siglent coefficients above 7.9 GHz are also missing. But the SNA5014A happily calibrates all the way up to 8.5 GHz without any complaints. Calibrated data above 7.9 GHz is obviously bad since it has no coefficients for that. The ECal information screen correctly shows the upper frequency limit of 7.9 GHz. Unless there are any concerns from your side I will merge this into main and create the 0.3.0 release from it (I think this warrants an increase in the minor version instead of just incrementing to 0.2.4). |
|
Seems reasonable to me. Consider also whether the GUI should have a button to write a parameter file out while doing the firmware upgrade, and/or whether there should be manual changes?On May 31, 2025, at 11:41, Jan Käberich ***@***.***> wrote:jankae left a comment (jankae/LibreCAL#31)
Merged into the siglent branch again (together with unrelated bug fixes).
After some more testing I think this works absolutely flawlessly:
Auto orientation detection works
Full 4-port calibration on the Siglent works
Calibration with the LibreVNA still works (when in default USB mode)
Well, there is one flaw but that is more on Siglent: My LibreCAL is missing P34_THRU coefficients above 7.9 GHz (this was an early bug in the factory calibration procedure). This means that all other Siglent coefficients above 7.9 GHz are also missing. But the SNA5014A happily calibrates all the way up to 8.5 GHz without any complaints. Calibrated data above 7.9 GHz is obviously bad since it has no coefficients for that. The ECal information screen correctly shows the upper frequency limit of 7.9 GHz.
Unless there are any concerns from your side I will merge this into main and create the 0.3.0 release from it (I think this warrants an increase in the minor version instead of just incrementing to 0.2.4).
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: ***@***.***>
|







This patch allows a Siglent SVA1032X to calibrate using a LibreCAL. It adds support in the firmware to boot into a Siglent-compatible mode (removes USB MSC, to avoid the instrument's UI trying to write to the disk; adds a very limited USB TMC that knows how to speak the Siglent calibration commands) when Siglent calibration coefficients are present, and the unit has the FUNCTION key held while powering on.
We also add a
convert_siglent.pyscript, which converts the calibration data stored in the LibreCAL's native Touchstone format to the reverse-engineered header and ZIP+CSV format that a Siglent VNA requires. Some fields in the Siglent header are not fully understood, but they don't seem to make a difference at least on SVA1032X.The calibration appears to provide good results tested against other calibration standards I have lying around, and so the S-parameter conversion for ports 1 and 2 at least are probably correct. Unimplemented is an "ATT" mode, used for the VNA's Confidence Check function; I suspect this may be an attenuator, but without a real Siglent eCal, I can't know for sure, and more to the point, the LibreCAL doesn't have one other than the Through port, so we do not implement it.
Here's a video of this operating: https://www.youtube.com/watch?v=H64bFWH6v2k