loboris / MicroPython_K210_LoBo

MicroPython implementation for Kendryte K210
128 stars 24 forks source link

Read data from 16-bit register address (I2C) #6

Closed Qutix closed 5 years ago

Qutix commented 5 years ago

Hello,

I'm trying to read the data from a battery fuel gauge (BQ27531) where I need to send a 16-bit register address: 16-bit

In other distros it can be achieved by:

from machine import I2C, Pin

i2c =machine.I2C(sda=Pin(4), scl=Pin(5))
value = i2c.readfrom_mem(0x55, 0x2233, 1, addrsize=16)

or by:

def _get_reg16(self, address):
        self.i2c.start()
        self.i2c.write(ustruct.pack('>BH', self._address << 1, address))
        data = self.i2c.readfrom(self._address, 2)
        return ustruct.unpack('>B', data)[0]

However we don't have "addrsize" attribute for i2c.readfrom_mem nor do we have i2c start/stop control. Here is similar question where I got the answers from.

Basically I have to send: 0x55 (slave address) + 0x00 (control reg) + 0x01 (tell me your device type) then the result would come back: 0x0531.

Do you think this can be done?

Qutix commented 5 years ago

Hmm,

Actually this can be done by:

 i2c.readfrom_mem(0x55, 0x0100, 2, adrlen=2)

However the resoponse is zero instead of the expected 0x0531. Here is a captured logic analyser screenshot: logic

So it seems to be working but I get no data. This is something I have to figure out from here. (Other operations like temperature reading is working fine)

loboris commented 5 years ago

Yes, the argument name is adrlen as mentioned in the Wiki. Always read the Wiki in case of any issue, it is not complete yet, but I'm working on it... In official MicroPython port this argument has a name addr_size and is specified in bits. In the next update, I will add this syntax to be accepted to. The hardware related functions are usually not standardized.

When other than expected value is read from I2C device it is usually caused by non-adequate pull-up resistors. As other readings are ok, in your case, this is probably not the issue.