juhasch / pyBusPirateLite

Python library for BusPirate
https://pybuspiratelite.readthedocs.io/en/latest/
Other
58 stars 33 forks source link

Unable to get consistent results using write_then_read() #25

Open pacmac opened 4 years ago

pacmac commented 4 years ago

I am unable to get consistent reads using the write_then_read method:

def get_byte_a(addr):
  i2c.write_then_read(2,0, [0x16, addr])  ## Write 2, receive none.
  r = i2c.write_then_read(1, 1, [0x17])   ## Write 1, receive 1
  print(f'VALUE = {hex(r[0])}') 

  for i in range(10):
    get_byte_a(0x10)
    time.sleep(0.1)

VALUE = 0xb8
VALUE = 0xb8
VALUE = 0xb8
VALUE = 0xb8
VALUE = 0xb8
VALUE = 0x17
VALUE = 0xb8
VALUE = 0xb8
VALUE = 0x0
VALUE = 0xb8

Or the using transfer and write_then_read method:

def get_byte_b(addr):
  i2c.start()
  i2c.transfer([0x16, addr])    ## Send Multiple
  r = i2c.write_then_read(1, 1, [0x17])
  print(f'VALUE = {hex(r[0])}') ## 0xB8 Is Correct Value = 184

  for i in range(10):
    get_byte_b(0x10)
    time.sleep(0.1)

VALUE = 0xb8
VALUE = 0x5c
VALUE = 0xb8
VALUE = 0xb8
VALUE = 0xb8
VALUE = 0xb8
VALUE = 0xb8
VALUE = 0xdc
VALUE = 0x5c
VALUE = 0xb8

The only way I can get a consistent result is by using I2C.read_byte():

def get_byte(addr):
  i2c.start()
  stat = i2c.transfer([0x16, addr])
  i2c.start()
  stat += i2c.transfer([0x16 | 1])
  r = i2c.read_byte()
  i2c.nack()
  i2c.stop()
  if stat.find(chr(0x01)) != -1:
    raise IOError("I2C command on address 0x%02x not acknowledged!" % (i2caddr))
  return ord(r)

And I had to add the read_byte method into I2C.py as it was missing:

    def read_byte(self):
        self.write(0x04)
        return self.response(1, True)