Skip to content

Instantly share code, notes, and snippets.

@enjoy-digital
Created April 13, 2021 18:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enjoy-digital/e40d296a852335acfcab89a686147272 to your computer and use it in GitHub Desktop.
Save enjoy-digital/e40d296a852335acfcab89a686147272 to your computer and use it in GitHub Desktop.
I2C BitBanging over LiteX-Server
import time
# I2C Constants ------------------------------------------------------------------------------------
I2C_SCL = 0x01
I2C_SDAOE = 0x02
I2C_SDAOUT = 0x04
I2C_SDAIN = 0x01
def delay_us(d):
time.sleep(d/1000000)
def delay_ms(d):
time.sleep(d/1000)
I2C_DELAY = 1
I2C_WRITE = 0
I2C_READ = 1
# SFP I2C -----------------------------------------------------------------------------------------
class SFPI2C:
def __init__(self, regs):
self.regs = regs
self.started = 0
self.regs.cpri0_i2c_w.write(I2C_SCL)
# Check the I2C bus is ready
while(not (self.regs.cpri0_i2c_r.read() & I2C_SDAIN)):
delay_ms(1)
# I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c
def read_bit(self):
# Let the Slave drive data
self.regs.cpri0_i2c_w.write(0)
delay_us(I2C_DELAY)
self.regs.cpri0_i2c_w.write(I2C_SCL)
delay_us(I2C_DELAY)
bit = (self.regs.cpri0_i2c_r.read() & I2C_SDAIN)
self.regs.cpri0_i2c_w.write(0)
return bit
def write_bit(self, bit):
if bit:
self.regs.cpri0_i2c_w.write(I2C_SDAOE| I2C_SDAOUT)
else:
self.regs.cpri0_i2c_w.write(I2C_SDAOE)
delay_us(I2C_DELAY)
# Clock stretching
self.regs.cpri0_i2c_w.write(self.regs.cpri0_i2c_w.read() | I2C_SCL);
delay_us(I2C_DELAY)
self.regs.cpri0_i2c_w.write(self.regs.cpri0_i2c_w.read() & ~I2C_SCL);
def start_cond(self):
if self.started:
# Set SDA to 1
self.regs.cpri0_i2c_w.write(I2C_SDAOE| I2C_SDAOUT);
delay_us(I2C_DELAY)
self.regs.cpri0_i2c_w.write(self.regs.cpri0_i2c_w.read() | I2C_SCL);
delay_us(I2C_DELAY)
# SCL is high, set SDA from 1 to 0
self.regs.cpri0_i2c_w.write(I2C_SDAOE| I2C_SCL)
delay_us(I2C_DELAY)
self.regs.cpri0_i2c_w.write(I2C_SDAOE)
self.started = 1
def stop_cond(self):
# Set SDA to 0
self.regs.cpri0_i2c_w.write(I2C_SDAOE)
delay_us(I2C_DELAY)
# Clock stretching
self.regs.cpri0_i2c_w.write(I2C_SDAOE| I2C_SCL)
# SCL is high, set SDA from 0 to 1
self.regs.cpri0_i2c_w.write(I2C_SCL)
delay_us(I2C_DELAY)
self.started = 0
def write(self, byte):
for bit in range(8):
self.write_bit(byte & 0x80)
byte <<= 1
ack = not self.read_bit()
return ack
def read(self, ack):
byte = 0
for bit in range(8):
byte <<= 1
byte |= self.read_bit()
self.write(not ack)
return byte
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment