add pinouts
use FIFO burst transfers fix hangups add whitening routines add DcFree options
This commit is contained in:
parent
8562a1520b
commit
685c53e2ff
1 changed files with 108 additions and 52 deletions
160
rfm69.py
160
rfm69.py
|
@ -6,22 +6,58 @@ import time
|
||||||
FXOSC = 32E6
|
FXOSC = 32E6
|
||||||
FSTEP = FXOSC / (1<<19)
|
FSTEP = FXOSC / (1<<19)
|
||||||
|
|
||||||
|
|
||||||
#------ Raspberry RFM Module connection -----
|
#------ Raspberry RFM Module connection -----
|
||||||
# Connect RaspyRFM module to pins 17-26 on raspberry pi
|
# RaspyRFM single module
|
||||||
|
# Connect to pins 17-26 on raspberry pi
|
||||||
#-------------------------------------------------#
|
#-------------------------------------------------#
|
||||||
# Raspi | Raspi | Raspi | RFM69 | RFM12 | PCB con #
|
# Raspi | Raspi | Raspi | RFM69 | RFM12 | PCB con #
|
||||||
# Name | GPIO | Pin | Name | Name | Pin #
|
# Name | GPIO | Pin | Name | Name | Pin #
|
||||||
#-------------------------------------------------#
|
#-------------------------------------------------#
|
||||||
# 3V3 | - | 17 | 3.3V | VDD | 1 #
|
# 3V3 | - | 17 | 3.3V | VDD | 1 #
|
||||||
# - | 24 | 18 | DIO1 | FFIT | 2 # only when PCB jumper closed, DIO0/nIRQ on 2nd modul!
|
# - | 24 | 18 | DIO1 | FFIT | 2 # only when PCB jumper closed
|
||||||
# MOSI | 10 | 19 | MOSI | SDI | 3 #
|
# MOSI | 10 | 19 | MOSI | SDI | 3 #
|
||||||
# GND | - | 20 | GND | GND | 4 #
|
# GND | - | 20 | GND | GND | 4 #
|
||||||
# MISO | 9 | 21 | MISO | SDO | 5 #
|
# MISO | 9 | 21 | MISO | SDO | 5 #
|
||||||
# - | 25 | 22 | DIO0 | nIRQ | 6 #
|
# - | 25 | 22 | DIO0 | nIRQ | 6 #
|
||||||
# SCKL | 11 | 23 | SCK | SCK | 7 #
|
# SCKL | 11 | 23 | SCK | SCK | 7 #
|
||||||
# CE0 | 8 | 24 | NSS | nSEL | 8 #
|
# CE0 | 8 | 24 | NSS | nSEL | 8 #
|
||||||
# CE1 | 7 | 26 | DIO2 | nFFS | 10 # only when PCB jumper closed, NSS/nFFS on 2nd modul!
|
# 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
|
#RFM69 registers
|
||||||
|
@ -107,6 +143,16 @@ MODE_FS = 2
|
||||||
MODE_TX = 3
|
MODE_TX = 3
|
||||||
MODE_RX = 4
|
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):
|
class Rfm69(threading.Thread):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def Test(cs):
|
def Test(cs):
|
||||||
|
@ -141,10 +187,10 @@ class Rfm69(threading.Thread):
|
||||||
self.__spi.max_speed_hz=int(5E6)
|
self.__spi.max_speed_hz=int(5E6)
|
||||||
self.__gpio_int = gpio_int
|
self.__gpio_int = gpio_int
|
||||||
self.__mutex = threading.Lock()
|
self.__mutex = threading.Lock()
|
||||||
self.__rxmode = False
|
|
||||||
self.__syncsize = 4
|
self.__syncsize = 4
|
||||||
|
self.__fifothresh = 32
|
||||||
|
|
||||||
print "RFM69 found on CS", cs
|
print("RFM69 found on CS " + str(cs))
|
||||||
GPIO.setmode(GPIO.BCM)
|
GPIO.setmode(GPIO.BCM)
|
||||||
GPIO.setup(gpio_int, GPIO.IN)
|
GPIO.setup(gpio_int, GPIO.IN)
|
||||||
GPIO.add_event_detect(gpio_int, GPIO.RISING, callback=self.__RfmIrq)
|
GPIO.add_event_detect(gpio_int, GPIO.RISING, callback=self.__RfmIrq)
|
||||||
|
@ -176,7 +222,7 @@ class Rfm69(threading.Thread):
|
||||||
config[RegLna] = 0x88
|
config[RegLna] = 0x88
|
||||||
config[RegRxBw] = 0x55
|
config[RegRxBw] = 0x55
|
||||||
config[RegAfcBw] = 0x8B
|
config[RegAfcBw] = 0x8B
|
||||||
config[RegOokPeak] = 0x40
|
config[RegOokPeak] = 0x40
|
||||||
config[RegOokAvg] = 0x80
|
config[RegOokAvg] = 0x80
|
||||||
config[RegOokFix] = 0x06
|
config[RegOokFix] = 0x06
|
||||||
config[RegAfcFei] = 0x00
|
config[RegAfcFei] = 0x00
|
||||||
|
@ -212,7 +258,6 @@ class Rfm69(threading.Thread):
|
||||||
config[RegPacketConfig2] = 0 #1<<AutoRxRestartOn
|
config[RegPacketConfig2] = 0 #1<<AutoRxRestartOn
|
||||||
|
|
||||||
for key in config:
|
for key in config:
|
||||||
v = self.ReadReg(key)
|
|
||||||
self.__WriteReg(key, config[key])
|
self.__WriteReg(key, config[key])
|
||||||
|
|
||||||
self.ModeStandBy()
|
self.ModeStandBy()
|
||||||
|
@ -246,6 +291,7 @@ class Rfm69(threading.Thread):
|
||||||
|
|
||||||
def __SetMode(self, mode):
|
def __SetMode(self, mode):
|
||||||
self.__WriteReg(RegOpMode, mode << 2)
|
self.__WriteReg(RegOpMode, mode << 2)
|
||||||
|
self.__mode = mode
|
||||||
while ((self.ReadReg(RegIrqFlags1) & (1<<7)) == 0):
|
while ((self.ReadReg(RegIrqFlags1) & (1<<7)) == 0):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -253,6 +299,13 @@ class Rfm69(threading.Thread):
|
||||||
temp = self.__spi.xfer2([reg & 0x7F, 0x00])
|
temp = self.__spi.xfer2([reg & 0x7F, 0x00])
|
||||||
return temp[1]
|
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] + data)
|
||||||
|
|
||||||
def ReadRegWord(self, reg):
|
def ReadRegWord(self, reg):
|
||||||
temp = self.__spi.xfer2([reg & 0x7F, 0x00, 0x00])
|
temp = self.__spi.xfer2([reg & 0x7F, 0x00, 0x00])
|
||||||
return (temp[1] << 8) | (temp[2])
|
return (temp[1] << 8) | (temp[2])
|
||||||
|
@ -260,12 +313,8 @@ class Rfm69(threading.Thread):
|
||||||
def ReadRssiValue(self):
|
def ReadRssiValue(self):
|
||||||
self.__WriteReg(RegRssiConfig, 1<<0)
|
self.__WriteReg(RegRssiConfig, 1<<0)
|
||||||
r = self.ReadReg(RegRssiConfig)
|
r = self.ReadReg(RegRssiConfig)
|
||||||
#print(hex(r))
|
|
||||||
while ((r & (1<<1)) == 0):
|
while ((r & (1<<1)) == 0):
|
||||||
# print(hex(r))
|
|
||||||
r = self.ReadReg(RegRssiConfig)
|
r = self.ReadReg(RegRssiConfig)
|
||||||
# time.sleep(0.05)
|
|
||||||
pass
|
|
||||||
return self.ReadReg(RegRssiValue)
|
return self.ReadReg(RegRssiValue)
|
||||||
|
|
||||||
def ModeStandBy(self):
|
def ModeStandBy(self):
|
||||||
|
@ -353,15 +402,12 @@ class Rfm69(threading.Thread):
|
||||||
elif key == "Callback":
|
elif key == "Callback":
|
||||||
self.__Callback = value
|
self.__Callback = value
|
||||||
|
|
||||||
elif key == "CallbackSync":
|
|
||||||
self.__CallbackSync = value
|
|
||||||
|
|
||||||
elif key == "DcFree":
|
elif key == "DcFree":
|
||||||
self.__SetReg(RegPacketConfig1, 3<<5, value<<5)
|
self.__SetReg(RegPacketConfig1, 3<<5, value<<5)
|
||||||
|
|
||||||
elif key == "OokThreshType":
|
elif key == "OokThreshType":
|
||||||
self.__SetReg(RegOokPeak, 3<<6, value<<6)
|
self.__SetReg(RegOokPeak, 3<<6, value<<6)
|
||||||
|
|
||||||
elif key == "OokFixedThresh":
|
elif key == "OokFixedThresh":
|
||||||
self.__WriteReg(RegOokFix, value)
|
self.__WriteReg(RegOokFix, value)
|
||||||
|
|
||||||
|
@ -369,18 +415,16 @@ class Rfm69(threading.Thread):
|
||||||
print("Unrecognized option >>" + key + "<<")
|
print("Unrecognized option >>" + key + "<<")
|
||||||
|
|
||||||
self.ModeStandBy();
|
self.ModeStandBy();
|
||||||
self.__rxmode = False
|
|
||||||
self.__mutex.release()
|
self.__mutex.release()
|
||||||
|
|
||||||
def __WaitInt(self):
|
def __WaitInt(self):
|
||||||
self.__event.clear()
|
self.__event.clear()
|
||||||
if GPIO.input(self.__gpio_int):
|
if GPIO.input(self.__gpio_int):
|
||||||
return
|
return
|
||||||
while not self.__event.wait(0.1):
|
while not self.__event.wait(0.5):
|
||||||
if GPIO.input(self.__gpio_int):
|
if GPIO.input(self.__gpio_int):
|
||||||
print("GPIO high!")
|
|
||||||
break
|
break
|
||||||
|
|
||||||
def WhitenHope(self, data):
|
def WhitenHope(self, data):
|
||||||
lfsr = 0x3fe
|
lfsr = 0x3fe
|
||||||
for i, d in enumerate(data):
|
for i, d in enumerate(data):
|
||||||
|
@ -391,7 +435,7 @@ class Rfm69(threading.Thread):
|
||||||
lfsr |= 1<<0
|
lfsr |= 1<<0
|
||||||
lfsr <<= 1
|
lfsr <<= 1
|
||||||
lfsr &= 0x3ff
|
lfsr &= 0x3ff
|
||||||
|
|
||||||
def WhitenTI(self, data):
|
def WhitenTI(self, data):
|
||||||
lfsr = 0x1ff
|
lfsr = 0x1ff
|
||||||
for i, d in enumerate(data):
|
for i, d in enumerate(data):
|
||||||
|
@ -412,40 +456,49 @@ class Rfm69(threading.Thread):
|
||||||
self.ReadReg(RegFifo)
|
self.ReadReg(RegFifo)
|
||||||
status = self.ReadReg(RegIrqFlags2)
|
status = self.ReadReg(RegIrqFlags2)
|
||||||
|
|
||||||
self.__WriteReg(RegPayloadLength, 0)
|
self.__WriteReg(RegPayloadLength, 0) #unlimited length
|
||||||
self.__SetDioMapping(0, 0) #DIO0 -> PacketSent
|
self.__WriteReg(RegFifoThresh, 0x80 | self.__fifothresh) #start TX with 1st byte in FIFO
|
||||||
self.__WriteReg(RegOpMode, MODE_TX << 2) #TX Mode
|
self.__SetDioMapping(0, DIO0_PM_SENT) #DIO0 -> PacketSent
|
||||||
|
self.__SetMode(MODE_TX)
|
||||||
|
|
||||||
for i, d in enumerate(data):
|
l = min(len(data), 64)
|
||||||
self.__WriteReg(RegFifo, d)
|
while True:
|
||||||
if i>60:
|
self.WriteFifoBurst(data[:l])
|
||||||
|
data = data[l:]
|
||||||
|
if len(data) == 0:
|
||||||
|
break
|
||||||
|
while True:
|
||||||
status = self.ReadReg(RegIrqFlags2)
|
status = self.ReadReg(RegIrqFlags2)
|
||||||
#check FifoFull
|
if (status & (1<<5)) == 0: #below fifothresh
|
||||||
while (status & 0x80) == 0x80:
|
l = min(len(data), self.__fifothresh)
|
||||||
status = self.ReadReg(RegIrqFlags2)
|
break
|
||||||
|
if (status & (1<<7)) == 0: #space for at least 1 bytearray
|
||||||
|
l = 1
|
||||||
|
break
|
||||||
|
|
||||||
#wait packet sent
|
|
||||||
self.__WaitInt()
|
self.__WaitInt()
|
||||||
self.ModeStandBy()
|
self.ModeStandBy()
|
||||||
self.__rxmode = False
|
|
||||||
self.__mutex.release()
|
self.__mutex.release()
|
||||||
|
|
||||||
def ReadFifoWait(self, length):
|
def ReadFifoWait(self, length):
|
||||||
ret = []
|
ret = []
|
||||||
while length > 0:
|
while length > 0:
|
||||||
flags = self.ReadReg(RegIrqFlags2)
|
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?
|
if (flags & (1<<6)) != 0: #FIFO not empty?
|
||||||
ret.append(self.ReadReg(RegFifo))
|
ret.append(self.ReadReg(RegFifo))
|
||||||
length -= 1
|
length -= 1
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def GetNoiseFloor(self):
|
def GetNoiseFloor(self):
|
||||||
self.__mutex.acquire()
|
self.__mutex.acquire()
|
||||||
#save values
|
#save values
|
||||||
rssithresh = self.ReadReg(RegRssiThresh)
|
rssithresh = self.ReadReg(RegRssiThresh)
|
||||||
ookthresh = self.ReadReg(RegOokFix)
|
ookthresh = self.ReadReg(RegOokFix)
|
||||||
sync = self.ReadReg(RegSyncConfig)
|
sync = self.ReadReg(RegSyncConfig)
|
||||||
|
|
||||||
self.__WriteReg(RegRssiThresh, 240)
|
self.__WriteReg(RegRssiThresh, 240)
|
||||||
self.__WriteReg(RegSyncConfig, 1<<6) #no sync, always fill FIFO
|
self.__WriteReg(RegSyncConfig, 1<<6) #no sync, always fill FIFO
|
||||||
self.__WriteReg(RegPayloadLength, 0) #unlimited length
|
self.__WriteReg(RegPayloadLength, 0) #unlimited length
|
||||||
|
@ -460,7 +513,7 @@ class Rfm69(threading.Thread):
|
||||||
break;
|
break;
|
||||||
if i == 149:
|
if i == 149:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#restore registers
|
#restore registers
|
||||||
self.__WriteReg(RegRssiThresh, rssithresh)
|
self.__WriteReg(RegRssiThresh, rssithresh)
|
||||||
self.__WriteReg(RegOokFix, ookthresh)
|
self.__WriteReg(RegOokFix, ookthresh)
|
||||||
|
@ -469,37 +522,40 @@ class Rfm69(threading.Thread):
|
||||||
self.__mutex.release()
|
self.__mutex.release()
|
||||||
return thresh
|
return thresh
|
||||||
|
|
||||||
def ReceivePacket(self, length):
|
def __StartRx(self):
|
||||||
|
self.__SetDioMapping(2, 1) #DIO2 -> DATA
|
||||||
self.__mutex.acquire()
|
self.__mutex.acquire()
|
||||||
while True:
|
while True:
|
||||||
self.__WriteReg(RegPayloadLength, length)
|
self.__WriteReg(RegPayloadLength, 0) #unlimited lendth
|
||||||
|
self.__WriteReg(RegFifoThresh, self.__fifothresh)
|
||||||
if self.__syncsize > 0:
|
if self.__syncsize > 0:
|
||||||
self.__SetDioMapping(0, 2) #DIO0 -> SyncAddress
|
self.__SetDioMapping(0, DIO0_PM_SYNC) #DIO0 -> SyncAddress
|
||||||
else:
|
else:
|
||||||
self.__SetDioMapping(0, 3) #DIO0 -> RSSI
|
self.__SetDioMapping(0, DIO0_PM_RSSI) #DIO0 -> RSSI
|
||||||
print("goto rx")
|
|
||||||
self.__SetMode(MODE_RX)
|
self.__SetMode(MODE_RX)
|
||||||
self.__rxmode = True
|
|
||||||
self.__mutex.release()
|
self.__mutex.release()
|
||||||
self.__WaitInt()
|
self.__WaitInt()
|
||||||
self.__mutex.acquire()
|
self.__mutex.acquire()
|
||||||
if self.__rxmode == True:
|
if self.__mode == MODE_RX:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
rssi = -self.ReadReg(RegRssiValue) / 2
|
def StartRx(self, cb):
|
||||||
|
self.__StartRx()
|
||||||
|
cb()
|
||||||
|
self.ModeStandBy()
|
||||||
|
self.__mutex.release()
|
||||||
|
|
||||||
|
def ReceivePacket(self, length):
|
||||||
|
self.__StartRx()
|
||||||
afc = self.ReadReg(RegAfcMsb) << 8
|
afc = self.ReadReg(RegAfcMsb) << 8
|
||||||
afc = afc | self.ReadReg(RegAfcLsb)
|
afc = afc | self.ReadReg(RegAfcLsb)
|
||||||
if afc >= 0x8000:
|
|
||||||
afc = afc - 0x10000
|
|
||||||
|
|
||||||
if hasattr(self, "_Rfm69__CallbackSync"):
|
|
||||||
self.__CallbackSync()
|
|
||||||
self.ModeStandBy()
|
|
||||||
self.__mutex.release()
|
|
||||||
return
|
|
||||||
|
|
||||||
result = self.ReadFifoWait(length)
|
result = self.ReadFifoWait(length)
|
||||||
|
|
||||||
|
rssi = -self.ReadReg(RegRssiValue) / 2
|
||||||
|
if afc >= 0x8000:
|
||||||
|
afc = afc - 0x10000
|
||||||
|
|
||||||
self.ModeStandBy()
|
self.ModeStandBy()
|
||||||
self.__mutex.release()
|
self.__mutex.release()
|
||||||
return (result, rssi, afc)
|
return (result, rssi, afc)
|
||||||
|
|
Loading…
Reference in a new issue