kopia lustrzana https://github.com/micropython/micropython-lib
re-commit after black
rodzic
ce4a579b6e
commit
1f37df5588
|
@ -34,16 +34,22 @@
|
|||
Q unsigned long long 8
|
||||
f float 4
|
||||
d double 8
|
||||
|
||||
|
||||
"""
|
||||
|
||||
from machine import I2C
|
||||
from struct import pack, unpack
|
||||
|
||||
|
||||
class RORegBit:
|
||||
def __init__(self, i2c, dev_addr, reg_addr, num_bytes, bit_location, endian='', fmt='B'):
|
||||
def __init__(
|
||||
self, i2c, dev_addr, reg_addr, num_bytes, bit_location, endian="", fmt="B"
|
||||
):
|
||||
"""
|
||||
Creates an :class:`RORegBit` object which allows read only access to a single bit within a register.
|
||||
|
||||
|
||||
:param i2c: I2C bus which connects the host system to the peripheral device
|
||||
:type kind: machine.I2C()
|
||||
:param dev_addr: I2C address of the device which
|
||||
|
@ -126,7 +132,7 @@ class RORegBit:
|
|||
|
||||
__check_reg(self)
|
||||
|
||||
del(i2c, dev_addr, reg_addr, num_bytes, bit_location, fmt)
|
||||
del (i2c, dev_addr, reg_addr, num_bytes, bit_location, fmt)
|
||||
|
||||
def __get__(self):
|
||||
"""
|
||||
|
@ -135,8 +141,11 @@ class RORegBit:
|
|||
"""
|
||||
return __getbit(self)
|
||||
|
||||
|
||||
class RWRegBit:
|
||||
def __init__(self, i2c, dev_addr, reg_addr, num_bytes, bit_location, endian='', fmt='B'):
|
||||
def __init__(
|
||||
self, i2c, dev_addr, reg_addr, num_bytes, bit_location, endian="", fmt="B"
|
||||
):
|
||||
"""
|
||||
Creates an :class:`RORegBit` object which allows read and write access to a single bit within a register.
|
||||
|
||||
|
@ -222,9 +231,11 @@ class RWRegBit:
|
|||
|
||||
__check_reg(self)
|
||||
|
||||
self._premask, self._postmask = __calc_mask(bit_location, bit_location, num_bytes)
|
||||
self._premask, self._postmask = __calc_mask(
|
||||
bit_location, bit_location, num_bytes
|
||||
)
|
||||
|
||||
del(i2c, dev_addr, reg_addr, num_bytes, bit_location, endian, fmt)
|
||||
del (i2c, dev_addr, reg_addr, num_bytes, bit_location, endian, fmt)
|
||||
|
||||
def __get__(self):
|
||||
"""
|
||||
|
@ -240,8 +251,11 @@ class RWRegBit:
|
|||
"""
|
||||
return __setbit(self, setting)
|
||||
|
||||
|
||||
class RORegBits:
|
||||
def __init__(self, i2c, dev_addr, reg_addr, num_bytes, lsb, msb, endian='', fmt='B'):
|
||||
def __init__(
|
||||
self, i2c, dev_addr, reg_addr, num_bytes, lsb, msb, endian="", fmt="B"
|
||||
):
|
||||
"""
|
||||
Creates an :class:`RORegBits` object which allows read only access to a sequential set of bits within a bitfield.
|
||||
|
||||
|
@ -334,7 +348,7 @@ class RORegBits:
|
|||
|
||||
self._premask, self._mask, self._postmask = __calc_mask(lsb, msb, num_bytes)
|
||||
|
||||
del(i2c, dev_addr, reg_addr, num_bytes, lsb, msb, endian, fmt)
|
||||
del (i2c, dev_addr, reg_addr, num_bytes, lsb, msb, endian, fmt)
|
||||
|
||||
def __get__(self):
|
||||
"""
|
||||
|
@ -343,8 +357,11 @@ class RORegBits:
|
|||
"""
|
||||
return __getbits(self)
|
||||
|
||||
|
||||
class RWRegBits:
|
||||
def __init__(self, i2c, dev_addr, reg_addr, num_bytes, lsb, msb, endian='', fmt='B'):
|
||||
def __init__(
|
||||
self, i2c, dev_addr, reg_addr, num_bytes, lsb, msb, endian="", fmt="B"
|
||||
):
|
||||
"""
|
||||
Creates an :class:`RWRegBits` object which allows read and write access to a sequential set of bits within a bitfield.
|
||||
|
||||
|
@ -447,7 +464,7 @@ class RWRegBits:
|
|||
|
||||
self._premask, self._mask, self._postmask = __calc_mask(lsb, msb, num_bytes)
|
||||
|
||||
del(i2c, dev_addr, reg_addr, num_bytes, lsb, msb, fmt, endian)
|
||||
del (i2c, dev_addr, reg_addr, num_bytes, lsb, msb, fmt, endian)
|
||||
|
||||
def __get__(self):
|
||||
"""
|
||||
|
@ -463,8 +480,9 @@ class RWRegBits:
|
|||
"""
|
||||
return __setbits(self, setting)
|
||||
|
||||
|
||||
class ROReg:
|
||||
def __init__(self, i2c, dev_addr, reg_addr, num_bytes=1, endian='', fmt='B'):
|
||||
def __init__(self, i2c, dev_addr, reg_addr, num_bytes=1, endian="", fmt="B"):
|
||||
"""
|
||||
Creates a :class:`ROReg` object which allows read only access to n number of sequential registers,
|
||||
where n is specified by :param num_bytes:.
|
||||
|
@ -551,7 +569,7 @@ class ROReg:
|
|||
|
||||
__check_reg(self)
|
||||
|
||||
del(i2c, dev_addr, reg_addr, num_bytes, fmt, endian)
|
||||
del (i2c, dev_addr, reg_addr, num_bytes, fmt, endian)
|
||||
|
||||
def __get__(self):
|
||||
"""
|
||||
|
@ -560,8 +578,10 @@ class ROReg:
|
|||
"""
|
||||
return __getreg(self)
|
||||
|
||||
|
||||
class RWReg:
|
||||
"""
|
||||
def __init__(self, i2c, dev_addr, reg_addr, num_bytes, endian="", fmt="B"):
|
||||
"""
|
||||
Creates a :class:`RWReg` object which allows read and write access to n number of sequential registers,
|
||||
where n is specified by :param num_bytes:.
|
||||
|
||||
|
@ -647,7 +667,6 @@ class RWReg:
|
|||
print(device.my_reg2) # prints 240
|
||||
|
||||
"""
|
||||
def __init__(self, i2c, dev_addr, reg_addr, num_bytes, endian='', fmt='B'):
|
||||
self._i2c = i2c
|
||||
self._dev_addr = dev_addr
|
||||
self._reg_addr = reg_addr
|
||||
|
@ -657,7 +676,7 @@ class RWReg:
|
|||
|
||||
__check_reg(self)
|
||||
|
||||
del(i2c, dev_addr, reg_addr, num_bytes, fmt, endian)
|
||||
del (i2c, dev_addr, reg_addr, num_bytes, fmt, endian)
|
||||
|
||||
def __get__(self):
|
||||
"""
|
||||
|
@ -675,43 +694,57 @@ class RWReg:
|
|||
"""
|
||||
return __setreg(self, setting)
|
||||
|
||||
|
||||
"""
|
||||
*
|
||||
* GLOBAL HELPER FUNCTIONS
|
||||
*
|
||||
*
|
||||
"""
|
||||
|
||||
|
||||
def __getbit(reg_object):
|
||||
if isinstance(reg_object, (RORegBit, RWRegBit)):
|
||||
# Retrieve register value and unpack to int
|
||||
value = reg_object._i2c.readfrom_mem(reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes)
|
||||
value = reg_object._i2c.readfrom_mem(
|
||||
reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes
|
||||
)
|
||||
|
||||
# Unpack byte
|
||||
value = unpack(reg_object._endian+reg_object._fmt, value)[0]
|
||||
value = unpack(reg_object._endian + reg_object._fmt, value)[0]
|
||||
|
||||
# Perform shift followed by _AND_ operation to determine bit state
|
||||
return (value >> reg_object._bit_location)&0b1
|
||||
return (value >> reg_object._bit_location) & 0b1
|
||||
|
||||
else:
|
||||
raise TypeError("incorrect object type - must be RORegBit, RWRegBit")
|
||||
raise TypeError("incorrect object type - must be RORegBit, RWRegBit")
|
||||
|
||||
|
||||
def __setbit(reg_object, setting):
|
||||
if isinstance(reg_object, RWRegBit):
|
||||
if setting in (0,1):
|
||||
if setting in (0, 1):
|
||||
# Retrieve register value and unpack to int
|
||||
value = reg_object._i2c.readfrom_mem(reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes)
|
||||
value = reg_object._i2c.readfrom_mem(
|
||||
reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes
|
||||
)
|
||||
|
||||
# Unpack byte
|
||||
value = unpack(reg_object._endian+reg_object._fmt, value)[0]
|
||||
value = unpack(reg_object._endian + reg_object._fmt, value)[0]
|
||||
|
||||
# Assemble byte
|
||||
value = (value®_object._postmask) + (setting<<reg_object._bit_location) + (value®_object._premask)
|
||||
value = (
|
||||
(value & reg_object._postmask)
|
||||
+ (setting << reg_object._bit_location)
|
||||
+ (value & reg_object._premask)
|
||||
)
|
||||
|
||||
# Pack to bytes
|
||||
value = pack(reg_object._endian+reg_object._fmt, value)
|
||||
value = pack(reg_object._endian + reg_object._fmt, value)
|
||||
|
||||
# Write to I2C
|
||||
reg_object._i2c.writeto_mem(reg_object._dev_addr, reg_object._reg_addr, value)
|
||||
reg_object._i2c.writeto_mem(
|
||||
reg_object._dev_addr, reg_object._reg_addr, value
|
||||
)
|
||||
|
||||
# Return True for success
|
||||
return True
|
||||
|
@ -721,63 +754,83 @@ def __setbit(reg_object, setting):
|
|||
else:
|
||||
raise TypeError("incorrect object type - must be RWRegBit")
|
||||
|
||||
|
||||
def __getbits(reg_object):
|
||||
if isinstance(reg_object, (RORegBits, RWRegBits)):
|
||||
# Retrieve register value and unpack to int
|
||||
value = reg_object._i2c.readfrom_mem(reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes)
|
||||
value = reg_object._i2c.readfrom_mem(
|
||||
reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes
|
||||
)
|
||||
|
||||
# Unpack bytes
|
||||
value = unpack(reg_object._endian+reg_object._fmt, value)[0]
|
||||
value = unpack(reg_object._endian + reg_object._fmt, value)[0]
|
||||
|
||||
# Return value of bit field
|
||||
return (value & reg_object._mask)>>reg_object._lsb
|
||||
return (value & reg_object._mask) >> reg_object._lsb
|
||||
|
||||
else:
|
||||
raise TypeError("incorrect object type - must be RORegBits, RWRegBits")
|
||||
raise TypeError("incorrect object type - must be RORegBits, RWRegBits")
|
||||
|
||||
|
||||
def __setbits(reg_object, setting):
|
||||
if isinstance(reg_object, RWRegBits):
|
||||
if isinstance(setting, int) and setting <= reg_object._mask:
|
||||
|
||||
# Retrieve register value and unpack to int
|
||||
value = reg_object._i2c.readfrom_mem(reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes)
|
||||
value = reg_object._i2c.readfrom_mem(
|
||||
reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes
|
||||
)
|
||||
|
||||
# Unpack bytes
|
||||
value = unpack(reg_object._endian+reg_object._fmt, value)[0]
|
||||
value = unpack(reg_object._endian + reg_object._fmt, value)[0]
|
||||
|
||||
# Assemble
|
||||
value = (value®_object._postmask) + (setting<<reg_object._lsb) + (value®_object._premask)
|
||||
value = (
|
||||
(value & reg_object._postmask)
|
||||
+ (setting << reg_object._lsb)
|
||||
+ (value & reg_object._premask)
|
||||
)
|
||||
|
||||
# Pack to bytes object
|
||||
value = struct.pack(reg_object._endian+reg_object._fmt, value)
|
||||
value = struct.pack(reg_object._endian + reg_object._fmt, value)
|
||||
|
||||
# Write to device
|
||||
reg_object._i2c.writeto_mem(reg_object._dev_addr, reg_object._reg_addr, value)
|
||||
reg_object._i2c.writeto_mem(
|
||||
reg_object._dev_addr, reg_object._reg_addr, value
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
else:
|
||||
raise ValueError(f"value of setting exceeds max value of bitfield: {reg_object._mask}")
|
||||
raise ValueError(
|
||||
f"value of setting exceeds max value of bitfield: {reg_object._mask}"
|
||||
)
|
||||
else:
|
||||
raise TypeError("incorrect object type - must be RWRegBits")
|
||||
|
||||
|
||||
def __getreg(reg_object):
|
||||
if isinstance(reg_object, (ROReg, RWReg)):
|
||||
# Retrieve register value and unpack to int
|
||||
values = reg_object._i2c.readfrom_mem(reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes)
|
||||
values = reg_object._i2c.readfrom_mem(
|
||||
reg_object._dev_addr, reg_object._reg_addr, reg_object._num_bytes
|
||||
)
|
||||
|
||||
# Return Tuple of values
|
||||
return unpack(reg_object._endian+reg_object._fmt, values)
|
||||
return unpack(reg_object._endian + reg_object._fmt, values)
|
||||
|
||||
else:
|
||||
raise TypeError("incorrect object type - must be ROReg, RWReg")
|
||||
raise TypeError("incorrect object type - must be ROReg, RWReg")
|
||||
|
||||
|
||||
def __setreg(reg_object, settings):
|
||||
|
||||
if isinstance(reg_object, RWReg):
|
||||
if isinstance(settings, (bytes, bytearray)):
|
||||
# Write to device
|
||||
reg_object._i2c.writeto_mem(reg_object._dev_addr, reg_object._reg_addr, settings)
|
||||
# Write to device
|
||||
reg_object._i2c.writeto_mem(
|
||||
reg_object._dev_addr, reg_object._reg_addr, settings
|
||||
)
|
||||
|
||||
elif isinstance(settings, (tuple, list)):
|
||||
# Where our data will go
|
||||
|
@ -785,20 +838,23 @@ def __setreg(reg_object, settings):
|
|||
|
||||
# Pack and append to d
|
||||
for n in range(0, len(settings)):
|
||||
d.extend(pack(reg_object._endian+reg_object._fmt[n] ,settings[n]))
|
||||
d.extend(pack(reg_object._endian + reg_object._fmt[n], settings[n]))
|
||||
|
||||
# Write to device
|
||||
reg_object._i2c.writeto_mem(reg_object._dev_addr, reg_object._reg_addr, d)
|
||||
|
||||
# Assumed single int() for single reg-op
|
||||
elif isinstance(settings, int):
|
||||
d = pack(reg_object._endian+reg_object._fmt ,settings)
|
||||
d = pack(reg_object._endian + reg_object._fmt, settings)
|
||||
reg_object._i2c.writeto_mem(reg_object._dev_addr, reg_object._reg_addr, d)
|
||||
|
||||
else:
|
||||
raise TypeError("unsupported object type, settings must be int(), bytes(), bytearray(), tuple(), or list()")
|
||||
raise TypeError(
|
||||
"unsupported object type, settings must be int(), bytes(), bytearray(), tuple(), or list()"
|
||||
)
|
||||
else:
|
||||
raise TypeError("incorrect object type - must be ROReg, RWReg")
|
||||
raise TypeError("incorrect object type - must be ROReg, RWReg")
|
||||
|
||||
|
||||
def __calc_mask(lsb, msb, numbytes):
|
||||
"""
|
||||
|
@ -806,25 +862,26 @@ def __calc_mask(lsb, msb, numbytes):
|
|||
|
||||
returns ints() pre, mask, post
|
||||
"""
|
||||
|
||||
# Check input types
|
||||
if lsb.__class__() == int() and lsb >= 0:
|
||||
if msb.__class__() == int() and msb >= 0:
|
||||
if numbytes.__class__() == int() and numbytes >= 0:
|
||||
|
||||
# Check for detectable errors
|
||||
if msb>=lsb:
|
||||
if msb >= lsb:
|
||||
|
||||
# Single bit mask
|
||||
if msb == lsb:
|
||||
pre, post = 0b0, 0b0
|
||||
|
||||
# Calc post masking
|
||||
for bit in range(msb+1, numbytes*8):
|
||||
post = (post<<1) + 0b1
|
||||
for bit in range(msb + 1, numbytes * 8):
|
||||
post = (post << 1) + 0b1
|
||||
|
||||
# Calc pre masking
|
||||
for bit in range(0, lsb):
|
||||
pre = (pre<<1) + 0b1
|
||||
pre = (pre << 1) + 0b1
|
||||
|
||||
return pre, post
|
||||
|
||||
|
@ -835,12 +892,12 @@ def __calc_mask(lsb, msb, numbytes):
|
|||
pre, mask, post = 0b0, 0b0, 0b0
|
||||
|
||||
# Calc post masking
|
||||
for bit in range(msb+1, numbytes*8):
|
||||
post = (post<<1) + 0b1
|
||||
for bit in range(msb + 1, numbytes * 8):
|
||||
post = (post << 1) + 0b1
|
||||
|
||||
# Calc bitfield masking
|
||||
for bit in range(lsb, msb+1):
|
||||
mask = (mask<<1) + 0b1
|
||||
for bit in range(lsb, msb + 1):
|
||||
mask = (mask << 1) + 0b1
|
||||
|
||||
# No bits lower than 0
|
||||
if lsb == 0:
|
||||
|
@ -848,7 +905,7 @@ def __calc_mask(lsb, msb, numbytes):
|
|||
|
||||
else:
|
||||
for bit in range(0, lsb):
|
||||
pre = (pre<<1) + 0b1
|
||||
pre = (pre << 1) + 0b1
|
||||
|
||||
return pre, mask, post
|
||||
else:
|
||||
|
@ -860,11 +917,24 @@ def __calc_mask(lsb, msb, numbytes):
|
|||
else:
|
||||
raise ValueError("lsb must be of type int() and 0 or greater")
|
||||
|
||||
|
||||
def __check_reg(reg_object):
|
||||
|
||||
# Alowable struct.pack/unpack formats to check for
|
||||
fmts = {'b':1, 'B':1, 'h':2, 'H':2, 'f':4, 'i':4, 'I':4, 'l':4, 'L':4, 'q':8, 'Q':8}
|
||||
endians = '@><'
|
||||
fmts = {
|
||||
"b": 1,
|
||||
"B": 1,
|
||||
"h": 2,
|
||||
"H": 2,
|
||||
"f": 4,
|
||||
"i": 4,
|
||||
"I": 4,
|
||||
"l": 4,
|
||||
"L": 4,
|
||||
"q": 8,
|
||||
"Q": 8,
|
||||
}
|
||||
endians = "@><"
|
||||
byte_count = 0
|
||||
|
||||
# Take in only register objects
|
||||
|
@ -880,12 +950,18 @@ def __check_reg(reg_object):
|
|||
byte_count = byte_count + fmts[reg_object._fmt[n]]
|
||||
|
||||
else:
|
||||
raise ValueError(f"unsupported format code of '{reg_object._fmt[n]}'")
|
||||
raise ValueError(
|
||||
f"unsupported format code of '{reg_object._fmt[n]}'"
|
||||
)
|
||||
|
||||
if byte_count != reg_object._num_bytes:
|
||||
raise ValueError(f"format string accounts for {byte_count} bytes, _num_bytes value of {reg_object._num_bytes} does not match")
|
||||
raise ValueError(
|
||||
f"format string accounts for {byte_count} bytes, _num_bytes value of {reg_object._num_bytes} does not match"
|
||||
)
|
||||
|
||||
else:
|
||||
raise TypeError("format and endian must be of type str()")
|
||||
else:
|
||||
raise TypeError("incorrect object type - must be ROReg, RWReg, ROBits, RWBits, ROReg, RWReg")
|
||||
raise TypeError(
|
||||
"incorrect object type - must be ROReg, RWReg, ROBits, RWBits, ROReg, RWReg"
|
||||
)
|
Ładowanie…
Reference in New Issue