Damien wrote:Following from
http://forum.micropython.org/viewtopic.php?f=3&t=2545, here we can discuss machine.I2C. This is really critical to get right, and make sure all ports implement it correctly, because it forms the basis of many drivers (eg LCD, env sensors, etc).
I think there should be a low-level I2C class which provides complete functionality and is relatively user-friendly, but at the same time being minimal. It should allow to construct I2C transactions piece-wise for cases where the data to send comes from different buffers (eg for controlling an LCD). It should allow to do (almost) everything without allocating on the heap.
Constructor:
Code: Select all
I2C(id, scl, sda, freq)
- id is the peripheral id, with -1 meaning software implementation
- scl, sda are pin objects
- freq is the frequency of the bus to use (could be called baudrate or baud)
Control/config methods:
Code: Select all
i2c.config(...) # general config function to get/set values, eg i2c.config(freq=100000)
i2c.close() # shut down the peripheral
Core transfer methods:
Code: Select all
i2c.start(addr, dir) # dir is one of i2c.READ, i2c.WRITE
i2c.write(buf)
i2c.writebyte(int)
i2c.readinto(buf)
i2c.readbyte()
i2c.stop()
Composite helper methods for common transactions:
Code: Select all
i2c.writeto(addr, buf) # = start(addr, i2c.WRITE); write(buf); stop()
i2c.readfrom_into(addr, buf) # = start(addr, i2c.READ); readinto(buf); stop()
i2c.write_readinto(addr, wr_buf, rd_buf) # = start(addr, i2c.WRITE); write(wr_buf); start(addr, i2c.READ); readinto(buf); stop()
In addition to I2C there would be an I2CEndpoint class which is purely for convenience, but is probably going to be used much more than the low-level I2C class itself.
Endpoint constructor:
Code: Select all
I2CEndpoint(i2c, addr, regaddrsize=8)
- i2c is a bus
- addr is the device address
- regaddrsize is the number of bits (8/16/32) needed to specify an i2c register address
Endpoint attributes:
Code: Select all
ep.i2c # get the underlying i2c bus
ep.addr # get the device address
ep.regaddrsize # get the register address size
Endpoint methods:
Code: Select all
ep.write(buf) # = i2c.writeto(ep.addr, buf)
ep.read(n) # = buf=bytearray(n); i2c.readfrom_into(ep.addr, buf); return buf
ep.readinto(buf) # = i2c.readfrom_into(ep.addr, buf)
ep.reg_write(regaddr, int_value) # select register and write value
ep.reg_read(regaddr) # select register and read value, returns an integer