Trying to puzzle out EEPROM storage in USB spectrometer - Page 1
Forum section: electronics / projects

author: amaschas
author_rank: Regular Contributor
timestamp: February 17, 2024, 10:22:59 pm
content: I've recently acquired a Stellarnet Bluewave visible light USB spectrometer off ebay, and I've run into some puzzling problems trying to use it. I have a feeling that most of my issues stem from this being an older model of the device, but I'm curious if anyone here might have some insight into the issues I'm encountering. The gist of my problem is that I've been able to get the spectrometer working fine with their legacy application called StellarWiz, which is a windows application. It manages to store settings like the calibration coefficients of the instrument, the integration time, etc, retain them between restarts and display a properly calibrated spectrum.Stellarnet also provides a Python API for their spectrometers. I've downloaded and attempted to run the test script they provide, but when I do so I get an error about the coefficient values missing from the device configuration. I've dug down a bit and what I've discovered is that the Python API uses the usb core package to read data from EEPROM via the USB controller for this particular device (CY7C68013A). Exploring further, I've tried to query the addresses that are hard-coded into the spectrometer library file, but the byte output of each address appears to be filled with 1s. Here's some example output from using the crtl_transfer interface from Python's API to read one of the memory addresses:array('B', [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255])I also attempted to write values to those addresses, and while the code would execute without errors, the values didn't appear to stick.Some additional complications: I explored the datasheet for the USB controller, and while it specifies an interface for EEPROM storage, it does not appear to have any EEPROM on board. On top of that the I2C lines that would be used to communicate with EEPROM don't appear to even be connected.At this point I started to think that maybe this model of the spectrometer doesn't have an internal configuration storage, and maybe the persistent configuration is actually stored on the computer running the SpectraWiz software. However, my sense is that if the Python API couldn't actually read from EEPROM, the response would be an error rather than a byte array of all ones. I tested this thesis by attempting to read some addresses that were out of the range specified in the library, and I did in fact get errors when the addresses could not be read. So unless I'm misunderstanding the functionality of the Python usb package, it appears that I'm able to read from _something_ on this device. I'm also not sure how the SpectraWiz software could be setting them unless the instrument had either some form of internal storage or a means to set those values with commands.I'd really like to be able to use this thing programmatically with Python, since this allows me to do some analysis and comparison with another spectrometer I own. It's also a bit of a puzzle that I've gotten interested in. I'm hoping someone here can suggest some addition avenues of explortion.StellarNet Python Info:https://www.stellarnet.us/software/spectrometer-python-application-driver/This is an open frontend for the Spectrometers where you can get the driver. Note that the message in the README says the driver has been deleted, but anyone who knows git is aware that deleting a file from a repo does not actually delete the file from the git history, so if you close this and check out the state a few commits back from HEAD the stellarnet.py file will magically reappear!:https://github.com/acpo/PiSpec20_stellarnetSome photos of the board. I don't see an EEPROM on here, but maybe I'm missing something?

author: jwet
author_rank: Frequent Contributor
timestamp: February 18, 2024, 03:53:44 am
content: Your pictures are just not quite good enough to read part numbers accurately. Its possible that in the first picture that CY chip is a USB interface that includes some EEPROM- I just can't make it out. Take another crack. EEPROM is included in a lot of part these days. I don't see any I2C or SPI 8 pin SO standard EE devices I don't think. Good luck- I've been involved in a lot of these hunts. If its an open source type project, are the original developers still available or will then at least respond to inquiries? Good luck- if you post better pics, I'll look at them.

author: amaschas
author_rank: Regular Contributor
timestamp: February 18, 2024, 06:28:17 pm
content: Quote from: jwet on February 18, 2024, 03:53:44 amHrm, you should be able to click them and get large versions. Is that not working? The specific USB controller IC appears to be CY7C68013A. Ive read through the docs for this part (https://www.infineon.com/dgdl/Infineon-CY7C68013A_CY7C68014A_CY7C68015A_CY7C68016A_EZ-USB_FX2LP_USB_Microcontroller_High-Speed_USB_Peripheral_Controller-DataSheet-v31_00-EN.pdf?fileId=8ac78c8c7d0d8da4017d0ec9f7974252), but as far as I can tell it doesn't have any onboard EEPROM which is the puzzling thing, though maybe I'm just misunderstanding the docs.

author: jwet
author_rank: Frequent Contributor
timestamp: February 20, 2024, 12:52:19 pm
content: The way EZ USB works is this. It actually RAM based. When it gets plugged into PC, it innumerates temporarily, the PC driver installer downloads the complete code for the external box- and then restarts and the final app runs. I know the designers and have some history with the part going back to Anchor. Its very likely that the storage is in the PC is the short answer.

author: amaschas
author_rank: Regular Contributor
timestamp: February 20, 2024, 10:14:03 pm
content: Quote from: jwet on February 20, 2024, 12:52:19 pmThis would make a lot of sense for what I'm observing. The confusing part is that there is a python API offered by the company that refers to EEPROM addresses. I'm wondering if this is some sort of product differentiation thing.I believe I've discovered where the EEPROM should be: it's the missing IC U76. I tested for continuity with the I2C pins on the CY7C68013A and it looks like there are two pins on U76 that connect to I2C and are in the correct spot to match the pinout of the EEPROM ICs that infineon recommends. I'm thinking of ordering an EEPROM and soldering it on to see what happens.

author: jwet
author_rank: Frequent Contributor
timestamp: February 21, 2024, 04:50:08 pm
content: I don't think this will do any good but I'd try too. The USB chip can use either the EEPROM or the PC method, yours is likely using the PC option. Can you get access to the EEPROM contents anywhere- this will be the next problem, a blank eeprom won't do much for you.

author: amaschas
author_rank: Regular Contributor
timestamp: February 27, 2024, 12:13:07 am
content: [ Specified attachment is not available ]Quote from: jwet on February 21, 2024, 04:50:08 pmHrm, maybe I'm misunderstanding what's going on here then? My sense is that the EEPROM is just being used to store various configuration values, and that when the USB controller attempts to read/write to the hard-coded addresses it can't because the EEPROM isn't present. For instance the driver just has a bunch of constants like this:Code:COEFF_C1_ADDR = 0x80"""The address of the string containing coefficient C1"""COEFF_C2_ADDR = 0xA0"""The address of the string containing coefficient C2"""COEFF_C3_ADDR = 0xC0"""The address of the string containing coefficient C3"""COEFF_C4_ADDR = 0xE0"""The address of the string containing coefficient C4"""And then attempts to read values from these addresses via something like this:Code:ctrl_transfer(StellarNet._IN_DEVICE, StellarNet.COEFF_C1_ADDR , 0, 0, 2)So there's no firmware stored in the EEPROM, just data (I think?).I've actually soldered a blank EEPROM in, but it doesn't seem that the board can read/write to it. I've attached a zipfile of pulseview recording of an attempt to read/write from the EEPROM. Looks like a lot of failures of the master/slave to respond? Anyone have some suggested reading that would help me puzzle out exactly what's happening here? Lots of this:

author: jwet
author_rank: Frequent Contributor
timestamp: February 27, 2024, 06:36:28 pm
content: I'm sorry you're right, the EEPROM only provides constants like VID and PID. I'm confusing it with another devices that gets its code from an EEPROM (Parallax Propeller). The initial enumeration initiates a code download and then a re enumeration runs the final code once downloaded.The unpopulated EEPROM must be a stuff option. The very first Anchor devices (AN2121) didn't have any EEPROM in the device- all ram. They could only provide a Revision ID that the PC Software could use for validation. The PC software could then provide the final VID and PID (from the end customer) that would be used on the second enumeration for normal operation.There is a great manual that Anchor published that is worth the download. Very clearly written and most is still valid though its a decade or more old. 115-00027-0-AN2121S.PDF. It may give you some guidance as to how the magic numbers are pulled out of EEPROM if found. Everything can be overwritten by the driver software of course. If you can capture the code as its downloaded, it could be dissassembled with JIRA- the CPU in the interface are an enhanced 8051 with a few feature and instruction enhancements- dual data pointer, dual UARTS. Disassembly would likely generate some errors that you could manually clean up.Sorry for the confusion.

author: amaschas
author_rank: Regular Contributor
timestamp: February 28, 2024, 06:37:56 pm
content: So a few updates for anyone who comes across this looking for info about this device in the future:• Sticking in an EEPROM actually worked, I had just configured pulseview incorrectly (sampling a 100khz signal at 25khz).• I can now write to EEPROM addresses and will start testing the features this enables. The empty U76 footprint is in fact intended for the EEPROM. Not sure if this was left off my board accidentally, or as some sort of feature differentiation strategy by the manufacturer.• While it appears that it is possible to program this device by copying the firmware into the EEPROM and loading the firmware into RAM in boot (the controller only has RAM onboard as I first assumed), this implementation actually works by literally reading a huge string from the end of the python "driver" file, which is a combination of memory addresses and instructions in hex, and copying it into RAM as part of the initialization process.

author: moffy
author_rank: Super Contributor
timestamp: February 28, 2024, 08:44:29 pm
content: That is a remarkable piece of detective work with a good outcome.