Helm Helper PIC .asm file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Helm Helper Pic
; Switch Code, Mic Code, Accel. Code, Shift Reg. Code, SSP 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)
 
; Note: Timing is based on using the external resonator (10MHz)
;
;               variable definitions
W_TEMP                          equ             0x70
STATUS_TEMP                     equ             0x71
overflow_count                  equ        0x20            ; counts number of timer 1 overflow (speed calc timer)
switch_count                    equ             0x21            ; counts number of switch hits (via input capture)
speed_calc                      equ             0x22            ; a flag, when = 1 2 sec have elapsed and the speed should be calc.
MicValue                        equ             0x24            ; when mic value = 1, a yell has occurred
Hi_PulseFlag                    equ             0x25            ; 7-segment variable
Lo_PulseFlag                    equ             0x26            ; 7-segment variable
number                          equ             0x27            ; the number that needs to be displayed on 7-segment
ClearCount                      equ             0x28            ; a counter in the display clear process
SpecialButton1                  equ             0x29            ; variable for SpecialButton1 (other boats)
SpecialButton2                  equ             0x2A            ; variable for SpecialButton2 (other boats)
temp_reg3                       equ             0x2B  
temp_reg                        equ             0x2C
subtractcount                   equ             0x2D
div_storage                     equ             0x2E
temp_reg1                       equ             0x2F
temp_reg2                       equ             0x30
ADC_DATA                    equ    0x31
LED_data                        equ             0x32
tx_ssp_byte                     equ             0x33
team                            equ             0x34            ; if team =0, blue team; if team =1, red team
 
; Information to send back to xBee pic
NAV                             equ             0x23            ; the navigation byte
SPECIAL                         equ             0x2B            ; the special byte
 
;multiply and divide variables:
number2                         equ             0x72            
multiplier                      equ             0x73
result_multiply                 equ             0x74
numerator                       equ             0x75
denominator                     equ             0x76
result_divide                   equ             0x77
 
;
;               #Defines
;               Button Count Defines
#define         TIMER_OVERFLOWS                 0x26            ; this enables 76 overflows at 0.026s/overflow (every 2 seconds)
#define         STOP_COUNT                      0x00            ; 0 switch counts results in no movement
#define         SLOW_COUNT                      0x03            ; 1-3 switch counts results in slow movement
#define         MEDIUM_COUNT                    0x07            ; 3-7 switch counts results in medium movement  
                                                                ; > 7 switch counts results in fast movement
#define         SSP_HEADER                      0xAA
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                org             0
                goto            Main
                org             4
                goto            InterruptServiceRoutine
                org             5
;
;       Tables can go here
;
DisplaySwitch:
                addwf           PCL,f
                goto            Case0
                goto            Case1
                goto            Case2
                goto            Case3
                goto            Case4
                goto            Case5
                goto            Case6
                goto            Case7
                goto            Case8
                goto            Case9
                goto            Case10
                goto            Case11
END_TBL:
;
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Main
; Main program
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main:
;
                call            SSP_Init
                call    InitializeSpeedSwitch
                call            InitializeMicrophone
                call            InitializeShiftRegister
                call            InitializeExtraButtons
                call            InitializeADC
                call            InitializeBaseLED
                call            ClearVariables
 
                banksel         TRISC
                bcf             TRISC,1
                banksel         ANSEL
                bcf             ANSEL,ANS5
 
;
Loop:
 
                banksel         PORTC
                bsf             PORTC,1
 
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
 
;               Call all sensor functions                
                call            GRAB_ADC
                btfsc           speed_calc,0                    ; if speed_calc = 0, it is not time to get a new speed
                call            CalculateSpeed
                call            GetMicrophone
                call            GetExtraButtons
 
 
;               Generate the packet
                call            GeneratePacket
                                
;               Send the packet
                movlw           SSP_HEADER                      ; send the sensor header byte
                movwf           tx_ssp_byte
                call            SSP
                movf            NAV,w
                movwf           tx_ssp_byte                     ; send the NAV byte
                call            SSP            
                movf            SPECIAL,w
                movwf           tx_ssp_byte                     ; send the SPECIAL byte
                call            SSP
 
;               Display boat number
                call            GetNumber                       ; get number out of LED_data byte
                call            GetTeam
                call            ClearDisplay
                call            DisplayNumber                   ; display number to 7-seg
                call            SetActiveBaseLED
 
                banksel         PORTC
                bcf             PORTC,1
                
                goto    Loop
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Setup for all the SSP:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SSP_Init:
                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 Slave mode: with clock = SCK pin, and SS pin control disabled
                ;----------------------    
                bcf    SSPCON,SSPM3    
                nop
                bsf    SSPCON,SSPM2    
                nop
                bcf    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 SDI 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
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Initialize Speed Switch
; Configures Port C5 for the input capture and timer 1 for timer 1 overflow interrupts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeSpeedSwitch:
;
;               Configure NECESSARY ports
                banksel         TRISC
                bsf             TRISC,TRISC5                    ; configure C5 as an input for input capture
 
;    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    
        
;               Enable input capture interrupts
                banksel         PIE1
                bsf             PIE1,CCP1IE                     ; enable capture/compare interrupts
 
;               Configure input capture, every rising edge
                banksel         CCP1CON
                bcf             CCP1CON,CCP1M3
                bsf             CCP1CON,CCP1M2
                bcf             CCP1CON,CCP1M1
                bsf             CCP1CON,CCP1M0
                banksel         PIR1
                bcf             PIR1,CCP1IF                     ; clear the input capture interrupt flag
 
;    Enable timer overflow interrupts
    banksel    INTCON
    bsf    INTCON,GIE        ; enable global interrupts
    bsf    INTCON,PEIE        ; enable peripheral interrrupts
    banksel    PIE1
    bsf    PIE1,TMR1IE        ; enable timer 1 interrupts
    banksel    PIR1
    bcf    PIR1,TMR1IF        ; clear the timer 1 interrupt flag
    
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeMicrophone
; Sets up ports for microphone input
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeMicrophone:
 
                banksel         TRISA
                bsf             TRISA,2                         ; make port A2 an input from the microphone
                banksel         ANSEL
                bcf             ANSEL,ANS2                      ; make port A2 digital I/O for mic
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeShiftRegister
; Sets up ports for shift register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeShiftRegister:
 
                ; A0 is the CLOCK LINE
                banksel         ANSEL
                bcf             ANSEL, ANS0                     ; A0 as a digital I/O
                
                banksel         TRISA
                bcf             TRISA,TRISA0                    ; A0 as an output
                
 
                ; A1 is the DATA LINE
                banksel         ANSEL
                bcf             ANSEL, ANS1                     ; A1 as a digital I/O
 
                banksel         TRISA
                bcf             TRISA, TRISA1                   ; A1 as an output
 
                
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeExtraButtons
; Initializes buttons that we do not use (for controlling other boats)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeExtraButtons:
 
;               Initialize ports for button inputs
                banksel         TRISC
                bsf             TRISC,TRISC2                    ; configure C2 as an input for extra button 1          
                bsf             TRISC,TRISC3                    ; configure C3 as an input for extra button 2
                banksel         ANSEL          
                bcf             ANSEL,ANS6                      ; configure C2 as digital I/O
                bcf             ANSEL,ANS7                      ; configure C3 as digital I/O
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeADC
; Initializes buttons that we do not use (for controlling other boats)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeADC:
                ;Setup for the port directions and etc.
                banksel         TRISC
                bsf             TRISC,0                         ; Set the direction port to be input
                banksel         ANSEL
                bsf             ANSEL,ANS0                      ; Set port C0 to be analog input.
 
                                              
                banksel         ADCON1          
                bsf             ADCON1,5
                bcf             ADCON1,6
                bcf             ADCON1,4
                
                banksel         ADCON0  
                movlw           b'00010001'
                movwf           ADCON0                          ; Turn on ADC, right justified, VDD is ref, and AN4 active, don't start conversion
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeBaseLED
; Initializes ports for base LED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeBaseLED:
 
;               Configure port for Blue Base Active LED
                banksel         TRISC
                bcf             TRISC,TRISC4                    ; configure C4 as an output
 
;               Configure port for Red Base Active LED
                banksel         TRISB
                bcf             TRISB,TRISB5                    ; configure B5 as an output
 
;               Configure port for Red Team LED
                banksel         TRISC
                bcf             TRISC,TRISC1
                banksel         ANSEL
                bcf             ANSEL,ANS1                      ; configure C1 as an output
return          
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ClearVariables
; Initially clears all the registers used as variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ClearVariables:
 
;               Clear speed calculation variables
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
    clrf    overflow_count                    ; initially clear the overflow count value
                clrf            switch_count                    ; initially clear the number of switch hits
                clrf            speed_calc                      ; initially clear the command to calculate speed
                clrf            ADC_DATA                        ; initially clear the ADC variable
                movlw           0x88                            ; move not moving into the NAV byte
                movwf           NAV
;               Clear microphone variables
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
                clrf            MicValue                        ; clear the MicValue
;               Clear 7-segment variables
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0                                        
                clrf            number                          ; clear the number variable
                clrf            ClearCount                      ; clear the ClearCount variable
;               Clear the special byte
                clrf            SPECIAL
;               Clear the LED_data byte initially
                clrf            LED_data
;               Set Base LED lines low
                banksel         PORTB
                bcf             PORTB,5
                banksel         PORTC
                bcf             PORTC,4
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SSP function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SSP:
;    function for sending data from an address through the SSP
;    The argument is the address of the data to be sent
 
 
sspcomplete1:                ; wait until the flag is set
    banksel    SSPSTAT
                pagesel         sspcomplete1
    BTFSS    SSPSTAT, BF        ; checks the status of the reg2 flag in the reg1 register.                
    GOTO     sspcomplete1
 
 
    banksel         SSPBUF
    MOVF    SSPBUF, W        ; contents of the SSBUF is now in w register
                
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0                    
    MOVWF    LED_data        ; save the receieved data to this variable
 
                bcf             STATUS,RP1                      ; switch to bank 0 to
                bcf             STATUS,RP0                    
    MOVF    tx_ssp_byte,W        ; prep the W reg with your data to send.
    banksel    SSPBUF
    MOVWF    SSPBUF        ; sends out your transmit data.
 
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GetNumber
; This function gets the boat number from the LED_data variable that is sent from the helm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetNumber:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                clrf            number                          ; initially clear the number variable for 7-segment
 
                btfsc           LED_data,0
                bsf             number,0                        ; set the 0 bit of number
                btfsc           LED_data,1
                bsf             number,1                        ; set the 1 bit of number
                btfsc           LED_data,2
                bsf             number,2                        ; set the 2 bit of number
                btfsc           LED_data,3
                bsf             number,3                        ; set the 3 bit of number
 
                movf            number,f
                btfss           STATUS,Z
                goto            second_check
                goto            set_default
 
second_check:
;               checks to see that "number" is valid                
                movlw           0x0C
                subwf           number,W                      
                btfsc           STATUS,C                        ; if C = 1 then number >= 12 ...THIS IS BAD
                goto            set_default
                goto            exit_get_number
 
set_default:
                clrf            number
                incf            number,f                        ; number is at default set to 1 now
 
exit_get_number:
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GetTeam
; This function gets the team affiliation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetTeam:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                
                btfss           LED_data,4                      ; test the 4th bit of LED_data
                goto            set_blue_team
                goto            set_red_team                    ; if the 4th bit is set, on red team (odd number)
 
set_blue_team:  
                ; clear bit 0 of team variable
                goto            exit_get_team
                bcf             PORTC,1
 
set_red_team:
                goto            exit_get_team
                bsf             PORTC,1
 
exit_get_team:
 
                return
;
;                      
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ClockPulse
; This function sets PORTA0 hi and low to pulse the clock...we do this when we want to send data out
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ClockPulse:
 
                banksel         PORTA
                bsf             PORTA,0                         ; set PORTA0 Hi
                nop
                nop
                nop
                bcf             PORTA,0                         ; set PORTA1 Lo
 
                
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DataHigh
; This function sets PORTA1 hi and then pulses the clock
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
DataHigh:
 
                banksel         PORTA
                bsf             PORTA,1                         ; set PORTA1 HI
                nop
                nop
                pagesel         ClockPulse
                call            ClockPulse                      ; pulse the clock after you've set the line hi
 
                
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DataLow
; This function sets PORTA1 low pulses the clock
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DataLow:
                banksel         PORTA
                bcf             PORTA,1                         ; set PORTC3 LO
                nop
                nop
                pagesel         ClockPulse
                call            ClockPulse                      ; pulse the clock after you've set the line lo  
                
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ClearDisplay
; This function sets PORTA1 hi and low to pulse the clock...we do this when we want to send data out
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ClearDisplay:
 
                banksel         ClearCount
                movlw           d'7'                            ; move 7 into W
                movwf           ClearCount                      ; move 7 into ClearCount
 
CountDownFrom8:                                                 ; this will call DataHi 8 times
                pagesel         DataHigh
                call            DataHigh
                banksel         ClearCount
 
                decfsz          ClearCount                      ; decrement ClearCount
                goto            CountDownFrom8
                
return                                                          ; done clearing all 8 registers
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DisplayNumpber
; Sets the 7-segment to display the correct number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                      
DisplayNumber:
 
                bcf             STATUS,RP0
                bcf             STATUS,RP1
 
                decf            number                          ; decrement number (so that it goes from 0 - 11)  
                movf            number,W                        ; move the number to W
                call            DisplaySwitch                   ; call the Display Switch statement
                
return          ; exit the Display Number function
;
;
                
Case0:                                                          ; display team 1
                pagesel         DataHigh
                call            DataHigh                        ; going to Q7        
                call            DataHigh                        ; going to Q6
                call            DataHigh                        ; going to Q5
                call            DataHigh                        ; going to Q4
                call            DataLow                         ; going to Q3
                call            DataLow                         ; going to Q2
                call            DataHigh                        ; going to Q1
                call            DataHigh                        ; going to Q0
                return
Case1:                                                          ; display team 2
 
                pagesel         DataHigh
                call            DataHigh                        ; going to Q7
                call            DataLow                         ; going to Q6
                call            DataHigh                        ; going to Q5
                call            DataLow                         ; going to Q4
                call            DataLow                         ; going to Q3
                call            DataHigh                        ; going to Q2
                call            DataLow                         ; going to Q1
                call            DataLow                         ; going to Q0
                return
 
Case2:                                                          ; display team 3
 
                pagesel         DataHigh
                call            DataHigh                        ; going to Q7
                call            DataLow                         ; going to Q6
                call            DataHigh                        ; going to Q5
                call            DataLow                         ; going to Q4
                call            DataLow                         ; going to Q3
                call            DataLow                         ; going to Q2
                call            DataLow                         ; going to Q1
                call            DataHigh                        ; going to Q0
                return
 
Case3:
                pagesel         DataHigh
                call            DataHigh                        ; going to Q7
                call            DataLow                         ; going to Q6
                call            DataLow                         ; going to Q5
                call            DataHigh                        ; going to Q4
                call            DataLow                         ; going to Q3
                call            DataLow                         ; going to Q2
                call            DataHigh                        ; going to Q1
                call            DataHigh                        ; going to Q0
                return
 
Case4:
                pagesel         DataHigh
                call            DataHigh                        ; Q7
                call            DataLow                         ; Q6
                call            DataLow                         ; Q5
                call            DataLow                         ; Q4
                call            DataHigh                        ; Q3
                call            DataLow                         ; Q2
                call            DataLow                         ; Q1
                call            DataHigh                        ; Q0
                return
Case5:
                pagesel         DataHigh
                call            DataHigh
                call            DataLow
                call            DataLow
                call            DataLow
                Call            DataHigh
                call            DataLow
                call            DataLow
                call            DataLow
                return
Case6:
 
                pagesel         DataHigh
                call            DataHigh                        
                call            DataHigh
                call            DataHigh
                call            DataHigh
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataHigh
                call            DataHigh
                return
Case7:
                pagesel         DataLow
                call            DataHigh
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                
                return
Case8:
                pagesel         DataHigh
                call            DataHigh
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataHigh
                call            DataHigh
                
                return
Case9:
                pagesel         DataHigh
                call            DataHigh
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataLow
                call            DataHigh
                call            DataLow
                
                return
Case10:
                pagesel         DataLow
                call            DataHigh                        ; Q7
                call            DataLow                         ; Q6
                call            DataLow                         ; Q5
                call            DataHigh                        ; Q4
                call            DataHigh                        ; Q3
                call            DataLow                         ; Q2
                call            DataLow                         ; Q1
                call            DataLow                         ; Q0
                return
Case11:
 
                pagesel         DataHigh
                call            DataHigh
                call            DataHigh
                call            DataHigh
                call            DataLow
                call            DataLow
                call            DataHigh
                call            DataHigh
                call            DataLow
                call            DataLow
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SetActiveBaseLED
; lights the appropriate LED (red or blue) depending on an admiral command to the helm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SetActiveBaseLED:
;
                banksel         PORTC
                bcf             PORTC,4
                banksel         PORTB
                bcf             PORTB,5
                
TestRed:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
                btfss           LED_data,4                      ; test the state of the Red Base LED bit
                goto            TestBlue
                banksel         PORTC
                bsf             PORTC,4                         ; set PORTC, 4 line high to turn on Red Base LED
                goto            exit_set_LED
TestBlue:
                btfss           LED_data,5
                goto            exit_set_LED                    ; this shouldn't happen
                banksel         PORTB
                bsf             PORTB,5                         ; set PORTB, 5 line high to turn on Blue Base LED
 
exit_set_LED:
 
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CalculateSpeed
; When a timer overflow has occurred, its time for the speed to be calculated :)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CalculateSpeed:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
SpeedCalculation:
                movlw           STOP_COUNT
                xorwf           switch_count,W
                btfsc           STATUS,Z                        ; if Z = 1 then switch_count = 0
                goto            StopSpeed      
                movlw           SLOW_COUNT
                subwf           switch_count,W
                btfss           STATUS,C                        ; if C = 1 then switch_count >= SLOW_COUNT
                goto            SlowSpeed
                movlw           MEDIUM_COUNT
                subwf           switch_count,W
                btfss           STATUS,C                        ; if C = 1 then switch_count >= MEDIUM_COUNT
                goto            MediumSpeed
                goto            FastSpeed          
StopSpeed:
                bsf             NAV,3                           ; write STOP (x08) to NAV direction nibble (will swapf later)
                nop
                bcf             NAV,2                           ; write bit-wise as to not affect
                nop            
                bcf             NAV,1                           ; assignments to NAV in the direction
                nop
                bcf             NAV,0                           ; nibble
                goto            ExitCalculateSpeed
SlowSpeed:
                bsf             NAV,3                           ; write SLOW (x0A) to NAV direction nibble (will swapf later)
                nop
                bcf             NAV,2                           ; write bit-wise as to not affect
                nop
                bsf             NAV,1                           ; assignments to NAV in the direction
                nop
                bcf             NAV,0                           ; nibble
                goto            ExitCalculateSpeed
MediumSpeed:
                bsf             NAV,3                           ; write MEDIUM (x0C) to NAV direction nibble (will swapf later)
                nop
                bsf             NAV,2                           ; write bit-wise as to not affect
                nop
                bcf             NAV,1                           ; assignments to NAV in the direction
                nop
                bcf             NAV,0                           ; nibble
                goto            ExitCalculateSpeed
FastSpeed:
                bsf             NAV,3                           ; write FAST (xFF) to NAV direction nibble (will swapf later)
                nop
                bsf             NAV,2                           ; write bit-wise as to not affect
                nop            
                bsf             NAV,1                           ; assignments to NAV in the direction
                nop
                bsf             NAV,0                           ; nibble
                goto            ExitCalculateSpeed
 
ExitCalculateSpeed:          
                clrf            switch_count                    ; reset the value of switch count = 0
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
                clrf            speed_calc                      ; reset the value of speed calc
                
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GetMicrophone
; Poles port A2 to see if it is high (the microhpone is triggered for pump to be on)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetMicrophone:
                banksel         PORTA
                btfsc           PORTA,2                         ; test the state of Port A2
                goto            NoMic                           ; the microphone input is not high
                goto            Mic                             ; the microphone input is high
 
NoMic:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                bcf             MicValue,0                      ; clear bit 1 of MicValue, no input
                return
Mic:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                bsf             MicValue,0                      ; set bit 1 of MicValue, input
                
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GetExtraButtons
; Poles ports C2 and C3 to see the state of the special function buttons (for controlling other boats)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetExtraButtons:
 
TestButton1:
                banksel         PORTC                           ; test the state of extra button 1
                btfss           PORTC,2
                goto            Extra1Low                       ; if low, go to Extra1Low
                goto            Extra1High                      ; if high, go to Extra1High
Extra1Low:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                bcf             SpecialButton1,0                ; clear SpecialButton1 bit 0
                goto            TestButton2
Extra1High:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                bsf             SpecialButton1,0                ; set SpecialButton1 bit 0
                goto            TestButton2
TestButton2:
                banksel         PORTC                           ; test the state of extra button 2
                btfss           PORTC,3
                goto            Extra2Low                       ; if low, go to Extra2Low
                goto            Extra2High                      ; if high, go to Extra2High
Extra2Low:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                bcf             SpecialButton2,0                ; clear SpecialButton1 bit 0
                return
Extra2High:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                bsf             SpecialButton2,0                ; set SpecialButton1 bit 0
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GRAB_ADC
; determines the direction we want to go
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GRAB_ADC:
                ;This simply grabs ADC and stores it.
                call            LONGNOP
                banksel         ADCON0
                BSF             ADCON0,1                        ; Starts the conversion
                BTFSC           ADCON0,1                        ; Is the conversion done?
                GOTO            $-1                             ; No, test again.
                banksel         ADRESH          
                movf            ADRESH,w
                movwf           ADC_DATA        
 
                ;This converts the ADC from 8bit data to a 4bit nibble.
                movlw           0x27
                subwf           ADC_DATA, f                     ; subtract: ADC - 39, store back into ADC_DATA
                movlw           0x02
                movwf           temp_reg1
                
                MULTIPLY        ADC_DATA,temp_reg1,temp_reg2    ; multiply (ADC-39) * 2 into temp_reg2
                DIVIDE          temp_reg2,d'11',ADC_DATA
 
                bcf             STATUS,RP0
                bcf             STATUS,RP1                  
 
                bcf             NAV,4
                bcf             NAV,5
                bcf             NAV,6
                bcf             NAV,7
 
                    
                btfsc           ADC_DATA,0
                bsf             NAV,4
                btfsc           ADC_DATA,1
                bsf             NAV,5
                btfsc           ADC_DATA,2
                bsf             NAV,6
                btfsc           ADC_DATA,3
                bsf             NAV,7
 
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GeneratePacket
; Generates the NAV and SPECIAL bytes to send back to the xBee helm pic
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                              
GeneratePacket:
;               Generate the special byte
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                clrf            SPECIAL                         ; initially clear the special byte
CheckWater:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 0
                btfss           MicValue,0                      ; see if MicValue bit 0 is set (water requested)
                goto            CheckSpecial1
                bsf             SPECIAL,0                       ; set bit 0 (the only bit WE care about)
                bsf             SPECIAL,1                       ; auto-set these for other boats
                bsf             SPECIAL,2                       ; auto-set these for other boats
                bsf             SPECIAL,3                       ; auto-set these for other boats
                goto            CheckSpecial1
CheckSpecial1:
                bcf             STATUS,RP0
                bcf             STATUS,RP1
                btfss           SpecialButton1,0                ; test to see if bit 0 of SpecialButton1 is set
                goto            CheckSpecial2
                bsf             SPECIAL,4                       ; set bit 4 for special functions
                goto            CheckSpecial2
CheckSpecial2:
                bcf             STATUS,RP0
                bcf             STATUS,RP1
                btfss           SpecialButton2,0                ; test to see if bit 0 of SpecialButton2 is set
                goto            exit_generate
                bsf             SPECIAL,5                       ; set bit 5 for special function
 
exit_generate:
 
                return
;                
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LONGNOP
; creats a brief pause
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LONGNOP:
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ISR
; Handles timer overflow and input capture interrupts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
 
InterruptSourceTest:
                banksel         PIR1
                btfsc           PIR1,CCP1IF                     ; test to see if the input capture flag was set
                goto            HandleSwitch                    ; handle the input capture
                goto            TimeoutTest                     ; else a timer overflow occured
TimeoutTest:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
    incf    overflow_count
    movlw    TIMER_OVERFLOWS        ; move 150 into W register
    xorwf    overflow_count,W
    btfsc    STATUS,Z        ; if Z = 1, then overflow_count = 150
    goto    ResetTimer
    banksel    PIR1
    bcf    PIR1,TMR1IF        ; clear the timer 1 overflow flag
    goto    Pop
HandleSwitch:
                banksel         PIR1
                bcf             PIR1,CCP1IF                     ; clear the input capture flag
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0                  
                incf            switch_count                    ; increment the number of switch hits
                goto            Pop
ResetTimer:
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
                movlw           0x01
                movwf           speed_calc                      ; set the value of speed_calc = 1, time to calculate speed
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; move to bank 0
    clrf    overflow_count        ; clear the overflow counter
    banksel    PIR1
    bcf    PIR1,TMR1IF        ; clear the timer 1 overflow flag
    goto    Pop                
Pop:
                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
 
                END