def i2c_bitbang(self, scl = 1, sda = 1, oe = 1): self.regs.i2c_w.write((scl << 0) | (oe << 1) | (sda << 2)) def i2c_start(self): self.i2c_bitbang(1, 1) self.i2c_bitbang(1, 0) self.i2c_bitbang(0, 0) def i2c_stop(self): self.i2c_bitbang(0, 0) self.i2c_bitbang(1, 0) self.i2c_bitbang(1, 1) self.i2c_bitbang(oe = 0) def i2c_transmit_bit(self, b): self.i2c_bitbang(0, b) self.i2c_bitbang(1, b) self.i2c_bitbang(0, b) self.i2c_bitbang(0, 0, 0) def i2c_receive_bit(self): self.i2c_bitbang(0, 0, 0) self.i2c_bitbang(1, 0, 0) b = self.regs.i2c_r.read() & 1 self.i2c_bitbang(0, 0, 0) return b def i2c_transmit_byte(self, b): for i in range(7, -1, -1): self.i2c_transmit_bit(1 if b & (1 << i) else 0) return self.i2c_receive_bit() == 0 def i2c_receive_byte(self, ack): b = 0 for i in range(7, -1, -1): b |= 1 << i if self.i2c_receive_bit() else 0 self.i2c_transmit_bit(0 if ack else 1) return b def i2c_transfer(self, addr, write = '', read = 0): rdata = [] try: if write: self.i2c_start() if not self.i2c_transmit_byte((addr << 1) | 0): raise Exception('Write address NAK') for b in write: if not self.i2c_transmit_byte(b): raise Exception('Write NAK') if read: self.i2c_start() if not self.i2c_transmit_byte((addr << 1) | 1): raise Exception('Read address NAK') while read: rdata.append(self.i2c_receive_byte(read > 1)) read -= 1 finally: self.i2c_stop() return bytes(rdata)