Boat Left Helper .asm                 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Helper PIC 2 (this pic drives the LEFT motor)
; Outputs left motor PWM, turns on the pump for 5 seconds, and drives the stepper motor
; 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             0x20
STATUS_TEMP     equ             0x21
PWM_Bit         equ             0x05            ; control of PWM is on C5
byte_count      equ             0x22
PWM_byte        equ             0x23
Special_byte    equ             0x24
temp_received   equ             0x25
flag_flag       equ             0x26
T1OF_count      equ             0x27
state           equ             0x28
StepCount       equ             0x29
;
;               #Defines
#define         LEFT_HEADER_BYTE     0x55
#define         OVERFLOWS_26MS       0x01            ; 1 overflow at 0.026 s/overflow creates a 0.026 s pause between steps 
#define         STEP_NUMBER          0x37            ; 55 Steps on stepper motor to create a 90 degree rotation          
;
                org             0
                goto            Main
                org             4
                goto            InterruptServiceRoutine
                org             5
;
;       Tables can go here
;
END_TBL:
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Main
;Main program
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main:
;
                call            PWM_Init
                call            General_Init
                call            SSP_Init
                call            TMR1_Init
                call            Receive_Init

ForeverLoop:
;                banksel         T1OF_count
;                movlw           OVERFLOWS_5S                   ; comment out for CONSTANT YELLING
;                subwf           T1OF_count,W
;                btfsc           STATUS,C                        ; if C = 1, a 5 sec. interval has occurred
                call            HandleWater                     ; go and handle pump events (if any)
                banksel         byte_count
                movlw           0x03
                xorwf           byte_count,W
                btfsc           STATUS,Z                        ; if Z = 1, then 3 bytes have been received (new data)
                goto            ProcessPacket
                goto            ForeverLoop
ProcessPacket:
                call            DriveLeftForward                ; update the PWM value
                ;call            RaiseFlag                       ; perform appropriate flag function
                banksel         byte_count                     
                clrf            byte_count                      ; clear byte count for next packet
                goto            ForeverLoop
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Initialize Timer2
; This subroutine intializes timer 0: sets the prescale value,  and clears the overflow flag
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TMR2_Init:
                BANKSEL         T2CON                           ; go to timer 2 bank
                CLRF            T2CON                           ; stop timer 2, prescaler = 1:1, post scaler
                CLRF            TMR2                            ; Clear Timer 2 register                
                CLRF            INTCON                          ; Disable interrupts
                BANKSEL         PIE1                            ; Bank 1
                BCF             PIE1, TMR2IE                    ; clear TMR2IE bit in PIE1 register
                BCF             STATUS, RP0                     ; Bank 0
                CLRF            PIR1                            ; Clear peripheral interrupts Flags
                MOVLW           0x7B                            ; Pre scalar = 1:16, Post scalar = 1:16
                MOVWF           T2CON                           ; move pre scale and post scale to T2CON register; Timer2 is not yet enabled
                RETURN
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Initialize Timer1
; This subroutine intializes timer 1: sets the prescale value,  and clears the overflow flag
; This timer is used for timing the pauses necessary for pump and flag raising operations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TMR1_Init:
;	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 Timer 1 overflow interrupts
                banksel         PIE1
                bsf             PIE1,TMR1IE                     ; enable timer 1 overflow interrupts
                bcf             PIR1,TMR1IF                     ; clear the timer 1 overflow flag
                return
;
;	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Initialize PWM
; This subroutine intializes timer 0: sets the prescale value,  and clears the overflow flag
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PWM_Init:
                PAGESEL         TMR2_Init                       ; go to page with TMR2_Init
                CALL            TMR2_Init                       ; initialize Timer 2 pre and post scalar, This doesn't turn on timer 2 or set PR2 (PWM frequency)
                CLRF            CCP1CON                         ; CCP Module is off for PWM 1
                CLRF            TMR2                            ; Clear Timer 2
                BANKSEL         PR2                             ; go to bank with PR2 register
                MOVLW           0xFF                            ; move 0xFF (256) to W register
                MOVWF           PR2                             ; set PR2 to compare only after 256 ticks Assuming Fosc = 8Mhz, Prescale 1:16, PWM frequency is 488 Hz
                BANKSEL         CCPR1L                          ; go to bank with CCPR1L register
                MOVLW           0x00                            ; 
                MOVWF           CCPR1L                          ; initially set Duty Cycle = 0% for PWM 1
                BANKSEL         INTCON                          ; go to bank with INTCON
                BSF             INTCON, GIE                     ; enable global interrupt
                BSF             INTCON, PEIE                    ; enable peripheral interrupt
                BANKSEL         PIE1                            ; go to bank with PIE
                BSF             PIE1, TMR2IE                    ; enable Timer 2 to PR2 Match interrupt                 
                BSF             PIE1, CCP1IE                    ; enable CCP1 interrupt for PWM 1 ** CCP1IE CHeck that it is not used for PWM mode
                BANKSEL         PIR1
                CLRF            PIR1                            ; clear peripheral interrupts flags
                BANKSEL         CCP1CON                         ; go to bank with CCP1CON
                MOVLW           0x0C            
                MOVWF           CCP1CON                         ; PWM mode, 2 LSBs of Duty cycle = 00 (using only the 8 Msbs)
                BANKSEL         TRISC                           ; go to bank with TRISC
                BCF             TRISC, PWM_Bit                  ; make pin output for PWM 1 ** CHECK TO SEE IF THESE ARE IN THE SAME BANK
                BANKSEL         T2CON                           
                BSF             T2CON, TMR2ON                   ; turn Timer 2 on; starts to increment

                banksel         TRISC
                bcf             TRISC,4
                banksel         PORTC
                bcf             PORTC,4                         ; Set Port C4 low
                RETURN
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; General Init
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
General_Init:
                BANKSEL         OSCCON
                MOVLW           0x70                            ; 0111 0000 set internal resonator to be 8MHz
                IORWF           OSCCON, 1                       ; inclusive OR, place result back into OSCCON register
                BANKSEL         TRISC
;               Configure Left PIC ports
                banksel         TRISA
                bcf             TRISA,0                         ; make A0 an output for pump
                banksel         PORTA
                bcf             PORTA,0                         ; initially clear port A0
                banksel         ANSEL
                bcf             ANSEL,ANS0                      ; make A0 digital I/O
                banksel         TRISC
                bcf             TRISC,0                         ; make C0 an output for Stepper ph A
                bcf             TRISC,1                         ; make C1 an output for Stepper ph A
                bcf             TRISC,2                         ; make C2 an output for Stepper ph B
                bcf             TRISC,3                         ; make C3 an output for Stepper ph B
                banksel         PORTC
                bcf             PORTC,0
                bcf             PORTC,1
                bcf             PORTC,2
                bcf             PORTC,3                         ; initially clear ports C0-C3
                banksel         ANSEL
                bcf             ANSEL,ANS4                      ; make C0 digital I/O
                bcf             ANSEL,ANS5                      ; make C1 digital I/O
                bcf             ANSEL,ANS6                      ; make C2 digital I/O
                bcf             ANSEL,ANS7                      ; make C3 digital I/O
;               Clear Left PIC variables
                banksel         byte_count
                clrf            byte_count                      ; initially clear byte_count
                banksel         PWM_byte
                clrf            PWM_byte                        ; initially clear PWM_byte
                banksel         temp_received
                clrf            temp_received                   ; initially clear temp_received
                banksel         Special_byte
                clrf            Special_byte                    ; initially clear Special_byte 
                banksel         flag_flag
                clrf            flag_flag                       ; initially clear the flag_flag
                banksel         T1OF_count                  
                clrf            T1OF_count                      ; initially clear the timer 1 overflow count 
                banksel         state
                movlw           0x01
                movwf           state                           ; initially set the first state to state = 1
                banksel         StepCount
                clrf            StepCount                       ; initially clear the StepCount counter      
                RETURN
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Receive Init
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Receive_Init:
                banksel         PIE1
                bsf             PIE1,SSPIE                      ; enable Synchronous Serial Port interrupts
                banksel         PIR1
                bcf             PIR1,SSPIF                      ; initially clear the SSPIF flag
                return
;
;               
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;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 SDO for the SSP		
	nop                

                banksel	TRISB
                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
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DriveLeftForward Routine
; Puts the value of the second byte received (PWM_byte) into the CCPR1L register to create a PWM signal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DriveLeftForward:
                BANKSEL         PORTC
                BCF             PORTC, 4                        ; make port C4 lo
                BANKSEL         CCPR1L
                movf            PWM_byte,W                      ; write PWM of DC 50%          
                MOVWF           CCPR1L
                RETURN
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; HandleWater Routine
; According to the state of bit0 in the third byte received (Special_byte), the pump is turned on or left off
; 1 = pump on 
; 0 = pump off
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HandleWater:
                banksel         Special_byte
                btfss           Special_byte,0
                goto            PumpOff                         ; The special byte does not call for the pump to be on
                goto            PumpOn

PumpOn:
                banksel         PORTA
                bsf             PORTA,0                         ; raise line to turn on pump
;                banksel         T1OF_count                      ; COMMENT OUT FOR CONSTANT YELLING
;                clrf            T1OF_count                      ; clear the number of timer 1 overflows
                return

PumpOff:
                banksel         PORTA
                bcf             PORTA,0                         ; lower line to turn off pump
;                banksel         T1OF_count                      ; COMMENT OUT FOR CONSTANT YELLING
;                clrf            T1OF_count                      ; clear the number of timer 1 overflows
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; RaiseFlag Routine
; According to the state of bit1 in the third byte received (Special_byte), the flag is raised
; This action will only occur once, and a software flag will be set to keep the flag from being raised again
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RaiseFlag:
                banksel         Special_byte
                btfsc           Special_byte,1
                goto            FlagUp
                goto            FlagDown

FlagUp:
                banksel         flag_flag                       ; software flag that denotes if the flag has already been raised
                movlw           0x01            
                xorwf           flag_flag,W
                btfsc           STATUS,Z                        ; if Z = 1, the flag has already been raised
                goto            FlagDown
StepThrough:
                banksel         StepCount
                movlw           STEP_NUMBER
                subwf           StepCount,W
                btfsc           STATUS,C                        ; if C = 0 then we have not reached max step number
                goto            FlagDown
                call            StepForward                     ; Call step forward code
                call            Pause26ms                       ; call 26 ms pause
                banksel         StepCount
                incf            StepCount                       ; increment the StepCount
                goto            StepThrough

FlagDown:
                movlw           0x01
                movwf           flag_flag                       ; set the flag_flag = 1 so it will not raise again
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; StepForward Routine
; Moves stepper motor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
StepForward:
;
STEPF           movf            state,W                         ; move the current state to W
                xorlw           4                               ; check to see if current state is 4
                movlw           1
                btfsc           STATUS,Z                        ; Z=1 if the current state is 4
                goto            WRAPDOWN
;
                incf             state,f                        ; increcment the state by 1 if state is 1-3
                movf            state,w
                xorlw           1
                btfsc           STATUS,Z                        ; Z=1 if current state is 1
                goto            StateOneF
                movf            state,w
                xorlw           2
                btfsc           STATUS,Z                        ; Z=1 if current state is 2
                goto            StateTwoF
                movf            state,w
                xorlw           3
                btfsc           STATUS,Z                        ; Z=1 if current state is 3
                goto            StateThreeF
                movf            state,w
                xorlw           4       
                btfsc           STATUS,Z                        ; Z =1 if current state is 4
                goto            StateFourF
;
WRAPDOWN        movlw           1
                movwf           state                           ; previous state was 4, set to 1
                goto            StateOneF                       ; and go to StateOneF
;
StateOneF       bcf             PORTC,0                         ; set ports for StateOne
                bsf             PORTC,1
                bcf             PORTC,2
                bsf             PORTC,3
                return
;
StateTwoF       bsf             PORTC,0                         ; set ports for StateTwo
                bcf             PORTC,1
                bcf             PORTC,2
                bsf             PORTC,3
                return
 ;
StateThreeF     bsf             PORTC,0                         ; set ports for StateThree
                bcf             PORTC,1
                bsf             PORTC,2
                bcf             PORTC,3
                return       
;
StateFourF      bcf             PORTC,0                         ; set ports for StateFour
                bsf             PORTC,1
                bsf             PORTC,2
                bcf             PORTC,3
                return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Pause5s Routine
; Creates a 0.026 pause in between step
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pause26ms:
                banksel         T1OF_count
                clrf            T1OF_count
TestCount26:
                movlw           OVERFLOWS_26MS
                xorwf           T1OF_count,W
                btfss           STATUS,Z                        ; if Z = 1, then the right # of overflows has occurred
                goto            TestCount26
                return
                
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Interrupt Service Routine for PWM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
;               First, test for the cause of the interrupt
InterrruptSourceTest:
                banksel         PIR1
                btfsc           PIR1,SSPIF                      ; test to see if a receive has occured
                goto            HandleReceive                   ; if SSPIF = 1, TX/RX is complete
                btfsc           PIR1,TMR1IF                     ; else, test to see if timer 1 overflow caused the interrupt
                goto            HandleT1OF                      ; handle the timer 1 overflow event
                goto            HandlePWM                       ; else, a PWM interrupt occurred
HandleReceive:
;               Handle the receive interrupt
                banksel         PIR1
                bcf             PIR1,SSPIF                      ; clear the receive flag
                banksel         byte_count
                movlw           0x00            
                xorwf           byte_count,W
                btfsc           STATUS,Z                        ; if Z = 1, then byte_count = 0
                goto            FirstByte
                movlw           0x01
                xorwf           byte_count,W
                btfsc           STATUS,Z                        ; if Z = 1, then byte_count = 1
                goto            SecondByte
                goto            ThirdByte                       ; else byte_count = 2
FirstByte:
                banksel         SSPBUF
                movf            SSPBUF,W
                movwf           temp_received                   ; the contents of SSPBUF are now stored in W
                movlw           LEFT_HEADER_BYTE
                xorwf           temp_received,W                 ; see if Byte 1 is actually the header
                bcf             STATUS,RP0
                bcf             STATUS,RP1                      ; switch to bank 1
                btfss           STATUS,Z                        ; if Z = 1, then Byte 1 is the header
                goto            ClearByteCount                  ; if Z = 0 then Byte 1 is not the header and we need to reset
                banksel         byte_count                      ; else, increment byte_count and exit
                incf            byte_count                      ; increment byte_count to = 1
                goto            Pop
SecondByte:
                banksel         SSPBUF
                movf            SSPBUF,W
                movwf           PWM_byte                        ; move the contents of Byte 2 into PWM_byte
                banksel         byte_count                      
                incf            byte_count                      ; increment byte_count to = 2
                goto            Pop
ThirdByte:
                banksel         SSPBUF
                movf            SSPBUF,W
                movwf           Special_byte                    ; move the contents of Byte 2 into Special_byte
                banksel         byte_count
                incf            byte_count                      ; increment byte_count to = 3
                goto            Pop  

ClearByteCount:
                banksel         byte_count
                clrf            byte_count                      ; reset byte_count for next packet, a byte was missed
                goto            Pop 

HandleT1OF:
;               Handle the timer 1 overflow interrupt
                banksel         PIR1
                bcf             PIR1,TMR1IF                     ; clear the timer 1 overflow flag
                banksel         T1OF_count
                incf            T1OF_count                      ; increment the number of timer 1 overflows
                goto            Pop                              
HandlePWM:
;               Handle the PWM timer 2 overflow interrupt                
PWM_Period:
                banksel         PIR1
                BCF             PIR1, TMR2IF                    ; update this PWM period and the following Duty Cycle

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                                          ; return from interrupt, keep fingers crossed that this actually works!
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
                END