Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: Use HAT EEPROM chip to store hardware configuration #292

Open
LaurentPV opened this issue Nov 27, 2023 · 4 comments
Open

proposal: Use HAT EEPROM chip to store hardware configuration #292

LaurentPV opened this issue Nov 27, 2023 · 4 comments
Labels
proposal A suggestion for a significant change

Comments

@LaurentPV
Copy link

Motivation

Over the years with the modularity and the constant evolution of the Planktoscope hardware configuration we face multiple users with different hardware configurations and bugs that needs to be solved in order to maintain a good community and to keep the Planktoscope modular.

We face the challenge of trying to achieve good results with different machines that can evolve with time.
We would like to retrieve easily the hardware configuration of the machine and that this configuration evolves automatically with the machine.

Proposal

The Planktoscope HAT contains a 32 Kbits EEPROM chip that can store informations.
We propose to use that chip to store the hardware configuration of the machine to fully use the possibilities of the PlanktoScope HAT and be able at anytime to get this configuration to help the debug process.

@LaurentPV LaurentPV added the proposal A suggestion for a significant change label Nov 27, 2023
@ethanjli ethanjli changed the title Use HAT EEPROM chip to store hardware configuration proposal: Use HAT EEPROM chip to store hardware configuration Nov 28, 2023
@ethanjli
Copy link
Member

ethanjli commented Nov 28, 2023

This proposal hasn't been submitted for review yet, so I haven't reviewed the design document in detail yet - but I did notice one particular question you had added to the "Open issues" section of the design document, and my answer might affect your design:

It remains to be confirmed that we can retrieve data from the focus and pump motors and if this data is sufficient to identify the pump model for example ?

No, we have no way of retrieving data from the motors about the identity of the motors. For information about what kinds of motors, LEDs, lenses, and flowcell are in the PlanktoScope, and for parameters related to the specific kinds of motors (e.g. microsteps or max speed), each of those values will need to be specified by the person who built the PlanktoScope or by the person who is operating the PlanktoScope. Thus, we will need to persist that information in a hardware.json file (as proposed by #290), in the EEPROM (as proposed by this issue), or both; and we will need to load that information from a hardware.json file and/or from the EEPROM to make it available to the frontend/backend.

@ethanjli
Copy link
Member

ethanjli commented Nov 28, 2023

The PlanktoScope HAT uses this series of EEPROM chips: https://www.st.com/resource/en/datasheet/m24c32-w.pdf . Here are my notes from reviewing the datasheet, which might be useful for troubleshooting the issues you've encountered with trying to write some data to the EEPROM and read it back to get the same values you had written:

  • Page size of 32 bytes: if you are writing multiple bytes at a time, you need to ensure that all of those bytes stay within the same page of memory in the EEPROM. Modifying bytes in different pages may need to be done with separate write commands. To keep things simple, for now you should only write bytes within the same page - you're probably already doing this in your troubleshooting.
  • Write takes up to 5 ms (or maybe 10 ms max): you should ensure that you are sleeping for at least 5 ms after writing data before reading it back.
    • While you are troubleshooting, you may want to sleep for 10 ms for each byte you write.
    • If you have been seeing nondeterministic behavior in the past (e.g. you repeatedly write [1, 2, 3, 4] but you are receiving different results when reading the data back from the EEPROM), or if you notice that earlier values in your byte sequence get written correctly while later values get written incorrectly, or if you notice that later values in the byte sequences you read back are always the same between consecutive write-read cycles, one very possible cause of such behavior is a race condition between your Python code and the EEPROM chip, e.g. because you are reading data from the EEPROM while it is still in the middle of writing your bytes.
    • It is possible to poll for an I2C ACK (see section 5.1.6) to determine when you can stop sleeping, because you usually don't need to sleep for the full 5 ms. But I'm not sure whether this is possible using the smbus2 Python library, because I'm not familiar with that library.
  • Two write address bytes per write command: you should make sure you are sending the full write address, which should be a two-byte value, before sending one or more data bytes. The memory is organized into 32-byte pages; the page you are writing into is selected using the more-significant-byte and the less-significant-byte of the address, while the individual byte(s) you are writing into is/are selected using bits 0-4 in the less-significant-byte of the address. I'm not familiar enough with the smbus2 Python library to know what writing to a a two-byte address should look like with the smbus2 library's API.
  • In order to read the memory at a particular address, you will need to first update the EEPROM chip's internal address counter. Section 5.2.1 describes how to do this; I don't know if the smbus2 Python library does this for you (I doubt it). This probably needs to happen between when you finish writing some bytes and when you try to read those same bytes.

Additional questions which might help you with troubleshooting:

  • If you try to repeatedly read the same set of addresses from the EEPROM before writing any bytes, do you always get back the same bytes, or does it change sometimes?
  • After writing a byte sequence, what do you see when you try to repeatedly read the same set of addresses again and again for the next 50 ms? If the result changes over time, is there any pattern in the changes?

@ethanjli
Copy link
Member

ethanjli commented Nov 28, 2023

Since the interface for this EEPROM chip appears to be rather complicated, I would suggest seeing if you can study and learn from any existing code for interfacing with this EEPROM chip. As far as Python projects go, I have found https://github.com/zzts/Python-eeprom, which was tested with the same chip we're using.

@ethanjli
Copy link
Member

ethanjli commented Nov 28, 2023

Copying Laurent's direct message to me on Slack:

Hi Ethan, if fact we confirmed with Thibaut that the chip detected on the i2c address 0x64 is the led driver. There is no current on pins 1, 2, 3 of the EEPROM. I tried to set the dtparam=i2c_vc in the boot/config.txt but it doesn't change anything

The I2C device address is separate from the memory address. The datasheet describes the I2C device address as an 8-bit address where the least-significant bit (bit 0) is a read/write bit describing whether the I2C command is for a read operation or a write operation; and the four most significant bits (bits 7, 6, 5, and 4) are 0b1010; and the value of your remaining bits (bits 3, 2, and 1) depends on the voltages of the chip's E3, E2, and E1 pins. In this interpretation of I2C device addresses, the device address should be between 0b10100000 (0xa0) and 0b10101110 (0xaf).

I believe the smbus2 library's API assumes that you provide the seven most-significant bits of the device address as the device's address, but shifted right by one position (so that the read/write bit is shifted out of the device address, e.g. 0b10101110/0b10101111 becomes 0b1010111); then the smbus2 library shifts that address left by one position (to make the device address an 8-bit address, e.g. 0b1010111 becomes 0b10101110) and then sets the least-significant bit depending on whether it is sending a read command (e.g. 0b10101111) or a write command (e.g. 0b10101110).

In the GitHub repo I linked to above, they called various smbus2 read/write functions with an I2C device address of 0x50 (0b101000), which corresponds to the E3, E2, and E1 pins connected to ground (or left floating). The PlanktoScope HAT schematic shows those pins being connected to ground for us too, so (if I have understood the datasheet and the smbus2 library correctly) we should probably also be using 0x50 as the device address for our EEPROM chip. Is that the address you're using?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal A suggestion for a significant change
Projects
Status: Draft
Development

No branches or pull requests

2 participants