'18F1320 4MHz INT Button send then receive 081016 1100 Define SIMULATION_WAITMS_VALUE = 1 'else 0 for PIC Define CLOCK_FREQUENCY = 4 'Be sure to REM out the line "__CONFIG _CONFIG1H, _XT_OSC_1H" in the \PBP\18F1320.INC file! '@ __CONFIG _CONFIG1H, _INTIO2_OSC_1H '@ __CONFIG _CONFIG3H, _MCLRE_OFF_3H Define CONFIG1L = 0x00 Define CONFIG1H = 0x01 Define CONFIG2L = 0x0e Define CONFIG2H = 0x00 Define CONFIG3L = 0x00 Define CONFIG3H = 0x00 Define CONFIG4L = 0x80 Define CONFIG4H = 0x00 Define CONFIG5L = 0x03 Define CONFIG5H = 0xc0 Define CONFIG6L = 0x03 Define CONFIG6H = 0xe0 Define CONFIG7L = 0x03 Define CONFIG7H = 0x40 '**************************************************************** '* Name : Transceiver.pbp * '* Author : Paul R. Steinmeyer * '* Notice : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] * '* : All Rights Reserved * '* Date : 11/02/2010 * '* Version : 1.0 * '* Notes : Target uC: 16F88, using 18F1320 * '* : Interface with RFM22 * '* : Waits in RX Mode unless button is pressed, at * '* : which point it transmits the packet and returns * '* : to RX mode. * '* : At any valid packet reception the LED blinks * '* : * '* : Un-rem lines with SEROUT2 for debugging serial * '* : transmissions at 9600 baud * '* : * '* : * '**************************************************************** '------------------------------------------------------------------------------------------------------------------------------------ '# Name |I/O| Alias | Var | Description '------------------------------------------------------------------------------------------------------------------------------------ '1 RA0/AN0 |D 1| nButton | | Goes low when button is pressed '2 RA1/AN1 |D 0| LED | | LED on when high '3 RA4/T0CKI |D 1| | | N/C '4 RA5/MCLR |D 1| | | N/C '5 Vss | | | | Ground '6 RA2/AN2 |D 1| | | N/C '7 RA3/AN3 |D 1| | | N/C '8 RB0/AN4 |D 1| nIRQ | | Goes low on interrupt from RFM '9 RB1/TX | 0| nSel | | Bring low to select RFM '------------------------------------------------------------------------------------------------------------------------------------ '10 RB4/RX |D 1|SDO | | Input from RFM output '11 RB5/SS |D 0|TX_ANT | | Selector for TX Mode '12 RB6/T1CKI |D 0|RX_ANT | | Selector for RX Mode '13 RB7 |D 0| | | N/C '14 Vdd | | | | +3V '15 RA6/OSC2 |D 1| | | N/C '16 RA7/OSC1 |D 1| | | N/C '17 RB2 |D 0|SCK | | Clock signal to RFM '18 RB3 |D 0|SDI | | Output to RFM input '------------------------------------------------------------------------------------------------------------------------------------ PORTA = %110111 TRISA = %000001 PORTB = %000010 TRISB = %010001 '********** 'DEFINES '********** 'Define osc 4 '*********** 'CONSTANTS '*********** 'packetsize con 3>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.. '**************** 'Hardware Setup '**************** 'All Ports Digital 'un-rem this line for 18F1320... ADCON1 = $7f '...or un-rem these two for 16F88 'ANSEL = 0 'CMCON = 7 'OSCCON = 100000 '4MHz>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. PORTA = %110111 TRISA = %000001 PORTB = %000010 TRISB = %010001 '********* 'ALIASES (SYMBOL) '********* 'nbutton var PORTA.0>>>>>>>>>>>>>>>>>>>>>>>>>>>. 'led var PORTA.1>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'sdo var PORTB.4>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'sdi var PORTB.3>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'sck var PORTB.2>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'nsel var PORTB.1>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'nirq var PORTB.0>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'tx_ant var PORTB.5>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'rx_ant var PORTB.6>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '*********** 'VARIABLES '*********** 'naddress var Byte>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'noutdata var Byte>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'nindata var Byte>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'nstatus1 var Byte>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'nstatus2 var Byte>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'i var Byte>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'anrxbuf var Byte[35] 'at least 2x the packet length>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'antxbuf var Byte[packetsize]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'nchecksum var Byte>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '********* Symbol nbutton = PORTA.0 Symbol led = PORTA.1 Symbol sdo = PORTB.4 Symbol sdi = PORTB.3 Symbol sck = PORTB.2 Symbol nsel = PORTB.1 Symbol nirq = PORTB.0 Symbol tx_ant = PORTB.5 Symbol rx_ant = PORTB.6 '*********** 'VARIABLES '*********** '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Dim packetsize As Byte Dim txi As Byte '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Dim naddress As Byte Dim noutdata As Byte Dim nindata As Byte Dim nstatus1 As Byte Dim nstatus2 As Byte Dim i As Byte Dim anrxbuf(35) As Byte '(35) 'at least 2x the packet length>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. Dim antxbuf As Byte '(packetsize) '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. Dim nchecksum As Byte '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 'Symbol packetsize = antxbuf '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> '********************** 'Initialize Variables '********************** nsel = 1 led = 1 WaitMs 1000 led = 0 For i = 0 To 34 anrxbuf(i) = $ff Next i For i = 0 To packetsize '- 1>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> antxbuf(i) = $30 + i Next i For txi = 0 To 34 anrxbuf(txi) = $ff Next txi For txi = 0 To packetsize '- 1>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> antxbuf(txi) = $30 + i Next txi 'Initialize the RFM22 Registers Gosub initrfm 'Set up to receive data Gosub to_rx_mode 'Jump to the main program loop Goto mainloop End '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. '******************************************************************************* 'HELPER FUNCTIONS '******************************************************************************* 'Write a single byte to the RFM22 spi_out: nsel = 0 'Select the RFM22 WaitUs 50 'Give it a moment naddress.7 = 1 'Tell the RFM22 we're doing a WRITE transaction 'shiftout sdi, sck, 1,(naddress, noutdata) 'Stuff the datum into the RFM22>>>>>>>>>>>>>>>>>>>> nsel = 1 'De-select the RFM22 WaitUs 100 'Unnecessary? Return 'Read a single byte from the RFM22 spi_in: nsel = 0 'Select the RFM22 WaitUs 50 'Give it a moment naddress.7 = 0 'Tell the RFM22 we're doing a READ transaction 'shiftout sdi, sck, 1,(naddress) 'First, write the ADDRESS we want to read from>>>>>>>>>>>>>>>>>>>>>>>. 'shiftin sdo, sck, 0,(nindata) 'Second, take in the datum>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. nsel = 1 'De-select the RFM22 WaitUs 100 'Unnecessary? Return 'Send the data contained in the anTXBuf array to_tx_mode: 'SEROUT2 PORTA.3,49236,["Entering RX Mode...",13,10] naddress = $07 noutdata = $01 Gosub spi_out 'Set READY mode in RFM22 rx_ant = 0 'Configure for transmission tx_ant = 1 'Configure for transmission WaitUs 50 'Give it a moment naddress = $08 noutdata = $03 Gosub spi_out 'Tell it we want to reset the FIFO naddress = $08 noutdata = $00 Gosub spi_out 'Reset the FIFO naddress = $34 noutdata = 64 Gosub spi_out 'Set the preamble = 64nibble naddress = $3e noutdata = packetsize Gosub spi_out 'Set the packet length nchecksum = 0 For i = 0 To packetsize '- 2>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> naddress = $7f noutdata = antxbuf(i) Gosub spi_out 'Write the data to the TX FIFO nchecksum = nchecksum + antxbuf(i) 'Calculate the checksum Next i naddress = $7f noutdata = nchecksum Gosub spi_out 'Write the checksum as the last byte naddress = $05 noutdata = $04 Gosub spi_out 'Enable the packet sent interrupt naddress = $03 Gosub spi_in nstatus1 = nindata 'Clear interrupts part 1 naddress = $04 Gosub spi_in nstatus2 = nindata 'Clear interrupts part 2 led = 1 'Turn on LED immediatly prior to start of transmission naddress = $07 noutdata = 9 Gosub spi_out 'Tell the RFM22 to start the transmission 'wait for the interrupt to tell us the transmission is complete txwait: If nirq = 1 Then Goto txwait Endif WaitUs 100 'This pause exists only to make the LED blink long enough to see led = 0 'turn off the LED Return 'Set up RFM22 hardware to receive mode to_rx_mode: 'SEROUT2 PORTA.3,49236,["Entering RX Mode...",13,10] rx_ant = 0 'Turn off receiver tx_ant = 0 'Turn off transmitter naddress = $03 Gosub spi_in nstatus1 = nindata 'Clear interrupts part 1 naddress = $04 Gosub spi_in nstatus2 = nindata 'Clear interrupts part 2 naddress = $07 noutdata = $01 Gosub spi_out 'Set READY mode in RFM22 WaitUs 50 'Give it a moment rx_ant = 1 'Configure for reception tx_ant = 0 'Configure for reception WaitUs 50 'Give it a moment Gosub rx_reset 'Configure RFM22 registers for reception WaitUs 10 'Give it a moment Return 'Configure RFM22 registers for reception rx_reset: 'Set READY Mode (Xtal is ON) naddress = $07 noutdata = $01 Gosub spi_out 'Set the RX FIFO Almost Full interrupt level to 17 (same as the packet size) naddress = $7e noutdata = packetsize Gosub spi_out 'Clear the RX FIFO and disable multi-packet naddress = $08 noutdata = $03 Gosub spi_out 'Second write to complete clearing FIFO buffers naddress = $08 noutdata = $00 Gosub spi_out 'READY mode set, RX on in Manual Receiver Mode naddress = $07 noutdata = $05 Gosub spi_out 'Disable extra/oddball interrupts naddress = $06 noutdata = 000000 Gosub spi_out 'Valid Packet Received interrupt is enabled naddress = $05 noutdata = $02 Gosub spi_out 'Read the interrupt registers (in order to clear them) naddress = $03 Gosub spi_in nstatus1 = nindata naddress = $04 Gosub spi_in nstatus2 = nindata Return 'Initial configuration of RFM22 Registers initrfm: 'Disable Interrupts naddress = $06 noutdata = $00 Gosub spi_out 'Set READY mode naddress = $07 noutdata = $01 Gosub spi_out 'cap = 12.5 pF naddress = $09 noutdata = $7f Gosub spi_out 'Clk output is 2 MHz naddress = $0a noutdata = $05 Gosub spi_out 'GPIO0 is RX data output naddress = $0b noutdata = $f4 Gosub spi_out 'GPIO1 Tx/Rx data clk output naddress = $0c noutdata = $ef Gosub spi_out 'GPIO2 for MCLK output naddress = $0d noutdata = $00 Gosub spi_out 'GPIO port use default value naddress = $0e noutdata = $00 Gosub spi_out 'no ADC used naddress = $0f noutdata = $70 Gosub spi_out naddress = $10 noutdata = $00 Gosub spi_out 'no temp sensor used naddress = $12 noutdata = $00 Gosub spi_out naddress = $13 noutdata = $00 Gosub spi_out 'no manchester code, no data whiting, data rate < 30Kbps naddress = $70 noutdata = $20 Gosub spi_out 'IF filter bandwidth naddress = $1c noutdata = $1d Gosub spi_out 'AFC loop naddress = $1d noutdata = $40 Gosub spi_out 'Clock Recovery naddress = $20 noutdata = $a1 Gosub spi_out naddress = $21 noutdata = $20 Gosub spi_out naddress = $22 noutdata = $4e Gosub spi_out naddress = $23 noutdata = $a5 Gosub spi_out 'Clock Recovery timing naddress = $24 noutdata = $00 Gosub spi_out naddress = $25 noutdata = $0a Gosub spi_out 'zero OOK counter naddress = $2c noutdata = $00 Gosub spi_out naddress = $2d noutdata = $00 Gosub spi_out 'slicer peak hold naddress = $2e noutdata = $00 Gosub spi_out 'TX data rate (4800 baud) naddress = $6e noutdata = $27 Gosub spi_out naddress = $6f noutdata = $52 Gosub spi_out 'Data Access Control naddress = $30 noutdata = $8c Gosub spi_out 'Header Control naddress = $32 noutdata = $ff Gosub spi_out 'header 3, 2, 1,0 used for head length, fixed packet length, synchronize word length 3, 2, naddress = $33 noutdata = $42 Gosub spi_out '64 nibble = 32byte preamble naddress = $34 noutdata = 64 Gosub spi_out '0x35 need to detect 20bit preamble naddress = $35 noutdata = $20 Gosub spi_out 'synchronize word naddress = $36 noutdata = $2d Gosub spi_out naddress = $37 noutdata = $d4 Gosub spi_out naddress = $38 noutdata = $00 Gosub spi_out naddress = $39 noutdata = $00 Gosub spi_out 'set tx header naddress = $3a noutdata = "h" Gosub spi_out naddress = $3B noutdata = "o" Gosub spi_out naddress = $3c noutdata = "p" Gosub spi_out naddress = $3d noutdata = "e" Gosub spi_out 'total tx 17 byte naddress = $3e noutdata = packetsize Gosub spi_out 'set rx header naddress = $3f noutdata = "h" Gosub spi_out naddress = $40 noutdata = "o" Gosub spi_out naddress = $41 noutdata = "p" Gosub spi_out naddress = $42 noutdata = "e" Gosub spi_out 'all the bits to be checked naddress = $43 noutdata = $ff Gosub spi_out naddress = $44 noutdata = $ff Gosub spi_out naddress = $45 noutdata = $ff Gosub spi_out naddress = $46 noutdata = $ff Gosub spi_out 'Reserved naddress = $56 noutdata = $01 Gosub spi_out 'tx power to Max naddress = $6d noutdata = $07 Gosub spi_out 'no frequency hopping naddress = $79 noutdata = $00 Gosub spi_out naddress = $7a noutdata = $00 Gosub spi_out 'Gfsk, fd[8] =0, no invert for Tx/Rx data, fifo mode, txclk -->gpio naddress = $71 noutdata = $22 Gosub spi_out 'frequency deviation setting to 35k = 56*625 naddress = $72 noutdata = $38 Gosub spi_out 'no frequency offset naddress = $73 noutdata = $00 Gosub spi_out naddress = $74 noutdata = $00 Gosub spi_out 'frequency set to 434MHz naddress = $75 noutdata = $53 Gosub spi_out naddress = $76 noutdata = $64 Gosub spi_out naddress = $77 noutdata = $00 Gosub spi_out 'NOTE: 'The following 5 registers are listed as RESERVED in the RFM22B v1.1 'datasheet. Try remming them if problems are experienced naddress = $5a noutdata = $7f Gosub spi_out naddress = $59 noutdata = $40 Gosub spi_out naddress = $58 noutdata = $80 Gosub spi_out naddress = $6a noutdata = $0b Gosub spi_out naddress = $68 noutdata = $04 Gosub spi_out 'Clock Recovery Gearshift Override naddress = $1f noutdata = $03 Gosub spi_out WaitUs 1000 'Let the settings settle Return '******************************************************************************* 'END OF HELPER FUNCTIONS, BEGIN MAIN PROGRAM LOOP '******************************************************************************* mainloop: 'nIRQ Pin Indicates that we have received a packet If nirq = 0 Then 'Packet received 'Clear the interrupt naddress = $03 Gosub spi_in nstatus1 = nindata naddress = $04 Gosub spi_in nstatus2 = nindata 'Read in the data 'For i = 0 To packetsize - 1>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> naddress = $7f Gosub spi_in anrxbuf(i) = nindata 'Next i>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. nsel = 1 'unncecessary? 'Calculate the checksum... nchecksum = 0 For i = 0 To packetsize '- 2>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. nchecksum = nchecksum + anrxbuf(i) 'SEROUT2 PORTA.3,49236,[Ihex2 anRxBuf(i)," "] anrxbuf(i) = 0 Next i 'SEROUT2 PORTA.3,49236,[13,10,"ChkSum=",Ihex2 anRxBuf[i],13,10] 'Verify that the calculate checksum matches the last byte in the packet If nchecksum = anrxbuf(packetsize) Then '- 1) Then>>>>>>>>>>>>>>>>>>>> led = 1 'SEROUT2 PORTA.3,49236,["ChkSum MATCH!",13,10] WaitMs 500 led = 0 Endif Gosub rx_reset '/ / rx reset Endif 'Check for button press If nbutton = 0 Then 'the button is pressed... 'SEROUT2 PORTA.3,49236,["Xmitting",13,10] 'Here would be a good place to load the relevant data into anTxBuf Gosub to_tx_mode 'and return back to RX_Mode Gosub to_rx_mode Endif Goto mainloop