ctypes into uctypes for crc communication
Posted: Sun Jan 19, 2020 5:03 am
Finally got some time to jump back onto micropython and finish a project I had for communicating with my offgrid inverter.
It is a MPP Solar unit and requires a CRC with the commands to ensure all is healthy with the data, the python project I am getting most of the ideas with regards to communication is https://github.com/jblance/mpp-solar
jblance uses the ctypes module in his code but this deviates from the micro python uctypes module and I am wondering if someone can help me translate the structures over as ctypes seems to respond with an actual class that contains a value attribute.
the crc high/low return method looks like this:
I was thinking of something like this, but when it loops through the command the index changes from what the ctypes can do due to the value of the class to being retained, and extends beyond the crc_ta scope.
Any help would be greatly appreciated as my experience is fairly limited in this area.
It is a MPP Solar unit and requires a CRC with the commands to ensure all is healthy with the data, the python project I am getting most of the ideas with regards to communication is https://github.com/jblance/mpp-solar
jblance uses the ctypes module in his code but this deviates from the micro python uctypes module and I am wondering if someone can help me translate the structures over as ctypes seems to respond with an actual class that contains a value attribute.
the crc high/low return method looks like this:
Code: Select all
import ctypes
def crc(cmd):
"""
Calculates CRC for supplied text
"""
log.info('Calculating CRC for %s', cmd)
crc = 0
da = 0
crc_ta = [0x0000, 0x1021, 0x2042, 0x3063,
0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b,
0xc18c, 0xd1ad, 0xe1ce, 0xf1ef]
for c in cmd:
t_da = ctypes.c_uint8(crc >> 8)
da = t_da.value >> 4
crc <<= 4
index = da ^ (ord(c) >> 4)
crc ^= crc_ta[index]
t_da = ctypes.c_uint8(crc >> 8)
da = t_da.value >> 4
crc <<= 4
index = da ^ (ord(c) & 0x0f)
crc ^= crc_ta[index]
crc_low = ctypes.c_uint8(crc).value
crc_high = ctypes.c_uint8(crc >> 8).value
if (crc_low == 0x28 or crc_low == 0x0d or crc_low == 0x0a):
crc_low += 1
if (crc_high == 0x28 or crc_high == 0x0d or crc_high == 0x0a):
crc_high += 1
crc = crc_high << 8
crc += crc_low
log.debug('Generated CRC %x %x %x', crc_high, crc_low, crc)
return [crc_high, crc_low]
Code: Select all
import uctypes
def crc(cmd):
crc = 0
da = 0
crc_ta = [0x0000, 0x1021, 0x2042, 0x3063,
0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b,
0xc18c, 0xd1ad, 0xe1ce, 0xf1ef]
for c in cmd:
t_da = crc >> 8 | uctypes.UINT8
da = t_da >> 4
crc <<= 4
index = da ^ (ord(c) >> 4)
crc ^= crc_ta[index]
t_da = crc >> 8 | uctypes.UINT8
da = t_da >> 4
crc <<= 4
index = da ^ (ord(c) & 0x0f)
crc ^= crc_ta[index]
crc_low = crc | uctypes.UINT8
crc_high = crc >> 8 | uctypes.UINT8
if (crc_low == 0x28 or crc_low == 0x0d or crc_low == 0x0a):
crc_low += 1
if (crc_high == 0x28 or crc_high == 0x0d or crc_high == 0x0a):
crc_high += 1
crc = crc_high << 8
crc += crc_low
print('Generated CRC {} {} {}'.format(crc_high, crc_low, crc))
return [crc_high, crc_low]