Quote Originally Posted by iw2fvo View Post
Yes, it will be very useful to me if you can post your code.
Here you go. Please let us know how it works out.

Code:
'****************************************************************
'*  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
'------------------------------------------------------------------------------------------------------------------------------------
'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


'**********
' 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
'*********
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


'**********************
' Initialize Variables
'**********************
nSEL = 1
LED = 1
PAUSE 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

'Initialize the RFM22 Registers
GOSUB InitRFM
'Set up to receive data
GOSUB To_RX_Mode
'Jump to the main program loop
GOTO MainLoop


'*******************************************************************************
' HELPER FUNCTIONS
'*******************************************************************************


'Write a single byte to the RFM22
SPI_Out:
  nSel = 0        'Select the RFM22
  PAUSEUS 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
  PAUSEUS 100  'Unnecessary?
RETURN


'Read a single byte from the RFM22
SPI_In:
  nSel = 0        'Select the RFM22
  PAUSEUS 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
  PAUSEUS 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
  Pause 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
  pause 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
  pause 50    'Give it a moment
  RX_ANT = 1  'Configure for reception
  TX_ANT = 0  'Configure for reception
  pause 50    'Give it a moment
  GOSUB RX_Reset  'Configure RFM22 registers for reception
  PAUSEUS 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
  PAUSEUS 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-1] then
      LED = 1
      'SEROUT2 PORTA.3,49236,["ChkSum MATCH!",13,10]
      PAUSE 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
Best Regards,
Paul