# 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 # wassyn 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): """Main SPI data transfer routine. A 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 range(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 range(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 range(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 range(0x44): # res = -1 v = xfr1(0, x, 0) print('@', format(x, '02X')) print(' ', ' $', format(v, '02X')) def GetOpMode(): # register 1 controls the RFM IC mode. eg FSK/LORA/SLEEP/STANDBY/TX/RX x = xfr1(0, 1, 0) return x def GetRegBitRate(): h = xfr1(0, 2, 0) l_c = xfr1(0, 3, 0) return h * 256 + l_c def GetCarrierFreq(): h = readReg(6) # MSB m = readReg(7) l_a = readReg(8) # LSB return ((h * 256.0 + m) * 256.0 + l_a) * 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_b = r - 256 * m writeReg(6, h) # MSB writeReg(7, m) writeReg(8, l_b) # 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()