refactoring, cleanup, testing
This commit is contained in:
parent
dcbdbeec0b
commit
aef9733f2e
8 changed files with 321 additions and 667 deletions
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python2.7
|
#!/usr/bin/env python2.7
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
import RaspyRFM
|
from raspyrfm import *
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
UDP_IP = "0.0.0.0"
|
UDP_IP = "0.0.0.0"
|
||||||
|
@ -12,10 +12,10 @@ sock = socket.socket(socket.AF_INET, # Internet
|
||||||
socket.SOCK_DGRAM) # UDP
|
socket.SOCK_DGRAM) # UDP
|
||||||
sock.bind((UDP_IP, UDP_PORT))
|
sock.bind((UDP_IP, UDP_PORT))
|
||||||
|
|
||||||
rfm = RaspyRFM.RaspyRFM()
|
rfm = RaspyRFM(1, RFM69)
|
||||||
rfm.SetParams(
|
rfm.set_params(
|
||||||
Freq = 433.92,
|
Freq = 433.92,
|
||||||
TXPower = 13,
|
TxPower = 13,
|
||||||
ModulationType = rfm69.OOK,
|
ModulationType = rfm69.OOK,
|
||||||
SyncPattern = [],
|
SyncPattern = [],
|
||||||
)
|
)
|
||||||
|
@ -24,7 +24,6 @@ print("Listening...")
|
||||||
while True:
|
while True:
|
||||||
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
|
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
|
||||||
print("received message from " + addr[0] + ': ' + str(data))
|
print("received message from " + addr[0] + ': ' + str(data))
|
||||||
print(sock)
|
|
||||||
msg = str(data).split(":")
|
msg = str(data).split(":")
|
||||||
|
|
||||||
if msg[0] == "SEARCH HCGW":
|
if msg[0] == "SEARCH HCGW":
|
||||||
|
@ -59,5 +58,5 @@ while True:
|
||||||
for i in range(bitleft):
|
for i in range(bitleft):
|
||||||
bindata[len(bindata) - 1] <<= 1
|
bindata[len(bindata) - 1] <<= 1
|
||||||
|
|
||||||
rfm.SetParams(Datarate = 1000.0 / steplen)
|
rfm.set_params(Datarate = 1000.0 / steplen)
|
||||||
rfm.SendPacket(bindata * rep)
|
rfm.send_packet(bindata * rep)
|
||||||
|
|
178
apps/fs20.py
Normal file
178
apps/fs20.py
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
#!/usr/bin/env python2.7
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
PROTOCOL = "FS20"
|
||||||
|
|
||||||
|
def __parse_byte(bits):
|
||||||
|
i = int(bits, 2)
|
||||||
|
cnt = 0
|
||||||
|
tmp = i
|
||||||
|
while tmp > 0:
|
||||||
|
cnt += 1
|
||||||
|
tmp &= tmp - 1
|
||||||
|
if (cnt & 1) == 0:
|
||||||
|
return i>>1
|
||||||
|
else:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def Decode(pulses):
|
||||||
|
if len(pulses) != 118:
|
||||||
|
print(len(pulses), pulses)
|
||||||
|
return
|
||||||
|
|
||||||
|
sym = ""
|
||||||
|
s = 0
|
||||||
|
for p in pulses:
|
||||||
|
if (p >= 300) and (p <= 500):
|
||||||
|
sym += 's'
|
||||||
|
s += p
|
||||||
|
elif (p > 500) and (p <= 750):
|
||||||
|
sym += 'l'
|
||||||
|
s += p
|
||||||
|
else:
|
||||||
|
sym += '?'
|
||||||
|
|
||||||
|
bits = ""
|
||||||
|
for i in range(59):
|
||||||
|
if sym[:2] == 'ss':
|
||||||
|
bits += "0"
|
||||||
|
elif sym[:2] == "ll":
|
||||||
|
bits += "1"
|
||||||
|
else:
|
||||||
|
bits +="?"
|
||||||
|
sym = sym[2:]
|
||||||
|
|
||||||
|
print(bits)
|
||||||
|
#check for sync sequence
|
||||||
|
if bits[:13] != "0000000000001":
|
||||||
|
return
|
||||||
|
bits = bits[13:] #strip off sync sequence
|
||||||
|
|
||||||
|
by = []
|
||||||
|
while len(bits) >= 9:
|
||||||
|
by.append(__parse_byte(bits[:9]))
|
||||||
|
bits = bits[9:]
|
||||||
|
|
||||||
|
#check checksum
|
||||||
|
cs = 6
|
||||||
|
for i in range(len(by) - 1):
|
||||||
|
cs += by[i]
|
||||||
|
cs = by[-1:][0] - (cs & 0xff)
|
||||||
|
if (cs > 2) or (cs < 0):
|
||||||
|
return
|
||||||
|
|
||||||
|
ret = {
|
||||||
|
"protocol": PROTOCOL,
|
||||||
|
"housecode": "{:04X}".format((by[0] << 8) | by[1]),
|
||||||
|
"address": "{:02X}".format(by[2]),
|
||||||
|
"command": "{:02X}".format(by[3]) if len(by) == 5 else "{:04X}".format(by[3] << 8 | by[4])
|
||||||
|
}
|
||||||
|
print(ret)
|
||||||
|
|
||||||
|
return
|
||||||
|
return ("fs20", bits, int(round(100 / (12.0 * 8 + 1))))
|
||||||
|
|
||||||
|
def Encode(args):
|
||||||
|
da = []
|
||||||
|
bp = [0]
|
||||||
|
bv = [0]
|
||||||
|
def add_pulse(val, length):
|
||||||
|
for i in range(length):
|
||||||
|
bp[0] += 1
|
||||||
|
bv[0] <<= 1
|
||||||
|
bv[0] |= val
|
||||||
|
if bp[0] == 8:
|
||||||
|
da.append(bv[0])
|
||||||
|
bv[0] = 0
|
||||||
|
bp[0] = 0
|
||||||
|
|
||||||
|
def add_bit(b):
|
||||||
|
if b == 0:
|
||||||
|
add_pulse(1, 2)
|
||||||
|
add_pulse(0, 2)
|
||||||
|
else:
|
||||||
|
add_pulse(1, 3)
|
||||||
|
add_pulse(0, 3)
|
||||||
|
|
||||||
|
def add_byte(by):
|
||||||
|
par = 0
|
||||||
|
mask = 0x80
|
||||||
|
while (mask):
|
||||||
|
add_bit(by & mask)
|
||||||
|
par >>= 1
|
||||||
|
par ^= (by & mask)
|
||||||
|
mask >>= 1
|
||||||
|
add_bit(par)
|
||||||
|
|
||||||
|
#add sync pattern
|
||||||
|
for i in range(12):
|
||||||
|
add_bit(0)
|
||||||
|
add_bit(1)
|
||||||
|
|
||||||
|
hc = int(args[0], 16)
|
||||||
|
adr = int(args[1], 16)
|
||||||
|
cmd = int(args[2], 16)
|
||||||
|
#calculate checksum
|
||||||
|
q = (6 + (hc >> 8) + (hc & 0xFF) + adr + (cmd >> 8) + (cmd & 0xFF)) & 0xff
|
||||||
|
#add housecode
|
||||||
|
add_byte(hc >> 8)
|
||||||
|
add_byte(hc & 0xFF)
|
||||||
|
#add address
|
||||||
|
add_byte(adr)
|
||||||
|
#add command
|
||||||
|
add_byte(cmd)
|
||||||
|
#add checksum
|
||||||
|
add_byte(q)
|
||||||
|
#add EOT
|
||||||
|
add_bit(0)
|
||||||
|
add_pulse(0, 33)
|
||||||
|
if bp[0] > 0:
|
||||||
|
add_pulse(0, 8-bp[0])
|
||||||
|
return (da, 3, 200)
|
||||||
|
|
||||||
|
code = ' '.join(args)
|
||||||
|
if re.match("^[01Ff]{12}$", code):
|
||||||
|
data = []
|
||||||
|
for c in code:
|
||||||
|
if c == '0':
|
||||||
|
data.append(0x88)
|
||||||
|
elif c == '1':
|
||||||
|
data.append(0xEE)
|
||||||
|
elif c in ['F', 'f']:
|
||||||
|
data.append(0x8E)
|
||||||
|
data += [0x80, 0x00, 0x00, 0x00] #sync
|
||||||
|
|
||||||
|
return (data, 5, 360)
|
||||||
|
|
||||||
|
elif re.match('^[A-P] [1-4] [1-4] (on|off)$', code):
|
||||||
|
g = re.match('^([A-P]) ([1-4]) ([1-4]) (on|off)$', code).groups()
|
||||||
|
tristate = ""
|
||||||
|
tristate += encodeBits(ord(g[0]) - ord('A'), 4) #housecode
|
||||||
|
tristate += encodeBits(ord(g[2]) - 1, 2) #channel
|
||||||
|
tristate += encodeBits(ord(g[1]) - 1, 2) #group
|
||||||
|
tristate += "0F"
|
||||||
|
tristate += 'FF' if g[3] == 'on' else 'F0'
|
||||||
|
return Encode([tristate])
|
||||||
|
|
||||||
|
elif re.match('^([01]{5}) ([1-4]) (on|off)$', code): #Brennenstuhl
|
||||||
|
g = re.match('^([01]{5}) ([1-4]) (on|off)$', code).groups()
|
||||||
|
tristate = ""
|
||||||
|
for c in g[0]:
|
||||||
|
tristate += '0' if c == '1' else 'F'
|
||||||
|
for i in range(4):
|
||||||
|
tristate += '0' if int(g[1]) - 1 == i else 'F'
|
||||||
|
tristate += 'F'
|
||||||
|
tristate += '0F' if g[2] == 'on' else 'F0'
|
||||||
|
return Encode([tristate])
|
||||||
|
|
||||||
|
elif re.match('^[1-4] [1-4] (on|off)$', code):
|
||||||
|
g = re.match('^([1-4]) ([1-4]) (on|off)$', code).groups()
|
||||||
|
tristate = ""
|
||||||
|
for i in range(4):
|
||||||
|
tristate += "0" if int(g[0]) - 1 == i else "F"
|
||||||
|
for i in range(4):
|
||||||
|
tristate += "0" if int(g[1]) - 1 == i else "F"
|
||||||
|
tristate += "FFF"
|
||||||
|
tristate += 'F' if g[2] == 'on' else '0'
|
||||||
|
return Encode([tristate])
|
131
apps/rcpulse.py
131
apps/rcpulse.py
|
@ -1,16 +1,21 @@
|
||||||
#!/usr/bin/env python2.7
|
#!/usr/bin/env python2.7
|
||||||
|
|
||||||
import RaspyRFM
|
from raspyrfm import *
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import it32
|
import it32
|
||||||
import tristate
|
import tristate
|
||||||
import bistate24
|
import bistate24
|
||||||
|
import fs20
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
import wave, struct
|
||||||
|
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
parser.add_argument("-t", "--timebase", type=int, help=u"timebase in \u03bcs")
|
parser.add_argument("-t", "--timebase", type=int, help=u"timebase in \u03bcs")
|
||||||
parser.add_argument("-r", "--repeats", type=int, help=u"number of repetitions")
|
parser.add_argument("-r", "--repeats", type=int, help=u"number of repetitions")
|
||||||
|
parser.add_argument("-m", "--module", type=int, metavar="1-4", help=u"RaspyRFM module 1-4", default=1)
|
||||||
|
parser.add_argument("-f", "--frequency", type=float, help=u"frequency in MHz", default=433.92)
|
||||||
|
parser.add_argument("-w", "--write", help=u"write wavefile")
|
||||||
parser.add_argument("code", nargs='*', help="code, e. g. '000000000FFF', 'A 1 2 on' or '10111100011101011111111110001110'")
|
parser.add_argument("code", nargs='*', help="code, e. g. '000000000FFF', 'A 1 2 on' or '10111100011101011111111110001110'")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -18,6 +23,7 @@ protos = [
|
||||||
it32,
|
it32,
|
||||||
tristate,
|
tristate,
|
||||||
bistate24,
|
bistate24,
|
||||||
|
fs20,
|
||||||
]
|
]
|
||||||
|
|
||||||
txdata = None
|
txdata = None
|
||||||
|
@ -33,25 +39,108 @@ if len(args.code) > 0:
|
||||||
print("invalid code!")
|
print("invalid code!")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
rfm = RaspyRFM.RaspyRFM()
|
rfm = RaspyRFM(args.module, RFM69)
|
||||||
rfm.SetParams(
|
rfm.set_params(
|
||||||
Freq = 433.92, #MHz
|
Freq = args.frequency, #MHz
|
||||||
Datarate = 20.0, #kbit/s
|
Datarate = 20.0, #kbit/s
|
||||||
Bandwidth = 200, #kHz
|
Bandwidth = 200, #kHz
|
||||||
SyncPattern = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F],
|
SyncPattern = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F],
|
||||||
RssiThresh = -105, #dBm
|
RssiThresh = -105, #dBm
|
||||||
ModulationType = RaspyRFM.OOK,
|
ModulationType = rfm69.OOK,
|
||||||
OokThreshType = 1, #peak thresh
|
OokThreshType = 1, #peak thresh
|
||||||
OokPeakThreshDec = 3,
|
OokPeakThreshDec = 3,
|
||||||
|
Preamble = 0,
|
||||||
|
TxPower = 13
|
||||||
|
)
|
||||||
|
|
||||||
|
wf = wave.open("out.wav", "wb")
|
||||||
|
def rxcb():
|
||||||
|
while True:
|
||||||
|
d = rfm.read_fifo_wait(64)
|
||||||
|
ba = bytearray()
|
||||||
|
for s in d:
|
||||||
|
mask = 0x80
|
||||||
|
while mask > 0:
|
||||||
|
if (s & mask) > 0:
|
||||||
|
ba.append(255)
|
||||||
|
else:
|
||||||
|
ba.append(0)
|
||||||
|
mask >>= 1
|
||||||
|
wf.writeframesraw(ba)
|
||||||
|
|
||||||
|
if args.write:
|
||||||
|
wf.setnchannels(1)
|
||||||
|
wf.setsampwidth(1)
|
||||||
|
wf.setframerate(20000)
|
||||||
|
|
||||||
|
rfm.set_params(
|
||||||
|
SyncPattern = [],
|
||||||
|
OokThreshType = 0, #fix thresh
|
||||||
|
OokFixedThresh = 85,
|
||||||
|
)
|
||||||
|
rfm.start_rx(rxcb)
|
||||||
|
|
||||||
|
wf.writeframes('')
|
||||||
|
wf.close()
|
||||||
|
print("WRITE!")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
rfm.set_params(
|
||||||
|
SyncPattern = [],
|
||||||
|
Datarate = 1.63,
|
||||||
|
)
|
||||||
|
i=[
|
||||||
|
"01010011110011111110000111111111",
|
||||||
|
"01011101110011111110000111111111",
|
||||||
|
"01100011110011111110000111111111",
|
||||||
|
"01101101110011111110000111111111",
|
||||||
|
]
|
||||||
|
do=[]
|
||||||
|
b=0
|
||||||
|
db=0
|
||||||
|
def addpulse(h, l):
|
||||||
|
global do, b, db
|
||||||
|
for i in range(h):
|
||||||
|
db <<= 1
|
||||||
|
db |= 1
|
||||||
|
b += 1
|
||||||
|
|
||||||
|
if b == 8:
|
||||||
|
do.append(db)
|
||||||
|
db = 0
|
||||||
|
b = 0
|
||||||
|
|
||||||
|
for i in range(l):
|
||||||
|
db <<= 1
|
||||||
|
b += 1
|
||||||
|
|
||||||
|
if b == 8:
|
||||||
|
do.append(db)
|
||||||
|
db = 0
|
||||||
|
b = 0
|
||||||
|
|
||||||
|
for c in i[args.timebase]:
|
||||||
|
if c == '0':
|
||||||
|
addpulse(2, 1)
|
||||||
|
else:
|
||||||
|
addpulse(1, 2)
|
||||||
|
addpulse(1, 17)
|
||||||
|
#print(do, b)
|
||||||
|
rfm.send_packet(do * 3)
|
||||||
|
exit()
|
||||||
|
|
||||||
|
rfm.set_params(
|
||||||
|
Datarate = 20.0, #kbit/s
|
||||||
|
SyncPattern = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F],
|
||||||
)
|
)
|
||||||
|
|
||||||
if txdata:
|
if txdata:
|
||||||
rfm.SetParams(
|
rfm.set_params(
|
||||||
SyncPattern = [],
|
SyncPattern = [],
|
||||||
Datarate = 1000.0 / (args.timebase if args.timebase else txdata[2])
|
Datarate = 1000.0 / (args.timebase if args.timebase else txdata[2])
|
||||||
)
|
)
|
||||||
rep = (args.repeats if args.repeats else txdata[1])
|
rep = (args.repeats if args.repeats else txdata[1])
|
||||||
rfm.SendPacket(txdata[0] * rep)
|
rfm.send_packet(txdata[0] * rep)
|
||||||
print("Code sent!")
|
print("Code sent!")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
@ -65,14 +154,34 @@ def Decode(pulses):
|
||||||
if dec:
|
if dec:
|
||||||
print(dec)
|
print(dec)
|
||||||
|
|
||||||
if not dec:
|
s = ""
|
||||||
print("Len " + str(len(pulses)) + ": " + str(pulses))
|
if len(pulses) == 66:
|
||||||
|
for p in pulses:
|
||||||
|
if (p>900):
|
||||||
|
s += "l"
|
||||||
|
else:
|
||||||
|
s += "s"
|
||||||
|
b = ""
|
||||||
|
while len(s) > 0:
|
||||||
|
if s[:2] == "sl":
|
||||||
|
b += "1"
|
||||||
|
elif s[:2] == "ls":
|
||||||
|
b += "0"
|
||||||
|
else:
|
||||||
|
b += "?"
|
||||||
|
s = s[2:]
|
||||||
|
#print(b)
|
||||||
|
|
||||||
|
#print(len(pulses), pulses)
|
||||||
|
|
||||||
|
#if not dec:
|
||||||
|
# print("Len " + str(len(pulses)) + ": " + str(pulses))
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
data = rfm.ReceivePacket(260)
|
data = rfm.receive_packet(260)
|
||||||
s = ""
|
s = ""
|
||||||
|
|
||||||
pulsecount = 7
|
pulsecount = 4
|
||||||
glitchcount = 0
|
glitchcount = 0
|
||||||
bit = True
|
bit = True
|
||||||
pulses = []
|
pulses = []
|
||||||
|
|
72
connair.py
72
connair.py
|
@ -1,72 +0,0 @@
|
||||||
#!/usr/bin/env python2.7
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import rfm69
|
|
||||||
import sys
|
|
||||||
|
|
||||||
UDP_IP = "0.0.0.0"
|
|
||||||
UDP_PORT = 49880
|
|
||||||
HELLO_MESSAGE = "HCGW:VC:Seegel Systeme;MC:RaspyRFM;FW:1.00;IP:192.168.2.124;;"
|
|
||||||
|
|
||||||
sock = socket.socket(socket.AF_INET, # Internet
|
|
||||||
socket.SOCK_DGRAM) # UDP
|
|
||||||
sock.bind((UDP_IP, UDP_PORT))
|
|
||||||
|
|
||||||
#sock.sendto("TXP:0,0,10,20000,350,25,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,1,3,1,3,3,1,1,17;", ("192.168.178.51", 49880))
|
|
||||||
#sys.exit(0)
|
|
||||||
|
|
||||||
rfm = rfm69.Rfm69()
|
|
||||||
rfm.SetParams(
|
|
||||||
Freq = 433.92,
|
|
||||||
TXPower = 13,
|
|
||||||
ModulationType = rfm69.OOK,
|
|
||||||
SyncPattern = [],
|
|
||||||
RssiThresh = -72
|
|
||||||
)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
|
|
||||||
#data = "TXP:0,0,6,5950,350,25,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,1,3,1,3,3,1,1,17;"
|
|
||||||
#addr = ("123", 5)
|
|
||||||
print "received message:", data, "from ", addr
|
|
||||||
|
|
||||||
msg = str(data).split(":")
|
|
||||||
|
|
||||||
if msg[0] == "SEARCH HCGW":
|
|
||||||
sock.sendto(HELLO_MESSAGE, addr)
|
|
||||||
print "Hello message"
|
|
||||||
|
|
||||||
if msg[0] == "TXP":
|
|
||||||
msg[1] = msg[1].replace(";", "")
|
|
||||||
cmd = msg[1].split(",")
|
|
||||||
rep = int(cmd[2])
|
|
||||||
pauselen = int(cmd[3])
|
|
||||||
steplen = int(cmd[4])
|
|
||||||
numpulse = int(cmd[5])
|
|
||||||
pulsedata = cmd[6:]
|
|
||||||
pulsedata[numpulse * 2 - 1] = int(pulsedata[numpulse * 2 - 1]) + pauselen / steplen
|
|
||||||
|
|
||||||
bindata = []
|
|
||||||
bit = True
|
|
||||||
numbit = 0
|
|
||||||
bitleft = 0
|
|
||||||
for i in range(numpulse * 2):
|
|
||||||
for bits in range(int(pulsedata[i])):
|
|
||||||
if bitleft == 0:
|
|
||||||
bitleft = 8
|
|
||||||
bindata.append(0x00)
|
|
||||||
|
|
||||||
bindata[len(bindata) - 1] <<= 1
|
|
||||||
if bit:
|
|
||||||
bindata[len(bindata) - 1] |= 0x01
|
|
||||||
bitleft -= 1
|
|
||||||
bit = not bit
|
|
||||||
for i in range(bitleft):
|
|
||||||
bindata[len(bindata) - 1] <<= 1
|
|
||||||
print "bitleft: ", bitleft
|
|
||||||
|
|
||||||
print "reps: ", rep
|
|
||||||
print "Pulse data", pulsedata
|
|
||||||
print "bin:", bindata
|
|
||||||
rfm.SetParams(Datarate = 1000.0 / steplen)
|
|
||||||
rfm.SendPacket(bindata * rep)
|
|
24
fs20tx.py
24
fs20tx.py
|
@ -1,23 +1,20 @@
|
||||||
#!/usr/bin/env python2.7
|
#!/usr/bin/env python2.7
|
||||||
|
|
||||||
from rfm69 import Rfm69
|
from raspyrfm import *
|
||||||
import rfm69
|
|
||||||
import sensors
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
if Rfm69.Test(1):
|
rfm = RaspyRFM(2, RFM69) #when using the RaspyRFM twin
|
||||||
rfm = Rfm69(1, 24) #when using the RaspyRFM twin
|
#elif Rfm69.Test(0):
|
||||||
elif Rfm69.Test(0):
|
# rfm = Rfm69() #when using a single single 868 MHz RaspyRFM
|
||||||
rfm = Rfm69() #when using a single single 868 MHz RaspyRFM
|
#else:
|
||||||
else:
|
# print "No RFM69 module found!"
|
||||||
print "No RFM69 module found!"
|
# exit()
|
||||||
exit()
|
|
||||||
|
|
||||||
rfm.SetParams(
|
rfm.set_params(
|
||||||
Freq = 868.350,
|
Freq = 868.350,
|
||||||
Datarate = 5.0,
|
Datarate = 5.0,
|
||||||
TXPower = -10,
|
TxPower = -10,
|
||||||
ModulationType = rfm69.OOK,
|
ModulationType = rfm69.OOK,
|
||||||
SyncPattern = [0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x38],
|
SyncPattern = [0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x38],
|
||||||
Preamble = 0
|
Preamble = 0
|
||||||
|
@ -81,5 +78,6 @@ def MakeFS20Frame(hc, adr, cmd):
|
||||||
data = []
|
data = []
|
||||||
bitcnt = 0
|
bitcnt = 0
|
||||||
MakeFS20Frame(int(sys.argv[1], 0), int(sys.argv[2], 0), int(sys.argv[3], 0))
|
MakeFS20Frame(int(sys.argv[1], 0), int(sys.argv[2], 0), int(sys.argv[3], 0))
|
||||||
|
print(data)
|
||||||
for x in range(3):
|
for x in range(3):
|
||||||
rfm.SendPacket(data)
|
rfm.send_packet(data)
|
||||||
|
|
1
maxrx.py
1
maxrx.py
|
@ -65,6 +65,7 @@ rxThread.daemon = True
|
||||||
rxThread.start()
|
rxThread.start()
|
||||||
|
|
||||||
def Decode(frame):
|
def Decode(frame):
|
||||||
|
print(frame)
|
||||||
#decode MAX! frame
|
#decode MAX! frame
|
||||||
cnt = frame[1]
|
cnt = frame[1]
|
||||||
flag = hex(frame[2])
|
flag = hex(frame[2])
|
||||||
|
|
|
@ -402,7 +402,7 @@ class Rfm69(threading.Thread):
|
||||||
self.__set_reg(RegOokPeak, 3<<6, value<<6)
|
self.__set_reg(RegOokPeak, 3<<6, value<<6)
|
||||||
|
|
||||||
elif key == "OokFixedThresh":
|
elif key == "OokFixedThresh":
|
||||||
self.___write_reg(RegOokFix, value)
|
self.__write_reg(RegOokFix, value)
|
||||||
|
|
||||||
elif key == "OokPeakThreshDec":
|
elif key == "OokPeakThreshDec":
|
||||||
self.__set_reg(RegOokPeak, 7<<0, value)
|
self.__set_reg(RegOokPeak, 7<<0, value)
|
||||||
|
|
559
rfm69.py
559
rfm69.py
|
@ -1,559 +0,0 @@
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
import spidev
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
FXOSC = 32E6
|
|
||||||
FSTEP = FXOSC / (1<<19)
|
|
||||||
|
|
||||||
#------ Raspberry RFM Module connection -----
|
|
||||||
# RaspyRFM single module
|
|
||||||
# Connect to pins 17-26 on raspberry pi
|
|
||||||
#-------------------------------------------------#
|
|
||||||
# Raspi | Raspi | Raspi | RFM69 | RFM12 | PCB con #
|
|
||||||
# Name | GPIO | Pin | Name | Name | Pin #
|
|
||||||
#-------------------------------------------------#
|
|
||||||
# 3V3 | - | 17 | 3.3V | VDD | 1 #
|
|
||||||
# - | 24 | 18 | DIO1 | FFIT | 2 # only when PCB jumper closed
|
|
||||||
# MOSI | 10 | 19 | MOSI | SDI | 3 #
|
|
||||||
# GND | - | 20 | GND | GND | 4 #
|
|
||||||
# MISO | 9 | 21 | MISO | SDO | 5 #
|
|
||||||
# - | 25 | 22 | DIO0 | nIRQ | 6 #
|
|
||||||
# SCKL | 11 | 23 | SCK | SCK | 7 #
|
|
||||||
# CE0 | 8 | 24 | NSS | nSEL | 8 #
|
|
||||||
# CE1 | 7 | 26 | DIO2 | nFFS | 10 # only when PCB jumper closed
|
|
||||||
#-------------------------------------------------#
|
|
||||||
|
|
||||||
# RaspyRFM twin module with 10-pin connector
|
|
||||||
# Connect to pins 17-26 on raspberry pi
|
|
||||||
#-------------------------------------------------#
|
|
||||||
# Raspi | Raspi | Raspi | RFM69 | RFM12 | PCB con #
|
|
||||||
# Name | GPIO | Pin | Name | Name | Pin #
|
|
||||||
#-------------------------------------------------#
|
|
||||||
# 3V3 | - | 17 | 3.3V | VDD | 1 #
|
|
||||||
# - | 24 | 18 | DIO0_2| FFIT | 2 #
|
|
||||||
# MOSI | 10 | 19 | MOSI | SDI | 3 #
|
|
||||||
# GND | - | 20 | GND | GND | 4 #
|
|
||||||
# MISO | 9 | 21 | MISO | SDO | 5 #
|
|
||||||
# - | 25 | 22 | DIO0_1| nIRQ | 6 #
|
|
||||||
# SCKL | 11 | 23 | SCK | SCK | 7 #
|
|
||||||
# CE0 | 8 | 24 | NSS1 | nSEL | 8 #
|
|
||||||
# CE1 | 7 | 26 | NSS2 | nFFS | 10 #
|
|
||||||
#-------------------------------------------------#
|
|
||||||
|
|
||||||
# RaspyRFM twin module with 12-pin connector
|
|
||||||
# Connect to pins 15-26 on raspberry pi
|
|
||||||
#-------------------------------------------------#
|
|
||||||
# Raspi | Raspi | Raspi | RFM69 | RFM12 | PCB con #
|
|
||||||
# Name | GPIO | Pin | Name | Name | Pin #
|
|
||||||
#-------------------------------------------------#
|
|
||||||
# - | 22 | 15 | DIO2_2| | 1 #
|
|
||||||
# - | 23 | 16 | DIO2_1| | 2 #
|
|
||||||
# 3V3 | - | 17 | 3.3V | VDD | 3 #
|
|
||||||
# - | 24 | 18 | DIO0_2| FFIT | 4 #
|
|
||||||
# MOSI | 10 | 19 | MOSI | SDI | 5 #
|
|
||||||
# GND | - | 20 | GND | GND | 6 #
|
|
||||||
# MISO | 9 | 21 | MISO | SDO | 7 #
|
|
||||||
# - | 25 | 22 | DIO0_1| nIRQ | 8 #
|
|
||||||
# SCKL | 11 | 23 | SCK | SCK | 9 #
|
|
||||||
# CE0 | 8 | 24 | NSS1 | nSEL | 10 #
|
|
||||||
# CE1 | 7 | 26 | NSS2 | nFFS | 12 #
|
|
||||||
#-------------------------------------------------#
|
|
||||||
|
|
||||||
#RFM69 registers
|
|
||||||
#common registers
|
|
||||||
RegFifo = 0x00
|
|
||||||
RegOpMode = 0x01
|
|
||||||
RegDataModul = 0x02
|
|
||||||
RegBitrateMsb = 0x03
|
|
||||||
RegBitrateLsb = 0x04
|
|
||||||
RegFdevMsb = 0x05
|
|
||||||
RegFdevLsb = 0x06
|
|
||||||
RegFrfMsb = 0x07
|
|
||||||
RegFrfMid = 0x08
|
|
||||||
RegFrfLsb = 0x09
|
|
||||||
RegOsc1 = 0x0A
|
|
||||||
RegAfcCtrl = 0x0B
|
|
||||||
RegListen1 = 0x0D
|
|
||||||
RegListen2 = 0x0E
|
|
||||||
RegListen3 = 0x0F
|
|
||||||
RegVersion = 0x10
|
|
||||||
#TX registers
|
|
||||||
RegPaLevel = 0x11
|
|
||||||
RegPaRamp = 0x12
|
|
||||||
RegOcp = 0x13
|
|
||||||
#RX registers
|
|
||||||
RegLna = 0x18
|
|
||||||
RegRxBw = 0x19
|
|
||||||
RegAfcBw = 0x1A
|
|
||||||
RegOokPeak = 0x1B
|
|
||||||
RegOokAvg = 0x1C
|
|
||||||
RegOokFix = 0x1D
|
|
||||||
RegAfcFei = 0x1E
|
|
||||||
RegAfcMsb = 0x1F
|
|
||||||
RegAfcLsb = 0x20
|
|
||||||
RegFeiMsb = 0x21
|
|
||||||
RegFeiLsb = 0x22
|
|
||||||
RegRssiConfig = 0x23
|
|
||||||
RegRssiValue = 0x24
|
|
||||||
#IRQ & pin mapping registers
|
|
||||||
RegDioMapping1 = 0x25
|
|
||||||
RegDioMapping2 = 0x26
|
|
||||||
RegIrqFlags1 = 0x27
|
|
||||||
RegIrqFlags2 = 0x28
|
|
||||||
RegRssiThresh = 0x29
|
|
||||||
RegRxTimeout1 = 0x2A
|
|
||||||
RegRxTimeout2 = 0x2B
|
|
||||||
#packet engine registers
|
|
||||||
RegPreambleMsb = 0x2C
|
|
||||||
RegPreambleLsb = 0x2D
|
|
||||||
RegSyncConfig = 0x2E
|
|
||||||
RegSyncValue1 = 0x2F
|
|
||||||
RegPacketConfig1 = 0x37
|
|
||||||
RegPayloadLength = 0x38
|
|
||||||
RegNodeAdrs = 0x39
|
|
||||||
RegBroadcastAdrs = 0x3A
|
|
||||||
RegAutoModes = 0x3B
|
|
||||||
RegFifoThresh = 0x3C
|
|
||||||
RegPacketConfig2 = 0x3D
|
|
||||||
RegTemp1 = 0x4E
|
|
||||||
RegTemp2 = 0x4F
|
|
||||||
RegTestLna = 0x58
|
|
||||||
RegTestDagc = 0x6F
|
|
||||||
RegTestAfc = 0x71
|
|
||||||
|
|
||||||
InterPacketRxDelay = 4 #Bitposition
|
|
||||||
RestartRx = 2
|
|
||||||
AutoRxRestartOn = 1
|
|
||||||
AesOn = 0
|
|
||||||
|
|
||||||
#Modulation type
|
|
||||||
OOK = 1
|
|
||||||
FSK = 0
|
|
||||||
|
|
||||||
#DcFree
|
|
||||||
DcFree_None = 0
|
|
||||||
DcFree_Manchester = 1
|
|
||||||
DcFree_Whitening = 2
|
|
||||||
|
|
||||||
#RFM69 modes
|
|
||||||
MODE_SLEEP = 0
|
|
||||||
MODE_STDBY = 1
|
|
||||||
MODE_FS = 2
|
|
||||||
MODE_TX = 3
|
|
||||||
MODE_RX = 4
|
|
||||||
|
|
||||||
#DIO packet mode
|
|
||||||
DIO0_PM_CRC = 0
|
|
||||||
DIO0_PM_PAYLOAD = 1
|
|
||||||
DIO0_PM_SYNC = 2
|
|
||||||
DIO0_PM_RSSI = 3
|
|
||||||
DIO0_PM_SENT = 0
|
|
||||||
DIO0_PM_TXDONE = 1
|
|
||||||
DIO0_PM_PLLLOCK = 3
|
|
||||||
|
|
||||||
|
|
||||||
class Rfm69(threading.Thread):
|
|
||||||
@staticmethod
|
|
||||||
def Test(cs):
|
|
||||||
spi = spidev.SpiDev()
|
|
||||||
spi.open(0, cs)
|
|
||||||
spi.max_speed_hz = 5000
|
|
||||||
#Testing presence of module
|
|
||||||
err = False
|
|
||||||
for i in range(0, 8):
|
|
||||||
spi.xfer2([(RegSyncValue1 + i) | 0x80, 0x55])
|
|
||||||
test = spi.xfer2([(RegSyncValue1 + i), 0x00])[1]
|
|
||||||
if test != 0x55:
|
|
||||||
err = True
|
|
||||||
break
|
|
||||||
temp = spi.xfer2([(RegSyncValue1 + i) | 0x80, 0xAA])
|
|
||||||
test = spi.xfer2([(RegSyncValue1 + i), 0x00])[1]
|
|
||||||
if test != 0xAA:
|
|
||||||
err = True
|
|
||||||
break
|
|
||||||
spi.close()
|
|
||||||
return not err
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, cs = 0, gpio_int = 25):
|
|
||||||
if not Rfm69.Test(cs):
|
|
||||||
print "ERROR! RFM69 not found"
|
|
||||||
return
|
|
||||||
|
|
||||||
self.__event = threading.Event()
|
|
||||||
self.__spi = spidev.SpiDev()
|
|
||||||
self.__spi.open(0, cs)
|
|
||||||
self.__spi.max_speed_hz=int(5E6)
|
|
||||||
self.__gpio_int = gpio_int
|
|
||||||
self.__mutex = threading.Lock()
|
|
||||||
self.__syncsize = 4
|
|
||||||
self.__fifothresh = 32
|
|
||||||
|
|
||||||
print("RFM69 found on CS " + str(cs))
|
|
||||||
GPIO.setmode(GPIO.BCM)
|
|
||||||
GPIO.setup(gpio_int, GPIO.IN)
|
|
||||||
GPIO.add_event_detect(gpio_int, GPIO.RISING, callback=self.__RfmIrq)
|
|
||||||
|
|
||||||
self.__SetMode(MODE_STDBY)
|
|
||||||
config = {}
|
|
||||||
|
|
||||||
#SET DEFAULTS
|
|
||||||
config[RegOpMode] = 0x04
|
|
||||||
config[RegDataModul] = 0x00
|
|
||||||
config[RegBitrateMsb] = 0x1A
|
|
||||||
config[RegBitrateMsb + 1] = 0x0B
|
|
||||||
config[RegFdevMsb] = 0x00
|
|
||||||
config[RegFdevMsb + 1] = 0x52
|
|
||||||
config[RegFrfMsb] = 0xE4
|
|
||||||
config[RegFrfMsb + 1] = 0xC0
|
|
||||||
config[RegFrfMsb + 2] = 0x00
|
|
||||||
config[RegOsc1] = 0x41
|
|
||||||
config[RegAfcCtrl] = 0x00
|
|
||||||
config[0x0C] = 0x02 # reserved
|
|
||||||
config[RegListen1] = 0x92
|
|
||||||
config[RegListen2] = 0xF5
|
|
||||||
config[RegListen3] = 0x20
|
|
||||||
config[RegVersion] = 0x24
|
|
||||||
config[RegPaLevel] = 0x9F
|
|
||||||
config[RegPaRamp] = 0x09
|
|
||||||
config[RegOcp] = 0x1A
|
|
||||||
config[0x17] = 0x9B # reserved
|
|
||||||
config[RegLna] = 0x88
|
|
||||||
config[RegRxBw] = 0x55
|
|
||||||
config[RegAfcBw] = 0x8B
|
|
||||||
config[RegOokPeak] = 0x40
|
|
||||||
config[RegOokAvg] = 0x80
|
|
||||||
config[RegOokFix] = 0x06
|
|
||||||
config[RegAfcFei] = 0x00
|
|
||||||
config[RegAfcMsb] = 0x00
|
|
||||||
config[RegAfcLsb] = 0x00
|
|
||||||
config[RegFeiMsb] = 0x00
|
|
||||||
config[RegFeiLsb] = 0x00
|
|
||||||
config[RegRssiConfig] = 0x02
|
|
||||||
config[RegDioMapping1] = 0x00
|
|
||||||
config[RegDioMapping2] = 0x05
|
|
||||||
config[RegIrqFlags1] = 0x80
|
|
||||||
config[RegIrqFlags2] = 0x10
|
|
||||||
config[RegRssiThresh] = 0xE4
|
|
||||||
config[RegRxTimeout1] = 0x00
|
|
||||||
config[RegRxTimeout2] = 0x00
|
|
||||||
config[RegPreambleMsb] = 0x00
|
|
||||||
config[RegPreambleLsb] = 0x00
|
|
||||||
config[RegSyncConfig] = 0x98
|
|
||||||
config[RegPacketConfig1] = 0x10
|
|
||||||
config[RegPayloadLength] = 0x40
|
|
||||||
config[RegNodeAdrs] = 0x00
|
|
||||||
config[RegBroadcastAdrs] = 0x00
|
|
||||||
config[RegAutoModes] = 0
|
|
||||||
config[RegFifoThresh] = 0x8F
|
|
||||||
config[RegPacketConfig2] = 0x02
|
|
||||||
config[RegTemp1] = 0x01
|
|
||||||
config[RegTemp2] = 0x00
|
|
||||||
config[RegTestLna] = 0x1B
|
|
||||||
config[RegTestDagc] = 0x30 #low beta 0
|
|
||||||
config[RegTestAfc] = 0x00
|
|
||||||
|
|
||||||
config[RegPacketConfig1] = 0x00 #Fixed length, CRC off, no adr
|
|
||||||
|
|
||||||
for key in config:
|
|
||||||
self.__WriteReg(key, config[key])
|
|
||||||
|
|
||||||
self.ModeStandBy()
|
|
||||||
threading.Thread.__init__(self)
|
|
||||||
print("Init complete.")
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while True:
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
def __RfmIrq(self, ch):
|
|
||||||
self.__event.set()
|
|
||||||
|
|
||||||
def __WriteReg(self, reg, val):
|
|
||||||
temp = self.__spi.xfer2([(reg & 0x7F) | 0x80, val & 0xFF])
|
|
||||||
|
|
||||||
def __WriteRegWord(self, reg, val):
|
|
||||||
self.__WriteReg(reg, (val >> 8) & 0xFF)
|
|
||||||
self.__WriteReg(reg + 1, val & 0xFF)
|
|
||||||
|
|
||||||
def __SetReg(self, reg, mask, val):
|
|
||||||
temp = self.ReadReg(reg) & (~mask)
|
|
||||||
temp |= val & mask
|
|
||||||
self.__WriteReg(reg, temp)
|
|
||||||
|
|
||||||
def __SetDioMapping(self, dio, mapping):
|
|
||||||
if ((dio >= 0) and (dio <=3)):
|
|
||||||
self.__SetReg(RegDioMapping1, 0xC0 >> (dio * 2), mapping << (6 - dio * 2))
|
|
||||||
elif (dio == 5):
|
|
||||||
self.__SetReg(RegDioMapping2, 0x03 << 4, mapping << 4)
|
|
||||||
|
|
||||||
def __SetMode(self, mode):
|
|
||||||
self.__WriteReg(RegOpMode, mode << 2)
|
|
||||||
self.__mode = mode
|
|
||||||
while ((self.ReadReg(RegIrqFlags1) & (1<<7)) == 0):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def ReadReg(self, reg):
|
|
||||||
temp = self.__spi.xfer2([reg & 0x7F, 0x00])
|
|
||||||
return temp[1]
|
|
||||||
|
|
||||||
def ReadFifoBurst(self, len):
|
|
||||||
temp = self.__spi.xfer2([0x00] + [0x00] * len)
|
|
||||||
return temp[1:]
|
|
||||||
|
|
||||||
def WriteFifoBurst(self, data):
|
|
||||||
self.__spi.xfer2([0x80] + list(data))
|
|
||||||
|
|
||||||
def ReadRegWord(self, reg):
|
|
||||||
temp = self.__spi.xfer2([reg & 0x7F, 0x00, 0x00])
|
|
||||||
return (temp[1] << 8) | (temp[2])
|
|
||||||
|
|
||||||
def ReadRssiValue(self):
|
|
||||||
return self.ReadReg(RegRssiValue)
|
|
||||||
|
|
||||||
def ModeStandBy(self):
|
|
||||||
self.__SetMode(MODE_STDBY)
|
|
||||||
|
|
||||||
def SetParams(self, **params):
|
|
||||||
self.__mutex.acquire()
|
|
||||||
self.__event.set()
|
|
||||||
for key in params:
|
|
||||||
value = params[key]
|
|
||||||
if key == "Freq":
|
|
||||||
fword = int(round(value * 1E6 / FSTEP))
|
|
||||||
self.__WriteReg(RegFrfMsb, fword >> 16)
|
|
||||||
self.__WriteReg(RegFrfMid, fword >> 8)
|
|
||||||
self.__WriteReg(RegFrfLsb, fword)
|
|
||||||
|
|
||||||
elif key == "TXPower":
|
|
||||||
pwr = int(value + 18)
|
|
||||||
self.__WriteReg(RegPaLevel, 0x80 | (pwr & 0x1F))
|
|
||||||
|
|
||||||
elif key == "Datarate":
|
|
||||||
rate = int(round(FXOSC / (value * 1000)))
|
|
||||||
self.__WriteRegWord(RegBitrateMsb, rate)
|
|
||||||
|
|
||||||
elif key == "Deviation":
|
|
||||||
dev = int(round(value * 1000 / FSTEP))
|
|
||||||
self.__WriteRegWord(RegFdevMsb, dev)
|
|
||||||
|
|
||||||
elif key == "ModulationType":
|
|
||||||
self.__SetReg(RegDataModul, 0x18, value << 3)
|
|
||||||
|
|
||||||
elif key == "ModulationsShaping":
|
|
||||||
self.__SetReg(RegDataModul, 0x03, value)
|
|
||||||
|
|
||||||
elif key == "SyncPattern":
|
|
||||||
conf = 0
|
|
||||||
self.__syncsize = len(value)
|
|
||||||
if (len(value)) > 0:
|
|
||||||
conf = ((len(value) - 1) & 0x07) << 3
|
|
||||||
conf |= 1<<7
|
|
||||||
else:
|
|
||||||
conf = 1<<6
|
|
||||||
self.__WriteReg(RegSyncConfig, conf)
|
|
||||||
for i, d in enumerate(value):
|
|
||||||
self.__WriteReg(RegSyncValue1 + i, d)
|
|
||||||
|
|
||||||
elif key == "Bandwidth":
|
|
||||||
RxBw = FXOSC / value / 1000 / 4
|
|
||||||
e = 0
|
|
||||||
while (RxBw > 32) and (e < 7):
|
|
||||||
e += 1
|
|
||||||
RxBw /= 2
|
|
||||||
RxBw = RxBw / 4 - 4
|
|
||||||
RxBw = max(RxBw, 0)
|
|
||||||
m = int(RxBw)
|
|
||||||
self.__SetReg(RegRxBw, 0x1F, m<<3 | e)
|
|
||||||
|
|
||||||
elif key == "AfcBandwidth":
|
|
||||||
RxBw = FXOSC / value / 1000 / 4
|
|
||||||
e = 0
|
|
||||||
while (RxBw > 32) and (e < 7):
|
|
||||||
e += 1
|
|
||||||
RxBw /= 2
|
|
||||||
RxBw = RxBw / 4 - 4
|
|
||||||
RxBw = max(RxBw, 0)
|
|
||||||
m = int(RxBw)
|
|
||||||
self.__SetReg(RegAfcBw, 0x1F, m<<3 | e)
|
|
||||||
|
|
||||||
elif key == "Preamble":
|
|
||||||
self.__WriteRegWord(RegPreambleMsb, value)
|
|
||||||
|
|
||||||
elif key == "LnaGain":
|
|
||||||
self.__SetReg(RegLna, 0x07, value)
|
|
||||||
|
|
||||||
elif key == "RssiThresh":
|
|
||||||
th = -(value * 2)
|
|
||||||
self.__WriteReg(RegRssiThresh, th)
|
|
||||||
|
|
||||||
elif key == "Dagc":
|
|
||||||
self.__WriteReg(RegDagc, value)
|
|
||||||
|
|
||||||
elif key == "AfcFei":
|
|
||||||
self.__WriteReg(RegAfcFei, value)
|
|
||||||
|
|
||||||
elif key == "Callback":
|
|
||||||
self.__Callback = value
|
|
||||||
|
|
||||||
elif key == "DcFree":
|
|
||||||
self.__SetReg(RegPacketConfig1, 3<<5, value<<5)
|
|
||||||
|
|
||||||
elif key == "OokThreshType":
|
|
||||||
self.__SetReg(RegOokPeak, 3<<6, value<<6)
|
|
||||||
|
|
||||||
elif key == "OokFixedThresh":
|
|
||||||
self.__WriteReg(RegOokFix, value)
|
|
||||||
|
|
||||||
elif key == "OokPeakThreshDec":
|
|
||||||
self.__SetReg(RegOokPeak, 7<<0, value)
|
|
||||||
|
|
||||||
else:
|
|
||||||
print("Unrecognized option >>" + key + "<<")
|
|
||||||
|
|
||||||
self.ModeStandBy();
|
|
||||||
self.__mutex.release()
|
|
||||||
|
|
||||||
def __WaitInt(self):
|
|
||||||
self.__event.clear()
|
|
||||||
if GPIO.input(self.__gpio_int):
|
|
||||||
return
|
|
||||||
while not self.__event.wait(0.5):
|
|
||||||
if GPIO.input(self.__gpio_int):
|
|
||||||
break
|
|
||||||
|
|
||||||
def WhitenHope(self, data):
|
|
||||||
lfsr = 0x3fe
|
|
||||||
for i, d in enumerate(data):
|
|
||||||
data[i] = data[i] ^ ((lfsr >> 2) & 0xFF)
|
|
||||||
#roll LFSR
|
|
||||||
for j in range(8):
|
|
||||||
if ((lfsr >> 5) ^ lfsr) & 0x10 != 0:
|
|
||||||
lfsr |= 1<<0
|
|
||||||
lfsr <<= 1
|
|
||||||
lfsr &= 0x3ff
|
|
||||||
|
|
||||||
def WhitenTI(self, data):
|
|
||||||
lfsr = 0x1ff
|
|
||||||
for i, d in enumerate(data):
|
|
||||||
data[i] = data[i] ^ (lfsr & 0xFF)
|
|
||||||
for i in range(8):
|
|
||||||
if ((lfsr >> 5) ^ lfsr) & 0x01 != 0:
|
|
||||||
lfsr |= 1<<9
|
|
||||||
lfsr >>= 1
|
|
||||||
|
|
||||||
def SendPacket(self, data):
|
|
||||||
self.__mutex.acquire()
|
|
||||||
self.__event.set()
|
|
||||||
self.ModeStandBy()
|
|
||||||
|
|
||||||
#flush FIFO
|
|
||||||
status = self.ReadReg(RegIrqFlags2)
|
|
||||||
while (status & 0x40 == 0x40):
|
|
||||||
self.ReadReg(RegFifo)
|
|
||||||
status = self.ReadReg(RegIrqFlags2)
|
|
||||||
|
|
||||||
self.__WriteReg(RegPayloadLength, 0) #unlimited length
|
|
||||||
self.__WriteReg(RegFifoThresh, 0x80 | self.__fifothresh) #start TX with 1st byte in FIFO
|
|
||||||
self.__SetDioMapping(0, DIO0_PM_SENT) #DIO0 -> PacketSent
|
|
||||||
self.__SetMode(MODE_TX)
|
|
||||||
|
|
||||||
l = min(len(data), 64)
|
|
||||||
while True:
|
|
||||||
self.WriteFifoBurst(data[:l])
|
|
||||||
data = data[l:]
|
|
||||||
if len(data) == 0:
|
|
||||||
break
|
|
||||||
while True:
|
|
||||||
status = self.ReadReg(RegIrqFlags2)
|
|
||||||
if (status & (1<<5)) == 0: #below fifothresh
|
|
||||||
l = min(len(data), self.__fifothresh)
|
|
||||||
break
|
|
||||||
if (status & (1<<7)) == 0: #space for at least 1 bytearray
|
|
||||||
l = 1
|
|
||||||
break
|
|
||||||
|
|
||||||
self.__WaitInt()
|
|
||||||
self.ModeStandBy()
|
|
||||||
self.__mutex.release()
|
|
||||||
|
|
||||||
def ReadFifoWait(self, length):
|
|
||||||
ret = []
|
|
||||||
while length > 0:
|
|
||||||
flags = self.ReadReg(RegIrqFlags2)
|
|
||||||
if ((flags & (1<<5)) != 0) and (length >= 32): #FIFO level?
|
|
||||||
ret += self.ReadFifoBurst(self.__fifothresh)
|
|
||||||
length -= self.__fifothresh
|
|
||||||
if (flags & (1<<6)) != 0: #FIFO not empty?
|
|
||||||
ret.append(self.ReadReg(RegFifo))
|
|
||||||
length -= 1
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def GetNoiseFloor(self):
|
|
||||||
self.__mutex.acquire()
|
|
||||||
#save values
|
|
||||||
rssithresh = self.ReadReg(RegRssiThresh)
|
|
||||||
ookthresh = self.ReadReg(RegOokFix)
|
|
||||||
sync = self.ReadReg(RegSyncConfig)
|
|
||||||
|
|
||||||
self.__WriteReg(RegRssiThresh, 240)
|
|
||||||
self.__WriteReg(RegSyncConfig, 1<<6) #no sync, always fill FIFO
|
|
||||||
self.__WriteReg(RegPayloadLength, 0) #unlimited length
|
|
||||||
self.__SetMode(MODE_RX)
|
|
||||||
thresh = 40
|
|
||||||
while True:
|
|
||||||
self.__WriteReg(RegOokFix, thresh)
|
|
||||||
for i in range(150):
|
|
||||||
b = self.ReadFifoWait()
|
|
||||||
if b <> 0:
|
|
||||||
thresh += 1
|
|
||||||
break;
|
|
||||||
if i == 149:
|
|
||||||
break;
|
|
||||||
|
|
||||||
#restore registers
|
|
||||||
self.__WriteReg(RegRssiThresh, rssithresh)
|
|
||||||
self.__WriteReg(RegOokFix, ookthresh)
|
|
||||||
self.__WriteReg(RegSyncConfig, sync)
|
|
||||||
self.ModeStandBy()
|
|
||||||
self.__mutex.release()
|
|
||||||
return thresh
|
|
||||||
|
|
||||||
def __StartRx(self):
|
|
||||||
self.__SetDioMapping(2, 1) #DIO2 -> DATA
|
|
||||||
self.__mutex.acquire()
|
|
||||||
while True:
|
|
||||||
self.__WriteReg(RegPayloadLength, 0) #unlimited length
|
|
||||||
self.__WriteReg(RegFifoThresh, self.__fifothresh)
|
|
||||||
if self.__syncsize > 0:
|
|
||||||
self.__SetDioMapping(0, DIO0_PM_SYNC) #DIO0 -> SyncAddress
|
|
||||||
else:
|
|
||||||
self.__SetDioMapping(0, DIO0_PM_RSSI) #DIO0 -> RSSI
|
|
||||||
self.__SetMode(MODE_RX)
|
|
||||||
self.__mutex.release()
|
|
||||||
self.__WaitInt()
|
|
||||||
self.__mutex.acquire()
|
|
||||||
if self.__mode == MODE_RX:
|
|
||||||
break;
|
|
||||||
|
|
||||||
def StartRx(self, cb):
|
|
||||||
self.__StartRx()
|
|
||||||
cb()
|
|
||||||
self.ModeStandBy()
|
|
||||||
self.__mutex.release()
|
|
||||||
|
|
||||||
def ReceivePacket(self, length):
|
|
||||||
self.__StartRx()
|
|
||||||
result = self.ReadFifoWait(length)
|
|
||||||
|
|
||||||
rssi = -self.ReadReg(RegRssiValue) / 2
|
|
||||||
afc = self.ReadReg(RegAfcMsb) << 8
|
|
||||||
afc = afc | self.ReadReg(RegAfcLsb)
|
|
||||||
|
|
||||||
if afc >= 0x8000:
|
|
||||||
afc = afc - 0x10000
|
|
||||||
|
|
||||||
self.ModeStandBy()
|
|
||||||
self.__mutex.release()
|
|
||||||
return (result, rssi, afc)
|
|
Loading…
Reference in a new issue