-
-
Save enjoy-digital/e40d296a852335acfcab89a686147272 to your computer and use it in GitHub Desktop.
I2C BitBanging over LiteX-Server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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