请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: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