'rfkey_418_1
'jleblanc 4.18.06
    'for my keyboard connector: 
        'red to ground
        'white to power
        'black to A0
        'yellow to A

'********************************************************************
'*Setup OSC, LCD and Keyboard pins
'********************************************************************
    DEFINE OSC 20
    'include modedefs.bas for shiftin and out modes used in the RF code
    INCLUDE "modedefs.bas"
    
    'SETUP LCD
        'This setup will tell PBP a 2-line LCD is connected in 4-bit 
        'mode with the data bus on the top 4 bits of PORTB, Register 
        'Select on PORTB.1, and Enable on PORTB.0.
        'Data Bits go like: D7>B.7, D6>B.6, D5>B.5, D4>B.4
    	DEFINE LCD_DREG	PORTB
    	' Set starting Data bit (0 or 4) if 4-bit bus
    	DEFINE LCD_DBIT	4
    	' Set LCD Register Select port
    	DEFINE LCD_RSREG	PORTB
    	' Set LCD Register Select bit
    	DEFINE LCD_RSBIT	1
    	' Set LCD Enable port
    	DEFINE LCD_EREG	PORTB
    	' Set LCD Enable bit
    	DEFINE LCD_EBIT	0
    	' Set LCD bus size (4 or 8 bits)
    	DEFINE LCD_BITS	4
    	' Set number of lines on LCD
    	DEFINE LCD_LINES	2
    	' Set command delay time in us
    	DEFINE LCD_COMMANDUS	2000
    	' Set data delay time in us
    	DEFINE LCD_DATAUS	50
    
    'Setup KeyBoard System
        'The keyboard runs off PORTA so this sets it to all digital
            ADCON1 = %10000110
            KeyData VAR PORTA.0
            KeyClk VAR PORTA.1
    'Setup RF 
        'pin definitions for comm w/ Sparkfun MiRF v01
            RF_CE   VAR    PORTD.7 'yellow
            RF_CS   VAR    PORTD.3 'dark green
            RF_DR   VAR    PORTD.2 'blue
        'channel 1 PIN definitions
            RF_CLK1 VAR    PORTD.1 'black
            RF_DATA_In VAR PORTD.0 'light blue
            RF_DATA_Out VAR PORTD.0
        'I/O + Control PINS
            switch  VAR portc.4
            receiveLED  VAR portc.3
            sendLED VAR portc.2    

'********************************************************************
'*Variables
'********************************************************************
    'GENERAL VARIABLES
       i VAR BYTE
        counter VAR BYTE 
    
    'KEYBOARD VARIABLES
        'Variables used to interface with keyboard
            Keypress VAR BYTE'Keyboard value read from keyboard
            AscKey VAR BYTE'This is used to send key scan data and subroutine controls to other subroutines
            TempReg VAR BYTE'Misc temp register
            Temp2Reg VAR BYTE'Misc temp register
            ShiftReg VAR BIT'Stores the shift key status. 1=shift 0=no shift
            DumpReg VAR BIT'Temp reg for dumping keypress values after a releasecommand

     'RF VARIABLES  
        ' THIS IS THE ADDRESS FOR THE MiRF v01
            WhichAddress1 VAR BYTE    'Channel 1
            WhichAddress2 VAR BYTE    'Channel 2         
        'constants for RF configuration modes
            CONRFRX VAR BYTE
            CONRFTX VAR BYTE    
        'indicates state of current RF configuration - TX is 0, RX is 1
            RFCurrentState VAR BIT    
        'hold data for RF message
            RFDataArrayIN VAR BYTE[19]
            RFDataArrayOUT VAR BYTE[19]   
        'hold data for RF configuration
            RFConfigArray VAR BYTE[16]    
        'variables for each received or sent message
            msgFromID VAR BYTE
            msgToID VAR BYTE
        'ID variables
        '**me is a key variable because it is the identifier for a given
        'unit. Each unit will have its own me ID, and when a unit writes out
        'it will either write to a specific other unit (using 1,2,3) or to all
        'units using A    
            me  VAR BYTE    'ID that should be set to a unique number for each board
            friend  VAR BYTE
     '******SET AS UNIQUE FOR EACH UNIT
            me = 1      'ID that should be set to a unique number for each board
            friend = 2    
         'Line Number Variable: Tells us what line on the LCD a line goes/comes from
             line_number VAR BYTE
             line_number=0
             
    'LCD VARIABLES
    'For the LCD the top 2 lines are the lines the keyboard can write to.
    'The bottom 2 lines are for incoming messages. Thus cursor max is 31         
         'Display Array
            DisplayArray VAR BYTE[64]   '4 lines by 16 bytes
         'Other Variables
            pos VAR BYTE    'cursor position
            MAXpos VAR BYTE 'max cursor position
            Bself VAR BYTE
            Eself VAR BYTE
            Bother VAR BYTE                      
            Eother VAR BYTE
            control VAR BYTE 'Not sure what this does
        'initialize
            Bself=0 : Eself=31 : Bother=32: Eother=63
            MAXpos=Eself 'since we start from 0
            pos=0
            FOR  i=0 TO Eother
                DisplayArray[i]=" "
            NEXT i
            
    'DISPLAY MEMORY VARIABLES
    'Each device will save the last 10 messages that came in
    'Anytime a message is sent in it gets sent to the rear
        'MemoryArray
            MemoryArray VAR BYTE[320] '10 x 32byte messages
            'initialize
            FOR i=0 TO 319
                MemoryArray[i]=" "
            NEXT
            
            mem_size VAR BYTE   'number of messages in memory
                mem_size=0
            current_mem VAR BYTE'newest msg place
                current_mem=0
            display_mem VAR BYTE 'Current msg on display
                display_mem=0
            nav VAR BIT  'used to navigate the memory
                               
    'OUTPUT CONTROL VARIABLES
        trigger VAR BIT
        trigger=0
        OutputArray VAR BYTE[32]
            

'************************************************************************
'*Bootup
'************************************************************************
    'Bootup RF
        WhichAddress1 =$BA 'These are things maybe to change????
        WhichAddress2 =$BA
        
        'intialize RF module configuration
        'constants to define receive/transmit modes at 2402 Mhz frequency
        CONRFRX = $05
        CONRFTX = $04
        RFCurrentState = CONRFRX
        
        GOSUB INITRFCONFIG
        
        msgToID = 0   ' CHANGE THIS TO WHO SHOULD RECIEVE MESSAGE
        msgFromID = me   '  CHANGE THIS TO ID OF SENDER
    
    'Bootup LCD   
        LCDOUT $fe, 1   ' Clear screen
        LCDOUT "Starting Up"  ' Send Startup Message
        PAUSE 1000  'Just Pause for a second
        LCDOUT $fe, 1   ' Clear screen

'************************************************************************
'*Main Loop
'************************************************************************
    Main:
        'This code brings the RF into an active state
        LOW RF_CS   ' bring CS low before turning CE high - only one high at a time!
        HIGH RF_CE  ' bring CE high to bring RF into active mode

        GOSUB ScanKeyboard'Gets key pressed keycode
        GOSUB BackSpace 'Handles backspacing
        GOSUB ChrtoASCII'Changes keycode into ascii
        GOSUB UpdateMSG 'Updates Msg array           
        GOSUB Renderscreen 'Updates LCD
        'For some reason We need this here even though its in scankeyboard
        'For the system to work. Not sure why.
        IF RF_DR = 1 THEN
            INPUT RF_DATA_In 'This makes that pin an Input PIN
            GOSUB RECEIVERF
        ENDIF
    GOTO Main

'************************************************************************
'*Sub Programs
'************************************************************************
    'ScanKeyboard: Gets input from the keyboard and on RETURN sends out message via RF
    'UpdateMSG: Updates the message Array and cursor position
    'Renderscreen: Renders Msg[] array to the LCD screen 
    'ClockCycle: Used by ScanKeyboard
    'ChrtoASCII: Converts keyboard scan codes to ASCII
    'BackSpace: Handles backspace key
    'RECEIVERF: Handles Incoming RF messages  
    'LOADARRAYS: THIS IS USED TO PIECE TOGETHER AN INCOMING MESSAGE   
    'SENDDATA: Sends Data Out via RF   
    'SETRFCONFIG: Resets RF configuration after a send or recieve 
    'INITRFCONFIG: Initiali RF configuration


    ScanKeyboard:
        DumpReg = 0
        DumpKeys:'NOTE
        
        AscKey = 0
        Keypress = 0
        INPUT KeyClk : KeyClk = 1 'Release Clock Line for Com from Keyboard to PIC
        GOSUB ClockCycle'Dumps start bit
        FOR TempReg = 0 TO 7
            GOSUB ClockCycle
            IF KeyData = 1 THEN 'Calculates bit value
                LOOKUP TempReg,[1,2,4,8,16,32,64,128],Temp2Reg
                Keypress = Keypress + Temp2Reg'Adds the bit values together
            ENDIF
        NEXT TempReg
        
        GOSUB ClockCycle'Dumps parity bit
        GOSUB ClockCycle'Dumps stop bit
        OUTPUT KeyClk : KeyClk = 0 'Set Clock Line Low and hold Com from Keyboard to PIC
    
        
        IF Keypress = $F0 THEN'If key release command then go again
            DumpReg = 1'Set so that next key will also get dumped
            GOTO DumpKeys'Rerun loop
        ENDIF
    
        IF Keypress=$58 || Keypress=$12 || Keypress=$59 && DumpReg = 1 THEN'Turn off ShiftReg
            ShiftReg = 0'Sets the Shift Reg for Shift
            AscKey = 255'Will not print anything on LCD
        ENDIF
    
        IF DumpReg = 1 THEN'If this loop was to dump chr then send a 255 to next
            DumpReg = 0 '???????
            Keypress = 255
        ENDIF
    
        IF Keypress=$58 || Keypress=$12 || Keypress=$59 THEN'Turn on ShiftReg
            ShiftReg = 1'Sets the Shift Reg for Shift
            AscKey = 255'Will not print anything on LCD
        ENDIF
        
        'Note we'll use F1 for back ($05) and F2 for forward ($06)
        'we'll say nav=1 goes forward and nav=0 goes back 
              IF Keypress=$06 THEN
                  display_mem=(display_mem+1)//(mem_size)'no -1
                  AscKey = 255'Will not print anything on LCD
              ENDIF
              
              IF Keypress=$05 THEN
                  IF display_mem=0 THEN
                    display_mem=(mem_size-1)
                  ELSE
                    display_mem=display_mem-1
                  ENDIF
                  AscKey = 255'Will not print anything on LCD
              ENDIF        
         
        'IF hit return then set trigger for sending message
        IF Keypress=$5A THEN'Turn on ShiftReg
            trigger=1 'set trigger to send message
            'Load outputarray with current display
            FOR i=0 TO 31
                OutputArray[i]=DisplayArray[i]
            NEXT
            'Now we want to display the pick who to send to message
             GOSUB DisplaySendMSG
            AscKey = 255'Will not print anything on LCD
        ENDIF    
    RETURN
    
    
         'Called in RecieveRF
        handlenewmsg:
            'UP mem_size                
                IF mem_size<10 THEN mem_size=mem_size+1
            'Set current pointer
                IF mem_size=1 THEN
                    current_mem=0
                ELSE
                    current_mem=(current_mem+1)//10'9c......
                ENDIF
            'We also are going to want to default display the new message
                display_mem=current_mem
             'RecieveRF will now do the proper thing with   
        RETURN
    
    DisplaySendMSG:
        DisplayArray[0]="S"
        DisplayArray[1]="e"
        DisplayArray[2]="n"
        DisplayArray[3]="d"
        DisplayArray[4]=" "
        DisplayArray[5]="t"
        DisplayArray[6]="o"
        DisplayArray[7]=" "
        DisplayArray[8]="1"
        DisplayArray[9]="("
        DisplayArray[10]="1"
        DisplayArray[11]=")"
        DisplayArray[12]=","
        DisplayArray[13]="2"
        DisplayArray[14]="("
        DisplayArray[15]="2"
        DisplayArray[16]=")"
        DisplayArray[17]=","
        DisplayArray[18]="3"
        DisplayArray[19]="("
        DisplayArray[20]="3"
        DisplayArray[21]=")"
        DisplayArray[22]=","
        DisplayArray[23]="A"
        DisplayArray[24]="l"
        DisplayArray[25]="l"
        DisplayArray[26]="("
        DisplayArray[27]="A"
        DisplayArray[28]=")"
        DisplayArray[29]=":"
        DisplayArray[30]=" "
        DisplayArray[31]=" "
    
    RETURN
    
    
     UpdateMSG:'This will convert the key scan codes to ASCCII
        IF AscKey <> 255 THEN
            IF trigger=0 THEN
                DisplayArray[pos]=Keypress
                pos=pos+1
                IF pos > MAXpos THEN pos=MAXpos
            ELSE
                'WE WANT TO SEND THE DATA
                 msgToID = Keypress   ' CHANGE THIS TO WHO SHOULD RECIEVE MESSAGE
'****************Changed from 416_5
                 IF msgToID="1" OR msgToID="!" THEN msgToID=1
                 IF msgToID="2" OR msgToID="@" THEN msgToID=2
                 IF msgToID="3" OR msgToID="#" THEN msgToID=3
                 IF msgToID="a" THEN msgToID="A"
                 IF msgToID<>1 AND msgToID<>2 AND msgToID<>3 AND msgToID<>"A" THEN msgToID="A"
               'Send 3 times
                    line_number=1
                    GOSUB SENDDATA    ' goto the sendData function
                    PAUSE 50
                    line_number=2
                    GOSUB SENDDATA    ' goto the sendData function
                    PAUSE 50
                    line_number=3
                    GOSUB SENDDATA    ' goto the sendData function
                    PAUSE 50
                    
            'We want now to reset self area
              FOR i=Bself TO Eself
                 DisplayArray[i]=" "
              NEXT
              pos=0
              trigger=0    
            ENDIF
        ENDIF
    RETURN

'    UpdateMSG:'This will convert the key scan codes to ASCCII
'        IF AscKey <> 255 THEN
'            DisplayArray[pos]=Keypress
'            pos=pos+1
'            IF pos > MAXpos THEN pos=MAXpos
'        ENDIF
'    RETURN

     Renderscreen:
        'Clear Screen
        LCDOUT $fe, 1
        'Print first line
        FOR i=0 TO 15
                LCDOUT  DisplayArray[i]
        NEXT
        'Move to second line
        LCDOUT $fe, $C0
        FOR i=16 TO 31
                LCDOUT  DisplayArray[i]
        NEXT
        
        IF mem_size>0 THEN
            'Move to third line
            LCDOUT $fe, $90
            FOR i=0 TO 15
                    LCDOUT  MemoryArray[i+display_mem*32]
            NEXT
            'Move to fourth line
            LCDOUT $fe, $D0
            FOR i=16 TO 31
                    LCDOUT  MemoryArray[i+display_mem*32]
            NEXT
         ELSE
             'Move to third line
            LCDOUT $fe, $90
            FOR i=0 TO 15
                    LCDOUT  " "
            NEXT
            'Move to fourth line
            LCDOUT $fe, $D0
            FOR i=16 TO 31
                    LCDOUT  " "
            NEXT
         ENDIF
'        'Move to third line
'        LCDOUT $fe, $90
'        FOR i=32 TO 47
'                LCDOUT  DisplayArray[i]
'        NEXT
'        'Move to fourth line
'        LCDOUT $fe, $D0
'        FOR i=48 TO 63
'                LCDOUT  DisplayArray[i]
'        NEXT    
     RETURN'renderscreen

    'NOTE: This function is the ClockCycle listner from the keyboard
    'But also has RF listening too. This is because this function loops
    'forever until it gets a signal from the keyboard. Thus embedding the
    'RF listen code in here ensures that we will not miss a RF incoming signal
    ClockCycle:'Waits for the clock to cycle from keyboard
        HoldClockLow:
            IF RF_DR = 1 THEN
                INPUT RF_DATA_In 'This makes that pin an Input PIN
                GOSUB RECEIVERF
            ENDIF
            
            IF KeyClk = 0 THEN HoldClockLow
        HoldClockHi:
            IF RF_DR = 1 THEN
                INPUT RF_DATA_In 'This makes that pin an Input PIN
                GOSUB RECEIVERF
            ENDIF
            
            IF KeyClk = 1 THEN HoldClockHi
    RETURN

    ChrtoASCII:'Converts keycode into ASCII
        IF AscKey <> 255 THEN
            AscKey = 255
            LOOKDOWN Keypress,[69,22,30,38,37,46,54,61,62,70,28,50,33,35,36,43,52,51,67,59,66,75,58,49,68,77,21,45,27,44,60,42,29,34,53,26,41,78,85,93,84,91,76,82,65,73,74],AscKey
            
            IF ShiftReg = 0 THEN
                LOOKUP AscKey,["0123456789abcdefghijklmnopqrstuvwxyz -=|{};',./"],Keypress
            ELSE
                LOOKUP AscKey,[")!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZ _+|{}:'<>?"],Keypress
            ENDIF
        ENDIF
    RETURN

    BackSpace:
        IF Keypress = $66 THEN'Backspace key pressed
            IF pos=MAXpos THEN 
                IF DisplayArray[pos]=" " THEN
                    pos=pos-1: DisplayArray[pos]=" "
                ELSE
                    DisplayArray[pos]=" "
                ENDIF
            ELSE
                IF pos > 0 THEN 
                    pos=pos-1
                    DisplayArray[pos]=" "
                ENDIF
            ENDIF       
            AscKey = 255 'Don't enable further writing
        ENDIF
    RETURN

'***************************************************************************
'*RF SUB PROGRAMS
'***************************************************************************       
    'RECEIVERF   
    'LOADARRAYS   
    'RUNDISPLAY   
    'SENDDATA   
    'SETRFCONFIG  
    'INITRFCONFIG
        
    RECEIVERF:
    'TAKE IN THE DATA INTO RFDATAARRAYIN   
        INPUT RF_DATA_In 'Redudant? given we say this in main loop?
        'power down RF front-end for current conservation
        LOW RF_CE
        'clock in data from RF-24G to PIC
        FOR i=0 TO 18
            'clock should follow data by at least 50nsec
            ''This basically sends out a clock signal
            ''SHIFTIN  DataPin,ClockPin,Mode,[Var{\Bits}...]
            SHIFTIN RF_DATA_In, RF_CLK1, MSBPRE, [RFDataArrayIN[i]\8]
        NEXT
     
    'LOAD DISPLAYARRAY   
        'power up RF front-end again
        HIGH RF_CE
'        'Add to the Control Variables
'            msgToID = RFDataArrayIN[0]       'the receiver is in msgToID
'            msgFromID = RFDataArrayIN[1]    'sender information in msgFromID
        'Load DisplayArray
            GOSUB LoadDisplayArray
        'Print the whole array
            GOSUB Renderscreen'RunDisplay  

    'Here we blink to acknowledge we have received the message
        HIGH receiveLED:PAUSE 50:LOW receiveLED:PAUSE 50
        HIGH receiveLED:PAUSE 50:LOW receiveLED:PAUSE 50    
    RETURN 'RECEIVERF
    
    'THIS IS USED TO PIECE TOGETHER AN INCOMING MESSAGE
    'NOTE THIS WILL ONLY PICK UP MESSAGES ADRESSED TO IT
    'OR TO ALL
    'RFDataArrayIN[0] = msgToID
    'RFDataArrayIN[1] = msgFromID
    'We want to make sure that [0] matches us or is 'A' (65)    
    LoadDisplayArray:
        msgToID = RFDataArrayIN[0]       'the receiver is in msgToID
        msgFromID = RFDataArrayIN[1]    'sender information in msgFromID
        IF msgToID=me OR msgToID="A" OR msgToID="a" THEN
            'First goto handle handlenewmsg, this will update where things
            'must point e.g. sets current_mem we only do this once!!!!
            IF RFDataArrayIN[2]=1 THEN
                GOSUB handlenewmsg
            ENDIF
            'Note array element [2] is the line number
            'Load first Line
            IF RFDataArrayIN[2]=1 THEN        
                'Load first part of array
                FOR i=0 TO 15
                    'DisplayArray[i+32]=RFDataArrayIN[i+3]
                    MemoryArray[i+32*current_mem]=RFDataArrayIN[i+3]
                NEXT
            ENDIF
            'Load second Line
            IF RFDataArrayIN[2]=2 THEN
                'Load second part of array
                FOR i=0 TO 15
                    'DisplayArray[i+48]=RFDataArrayIN[i+3]
                     MemoryArray[i+32*current_mem+16]=RFDataArrayIN[i+3]
                NEXT  
            ENDIF
        ENDIF
    RETURN'LOADARRAYS
    
    SENDDATA: 'SENDS OUT 19 byte message
        'LOAD RFDATAARRAYOUT
            'Load the RF data out array with control Items
               RFDataArrayOUT[0] = msgToID
               RFDataArrayOUT[1] = me'msgFromID
               RFDataArrayOUT[2] = line_number 'this is line number 1-3, here just the number of times we've sent
    
             'Load array with correct line number information
             IF line_number=1 THEN        
                'Load first part of array
                 FOR i=0 TO 15
                    RFDataArrayOUT[i+3]=OutputArray[i]              
                NEXT
            ENDIF
            'Load second Line
            IF line_number=2 THEN
                'Load second part of array
                FOR i=0 TO 15
                    RFDataArrayOUT[i+3]=OutputArray[i+16]
                NEXT
            ENDIF
        
        'SEND THE DATA
            'set RF to transmit mode...
            RFCurrentState = CONRFTX
            GOSUB SETRFCONFIG
            
            ' for shockburst TX, the sum of RX address, payload, and CRC must be less than 256 bits long
            ' the chip then tacks on a preamble to this message, and the total msg is 266 bits
            
            OUTPUT RF_DATA_Out   'Makes the pin an Output    
            'get back into active mode
            HIGH RF_CE    
            'Need pause between CE high and DATA clock out
            PAUSEUS 100    
            'clock out 5 byte RF address of recipient
            FOR i = 8 TO 12
               'clock out this byte
               SHIFTOUT RF_DATA_Out, RF_CLK1, MSBFIRST, [RFConfigArray[i]\8]
            NEXT    
            'clock out 19 bytes of data payload
            FOR i = 0 TO 18
               'clock out this byte
               SHIFTOUT RF_DATA_Out, RF_CLK1, MSBFIRST, [RFDataArrayOUT[i]\8]
            NEXT
            
            'start shockburst transmission
            LOW RF_CE
            PAUSEUS 300
            
            'flash LED to indicate that we transmitted
            HIGH sendLED:PAUSE 50:LOW sendLED:PAUSE 50
            HIGH sendLED:PAUSE 50:LOW sendLED:PAUSE 50
            
        'afterward, set RF back to its default receive state
        RFCurrentState = CONRFRX
        GOSUB SETRFCONFIG
    RETURN'SENDATA
           
    SETRFCONFIG:  '  THIS IS USED TO SWITCH BETWEEN RECIEVE AND TRANSMIT MODES    
       'during configuration of the transmitter, we need RF_DATA as an output
       OUTPUT RF_DATA_Out
    
       'set chip to configure mode (CE low, CS high)
       LOW RF_CE
       HIGH RF_CS
    
       'pause between CS high and DATA clockout
       PAUSEUS 100
    
       'RFCurrentState indicates 2402 Mhz frequency and either RX or TX state
       'clock out new configuration data from PIC to RF-24G
       SHIFTOUT RF_DATA_Out, RF_CLK1, MSBFIRST, [RFCurrentState\8]
    
       'configuration set on falling edge of CS
       LOW RF_CS
       LOW RF_CE
    
       'for consistency with the rx, stick this here
       INPUT RF_DR
    
       'flash the LED on B6 to indicate that we configured
       'high DEBUG_LED1
      ' pause 250
       'low DEBUG_LED1    
    RETURN'SETRFCONFIG
    
    INITRFCONFIG:
       'configuration is a 144 bit word
       'must be clocked in MSB first
       'bit map
       '143:120 - reserved for testing
       '119:112 - length of data payload section RX channel 2
       '111-104 - length of data payload section RX channel 1
       '103:64  - up to 5 byte address for RX channel 2
       '63:24   - up to 5 byte address for RX channel 1
       '23:18   - number of address bits (both RX channels)
       '17      - 8 or 16 bit CRC
       '16      - enable on-chip CRCD generation/checking
       '15      - enable two channel receive mode
       '14      - communication mode (direct or shockburst)
       '13      - RF data rate (1Mbps requires 16Mhz crystal)
       '12:10   - crystal frequency
       '9:8     - RF output power
       '7:1     - frequency channel
       '0       - RX or TX operation
    
       'setup RFConfigArray with config bytes, see datasheet for default configuration
       'this array is backwards so we can clock from MSB to LSB by increasing the index
       'Data bits 119-112: Max data width on channel 2 (excluding CRC and adrs)
        RFConfigArray[1] = $98 'payloadSize, 19 BYTES (this is 19*8 for bits in hex)
       'Data bits 111-104: Max data width on channel 1 (excluding CRC and adrs)
        RFConfigArray[2] = $98 'payloadSize, 19 BYTES
       'Data bits 103-64: Channel 2 address, 5 bytes (40 bits)
        RFConfigArray[3] = WhichAddress2
        RFConfigArray[4] = WhichAddress2
        RFConfigArray[5] = WhichAddress2
        RFConfigArray[6] = WhichAddress2
        RFConfigArray[7] = WhichAddress2
       'Data bits 63-24: Channel 1 address, 5 bytes (40 bits)
        RFConfigArray[8] = WhichAddress1
        RFConfigArray[9] = WhichAddress1
        RFConfigArray[10] = WhichAddress1
        RFConfigArray[11] = WhichAddress1
        RFConfigArray[12] = WhichAddress1
       'Data bits 23-16: Address width and CRC  - 40 bit addr, 16 bit CRC, CRC enabled
        RFConfigArray[13] = $A3
       'Data bits 15-8: One Channel Receive, Shockburst Enabled, 250 kilobits, etc
        RFConfigArray[14] = $4F
       'Data bits 7-0: 2402 Mhz frequency, RX enabled/disabled (depending on RFCurrentState)
        RFConfigArray[15] = RFCurrentState
    
       '===================================================================
       'During configuration of the transmitter, we need RF_DATA as an output
       INPUT RF_DR
       INPUT RF_DATA_In
       OUTPUT RF_DATA_Out
    
       'set chip to configure mode (CE low, CS high)
       LOW RF_CE
       HIGH RF_CS
    
       'pause between CS high and DATA clockout
       PAUSEUS 100
    
       'clock out configuration bytes from PIC to RF-24G
       FOR i = 1 TO 15
           'set config one byte at a time from MSB to LSB
           SHIFTOUT RF_DATA_Out, RF_CLK1, MSBFIRST, [RFConfigArray[i]\8]
       NEXT
       'configuration is set on the falling edge of CS, bring it low
       LOW RF_CS
       LOW RF_CE
    
       'flash LED on pin B6 to debug that we configured
       HIGH sendLED:PAUSE 250:LOW sendLED:PAUSE 250
       HIGH receiveLED:PAUSE 250:LOW receiveLED:PAUSE 250
       HIGH sendLED:PAUSE 250:LOW sendLED:PAUSE 250
       HIGH receiveLED:PAUSE 250:LOW receiveLED:PAUSE 250
    
    RETURN'INITRFCONFIG
    
'***************************************************************************
'*END SUB PROGRAMS
'***************************************************************************