ME 218C Final Project
Introduction Mechanical
Hardware
Electrical
Hardware
Software Gems of
Wisdom
Pictures/
Video
Links

_HMstrFinal.asm

; Final Project - Terman Pond Flotilla
; ME218C
; -----------------------------------------------------------------
;
;
	list 	P=PIC16F690
	#include 	"p16F690.inc"
	__config 	(_CP_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _INTOSCIO)

;   Variable declared here
;   --------------------------------------------------------------------
	#include	vars.h

;   Beginning of Program
;   --------------------------------------------------------------------
	org	0
	goto	Main
	org	5

; ******************************************************************************
;	Interrupt
; ******************************************************************************
; ******************************************************************************
; If you add new interrupts, then check to make sure you end in bank 0!!!
Interrupt:
;	PUSH
	MOVWF	W_TEMP	; Copy W to TEMP register
	SWAPF	STATUS, W	; Swap status to be saved into W
	banksel	PORTA
	MOVWF	STATUS_TEMP	; Save status to STATUS_TEMP register
;	ISR
	BTFSC	PIR1, RCIF
	CALL	EUSART_Rx_Int
	BTFSC	INTCON, T0IF
	CALL	Timer0_Int
;	POP
	SWAPF	STATUS_TEMP, W	; Swap nibbles in STATUS_TEMP register
			; and place result into 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 in W_TEMP
	SWAPF	W_TEMP, W	; Swap nibbles in W_TEMP and place result into W	
	RETFIE

EUSART_Rx_Int:
;	Clear flag first
	BCF	PIR1, RCIF
	BTFSC	COM_rxFlag, 3
	GOTO	AllFlagsClear
	BTFSC	COM_rxFlag, 2
	GOTO	CheckFor0x81
	BTFSC	COM_rxFlag, 1
	GOTO	CheckFor0x08
	BTFSC	COM_rxFlag, 0
	GOTO	CheckFor0x00
CheckFor0x7E:	MOVLW	0x7E
	SUBWF	RCREG, W
	BTFSS	STATUS, Z
	GOTO	SomethingWrong
	BSF	COM_rxFlag, 0
	RETURN
CheckFor0x00:	MOVF	RCREG, F
	BTFSS	STATUS, Z
	GOTO	SomethingWrong
	BSF	COM_rxFlag, 1
	RETURN
CheckFor0x08:	MOVLW	0x08
	SUBWF	RCREG, W
	BTFSS	STATUS, Z
	GOTO	SomethingWrong
	BSF	COM_rxFlag, 2
	RETURN
CheckFor0x81:	MOVLW	0x81
	SUBWF	RCREG, W
	BTFSS	STATUS, Z
	GOTO	SomethingWrong
	BSF	COM_rxFlag, 3
	RETURN
AllFlagsClear:
;	Read data into appropriate index of receiving buffer
	MOVLW	COM_rxBuffAddr
	ADDWF	COM_rxIndex, W
	MOVWF	FSR
;	Read data
	MOVF	RCREG, W
	MOVWF	INDF
;	Increment the index
	INCF	COM_rxIndex, F
	MOVF	COM_rxIndex, W
	SUBLW	COM_rxLn
	BTFSS	STATUS, Z
;	index is not equal to array length, just return
	RETURN
;	index is equal to array length, API frame is done
	CLRF	COM_rxFlag
	CLRF	COM_rxIndex
	BSF	COM_rxFlag, COM_rxDone
	RETURN		

SomethingWrong:
	CLRF	COM_rxIndex
	CLRF	COM_rxFlag
	RETURN

Timer0_Int:
	BCF	INTCON, T0IF
	DECFSZ	Timer0Count, F
	RETURN
;	If the counter finished, reset it and set a flag
	MOVLW	Timer0Max
	MOVWF	Timer0Count
	BSF	Timer0Flag, 0

	RETURN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	#include	adc.h
	#include	helminits.h
	#include	xbee_comm.h
	#include	ibutton.h
	#include	synch.h


Initialize:
	banksel	ANSEL
	CLRF	ANSEL
	CLRF	ANSELH
; 	Setup ADC
	CALL	ADC_Init
;	Set to 8 MHz
	CALL	Clock_Init
;	Setup EUSART
	CALL	EUSART_Init
;	Setup PWM
	CALL	PWM_Init
;	Setup SPI
	CALL	SPI_Init
;	Setup LEDs
	CALL	LED_Init
;	Setup Switches/buttons
	CALL	Input_Init
;	Setup Timer0
	CALL	Timer0_Init
;	Enable Interrupts
	banksel	INTCON
	BSF	INTCON, GIE
	BSF	INTCON, PEIE
	RETURN


InitializeGameStates:
	banksel	PORTA
	CLRF	FLAG
	MOVLW	0x01
	MOVWF	PING_Data2
	CLRF	PING_Data3
	CLRF	CraftAddrH
	CLRF	CraftAddrL
	CLRF	COM_rxIndex
	CLRF	COM_rxFlag
	CLRF	StandDownTimer2

	MOVLW	0x00
	MOVWF	COM_frameid
	MOVLW	0x01
	MOVWF	COM_options
;	RESET TEAM, CRAFT#, ACTIVE BASE, STAND DOWN INDICATORS 
	MOVLW	0xff
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit


	RETURN

;********************************************************************************	
;********************************************************************************
;	Main Loop
;   --------------------------------------------------------------------
;   Continuously loops and handles the program
;       Looks for a button press, looks for a received message on EUSART
;       If slave select raised transmits message or ack
;********************************************************************************
;********************************************************************************
Main:


	CALL	Initialize
	CALL	InitializeGameStates
	CALL	Waiting_for_iButton
	CALL	ToggleLED
	CALL	Waiting_for_Sync
	CALL	ToggleLED

; WAIT FOR THE GAME TO START HERE
PNT:
	BTFSC	FLAG, Hard_Reset_Flag
	GOTO	Main
	CALL	CheckTimer0Flag
	CALL	CheckInputs
	CALL	SetupNavRegs
	CALL	APIRx
	GOTO	PNT

Check_Team:
	banksel	PORTA
	MOVLW	b'10001001'	; red
	MOVWF	SPI_TXDATA
	BTFSC	iButtonReadingM, 0
	GOTO	$+3
	MOVLW	b'10001000'	; blue
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit
	
	RETURN

Indicate_Craft_Num:
;	INDICATE CRAFT NUM HERE 
	banksel	PORTA
	MOVLW	0x04
	MOVWF	PING_Data2
	MOVF	CraftAddrL, W
	MOVWF	PING_Data3
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit
	RETURN

;   Interpret the user inputs to the helm to get water speed, specials, speed, and direction
CheckInputs:
;	Get Speed
	ADC_SelectChan	ADC_AN4
	BSF 	ADCON0,GO	;Start conversion
	BTFSC	ADCON0,GO	;Is conversion done?
	GOTO	$-1	;No, test again
	banksel	PORTA
	MOVF	ADRESH, W	;Read upper 8 bits
	MOVWF	Speed
;	Put speed in PWM
	banksel	CCPR1L
	MOVWF	CCPR1L
	banksel	PORTA
;	Are we going backwards or forwards?
	RRF	Speed, W	; Divide by two and store in W
	ANDLW	0x7F
;	Forwwards - add to 8, Backwards - subtract from 8
	BTFSS	PORTA, 3
	GOTO	Forwards
Backwards:	SUBLW	0x80
	MOVWF	Speed	; Store new speed
	GOTO	GetDir
Forwards:	ADDLW	0x80
	MOVWF	Speed

;	Get Direction
GetDir:	ADC_SelectChan	ADC_AN6
	BSF 	ADCON0,GO	;Start conversion
	BTFSC	ADCON0,GO	;Is conversion done?
	GOTO	$-1	;No, test again
	banksel	PORTA
	MOVF	ADRESH, W	;Read upper 8 bits
	MOVWF	Direction
;    	Direction calibration
                MOVLW     	b'01000000'
                SUBWF     	Direction, F
                BTFSS     	STATUS, C
                CALL      	Set_Direction_Min
                RLF       	Direction, F
                BTFSC     	STATUS, C
                CALL      	Set_Direction_Max
	GOTO	GetWaterS
Set_Direction_Min:
                MOVLW     	0x00
                MOVWF     	Direction
                GOTO	GetWaterS
Set_Direction_Max:
	MOVLW     	0xff
	MOVWF     	Direction

;	Get Specials Inputs
	BTFSS	PORTC, 3
	GOTO	$+3
	BSF	Specials, 0
	GOTO	$+2
	BCF	Specials, 0
	BTFSS	PORTC, 4
	GOTO	$+3
	BSF	Specials, 1
	GOTO	$+2
	BCF	Specials, 1

;	Get Water strength
GetWaterS:	ADC_SelectChan	ADC_AN5
	BSF 	ADCON0,GO	;Start conversion
	BTFSC	ADCON0,GO	;Is conversion done?
	GOTO	$-1	;No, test again
	banksel	PORTA
	MOVF	ADRESH, W	;Read upper 8 bits
	MOVWF	WaterStrength

	BTFSS	PORTA, 2
	GOTO	$+3
	BTFSS	FLAG, End_Game_Flag
	RETURN
;	if End_Game command received, disable water strength
	CLRF	WaterStrength
	RETURN

;   Once all ship control parameters are known, setup navigation registers
;   to hold the data for transfer over the Xbee
SetupNavRegs:
;	Setup Navigation Byte 1 with speed and direction info
	banksel	PORTA
	MOVF	Speed, W
	MOVWF	NavByte1
	RRF	NavByte1, F
	RRF	NavByte1, F
	RRF	NavByte1, F
	RRF	NavByte1, F
	MOVLW	0x0F
	ANDWF	NavByte1, F
	MOVLW	0xF0
	ANDWF	Direction, W
	IORWF	NavByte1, F
;	Setup Navigation Byte 2 with water strength info
	MOVF	WaterStrength, W
	MOVWF	NavByte2
	RRF	NavByte2, F
	RRF	NavByte2, F
	RRF	NavByte2, F
	RRF	NavByte2, F
	MOVLW	0x0F
	ANDWF	NavByte2, F
;	Setup specials
	BTFSS	Specials, 0
	GOTO	$+3
	BSF	NavByte2, 5
	GOTO	$+2
	BCF	NavByte2, 5
	BTFSS	Specials, 1
	GOTO	$+3
	BSF	NavByte2, 6
	GOTO	$+2
	BCF	NavByte2, 6
	RETURN

;	TransmitNoAxn
;   --------------------------------------------------------------------
;   Sends a no action command (helm to craft) as defined in Comm. protocol.
TransmitNoAxn:
	banksel	PORTA
	MOVLW	0x88
	MOVWF	NavByte1
	MOVLW	0x00
	MOVWF	NavByte2
	CALL	TransmitNav
	RETURN

;   To use this function, first load NavByte1 and NavByte2 with the navigation
;   data the helm needs to transmit, then call this function.
TransmitNav:
	CALL	SetAddressToShip
	banksel	PORTA
	MOVLW	0x02
	MOVWF	COM_data1
	MOVF	NavByte1, W
;	MOVLW	0x88
	MOVWF	COM_data2
	MOVF	NavByte2, W
;	MOVLW	0x88
	MOVWF	COM_data3
	CALL	API_TxPacket
	RETURN	

APIRx:
	banksel	PORTA
;	Check whether an API packet is received
	BTFSS	COM_rxFlag, COM_rxDone
	RETURN
	BCF	COM_rxFlag, COM_rxDone
	CALL	ToggleLED
;	A packet has been received, what is it?
	MOVLW	COM_craft
	SUBWF	COM_rxData1, W
	BTFSC	STATUS, Z
;	It's from the craft
	GOTO	API_Craft
	MOVLW	COM_adm
	SUBWF	COM_rxData1, W
	BTFSC	STATUS, Z
;	It's admiral
	GOTO	API_Admiral
;	It's garbage, return
	RETURN

API_Admiral:
	CALL	CheckAdmAddr
	ADDLW	0x00
	BTFSS	STATUS, Z
	RETURN
;	It is from the admiral's address
	MOVF	COM_rxData2, W
	BTFSS	STATUS, Z
	RETURN
;	Is it start game?
	MOVLW	COM_startgame
	SUBWF	COM_rxData3, W
	BTFSC	STATUS, Z
	GOTO	AdmStartgame
;	Is it end game?
	MOVLW	COM_endgame
	SUBWF	COM_rxData3, W
	BTFSC	STATUS, Z
	GOTO	AdmEndgame
;	Is it blue goal?
	MOVLW	COM_bluegoal
	SUBWF	COM_rxData3, W
	BTFSC	STATUS, Z
	GOTO	AdmBluegoal
;	Is it red goal?
	MOVLW	COM_redgoal
	SUBWF	COM_rxData3, W
	BTFSC	STATUS, Z
	GOTO	AdmRedgoal
;	Is it hard reset?
	MOVLW	COM_hardreset
	SUBWF	COM_rxData3, W
	BTFSC	STATUS, Z
	GOTO	AdmHardreset
;	Is ping?
	MOVLW	COM_ping
	SUBWF	COM_rxData3, W
	BTFSC	STATUS, Z
	GOTO	AdmPing
	RETURN

;   We set the game state so we can play, but first respond with ack
;   to admiral
AdmStartgame:
	CALL	SetAddressToAdmiral
	CALL	SendAckToAddress
	BSF	FLAG, Start_Game_Flag
	RETURN

;   We set the game state to end game mode, but first respond with ack
;   to admiral
AdmEndgame:
	CALL	SetAddressToAdmiral
	CALL	SendAckToAddress
	BSF	FLAG, End_Game_Flag
	RETURN

;   Indicate that the blue goal is active - send to slave over SPI
AdmBluegoal:
	banksel	PORTA
	MOVLW	b'10000011'	; Turn off ActiveRed LED
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit
	MOVLW	b'10001010'	; Turn on ActiveBlue LED
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit
;	NEED TO INDICATE active base HERE ****************************************************************
	RETURN

;   Indicate that the red goal is active - send to slave over SPI
AdmRedgoal:
	banksel	PORTA
;	INDICATE active base HERE 
	MOVLW	b'10001011'	; Turn on ActiveRed LED
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit
	MOVLW	b'10000010'	; Turn off ActiveBlue LED
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit
	RETURN

;   Set the hard reset flag
AdmHardreset:
	BSF	FLAG, Hard_Reset_Flag
	RETURN

;  Send back the correct ping data
AdmPing:
	CALL	SetAddressToAdmiral
	MOVLW	COM_pingresp
	MOVWF	COM_data1
	MOVF	PING_Data2, W
	MOVWF	COM_data2
	MOVF	PING_Data3, W
	MOVWF	COM_data3
	CALL	API_TxPacket
	RETURN


;   The only command we really want is stand down, since matched would happen
;   during waiting for synch section of code
API_Craft:
	CALL	CheckCraftAddr
	ADDLW	0x00
	BTFSS	STATUS, Z
	RETURN
;	Is it garbage?
	MOVF	COM_rxData2, W
	BTFSS	STATUS, Z
;	If byte 2 is not 0x00, then garbage, return
	RETURN
;	Is it stand down?
	MOVLW	COM_sdreceived
	SUBWF	COM_rxData3, W
	BTFSS	STATUS, Z
	RETURN
;	It's a stand down command, implement it here
;	What we want to do is send an ack to the craft and then send no actions
;	for 10 seconds
	CALL	SetAddressToShip
	CALL	SendAckToAddress
	BSF	FLAG, StandDown_Flag
	RETURN

SendAckToAddress:
	MOVLW	COM_ack
	MOVWF	COM_data1
	MOVF	COM_rxData2, W
	MOVWF	COM_data2
	MOVF	COM_rxData3, W
	MOVWF	COM_data3
	CALL	API_TxPacket
	RETURN


;	SPI_Transmit
;   --------------------------------------------------------------------
;   Transmits to SPI, no slave select
SPI_Transmit:
;	Ensure Bank 1
	BSF	STATUS,RP0
	BCF	STATUS,RP1
	BTFSS	SSPSTAT, BF 	; Has data been received(transmit complete)?
	GOTO	$-1
;	Bank 0
	BCF	STATUS,RP0
	MOVF	SSPBUF, W	; WREG reg = contents of SSPBUF
	MOVWF	SPI_RXDATA	; Save in user RAM, if data is meaningful
	MOVF	SPI_TXDATA, W	; W reg = contents of TXDATA
	MOVWF	SSPBUF	; New data to xmit
	RETURN

CheckTimer0Flag:
	banksel	PORTA
	BTFSS	Timer0Flag, 0
	RETURN
;	Flag is set, then clear it and transmit something
	BCF	Timer0Flag, 0
;	Toggle LED
	CALL	ToggleLED
;	Are we getting a new stand down command?  If so reset the timer.
	BTFSS	FLAG, StandDown_Flag
	GOTO	NoNewStandDown
	BCF	FLAG, StandDown_Flag
	MOVLW	StandDownTimer2Max
	MOVWF	StandDownTimer2
NoNewStandDown:
;	Are we standing down?  If the stand down timer2 is zero, then we aren't
;	standing down.  If it's more than zero, then we are standing down and
;	we can decrement the stand down timer so that we eventually leave stand
;	down.
	MOVF	StandDownTimer2, W
	BTFSS	STATUS, Z
	GOTO	StandingDown
	CALL	Indicate_No_Stand_Down
;	Not standing down.  Has the game started?
	BTFSS	FLAG, Start_Game_Flag
	GOTO	$+3
;	It's started, so transmit a nav command
	CALL	TransmitNav
	RETURN
;	CALL	TransmitNoAxn
	CALL	TransmitNav
	RETURN
StandingDown:
;	We're standing down.  Simply send a no action and then decrement the counter
	CALL	TransmitNoAxn
	CALL	Indicate_Stand_Down
	DECF	StandDownTimer2, F
	RETURN

Indicate_Stand_Down:
	MOVLW	b'10001100'
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit
;	NEED TO INDICATE STAND DOWN HERE ****************************************************************
	RETURN

Indicate_No_Stand_Down:
	MOVLW	b'10000100'
	MOVWF	SPI_TXDATA
	CALL	SPI_Transmit
;	NEED TO INDICATE STAND DOWN HERE ****************************************************************
	RETURN

ToggleLED:
	banksel	PORTA
	BTFSS	PORTA, 1
	GOTO	$+3
	BCF	PORTA, 1
	RETURN
	BSF	PORTA, 1
	RETURN

	END

ibutton.h

; ******************************************************************************
; ******************************************************************************
;	Functions for iButton
; ******************************************************************************
; ******************************************************************************

iWAIT:
	BTFSS	PIR1, TMR1IF
	GOTO	iWAIT	
	RETURN

TIMER1_Init:
	banksel	OSCCON
	BSF	OSCCON, IRCF0
	BSF	OSCCON, IRCF1
	BSF	OSCCON, IRCF2

	banksel	T1CON
	BCF	T1CON, TMR1CS	; use internal clock (Fosc/4)
	BCF	T1CON, T1CKPS0	; set prescale value as 1:1
	BCF	T1CON, T1CKPS1
	BSF	T1CON, TMR1ON	; Enable Timer 1
;	BCF	T1CON, TMR1GE

	RETURN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

iButton_Init:
	banksel	ANSEL
	BCF	ANSEL, ANS0
	RETURN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

READ_iButton:
;	Have we received something?  All we care about is admiral ping
	BTFSC	COM_rxFlag, COM_rxDone
	CALL	CheckIfAdmiralPingIbutton

;	banksel	TRISA	; set the pin as an output
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	BCF	TRISA, 0
	
;	banksel	PORTA	; set the line low
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	BCF	iButtonPin
	
;	banksel	TMR1L	; wait for 500 usec
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	MOVLW	0xd5	;232-19
	XORLW	0xFF
	MOVWF	TMR1L
	MOVLW	0xFC	; 768
	MOVWF	TMR1H
	BCF	PIR1, TMR1IF
	CALL	iWAIT			

;	banksel	TRISA	; set the pin as an input
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	BSF	TRISA, 0

;	banksel	TMR1L	; wait for 50 usec
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	MOVLW	0x4e	; 100-22
	XORLW	0xFF
	MOVWF	TMR1L
	MOVLW	0xFF
	MOVWF	TMR1H
	BCF	PIR1, TMR1IF
	CALL	iWAIT	

;	banksel	PORTA	; read the pin
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	BTFSC	iButtonPin
	GOTO	READ_iButton	; if no iButton found, repeat
	RETURN		; if iButton is found, proceed to reset

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CheckIfAdmiralPingIbutton:
	MOVLW	COM_adm
	SUBWF	COM_rxData1, W
	BTFSS	STATUS, Z
;	It's not admiral command
	RETURN
;	It is admiral
	CALL	CheckAdmAddr
	ADDLW	0x00
	BTFSS	STATUS, Z
	RETURN
;	Address matches admiral, now is it ping?
	MOVF	COM_rxData2, W
	BTFSS	STATUS, Z
	RETURN
	MOVLW	COM_ping
	SUBWF	COM_rxData3, W
	BTFSS	STATUS, Z
	CALL	AdmPing
	RETURN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

RESET_iButton:
;	banksel	TRISA	; set the pin as an output
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	BCF	TRISA, 0
	
;	banksel	PORTA	; set the line low
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	BCF	iButtonPin
	
;	banksel	TMR1L	; wait for 500 usec
	MOVLW	0xd5	;232-19
	XORLW	0xFF
	MOVWF	TMR1L
	MOVLW	0xFC	; 768
	MOVWF	TMR1H
	BCF	PIR1, TMR1IF
	CALL	iWAIT	

	NOP		
	NOP		
	NOP		
	NOP		
	NOP		
	NOP		
	
;	banksel	PORTA	; set the line high
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	BSF	iButtonPin
	
;	banksel	TMR1L	; wait for 500 usec
	MOVLW	0xd5	;232-19
	XORLW	0xFF
	MOVWF	TMR1L
	MOVLW	0xFC	; 768
	MOVWF	TMR1H
	BCF	PIR1, TMR1IF
	CALL	iWAIT			

	NOP

;goto	RESET_iButton
	RETURN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SEND_READ_COMMAND:
;	banksel	TMR1L
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	MOVLW	0x33
	MOVWF	readROMcommand
	MOVLW	8
	MOVWF	CNT
SEND_LOOP:			; send read ROM command
	RRF	readROMcommand, f
	BTFSS	STATUS, C
	GOTO	WRITE_0
	GOTO	WRITE_1
CHECK_END_OF_SEND_LOOP:
	DECFSZ	CNT, f
	GOTO	SEND_LOOP

	RETURN

WRITE_1:
;	banksel	TRISA	; set the pin as an output
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	BCF	TRISA, 0
	
;	banksel	PORTA	; set the line low
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	BCF	iButtonPin
	
	NOP		; wait for 5 usec
	NOP
	NOP
	
	banksel	TRISA	; set the pin as an input
	BSF	TRISA, 0
	
;	banksel	TMR1L	; wait for 70 usec
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	MOVLW	0x70	;140-28
	XORLW	0xFF
	MOVWF	TMR1L
	MOVLW	0xFF
	MOVWF	TMR1H
	BCF	PIR1, TMR1IF
	CALL	iWAIT

	NOP
	NOP
	NOP

	GOTO	CHECK_END_OF_SEND_LOOP
	
WRITE_0:
;	banksel	TRISA	; set the pin as an output
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	BCF	TRISA, 0
	
;	banksel	PORTA	; set the line low
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	BCF	iButtonPin
	
;	banksel	TMR1L	; wait for 60 usec
	MOVLW	0x68	;120-16
	XORLW	0xFF
	MOVWF	TMR1L
	MOVLW	0xFF
	MOVWF	TMR1H
	BCF	PIR1, TMR1IF
	CALL	iWAIT	
	
;	banksel	TRISA	; set the pin as an input
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	BSF	TRISA, 0
	
;	banksel	TMR1L	; wait for 15 usec
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	MOVLW	0x04	;30-26
	XORLW	0xFF
	MOVWF	TMR1L
	MOVLW	0xFF
	MOVWF	TMR1H
	BCF	PIR1, TMR1IF
	CALL	iWAIT	

	NOP
	NOP

	GOTO	CHECK_END_OF_SEND_LOOP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
READ_iButton_data:
;	banksel	TMR1L
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	MOVLW	0x18	;24
	MOVWF	CNT

READ_LOOP:	
;	banksel	TRISA	; set the pin as an output
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	BCF	TRISA, 0
	
;	banksel	PORTA	; set the line low
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	BCF	iButtonPin
	
;	banksel	TMR1L	; wait for 5 usec

	NOP
	NOP
	NOP
	NOP
	
;	banksel	TRISA	; set the pin as an input
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	BSF	TRISA, 0
	
;	banksel	TMR1L	; wait for 10 usec

	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP

;	banksel	TMR1L
	BCF	STATUS, RP1
	BCF	STATUS, RP0
						
	RRF	iButtonReadingM, f	; shift the reading to get it ready for the next bit
	RRF	iButtonReadingH, f
	BTFSC	STATUS, C
	GOTO	SETHI
	BCF	iButtonReadingM, 7
	GOTO	NEXT

SETHI	BSF	iButtonReadingM, 7

;	banksel	PORTA		; read the pin
NEXT	BCF	STATUS, RP1
	BCF	STATUS, RP0
	BTFSC	iButtonPin
	GOTO	READ_1		; if high, reading is 1
	BCF	iButtonReadingH, 7	; if low, reading is 0

CHECK_END_OF_READ_LOOP:
;	banksel	TMR1L	; wait for 60 usec
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	MOVLW	0x5c	;120-28
	XORLW	0xFF
	MOVWF	TMR1L
	MOVLW	0xFF
	MOVWF	TMR1H
	BCF	PIR1, TMR1IF
	CALL	iWAIT	

	NOP
	NOP
	NOP
	NOP
	NOP
	NOP

	DECFSZ	CNT, f
	GOTO	READ_LOOP

	RETURN
READ_1:
	BSF	iButtonReadingH, 7
	GOTO	CHECK_END_OF_READ_LOOP

Waiting_for_iButton:
	CALL	TIMER1_Init
	CALL	iButton_Init
start_iButton:
	CALL	READ_iButton
	CALL	RESET_iButton
	CALL	SEND_READ_COMMAND
	CALL	READ_iButton_data

	RETURN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

adc.h

ADC_AN4	equ	B'00010001'
ADC_AN5	equ	B'00010101'
ADC_AN6	equ	B'00011001'

Acquis_Time:
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	RETURN

ADC_SelectChan	macro	byte
	BCF	STATUS, RP1
	BCF	STATUS, RP0
	MOVLW	byte	;Left justify, Vdd Vref, AN2, On
	MOVWF 	ADCON0
	CALL 	Acquis_Time	;Acquisiton delay
endm

helminits.h

;
;   Clock_Init
;
;
Clock_Init:
	banksel	OSCCON
	BSF	OSCCON, IRCF0
	BSF	OSCCON, IRCF1
	BSF	OSCCON, IRCF2
	RETURN



ADC_Init:
;	Ensure bank 1
	BCF	STATUS, RP1
	BSF	STATUS, RP0
	MOVLW	B'01010000'	; clock select Fosc/16
	MOVWF 	ADCON1 
;	Setup the analog pins
	BSF 	TRISC, 0	; Set RC0 to input
	BSF	TRISC, 1	; Set RC1 to input
	BSF	TRISC, 2	; Set RC2 to input
;	Ensure bank 2
	BSF	STATUS, RP1
	BCF	STATUS, RP0
	BSF	ANSEL, 4
	BSF	ANSEL, 5
	BSF	ANSEL, 6
	RETURN


;
;   SPI_Init
;   --------------------------------------------------------------------
;   Routine to initialize SPI on the PIC.
SPI_Init:
	; Handle all the ANSEL and TRIS pins for SPI
	; We already handle this in the parent initialize function
;	banksel	ANSELH
;	BCF	ANSELH, ANS8;		Turn off AD on SS
;	BCF	ANSELH, ANS9;		Turn off AD on SDO
;	BCF	ANSELH, ANS10;		Turn off AD on SDI/SDA
	banksel	TRISA
	BSF	TRISB, TRISB4;		Set SDI/SDA line as input
	BCF	TRISC, TRISC7;		Set SDO line as output
	; Are we master or slave
	BCF	TRISB, TRISB6;		Set SCK line as output for Master
	banksel	SSPSTAT
	CLRF	SSPSTAT;		SMP = 0, CKE = 0, clear status bits
	BSF	SSPSTAT, CKE;		CKE = 1
	banksel	SSPCON
	MOVLW	0x32		; Set up SPI port, Master mode, CLK/64
	MOVWF	SSPCON		; Mode 3 (CKE = 1, CKP = 1)
				; Data sampled in middle (SMP = 0, Master mode)
;	banksel	PIE1
;	BSF	PIE1, SSPIE		; Enable SSP interrupt
;	banksel	INTCON

;	BSF	INTCON, GIE		; Enable enabled interrupts
;	banksel	PIR1
;	BCF	PIR1, SSPIF		; Clear interrupt flag

;	Set up the Slave Select lines as outputs raised high
	banksel	PORTA
	BSF	PORTC, 6
	banksel	TRISA
	BCF	TRISC, TRISC6;		Set SS line as output
	
	; Should be ready to transmit
	banksel	SSPBUF
	MOVLW	0x55
	MOVWF	SSPBUF	; New data to xmit
	RETURN

;
;	EUSART_Init routine.
;   --------------------------------------------------------------------
;   Routine to initialize the EUSART peripheral on the PIC
EUSART_Init:
;	Clear analog for RB5
;	This is already handled for us in parent initialize function
;	banksel ANSEL
;	BCF	ANSELH, ANS11
	banksel	TXSTA
;	Choose 8 bit asynchronous /16
	BCF	TXSTA, SYNC
	BSF	TXSTA, BRGH
	BCF	BAUDCTL, BRG16
;	Choose a 9600 Baud rate (10 MHz clock)
;	MOVLW	0x0C
	;MOVLW	64
	;MOVLW	0x40
;	Choose a 9600 Baud rate (8 MHz clock)
	MOVLW	0x33
	MOVWF	SPBRG
;	Enable 8-bit tx
	BCF	TXSTA, TX9
;	Enable transmit
	BSF	TXSTA, TXEN
;	Enable serial port
	banksel	RCSTA
	BSF	RCSTA, SPEN
;	Enable 8-bit rx
	BCF	RCSTA, RX9
;	Enable receive
	BSF	RCSTA, CREN
;	Enable interrupt
	banksel	PIE1
	BSF	PIE1, RCIE
	RETURN
;
;	PWM_Init routine
;   --------------------------------------------------------------------
;   Routine to initialize PWM on the PIC
PWM_Init:
;	Ensure Bank 1
                BSF             STATUS, RP0
	BCF	STATUS, RP1
;	Disable PWM pin
                BSF             TRISC, TRISC5	; Set C5 to input
;	Set PWM Period
                MOVLW           0xFF
                MOVWF           PR2
;	Configure CCP for PWM
                BCF             STATUS, RP0	; Select bank 0
                MOVLW           0x3C
                MOVWF           CCP1CON
;	Set PWM duty cycle
                MOVLW           0x00
                MOVWF           CCPR1L
;	Configure and start Timer2
                BCF             PIR1, TMR2IF	; Clear Timer2 interrupt flag
                BSF             T2CON, T2CKPS0	; Set Timer2 prescale value to 4
                BSF             T2CON, TMR2ON	; Turn Timer2 on
;	Enable PWM output after new PWM cycle started
PWM_Pt_1:	BTFSS           PIR1, TMR2IF
                GOTO            PWM_Pt_1
                BSF             STATUS, RP0	; Select bank 1
                BCF             TRISC, TRISC5	; Set C5 to output
	RETURN

;
;	Timer0_Init routine
;   --------------------------------------------------------------------
;   Routine to initialize Timer0 on the PIC
Timer0_Init:
;	Ensure bank 1
	BSF	STATUS, RP0
	BCF	STATUS, RP1
;	Set as timer
	BCF	OPTION_REG, T0CS
;	Set prescaler to timer 0
	BCF	OPTION_REG, PSA
;	1:256 prescaler
	BSF	OPTION_REG, PS0
	BSF	OPTION_REG, PS1
	BSF	OPTION_REG, PS2
;	Clear the flag
	BCF	INTCON, T0IF
;	Enable the interrupt
	BSF	INTCON, T0IE
;	Reset the counter and flag
	BCF	STATUS, RP0
	MOVLW	Timer0Max
	MOVWF	Timer0Count
	CLRF	Timer0Flag
	RETURN
	

LED_Init:
	banksel	PORTA
	BCF	PORTA, 1
	banksel	TRISA
	BCF	TRISA, 1
	RETURN

Input_Init:
;	Water shooting and forwards/backwards
	banksel	TRISA
	BSF	TRISA, 2
	BSF	TRISA, 3
;	Specials
	BSF	TRISC, 3
	BSF	TRISC, 4
	RETURN

synch.h

Waiting_for_Sync:

	banksel	PORTA
	MOVLW	0x02
	MOVWF	PING_Data2	; update status for ping command
;	Setup to broadcast ibutton data
Broadcast_iButton_data:
	CALL	SetAddressToBroadcast
	MOVLW	0x01
	MOVWF	COM_data1
	MOVF	iButtonReadingH, W
	MOVWF	COM_data2
	MOVF	iButtonReadingM, W
	MOVWF	COM_data3
	CALL	API_TxPacket
	CALL	Wait
;	Check if we've received a message.  At this point all we care about
;	   receiving are matched from the ship, or ping from the admiral
	BTFSS	COM_rxFlag, COM_rxDone
	GOTO	Broadcast_iButton_data
	BCF	COM_rxFlag, COM_rxDone
;	Received a packet, now let's check if it's a matched command
	MOVLW	COM_craft
	SUBWF	COM_rxData1, W
	BTFSS	STATUS, Z
;	Now check if it's an admiral ping
	GOTO	CheckIfAdmiralPing
	MOVF	COM_rxData2, W
	BTFSS	STATUS, Z
	GOTO	Broadcast_iButton_data
	MOVLW	COM_matched
	SUBWF	COM_rxData3, W
	BTFSS	STATUS, Z
	GOTO	Broadcast_iButton_data
;	It is a matched command!  Respond to it here
;	First let's save the address of the craft
	MOVF	COM_rxAddrH, W
	MOVWF	CraftAddrH
	MOVF	COM_rxAddrL, W
	MOVWF	CraftAddrL
;	Now let's setup ping data to respond
	MOVWF	PING_Data3
	MOVLW	0x04
	MOVWF	PING_Data2
	CALL	Check_Team	
	CALL	Indicate_Craft_Num
	RETURN

CheckIfAdmiralPing:
	MOVLW	COM_adm
	SUBWF	COM_rxData1, W
	BTFSS	STATUS, Z
;	It's not admiral command
	GOTO	Broadcast_iButton_data
;	It is admiral
	CALL	CheckAdmAddr
	ADDLW	0x00
	BTFSS	STATUS, Z
	GOTO	Broadcast_iButton_data
;	Address matches admiral, now is it ping?
	MOVF	COM_rxData2, W
	BTFSS	STATUS, Z
	GOTO	Broadcast_iButton_data
	MOVLW	COM_ping
	SUBWF	COM_rxData3, W
	BTFSS	STATUS, Z
	CALL	AdmPing
	GOTO	Broadcast_iButton_data

Wait:
	banksel	Timer1
	MOVLW	0xFF;		setup the first counter for waiting
	MOVWF	Timer2
Wait2:	MOVLW	0xFF;		setup the second counter for waiting
	MOVWF	Timer1
Wait1:	NOP
	NOP
	DECFSZ	Timer1, F;		decrement first counter, if zero loop
	GOTO	Wait1;		is done
	DECFSZ	Timer2, F;		decrement second counter, if zero loop
	GOTO	Wait2;		is done
	RETURN

vars.h

;   Utility Variables
BIT0HI	equ	0x01
BIT1HI	equ	0x02
BIT2HI	equ	0x04

Timer0Max	equ	0x0A

EndGame	equ	0x04
BlueGoal	equ	0x08
RedGoal	equ	0x10
HardReset	equ	0x40
Ping	equ	0x80
StartGame	equ	0x02

AdmiralAddrH	equ	0xBC
AdmiralAddrL	equ	0xFF

; Literals for ibutton
RedTeam	equ	0x00
BlueTeam	equ	0xff
; Locations in memory
SPI_RXDATA	equ	0x20
SPI_TXDATA	equ	0x21
Timer1	equ	0x22
Timer2	equ	0x23

COM_addrs_msb	equ	0x24
COM_addrs_lsb	equ	0x25
COM_data1	equ	0x26
COM_data2	equ	0x27
COM_data3	equ	0x28
COM_frameid	equ	0x29
COM_options	equ	0x2A
COM_checksum	equ	0x2B

COM_rxBuffAddr	equ	0x2C
COM_rxAddrH	equ	0x2C
COM_rxAddrL	equ	0x2D
COM_rxData1	equ	0x30
COM_rxData2	equ	0x31
COM_rxData3	equ	0x32
COM_rxIndex	equ	0x34
COM_rxFlag	equ	0x35
COM_rxDone	equ	7

W_TEMP	equ	0x36
STATUS_TEMP 	equ	0x37

Timer0Count	equ	0x38
Timer0Flag	equ	0x39

Speed	equ	0x3A
Direction	equ	0x3B
WaterStrength	equ	0x3C

NavByte1	equ	0x3D
NavByte2	equ	0x3E

CraftAddrH	equ	0x3F
CraftAddrL	equ	0x40
FLAG	equ	0x41
End_Game_Flag	equ	0
Hard_Reset_Flag	equ	1
Start_Game_Flag	equ	2
StandDown_Flag	equ	4

PING_Data2	equ	0x42
PING_Data3	equ	0x43

StandDownTimer2	equ	0x45
StandDownTimer2Max	equ	0x1F

Specials	equ	0x46

; variables for iButton
readROMcommand	equ	0x50
CNT	equ	0x51
iButtonReadingH	equ	0x52
iButtonReadingM	equ	0x53
iButtonReadingL	equ	0x54
Team	equ	0x55
#define	iButtonPin	PORTA, 0

xbee_comm.h

API_Start	equ	0x7E
API_NoRsp	equ	0x00
API_Tx16b	equ	0x01
API_TxResult	equ	0x89
API_Rx16b	equ	0x81
API_Broadcast	equ	0xFF
COM_lnth_msb	equ	0x00
COM_lnth_lsb	equ	0x08
COM_rxLn	equ	0x08

;	Types of messages
COM_nav	equ	0x02
COM_adm	equ	0x04
COM_ibutton	equ	0x01
COM_craft	equ	0x08
COM_pingresp	equ	0x10
COM_ack	equ	0x80

;	Ship to helm message tags
COM_matched	equ	0x01
COM_sdreceived	equ	0x02

;	Admiral to helm message tags
COM_startgame	equ	0x02
COM_endgame	equ	0x04
COM_bluegoal	equ	0x08
COM_redgoal	equ	0x10
COM_hardreset	equ	0x40
COM_ping	equ	0x80

EUSART_txL	macro	byte
	CALL	Wt_USART_TxRdy
	banksel	TXREG
	MOVLW	byte
	MOVWF	TXREG
endm

EUSART_txF	macro	file
	CALL	Wt_USART_TxRdy
	banksel	TXREG
	MOVF	file, W
	MOVWF	TXREG
endm

ChecksumCalc	macro
;	Ensure Bank 0
	BCF	STATUS,RP0
	BCF	STATUS,RP1
;	Start setting up the checksum
	MOVLW	API_Tx16b
	MOVWF	COM_checksum
	MOVF	COM_frameid, W
	ADDWF	COM_checksum, F
	MOVF	COM_options, W
	ADDWF	COM_checksum, F	
	MOVF	COM_addrs_msb, W
	ADDWF	COM_checksum, F
	MOVF	COM_addrs_lsb, W
	ADDWF	COM_checksum, F
	MOVF	COM_data1, W
	ADDWF	COM_checksum, F	
	MOVF	COM_data2, W
	ADDWF	COM_checksum, F	
	MOVF	COM_data3, W
	ADDWF	COM_checksum, F
	COMF	COM_checksum, F
endm

;	Wait til the transfer buffer is ready
;   --------------------------------------------------------------------
;   Routine that waits until the EUSART is ready to transmit another byte of data
Wt_USART_TxRdy:
	banksel	TXSTA	; wait til tranfer register ready
	BTFSS	TXSTA, TRMT	; check state of transmit buffer
	GOTO	$-1
	RETURN

API_TxPacket:
	ChecksumCalc
	EUSART_txL	API_Start
	EUSART_txL	COM_lnth_msb
	EUSART_txL	COM_lnth_lsb
	EUSART_txL	API_Tx16b
	EUSART_txF	COM_frameid
	EUSART_txF	COM_addrs_msb
	EUSART_txF	COM_addrs_lsb
	EUSART_txF	COM_options
	EUSART_txF	COM_data1
	EUSART_txF	COM_data2
	EUSART_txF	COM_data3
	EUSART_txF	COM_checksum
	RETURN

SetAddressToBroadcast:
	MOVLW	0xFF
	MOVWF	COM_addrs_msb
	MOVWF	COM_addrs_lsb
	RETURN

SetAddressToAdmiral:
	MOVLW	AdmiralAddrH
	MOVWF	COM_addrs_msb
	MOVLW	AdmiralAddrL
	MOVWF	COM_addrs_lsb
	RETURN

SetAddressToShip:
	MOVF	CraftAddrH, W
	MOVWF	COM_addrs_msb
	MOVF	CraftAddrL, W
	MOVWF	COM_addrs_lsb
	RETURN

CheckAdmAddr:
	banksel	PORTA
	MOVLW	AdmiralAddrH
	SUBWF	COM_rxAddrH, W
	BTFSS	STATUS, Z
	RETLW	0xFF
	MOVLW	AdmiralAddrL
	SUBWF	COM_rxAddrL, W
	BTFSS	STATUS, Z
	RETLW	0xFF
	RETLW	0x00

CheckCraftAddr:
	banksel	PORTA
	MOVF	CraftAddrH, W
	SUBWF	COM_rxAddrH, W
	BTFSS	STATUS, Z
	RETLW	0xFF
	MOVF	CraftAddrL, W
	SUBWF	COM_rxAddrL, W
	BTFSS	STATUS, Z
	RETLW	0xFF
	RETLW	0x00
Helm_Slv.asm
; Final Project - Terman Pond Flotilla
;
	list 	P=PIC16F690
	#include 	"p16F690.inc"
;	#include	pwm.h
	__config 	(_CP_OFF & _WDT_OFF & _PWRTE_ON & _INTOSCIO)


;
;	Variable Definitions
;   ---------------------------------------------------------------
;   Utility Variables
BIT0HI	equ	0x01
BIT1HI	equ	0x02
BIT2HI	equ	0x04

Tmr0ServMax	equ	0x3F
Timer0Max	equ	0xFF
#define	ServoPin	PORTA,1

MotorSpeedMask	equ	0xE0
; Locations in memory
SPI_RXDATA	equ	0x20
SPI_TXDATA	equ	0x21

Timer1	equ	0x22
Timer2	equ	0x23

W_TEMP	equ	0x24
STATUS_TEMP 	equ	0x25

INPUT	equ	0x26
CNT	equ	0x27

CLOCKBIT	equ	0
INPUTBIT	equ	1
CYCLEBIT	equ	2
CraftNumBit	equ	3
TeamBlue	equ	4	; PORT C
TeamRed	equ	1	; PORT A
ActiveBlue	equ	5	; PORT A
ActiveRed	equ	4	; PORT A
StandDown	equ	0	; PORT A

;   Beginning of Program
;   --------------------------------------------------------------------
	org	0
	goto	Main
	org	5
	goto	Interrupt

;
;	Tables
;   --------------------------------------------------------------------
;	Lookup table for bit pattern to write to Port C output
END_TBL:

LCDTable:
	ADDWF	PCL, F
	RETLW	b'11111111'
	RETLW	b'11101101'
	RETLW	b'00011001'
	RETLW	b'10001001'
	RETLW	b'11000101'
	RETLW	b'10000011'
	RETLW	b'00000011'
	RETLW	b'11101001'
	RETLW	b'00000001'
	RETLW	b'11000001'
	RETLW	b'00100000'
	RETLW	b'11101100'
	RETLW	b'00011000'
	
Clock_Init:
	banksel	OSCCON
	BSF	OSCCON, IRCF0
	BSF	OSCCON, IRCF1
	BSF	OSCCON, IRCF2
	RETURN

;
;   SPI_Init
;   -------------------------------------------------------------------
;   Routine to initialize SPI on the PIC.
SPI_Init:
	; Handle all the ANSEL and TRIS pins for SPI
	banksel	ANSELH
	BCF	ANSELH, ANS8;		Turn off AD on SS
	BCF	ANSELH, ANS9;		Turn off AD on SDO
	BCF	ANSELH, ANS10;		Turn off AD on SDI/SDA
	banksel	TRISA
	BSF	TRISB, TRISB4;		Set SDI/SDA line as input
	BCF	TRISC, TRISC7;		Set SDO line as output
	BSF	TRISC, TRISC6;		Set SS line as input
	; Are we master or slave
	BSF	TRISB, TRISB6;		Set SCK line as input for Slave

	banksel	SSPSTAT
	CLRF	SSPSTAT;		SMP = 0, CKE = 0, clear status bits
	BSF	SSPSTAT, CKE;		CKE = 1
	banksel	SSPCON
	BCF	SSPCON, SSPEN
	MOVLW	0x35		; Set up SPI port, Slave mode (SS), enable
	MOVWF	SSPCON		; Mode 3 (CKE = 1, CKP = 1)
				; (SMP cleared for slave mode)
	banksel	PIE1
	BSF	PIE1, SSPIE		; Enable SSP interrupt
	banksel	PIR1
	BCF	PIR1, SSPIF		; Clear interrupt flag
	; Should be ready to transmit
	RETURN



LED_Init:
	banksel	ANSEL
	CLRF	ANSELH
	CLRF	ANSEL

	banksel	PORTA
	CLRF	PORTA
	banksel	TRISA
	CLRF	TRISA
	BCF	TRISC, CLOCKBIT
	BCF	TRISC, INPUTBIT
	BCF	TRISC, CYCLEBIT
	BCF	TRISC, CraftNumBit
	BCF	TRISC, TeamBlue
	banksel	PORTC
	BCF	PORTC, TeamBlue
	BCF	PORTC, CLOCKBIT
	BCF	PORTC, INPUTBIT
	BCF	PORTC, CYCLEBIT
	BCF	PORTC, CraftNumBit
	CLRF	SPI_RXDATA
	CALL	CraftNumCtrl

	RETURN

;
;	Initialize routine.  
;   --------------------------------------------------------------------
Initialize:
;	Setup Clock
	CALL	Clock_Init
;	Setup SPI
	CALL	SPI_Init
;	Setup LEDs
	CALL	LED_Init
;	Enable Interrupts
	banksel	INTCON
	BSF	INTCON, GIE
	BSF	INTCON, PEIE
	RETURN


;********************************************************************************	
;********************************************************************************
;	Main Loop
;   --------------------------------------------------------------------
;   Continuously loops and handles the program
;       Looks for a button press, looks for a received message on EUSART
;       If slave select raised transmits message or ack
;********************************************************************************
;********************************************************************************
Main:
	CALL	Initialize

PNT_2:
	NOP
	GOTO	PNT_2


;
;	Interrupt Service Routine
;   ***********************************************************************
;   ***** The PIC's one and only ISR...  =(  ******************************
;   ***********************************************************************
Interrupt:
;	PUSH
	MOVWF	W_TEMP	; Copy W to TEMP register
	SWAPF	STATUS, W	; Swap status to be saved into W
	banksel	PORTA
	MOVWF	STATUS_TEMP	; Save status to STATUS_TEMP register
;	ISR
	banksel	PIR1
	BTFSC	PIR1, SSPIF
	CALL	SPI_Int
;	POP
	banksel	PORTA
	SWAPF	STATUS_TEMP, W	; Swap nibbles in STATUS_TEMP register
			; and place result into 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 in W_TEMP
	SWAPF	W_TEMP, W	; Swap nibbles in W_TEMP and place result into W	
	RETFIE

;	SPI_Int
;   --------------------------------------------------------------------
;   ISR that receives/transmits from SPI, but primary purpose is to receive
SPI_Int:
	BCF	PIR1, SSPIF
	banksel	PORTA
	MOVF	SSPBUF, W	; WREG reg = contents of SSPBUF
	MOVWF	SPI_RXDATA	; Save in user RAM, if data is meaningful
	MOVF	SPI_TXDATA, W	; W reg = contents of TXDATA
	MOVWF	SSPBUF	; New data to xmit
;	Process the command
	MOVLW	0xff
	SUBWF	SPI_RXDATA, w
	BTFSC	STATUS, Z
	GOTO	Initialize
	BTFSC	SPI_RXDATA, 7
	GOTO	LEDCtrl
	GOTO	CraftNumCtrl
LEDCtrl:
	BTFSC	SPI_RXDATA, 2
	GOTO	CheckStandDown
	BTFSC	SPI_RXDATA, 1
	GOTO	CheckActiveBase
	GOTO	CheckTeam
CheckActiveBase:
	BTFSC	SPI_RXDATA, 0
	GOTO	CtrlActiveRed
	GOTO	CtrlActiveBlue
CheckTeam:
	BTFSC	SPI_RXDATA, 0
	GOTO	CtrlTeamRed
	GOTO	CtrlTeamBlue
CtrlActiveRed:
	BTFSC	SPI_RXDATA, 3
	GOTO	IndicateActiveRed
	BCF	PORTA, ActiveRed
	RETURN
IndicateActiveRed:
	BSF	PORTA, ActiveRed
	RETURN
CtrlActiveBlue:
	BTFSC	SPI_RXDATA, 3
	GOTO	IndicateActiveBlue
	BCF	PORTA, ActiveBlue
	RETURN
IndicateActiveBlue:
	BSF	PORTA, ActiveBlue
	RETURN

CtrlTeamRed:
	BTFSC	SPI_RXDATA, 3
	GOTO	IndicateTeamRed
	BCF	PORTA, TeamRed
	RETURN
IndicateTeamRed:
	BSF	PORTA, TeamRed
	RETURN
CtrlTeamBlue:
	BTFSC	SPI_RXDATA, 3
	GOTO	IndicateTeamBlue
	BCF	PORTC, TeamBlue
	RETURN
IndicateTeamBlue:
	BSF	PORTC, TeamBlue
	RETURN

CheckStandDown:
	BTFSC	SPI_RXDATA, 3
	GOTO	IndicateStandDown
	BCF	PORTA, StandDown
	RETURN
IndicateStandDown:
	BSF	PORTA, StandDown
	RETURN

CraftNumCtrl:
;	ERROR CHECKING : data only btwn 1 and 12
	MOVLW	0x13
	SUBWF	SPI_RXDATA, W
	BTFSC	STATUS, C
	RETURN

	MOVF	SPI_RXDATA, W
	CALL	LCDTable
	banksel	PORTA
	MOVWF	INPUT

	MOVLW	0x00
	BTFSS	INPUT, 7
	CALL	LEDOff
	ADDWF	PCL, F
	BSF	PORTC, INPUTBIT
	CALL	PULSE

	MOVLW	0x00
	BTFSS	INPUT, 6
	CALL	LEDOff
	ADDWF	PCL, F
	BSF	PORTC, INPUTBIT
	CALL	PULSE

	MOVLW	0x00
	BTFSS	INPUT, 5
	CALL	LEDOff
	ADDWF	PCL, F
	BSF	PORTC, INPUTBIT
	CALL	PULSE

	MOVLW	0x00
	BTFSS	INPUT, 4
	CALL	LEDOff
	ADDWF	PCL, F
	BSF	PORTC, INPUTBIT
	CALL	PULSE

	MOVLW	0x00
	BTFSS	INPUT, 3
	CALL	LEDOff
	ADDWF	PCL, F
	BSF	PORTC, INPUTBIT
	CALL	PULSE

	MOVLW	0x00
	BTFSS	INPUT, 2
	CALL	LEDOff
	ADDWF	PCL, F
	BSF	PORTC, INPUTBIT
	CALL	PULSE

	MOVLW	0x00
	BTFSS	INPUT, 1
	CALL	LEDOff
	ADDWF	PCL, F
	BSF	PORTC, INPUTBIT
	CALL	PULSE

	MOVLW	0x00
	BTFSS	INPUT, 0
	CALL	LEDOff
	ADDWF	PCL, F
	BSF	PORTC, INPUTBIT
	CALL	PULSE

	BSF	PORTC, CYCLEBIT
	NOP
	BCF	PORTC, CYCLEBIT

	MOVLW	0x0A
	SUBWF	SPI_RXDATA, W
	BTFSC	STATUS, C
	GOTO	$+3
	BCF	PORTC, CraftNumBit
	RETURN
	BSF	PORTC, CraftNumBit
	RETURN


LEDOff:
	BCF	PORTC, INPUTBIT
	RETLW	0x01

PULSE:
	BSF	PORTC, CLOCKBIT
	nop
	BCF	PORTC, CLOCKBIT
	RETURN

Wait:
	banksel	Timer1
	MOVLW	0xFF;		setup the first counter for waiting
	MOVWF	Timer2
Wait2:
	MOVLW	0xFF;		setup the second counter for waiting
	MOVWF	Timer1
Wait1:
	NOP
	DECFSZ	Timer1, F;		decrement first counter, if zero loop
	GOTO	Wait1;		is done
	DECFSZ	Timer2, F;		decrement second counter, if zero loop
	GOTO	Wait2;		is done
	RETURN

	END