Boat Code .asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;xBee_Helm_Code
;218C Spring 2008
;Redneck Yacht Club
;Kuan Li, Stephanie Lue, Christine Tower
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
list P=PIC16F690
#include "p16f690.inc"
                __config (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC)
; This is for our state machine
current_state                   equ                             0x7F
temp_reg                        equ                             0x7E
dump_data                       equ                             0x7D
;
; This for our ibutton
SN_Family_byte		equ	                0x20            
SN_Low_byte		equ	                0x21
SN_High_byte		equ	                0x22
loop_count		equ	                0x23
bit_count		equ	                0x24
first_byte_full		equ	                0x25
second_byte_full	equ	                0x26
;
; This is for the sendout timer
send_tof_count                  equ                             0x27
send_flag                       equ                             0x28
;
; SSP variables
rx_ssp_byte                     equ                             0x29
tx_ssp_byte                     equ                             0x2A
;
; Receive variables
byte_count                      equ                             0x2B
full_packet                     equ                             0x2C
temp_received                   equ                             0x2D
byte_1                          equ                             0x2E
byte_2                          equ                             0x2F
byte_3                          equ                             0x30
byte_4                          equ                             0x31
byte_5                          equ                             0x32
byte_6                          equ                             0x33
byte_7                          equ                             0x34
byte_8                          equ                             0x35
byte_9                          equ                             0x36
byte_10                         equ                             0x37
byte_11                         equ                             0x38
byte_12                         equ                             0x39

; the checksum
CheckSumValue                   equ                             0x3A

;sending packet
Tx_Destination_MSB              equ                             0x3B
Tx_Destination_LSB              equ                             0x3C
Tx_Info_Byte0                   equ                             0x3D
Tx_Info_Byte1                   equ                             0x3E
Tx_Info_Byte2                   equ                             0x3F
Paired_Helm_LSB                 equ                             0x40
Paired_Hull_MSB                 equ                             0x41

;recieving packet
Rx_Info_Byte0                   equ                             0x42
Rx_Info_Byte1                   equ                             0x43
Rx_Info_Byte2                   equ                             0x44
Rx_AddressLSB_Byte              equ                             0x45

;standown timer
Standown_Timer_LSB              equ                             0x47
Standown_Timer_MSB              equ                             0x48


;controller Helper pic
led_data                        equ                             0x49

; ISR entry/exit variables
W_TEMP                          equ                             0x70 
STATUS_TEMP                     equ                             0x71
PCLATH_TEMP                     equ                             0x72
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; #define the states
#define                         WAIT_IBUTTON_st                  b'00000001'
#define                         WAIT_HELM_st                     b'00000010'
#define                         PLAY_GAME_st                     b'00000100'
#define                         STAND_DOWN_st                    b'00001000'
;
; #define for the bit_test states
#define                         WAIT_IBUTTON_BT                 0x00
#define                         WAIT_HELM_BT                    0x01
#define                         PLAY_GAME_BT                    0x02
#define                         STAND_DOWN_BT                   0x03
;
; ibutton #defines
#define                         HI_500		0x04
#define                         LO_500		0xC4
#define                         HI_50		0x00
#define                         LO_50		0x64
#define                         HI_5		0x00
#define                         LO_5		0x02
#define                         HI_75		0x00
#define                         LO_75		0xA5
#define                         HI_60		0x00
#define                         LO_60		0x7D
#define	                HI_40		0x00
#define                         LO_40		0x32
#define                         LOOP_COUNT	                0x18
#define                         BIT_COUNT	                0x00
;
; EUSART #defines
#define                         BAUDRATEX       	d'64'           ; this is for a baud rate of 9600 with an external resonator that runs at 10 MHz
;
; 0.2 sec sendout timer #defines
#define                         SENDOUT_TOF                     0x7B            ; this creates a 0.2 sec pause between transmits 
;
; SSP #defines
#define                         SLAVE_SELECT_LINE               0x06
;
; communication protocol #defines
#define                         HELM_HEADER		0xAA
#define                         START_BYTE		0x7E
#define                         LENGTH_MSB		0x00
#define                         LENGTH_LSB		0x08
#define                         API_RX          	0x81
#define                         API_TX          	0x01
;
; Frame ID:  change this to non-zero if you wish 
; your xBee to respond with a Tx Status message
#define                         FRAME_ID	                0x00	
;
; Addresses
#define                         ADMIRAL_ADDRESS_MSB	0xBC
#define                         ADMIRAL_ADDRESS_LSB	0xFF
#define                         BROADCAST_ADDRESS_MSB           0xFF
#define                         BROADCAST_ADDRESS_LSB           0xFF
;
#define                         HELM_MSB		0xBC			
#define                         CRAFT_MSB		0xAF
#define                         OURHELM_LSB                     0x02
#define                         OURCRAFT_LSB                    0x02
;
; OPTIONS 
#define                         OPTIONS_DEFAULT                 0x01
;
; for ME218C Data Byte 0 Header
#define	                IBUTTON		0x01
#define	                NAVIGATION		0x02
#define	                ADMIRAL		0x04
#define	                WATERCRAFT		0x08
#define	                PING_RESPONSE	                0x10
#define	                ACK		0x80
;
; Admiral Messages
#define	                STAND_DOWN		0x01
#define	                START_GAME		0x02
#define	                END_GAME		0x04
#define	                BLUE_GOAL		0x08
#define	                RED_GOAL		0x10
#define	                SOFT_RESET		0x20
#define	                HARD_RESET		0x40
#define	                ADMIRAL_PING		0x80
;
; Commands from Helm to Watercraft
#define	                NO_ACTION_1		0x88
#define	                NO_ACTION_2		0x00
;
; Commands from Watercraft to Helm
#define	                STAND_DOWN_RECEIVED_1	0x00
#define	                STAND_DOWN_RECEIVED_2	0x02
#define	                MATCHED_0		0x08
#define	                MATCHED_1		0x00
#define                         MATCHED_2                       0x01
;
; Ping Responses
#define	                WAITING_IBUTTON		0x01
#define         	WAITING_PAIR		0x02
#define	                PAIRED		0x04
#define                         UNPAIRED                        0x00

; Standdown #defines
#define                         STANDOWN_TOF_MSB                0x17
#define                         STANDOWN_TOF_LSB                0xEF

;Note: Timing is based on using the external resonator (10MHz)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;     
                org             0
                pagesel         Main
  	goto            Main
                org             4
                nop
                org             5
                pagesel         InterruptServiceRoutine
                goto            InterruptServiceRoutine
                
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Tables can go here
ByteSwitch:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                addwf           PCL, f                          ; add ByteCount to PCL, store back to PCL...this tells you which 'switch case' you are going to
                goto            WriteByte1                      ; go to Byte1 processing
                goto            WriteByte2                      ; go to Byte2 processing
                goto            WriteByte3                      ; go to Byte3 processing
                goto            WriteByte4                      ; go to Byte4 processing
                goto            WriteByte5                      ; go to Byte5 processing
                goto            WriteByte6                      ; go to Byte6 processing
                goto            WriteByte7                      ; go to Byte7 processing
                goto            WriteByte8                      ; go to Byte8 processing
                goto            WriteByte9                      ; go to Byte9 processing
                goto            WriteByte10                     ; go to Byte10 processing
                goto            WriteByte11                     ; go to Byte11 processing
                goto            WriteByte12                     ; go to Byte12 processing

;
;	Macro for sending a literal data through the SSP
;	The argument is the literal data to be sent
;
;ISR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InterruptServiceRoutine
Push:
                movwf           W_TEMP                          ; Copy W to TEMP register
                swapf           STATUS, W                       ; Swap status to be saved into W
                movwf           STATUS_TEMP                     ; Save status to STATUS_TEMP register
                movf            PCLATH,W
                movwf           PCLATH_TEMP

;               Test for receive interrupt
                banksel         PIR1
                btfss           PIR1,RCIF                       ; test to see if a receive caused the interrupt
                goto            TOF_test
                goto            HandleReceive                   

HandleReceive:
                banksel         RCREG
                movf            RCREG,w                         ; move the contents of the receive register to W/clear flag
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                movwf           temp_received                   ; put byte into temp_received variable
;               Prepare to use the byte switch variable
                movf            byte_count,w
                goto            ByteSwitch                      ; go to the ByteSwitch table

TOF_test:
;               Test for timer overflow
                banksel         PIR1
                btfss           PIR1,TMR2IF                     ; test to see if the timer 2 overflow flag is set
                goto            Pop
;               increment timer overflow counters                
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                incf            send_tof_count,F                  ; increment the sendout timer overflow count
                movlw           SENDOUT_TOF
                xorwf           send_tof_count,W
                btfss           STATUS,Z                        ; if Z = 1, then the send overflow count has reached our value
                goto            StandownTimer
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                bsf             send_flag, 0                    ; set bit 0 of SendFlag to show that the timer is over
                goto            StandownTimer

StandownTimer:
;               Standown timer overflow counter
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0     
                incfsz          Standown_Timer_LSB              ; increment the standown timer low byte        
                goto            Pop
                incf            Standown_Timer_MSB              ; denote the rollover by incrementing standown  timer high byte 
                goto            Pop

;               write the first byte to memory
WriteByte1:        
                movlw           START_BYTE                      ; test to see if this "first" byte is the actual start byte
                xorwf           temp_received,w
                btfss           STATUS,Z                        ; if Z = 1, then this is the start byte
                goto            ClearByteCount                  ; something bad happened
                movf            temp_received,w
                movwf           byte_1                          ; move this data into byte_1 variable
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte count (= 1)
                goto            Pop

;               write the second byte to memory               
WriteByte2:                    
                movlw           LENGTH_MSB                      ; test to see if this "second" byte is correct
                xorwf           temp_received,w
                btfss           STATUS,Z                        ; if Z =1, then this is length_msb byte
                goto            ClearByteCount                  ; something bad happened
                movf            temp_received,w
                movwf           byte_2                          ; move this data into byte_2
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte count (= 2)
                goto            Pop

;               write the third byte to memory
WriteByte3:                     
                movlw           LENGTH_LSB                      ; test to see if this "third" byte is correct
                xorwf           temp_received,w
                btfss           STATUS,Z                        ; if Z = 1, then this is length_lsb byte
                goto            ClearByteCount                  ; something bad happened
                movf            temp_received,w
                movwf           byte_3                          ; move this data into byte_3
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte count (= 3)
                goto            Pop

;               write the fourth byte to memory
WriteByte4:
                movf            temp_received,w
                movwf           byte_4                          ; move this data into byte_4
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte count (= 4)
                goto            Pop

;               write the 5th byte to memory
WriteByte5:
                movf            temp_received,w                 
                movwf           byte_5                          ; move this data into byte_5
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte_count (= 5)
                goto            Pop

;               write the 6th byte to memory
WriteByte6:
                movf            temp_received,w
                movwf           byte_6                          ; move this data into byte_6
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte_count (= 6)
                goto            Pop

;               write the 7th byte to memory
WriteByte7:
                movf            temp_received,w
                movwf           byte_7                          ; move this data into byte_7
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte_count (= 7)
                goto            Pop
WriteByte8:
                movf            temp_received,w
                movwf           byte_8                          ; move this data into byte_8
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte_count (= 8)
                goto            Pop
WriteByte9:
                movf            temp_received,w
                movwf           byte_9                          ; move this data into byte_9
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte_count (= 9)
                goto            Pop
WriteByte10:
                movf            temp_received,w
                movwf           byte_10                         ; move this data into byte_10
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte_count (= 10)
                goto            Pop
WriteByte11:
                movf            temp_received,w
                movwf           byte_11                         ; move this data into byte_11
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte_count (= 11)
                goto            Pop
WriteByte12:
                movf            temp_received,w
                movwf           byte_12                         ; move this data into byte_12
                clrf            temp_received                   ; clear the temp_received variable
                incf            byte_count,f                    ; increment byte_count (= 12)
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                bsf             full_packet,0                   ; set bit 0 of full packet variable, received 12 bytes
                goto            Pop

ClearByteCount:
                bcf             STATUS,RP0      
                bcf             STATUS,RP1                      ; switch to bank 0
                clrf            full_packet                     ; clear the full_packet variable
                clrf            byte_count                      ; clear the byte_count variable
                goto            Pop             
                

Pop:
;               Clear interrupt flags
                banksel         PIR1
                bcf             PIR1,TMR2IF

                movf            PCLATH_TEMP,W
                movwf           PCLATH
                swapf           STATUS_TEMP, W                  ; swap nibbles in STATUS_TEMp register and place result in W
                movwf           STATUS                          ; Move W into STATUS register (sets bank to original state)
                swapf           W_TEMP, F                       ; Swap nibbles in W_TEMP and place result into W_TEMP
                swapf           W_TEMP, W                       ; Swap nibbles in W_TEMP and place result into W    
                retfie

;Main program
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main:
;               INITIALIZATION SEQUENCE 
                pagesel         Initialize                      ; general init for SCI Tx, Rx and iButton
                call            Initialize

                pagesel         debuginit
                call            debuginit

foreverloop:

teststate1:
                btfss           current_state,WAIT_IBUTTON_BT
                goto            teststate2
                call            wait_for_ibutton

teststate2:
                btfss           current_state,WAIT_HELM_BT
                goto            teststate3
                call            wait_for_helm

teststate3:
                btfss           current_state,PLAY_GAME_BT
                goto            teststate4
                call            play_game

teststate4:
                btfss           current_state,STAND_DOWN_BT
                goto            foreverloop
                call            stand_down

                goto            foreverloop
;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
debuginit:

                ;Debugging ports
                banksel         TRISA
                bcf             TRISA,2
                bcf             TRISA,1
                banksel         ANSEL
                bcf             ANSEL,ANS2
                bcf             ANSEL,ANS1
                banksel         PORTA
                bcf             PORTA,2   
                bcf             PORTA,1            


return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Initialize:



                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
                ;InitializeiButton
                ;Sets port A0 as a digital I/O line
                ;Configures timer 1, uses 10 MHz external resonator
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;	Configure ports, set up timer 1
;
;	Port A0 set up				
	banksel	ANSEL
	bcf	ANSEL,ANS0	                ; Configure A0 as digital I/O
;		

					
;	Timer 1 set up
	banksel 	T1CON
	bsf	T1CON,TMR1ON	                ; Enable timer 1
	bcf	T1CON,TMR1CS	                ; Use internal clock 
	bcf	T1CON,T1CKPS1	                ; Set clock prescale to 1:1
	bcf	T1CON,T1CKPS0			
;
;	Set up output compare for timers
	banksel	CCP1CON
                bsf     	CCP1CON,CCP1M3                  ; set C5 up for output compare
                bcf    	CCP1CON,CCP1M2                  ; 1011, will generate software
                bsf     	CCP1CON,CCP1M1                  ; interrupt on match
                bcf     	CCP1CON,CCP1M0  
;					
	bcf	PIR1,CCP1IF		; clear the output compare flag
;
;
;	Initializlie the Serial Number counters and variables
;
                bcf             STATUS,RP0      
                bcf             STATUS,RP1                      ; switch to bank 0
	movlw	LOOP_COUNT		; set loop count to 16
	movwf	loop_count
	movlw	BIT_COUNT		; set bit count to 0
	movwf	bit_count
	clrf	first_byte_full	                ; family byte is initially empty
	clrf	second_byte_full                ; low byte is initially empty
                ;

                ;Clear relevant data.
                clrf            SN_High_byte
                clrf            SN_Low_byte



                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
                ;Initializethe EUSART
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                ; NOTE: ANSEL config is necessary for RX line
                banksel         ANSELH
                bcf             ANSELH, ANS11                   ; RX as ditigal I/O
                banksel         TRISB
                bsf             TRISB, TRISB5                   ; B5 as input for RX line
                nop
                bcf             TRISB, TRISB7                   ; B7 as output for TX line
                ;	
	banksel         SPBRG
	movlw	BAUDRATEX                     	; set X value for Baud Rate Generator --> this is d'64' to get 9600 baud rate
	movwf	SPBRG
                ;
	bcf	TXSTA,SYNC		; set config for Baud Rate Generator
	bcf	BAUDCTL,BRG16	               	; set config for Baud Rate Generator
	bsf	TXSTA,BRGH		; set config for Baud Rate Generator
                ;	
	banksel         RCSTA	                ; switch banks to configure EUSART	
	bcf	RCSTA,RX9		; configure for 8-bit reception
                nop
	bsf	RCSTA,CREN		; enable continuos receive
                nop
                bsf	RCSTA,SPEN		; set up EUSART

	banksel         TXSTA		; switch banks to enable trasmit
	bsf	TXSTA,TXEN		; transmit enable
                
                banksel         PIE1
                bsf             PIE1,RCIE                       ; enable receive interrupt
                banksel         PIR1
                bcf             PIR1,RCIF                       ; initially clear the receive interrupt flag

                ; clear related variables
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                clrf            byte_count                      ; initially clear byte_count
                bcf             full_packet,0                     ; initially clear full_packet


                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
                ;Initialize timer 2
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                banksel         T2CON
                bsf             T2CON, TMR2ON                   ; Enable timer 2
                bsf             T2CON, T2CKPS1                  ; Set clock prescale to 1:16
                bcf             T2CON, T2CKPS0 
                bcf             T2CON, TOUTPS0
                bcf             T2CON, TOUTPS1
                bcf             T2CON, TOUTPS2
                bcf             T2CON, TOUTPS3                  ; Set postscale 1:1

                ; Timer overflow (TMR2IF is triggered)
                banksel         PR2                             ; go to PR2 register
                movlw           0xFF                            ; make PR2 count all the way up to 255
                movwf           PR2                             ; move 0xFF into PR2

                ; Enable timer 2 overflow interrupts
                banksel         PIE1
                bsf             PIE1,TMR2IE                     ; enable timer 2 overflow interrupts
                banksel         PIR1            
                bcf             PIR1,TMR2IF                     ; initially clear timer 2 overflow flag

                ; clear related variables                
                bcf             STATUS,RP0
                bcf             STATUS, RP1                     ; switch to bank 0
                clrf            send_tof_count                  ; initially clear timer 2 overflow count
                clrf            send_flag                       ; initially clear send_flag

                ; Clear flags for the standown timer.
                clrf            Standown_Timer_LSB              ;count down timer
                clrf            Standown_Timer_MSB
                
                
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
                ; Initialize SSP
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                banksel	SSPSTAT		; The Sync Serial Port Status Register (pg 180 of manual)
                bsf	SSPSTAT,SMP		; Input data sampled at end of data output line. (clear for Slave mode)
                nop
                bsf	SSPSTAT,CKE		; Data transmitted on falling edge of SCK
                nop		
                
                banksel         SSPCON		; The Sync Serial Port Control Register (pg 181 of manual)
                bsf	SSPCON,SSPEN	                ; SSP enable bit.
                nop			
                bsf	SSPCON,CKP		; Clock polarity Select Bit; transmit happens on rising edge, receive on falling edge
                nop
                ;The SSP mode select. 
                ;This is for the Master mode: with clock = FOSC/64
                bcf	SSPCON,SSPM3	
                nop
                bcf	SSPCON,SSPM2	
                nop
                bsf	SSPCON,SSPM1	
                nop
                bcf	SSPCON,SSPM0	
                nop
                banksel	ANSELH
	bcf	ANSELH,1		; Sets the ANSEL9 (RC7) to digital input/output
	nop
	bcf	ANSELH,2		; Sets the ANSEL10 (RB4) to digital input/output.
		
	banksel	TRISC
                bcf	TRISC,7		; Set the Data direction to output for the SDO for the SSP
	nop
                bsf	TRISB,4		; Set the Data direction to input for the SDO for the SSP		
	nop                

                banksel	TRISB
                bcf	TRISB,6		; Clear the SCK to output for MASTER MODE on TRISB 6								
                nop
                ;bsf	TRISB,6		; SET the SCK to input for SLAVE MODE on TRISB 6								
                ;nop
                	
	;This is setting up the slave select line.
	banksel	ANSELH
	bcf	ANSELH,ANS8		; This is to set control of the Slave select line.
		
	banksel	TRISC				
	bcf	TRISC,6		; Clears the bit so that the SS is output (This is for MASTER)
	nop
	;bsf	TRISC,6		; Sets the bit so that the SS is input (this is for SLAVE)
	;nop
                banksel         ANSEL                           ; slave select line for Right Motor PIC
                bcf             ANSEL,4
                
                banksel         TRISC                           ; slave select line for Right Motor PIC
                BCF             TRISC,0

                banksel         PORTC
	bsf	PORTC,6

                ;this is setting a default LED_state
                bcf             STATUS,RP0      
                bcf             STATUS,RP1                      ; switch to bank 0
                movlw           0x00
                movwf           led_data

                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
                ; Enable Interrupts
                ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                banksel         INTCON                          ; go to bank with INTCON
                bsf             INTCON, GIE                     ; enable global interrupt
                bsf             INTCON, PEIE                    ; enable peripheral interrupt



                ;Start in waiting for ibutton state.ASDF
                movlw           WAIT_HELM_st
                movwf           current_state



                ;Debugging Code:
                movlw           0x59
                movwf           SN_High_byte 

                movlw           0xF1
                movwf           SN_Low_byte 
               return

;Section of ibutton code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;Pause500
;Creates a 500 usec pause and then returns
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pause500:

	banksel	PIR1
	movlw	LO_500
	movwf	CCPR1L		
	movlw	HI_500		; Set up value in CCPR1
	movwf	CCPR1H
	clrf	TMR1H		; Clear the timer
	clrf	TMR1L
	bcf	PIR1,CCP1IF		; Clear the OC flag	
Check500Timer:
	pagesel         Check500Timer
                btfss	PIR1,CCP1IF		; Check output compare flage
	goto	Check500Timer	                ; Loop if flag is not set 
                pagesel         Timer500Expired
	goto	Timer500Expired
Timer500Expired:
	bcf             PIR1,CCP1IF                     ; clear the output compare flag
	return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;Pause50
;Creates a 50 usec pause and then returns
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pause50:
;
	banksel	PIR1				
	movlw	HI_50	                ; Set up value in CCPR1
	movwf	CCPR1H
	movlw	LO_50
	movwf	CCPR1L
	clrf	TMR1H		; Clear the timer
	clrf	TMR1L	
	bcf	PIR1,CCP1IF		; Clear OC flag
Check50Timer:
                pagesel         Check50Timer
	btfss	PIR1,CCP1IF     	; Check output compare flage
	goto	Check50Timer	                ; Loop if flag is not set 
                pagesel         Timer50Expired
	goto	Timer50Expired
Timer50Expired:
	bcf     	PIR1,CCP1IF                     ; clear the output cmpare flag
	return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;Pause40
;Creates a 40 usec pause and then returns
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pause40:
;
	banksel	PIR1				
	movlw	HI_40		; Set up value in CCPR1
	movwf	CCPR1H
	movlw	LO_40
	movwf	CCPR1L
	clrf	TMR1H		; Clear the timer
	clrf	TMR1L	
	bcf	PIR1,CCP1IF		; Clear OC flag
Check40Timer:
	pagesel         Check40Timer
                btfss	PIR1,CCP1IF		; Check output compare flage
	goto	Check40Timer	                ; Loop if flag is not set 
                pagesel         Timer40Expired
	goto	Timer40Expired
Timer40Expired:
	bcf     	PIR1,CCP1IF                     ; clear the output compare flag
	return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;Pause5
;Creates a 5 usec pause and then returns
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pause5:
;	
Check5Timer:
	nop
	nop
	nop
	nop
	nop
	nop	                                ; simply use nops here
	nop	                                ; only 5 usec pause
	return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;Pause75
;Creates a 75 usec pause and then returns
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pause75:
	;
	banksel	PIR1							
	movlw	HI_75		; Set up value in CCPR1
	movwf	CCPR1H
	movlw	LO_75
	movwf	CCPR1L
	clrf	TMR1H		; Clear the timer
	clrf	TMR1L	
	bcf	PIR1,CCP1IF		; Clear the OC flag	
Check75Timer:
	pagesel         Check75Timer
                btfss	PIR1,CCP1IF		; Check output compare flage
	goto	Check75Timer	                ; Loop if flag is not set 
                pagesel         Timer75Expired
	goto	Timer75Expired
Timer75Expired:
	bcf     	PIR1,CCP1IF                     ; clear the output compare flag
	return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;Pause60
;Creates a 60 usec pause and then returns
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pause60:
;
	banksel	PIR1		; Clear the OC flag			
	movlw	HI_60		; Set up value in CCPR1
	movwf	CCPR1H
	movlw	LO_60
	movwf	CCPR1L
	clrf	TMR1H	                ; Clear the timer
	clrf	TMR1L	
	bcf	PIR1,CCP1IF		
Check60Timer:
	pagesel         Check60Timer
                btfss	PIR1,CCP1IF		; Check output compare flage
	goto	Check60Timer	                ; Loop if flag is not set        
                pagesel         Timer60Expired
	goto	Timer60Expired
Timer60Expired:
	bcf     	PIR1,CCP1IF                     ; clear the output compare flag
	return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;iButtonFind 
;Reads and writes iButton line until an iButton is found
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iButtonFind:
;
iButton_check_admiral:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0

                ;see if you got something from the admiral when waiting for your ibutton
                btfss           full_packet,0
                goto            iButtonFindLoop
                call            HandlePacket
                
                ;It's ok to immediately respond when you get a packet.
                bsf             send_flag,0
                
                ;Check if the command is from the admiral
                movlw           ADMIRAL
                xorwf           Rx_Info_Byte0,W 
                btfss           STATUS,Z                        ;if Z == 1.  This is from the admiral
                goto            iButtonFindLoop
            
                ;Check if this is a ping command
                movlw           ADMIRAL_PING
                xorwf           Rx_Info_Byte2,W 
                btfss           STATUS,Z                        ;if Z == 1.  This is from the admiral
                goto            iButtonFindLoop
                
                ;Formulate the ping responds packet

                movlw           ADMIRAL_ADDRESS_MSB
                movwf           Tx_Destination_MSB

                movlw           ADMIRAL_ADDRESS_LSB
                movwf           Tx_Destination_LSB

                ;this is the ping responds header. This is constant and never changes
                movlw           PING_RESPONSE      
                movwf           Tx_Info_Byte0
                
                ;This the state that you are in with your ibutton pairing.
                ;0x01=waiting for ibutton
                ;0x02=ibutton read and waiting for pairing
                ;0x04=if ibutton is paired.
                movlw           WAITING_IBUTTON
                movwf           Tx_Info_Byte1

                ;Leat significant bit of paird helm/craft address (Send 0x00 if unpaired)
                movlw           UNPAIRED            
                movwf           Tx_Info_Byte2

                call            send_packet

iButtonFindLoop:
	banksel	TRISA
	bcf	TRISA,0		; Set A0 as an output
	banksel	PORTA
	bcf	PORTA,0		; Set A0 low
	nop
	call	Pause500		; Wait for 500 usec
	banksel	TRISA
	bsf	TRISA,0		; Set A0 as an input
	nop
	call	Pause50		; Wait for 50 usec
	banksel	PORTA
	btfss	PORTA,0		; Test the state of A0
	return
	goto	iButton_check_admiral           ; Repeat if no iButton found, will also check for admiral command
;
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;ResetSequence 
;Conducts reset sequence that must be done at the beginning of any new
;read
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ResetSequence:
	;
	banksel	TRISA
	bcf	TRISA,TRISA0	                ; Set A0 as an output
	nop
	banksel	PORTA
	bcf	PORTA,0		; Set A0 low
	nop
                pagesel         Pause500
                call            Pause500
                pagesel         Pause500
	call	Pause500		; Wait for 500 usec
	bsf	PORTA,0		; Set A0 high
	nop
                pagesel         Pause500
	call	Pause500		; Wait for 500 usec
	return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SendReadROM 
;Sends 0x33 out, LSB first
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SendReadROM:
;
;	The Read ROM command is sending 0x33 (00110011) out, LSB first
;
;	Run through Read ROM routine
	pagesel         WriteOne
                call	WriteOne
                pagesel         WriteOne
	call	WriteOne
                pagesel         WriteZero
	call	WriteZero
                pagesel         WriteZero
	call	WriteZero
                pagesel         WriteOne
	call	WriteOne
                pagesel         WriteOne
	call	WriteOne
                pagesel         WriteZero
	call	WriteZero
                pagesel         WriteZero
	call	WriteZero
	return
;
WriteOne:
	banksel	TRISA
	bcf	TRISA,TRISA0	                ; Set A0 as an output
	nop		
	banksel	PORTA
	bcf	PORTA,0		; Set A0 as low
	nop
                pagesel         Pause5
	call	Pause5		; wait 5 usec
	banksel	TRISA
	bsf	TRISA,TRISA0	                ; Set A0 as input                
	nop
                pagesel         Pause5
	call	Pause5		; wait 5 usec
	nop
                pagesel         Pause5
	call	Pause5		; wait 5 usec
	nop
                pagesel         Pause60
	call	Pause60		; wait 60 usec
	return
;
WriteZero:
	banksel	TRISA
	bcf	TRISA,TRISA0	                ; Set A0 as an output
	nop		
	banksel	PORTA		
	bcf	PORTA,0		; Set A0 as low
	nop
                pagesel         Pause60
	call	Pause60		; wait 60 usec	
	banksel	TRISA
	bsf	TRISA,TRISA0	                ; Set A0 as input
	nop
                pagesel         Pause5
	call	Pause5		; wait 5 usec
	nop
                pagesel         Pause5
	call	Pause5		; wait 5 usec
	nop
                pagesel         Pause5
	call	Pause5		; wait 5 usec
	return	
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ReadiButton 
;Reads last two bytes of the SN and stores the information
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ReadiButton:
;
;	Will read out the LSB first
;
	nop
                pagesel         Pause5
	call	Pause5
	nop
                pagesel         Pause5
	call	Pause5
	nop
                pagesel         Pause5
	call	Pause5
First_Read:
	pagesel         Read_Family
                goto	Read_Family
;
ReadLoop:
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0
	movlw	0x01		; test status of low_byte_full
	xorwf	first_byte_full,W	; if Z=1, the low_byte is full
                pagesel         Read_Family
	btfss	STATUS,Z
	goto	Read_Family
	pagesel         Read_Low
                btfss	second_byte_full,W
	goto	Read_Low
                pagesel         Read_High
	goto	Read_High			
;			
DecreaseLoop:
                bcf             STATUS,RP1                      ;switch to bank 0 to
                bcf             STATUS,RP0
	incf	bit_count			
	pagesel         ReadLoop
                decfsz	loop_count
	goto	ReadLoop
	return	
;
Switch_Bytes1:
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0		; In this situation we only
	decf	loop_count		; increment loop count, bit count
                pagesel         ReadLoop
	goto	ReadLoop		; =0 again
;
Switch_Bytes2:	
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0		; In this situation we only
	decf	loop_count		; increment loop count, bit count
                pagesel         ReadLoop
	goto	ReadLoop		; =0 again		
;
Read_Family:		
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0
	rrf	SN_Family_byte,f
	banksel	TRISA
	bcf	TRISA,TRISA0		; Set A0 as an output
	nop
	banksel	PORTA
	bcf	PORTA,0		; Set A0 as low
	nop
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
	banksel	TRISA
	bsf	TRISA,TRISA0		; Set A0 as an input
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
	nop
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
	bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0
	btfsc	PORTA,0		; test state of A0
	bsf	SN_Family_byte,7
	nop
	movlw	0x07		; test status of bit count
	xorwf	bit_count,W		; Z=1 if bit_count=7
                pagesel         Last_Bit1
	btfsc	STATUS,Z
	goto	Last_Bit1
                pagesel         Pause50
	call	Pause50
                pagesel         DecreaseLoop
	goto	DecreaseLoop
;
Last_Bit1:
	nop
                pagesel         Pause40
	call	Pause40
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0
	bsf	first_byte_full,0	; set low_byte_full=1
	movlw	0x00
	movwf	bit_count		; reset bit_count for high byte
                pagesel         Switch_Bytes1
	goto	Switch_Bytes1
;
Read_Low:
                bcf             STATUS,RP1                      ;switch to bank 0 to
                bcf             STATUS,RP0
	rrf	SN_Low_byte,f
	banksel	TRISA
	bcf	TRISA,TRISA0		; Set A0 as an output
	nop
	banksel	PORTA
	bcf	PORTA,0		; Set A0 as low
	nop
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
	banksel	TRISA
	bsf	TRISA,TRISA0		; Set A0 as an input
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
	nop
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
	bcf             STATUS,RP1                      ;switch to bank 0 to
                bcf             STATUS,RP0
	btfsc	PORTA,0		; test state of A0
	bsf	SN_Low_byte,7
	nop
	movlw	0x07		; test status of bit coun
	xorwf	bit_count,W		; Z=1 if bit_count=7
	pagesel         Last_Bit2
                btfsc	STATUS,Z
	goto	Last_Bit2
                pagesel         Pause50
	call	Pause50
                pagesel         DecreaseLoop
	goto	DecreaseLoop
;
Last_Bit2:
	nop
                pagesel         Pause40
	call	Pause40
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0
	bsf	second_byte_full,0	; set low_byte_full=1
	movlw	0x00
	movwf	bit_count		; reset bit_count for high byte
                pagesel         Switch_Bytes2
	goto	Switch_Bytes2			
;
Read_High:
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0
	rrf	SN_High_byte,f
	banksel	TRISA
	bcf	TRISA,TRISA0		; Set A0 as an output
	nop
	banksel	PORTA		
	bcf	PORTA,0		; Set A0 as low
	nop
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
	banksel	TRISA
	bsf	TRISA,TRISA0		; Set A0 as an input
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
	nop
                pagesel         Pause5
	call	Pause5		; Wait 5 usec
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0
	btfsc	PORTA,0		; test state of A0
	bsf	SN_High_byte,7
                pagesel         Pause50
	call	Pause50
                pagesel         DecreaseLoop
	goto	DecreaseLoop			
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
send_packet:

;               Test the ability to have a .2 s pause before sends
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0

;               SendPause                
                btfsc           send_flag,0                     ; if the flag is set we can proceed to sending (this is the .2 second wait for the send)
                goto            PrePacketChecksum
                goto            end_send_packet                 ; timer is not expired, exit funtion

PrePacketChecksum:                
                call            CalculateCheckSum
                
PrePacketPause1:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause1

                ; SENDING START_DELIMETER Byte 1
                banksel         TXREG                           ; go to bank with TXREG. Both TXREG and SN_HIGH_BYTE is in bank 0
                movlw           START_BYTE                      ; move START_BYTE to W                
                movwf           TXREG                           ; move W to TXREG - this transmits the byte 

PrePacketPause2:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause2

                ; SENDING LENGTH_MSB Byte 2
                banksel         TXREG                           ; go to bank with TXREG.  Both TXREG and SN_HIGH_BYTE is in bank 0
                movlw           LENGTH_MSB                      ; move MSB of frame length to W
                movwf           TXREG                           ; move W to TXREG - this transmits the byte

PrePacketPause3:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause3

                ; SENDING LENGTH_LSB Byte 3
                banksel         TXREG                           ; go to bank with TXREG.  Both TXREG and SN_HIGH_BYTE is in bank 0
                movlw           LENGTH_LSB      ; move LSB of frame length to W
                movwf           TXREG   

PrePacketPause4:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause4

                ; SENDING API_IDENTIFIER Byte 4
                banksel         TXREG                           ; go to bank with TXREG.  Both TXREG and SN_HIGH_BYTE is in bank 0
                movlw           API_TX                          ; move LSB of frame length to W
                movwf           TXREG   

PrePacketPause5:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause5

                ; SENDING FRAME_ID Byte 5
                banksel         TXREG
                movlw           FRAME_ID        ; move FRAME_ID to W
                movwf           TXREG           ; move W to TXREG - this transmits the byte

PrePacketPause6:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause6

; SENDING MSB of Destination Address Byte 6
                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0
                movf            Tx_Destination_MSB,W ; move Craft MSB to W
                banksel         TXREG
                movwf           TXREG           ; move W to TXREG - this transmits the byte

PrePacketPause7:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause7

                 ; SENDING LSB of Destination Address Byte 7
                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0
                movf            Tx_Destination_LSB, W    ; move Craft LSB to W (this is the LSB of OUR craft) ** this will change once we start syncing to other boats!!
                banksel         TXREG
                movwf           TXREG           ; move W to TXREG - this transmits the byte

PrePacketPause8:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause8
       
                ; SENDING OPTIONS Byte (0x00) default Byte 8
                banksel         TXREG
                movlw           OPTIONS_DEFAULT ;move otpions default to W
                movwf           TXREG           ; move W to TXREg - this transmits the byte


PrePacketPause9:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause9

                ; SENDING ME218C Header (Data Byte 0) Byte 9
                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0     ; indicate that we are sending a command from the helm ** this can change once we start sending different types of messages!!
                movf            Tx_Info_Byte0, W
                banksel         TXREG
                movwf           TXREG           ; move W to TXREG - this transmits the byte


PrePacketPause10:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause10


                ; SENDING ME218C (Navigation Byte) Byte 10
                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0
                movf            Tx_Info_Byte1, W ; indicate that we are telling motors to turn off
                banksel         TXREG
                movwf           TXREG           ;move W to TXREG - this transmits the byte

PrePacketPause11:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause11

                ;SENDING ME218C Special Byte Byte 11
                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0
                movf            Tx_Info_Byte2,W    ; indicate that we are turning off all special functions
                banksel         TXREG
                movwf           TXREG           ; move W to TXREG - this transmits the byte

PrePacketPause12:
                banksel         TXSTA
                btfss           TXSTA, TRMT                     ; check to see if the transmit register is clear
                goto            PrePacketPause12

                ;SENDING CHECK SUM
                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0
                movf            CheckSumValue, W ; this is a value calcualted by a special sub function ** DON"T FORGET TO WRITE THIS!!!!!!!!'
                banksel         TXREG
                movwf           TXREG           ; move CheckSumValue to W - this transmits the byte

                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                clrf            send_flag                       ; clear the send_flag
                clrf            send_tof_count                  ; clear the number of tof counts
     
end_send_packet:


                return

;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Calculating Check Sum
; This function calculates the check sum.  Check sum is calculated by: adding up the value of all bytes (excluding the Start delimter
; and frame length Bytes).  Keep only the lowest 8 bits of the result and subtract from 0xFF.  
; To verify that the checksum is correct, add all byte (excluding delimter and length but include the checksum).  If it is correct,
; the sum should = 0xFF.
; In our case, we will add up bytes 4 through 11 THIS IS IN THE CASE THAT WE'RE TRANSMITTING THIS WILL BE FOR THE PIC ON THE HELM
; DO WE NEED TO WORRY ABOUT THE CARRY BIT?  !!!!!!!!!!!!!!!!!! THIS IS A KARL QUESTION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CalculateCheckSum:
                bcf             STATUS,RP1                      ;switch to bank 0 to
                bcf             STATUS,RP0                      ; go to bank with CheckSumValue
                clrf            CheckSumValue                   ; clear value in checksum
Add_API:
                movlw           API_TX                          ; move API_TX to W
                addwf           CheckSumValue, f                ; add API_TX to CheckSumValue, store back in CheckSumValue

Add_FrameID:
                movlw           FRAME_ID                        ; move FRAME_ID to W
                addwf           CheckSumValue,f                 ; add FRAME_ID to CheckSumValue, store back in CheckSumValue 
Add_DestMSB:
                movf            Tx_Destination_MSB, W           ; move value in Destination_MSB to W
                addwf           CheckSumValue,f                 ; add Destination_MSB to CheckSumvalue, store back in CheckSumValue
            
Add_DestLSB:    
                movf            Tx_Destination_LSB,W            ; move value in Destinatino_LSB to W
                addwf           CheckSumValue,f                 ; add Destination_LSB to CheckSumValue, store back in CheckSumValue
Add_Options:
                movlw           OPTIONS_DEFAULT                 ; move options Default literal value (0x00) to W
                addwf           CheckSumValue,f                 ; add Options value to CheckSumValue, store back in CheckSumValue
Add_Header:
                movf            Tx_Info_Byte0, W                ; move value in Header_Byte to W
                addwf           CheckSumValue,f                 ; add Header_Byte value to CheckSumValue, store back in CheckSumValue
Add_Navigation:
                movf            Tx_Info_Byte1, W                ; move value in Navigation_Byte to W
                addwf           CheckSumValue, f                ; add Navigation_Byte value to CheckSumValue, store back in CheckSumValue
Add_Special:
                movf            Tx_Info_Byte2, W                ; move value in Special Byte to W
                addwf           CheckSumValue, f                ; add Special_Byte value to CheckSumValue, store back in CheckSumValue

; do we have to do anything special to keep the lowest 8 bits? or just assume that the variable registers are only 8 bits...?

                movf            CheckSumValue, W                ; move value in CheckSum to W
                sublw           0xFF                            ; 0xFF - CheckSumValue, result stored back into W
                movwf           CheckSumValue                   ; move results of subtraction back into CheckSumValue  
                return  


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SENDSSP_F:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	function for sending data from an address through the SSP
;	The argument is the address of the data to be sent
;
	;stores what was in the literal so that it can be restored.		

	banksel	PORTC
	bcf	PORTC,SLAVE_SELECT_LINE					;Set the SS low so that transmissions can be recieved.


                bcf             STATUS,RP0
                bcf             STATUS,RP1
	MOVF	tx_ssp_byte,W			;prep the W reg with your data to send.
	banksel	SSPBUF
	MOVWF	SSPBUF			;sends out your transmit data.	


sspcomplete:				; wait until the flag is set
	banksel	SSPSTAT
                pagesel         sspcomplete
	BTFSS	SSPSTAT, BF		; checks the status of the reg2 flag in the reg1 register.                
	GOTO 	sspcomplete 


	banksel         SSPBUF
	MOVF	SSPBUF, W				;contents of the SSBUF is now in w register
                bcf             STATUS,RP0
                bcf             STATUS,RP1
	MOVWF	rx_ssp_byte			;This is just done so that the BF Flag gets reset (data is thrown away)   
             

	banksel	PORTC
	bsf	PORTC,SLAVE_SELECT_LINE					;Set the SS high so that no more transmissions are sent.
		
return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Handle Packet Function
; This function will one day become more meaningful than this. I promise.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HandlePacket:                         

StoreData:

                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0
                

                movf            byte_6,W
                movwf           Rx_AddressLSB_Byte            ; move Byte 7 into Rx_AddressLSB_Byte
                      
                movf            byte_9,W     
                movwf           Rx_Info_Byte0                 ; move Byte9 into Rx_Info_Byte0
                
                movf            byte_10, W  
                movwf           Rx_Info_Byte1                 ; store Byte10 into Rx_Navigation Byte

                movf            byte_11,W
                movwf           Rx_Info_Byte2                ; store Byte 11 into Rx_Info_Byte2

                clrf            full_packet
                clrf            byte_count
                
                return

;               
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; RespondToMatch
; This function stores the appropriate data to Paired_Hull_LSB
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;respond_to_match:
;                bcf             STATUS,RP1                    ;switch to bank 0 to
;                bcf             STATUS,RP0
;                movf            Rx_AddressLSB_Byte,W
;                movwf           Paired_Hull_LSB              ; the sender's address is officially the address of our paired hull
;                movlw           CRAFT_MSB
;                movwf           Paired_Hull_MSB     
;
;                ;Store what boat you are controlling into the LSB
;                movf            Paired_Hull_LSB,W
;                ;movlw           0x06
;                movwf           led_data
;                bcf             led_data,4
;                bcf             led_data,5
;                bcf             led_data,6
;                bcf             led_data,7
;                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ping_response
; This function generates an appropriate ping response
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ping_response:

                ;Formulate the ping responds packet
                movlw           ADMIRAL_ADDRESS_MSB
                movwf           Tx_Destination_MSB

                movlw           ADMIRAL_ADDRESS_LSB
                movwf           Tx_Destination_LSB

                ;this is the ping responds header. This is constant and never changes
                movlw           PING_RESPONSE      
                movwf           Tx_Info_Byte0
                
                
                ;This the state that you are in with your ibutton pairing.
                ;0x01=waiting for ibutton
                ;0x02=ibutton read and waiting for pairing
                ;0x04=if ibutton is paired.
                btfss           current_state,WAIT_HELM_BT
                goto            paired_ping_response
                
                movlw           WAITING_PAIR
                movwf           Tx_Info_Byte1

                ;Leat significant bit of paird helm/craft address (Send 0x00 if unpaired)
                movlw           UNPAIRED            
                movwf           Tx_Info_Byte2

                
                goto            exit_ping_response

paired_ping_response:

                movlw           PAIRED
                movwf           Tx_Info_Byte1               
                
                ;Leat significant bit of paird helm/craft address (Send 0x00 if unpaired)
                movf            Paired_Helm_LSB,W            
                movwf           Tx_Info_Byte2

exit_ping_response:

                call            send_packet                
                
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; STATE MACHINE STATES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wait_for_ibutton:


                banksel         PORTA
                bcf             PORTA,1

	call	iButtonFind
	call	ResetSequence
	call	SendReadROM
	call	ReadiButton

                movlw           WAIT_HELM_st
                movwf           current_state
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wait_for_helm:

                
;
                banksel         PORTA
                bsf             PORTA,1
;
                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0
                                
                ;see if you got some kind of communications or else you would just exit.
                btfss           full_packet,0
                goto            exit_wait_for_helm
                call            HandlePacket;	
                bsf             send_flag,0
;

;
wait_for_helm_check_admiral:

                
                ;we are checking to see if the packet is from the admiral.  If it isn't from the admiral then you don't have to do anything else with it.
	movlw           ADMIRAL
                xorwf           Rx_Info_Byte0,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            wait_for_helm_record_ibutton

                ;it is from the admiral and we want to see if it is a hard reset                
                movlw           HARD_RESET
                xorwf           Rx_Info_Byte2,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            wait_for_helm_check_ping
                
                ;It is a hard reset so change the state and exit this state:
                movlw           WAIT_IBUTTON_st
                movwf           current_state 

                goto            exit_wait_for_helm

wait_for_helm_check_ping:
                movlw           ADMIRAL_PING
                xorwf           Rx_Info_Byte2,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            exit_wait_for_helm

                ;It is now a Ping command from the admiral we will respond to ping and then continue broadcast the ibutton

                call            ping_response
                
                goto            exit_wait_for_helm


wait_for_helm_record_ibutton:

;check if it is a ibutton broadcast
     
  ;we are checking to see if the packet is from the admiral.  If it isn't from the admiral then you don't have to do anything else with it.
	movlw           IBUTTON
                xorwf           Rx_Info_Byte0,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            exit_wait_for_helm              ;if the broadcast command is not a ibutton do this
                goto            CheckSerialNumber               ;if the command is a ibutton then do this


;See if your serial number matches the broadcast one so that you can go on to the next state
CheckSerialNumber:
                ; check the bytes 

TestSNHighByte:

                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0


                movf            Rx_Info_Byte1, W           ; move contents of Rx_Navigation_Byte into W
                xorwf           SN_High_byte,W                    ; xor OUR SN_high_byte with the serial number you just received
                pagesel         No_Match
                btfss           STATUS, Z                       ; check to see if the serial high byte we just received is equal to our SN_high_byte
                goto            No_Match                        ; Z=0, so the high serial byte we just received is NOT equal to our SN_High_byte
                pagesel         TestSNLowByte
                goto            TestSNLowByte                   ; Z=1.  The high byte matches, so we need to check the low byte

TestSNLowByte:

                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0

                movf            Rx_Info_Byte2, W              ; move contents of Rx_Special_Byte into W
                xorwf           SN_Low_byte,W                    ; xor OUR SN_Low_byte with the serial number we just received
                pagesel         No_Match
                btfss           STATUS, Z                       ; check to see if the serial low byte we just received is equal to our SN_low_byte
                goto            No_Match                        ; Z=0, so the low serial byte we just received is not equal to our SN_low_byte
                pagesel         Match
                goto            Match                           ; we have a match!

No_Match:       ;No match so don't do anything
                pagesel         exit_wait_for_helm
                goto            exit_wait_for_helm

Match: 

                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0

                ;save the LSB of the helm so that you can filter out your messages:
                movf            Rx_AddressLSB_Byte,W
                movwf           Paired_Helm_LSB

                ;Change states:
                movlw           PLAY_GAME_st
                movwf           current_state          

                goto            exit_wait_for_helm 


exit_wait_for_helm:
              

                return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
play_game:


                banksel         PORTA
                bsf             PORTA,1
;
                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0
                                
                ;see if you got some kind of communications or else you would just exit.
                btfss           full_packet,0
                goto            exit_playing_game
                call            HandlePacket;	
                bsf             send_flag,0

play_game_check_admiral:
   
                ;we are checking to see if the packet is from the admiral.  If it isn't from the admiral then you don't have to do anything else with it.
	movlw           ADMIRAL
                xorwf           Rx_Info_Byte0,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            play_game_check_from_helm_ibutton

                ;it is from the admiral and we want to see if it is a hard reset                
                movlw           HARD_RESET
                xorwf           Rx_Info_Byte2,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            play_game_check_ping
                
                ;It is a hard reset so change the state and exit this state:
                movlw           WAIT_IBUTTON_st
                movwf           current_state 

                goto            exit_wait_for_helm

play_game_check_ping:
                movlw           ADMIRAL_PING
                xorwf           Rx_Info_Byte2,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            exit_playing_game

                ;It is now a Ping command from the admiral we will respond to ping and then continue broadcast the ibutton

                call            ping_response
                
                goto            exit_playing_game


play_game_check_from_helm_ibutton:

                ;we are checking to see if the packet is from the helm and is a ibutton.
	movlw           IBUTTON
                xorwf           Rx_Info_Byte0,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            play_game_check_from_helm_nav


                ;we are checking to see if the lsb matches what you have.
	movf            Paired_Helm_LSB,W
                xorwf           Rx_AddressLSB_Byte,W
                btfss           STATUS,Z                        ;If Z==1 the command is from admiral
                goto            play_game_check_from_helm_nav                

play_game_send_out_matched:
                ;Send out a matched command                

                bcf             STATUS,RP1                    ;switch to bank 0 to
                bcf             STATUS,RP0

                ;we are prepping the send packet for a broadcast of the ibutton   
                movlw           HELM_MSB
                movwf           Tx_Destination_MSB

                movf            Paired_Helm_LSB,W
                movwf           Tx_Destination_LSB

                movlw           MATCHED_0
                movwf           Tx_Info_Byte0

                movlw           MATCHED_1  
                movwf           Tx_Info_Byte1

                movlw           MATCHED_2 
                movwf           Tx_Info_Byte2

                call            send_packet                     ;Send packet does nothing if you 

                goto            exit_playing_game

play_game_check_from_helm_nav

                goto            exit_playing_game

exit_playing_game:

                ;movlw           STAND_DOWN_st
                ;movwf           current_state 
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
stand_down:           
     
exit_stand_down:

                movlw           WAIT_IBUTTON_st
                movwf           current_state
                return


;
;
                
END