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

Invalid read implementation for write_then_read method #27

Open
horror-vacui opened this issue Jan 17, 2020 · 1 comment
Open

Invalid read implementation for write_then_read method #27

horror-vacui opened this issue Jan 17, 2020 · 1 comment

Comments

@horror-vacui
Copy link

The write_then_read method, which according to my understanding supposed to be the general I2C read/write function implements the I2C wrong. The read supposed to be as follows:

  • write I2C device address with R/Wb bit set to 0
  • write register address
  • repeated start condition
  • write I2C device address with R/Wb bit set to 1
  • supply the clock for the bytes to be read and acknowledge every byte
  • not acknowledge (NACK) after the last byte
  • stop condition

The example in the README does not tell anything about how to issue a repeated start. I've written a code in the spirit of the example in the README:

>>> import pyBusPirateLite
>>> i2c = pyBusPirateLite.I2C()
>>> i2c.speed = '5kHz'
>>> i2c.configure(power=True)
>>> i2c.write_then_read(4,0, [ 0x3e, 0x82, 0xf0, 0xf0 ]  )
b''
>>> i2c.write_then_read(2,2, [ 0x3f, 0x01]  )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/dist-packages/pyBusPirateLite/I2C.py", line 308, in write_then_read
    raise ProtocolError('Error in transmission')
pyBusPirateLite.base.ProtocolError: Error in transmission

Note to the code: The 0x82 command sets among others the 0x01 register, what I want to read out.

The signal waveforms shows that the first part of the transmission is missing (R/Wb=0 & reg address = 0x01)
scope_3

I could get around with this if I could force a repeated start in the read_then_write's txdata. In its form either the implementation of the code is bad, or something is missing from the description.

@julianvilas
Copy link

Hi @horror-vacui,

The Bus Pirate Write then read command works exactly as you said it should work, you can check it on the Bus Pirate firmware. The pyBusPirateLite.I2C.write_then_read just implements the bitbang mode call for the firmware method.

According to the firmware code you should provide the write address if you are not going to read anything or you are going to read and write more data than just the single byte of the device address. Because in the second case as you can see the firmware itself will issue the i2c restart and set the read bit in the device address. The only case where you would need to send the read device address is when you are just reading.

I don't know the details of the peripheral you are communicating with through I2C, but here you can see some examples for reading/writing an AT24C128/256 EEPROM using the write_then_read, with the particularities of that specific device.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants