From 2f1a2782d28698258cb6c92a2de3d6ef1150096e Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 5 Mar 2016 00:17:41 +0800 Subject: [PATCH] coredevice: add I2C, PCA9548, TCA6424A drivers --- artiq/coredevice/i2c.py | 75 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 artiq/coredevice/i2c.py diff --git a/artiq/coredevice/i2c.py b/artiq/coredevice/i2c.py new file mode 100644 index 000000000..09f449b0c --- /dev/null +++ b/artiq/coredevice/i2c.py @@ -0,0 +1,75 @@ +from artiq.language.core import syscall, kernel +from artiq.language.types import TBool, TInt8, TInt32, TNone +from artiq.coredevice.exceptions import I2CError + + +@syscall +def i2c_init(busno: TInt32) -> TNone: + raise NotImplementedError("syscall not simulated") + + +@syscall +def i2c_start(busno: TInt32) -> TNone: + raise NotImplementedError("syscall not simulated") + + +@syscall +def i2c_stop(busno: TInt32) -> TNone: + raise NotImplementedError("syscall not simulated") + + +@syscall +def i2c_write(busno: TInt32, b: TInt32) -> TBool: + raise NotImplementedError("syscall not simulated") + + +@syscall +def i2c_read(busno: TInt32, ack: TBool) -> TInt32: + raise NotImplementedError("syscall not simulated") + + +class PCA9548: + def __init__(self, dmgr, busno=0, address=0x74): + self.core = dmgr.get("core") + self.busno = busno + self.address = address + + @kernel + def set(self, channel): + i2c_init(self.busno) + i2c_start(self.busno) + try: + if not i2c_write(self.busno, self.address): + raise I2CError("PCA9548 failed to ack address") + if not i2c_write(self.busno, 1 << channel): + raise I2CError("PCA9548 failed to ack control word") + finally: + i2c_stop(self.busno) + + +class TCA6424A: + def __init__(self, dmgr, busno=0, address=0x44): + self.core = dmgr.get("core") + self.busno = busno + self.address = address + + @kernel + def _write24(self, command, value): + i2c_init(self.busno) + i2c_start(self.busno) + try: + if not i2c_write(self.busno, self.address): + raise I2CError("TCA6424A failed to ack address") + if not i2c_write(self.busno, command): + raise I2CError("TCA6424A failed to ack command") + for i in range(3): + if not i2c_write(self.busno, value >> 16): + raise I2CError("TCA6424A failed to ack command") + value <<= 8 + finally: + i2c_stop(self.busno) + + @kernel + def set(self, outputs): + self._write24(0x8c, 0) # set all directions to output + self._write24(0x84, output) # set levels