This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TLA2528:写入和读取寄存器问题

Guru**** 2380860 points
Other Parts Discussed in Thread: TLA2528
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1052491/tla2528-writting-and-reading-register-issue

器件型号:TLA2528

您好!

我使用 python 在 Linux 嵌入式机器上写入和读取寄存器、如果我以块大小写入/读取寄存器、我将得到以下结果:

如果我在单次写入中写入/读取它、它将会起作用、但如果我阻止写入和单次读取、我将得到:

有什么想法吗? TLA2528的地址为0x10

此致、

Michael

import time
from enum import Enum
import ctypes
from ctypes import *
from smbus2 import SMBus
from smbus2.smbus2 import i2c_smbus_ioctl_data, I2C_SMBUS_READ, I2C_SMBUS, I2C_SMBUS_BLOCK_MAX, I2C_SMBUS_I2C_BLOCK_DATA
from fcntl import ioctl

class REGISTER(Enum):
    SYSTEM_STATUS_REG = 0x00
    GENERAL_CFG_REG = 0x01
    DATA_CFG_REG = 0x02
    OSR_CFG_REG = 0x03
    OPMODE_CFG_REG = 0x04
    PIN_CFG_REG = 0x05
    GPIO_CFG_REG = 0x07
    GPO_DRIVE_CFG_REG = 0x09
    GPO_VALUE_REG = 0x0B
    GPI_VALUE_REG = 0x0D
    SEQUENCE_CFG_REG = 0x10
    CHANNEL_SEL_REG = 0x11
    AUTO_SEQ_CH_SEL_REG = 0x12



class OPCODES(Enum):
    SINGLE_READ = 0x10
    SINGLE_WRITE = 0x08
    SET_BIT = 0x18
    CLEAR_BIT = 0x20
    READ_BLOCK = 0x30
    WRITE_BLOCK = 0x28

class SYSTEM_STATUS(ctypes.Structure):

    _fields_ = [
        ("BOR", ctypes.c_uint8, 1),
        ("RESERVED", ctypes.c_uint8, 1),
        ("CRC_ERR_FUSE", ctypes.c_uint8, 1),
        ("OSR_DONE", ctypes.c_uint8, 1),
        ("RESERVED", ctypes.c_uint8, 1),
        ("I2C_SPEED", ctypes.c_uint8, 1),
        ("SEQ_STATUS", ctypes.c_uint8, 1),
        ("RSVD", ctypes.c_uint8, 1)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass


class GENERAL_CFG(ctypes.Structure):

    _fields_ = [
        ("RST", ctypes.c_uint8, 1),
        ("CAL", ctypes.c_uint8, 1),
        ("CH_RST", ctypes.c_uint8, 1),
        ("CNVST", ctypes.c_uint8, 1),
        ("RESERVED", ctypes.c_uint8, 4)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class DATA_CFG(ctypes.Structure):

    _fields_ = [
        ("RESERVED_1", ctypes.c_uint8, 4),
        ("APPEND_STATUS", ctypes.c_uint8, 2),
        ("RESERVED_2", ctypes.c_uint8, 1),
        ("FIX_PAT", ctypes.c_uint8, 1)]


    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class OSR_CFG(ctypes.Structure):

    _fields_ = [
        ("OSR", ctypes.c_uint8, 3),
        ("RESERVED", ctypes.c_uint8, 5)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class OPMODE_CFG(ctypes.Structure):

    _fields_ = [
        ("CLK_DIV", ctypes.c_uint8, 4),
        ("OSC_SEL", ctypes.c_uint8, 1),
        ("RESERVED", ctypes.c_uint8, 3)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class PIN_CFG(ctypes.Structure):

    _fields_ = [
        ("PIN_CFG_0", ctypes.c_uint8, 1),
        ("PIN_CFG_1", ctypes.c_uint8, 1),
        ("PIN_CFG_2", ctypes.c_uint8, 1),
        ("PIN_CFG_3", ctypes.c_uint8, 1),
        ("PIN_CFG_4", ctypes.c_uint8, 1),
        ("PIN_CFG_5", ctypes.c_uint8, 1),
        ("PIN_CFG_6", ctypes.c_uint8, 1),
        ("PIN_CFG_7", ctypes.c_uint8, 1)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class GPIO_CFG(ctypes.Structure):

    _fields_ = [
        ("GPIO_CFG_0", ctypes.c_uint8, 1),
        ("GPIO_CFG_1", ctypes.c_uint8, 1),
        ("GPIO_CFG_2", ctypes.c_uint8, 1),
        ("GPIO_CFG_3", ctypes.c_uint8, 1),
        ("GPIO_CFG_4", ctypes.c_uint8, 1),
        ("GPIO_CFG_5", ctypes.c_uint8, 1),
        ("GPIO_CFG_6", ctypes.c_uint8, 1),
        ("GPIO_CFG_7", ctypes.c_uint8, 1)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class GPO_DRIVE_CFG(ctypes.Structure):

    _fields_ = [
        ("GPO_DRIVE_CFG_0", ctypes.c_uint8, 1),
        ("GPO_DRIVE_CFG_1", ctypes.c_uint8, 1),
        ("GPO_DRIVE_CFG_2", ctypes.c_uint8, 1),
        ("GPO_DRIVE_CFG_3", ctypes.c_uint8, 1),
        ("GPO_DRIVE_CFG_4", ctypes.c_uint8, 1),
        ("GPO_DRIVE_CFG_5", ctypes.c_uint8, 1),
        ("GPO_DRIVE_CFG_6", ctypes.c_uint8, 1),
        ("GPO_DRIVE_CFG_7", ctypes.c_uint8, 1)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class GPO_VALUE(ctypes.Structure):

    _fields_ = [
        ("GPO_VALUE_0", ctypes.c_uint8, 1),
        ("GPO_VALUE_1", ctypes.c_uint8, 1),
        ("GPO_VALUE_2", ctypes.c_uint8, 1),
        ("GPO_VALUE_3", ctypes.c_uint8, 1),
        ("GPO_VALUE_4", ctypes.c_uint8, 1),
        ("GPO_VALUE_5", ctypes.c_uint8, 1),
        ("GPO_VALUE_6", ctypes.c_uint8, 1),
        ("GPO_VALUE_7", ctypes.c_uint8, 1)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class GPI_VALUE(ctypes.Structure):

    _fields_ = [
        ("GPI_VALUE_0", ctypes.c_uint8, 1),
        ("GPI_VALUE_1", ctypes.c_uint8, 1),
        ("GPI_VALUE_2", ctypes.c_uint8, 1),
        ("GPI_VALUE_3", ctypes.c_uint8, 1),
        ("GPI_VALUE_4", ctypes.c_uint8, 1),
        ("GPI_VALUE_5", ctypes.c_uint8, 1),
        ("GPI_VALUE_6", ctypes.c_uint8, 1),
        ("GPI_VALUE_7", ctypes.c_uint8, 1)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class SEQUENCE_CFG(ctypes.Structure):

    _fields_ = [
        ("SEQ_MODE", ctypes.c_uint8, 2),
        ("RESERVED", ctypes.c_uint8, 2),
        ("SEQ_START", ctypes.c_uint8, 1),
        ("RESERVED", ctypes.c_uint8, 3)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class CHANNEL_SEL(ctypes.Structure):

    _fields_ = [
        ("MANUAL_CHID", ctypes.c_uint8, 4),
        ("RESERVED", ctypes.c_uint8, 4)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class AUTO_SEQ_CH_SEL(ctypes.Structure):

    _fields_ = [
        ("AUTO_SEQ_CH_SEL_0", ctypes.c_uint8, 1),
        ("AUTO_SEQ_CH_SEL_1", ctypes.c_uint8, 1),
        ("AUTO_SEQ_CH_SEL_2", ctypes.c_uint8, 1),
        ("AUTO_SEQ_CH_SEL_3", ctypes.c_uint8, 1),
        ("AUTO_SEQ_CH_SEL_4", ctypes.c_uint8, 1),
        ("AUTO_SEQ_CH_SEL_5", ctypes.c_uint8, 1),
        ("AUTO_SEQ_CH_SEL_6", ctypes.c_uint8, 1),
        ("AUTO_SEQ_CH_SEL_7", ctypes.c_uint8, 1)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass


class TLA2528_REGISTER(ctypes.Structure):
    _fields_ = [
        ("SYSTEM_STATUS", SYSTEM_STATUS),
        ("GENERAL_CFG", GENERAL_CFG),
        ("DATA_CFG", DATA_CFG),
        ("OSR_CFG", OSR_CFG),
        ("OPMODE_CFG", OPMODE_CFG),
        ("PIN_CFG", PIN_CFG),
        ("GPIO_CFG", GPIO_CFG),
        ("GPO_DRIVE_CFG", GPO_DRIVE_CFG),
        ("GPO_VALUE", GPO_VALUE),
        ("GPI_VALUE", GPI_VALUE),
        ("SEQUENCE_CFG", SEQUENCE_CFG),
        ("CHANNEL_SEL", CHANNEL_SEL),
        ("AUTO_SEQ_CH_SEL", AUTO_SEQ_CH_SEL)]

    def __new__(cls, buf):
        return cls.from_buffer_copy(buf)

    def __init__(self, data):
        pass

class SLAVEADDRESS(Enum):
    POWER_MANAGEMENT_0 = 0x10
    POWER_MANAGEMENT_1 = 0x13

class mySMBUS(SMBus):
    def read_i2c_block_data_noRegister(self, i2c_addr, length, force=None):
        """
                Read a block of byte data from a given register.

                :param i2c_addr: i2c address
                :type i2c_addr: int
                :param register: Start register
                :type register: int
                :param length: Desired block length
                :type length: int
                :param force:
                :type force: Boolean
                :return: List of bytes
                :rtype: list
                """
        if length > I2C_SMBUS_BLOCK_MAX:
            raise ValueError("Desired block length over %d bytes" % I2C_SMBUS_BLOCK_MAX)
        self._set_address(i2c_addr, force=force)
        msg = i2c_smbus_ioctl_data.create(
            read_write=I2C_SMBUS_READ, command=0, size=I2C_SMBUS_I2C_BLOCK_DATA
        )
        msg.data.contents.byte = length
        ioctl(self.fd, I2C_SMBUS, msg)
        return msg.data.contents.block[1:length + 1]

class TLA2528(object):

    def __init__(self,  I2C):

        self.I2C = I2C
        self.TLA = TLA2528_REGISTER(b'\0' * ctypes.sizeof(TLA2528_REGISTER))

        self.HARDWARE_VERSION = 0
        self.PG_12V_1 = 0
        self.PG_12V_2 = 0
        self._n48V = 0
        self._12V_Internal = 0
        self._12V_BUS = 0


        for address in SLAVEADDRESS:
            try:
                self.I2C.write_quick(address.value) #Check if slave address is on the bus
                #If gets here than it is the new PMM Hardware
                self.readregister(address.value)
                self.writeregister(address.value)
                self.readvalues(address.value)

            except Exception as e:
                print(str(e))

    def readregister(self, address):

        recBytes = bytearray(b'')

        for reg in REGISTER:
            self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, reg.value)
            recBytes.append(self.I2C.read_byte(address))

        self.TLA = TLA2528_REGISTER(recBytes)


    def writeregister(self, address):

        self.TLA = TLA2528_REGISTER(b'\0' * ctypes.sizeof(TLA2528_REGISTER))
        self.TLA.SYSTEM_STATUS = SYSTEM_STATUS((0x89).to_bytes(1, byteorder='little'))
        self.TLA.GENERAL_CFG.CAL = 0
        self.TLA.GENERAL_CFG.CAL = 0
        self.TLA.GENERAL_CFG.CNVST = 0
        self.TLA.DATA_CFG.APPEND_STATUS = 1
        self.TLA.DATA_CFG.FIX_PAT = 1
        self.TLA.OSR_CFG.OSR = 7
        self.TLA.OPMODE_CFG.OSC_SEL = 0
        self.TLA.PIN_CFG = PIN_CFG((0x37).to_bytes(1, byteorder='little'))
        self.TLA.GPIO_CFG = GPIO_CFG((0xFF).to_bytes(1, byteorder='little'))
        self.TLA.SEQUENCE_CFG = SEQUENCE_CFG((0x11).to_bytes(1, byteorder='little'))
        self.TLA.AUTO_SEQ_CH_SEL = AUTO_SEQ_CH_SEL((0xC4).to_bytes(1, byteorder='little'))

        a = list(bytes(self.TLA))
        a.insert(0, 0)
        self.I2C.write_block_data(address, OPCODES.WRITE_BLOCK.value, a)


        for i, reg in enumerate(REGISTER):
           # self.I2C.write_block_data(address, OPCODES.SINGLE_WRITE.value, [reg.value, bytes(self.TLA)[i]])

            self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, reg.value)
            rec = self.I2C.read_byte(address).to_bytes(1, "little")
            print(str(reg) + " write: " + str(bytes(self.TLA)[i].to_bytes(1, "little")) + " read: " + str(rec))

        # self.I2C.write_byte_data(address, OPCODES.READ_BLOCK.value, 0x00)
        #b = self.I2C.read_i2c_block_data_noRegister(address, 13)
        print

    def readvalues(self, address):

        self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, REGISTER.SYSTEM_STATUS_REG.value)
        self.TLA.SYSTEM_STATUS = SYSTEM_STATUS((self.I2C.read_byte(address).to_bytes(1, byteorder='little')))

        if self.TLA.SYSTEM_STATUS.OSR_DONE \
            and not self.TLA.SYSTEM_STATUS.CRC_ERR_FUSE :

            # 0 HW0
            # 1 HW1
            # 2 HW2
            # 3 -48V
            # 4 12V_2_PG
            # 5 12V_1_PG
            # 6 12V_Internal
            # 7 12V_Bus
            values = self.I2C.read_i2c_block_data_noRegister(address, 3 * 3)  # TODO fixme, 3 bytes for 3 values

            for i in range(3):
                test = values[(3 * i) + 2] >> 4
                value = int(values[3 * i] << 8 | values[(3 * i) + 1])
                if test == 3:
                    self._n48V = value
                elif test == 6:
                    self._12V_Internal = value
                elif test == 7:
                    self._12V_BUS = value

            self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, REGISTER.GPI_VALUE_REG.value)
            digitalbits = self.I2C.read_byte(address)
            self.HARDWARE_VERSION = digitalbits & 0x07
            self.PG_12V_1 = digitalbits & 0x10 >> 4
            self.PG_12V_2 = digitalbits & 0x20 >> 5

            self.I2C.write_block_data(address, OPCODES.WRITE_BLOCK.value, [REGISTER.SYSTEM_STATUS_REG.value, bytes(self.TLA.SYSTEM_STATUS)])  # Clear OSR_DONE bit


        else:
            self.writeregister(address)

if __name__ == '__main__':
    I2C1 = mySMBUS(1)
    tla = TLA2528(I2C1)
    print

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我不理解您的问题、您能解释一下您遇到的问题吗?

    从我可以说明的内容来看、您在读取/写入寄存器内容时似乎遇到了问题。 我建议通过调试来探测具有示波器的数字线路、以便在总线上进行目视检查、这将有助于确认传输的内容是否符合预期。  

    此致

    Cynthia

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Cynthia、

    昨天、我看到了 SCL/SDA 线与示波器、发现问题出在 smbus python 库上。

    如果有人在此处查找 python 工作驱动程序代码、则为:

    import time
    from enum import Enum
    import ctypes
    from ctypes import *
    from smbus2 import SMBus
    from smbus2.smbus2 import i2c_smbus_ioctl_data, I2C_SMBUS_READ, I2C_SMBUS, I2C_SMBUS_BLOCK_MAX, I2C_SMBUS_I2C_BLOCK_DATA
    from fcntl import ioctl
    
    class REGISTER(Enum):
        SYSTEM_STATUS_REG = 0x00
        GENERAL_CFG_REG = 0x01
        DATA_CFG_REG = 0x02
        OSR_CFG_REG = 0x03
        OPMODE_CFG_REG = 0x04
        PIN_CFG_REG = 0x05
        GPIO_CFG_REG = 0x07
        GPO_DRIVE_CFG_REG = 0x09
        GPO_VALUE_REG = 0x0B
        GPI_VALUE_REG = 0x0D
        SEQUENCE_CFG_REG = 0x10
        CHANNEL_SEL_REG = 0x11
        AUTO_SEQ_CH_SEL_REG = 0x12
    
    
    
    class OPCODES(Enum):
        SINGLE_READ = 0x10
        SINGLE_WRITE = 0x08
        SET_BIT = 0x18
        CLEAR_BIT = 0x20
        READ_BLOCK = 0x30
        WRITE_BLOCK = 0x28
    
    class SYSTEM_STATUS(ctypes.Structure):
    
        _fields_ = [
            ("BOR", ctypes.c_uint8, 1),
            ("RESERVED", ctypes.c_uint8, 1),
            ("CRC_ERR_FUSE", ctypes.c_uint8, 1),
            ("OSR_DONE", ctypes.c_uint8, 1),
            ("RESERVED", ctypes.c_uint8, 1),
            ("I2C_SPEED", ctypes.c_uint8, 1),
            ("SEQ_STATUS", ctypes.c_uint8, 1),
            ("RSVD", ctypes.c_uint8, 1)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    
    class GENERAL_CFG(ctypes.Structure):
    
        _fields_ = [
            ("RST", ctypes.c_uint8, 1),
            ("CAL", ctypes.c_uint8, 1),
            ("CH_RST", ctypes.c_uint8, 1),
            ("CNVST", ctypes.c_uint8, 1),
            ("RESERVED", ctypes.c_uint8, 4)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class DATA_CFG(ctypes.Structure):
    
        _fields_ = [
            ("RESERVED_1", ctypes.c_uint8, 4),
            ("APPEND_STATUS", ctypes.c_uint8, 2),
            ("RESERVED_2", ctypes.c_uint8, 1),
            ("FIX_PAT", ctypes.c_uint8, 1)]
    
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class OSR_CFG(ctypes.Structure):
    
        _fields_ = [
            ("OSR", ctypes.c_uint8, 3),
            ("RESERVED", ctypes.c_uint8, 5)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class OPMODE_CFG(ctypes.Structure):
    
        _fields_ = [
            ("CLK_DIV", ctypes.c_uint8, 4),
            ("OSC_SEL", ctypes.c_uint8, 1),
            ("RESERVED", ctypes.c_uint8, 3)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class PIN_CFG(ctypes.Structure):
    
        _fields_ = [
            ("PIN_CFG_0", ctypes.c_uint8, 1),
            ("PIN_CFG_1", ctypes.c_uint8, 1),
            ("PIN_CFG_2", ctypes.c_uint8, 1),
            ("PIN_CFG_3", ctypes.c_uint8, 1),
            ("PIN_CFG_4", ctypes.c_uint8, 1),
            ("PIN_CFG_5", ctypes.c_uint8, 1),
            ("PIN_CFG_6", ctypes.c_uint8, 1),
            ("PIN_CFG_7", ctypes.c_uint8, 1)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class GPIO_CFG(ctypes.Structure):
    
        _fields_ = [
            ("GPIO_CFG_0", ctypes.c_uint8, 1),
            ("GPIO_CFG_1", ctypes.c_uint8, 1),
            ("GPIO_CFG_2", ctypes.c_uint8, 1),
            ("GPIO_CFG_3", ctypes.c_uint8, 1),
            ("GPIO_CFG_4", ctypes.c_uint8, 1),
            ("GPIO_CFG_5", ctypes.c_uint8, 1),
            ("GPIO_CFG_6", ctypes.c_uint8, 1),
            ("GPIO_CFG_7", ctypes.c_uint8, 1)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class GPO_DRIVE_CFG(ctypes.Structure):
    
        _fields_ = [
            ("GPO_DRIVE_CFG_0", ctypes.c_uint8, 1),
            ("GPO_DRIVE_CFG_1", ctypes.c_uint8, 1),
            ("GPO_DRIVE_CFG_2", ctypes.c_uint8, 1),
            ("GPO_DRIVE_CFG_3", ctypes.c_uint8, 1),
            ("GPO_DRIVE_CFG_4", ctypes.c_uint8, 1),
            ("GPO_DRIVE_CFG_5", ctypes.c_uint8, 1),
            ("GPO_DRIVE_CFG_6", ctypes.c_uint8, 1),
            ("GPO_DRIVE_CFG_7", ctypes.c_uint8, 1)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class GPO_VALUE(ctypes.Structure):
    
        _fields_ = [
            ("GPO_VALUE_0", ctypes.c_uint8, 1),
            ("GPO_VALUE_1", ctypes.c_uint8, 1),
            ("GPO_VALUE_2", ctypes.c_uint8, 1),
            ("GPO_VALUE_3", ctypes.c_uint8, 1),
            ("GPO_VALUE_4", ctypes.c_uint8, 1),
            ("GPO_VALUE_5", ctypes.c_uint8, 1),
            ("GPO_VALUE_6", ctypes.c_uint8, 1),
            ("GPO_VALUE_7", ctypes.c_uint8, 1)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class GPI_VALUE(ctypes.Structure):
    
        _fields_ = [
            ("GPI_VALUE_0", ctypes.c_uint8, 1),
            ("GPI_VALUE_1", ctypes.c_uint8, 1),
            ("GPI_VALUE_2", ctypes.c_uint8, 1),
            ("GPI_VALUE_3", ctypes.c_uint8, 1),
            ("GPI_VALUE_4", ctypes.c_uint8, 1),
            ("GPI_VALUE_5", ctypes.c_uint8, 1),
            ("GPI_VALUE_6", ctypes.c_uint8, 1),
            ("GPI_VALUE_7", ctypes.c_uint8, 1)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class SEQUENCE_CFG(ctypes.Structure):
    
        _fields_ = [
            ("SEQ_MODE", ctypes.c_uint8, 2),
            ("RESERVED", ctypes.c_uint8, 2),
            ("SEQ_START", ctypes.c_uint8, 1),
            ("RESERVED", ctypes.c_uint8, 3)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class CHANNEL_SEL(ctypes.Structure):
    
        _fields_ = [
            ("MANUAL_CHID", ctypes.c_uint8, 4),
            ("RESERVED", ctypes.c_uint8, 4)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class AUTO_SEQ_CH_SEL(ctypes.Structure):
    
        _fields_ = [
            ("AUTO_SEQ_CH_SEL_0", ctypes.c_uint8, 1),
            ("AUTO_SEQ_CH_SEL_1", ctypes.c_uint8, 1),
            ("AUTO_SEQ_CH_SEL_2", ctypes.c_uint8, 1),
            ("AUTO_SEQ_CH_SEL_3", ctypes.c_uint8, 1),
            ("AUTO_SEQ_CH_SEL_4", ctypes.c_uint8, 1),
            ("AUTO_SEQ_CH_SEL_5", ctypes.c_uint8, 1),
            ("AUTO_SEQ_CH_SEL_6", ctypes.c_uint8, 1),
            ("AUTO_SEQ_CH_SEL_7", ctypes.c_uint8, 1)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    
    class TLA2528_REGISTER(ctypes.Structure):
        _fields_ = [
            ("SYSTEM_STATUS", SYSTEM_STATUS),
            ("GENERAL_CFG", GENERAL_CFG),
            ("DATA_CFG", DATA_CFG),
            ("OSR_CFG", OSR_CFG),
            ("OPMODE_CFG", OPMODE_CFG),
            ("PIN_CFG", PIN_CFG),
            ("GPIO_CFG", GPIO_CFG),
            ("GPO_DRIVE_CFG", GPO_DRIVE_CFG),
            ("GPO_VALUE", GPO_VALUE),
            ("GPI_VALUE", GPI_VALUE),
            ("SEQUENCE_CFG", SEQUENCE_CFG),
            ("CHANNEL_SEL", CHANNEL_SEL),
            ("AUTO_SEQ_CH_SEL", AUTO_SEQ_CH_SEL)]
    
        def __new__(cls, buf):
            return cls.from_buffer_copy(buf)
    
        def __init__(self, data):
            pass
    
    class SLAVEADDRESS(Enum):
        POWER_MANAGEMENT_0 = 0x10
        POWER_MANAGEMENT_1 = 0x13
    
    class mySMBUS(SMBus):
    
    
        def read_i2c_block_data_noRegister(self, i2c_addr, length, force=None):
            """
                    Read a block of byte data from a given register.
    
                    :param i2c_addr: i2c address
                    :type i2c_addr: int
                    :param register: Start register
                    :type register: int
                    :param length: Desired block length
                    :type length: int
                    :param force:
                    :type force: Boolean
                    :return: List of bytes
                    :rtype: list
                    """
            if length > I2C_SMBUS_BLOCK_MAX:
                raise ValueError("Desired block length over %d bytes" % I2C_SMBUS_BLOCK_MAX)
            self._set_address(i2c_addr, force=force)
            msg = i2c_smbus_ioctl_data.create(
                read_write=I2C_SMBUS_READ,  size=I2C_SMBUS_I2C_BLOCK_DATA
            )
            msg.data.contents.byte = length
            ioctl(self.fd, I2C_SMBUS, msg)
            return msg.data.contents.block[1:length + 1]
    
    class TLA2528(object):
    
        def __init__(self,  I2C):
    
            self.I2C = I2C
            self.TLA = TLA2528_REGISTER(b'\0' * ctypes.sizeof(TLA2528_REGISTER))
    
            self.HARDWARE_VERSION = 0
            self.PG_12V_1 = 0
            self.PG_12V_2 = 0
            self._n48V = 0
            self._12V_Internal = 0
            self._12V_BUS = 0
    
    
            for address in SLAVEADDRESS:
                try:
                    self.I2C.write_quick(address.value) #Check if slave address is on the bus
                    #If gets here than it is the new PMM Hardware
                    self.readregister(address.value)
                    self.writeregister(address.value)
                    self.readvalues(address.value)
    
                except Exception as e:
                    print(str(e))
    
        def readregister(self, address):
    
            recBytes = bytearray(b'')
    
            for reg in REGISTER:
                self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, reg.value)
                recBytes.append(self.I2C.read_byte(address))
    
            self.TLA = TLA2528_REGISTER(recBytes)
    
    
        def writeregister(self, address):
    
            self.TLA = TLA2528_REGISTER(b'\0' * ctypes.sizeof(TLA2528_REGISTER))
            self.TLA.SYSTEM_STATUS = SYSTEM_STATUS((0x89).to_bytes(1, byteorder='little'))
            self.TLA.GENERAL_CFG.CAL = 0
            self.TLA.GENERAL_CFG.CAL = 0
            self.TLA.GENERAL_CFG.CNVST = 0
            self.TLA.DATA_CFG.APPEND_STATUS = 1
            self.TLA.DATA_CFG.FIX_PAT = 0
            self.TLA.OSR_CFG.OSR = 7
            self.TLA.OPMODE_CFG.OSC_SEL = 0
            self.TLA.PIN_CFG = PIN_CFG((0x37).to_bytes(1, byteorder='little'))
            self.TLA.GPIO_CFG = GPIO_CFG((0x37).to_bytes(1, byteorder='little'))
            self.TLA.SEQUENCE_CFG = SEQUENCE_CFG((0x11).to_bytes(1, byteorder='little')) #TODO not right
            self.TLA.AUTO_SEQ_CH_SEL = AUTO_SEQ_CH_SEL((0xC8).to_bytes(1, byteorder='little')) #TODO not right
    
            a = list(bytes(self.TLA))
            a.insert(0, 0)
            self.I2C.write_i2c_block_data(address, OPCODES.WRITE_BLOCK.value, a)
            print
            for i, reg in enumerate(REGISTER):
                self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, reg.value)
                rec = self.I2C.read_byte(address)
    
    
                if bytes(self.TLA)[i] != rec:
                    self.I2C.write_i2c_block_data(address, OPCODES.SINGLE_WRITE.value, [reg.value, bytes(self.TLA)[i]])
                    self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, reg.value)
                    rec = self.I2C.read_byte(address)
                    print("retry "+str(reg) + " write: " + str(bytes(self.TLA)[i]) + " read: " + str(rec))
                    print
                else:
                    print(str(reg) + " write: " + str(bytes(self.TLA)[i]) + " read: " + str(rec))
    
    
        def readvalues(self, address):
    
            #Start of convertion here!
            self.TLA.GENERAL_CFG.CNVST = 1
            self.I2C.write_i2c_block_data(address, OPCODES.SINGLE_WRITE.value, [REGISTER.GENERAL_CFG_REG.value, int.from_bytes(bytes(self.TLA.GENERAL_CFG), "little")])
    
            self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, REGISTER.SYSTEM_STATUS_REG.value)
            self.TLA.SYSTEM_STATUS = SYSTEM_STATUS((self.I2C.read_byte(address).to_bytes(1, byteorder='little')))
    
            if self.TLA.SYSTEM_STATUS.OSR_DONE \
                and not self.TLA.SYSTEM_STATUS.CRC_ERR_FUSE :
    
                # 0 HW0
                # 1 HW1
                # 2 HW2
                # 3 -48V
                # 4 12V_2_PG
                # 5 12V_1_PG
                # 6 12V_Internal
                # 7 12V_Bus
                values = self.I2C.read_i2c_block_data_noRegister(address, 3 * 3)  # TODO fixme, 3 bytes for 3 values
    
                for i in range(3):
                    test = values[(3 * i) + 2] >> 4
                    value = int(values[3 * i] << 8 | values[(3 * i) + 1])
                    #value = int(values[(3 * i) +1] << 8 | values[(3 * i) ])
                    if test == 3:
                        self._n48V = value * 5/65536 * -21.145 + 4.229 #TODO calculate slope and offset better
                    elif test == 6:
                        self._12V_Internal = value * 5/65536 * 3
                    elif test == 7:
                        self._12V_BUS = value * 5/65536 * 3
    
                self.I2C.write_byte_data(address, OPCODES.SINGLE_READ.value, REGISTER.GPI_VALUE_REG.value)
                digitalbits = self.I2C.read_byte(address)
                self.HARDWARE_VERSION = digitalbits & 0x07
                self.PG_12V_1 = digitalbits & 0x10 >> 4
                self.PG_12V_2 = digitalbits & 0x20 >> 5
    
                self.I2C.write_i2c_block_data(address, OPCODES.WRITE_BLOCK.value, [REGISTER.SYSTEM_STATUS_REG.value,  int.from_bytes(bytes(self.TLA.SYSTEM_STATUS), "little")])  # Clear OSR_DONE bit
    
    
            else:
                self.writeregister(address)
    
    if __name__ == '__main__':
        I2C1 = mySMBUS(1)
        tla = TLA2528(I2C1)
        print