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

