160 lines
3.3 KiB
Python
160 lines
3.3 KiB
Python
# rfmtest.py - performs SPI comms on raspberry pi to RFM95 IC. Paul Richarsd pi@sosgez.co.uk
|
|
#
|
|
# NB this is python2 code. SPI data transfer does not use external driver.
|
|
#
|
|
import RPi.GPIO as GPIO
|
|
from time import sleep
|
|
#define GPIO board pin assignments for comms
|
|
|
|
def swait(): # just a short delay.
|
|
sleep(0.001)
|
|
|
|
def initports():
|
|
global gclk,gout,gin,ginit,gen
|
|
ginit=15 # was 3 # chip reset
|
|
gclk=23 # CLOCK
|
|
gout=19 # MOSI
|
|
gin=21 # MISO
|
|
gen=24 # chip enable (active low)
|
|
GPIO.setmode(GPIO.BOARD)
|
|
GPIO.setup(ginit,GPIO.OUT)
|
|
GPIO.setup(gclk,GPIO.OUT)
|
|
GPIO.setup(gout,GPIO.OUT)
|
|
GPIO.setup(gen,GPIO.OUT)
|
|
GPIO.setup(gin,GPIO.IN,pull_up_down = GPIO.PUD_UP)
|
|
swait()
|
|
# set default state
|
|
GPIO.output(ginit,0)
|
|
GPIO.output(gclk,0)
|
|
GPIO.output(gout,0)
|
|
GPIO.output(gen,1)
|
|
GPIO.output(ginit,1)
|
|
# READY FOR 1 TRANSFER
|
|
|
|
def xfr1(iswrite,address,data1): # SPI data transfer main routine. Single byte is transferred out and in
|
|
global gen,gout,gin,gclk
|
|
GPIO.output(gen,0)
|
|
swait()
|
|
swait()
|
|
d1 = address & 127
|
|
if iswrite>0:
|
|
d1 = d1 | 128
|
|
swait()
|
|
m=128 # send MSB first
|
|
for bit in xrange(8):
|
|
if((d1 & m) >0):
|
|
GPIO.output(gout,1)
|
|
else:
|
|
GPIO.output(gout,0)
|
|
swait()
|
|
GPIO.output(gclk,1)
|
|
swait()
|
|
GPIO.output(gclk,0)
|
|
swait()
|
|
m = (m >> 1) & 127
|
|
m = 128
|
|
d2 = data1
|
|
res = 0
|
|
for bit in xrange(8):
|
|
if((d2 & m)>0):
|
|
GPIO.output(gout,1)
|
|
else:
|
|
GPIO.output(gout,0)
|
|
swait()
|
|
res = res << 1
|
|
GPIO.output(gclk,1)
|
|
if(GPIO.input(gin)>0):
|
|
res = res | 1
|
|
swait()
|
|
GPIO.output(gclk,0)
|
|
swait()
|
|
m = m >> 1
|
|
GPIO.output(gen,1)
|
|
swait()
|
|
return res
|
|
|
|
|
|
def writeReg(where,data):
|
|
xfr1(1,where,data)
|
|
|
|
def readReg(where):
|
|
return xfr1(0,where,0)
|
|
|
|
def ex1(): # just exercising a pin so I can see it on scope
|
|
global gclk,gout,gin,gen,ginit
|
|
dt = 0.01
|
|
port = gen
|
|
for x in xrange(100):
|
|
print 1
|
|
GPIO.output(port,1)
|
|
sleep(dt)
|
|
print 0
|
|
GPIO.output(port,0)
|
|
sleep(dt)
|
|
|
|
def readregs():
|
|
print "Reg Value"
|
|
for x in xrange(0x44):
|
|
res = -1
|
|
v = xfr1(0,x,0)
|
|
print '@',format(x,'02X'),
|
|
print ' ',' $',format(v,'02X')
|
|
|
|
|
|
def GetOpMode():
|
|
x = xfr1(0,1,0) # register 1 controls the RFM IC mode. eg FSK/LORA/SLEEP/STANDBY/TX/RX
|
|
return x
|
|
|
|
def GetRegBitRate():
|
|
h = xfr1(0,2,0)
|
|
l = xfr1(0,3,0)
|
|
return h*256 + l
|
|
|
|
def GetCarrierFreq():
|
|
h = readReg(6) # MSB
|
|
m = readReg(7)
|
|
l = readReg(8) # LSB
|
|
return ((h*256.0+m)*256.0 + l)*61.035 # in Hz
|
|
|
|
def SetFreq(mhz):
|
|
f = int(mhz*1e6/61.035)
|
|
h = int(f/65536.0)
|
|
r = f-h*65536
|
|
m = int(r/256)
|
|
l = r-256*m
|
|
writeReg(6,h) # MSB
|
|
writeReg(7,m)
|
|
writeReg(8,l) # LSB
|
|
return
|
|
|
|
def GetAGC():
|
|
return xfr1(0,0x61,0) # or use readReg(0x61) etc
|
|
|
|
def GetAGC1():
|
|
return xfr1(0,0x62,0)
|
|
|
|
def GetAGC2():
|
|
return xfr1(0,0x63,0)
|
|
|
|
def GetAGC3():
|
|
return xfr1(0,0x64,0)
|
|
|
|
def ShowRegs():
|
|
print' Some regsiter examples'
|
|
print 'Op Mode ',GetOpMode()
|
|
print 'Bit Rate ', GetRegBitRate()
|
|
print 'Default carrier freq ',GetCarrierFreq()/1e6, ' MHz'
|
|
print 'AGC regs 61-64 : ',format(GetAGC(),'02X'),format(GetAGC1(),'02X'),format(GetAGC2(),'02X'),format(GetAGC3(),'02X')
|
|
|
|
def main():
|
|
print ('Simple GPIO SPI without drivers')
|
|
sleep(0.5) # secs
|
|
initports()
|
|
readregs() # shows massive list, before any changes are made
|
|
ShowRegs() # shows a few interesting registers
|
|
SetFreq(868.1) # now write to registers 6,7,8
|
|
print 'New carrier freq ',GetCarrierFreq()/1e6, ' MHz'
|
|
print ("*** Finished")
|
|
GPIO.cleanup()
|
|
main()
|