|
@@ -2,35 +2,37 @@
|
|
|
# NRF24L01+ Enhanced ShockBurst packets decoder
|
|
# NRF24L01+ Enhanced ShockBurst packets decoder
|
|
|
#
|
|
#
|
|
|
payload_len_default = 4
|
|
payload_len_default = 4
|
|
|
-packets = \
|
|
|
|
|
-(
|
|
|
|
|
- '10101010 11101110 00000011 00001000 00001011 01000111 000100 10 0 10101010 10101010 10101010 10101010 00011101',
|
|
|
|
|
- '10101010 11001000 11001000 11000011 110011 10 0 00001011 00000011 00000101 00000000 0010001100100000',
|
|
|
|
|
- '10101010 11001000 11001000 11000100 000100 11 1 00001011 00000011 00000101 00000000 0010010011100010',
|
|
|
|
|
- '10101010 11001000 11001000 11000100 00001011 00000011 00000101 00000010 1000010101000010',
|
|
|
|
|
- '10101010 11001000 11001000 11000000 110011 10 0 11110101 00000010 00000011 00000000 0000111001000000',
|
|
|
|
|
- '01010101 01000000 01101000 00010101 000000 00 0 0100100000100000',
|
|
|
|
|
-# '01010101 01000010 11100100 10100110 01010101 01000100 110011 00 0 10010101 10110011 01100100 10101100 10101011 01010010 01111100 01001010 1100110100110001',
|
|
|
|
|
-
|
|
|
|
|
|
|
+packets = (
|
|
|
|
|
+ "10101010 11101110 00000011 00001000 00001011 01000111 000100 10 0 10101010 10101010 10101010 10101010 00011101",
|
|
|
|
|
+ "10101010 11001000 11001000 11000011 110011 10 0 00001011 00000011 00000101 00000000 0010001100100000",
|
|
|
|
|
+ "10101010 11001000 11001000 11000100 000100 11 1 00001011 00000011 00000101 00000000 0010010011100010",
|
|
|
|
|
+ "10101010 11001000 11001000 11000100 00001011 00000011 00000101 00000010 1000010101000010",
|
|
|
|
|
+ "10101010 11001000 11001000 11000000 110011 10 0 11110101 00000010 00000011 00000000 0000111001000000",
|
|
|
|
|
+ "01010101 01000000 01101000 00010101 000000 00 0 0100100000100000",
|
|
|
|
|
+ # '01010101 01000010 11100100 10100110 01010101 01000100 110011 00 0 10010101 10110011 01100100 10101100 10101011 01010010 01111100 01001010 1100110100110001',
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+
|
|
|
def bin2hex(x):
|
|
def bin2hex(x):
|
|
|
def bin2hex_helper(r):
|
|
def bin2hex_helper(r):
|
|
|
while r:
|
|
while r:
|
|
|
yield r[0:2].upper()
|
|
yield r[0:2].upper()
|
|
|
r = r[2:]
|
|
r = r[2:]
|
|
|
- if len(x) == 0: return
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if len(x) == 0:
|
|
|
|
|
+ return
|
|
|
fmt = "{0:0" + str(int(len(x) / 8 * 2)) + "X}"
|
|
fmt = "{0:0" + str(int(len(x) / 8 * 2)) + "X}"
|
|
|
hex_data = fmt.format(int(x, 2))
|
|
hex_data = fmt.format(int(x, 2))
|
|
|
return list(bin2hex_helper(hex_data))
|
|
return list(bin2hex_helper(hex_data))
|
|
|
|
|
|
|
|
|
|
+
|
|
|
def bin2hexlong(b):
|
|
def bin2hexlong(b):
|
|
|
b = b.replace(" ", "")
|
|
b = b.replace(" ", "")
|
|
|
- out = "";
|
|
|
|
|
|
|
+ out = ""
|
|
|
n = 8
|
|
n = 8
|
|
|
- for i in range(0, len(b), n):
|
|
|
|
|
- b2 = b[i:i+n]
|
|
|
|
|
- out = out + "{0:02X}".format(int(b2.ljust(8, '0'),2))
|
|
|
|
|
|
|
+ for i in range(0, len(b), n):
|
|
|
|
|
+ b2 = b[i : i + n]
|
|
|
|
|
+ out = out + "{0:02X}".format(int(b2.ljust(8, "0"), 2))
|
|
|
return out
|
|
return out
|
|
|
|
|
|
|
|
|
|
|
|
@@ -42,7 +44,7 @@ def split_packet(packet, parts):
|
|
|
:return: list of substrings
|
|
:return: list of substrings
|
|
|
"""
|
|
"""
|
|
|
out = []
|
|
out = []
|
|
|
- packet = packet.replace(' ', '')
|
|
|
|
|
|
|
+ packet = packet.replace(" ", "")
|
|
|
for part_length in parts:
|
|
for part_length in parts:
|
|
|
out.append(packet[0:part_length])
|
|
out.append(packet[0:part_length])
|
|
|
packet = packet[part_length:]
|
|
packet = packet[part_length:]
|
|
@@ -53,15 +55,29 @@ def split_packet(packet, parts):
|
|
|
def parse_packet(packet, address_length, ESB):
|
|
def parse_packet(packet, address_length, ESB):
|
|
|
"""Split a packet into its fields and return them as tuple."""
|
|
"""Split a packet into its fields and return them as tuple."""
|
|
|
if ESB:
|
|
if ESB:
|
|
|
- preamble, address, payload_length, pid, no_ack, rest = split_packet(packet=packet, parts=(8, 8 * address_length, 6, 2, 1))
|
|
|
|
|
- payload, crc = split_packet(packet=rest, parts=((payload_len_default if int(payload_length, 2) > 32 else int(payload_length, 2)) * 8,))
|
|
|
|
|
|
|
+ preamble, address, payload_length, pid, no_ack, rest = split_packet(
|
|
|
|
|
+ packet=packet, parts=(8, 8 * address_length, 6, 2, 1)
|
|
|
|
|
+ )
|
|
|
|
|
+ payload, crc = split_packet(
|
|
|
|
|
+ packet=rest,
|
|
|
|
|
+ parts=(
|
|
|
|
|
+ (
|
|
|
|
|
+ payload_len_default
|
|
|
|
|
+ if int(payload_length, 2) > 32
|
|
|
|
|
+ else int(payload_length, 2)
|
|
|
|
|
+ )
|
|
|
|
|
+ * 8,
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
else:
|
|
else:
|
|
|
- preamble, address, rest = split_packet(packet=packet, parts=(8, 8 * address_length))
|
|
|
|
|
- crc = packet.rsplit(' ', 1)[1]
|
|
|
|
|
- payload = rest[0:len(rest) - len(crc)]
|
|
|
|
|
- payload_length = pid = no_ack = ''
|
|
|
|
|
|
|
+ preamble, address, rest = split_packet(
|
|
|
|
|
+ packet=packet, parts=(8, 8 * address_length)
|
|
|
|
|
+ )
|
|
|
|
|
+ crc = packet.rsplit(" ", 1)[1]
|
|
|
|
|
+ payload = rest[0 : len(rest) - len(crc)]
|
|
|
|
|
+ payload_length = pid = no_ack = ""
|
|
|
|
|
|
|
|
- assert preamble in ('10101010', '01010101')
|
|
|
|
|
|
|
+ assert preamble in ("10101010", "01010101")
|
|
|
assert len(crc) in (8, 16)
|
|
assert len(crc) in (8, 16)
|
|
|
|
|
|
|
|
return preamble, address, payload_length, pid, no_ack, payload, crc
|
|
return preamble, address, payload_length, pid, no_ack, payload, crc
|
|
@@ -76,11 +92,11 @@ def crc(bits, size=8):
|
|
|
:polynomial: 2 byte CRC - standard is 0x11021 = X^16+X^12+X^5+1, result the same for 0x1021
|
|
:polynomial: 2 byte CRC - standard is 0x11021 = X^16+X^12+X^5+1, result the same for 0x1021
|
|
|
"""
|
|
"""
|
|
|
if size == 8:
|
|
if size == 8:
|
|
|
- polynomial = 0x107
|
|
|
|
|
- crc = 0xFF
|
|
|
|
|
|
|
+ polynomial = 0x107
|
|
|
|
|
+ crc = 0xFF
|
|
|
else:
|
|
else:
|
|
|
- polynomial = 0x11021
|
|
|
|
|
- crc = 0xFFFF
|
|
|
|
|
|
|
+ polynomial = 0x11021
|
|
|
|
|
+ crc = 0xFFFF
|
|
|
max_crc_value = (1 << size) - 1 # e.g. 0xFF for mode 8bit-crc
|
|
max_crc_value = (1 << size) - 1 # e.g. 0xFF for mode 8bit-crc
|
|
|
for bit in bits:
|
|
for bit in bits:
|
|
|
bit = int(bit, 2)
|
|
bit = int(bit, 2)
|
|
@@ -88,44 +104,65 @@ def crc(bits, size=8):
|
|
|
if (crc >> size) ^ bit: # top most lfsr bit xor current data bit
|
|
if (crc >> size) ^ bit: # top most lfsr bit xor current data bit
|
|
|
crc ^= polynomial
|
|
crc ^= polynomial
|
|
|
crc &= max_crc_value # trim the crc to reject carry over bits
|
|
crc &= max_crc_value # trim the crc to reject carry over bits
|
|
|
-# print('{:X}'.format(crc))
|
|
|
|
|
|
|
+ # print('{:X}'.format(crc))
|
|
|
return crc
|
|
return crc
|
|
|
|
|
|
|
|
|
|
|
|
|
-if __name__ == '__main__':
|
|
|
|
|
|
|
+if __name__ == "__main__":
|
|
|
for packet in packets:
|
|
for packet in packets:
|
|
|
- fld = packet.split(' ');
|
|
|
|
|
|
|
+ fld = packet.split(" ")
|
|
|
address_length = -1
|
|
address_length = -1
|
|
|
ESB = True
|
|
ESB = True
|
|
|
for f in fld:
|
|
for f in fld:
|
|
|
- if len(f) == 6 : break
|
|
|
|
|
- if len(f) == 0 :
|
|
|
|
|
- ESB = False
|
|
|
|
|
|
|
+ if len(f) == 6:
|
|
|
|
|
+ break
|
|
|
|
|
+ if len(f) == 0:
|
|
|
|
|
+ ESB = False
|
|
|
break
|
|
break
|
|
|
address_length += 1
|
|
address_length += 1
|
|
|
- preamble, address, payload_length, pid, no_ack, payload, crc_received = \
|
|
|
|
|
- parse_packet(packet=packet, address_length=address_length, ESB=ESB)
|
|
|
|
|
|
|
+ (
|
|
|
|
|
+ preamble,
|
|
|
|
|
+ address,
|
|
|
|
|
+ payload_length,
|
|
|
|
|
+ pid,
|
|
|
|
|
+ no_ack,
|
|
|
|
|
+ payload,
|
|
|
|
|
+ crc_received,
|
|
|
|
|
+ ) = parse_packet(packet=packet, address_length=address_length, ESB=ESB)
|
|
|
crc_size = len(crc_received)
|
|
crc_size = len(crc_received)
|
|
|
- crc_received = '0x' + '{:X}'.format(int(crc_received, 2))
|
|
|
|
|
|
|
+ crc_received = "0x" + "{:X}".format(int(crc_received, 2))
|
|
|
print(f"Packet: {packet}")
|
|
print(f"Packet: {packet}")
|
|
|
- print('\n'.join((
|
|
|
|
|
- f'Hex: {bin2hexlong(packet)}',
|
|
|
|
|
- 'Preamble: 0x%X' % int(preamble,2),
|
|
|
|
|
- f'Address: {address_length} bytes - {bin2hex(address)}')))
|
|
|
|
|
|
|
+ print(
|
|
|
|
|
+ "\n".join(
|
|
|
|
|
+ (
|
|
|
|
|
+ f"Hex: {bin2hexlong(packet)}",
|
|
|
|
|
+ "Preamble: 0x%X" % int(preamble, 2),
|
|
|
|
|
+ f"Address: {address_length} bytes - {bin2hex(address)}",
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
if ESB:
|
|
if ESB:
|
|
|
- print('\n'.join((
|
|
|
|
|
- f'Payload length in packet: {int(payload_length, 2)}, used: {(payload_len_default if int(payload_length, 2) > 32 else int(payload_length, 2))}',
|
|
|
|
|
- f'Payload: {bin2hex(payload)}',
|
|
|
|
|
- f'Pid: {int(pid, 2)}',
|
|
|
|
|
- f'No_ack: {int(no_ack, 2) == 1}')))
|
|
|
|
|
|
|
+ print(
|
|
|
|
|
+ "\n".join(
|
|
|
|
|
+ (
|
|
|
|
|
+ f"Payload length in packet: {int(payload_length, 2)}, used: {(payload_len_default if int(payload_length, 2) > 32 else int(payload_length, 2))}",
|
|
|
|
|
+ f"Payload: {bin2hex(payload)}",
|
|
|
|
|
+ f"Pid: {int(pid, 2)}",
|
|
|
|
|
+ f"No_ack: {int(no_ack, 2) == 1}",
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
else:
|
|
else:
|
|
|
- print(f'Not Enhanced ShockBurst packet, payload length: {int(len(payload) / 8)}')
|
|
|
|
|
- print(f'Payload: {bin2hex(payload)}')
|
|
|
|
|
- print(f'CRC{crc_size}: {crc_received}')
|
|
|
|
|
- crc_calculated = '0x' + '{:X}'.format(crc(address + payload_length + pid + no_ack + payload, size=crc_size))
|
|
|
|
|
|
|
+ print(
|
|
|
|
|
+ f"Not Enhanced ShockBurst packet, payload length: {int(len(payload) / 8)}"
|
|
|
|
|
+ )
|
|
|
|
|
+ print(f"Payload: {bin2hex(payload)}")
|
|
|
|
|
+ print(f"CRC{crc_size}: {crc_received}")
|
|
|
|
|
+ crc_calculated = "0x" + "{:X}".format(
|
|
|
|
|
+ crc(address + payload_length + pid + no_ack + payload, size=crc_size)
|
|
|
|
|
+ )
|
|
|
if crc_received == crc_calculated:
|
|
if crc_received == crc_calculated:
|
|
|
- print('CRC is valid!')
|
|
|
|
|
|
|
+ print("CRC is valid!")
|
|
|
else:
|
|
else:
|
|
|
- print(f'CRC mismatch! Calculated CRC is {crc_calculated}.')
|
|
|
|
|
- print('-------------')
|
|
|
|
|
-
|
|
|
|
|
|
|
+ print(f"CRC mismatch! Calculated CRC is {crc_calculated}.")
|
|
|
|
|
+ print("-------------")
|