Main Page

        Boat Source Code

 

list            P=PIC16F690

                    #include        "p16F690.inc"

                    __config        (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC)

 

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

;               #defines

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

 

#define                    NUMBER_OF_BYTES                                              0x0B

                ; Framing

#define                    START_BYTE                                                           0x7E

#define                    LENGTH_MSB                                                         0x00

#define                    LENGTH_LSB                                                          0x08

 

                ; API identifier

#define                    API_RX                                                    0x81

#define                    API_TX                                                     0x01

 

                ; Frame ID

#define                    FRAME_ID                                                               0x00       

 

                ; Option

#define                    OPTIONS                                                 0x01                       

 

                ; Addresses

#define                    ADMIRAL_ADDRESS_MSB                      0xBC

#define                    ADMIRAL_ADDRESS_LSB                       0xFF

#define                    HELM_MSB                                                             0xBC

#define                    HELM_LSB                                                              0x06                                                       

#define                    CRAFT_MSB                                                            0xAF

#define                    CRAFT_LSB                                                             0x06

#define                    BROADCAST_MSB                                  0xFF

#define                    BROADCAST_LSB                                    0xFF

 

                ; for ME218C Data Byte 0 Header

#define                    IBUTTON_HEADER                                 0x01

#define                    NAVIGATION_HEADER                                           0x02

#define                    ADMIRAL_HEADER                                 0x04

#define                    WATERCRAFT_HEADER                                         0x08

#define                    PING_RESPONSE_HEADER                    0x10

#define                    ACK_HEADER                                                          0x80

 

                ; for ME218C Header Bit Check Bits

 

#define                    IBUTTON_HEADER_BIT                          0

#define                    NAVIGATION_HEADER_BIT                   1

#define                    ADMIRAL_HEADER_BIT                          2

#define                    WATERCRAFT_HEADER_BIT                  3

#define                    PING_RESPONSE_HEADER_BIT             4

#define                    ACK_HEADER_BIT                                   7

 

                ; Admiral Message Bytes

#define                    STAND_DOWN                                                       0x01

#define                    START_GAME                                                         0x02

#define                    END_GAME                                                             0x04

#define                    BLUE_GOAL                                                            0x08

#define                    RED_GOAL                                                              0x10

#define                    SOFT_RESET                                                           0x20

#define                    HARD_RESET                                                          0x40

#define                    ADMIRAL_PING1                                    0x00

#define                    ADMIRAL_PING2                                    0x80

 

                ; Admiral Message Bits

#define                    STAND_DOWN_BIT                                                0

#define                    START_GAME_BIT                                  1

#define                    END_GAME_BIT                                     2

#define                    BLUE_GOAL_BIT                                     3

#define                    RED_GOAL_BIT                                       4

#define                    SOFT_RESET_BIT                                    5

#define                    HARD_RESET_BIT                                   6

#define                    ADMIRAL_PING_BIT                                               7

 

                ; Commands from Helm to Watercraft

#define                    NO_ACTION_1                                                        0x88

#define                    NO_ACTION_2                                                        0x00

 

#define                    NO_ACTION_NAVIGATION                    0x88                                       

#define                    NO_ACTION_SPECIAL                                             0x00                                       

 

                ; Commands from Watercraft to Helm

#define                    STAND_DOWN_RECEIVED_1                 0x00

#define                    STAND_DOWN_RECEIVED_2                 0x02

#define                    MATCHED_1                                                           0x00

#define                    MATCHED_2                                                           0x01

 

                ; Ping Response Bytes

#define                    PING_WAIT_IBUTTON_BYTE1                               0x01

#define                    PING_WAIT_IBUTTON_BYTE2                               0x00

#define                    PING_WAIT_MATCH_BYTE1                  0x02

#define                    PING_WAIT_MATCH_BYTE2                  0x00

#define                    PING_PAIRED_BYTE1                                             0x04

;                                               PING_FOR_PAIRED_BYTE2                    is the LSB of the matched boat/helm

               

                ; Ping Response Bits

#define                    PING_WAIT_IBUTTON_BIT                    0

#define                    PING_WAIT_MATCH_BIT                       1

#define                    PING_PAIRED_BIT                                  2

 

                ; iButton variables

 

#define                    IBUTTON_TRIS_INPUT                           b'00010000'                                                            ; iButton tris bits input

#define                    IBUTTON_TRIS_OUTPUT                       b'11101111'                                                            ; iButton tris bits output

#define                    IBUTTON_BIT                                                         4                                                                              ; defined value for iButton bit in PORTB

#define                    IBUTTON_FAMILY1                                                0x01                                                                        ; first possible iButton family byte

#define                    IBUTTON_FAMILY2                                                0x09                                                                        ; second possible iButton family byte

 

                ; Tris bit defines

 

#define                    TRISA_BITS                                                             b'00000000'                                                            ; all PORTA outputs

#define                    TRISB_BITS                                                             b'01100000'                                                            ; all PORTB outputs except bit 5

#define                    TRISC_BITS                                                             b'00000000'                                                            ; all PORTC bits are inputs

 

                ; PIC baudrate define

 

#define                    PIC_BAUDRATE                                       d'129'                                                      ; calculated baudrate = 9615 so X = 129 for 20MHz clock

 

                ; Navigation defines

 

#define                    MOTOR_TIMER_MAX                                             20                                                                            ; number of flag sets to reach 0.01ms period

#define                    MOTOR_DUTY_75_FORWARD                              15                                                                            ; number of flag sets to reach 75% duty cycle

#define                    MOTOR_DUTY_50                                  10                                                                            ; number of flag sets to reach 50% duty cycle

#define                    MOTOR_DUTY_75_BACKWARD                             15                                                                            ; number of flag sets to reach 75% duty cycle

#define                    SERVO_PIN                                                             0                                                                              ; Pin number for servo signal, portC

#define                    SERVO_MAX                                                           27                                                                            ; number of flag sets in 20 ms

#define                    SERVO_LEFT                                                           4                                                                              ; number of flag sets in 1.5 ms

#define                    SERVO_CENTER                                      3                                                                              ; number of flag sets in 2 ms

#define                    SERVO_RIGHT                                                        2                                                                              ; number of flag sets in 2.5 ms

#define                    MOTOR_DIRECTION_PIN                       1                                                                              ; Pin number for motor direction, portC

#define                    MOTOR_PWM_PIN                                                2                                                                              ; Pin number for motor PWM, portC

#define                    PUMP_PIN                                                              3                                                                              ; Pin number for the pump control, portC

#define                    BLUE_LED                                                               6                                                                              ; Pin number for blue team indicator, portC

#define                    RED_LED                                                 7                                                                              ; Pin number for red team indicator, portC

#define                    TEAM_BIT                                                               0                                                                              ; bit of ibutton byte1 to check for team association

 

                ; Babysit function defines (stop moving after 3 seconds no msg receive from helm)

 

#define                    NUM_TICKS_3SEC_HIGH                       0x0B                                                                        ; Actually 1.5 sec because of the implementation

#define                    NUM_TICKS_3SEC_LOW                        0xB8

#define                    RX_BABYSIT_BIT                                    0                                             

 

                ; Transmit delay defines (transmit no faster than 5Hz)

 

#define                    TRANSMIT_COUNTDOWN_TO_20MS_1               d'200'

#define                    TRANSMIT_COUNTDOWN_TO_20MS_2               d'2'

 

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

;               location and variable definitions

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

 

                ; Receive and Transmit Byte Locations

 

RX_DATA_HEADER                 equ                                          0x20                                                                        ; RX data header byte

RX_DATA_BYTE1                    equ                                          0x21                                                                        ; RX data byte 1

RX_DATA_BYTE2                    equ                                          0x22                                                                        ; RX data byte 2

TX_DATA_HEADER                 equ                                          0x23                                                                        ; TX data header byte

TX_DATA_BYTE1                     equ                                          0x24                                                                        ; TX data byte 1

TX_DATA_BYTE2                     equ                                          0x25                                                                        ; TX data byte 2

RECEIVE_BYTE_COUNT          equ                                          0x26                                                                        ; number of received bytes in packet

CHECKSUM                                             equ                                          0x27                                                                        ; checksum

DEST_ADDRESS_MSB                             equ                                          0x28                                                                        ; destination address msb

DEST_ADDRESS_LSB                              equ                                          0x29                                                                       ; destination address lsb

DATA_RECEIVED                     equ                                          0x2A                                                                        ; byte received

SOURCE_ADDRESS_MSB       equ                                          0x2B                                                                        ; source address msb

SOURCE_ADDRESS_LSB         equ                                          0x2C                                                                        ; source address lsb

PAIRED_ADDRESS_MSB         equ                                          0x2D                                                                        ; paired address msb

PAIRED_ADDRESS_LSB           equ                                          0x2E                                                                        ; paired address lsb

 

                ; Temp registers for ISRs

 

W_TEMP                                 equ                                          0x2F                                                                        ; temp storage for W

STATUS_TEMP                                        equ                                          0x30                                                                        ; temp storage for status register

 

                ; Ping counter register and bytes

 

PING_RESPONSE_BYTE1        equ                                          0x31                                                                        ; first byte of ping response

PING_RESPONSE_BYTE2        equ                                          0x32                                                                        ; second byte of ping response

 

                ; iButton Bit Definitions

 

IBUTTON_BYTE0                    equ                                          0x34                                                                        ; location for 1st byte of iButton serial number (contains bits 0-8), family byte

IBUTTON_BYTE1                    equ                                          0x35                                                                        ; location for 2st byte of iButton serial number (contains bits 9-16), 1st keeper byte

IBUTTON_BYTE2                    equ                                          0x36                                                                        ; location for 3st byte of iButton serial number (contains bits 17-24), 2nd keeper byte

DELAY_COUNTER                   equ                                          0x37                                                                        ; location for delay counter

READ_BYTE_COUNTER                          equ                                          0x38                                                                        ; location for read byte counter

READ_BIT_COUNTER                             equ                                          0x39                                                                        ; location for read bit counter

 

                ; Navigation registers

 

SPEED_COMMAND                 equ                                          0x3B                                                                        ; motor speed command byte

DIRECTION_COMMAND                         equ                                          0x3C                                                                        ; motor direction command byte

MOTOR_TIMER_DESIRED      equ                                          0x3D                                                                        ; number of desired timer ticks to hold pwm line high (20 ticks for 100% duty)

SERVO_DESIRED                     equ                                          0x3E                                                                        ; number of timer ticks high (2 ms is neutral)

NAVIGATION_BYTE                                equ                                          0x3F                                                                        ; Byte 1 of the command communication to be received via XBEE

SPECIAL_BYTE                         equ                                          0x40                                                                        ; Byte 2 of the command communication to be received via XBEE

MOTOR_TIMER_COUNT                        equ                                          0x41                                                                        ; increments everytime the TMR2 interrupt flag is tripped

SERVO_TIMER_COUNT                          equ                                          0x42                                                                        ; increments everytime the TMR2 interrupt flag is tripped         

MOTOR_PORT                                        equ                                          PORTC                                                                     ; Port for motor control

PUMP_PORT                                           equ                                          PORTC                                                                     ; Port for pump control

SERVO_PORT                                          equ                                          PORTC                                                                     ; Port for servo control

 

THREE_SEC_COUNTER_HIGH                equ                                          0x45                                                                        ; high byte for 3 second shut down counter

THREE_SEC_COUNTER_LOW equ                                          0x46                                                                        ; low byte for 3 second shut down counter

RX_BABYSIT                                            equ                                          0x47                                                                        ; stores a flag on whether receiving has occurred

HELM_MATCH_FLAG                             equ                                          0x48                                                                        ; flag to signify that the boat has matched with a helm

ACK_FLAG                                               equ                                          0x49                                                                        ; flag to signify that an acknowledgment is required

HELM_STAND_DOWN_RESPONSE        equ                          0x4A                                                                        ; flag to signify that the helm has received the stand down command

 

TRANSMIT_COUNTDOWN_1 equ                                          0x4B                                                                        ; first count down timer for transmission delay

TRANSMIT_COUNTDOWN_2 equ                                          0x4C                                                                        ; second count down timer for transmission delay

TRANSMIT_COUNTDOWN_FLAG          equ                                          0x4D                                                                        ; flag to signify that the desired count down has been completed

 

                ; End Bit Definitions

 

                                org         0

                                GOTO        MAIN

                                                                org                           4

                                                                GOTO                      ISR

                                org         5

 

RX_JUMP_TABLE:

                                                                                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

 

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

;               MAIN

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

 

MAIN:  

                                       

INITIALIZE:

clear_ansel_bits:

                                                                                BANKSEL     ANSEL                   ; select bank containing ANSEL

                                                CLRF        ANSEL                   ; clears analog bits

                                                                                BANKSEL ANSELH                                   ; select bank containing ANSLEH

                                                CLRF        ANSELH                  ; clears other analog bits

set_data_direction:

                                                                                BANKSEL TRISA                                                                      ; select bank containing TRISA

                                                                                MOVLW                  TRISA_BITS                                                             ; write TRISA_BITS to W

                                                                                MOVWF                  TRISA                                                                      ; write TRISA_BITS from W to TRISA

                                                                                MOVLW                  TRISB_BITS                                                             ; write TRISB_BITS to W

                                                                                MOVWF                  TRISB                                                                      ; write TRISB_BITS from w to TRISB

                                                                                MOVLW                  TRISC_BITS                                                             ; write TRISC_BITS to W

                                                                                MOVWF                  TRISC                                                                       ; write TRISC_BITS from W to TRISC

intialize_general:                                   

                                                                                BANKSEL SPBRGH                                                  ; select bank containing SPBRGH

                                                                                CLRF        SPBRGH                                                  ; set SPBRGH byte to 0

                                                                                MOVLW       PIC_BAUDRATE                                  ; write the contents of PIC_BAUDRATE to W

                                                                                MOVWF                  SPBRG                                                                     ; set x = 64 and calculated baudrate = 9615

                                                                                BANKSEL TXSTA                                                                      ; select bank containing TXSTA

                                                                                BCF                          TXSTA, BRGH                                                          ; clear BRGH bit of TXSTA / low speed

                                                                                BCF                          TXSTA, SYNC                                                           ; clear SYNC bit of TXSTA / asynchronous mode

                                                                                BANKSEL BAUDCTL                                                 ; select bank containing BAUDCTL

                                                                                BSF                          BAUDCTL, BRG16                                   ; clear BRG16 bit of BAUDCTL / 16-bit baud rate generator is used

                                                                                                                                                                                                ; SYNC:BRG16:BRGH = 0:1:0 / 16-bit asynchronous / (FOSC/[16*(n+1)])

initialize_variables:                                                                               

                                                                                BANKSEL PORTA                    

                                                                                CLRF                        RECEIVE_BYTE_COUNT

                                                                                CLRF                        CHECKSUM

                                                                                CLRF                        RX_DATA_HEADER

                                                                                CLRF                        RX_DATA_BYTE1

                                                                                CLRF                        RX_DATA_BYTE2

                                                                                CLRF                        TX_DATA_HEADER

                                                                                CLRF                        TX_DATA_BYTE1

                                                                                CLRF                        TX_DATA_BYTE2

                                                                                CLRF                        DEST_ADDRESS_MSB

                                                                                CLRF                        DEST_ADDRESS_LSB

                                                                                CLRF                        PAIRED_ADDRESS_MSB

                                                                                CLRF                        PAIRED_ADDRESS_LSB

                                                                                CLRF                        DATA_RECEIVED

                                                                                CLRF                        PORTC                                                                    

                                                                                CLRF                        THREE_SEC_COUNTER_LOW

                                                                                CLRF                        THREE_SEC_COUNTER_HIGH

                                                                                CLRF                        HELM_STAND_DOWN_RESPONSE

                                                                                CLRF                        HELM_MATCH_FLAG            

                                                                                CLRF                        ACK_FLAG

                                                                                CLRF                        SPECIAL_BYTE

                                                                                MOVLW                  NO_ACTION_NAVIGATION                    ; write no action to w

                                                                                MOVWF                  NAVIGATION_BYTE                                                ; write no action from w to the navication byte

                                                                                CLRF                        TRANSMIT_COUNTDOWN_1

                                                                                CLRF                        TRANSMIT_COUNTDOWN_2

                                                                                CLRF                        TRANSMIT_COUNTDOWN_FLAG

 

initialize_interrupts:

                                                                                BANKSEL INTCON                                                   ; select bank containing INTCON

                                                                                BSF                          INTCON, GIE                                                           ; enable global interrupts

                                                                                BSF                          INTCON, PEIE                                          ; enable peripheral interrupts

                                                                                BANKSEL PIE1                                                                         ; select bank containing PIE1

                                                                                BSF                          PIE1, RCIE                                                                ; enable EUSART receive interrupt

initialize_comm:

                                                                                BANKSEL RCSTA                                                                     ; select bank containing RCSTA

                                                                                BSF                          RCSTA, SPEN                                                           ; enable serial port

                                                                                BSF                          RCSTA, CREN                                                          ; enable receive

                                                                                BANKSEL TXSTA                                                                      ; select bank containing TXSTA

                                                                                BSF                          TXSTA, TXEN                                                           ; enable transmit(also enables TXIF in PIR1)

 

INIT_DELAY_TIMERS:

                                                BANKSEL                 T2CON                                     ; select bank containing T2CON

                                                                                BSF         T2CON, TMR2ON                    ; set TMR2ON bit to turn Timer2 on (Timer2 at 20MHz/4 = 5MHz)

 

INIT_HARD_RESET:

                                                                                BCF                          ACK_FLAG, HARD_RESET_BIT                ; clear the hard reset acknowledgement flag

 

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

;               MAIN LOOP

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

 

PLAY_GAME:

                                ; check for hard reset

                                                                                BANKSEL PIR1                                                                         ; select bank containing PIR1

                                                                                BTFSC                      ACK_FLAG, HARD_RESET_BIT                ; check if a hard reset has been received

                                                                                GOTO                      MAIN                                                                       ; if a hard reset has been received then goto MAIN

                                ; set ping response bytes                                                                                        ; if no hard reset was received, setup the waiting for iButton state ping response

                                                                                MOVLW                  PING_WAIT_IBUTTON_BYTE1                              

                                                                                MOVWF                  PING_RESPONSE_BYTE1                       

                                                                                MOVLW                  PING_WAIT_IBUTTON_BYTE2                              

                                                                                MOVWF                  PING_RESPONSE_BYTE2

                                ; enter wait for ibutton state

                                                                                CALL                        WAIT_FOR_IBUTTON                                             ; go to the waiting for iButton state

                                ; check for hard reset

                                                                                BANKSEL PIR1                                                                         ; select the bank containing PIR1

                                                                                BTFSC                      ACK_FLAG, HARD_RESET_BIT                ; check if a hard reset has been received

                                                                                GOTO                      MAIN                                       ; if a hard reset hsa been received then goto MAIN

                                ; set ping response bytes                                                                                        ; if no hard reset was received, setup the waiting for helm match state ping response

                                                                                BANKSEL PIR1                                                                         ; also initialize the navigation and special bytes to no action

                                                                                CLRF                        RX_DATA_HEADER                                

                                                                                MOVLW                  NO_ACTION_NAVIGATION

                                                                                MOVWF                  NAVIGATION_BYTE

                                                                                CLRF                        SPECIAL_BYTE

                                                                                CALL                        HANDLE_NAVIGATION_BYTE

                                                                                CALL                        HANDLE_SPECIAL_BYTE                                                                        

                                                                                MOVLW                  PING_WAIT_MATCH_BYTE1

                                                                                MOVWF                  PING_RESPONSE_BYTE1

                                                                                MOVLW                  PING_WAIT_MATCH_BYTE2

                                                                                MOVWF                  PING_RESPONSE_BYTE2

                                ; enter wait for helm match state

                                                                                CALL                        WAIT_FOR_HELM_MATCH                    ; go to the waiting for helm match state

                                ; check for hard reset

                                                                                BTFSC                      ACK_FLAG, HARD_RESET_BIT                ; check if a hard reset has been received

                                                                                GOTO                      MAIN                                                                       ; if a hard reset has been received, goto main

                                ; set ping response bytes                                                                                        ; if no hard reset has been received, setup the paired ping response

                                                                                MOVLW                  PING_PAIRED_BYTE1

                                                                                MOVWF                  PING_RESPONSE_BYTE1

                                                                                MOVF                      PAIRED_ADDRESS_LSB, W

                                                                                MOVWF                  PING_RESPONSE_BYTE2

                                ; enter execute commands state

                                                                                CALL                        EXECUTE_COMMANDS                                           ; goto the execute commands state and begin responding to helm commands

                                ; check for hard reset

                                                                                BANKSEL PIR1                                                                         ; select the bank containing PIR1

;                                                                               BTFSC                      ACK_FLAG, HARD_RESET_BIT                ; check if a hard reset has been received

;                                                                               GOTO                      MAIN                                                                       ; if a hard reset has been received goto main

                                                                                GOTO                      MAIN                                                                       ; if no hard reset was received, an error occured somewhere, goto main

 

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

;               CHECK FOR IBUTTON ROUTINE

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

 

WAIT_FOR_IBUTTON:

 

CHECK_FOR_IBUTTON:         

                                                                                BANKSEL PIR1                                                                         ; select the bank containing PIR1

                                                                                BCF                          ACK_FLAG, STAND_DOWN_BIT             ; clear the stand down flag, no stand down can be responded to in this state

                                                                                NOP

                                                                                BCF                          HELM_STAND_DOWN_RESPONSE, 0    ; clear the helm stand down response flag, no stand down can be responsed to in this state

                                                                                NOP

                                                                                BCF                          ACK_FLAG, SOFT_RESET_BIT ; clear the soft reset bit, no soft reset can be responded to in this state

                                                                                NOP

                                                                                BTFSC                      ACK_FLAG, ADMIRAL_PING_BIT            ; check if a ping from the admiral has been received

                                                                                CALL                        SEND_PING_RESPONSE                         ; if a ping from the admiral has been received, respond to the ping

                                                                                BANKSEL PIR1                                                                         ; if no ping has been received, select the bank containing PIR1

                                                                                BTFSC                      ACK_FLAG, HARD_RESET_BIT                ; check if a hard reset has been received

                                                                                RETURN                                                                                  ; if a hard reset has been received, break out of this state to respond to the hard reset

                                                                                CALL                        IBUTTON_PIN_TO_OUTPUT                  ; if no hard reset has been received, set iButton pin to output

                                                                                BANKSEL PORTB                                                                     ; select the bank containing PORTB

                                                                                BCF                          PORTB, IBUTTON_BIT                            ; set the iButton pin low

                                                                                CALL                        WAIT_500US                                                          ; wait 500us

                                                                                CALL                        IBUTTON_PIN_TO_INPUT                      ; set iButton pin to input

                                                                                CALL                        WAIT_50US                                                            ; wait 50us

                                                                                BANKSEL PORTB                                                                     ; select the bank containing PORTB

                                                                                BTFSC                      PORTB, IBUTTON_BIT                            ; check if the iButton pin is low, it is low if there is an iButton there

                                                                                GOTO                      CHECK_FOR_IBUTTON                                           ; if there is no iButton then check again

                                                                                GOTO                      CONDUCT_RESET                                   ; if there is an iButton the conduct a reset

 

CONDUCT_RESET:

                                                                                BANKSEL PORTC                                                                     ; select the bank containing PORTC

                                                                                CALL                        IBUTTON_PIN_TO_OUTPUT                  ; set iButton pin to output

                                                                                BANKSEL PORTB                                                                     ; select the bank containing PORTB

                                                                                BCF                          PORTB, IBUTTON_BIT                            ; set the line low

                                                                                CALL                        WAIT_500US                                                          ; wait 500us

                                                                                BANKSEL PORTB                                                                     ; select the bank containing PORTB

                                                                                BSF                          PORTB, IBUTTON_BIT                            ; set the line high

                                                                                CALL                        WAIT_500US                                                          ; wait 500us

SEND_READ_ROM_COMMAND:

                                                                                ; Read ROM command is 0x33 (b'00110011'), sending LSB first (b'11001100')                                                                 

                                                                                CALL                        SEND_READ_ROM_BIT_HIGH                               ; send bit0, 1

                                                                                CALL                        SEND_READ_ROM_BIT_HIGH                               ; send bit1, 1

                                                                                CALL                        SEND_READ_ROM_BIT_LOW                                ; send bit2, 0

                                                                                CALL                        SEND_READ_ROM_BIT_LOW                                ; send bit3, 0

                                                                                CALL                        SEND_READ_ROM_BIT_HIGH                               ; send bit4, 1

                                                                                CALL                        SEND_READ_ROM_BIT_HIGH                               ; send bit5, 1

                                                                                CALL                        SEND_READ_ROM_BIT_LOW                                ; send bit6, 0

                                                                                CALL                        SEND_READ_ROM_BIT_LOW                                ; send bit7, 0

INIT_IBUTTON_READING:

                                                                                BANKSEL PORTA                                                                     ; select the bank containing PORTA

                                                                                CLRF                        IBUTTON_BYTE0                                    ; clear ibutton byte 0

                                                                                CLRF                        IBUTTON_BYTE1                                    ; clear ibutton byte 1

                                                                                CLRF                        IBUTTON_BYTE2                                    ; clear ibutton byte 2

                                                                                CLRF                        READ_BYTE_COUNTER                                          ; set the read byte counter to 0

                                                                                BSF                          READ_BYTE_COUNTER, 0                      ; set bit 0 of the read byte counter to 1

                                                                                CLRF                        READ_BIT_COUNTER                                             ; set the read bit counter to 0

                                                                                BSF                          READ_BIT_COUNTER, 0                         ; set bit 0 of the read bit counter to 1

READ_IBUTTON_BYTE:

                                                                                CALL                        READ_IBUTTON                                      ; read the iButton

                                                                                BANKSEL PORTB                                                                     ; select the bank containing PORTB

                                                                                BTFSC                      READ_BIT_COUNTER, 7                         ; check if the read bit counter is clear, 0

                                                                                GOTO                      INIT_NEXT_BYTE_READ                         ; read the next byte

                                                                                RLF                          READ_BIT_COUNTER, F                         ; shift the read bit counter left one space

                                                                                GOTO                      READ_IBUTTON_BYTE                                           ; read the next bit of the byte

INIT_NEXT_BYTE_READ:

                                                                                RLF                          READ_BYTE_COUNTER, F                      ; shift the read byte counter left one space

                                                                                BTFSC                      READ_BYTE_COUNTER,3                      ; check if bit 3 of the read byte counter is set, ie. preparing to read a 4th byte

                                                                                GOTO                      CHECK_READING_ERROR                      ; if we are trying to read a 4th byte, check for a reading error

                                                                                CLRF                        READ_BIT_COUNTER                                             ; if we are still trying to read bytes 1, 2, or 3 clear the read bit counter

                                                                                BSF                          READ_BIT_COUNTER, 0                         ; set bit 0 of the read bit counter to 1

                                                                                GOTO                      READ_IBUTTON_BYTE                                           ; read the next byte

CHECK_READING_ERROR:

                                                                                BANKSEL PORTA                                                                     ; select the bank containing PORTA

                                                                                MOVF                      IBUTTON_BYTE0, W                                               ; move iButton byte 0 to W

                                                                                SUBLW                    IBUTTON_FAMILY1                                                ; subtract IBUTTON_FAMILY1 (0x01) from IBUTTON_BYTE0

                                                                                BTFSC                      STATUS,Z                                                                ; test bit Z of STATUS register               

                                                                                GOTO                      DETERMINE_TEAM                                 ; if IBUTTON_BYTE0 = IBUTTON_FAMILY1 (0x01), display the appropriate byte

                                                                                MOVF                      IBUTTON_BYTE0, W                                               ; move iButton byte 0 to W

                                                                                SUBLW                    IBUTTON_FAMILY2                                                ; subtract IBUTTON_FAMILY2 (0x09) from IBUTTON_BYTE0

                                                                                BTFSC                      STATUS, Z                                                               ; test bit Z of STATUS register

                                                                                GOTO                      DETERMINE_TEAM                                 ; if IBUTTON_BYTE0 = IBUTTON_FAMILY2 (0x09), determine and display which team you are on

                                                                                GOTO                      CHECK_FOR_IBUTTON                                           ; if IBUTTON_BYTE0 is not IBUTTON_FAMILY1 or IBUTTON_FAMILY2, an error occured, check for the ibutton again

DETERMINE_TEAM:

                                                                                BANKSEL PORTC                                                                     ; select the bank containing PORTC

                                                                                BCF                          PORTC, RED_LED                                    ; clear the signal pin for the red team led on PORTC

                                                                                NOP

                                                                                BCF                          PORTC, BLUE_LED                                  ; clear the signal pin for the blue team led on PORTC

                                                                                NOP

                                                                                BTFSC                      IBUTTON_BYTE1, TEAM_BIT                 ; check if the ibutton received puts the boat on the red team

                                                                                BSF                          PORTC, RED_LED                                    ; if the ibutton is a red team ibutton, turn on the red light

                                                                                BTFSS                      IBUTTON_BYTE1, TEAM_BIT                 ; check if the ibutton received puts the boat on the blue team

                                                                                BSF                          PORTC, BLUE_LED                                  ; if the ibutton is a blue team ibutton, turn on the blue light

                                                                                RETURN                                                                                  ; break out of the waiting for ibutton state

 

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

;               WAIT FOR MATCH WITH HELM ROUTINE

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

 

WAIT_FOR_HELM_MATCH:

 

RE_INIT_TIMER2:

                                                                                BANKSEL                 T2CON                                     ; select bank containing T2CON

                                                                                BSF                          T2CON, TMR2ON                                    ; turn on timer 2

                                                                                MOVLW                  b'01001000'                                                            ; move 01001000 to W

                                                                                IORWF                    T2CON, F                                                 ; or W with T2CON to set TOUTPS1-3 to 1001 and postscale timer 2 by 1:10, timer effectively at 500kHz

                                                                                BANKSEL PR2                                                                          ; select the bank containing PR2

                                                                                MOVLW                  b'11110111'                                                            ; d'249'

                                                                MOVWF       PR2                                     ; move 11111001 from W to PR2 (Timer 2 Flag set every 1/500kHz * (249+1)ticks = 500us)

                                                                                BANKSEL PIE1                                                                         ; select the bank containing PIE1

                                                                                BSF                          PIE1, TMR2IE                                          ; enable the TMR2 interrupt

 

WAIT_TO_RECEIVE_MATCHING_IBUTTON:

                                                                                BANKSEL PIR1                                                                         ; select the bank containing PIR1

                                                                                BCF                          ACK_FLAG, STAND_DOWN_BIT             ; clear the stand down flag, can not respond to a stand down in this state

                                                                                NOP

                                                                                BCF                          HELM_STAND_DOWN_RESPONSE, 0    ; clear the helm stand down flag, can not respond to a stand down in this state

                                                                                NOP

                                                                                BCF                          ACK_FLAG, SOFT_RESET_BIT ; clear the soft reset bit, can no respond to a soft reset in this state

                                                                                NOP

                                                                                NOP

                                                                                BTFSC                      ACK_FLAG, ADMIRAL_PING_BIT            ; check if a ping has been received

                                                                                CALL                        SEND_PING_RESPONSE                         ; if a ping has been received, respond to it

                                                                                BANKSEL PIR1                                                                         ; if no ping has been received, select the bank containing PIR1

                                                                                BTFSC                      ACK_FLAG, HARD_RESET_BIT                ; check if a hard reset has been received

                                                                                RETURN                                                                                  ; if a hard reset has been received, break out of this state to respond to it

                                                                                BANKSEL PIR1                                                                         ; if no hard reset hsa been received, select the bank containing PIR1

                                                                                BTFSS                      HELM_MATCH_FLAG, 0                         ; check if a helm has broadcast a matching ibutton serial

                                                                                GOTO                      WAIT_TO_RECEIVE_MATCHING_IBUTTON           ; if no helm has broadcast a matching ibutton serial, keep listening

                                                                                GOTO                      TRANSMIT_MATCHED_MSG                  ; if a helm has broadcast a matching ibutton serial, transmit a message to the helm signifying receipt

TRANSMIT_MATCHED_MSG:

                                                                                BANKSEL PIR1                                                                         ; select the bank containing PIR1

                                                                                BTFSS                      TRANSMIT_COUNTDOWN_FLAG, 0      ; check if the transmit delay count down is complete

                                                                                GOTO                      WAIT_TO_RECEIVE_MATCHING_IBUTTON           ; if the transmit delay count down is not complete, keep waiting to transmit

                                                                                CLRF                        TRANSMIT_COUNTDOWN_1                 ; if the count down is complete, clear the first count down timer

                                                                                CLRF                        TRANSMIT_COUNTDOWN_2                 ; clear the second count down timer

                                                                                CLRF                        TRANSMIT_COUNTDOWN_FLAG                          ; clear the count down complete flag

                                                                                BANKSEL PIR1                                                                         ; select the bank containing PIR1

                                                                                MOVF                      PAIRED_ADDRESS_MSB, W                   ; move the PAIRED_ADDRESS_MSB to W

                                                                                MOVWF                  DEST_ADDRESS_MSB                                             ; move the PAIRED_ADDRESS_MSB from W to DEST_ADDRESS_MSB

                                                                                MOVF                      PAIRED_ADDRESS_LSB, W                     ; move the PAIRED_ADDRESS_LSB to W

                                                                                MOVWF                  DEST_ADDRESS_LSB                                              ; move the PAIRED_ADDRESS_LSB from W to DEST_ADDRESS_LSB

                                                                                MOVLW                  WATERCRAFT_HEADER                                         ; move WATERCRAFT_HEADER to W

                                                                                MOVWF                  TX_DATA_HEADER                                 ; move the WATERCRAFT_HEADER from W to TX_DATA_HEADER

                                                                                MOVLW                  MATCHED_1                                                           ; move MATCHED_1 to W

                                                                                MOVWF                  TX_DATA_BYTE1                                     ; move MATCHED_1 from W to TX_DATA_BYTE1

                                                                                MOVLW                  MATCHED_2                                                           ; move MATCHED_2 to W

                                                                                MOVWF                  TX_DATA_BYTE2                                     ; move MATCHED_2 from W to TX_DATA_BYTE2

                                                                                CALL                        TRANSMIT                                                              ; transmit the stored message

                                                                                BTFSS                      HELM_MATCH_FLAG, 1                         ; check if the helm has responded with a no action

                                                                                GOTO                      WAIT_TO_RECEIVE_MATCHING_IBUTTON           ; if the helm has not responded, keep transmitting

                                                                                RETURN                                                                                  ; if the helm has responded, break out of this state

 

; check address if additional msg checks are needed

 

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

;               EXECUTE COMMANDS ROUTINE

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

 

EXECUTE_COMMANDS:

 

INIT_COUNTERS:                                                                                                                                                    ; clear all necessary bytes, counters, etc.

                                                                                BANKSEL                 PIR1        

                                                                                CLRF                        MOTOR_TIMER_COUNT                       

                                                                                CLRF                        SERVO_TIMER_COUNT                         

                                                                                CLRF                        ACK_FLAG

                                                                                CLRF                        HELM_STAND_DOWN_RESPONSE

                                                                                CLRF                        THREE_SEC_COUNTER_HIGH

                                                                                CLRF                        THREE_SEC_COUNTER_LOW

                                                                                CLRF                        RX_BABYSIT

CHECK_INCOMING_DATA:                                                    

                                                                                BANKSEL                 PIR1                                                                         ; select the bank containing PIR1

                                                                                BTFSC                      ACK_FLAG, ADMIRAL_PING_BIT                            ; check if a ping from the admiral has been received

                                                                                CALL                        SEND_PING_RESPONSE                                         ; if a ping from the admiral has been received,respond to the ping

                                                                                BANKSEL                 PIR1                                                                         ; if no ping was received, select the bank containing PIR1       

                                                                                BTFSC                      ACK_FLAG, STAND_DOWN_BIT                             ; check if a stand down command has been issued

                                                                                CALL                        SEND_STAND_DOWN_ACK_TO_ADMIRAL                            ; if a stand down command has been issued, respond to it

                                                                                BANKSEL                 PIR1                                                                         ; if no stand down command was issued, select the bank containing PIR1

                                                                                BTFSC                      ACK_FLAG, SOFT_RESET_BIT                 ; chceck if a soft reset has been issued

                                                                                CALL                        SEND_SOFT_RESET_ACKNOWLEDGEMENTS        ; if a soft reset has been issued, respond to it

                                                                                BANKSEL                 PIR1                                                                         ; if no soft reset was issued, select the bank containing PIR1

                                                                                BTFSC                      ACK_FLAG, HARD_RESET_BIT                                ; check if a hard reset has been issued

                                                                                GOTO                      HANDLE_HARD_RESET                                          ; if a hard reset has been issued, handle it

                                                                                GOTO                      HANDLE_INCOMING_DATA                                   ; if no hard reset has been issued, process the incoming navigation commands

HANDLE_INCOMING_DATA:

                                                                                BANKSEL                 PIR1                                                                         ; select the bank containing PIR1

                                                                                BTFSS                      HELM_STAND_DOWN_RESPONSE, 0                    ; check if a respone to a stand down from the helm is pending

                                                                                CALL                        CHECK_FOR_NAVIGATION_BYTE                          ; if yes, skip this step, if not, check to see if the most recent received packet has a navigation header

                                                                                CALL                        HANDLE_NAVIGATION_BYTE                                                ; handle the most recent navigation byte

                                                                                CALL                        HANDLE_SPECIAL_BYTE                                         ; handle the most recent special byte

                                                                                BANKSEL                 PIR1                                                                         ; select the bank containing PIR1

                                                                                BTFSC                      HELM_STAND_DOWN_RESPONSE, 0                    ; check if a response to a stand down from the helm is pending

                                                                                CALL                        SEND_STAND_DOWN_TO_HELM                                          ; if yes, send a stand down command to the helm

                                                                                GOTO                      CHECK_INCOMING_DATA                                      ; if no response is pending, begin processing the most recent navigation data

HANDLE_HARD_RESET:

                                                                                CALL                        HANDLE_NAVIGATION_BYTE                                                ; handle the navigation byte

                                                                                CALL                        HANDLE_SPECIAL_BYTE                                         ; handle the special byte

                                                                                RETURN

 

CHECK_FOR_NAVIGATION_BYTE:

                                                                                BANKSEL                 PIR1

                                                                                BTFSS                      RX_DATA_HEADER, NAVIGATION_HEADER_BIT  ; check if RX_DATA_HEADER is a NAVIGATION_HEADER

                                                                                RETURN                                                                                                  ; if Z = 0, the RX_DATA_HEADER is not a NAVIGATION_HEADER, go back to waiting for the correct msg type

                                                                                MOVF                      RX_DATA_BYTE1, W                                               ; if Z = 1, the RX_DATA_HEADER is a NAVIGATION_HEADER, move RX_DATA_BYTE1 to W

                                                                                MOVWF                  NAVIGATION_BYTE                                                                ; move RX_DATA_BYTE1 from W to NAVIGATION_BYTE

                                                                                MOVF                      RX_DATA_BYTE2, W                                               ; move RX_DATA_BYTE2 to W

                                                                                MOVWF                  SPECIAL_BYTE                                                         ; move RX_DATA_BYTE2 from W to SPECIAL_BYTE

                                                                                RETURN

 

HANDLE_NAVIGATION_BYTE:

                                                                                MOVF                      NAVIGATION_BYTE,W                                           ; move NAVIGATION_BYTE to W

                                                                                ANDLW                   0x0F                                                                        ; save last four bits of NAVIGATION for Speed

                                                                                MOVWF                  SPEED_COMMAND                                                 ; store speed

                                                                                SWAPF                    NAVIGATION_BYTE,W                                           ; move Swapped Navigation byte to W

                                                                                ANDLW                   0x0F                                                                        ; save four bits of Navigation for Direction

                                                                                MOVWF                  DIRECTION_COMMAND                                         ; store direction

                                                                                RETURN

 

HANDLE_SPECIAL_BYTE:

                                                                                MOVF                      SPECIAL_BYTE, W                                                   ; move SPECIAL_BYTE to W

                                                                                ANDLW                   0x0F                                                                        ; save last four bits of Special for water

                                                                                BTFSC                      STATUS,Z                                                                ; Skip if not zero

                                                                                BCF                          PUMP_PORT,PUMP_PIN                                        ; Turn off Pump

                                                                                BTFSS                      STATUS,Z                                                                ; Skip if is zero

                                                                                BSF                          PUMP_PORT,PUMP_PIN                                        ; Turn on Pump

                                                                                RETURN

                                                               

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

;               SERVO CONTROL SUBROUTINES

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

 

SERVICE_SERVO_DIRECTION:

                                                                                BANKSEL                 PORTC

                                                                                BTFSS                      DIRECTION_COMMAND,3                      ; skip if the direction bit is set (Straight or right)

                                                                                CALL                        SET_SERVO_LEFT                                   ; move servo left command into W

                                                                                BTFSC                      DIRECTION_COMMAND,3                      ; skip if the direction bit is clear (Left)

                                                                                CALL                        CENTER_OR_RIGHT

                                                                                RETURN

 

CENTER_OR_RIGHT:

                                                                                MOVF                      DIRECTION_COMMAND,W                     ; move direction command to W

                                                                                ANDLW                   0x07                                                        ; save last three bits of the direction

                                                                                BTFSC                      STATUS,Z                                                ; skip if the result above was not equal to zero

                                                                                CALL                        SET_SERVO_CENTER                              ; set the servo to the center position

                                                                                MOVF                      DIRECTION_COMMAND,W                     ; move direction command to W

                                                                                ANDLW                   0x07                                                        ; save last three bits of the direction

                                                                                BTFSS                      STATUS,Z                                                ; skip if the result above was equal to zero

                                                                                CALL                        SET_SERVO_RIGHT                                                ; set the servo to the center position

                                                                                RETURN

 

SET_SERVO_CENTER:

                                                                                MOVLW                  SERVO_CENTER                                      ; set the servo high value to reflect center position

                                                                                MOVWF                  SERVO_DESIRED

                                                                                RETURN

 

SET_SERVO_RIGHT:

                                                                                MOVLW                  SERVO_RIGHT                                        ; set the servo high value to reflect right position

                                                                                MOVWF                  SERVO_DESIRED

                                                                                RETURN

 

SET_SERVO_LEFT:

                                                                                MOVLW                  SERVO_LEFT                                           ; set the servo high value to reflect left position

                                                                                MOVWF                  SERVO_DESIRED

                                                                                RETURN 

 

SERVICE_SERVO_TIMER:

                                                                                BANKSEL                 PORTC                                                     ; select port bank

                                                                                MOVF                      SERVO_TIMER_COUNT,W                     ; move period position to W

                                                                                SUBWF                   SERVO_DESIRED,W                                                ; subtract SERVO_TIMER_COUNTER from SERVO_DESIRED

                                                                                BTFSC                      STATUS,C                                                ; skip if carry bit is 0 meaning skip if SERVO_AT > SERVO_DESIRED

                                                                                BSF                                          SERVO_PORT,SERVO_PIN      ; set the servo pin high

                                                                                BTFSS                      STATUS,C                                                ; skip if carry bit is 1 meaning skip if SERVO_AT <= SERVO_DESIRED

                                                                                BCF                                          SERVO_PORT,SERVO_PIN      ; set the servo pin low

                                                                                MOVF                      SERVO_TIMER_COUNT,W                     ; move period position to W

                                                                                SUBLW                    SERVO_MAX                                           ; subtract W from SERVO_MAX

                                                                                BTFSC                      STATUS,Z                                                ; skip if subtraction not equal to zero

                                                                                GOTO                      RESET_SERVO_TIMER_COUNT                              ; reset SERVO_MOTOR_COUNTER for new period

                                                                                GOTO                      INCF_SERVO_TIMER_COUNT                                ; if the subtraction is non-zero then increment the counters

 

RESET_SERVO_TIMER_COUNT:

                                                                                CLRF                        SERVO_TIMER_COUNT                          ; clear the SERVO_TIMER_COUNT

                                                                                RETURN

 

INCF_SERVO_TIMER_COUNT:

                                                                                INCF                        SERVO_TIMER_COUNT, F                      ; increment the SERVO_TIMER_COUNT

                                                                                RETURN

 

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

;               MOTOR CONTROL SUBROUTINES

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

 

SERVICE_MOTOR_DIRECTION:

                                                                                BTFSC                      SPEED_COMMAND,3                                              ; Skip if MSB of Motor command is low (backwards)

                                                                                CALL                        GO_FORWARD                                       ; if bit 3 of the speed command is high, go forward

                                                                                BTFSS                      SPEED_COMMAND,3                                              ; Skip if MSB of Motor command is high (forwards)      

                                                                                CALL                        GO_BACKWARD                                     ; if bit 3 of the speed command is low go backward

                                                                                RETURN

 

GO_FORWARD:

                                                                                BCF                          MOTOR_PORT,MOTOR_DIRECTION_PIN                              ; Set Motor direction pin low

                                                                                MOVF                      SPEED_COMMAND,W                                                                            ; Move Speed command to W

                                                                                ANDLW                   0x07                                                                                        ; AND speed command with 0000 0111

                                                                                BTFSC                      STATUS,Z                                                                                ; if result of AND is not zero, skip

                                                                                CLRF                        MOTOR_TIMER_DESIRED                                                      ; if the result is zero then a no move command has been issued, don't move

                                                                                BTFSS                      STATUS,Z                                                                                ; if it is zero then skip (not affected by BCF command)

                                                                                CALL                        SET_FORWARD_LEVEL                                                           ; call subroutine to check for full or partial speed

                                                                                RETURN

 

GO_BACKWARD:

                                                                                BSF                          MOTOR_PORT,MOTOR_DIRECTION_PIN                              ; Set Motor direction pin high

                                                                                MOVF                      SPEED_COMMAND,F                                                              ; Move the file to itself to test for zero

                                                                                BTFSC                      STATUS,Z                                                                ; Skip if speed command not zero

                                                                                CALL                        SET_DUTY_75_BACKWARD                                    ; if Z is 1 then full backwards was requested, set duty to 75%

                                                                                BTFSS                      STATUS,Z                                                                                                ; Skip if speed command is zero and was handled with the BCF

                                                                                CALL                        SET_DUTY_50                                                                                         ; if if Z is 0 then a slower backward speed was requested, set duty to 50%

                                                                                RETURN

 

SET_FORWARD_LEVEL:

                                                                                SUBLW                    0x07                                                                                                        ; subtract 0000 0111 from W, if zero, original speed was full forward

                                                                                BTFSC                      STATUS,Z                                                                                                ; skip if Z is not set, i.e. not full forward

                                                                                CALL                        SET_DUTY_75_FORWARD                                                                     ; if Z is set, set the motor duty cycle to 75% forward

                                                                                BTFSS                      STATUS,Z                                                                                                ; skip if Z is set, i.e. full speed already set

                                                                                CALL                        SET_DUTY_50                                                                                         ; if Z is not set, set the motor duty cycle to 50%

                                                                                RETURN

 

SET_DUTY_75_FORWARD:

                                                                                MOVLW                  MOTOR_DUTY_75_FORWARD                                                                              ; move MOTOR_DUTY_75_FORWARD to W

                                                                                MOVWF                  MOTOR_TIMER_DESIRED                                                                      ; move MOTOR_DTUY_75_FORWARD from W to MOTOR_TIMER_DESIRED

                                                                                RETURN

 

SET_DUTY_50:

                                                                                MOVLW                  MOTOR_DUTY_50                                                                                  ; move MOTOR_DUTY_50 to W

                                                                                MOVWF                  MOTOR_TIMER_DESIRED                                                                      ; move MOTOR_DUTY_50 from W to MOTOR_TIMER_DESIRED

                                                                                RETURN

 

SET_DUTY_75_BACKWARD:

                                                                                MOVLW                  MOTOR_DUTY_75_BACKWARD                                                                             ; move MOTOR_DUTY_75_BACKWARD, to W

                                                                                MOVWF                  MOTOR_TIMER_DESIRED                                                                      ; move MOTOR_DUTY_75_BACKWARD from W to MOTOR_TIMER_DESIRED

                                                                                RETURN

 

SERVICE_MOTOR_TIMER:

                                                                                BANKSEL                 PORTC                                                                                                     ; select port bank

                                                                                INCF                        MOTOR_TIMER_COUNT, F                                    ; increment MOTOR_TIMER_COUNT

                                                                                MOVF                      MOTOR_TIMER_COUNT, W                                   ; move period position to W

                                                                                DECF                        MOTOR_TIMER_COUNT, F                                    ; set MOTOR_TIMER_COUNT back to what it should be

                                                                                SUBWF                   MOTOR_TIMER_DESIRED,W                                  ; subtract MOTOR_TIMER_COUNTER from MOTOR_TIMER_DESIRED

                                                                                BTFSC                      STATUS,C                                                                                                ; skip if carry bit is 0 meaning skip if MOTOR_TIMER_COUNT => MOTOR_TIMER_DESIRED (b/c of inc before MOVF)

                                                                                BSF                          MOTOR_PORT,MOTOR_PWM_PIN                       ; set the servo pin high

                                                                                BTFSS                      STATUS,C                                                                                                ; skip if zero bit is 1 meaning skip if MOTOR_TIMER_COUNT < MOTOR_TIMER_DESIRED

                                                                                BCF                          MOTOR_PORT,MOTOR_PWM_PIN                                       ; set the servo pin low

                                                                                MOVF                      MOTOR_TIMER_COUNT,W                                                    ; move period position to W

                                                                                SUBLW                    MOTOR_TIMER_MAX                                                                             ; subtract W from MOTOR_TIMER_MAX

                                                                                BTFSC                      STATUS,Z                                                                                                ; skip if subtraction not equal to zero

                                                                                GOTO                      RESET_MOTOR_TIMER_COUNT                                            ; if the subtraction is equal to zero, reset MOTOR_TIMER_COUNTER for new period

                                                                                GOTO                      INCF_MOTOR_TIMER_COUNT                                               ; if the subtraction is non-zero then increment the MOTOR_TIMER_COUNTER

 

RESET_MOTOR_TIMER_COUNT:

                                                                                CLRF                        MOTOR_TIMER_COUNT                        ; clear the MOTOR_TIMER_COUNT

                                                                                RETURN

 

INCF_MOTOR_TIMER_COUNT:                             

                                                                                INCF                        MOTOR_TIMER_COUNT, F                    ; increment the MOTOR_TIMER_COUNT

                                                                                RETURN

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

;               RESPONSE CODE FOR PINGS ADMIRALS AND ALL THAT BUSINESS

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

 

                ; Ping Responses

 

SEND_PING_RESPONSE:

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                MOVLW                  ADMIRAL_ADDRESS_MSB                      ; move the ADMIRAL_ADDRESS_MSB to W

                                                                                MOVWF                  DEST_ADDRESS_MSB                             ; move the ADMIRAL_ADDRESS_MSB from W to DEST_ADDRESS_MSB

                                                                                MOVLW                  ADMIRAL_ADDRESS_LSB                       ; move the ADMIRAL_ADDRESS_LSB to W

                                                                                MOVWF                  DEST_ADDRESS_LSB                              ; move the ADMIRAL_ADDRESS_LSB from W to DEST_ADDRESS_LSB

                                                                                MOVLW                  PING_RESPONSE_HEADER                    ; move the PING_RESPONSE_HEADER to W

                                                                                MOVWF                  TX_DATA_HEADER                                 ; move the PING_RESPONSE_HEADER from W to TX_DATA_HEADER

                                                                                MOVF                      PING_RESPONSE_BYTE1, W                  ; move the PING_RESPONSE_BYTE1 to W

                                                                                MOVWF                  TX_DATA_BYTE1                                     ; move the PING_RESPONSE_BYTE1 from W to TX_DATA_BYTE1

                                                                                MOVF                      PING_RESPONSE_BYTE2, W                  ; move the PING_RESPONSE_BYTE2 to W

                                                                                MOVWF                  TX_DATA_BYTE2                                     ; move the PING_RESPONSE_BYTE2 from W to TX_DATA_BYTE2

                                                                                CALL                        TRANSMIT                                              ; transmit

                                                                                BANKSEL                 PORTA                                                     ; select the bank containing PORTA      

                                                                                BCF                          ACK_FLAG, ADMIRAL_PING_BIT            ; clear the ping received from admiral flag

                                                                                RETURN

 

                ; Ackowledgements

 

SEND_SOFT_RESET_ACKNOWLEDGEMENTS:

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                MOVLW                  ADMIRAL_ADDRESS_MSB                      ; move the ADMIRAL_ADDRESS_MSB to W

                                                                                MOVWF                  DEST_ADDRESS_MSB                             ; move the ADMIRAL_ADDRESS_MSB from W to DEST_ADDRESS_MSB

                                                                                MOVLW                  ADMIRAL_ADDRESS_LSB                       ; move the ADMIRAL_ADDRESS_LSB to W

                                                                                MOVWF                  DEST_ADDRESS_LSB                              ; move the ADMIRAL_ADDRESS_LSB from W to DEST_ADDRESS_LSB

                                                                                MOVLW                  ACK_HEADER                                          ; move ACK_HEADER to W

                                                                                MOVWF                  TX_DATA_HEADER                                 ; move the ACK_HEADER from W to TX_DATA_HEADER

                                                                                MOVLW                  0x00                                                        ; move 0x00 to W

                                                                                MOVWF                  TX_DATA_BYTE1                                     ; move 0x00 from W to TX_DATA_BYTE1

                                                                                MOVLW                  SOFT_RESET                                           ; move SOFT_RESET to W

                                                                                MOVWF                  TX_DATA_BYTE2                                     ; move SOFT_RESET from W to TX_DATA_BYTE2

                                                                                CALL                        TRANSMIT                                              ; transmit

                                                                                BANKSEL                 PORTA                                                     ; select the bank containing PORTA

                                                                                BCF                          ACK_FLAG, SOFT_RESET_BIT ; clear the soft reset received flag

                                                                                RETURN

 

SEND_STAND_DOWN_ACK_TO_ADMIRAL:

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                MOVLW                  ADMIRAL_ADDRESS_MSB                      ; move the ADMIRAL_ADDRESS_MSB to W

                                                                                MOVWF                  DEST_ADDRESS_MSB                             ; move the ADMIRAL_ADDRESS_MSB from W to DEST_ADDRESS_MSB

                                                                                MOVLW                  ADMIRAL_ADDRESS_LSB                       ; move the ADMIRAL_ADDRESS_LSB to W

                                                                                MOVWF                  DEST_ADDRESS_LSB                              ; move the ADMIRAL_ADDRESS_LSB from W to DEST_ADDRESS_LSB

                                                                                MOVLW                  ACK_HEADER                                          ; move ACK_HEADER to W

                                                                                MOVWF                  TX_DATA_HEADER                                 ; move the ACK_HEADER from W to TX_DATA_HEADER

                                                                                MOVLW                  0x00                                                        ; move 0x00 to W

                                                                                MOVWF                  TX_DATA_BYTE1                                     ; move 0x00 from W to TX_DATA_BYTE1

                                                                                MOVLW                  STAND_DOWN                                       ; move STAND_DOWN to W

                                                                                MOVWF                  TX_DATA_BYTE2                                     ; move STAND_DOWN from W to TX_DATA_BYTE2

                                                                                CALL                        TRANSMIT                                              ; transmit

                                                                                BANKSEL                 PORTA                                                     ; select the bank containing PORTA

                                                                                BCF                          ACK_FLAG, STAND_DOWN_BIT             ; clear the stand down received flag

                                                                                RETURN

 

SEND_STAND_DOWN_TO_HELM:

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                BTFSS                      TRANSMIT_COUNTDOWN_FLAG, 0      ; check if the transmit count down has been completed

                                                                                RETURN                                                                                  ; if it has not completed, do not proceed with transmission

                                                                                CLRF                        TRANSMIT_COUNTDOWN_1                 ; if it has completed, clear the first count down timer

                                                                                CLRF                        TRANSMIT_COUNTDOWN_2                 ; clear the second count down timer

                                                                                CLRF                        TRANSMIT_COUNTDOWN_FLAG                          ; clear the count down timer flag

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                MOVF                      PAIRED_ADDRESS_MSB, W                   ; move the PAIRED_ADDRESS_MSB to W

                                                                                MOVWF                  DEST_ADDRESS_MSB                             ; move the PAIRED_ADDRESS_MSB from W to DEST_ADDRESS_MSB

                                                                                MOVF                      PAIRED_ADDRESS_LSB, W                     ; move the PAIRED_ADDRESS_LSB to W

                                                                                MOVWF                  DEST_ADDRESS_LSB                              ; move the PAIRED_ADDRESS_LSB from W to DEST_ADDRESS_LSB

                                                                                MOVLW                  WATERCRAFT_HEADER                         ; move WATERCRAFT_HEADER to W

                                                                                MOVWF                  TX_DATA_HEADER                                 ; move the WATERCRAFT_HEADER from W to TX_DATA_HEADER

                                                                                MOVLW                  STAND_DOWN_RECEIVED_1                 ; move STAND_DOWN_RECEIVED_1 to W

                                                                                MOVWF                  TX_DATA_BYTE1                                     ; move STAND_DOWN_RECEIVED_1 from W to TX_DATA_BYTE1

                                                                                MOVLW                  STAND_DOWN_RECEIVED_2                 ; move STAND_DOWN_RECEIVED_2 to W

                                                                                MOVWF                  TX_DATA_BYTE2                                     ; move STAND_DOWN_RECEIVED_2 from W to TX_DATA_BYTE2

                                                                                CALL                        TRANSMIT                                              ; transmit

                                                                                RETURN

 

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

;               INTERRUPT SERVICE ROUTINES

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

 

ISR:

SAVE_REGISTERS:                 

                                                                                BANKSEL                 PORTA                                                     ; select bank containing PORTA

                                                                                MOVWF                  W_TEMP                                                 ; copy pre-interrupt contents of W to TEMP

                                                                                SWAPF                    STATUS, W                                             ; swap STATUS register and save to W

                                                                                MOVWF                  STATUS_TEMP                                        ; save contents of W to STATUS_TEMP

 

                ; INTERRUPT TYPE CHECK

 

CHECK_INTERRUPT_TYPE:

                                                                                BANKSEL                 PIR1

                                                                                BTFSC                      PIR1, RCIF                                               ; check if the receive interrupt flag has been set

                                                                                GOTO                      RECEIVE                                                  ; if the RCIE receive interrupt flag is set, run receive protocol

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1          

                                                                                BTFSS                      PIR1, TMR2IF                                          ; check if the timer2 interrupt flag has been set

                                                                                GOTO                      RESTORE_REGISTERS                            ; if timer2 has not overflowed, restore the registers and break out of the ISR

                                                                                CALL                        SERVICE_TRANSMIT_COUNTDOWN     ; if it has overflowed, service the transmit count down timers

                                                                                GOTO                      SERVICE_BABYSIT                                  ; service the baby sit function

               

                ; RECEIVE

               

RECEIVE:                                                                                

                                                                                BANKSEL                 RCSTA                                                     ; select the bank containing RCSTA

                                                                                BTFSC                      RCSTA, OERR                                          ; check for overrun error

                                                                                CALL                        CLEAR_OVERRUN_ERROR                     ; if overrun error occured, go to CLEAR_OVERRUN_ERROR

                                                                                MOVF                      RCREG, W                                               ; copy the RCREG register to W

                                                                                BANKSEL                 PORTA                                                     ; select the bank containing PORTA

                                                                                MOVWF                  DATA_RECEIVED                                     ; save the content of w register to DATA_RECEIVED

                                                                                MOVF                      RECEIVE_BYTE_COUNT,W                     ; move RECEIVED_BYTE_COUNT to W

                                                                                CALL                        RX_JUMP_TABLE                                    ; call jump table

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                MOVF                      RECEIVE_BYTE_COUNT,F                       ; move RECEIVED_BYTE_COUNT to itself

                                                                                BTFSS                      STATUS, Z                                               ; check if bit Z is set, if it is set, then RECEIVED_BYTE_COUNT is zero

                                                                                GOTO                      RESTORE_REGISTERS                            ; if bit Z is not zero, restore registers and break out of the ISR

                                                                                GOTO                      PROCESS                                                 ; if the RECEIVE_BYTE_COUNT is 0 process the received data packet

 

PROCESS:

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                BTFSS                      HELM_MATCH_FLAG, 0                         ; check if the boat has matched with a helm

                                                                                GOTO                      CHECK_FOR_IBUTTON_MATCH                             ; if no, check for a broadcast with a matching iButton serial number

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                BTFSS                      HELM_MATCH_FLAG, 1                         ; check if the boat has received a no action command in response to its transmitted matched message

                                                                                GOTO                      CHECK_FOR_NO_ACTION_MSG                            ; if no, check for a no action message from the paired helm

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                BTFSC                      HELM_STAND_DOWN_RESPONSE, 0    ; check if a helm response to a stand down is pending

                                                                                CALL                        CHECK_STAND_DOWN_ACK                  ; if yes, check for the acknoledgement from the helm

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED         ; if no, check if any other responses are required

 

                ; STATUS CHECKS

 

CHECK_FOR_IBUTTON_MATCH:

                                                                                BANKSEL                 PIR1

                                                                                BTFSS                      RX_DATA_HEADER, IBUTTON_HEADER_BIT         ; check if the RX_DATA_HEADER is an IBUTTON_HEADER

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED                         ; if Z = 0, the RX_DATA_HEADER is not an IBUTTON_HEADER, go back to waiting for the correct msg type

                                                                                MOVF                      RX_DATA_BYTE1, W                                               ; if Z = 1, the RX_DATA_HEADER is an IBUTTON_HEADER, check for an iButton serial number match, move RX_DATA_BYTE1 to W

                                                                                SUBWF                   IBUTTON_BYTE1, W                                               ; subtract RX_DATA_BYTE1 from IBUTTON_BYTE1

                                                                                BTFSS                      STATUS, Z                                                               ; check the Z bit of the status register

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED                         ; if Z = 0, the RX_DATA_BYTE1 is not IBUTTON_BYTE1, go back to waiting for the correct msg type

                                                                                MOVF                      RX_DATA_BYTE2, W                                               ; if Z = 1, the RX_DATA_BYTE1 is IBUTTON_BYTE1, check IBUTTON_BYTE2, move RX_DATA_BYTE2 to W

                                                                                SUBWF                   IBUTTON_BYTE2, W                                               ; subtract RX_DATA_BYTE2 from IBUTTON_BYTE2

                                                                                BTFSS                      STATUS, Z                                                               ; check the Z bit of the status register

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED                         ; if Z = 0, the RX_DATA_BYTE2 is not IBUTTON_BYTE2, go back to waiting for the correct msg type

                                                                                GOTO                      SAVE_PAIRED_ADDRESS                                        ; if Z = 1, the RX_DATA_BYTE2 is IBUTTON_BYTE2, an iButton match has been found, save source address and send matched msg

 

SAVE_PAIRED_ADDRESS:

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                MOVF                      SOURCE_ADDRESS_MSB, W                  ; move the SOURCE_ADDRESS_MSB to W

                                                                                MOVWF                  PAIRED_ADDRESS_MSB                         ; save the SOURCE_ADDRESS_MSB to PAIRED_ADDRESS_MSB

                                                                                MOVF                      SOURCE_ADDRESS_LSB, W                   ; move the SOURCE_ADDRESS_LSB to W

                                                                                MOVWF                  PAIRED_ADDRESS_LSB                           ; save the SOURCE_ADDRESS_LSB to PAIRED_ADDRESS_LSB

                                                                                BSF                          HELM_MATCH_FLAG, 0                         ; set the helm match flag high to signify a sucessful pairing

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED         ; check if any other responses are required

 

CHECK_FOR_NO_ACTION_MSG:

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                MOVF                      SOURCE_ADDRESS_MSB, W                  ; move the source address msb to W

                                                                                SUBWF                   PAIRED_ADDRESS_MSB, W                   ; subtract the source address msb from the paired address msb

                                                                                BTFSS                      STATUS, Z                                               ; check if the Z bit of the status register is set

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED         ; if it is not set, the source and paired addresses do not match, check if any other responses are required

                                                                                MOVF                      SOURCE_ADDRESS_LSB, W                   ; if it is set, move the source address lsb to W

                                                                                SUBWF                   PAIRED_ADDRESS_LSB, W                     ; subtract the source address lsb from the paired address lsb

                                                                                BTFSS                      STATUS, Z                                               ; check if the Z bit of the status register is set

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED         ; if it is not set, the source and paired addresses do not match, check if any other responses are required

                                                                                BANKSEL                 PIR1                                                         ; select the bank containing PIR1

                                                                                BTFSS                      RX_DATA_HEADER, NAVIGATION_HEADER_BIT  ; check if RX_DATA_HEADER is a NAVIGATION_HEADER

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED         ; if Z = 0, the RX_DATA_HEADER is not a NAVIGATION_HEADER, go back to waiting for the correct msg type

                                                                                MOVF                      RX_DATA_BYTE1, W                               ; if Z = 1, the RX_DATA_HEADER is a NAVIGATION_HEADER, check for the no action msg, move RX_DATA_BYTE1 to W

                                                                                SUBLW                    NO_ACTION_1                                        ; subtract RX_DATA_BYTE1 from NO_ACTION_1

                                                                                BTFSS                      STATUS, Z                                               ; check the Z bit of the status register

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED         ; if Z = 0, the RX_DATA_BYTE1 is not NO_MATCH_1, go back to waiting for the correct msg type

                                                                                MOVF                      RX_DATA_BYTE2, W                               ; if Z = 1, the RX_DATA_BYTE1 is NO_ACTION_1, check for NO_ACTION_2, move RX_DATA_BYTE2 to W

                                                                                SUBLW                    NO_ACTION_2                                        ; subtract RX_DATA_BYTE2 from NO_ACTION_2

                                                                                BTFSC                      STATUS, Z                                               ; check the Z bit of the status register

                                                                                BSF                                          HELM_MATCH_FLAG, 1                                                                        

                                                                                GOTO                      CHECK_IF_RESPONSE_REQUIRED                                                                                                                         ; if Z = 0, the RX_DATA_BYTE2 is not NO_ACTION_2, go back to waiting for the correct msg type

 

CHECK_STAND_DOWN_ACK:

 

                                                                                BANKSEL                 PORTA                                                     ; select the bank containing PORTA

                                                                                MOVF                      SOURCE_ADDRESS_MSB, W                  ; move the source address msb to W

                                                                                SUBWF                   PAIRED_ADDRESS_MSB, W                   ; subtract the source address from the paired address msb

                                                                                BTFSS                      STATUS, Z                                               ; check to see if they match

                                                                                RETURN                                                                                  ; if they do not match, no stand down ack was received, return

                                                                                MOVF                      SOURCE_ADDRESS_LSB, W                   ; if they do match, move the source address lsb to W

                                                                                SUBWF                   PAIRED_ADDRESS_LSB, W                     ; subtract the source address from the paired address lsb

                                                                                BTFSS                      STATUS, Z                                               ; check to see if they match

                                                                                RETURN                                                                                  ; if they do not match, no stand down ack was received, return

                                                                                BTFSS                      RX_DATA_HEADER, ACK_HEADER_BIT  ; if they do match, check if RX_DATA_HEADER is a ACK_HEADER

                                                                                RETURN                                                                                  ; if Z = 0, the RX_DATA_HEADER is not an ACK_HEADER, go back to waiting for the correct msg type

                                                                                MOVF                      RX_DATA_BYTE1, W                               ; if Z = 1, the RX_DATA_HEADER is an ACK_HEADER, check for the no action msg, move RX_DATA_BYTE1 to W

                                                                                SUBLW                    STAND_DOWN_RECEIVED_1                 ; subtract RX_DATA_BYTE1 from STAND_DOWN_RECEIVED_1

                                                                                BTFSS                      STATUS, Z                                               ; check the Z bit of the status register

                                                                                RETURN                                                                                  ; if Z = 0, the RX_DATA_BYTE1 is not STAND_DOWN_RECEVIED_1, go back to waiting for the correct msg type

                                                                                MOVF                      RX_DATA_BYTE2, W                               ; if Z = 1, the RX_DATA_BYTE1 is STAND_DOWN_RECEIVED_1, check for STAND_DOWN_RECEIVED_2, move RX_DATA_BYTE2 to W

                                                                                SUBLW                    STAND_DOWN_RECEIVED_2                 ; subtract RX_DATA_BYTE2 from STAND_DOWN_RECEIVED_2

                                                                                BTFSC                      STATUS, Z                                               ; check the Z bit of the status register

                                                                                BCF                          HELM_STAND_DOWN_RESPONSE, 0    ; if Z = 1, the RX_DATA_BYTE2 is STAND_DOWN_RECEIVED_2, the stand down ack has been received from the helm

                                                                                RETURN                                                                                  ; if Z = 0, the RX_DATA_BYTE2 is not STAND_DOWN_RECEIVED_2, go back to waiting for the correct msg type

 

                                ; MESSAGE RESPONSE CHECKS

 

CHECK_IF_RESPONSE_REQUIRED:

                                                                                BANKSEL                 PORTA                                                     ; select the bank containing PORTA

                                                                                MOVF                      SOURCE_ADDRESS_MSB, W                  ; move the source address msb to W

                                                                                SUBWF                   PAIRED_ADDRESS_MSB, W                   ; subtract the source address msb from the paired address msb to W

                                                                                BTFSS                      STATUS, Z                                               ; check if they match

                                                                                GOTO                      CHECK_IF_ADMIRAL_MSG                     ; if they do not match, the message was not from the helm, check if it was from the admiral

                                                                                MOVF                      SOURCE_ADDRESS_LSB, W                   ; if they do match, move the source address lsb to W

                                                                                SUBWF                   PAIRED_ADDRESS_LSB, W                     ; subtract the source address lsb from the paired address lsb

                                                                                BTFSS                      STATUS, Z                                               ; check if they match

                                                                                GOTO                      CHECK_IF_ADMIRAL_MSG                     ; if they don't match, the message was not from the helm, check if it was from the admiral

                                                                                BANKSEL                 PORTA                                                     ; select the bank containing PORTA

                                                                                BCF                          RX_BABYSIT, RX_BABYSIT_BIT              ; clear the 3 sec babysit flag since a message was received from the helm

                                                                                GOTO                      CHECK_IF_ADMIRAL_MSG                     ; check if the message was from the admiral

                                                                               

                                                                                                                                                                                ; BOAT will only have to send responses to the ADMIRAL

CHECK_IF_ADMIRAL_MSG:

                                                                                BANKSEL                 PORTA                                                     ; select the bank containing PORTA

                                                                                MOVF                      SOURCE_ADDRESS_MSB, W                  ; move the source address msb to W

                                                                                SUBLW                    ADMIRAL_ADDRESS_MSB                      ; subtract the source address msb from the admiral address msb

                                                                                BTFSS                      STATUS, Z                                               ; check to see if they match

                                                                                GOTO                      RESTORE_REGISTERS                            ; if they don't match then the message is not from the admiral, restore registers and break out of the ISR

                                                                                MOVF                      SOURCE_ADDRESS_LSB, W                   ; if they do match, move the source address lsb to W

                                                                                SUBLW                    ADMIRAL_ADDRESS_LSB                       ; subtract the source address lsb from the admiral address lsb

                                                                                BTFSS                      STATUS, Z                                               ; check if they match

                                                                                GOTO                      RESTORE_REGISTERS                            ; if they do not match then the message is not from the admiral, restore registers and break out of the ISR

                                                                                BTFSS                      RX_DATA_HEADER, ADMIRAL_HEADER_BIT         ; if they do match, check if the RX_DATA_HEADER is an ADMIRAL_HEADER

                                                                                GOTO                      RESTORE_REGISTERS                            ; if the admiral header bit is 0, the received data is not from the admiral, no response required

                                                                                GOTO                      DETERMINE_RESPONSE_TYPE                               ; if the message is indeed from the admiral, determine what response is necessary

 

DETERMINE_RESPONSE_TYPE:

                                                                                BANKSEL                 PORTA

                                                                                BTFSS                      HELM_MATCH_FLAG, 0

                                                                                GOTO                      PING_AND_HARD_RESET_ONLY

                                                                                BTFSS                      HELM_MATCH_FLAG, 1

                                                                                GOTO                      PING_AND_HARD_RESET_ONLY                                                                          

                                                                                BTFSC                      RX_DATA_BYTE2, STAND_DOWN_BIT                 ; if the ADMIRAL_PING_BIT is clear, check if the RX_DATA_BYTE2 is a stand down command

                                                                                GOTO                      RESPOND_TO_STAND_DOWN                                               ; if a stand down command was sent, respond accordingly

                                                                                BTFSC                      RX_DATA_BYTE2, SOFT_RESET_BIT                     

                                                                                GOTO                      RESPOND_TO_SOFT_RESET

 

PING_AND_HARD_RESET_ONLY:

                                                                                BTFSC                      RX_DATA_BYTE2, ADMIRAL_PING_BIT                 ; check if the RX_DATA_BYTE2 is a ping from the admiral

                                                                                GOTO                      RESPOND_TO_PING                                                               ; if the ADMIRAL_PING_BIT is set, a ping was sent from teh admiral, respond accordingly

                                                                                BTFSC                      RX_DATA_BYTE2, HARD_RESET_BIT

                                                                                GOTO                      RESPOND_TO_HARD_RESET

                                                                                GOTO                      RESTORE_REGISTERS                                            ; if neither a ping nor a stand down command were sent, restore registers

 

RESPOND_TO_PING:

                                                                                BANKSEL                 PORTC

                                                                                BSF                          ACK_FLAG, ADMIRAL_PING_BIT

                                                                                GOTO                      RESTORE_REGISTERS

 

RESPOND_TO_STAND_DOWN:

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  NO_ACTION_NAVIGATION

                                                                                MOVWF                  NAVIGATION_BYTE

                                                                                MOVLW                  NO_ACTION_SPECIAL

                                                                                MOVWF                  SPECIAL_BYTE

                                                                                BSF                                          ACK_FLAG, STAND_DOWN_BIT             ; set the stand down flag high

                                                                                NOP

                                                                                BSF                                          HELM_STAND_DOWN_RESPONSE, 0

                                                                                GOTO                      RESTORE_REGISTERS

 

RESPOND_TO_SOFT_RESET:

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  NO_ACTION_NAVIGATION

                                                                                MOVWF                  NAVIGATION_BYTE

                                                                                MOVLW                  NO_ACTION_SPECIAL

                                                                                MOVWF                  SPECIAL_BYTE

                                                                                BSF                                          ACK_FLAG, SOFT_RESET_BIT

                                                                                GOTO                      RESTORE_REGISTERS

RESPOND_TO_HARD_RESET:

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  NO_ACTION_NAVIGATION

                                                                                MOVWF                  NAVIGATION_BYTE

                                                                                MOVLW                  NO_ACTION_SPECIAL

                                                                                MOVWF                  SPECIAL_BYTE

                                                                                BSF                                          ACK_FLAG, HARD_RESET_BIT

                                                                                GOTO                      RESTORE_REGISTERS

 

SERVICE_TRANSMIT_COUNTDOWN:

                                                                                BANKSEL                 PIR1

                                                                                INCF                        TRANSMIT_COUNTDOWN_1, F

                                                                                MOVF                      TRANSMIT_COUNTDOWN_1, W

                                                                                SUBLW                    TRANSMIT_COUNTDOWN_TO_20MS_1

                                                                                BTFSS                      STATUS, Z

                                                                                RETURN

                                                                                CLRF                        TRANSMIT_COUNTDOWN_1

                                                                                INCF                        TRANSMIT_COUNTDOWN_2, F

                                                                                MOVF                      TRANSMIT_COUNTDOWN_2, W

                                                                                SUBLW                    TRANSMIT_COUNTDOWN_TO_20MS_2

                                                                                BTFSS                      STATUS, Z

                                                                                RETURN                                                                 

                                                                                BSF                                          TRANSMIT_COUNTDOWN_FLAG, 0

                                                                                MOVF                      TRANSMIT_COUNTDOWN_2, W

                                                                                SUBLW                    3

                                                                                BTFSC                      STATUS, Z

                                                                                CLRF                        TRANSMIT_COUNTDOWN_2                                                                

                                                                                RETURN

                                                                               

SERVICE_BABYSIT:

                                                                                BANKSEL                 PIR1

                                                                                INCF                        THREE_SEC_COUNTER_LOW, F             ; increment the three second counter low byte

                                                                                BTFSC                      STATUS,Z                                                                                ; if there is rollover

                                                                                INCF                        THREE_SEC_COUNTER_HIGH, F            ; increment the three second counter high byte

                                                                                MOVF                      THREE_SEC_COUNTER_HIGH,W           ; move the high byte to W                     

                                                                                SUBLW                    NUM_TICKS_3SEC_HIGH                                       ; subtract the desired number from W

                                                                                BTFSC                      STATUS,Z                                                                                ; if there is a match

                                                                                GOTO                      CHECK_LOW_BABYSIT                                           ; check the low byte

                                                                                GOTO                      SERVO_CONTROL                                                   ; otherwise go to servo control

 

CHECK_LOW_BABYSIT:

                                                                                BANKSEL                 PIR1

                                                                                MOVF                      THREE_SEC_COUNTER_LOW,W                            ; move the low byte to W

                                                                                SUBLW                    NUM_TICKS_3SEC_LOW                                        ; subtract the desired number from W

                                                                                BTFSS                      STATUS,Z                                                                                ; if there is no match

                                                                                GOTO                      SERVO_CONTROL                                                   ; go to servo control

                                                                                CLRF                        THREE_SEC_COUNTER_HIGH                                ; clear high byte of counter

                                                                                CLRF                        THREE_SEC_COUNTER_LOW                 ; clear low byte of counter

                                                                                BTFSS                      RX_BABYSIT,RX_BABYSIT_BIT               ; if the babysit bit is low (we have received in the last 3 sec)

                                                                                GOTO                      RESET_BABYSIT                                                      ; reset babysit

                                                                                MOVLW                  NO_ACTION_NAVIGATION                    ; move No action byte to W

                                                                                MOVWF                  NAVIGATION_BYTE                                                                ; Set NAVIGATION_BYTE to no action

                                                                                MOVLW                  NO_ACTION_SPECIAL                                             ; move NO action byte to W

                                                                                MOVWF                  SPECIAL_BYTE                                                         ; Set SPECIAL_BYTE to no action

                                                                                MOVWF                  RX_DATA_HEADER

                                                                                GOTO                      RESET_BABYSIT

 

RESET_BABYSIT:

                                                                                BANKSEL                 PIR1

                                                                                BSF                                          RX_BABYSIT,RX_BABYSIT_BIT

                                                                                GOTO                      SERVO_CONTROL

                                                                                                                                                               

                ; NAVIGATION CONTROL

 

SERVO_CONTROL:                                                                                                                                                                  ; TO BE IMPLEMENTED AS ISR

                                                                                CALL                        SERVICE_SERVO_DIRECTION ; service the servo

                                                                                CALL                        SERVICE_SERVO_TIMER

                                                                                GOTO                      MOTOR_CONTROL

 

MOTOR_CONTROL:                                                                                                                                                                                ; TO BE IMPLEMENTED AS ISR

                                                                                CALL                        SERVICE_MOTOR_DIRECTION

                                                                                CALL                        SERVICE_MOTOR_TIMER

                                                                                GOTO                      RESET_TMR2IF

 

RESET_TMR2IF:

                                                                                BANKSEL                 PIR1

                                                                                BCF                                          PIR1, TMR2IF                                          ; clear the Timer 2 flag

                                                                                GOTO                      RESTORE_REGISTERS

 

RESTORE_REGISTERS:

                                                                                CLRF                        DATA_RECEIVED                                     ; clear DATA_RECEIVED

                                                                                SWAPF                    STATUS_TEMP, W                                  ; swap nibbles in STATUS_TEMP register and save in W

                                                                                MOVWF                  STATUS                                                                   ; restore pre-interrupt STATUS register

                                                                                SWAPF                    W_TEMP, F                                                             ; swap nibbles in W_TEMP and save results in W_TEMP

                                                                                SWAPF                    W_TEMP, W                                                           ; swap nibbles in W_TEMP and save results in W_TEMP

                                                                                RETFIE                                                                                                                     ; return to interrupted code

 

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

;               TRANSMIT ROUTINE

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

                                               

TRANSMIT:

                                                                                CALL                        CALCULATE_CHECKSUM

; start sending the data packet

; send START_BYTE

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  START_BYTE

                                                                                CALL                        TRANSMIT_BYTE                                                                   

; send LENGTH_MSB

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  LENGTH_MSB                                                         ; 0x00

                                                                                CALL                        TRANSMIT_BYTE

; send LENGTH_LSB

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  LENGTH_LSB                                                          ; 0x08

                                                                                CALL                        TRANSMIT_BYTE

; send API_TX

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  API_TX                                                                     ; 0x01

                                                                                CALL                        TRANSMIT_BYTE

; send FRAME_ID

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  FRAME_ID                                                               ; 0x00

                                                                                CALL                        TRANSMIT_BYTE

; send ADDRESS_MSB

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVF                      DEST_ADDRESS_MSB,W

                                                                                CALL                        TRANSMIT_BYTE

; send ADDRESS_LSB

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVF                      DEST_ADDRESS_LSB,W

                                                                                CALL                        TRANSMIT_BYTE

; send OPTIONS

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  OPTIONS                                                                 ; 0x01

                                                                                CALL                        TRANSMIT_BYTE

; send TX_DATA_HEADER

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVF                      TX_DATA_HEADER,W

                                                                                CALL                        TRANSMIT_BYTE

; send TX_DATA_BYTE1

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVF                      TX_DATA_BYTE1,W

                                                                                CALL                        TRANSMIT_BYTE

; send TX_DATA_BYTE2

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVF                      TX_DATA_BYTE2,W

                                                                                CALL                        TRANSMIT_BYTE

; send CHECKSUM

                                                                                CALL                        WAIT_FOR_TSR_EMPTY

                                                                                BANKSEL                 PORTA

                                                                                MOVF                      CHECKSUM,W

                                                                                CALL                        TRANSMIT_BYTE

                                                                                RETURN

 

CALCULATE_CHECKSUM:

                                                                                BANKSEL                 PORTA

                                                                                MOVLW                  FRAME_ID                                                               ; Frame ID (Byte5)

                                                                                ADDLW                    API_TX

                                                                                ADDWF                   DEST_ADDRESS_MSB, W                       ; add destination address MSB (Byte 6)

                                                                                NOP

                                                                                ADDWF                   DEST_ADDRESS_LSB, W                         ; add destination address LSM (Byte 7)

                                                                                NOP

                                                                                ADDLW                    OPTIONS                                                                 ; add options ACK enabled (Byte 8)

                                                                                NOP

                                                                                ADDWF                   TX_DATA_HEADER,W                             ; add TX Data Byte 0 of 3 (Byte 11)

                                                                                NOP

                                                                                ADDWF                   TX_DATA_BYTE1, W                               ; add TX Data Byte 1 of 3 (Byte 10)

                                                                                NOP

                                                                                ADDWF                   TX_DATA_BYTE2, W                               ; add TX Data Byte 2 of 3 (Byte 9)

                                                                                NOP

                                                                                SUBLW                    0xFF                                                                        ; subtract the last 8 bits of the resulting sum from 0xFF

                                                                                MOVWF                  CHECKSUM

                                                                                RETURN

WAIT_FOR_TSR_EMPTY:

                                                                                BANKSEL                 TXSTA

                                                                                BTFSS                      TXSTA, TRMT

                                                                                GOTO                      WAIT_FOR_TSR_EMPTY

                                                                                RETURN

TRANSMIT_BYTE:

                                                                                BANKSEL                 TXREG

                                                                                MOVWF                  TXREG

                                                                                RETURN 

 

CLEAR_OVERRUN_ERROR:

 

                                                                                BANKSEL                 RCSTA

                                                                                BCF                                          RCSTA, CREN                                                          ; disable receive

                                                                                NOP

                                                                                BSF                                          RCSTA, CREN                                                          ; re-enable receive to clear the overrun error

                                                                                RETURN

 

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

;               JUMP TABLE FOR RECEIVING

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

 

; discard start byte

Case0:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                MOVF                      DATA_RECEIVED, W                               ; move DATA_RECEIVED to W

                                                                                SUBLW                    START_BYTE                                                           ; subtract W from START_BYTE

                                                                                BTFSS                      STATUS, Z                                                               ; test bit Z of STATUS register

                                                                                GOTO                      Error_Detected                                       ; if Z = 0, received data is not START_BYTE, deal with error

                                                                                INCF                        RECEIVE_BYTE_COUNT, F      ; if Z = 1, received data is START_BYTE, increment the RECEIVE_BYTE_COUNT and look for the LENGTH_MSB

                                                                                RETURN 

; discard length MSB byte

Case1:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                MOVF                      DATA_RECEIVED, W                               ; move DATA_RECEIVED to W

                                                                                SUBLW                    LENGTH_MSB                                                         ; subtract W from LENGTH_MSB

                                                                                BTFSS                      STATUS, Z                                                               ; test bit Z of STATUS register

                                                                                GOTO                      Error_Detected                                       ; if Z = 0, received data is not START_BYTE, deal with error

                                                                                INCF                        RECEIVE_BYTE_COUNT, F      ; if Z = 1, received data is LENGTH_MSB, increment the RECEIVE_BYTE_COUNT and look for the LENGTH_MSB

                                                                                RETURN 

; discard length LSB byte

Case2:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                MOVF                      DATA_RECEIVED, W                               ; move DATA_RECEIVED to W

                                                                                SUBLW                    LENGTH_LSB                                                          ; subtract W from LENGTH_LSB

                                                                                BTFSS                      STATUS, Z                                                               ; test bit Z of STATUS register

                                                                                GOTO                      Error_Detected                                       ; if Z = 0, received data is not START_BYTE, deal with error

                                                                                INCF                        RECEIVE_BYTE_COUNT, F      ; if Z = 1, received data is LENGTH_LSB, increment the RECEIVE_BYTE_COUNT and look for the LENGTH_MSB

                                                                                RETURN 

; discard API ID byte

Case3:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                MOVF                      DATA_RECEIVED, W                               ; move DATA_RECEIVED to W

                                                                                SUBLW                    API_RX                                                                    ; subtract W from API_RX

                                                                                BTFSS                      STATUS, Z                                                               ; test bit Z of STATUS register

                                                                                GOTO                      Error_Detected                                       ; if Z = 0, received data is not START_BYTE, deal with error

                                                                                INCF                        RECEIVE_BYTE_COUNT, F      ; if Z = 1, received data is API_ID, increment the RECEIVE_BYTE_COUNT and look for the LENGTH_MSB

                                                                                RETURN

; save source address MSB byte

Case4:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                INCF                        RECEIVE_BYTE_COUNT, F

                                                                                MOVF                      DATA_RECEIVED, W

                                                                                MOVWF                  SOURCE_ADDRESS_MSB

                                                                                RETURN

; save source address LSB byte

Case5:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                INCF                        RECEIVE_BYTE_COUNT, F

                                                                                MOVF                      DATA_RECEIVED, W

                                                                                MOVWF                  SOURCE_ADDRESS_LSB

                                                                                RETURN

; discard RSSI byte

Case6:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                INCF                        RECEIVE_BYTE_COUNT, F

                                                                                RETURN

; discard Options byte

Case7:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                INCF                        RECEIVE_BYTE_COUNT, F

                                                                                RETURN

; save RF data header byte

Case8:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                INCF                        RECEIVE_BYTE_COUNT, F

                                                                                MOVF                      DATA_RECEIVED, W

                                                                                MOVWF                  RX_DATA_HEADER

                                                                                RETURN

Case9:    

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA                               

                                                                                INCF                        RECEIVE_BYTE_COUNT, F     

                                                                                MOVF                      DATA_RECEIVED, W

                                                                                MOVWF                  RX_DATA_BYTE1

                                                                                RETURN

Case10:                  

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA               

                                                                                INCF                        RECEIVE_BYTE_COUNT, F

                                                                                MOVF                      DATA_RECEIVED, W

                                                                                MOVWF                  RX_DATA_BYTE2

                                                                                RETURN

; discard checksum byte

Case11:                                  

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA               

                                                                                CLRF                        RECEIVE_BYTE_COUNT

                                                                                RETURN                                                 

Error_Detected:

                                                                                BANKSEL                 PORTA                                                                     ; select the bank containing PORTA

                                                                                CLRF                        RECEIVE_BYTE_COUNT

                                                                                RETURN

 

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

;               CHECK FOR IBUTTON SUBROUNTINES

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

 

IBUTTON_PIN_TO_OUTPUT:

                                                                                BANKSEL                 TRISB                                                                      ; select bank containing TRISB

                                                                                MOVLW                  IBUTTON_TRIS_OUTPUT                       ; write iButton tris output bits to W

                                                                                ANDWF                   TRISB, f                                                   ; set the iButton pin to output

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

IBUTTON_PIN_TO_INPUT:

                                                                                BANKSEL                 TRISB                                                                      ; select bank containing TRISB

                                                                                MOVLW                  IBUTTON_TRIS_INPUT                           ; write iButton tris input bits to W

                                                                                IORWF                    TRISB, f                                                   ; set the iButton pin to input

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

SEND_READ_ROM_BIT_HIGH:

                                                                                CALL                        IBUTTON_PIN_TO_OUTPUT  ; set iButton pin to output

                                                                                BANKSEL                 PORTB

                                                                                BCF                                          PORTB, IBUTTON_BIT                            ; set iButton pin low

                                                                                CALL                        WAIT_5US                                                              ; wait 5us

                                                                                CALL                        IBUTTON_PIN_TO_INPUT      ; set iButton pin to input

                                                                                CALL                        WAIT_70US                                                            ; wait 70us

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

SEND_READ_ROM_BIT_LOW:

                                                                                CALL                        IBUTTON_PIN_TO_OUTPUT  ; set iButton pin to output

                                                                                BANKSEL                 PORTB

                                                                                BCF                                          PORTB, IBUTTON_BIT                            ; set iButton pin low

                                                                                CALL                        WAIT_60US                                                            ; wait 60us

                                                                                CALL                        IBUTTON_PIN_TO_INPUT      ; set iButton pin to input

                                                                                CALL                        WAIT_15US                                                            ; wait 15us

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

READ_IBUTTON:

                                                                                CALL                        IBUTTON_PIN_TO_OUTPUT  ; set iButton pin to output

                                                                                BANKSEL                 PORTB

                                                                                BCF                                          PORTB, IBUTTON_BIT                            ; set iButton pin low

                                                                                CALL                        WAIT_5US                                                              ; wait 5us

                                                                                CALL                        IBUTTON_PIN_TO_INPUT      ; set iBUTTON pin to input

                                                                                CALL                        WAIT_10US                                                            ; wait 10us

                                                                                BANKSEL                 PORTB

                                                                                BTFSC                      PORTB, IBUTTON_BIT                            ; if bit1 is set, check if the iButton pin is high

                                                                                GOTO                      IBUTTON_HIGH                                      ; if the incoming bit is high deal with it

                                                                                GOTO                      IBUTTON_LOW                                                       ; if the incoming bit is low deal with it

IBUTTON_HIGH:

                                                                                BANKSEL                 PORTB

                                                                                CLRW                                                                                                                      ; clear W

                                                                                MOVF                      READ_BIT_COUNTER,W                         ; move the read bit counter to W

                                                                                BTFSC                      READ_BYTE_COUNTER,0                       ; check if we are reading byte 0

                                                                                GOTO                      WRITE_TO_IBUTTON_BYTE0 ; write the high to iButton byte 0

                                                                                BTFSC                      READ_BYTE_COUNTER,1                       ; check if we are reading byte 1

                                                                                GOTO                      WRITE_TO_IBUTTON_BYTE1 ; write the high to iButton byte 1

                                                                                BTFSC                      READ_BYTE_COUNTER,2                       ; check if we are reading byte 2

                                                                                GOTO                      WRITE_TO_IBUTTON_BYTE2 ; write the high to iButton byte 2

IBUTTON_LOW:

                                                                                BANKSEL                 PORTB

                                                                                CALL                        WAIT_60US                                                            ; wait 60us

                                                                                RETURN                                                                                                                  ; return to line after the subroutine was called

WRITE_TO_IBUTTON_BYTE0:

                                                                                IORWF                    IBUTTON_BYTE0, f                 ; or W with iButton byte 0 to record the high

                                                                                CALL                        WAIT_60US                                                            ; wait 60us

                                                                                RETURN                                                                                                                  ; return to line after the subroutine was called

WRITE_TO_IBUTTON_BYTE1:

                                                                                IORWF                    IBUTTON_BYTE1, f                 ; or W with iButton byte 1 to record the high

                                                                                CALL                        WAIT_60US                                                            ; wait 60us

                                                                                RETURN                                                                                                                  ; return to line after the subroutine was called

WRITE_TO_IBUTTON_BYTE2:

                                                                                IORWF                    IBUTTON_BYTE2, f                 ; or W with iButton byte 2 to record the high

                                                                                CALL                        WAIT_60US                                                            ; wait 60us

                                                                                RETURN                                                                                                                  ; return to line after the subroutine was called

 

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

;               WAIT COMMANDS FOR IBUTTON ROUTINE

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

 

WAIT_5US:

                                                                                NOP                                                                                                                                         ; wait for 5us

                                                                                NOP

                                                                                NOP

                                                                                NOP

                                                                                NOP

                                                                                NOP

                                                                                NOP

                                                                                NOP

                                                                                NOP

                                                                                NOP

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

WAIT_10US:

                                                                                BANKSEL                 TMR2                                                                      ; select the bank containing TMR2

                                                                                CLRF                        TMR2                                                                      ; clear the timer TMR2

                                                                                BANKSEL                 PR2                                                                                          ; select the bank containing PR2

                                                                                MOVLW                  b'00011101'                                                            ; d'29'

                                                                MOVWF       PR2                     ; move 00110001 from W to PR2 (Timer 2 Flag set every 1/5MHz * (49+1)ticks = 10us)

                                                                                BANKSEL                 PIR1                         ; select bank containing PIR1

                                                                                BTFSS       PIR1, TMR2IF            ; check if Timer 2 flag is set

                                                GOTO        $-1                                                         ; if clear, check again if Timer 2 flag is set

                                                                                BCF                                          PIR1, TMR2IF                                          ; clear the Timer 2 flag

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

WAIT_15US:

                                                                                BANKSEL                 TMR2                                                                      ; select the bank containing TMR2

                                                                                CLRF                        TMR2                                                                      ; clear the timer TMR2

                                                                                BANKSEL                 PR2                                                                                          ; select the bank containing PR2

                                                                                MOVLW                  b'00110110'                                                            ; d'54'

                                                MOVWF       PR2                     ; move 01001010 from W to PR2 (Timer 2 Flag set every 1/5MHz * (74+1)ticks = 15us)

                                                                                BANKSEL                 PIR1                         ; select bank containing PIR1

                                                                                BTFSS       PIR1, TMR2IF            ; check if Timer 2 flag is set

                                GOTO        $-1                                                         ; if clear, check again if Timer 2 flag is set

                                                                                BCF                                          PIR1, TMR2IF                                          ; clear the Timer 2 flag

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

WAIT_50US:

                                                                                BANKSEL                 TMR2                                                                      ; select the bank containing TMR2

                                                                                CLRF                        TMR2                                                                      ; clear the timer TMR2

                                                                                BANKSEL                 PR2                                                                                          ; select the bank containing PR2

                                                                                MOVLW                  b'11100101'                                                            ; d'229'

                                                MOVWF       PR2                     ; move 11111001 from W to PR2 (Timer 2 Flag set every 1/5MHz * (249+1)ticks = 50us)

                                                                                BANKSEL                 PIR1                         ; select bank containing PIR1

                                                                                BTFSS       PIR1, TMR2IF            ; check if Timer 2 flag is set

                                GOTO        $-1                                                         ; if clear, check again if Timer 2 flag is set

                                                                                BCF                                          PIR1, TMR2IF                                          ; clear the Timer 2 flag

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

WAIT_60US:

                                                                                BANKSEL                 TMR2                                                                      ; select the bank containing TMR2

                                                                                CLRF                        TMR2                                                                      ; clear the timer TMR2

                                                                                MOVLW                  b'00001000'                                                            ; move 00001000 to W

                                                                                IORWF                    T2CON, F                                                 ; or W with T2CON to set TOUTPS1-3 to 0001 and postscale timer 2 by 1:2, timer effectively at 2.5MHz                                                                         

                                                                                BANKSEL                 PR2                                                                                          ; select the bank containing PR2

                                                MOVLW                  b'10001011'                                                            ; d'139

                                                                                MOVWF       PR2                     ; move 10010110 from W to PR2 (Timer 2 Flag set every 1/2.5MHz * (149+1)ticks = 60us)

                                                                                BANKSEL                 PIR1                         ; select bank containing PIR1

                                                                                BTFSS       PIR1, TMR2IF            ; check if Timer 2 flag is set

                                GOTO        $-1                                                         ; if clear, check again if Timer 2 flag is set

                                                                                BCF                                          PIR1, TMR2IF                                          ; clear the Timer 2 flag

                                                                                MOVLW                  b'00000111'                                                            ; move 00000111 to W

                                                                                ANDWF                   T2CON, F                                                 ; and W with TSCON to set TOUTPS1-3 to 0000 and postscale timer 2 by 1:1

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

WAIT_70US:

                                                                                BANKSEL                 TMR2                                                                      ; select the bank containing TMR2

                                                                                CLRF                        TMR2                                                                      ; clear the timer TMR2

                                                                                MOVLW                  b'00001000'                                                            ; move 00001000 to W

                                                                                IORWF                    T2CON, F                                                 ; or W with T2CON to set TOUTPS1-3 to 1001 and postscale timer 2 by 1:2, timer effectively at 2.5MHz

                                                                                BANKSEL                 PR2                                                                                          ; select the bank containing PR2

                                                                                MOVLW                  b'10100100'                                                            ; d'164'

                                                MOVWF       PR2                     ; move 10101110 from W to PR2 (Timer 2 Flag set every 1/2.5MHz * (174+1)ticks = 70us)

                                                                                BANKSEL                 PIR1                         ; select bank containing PIR1

                                                                                BTFSS       PIR1, TMR2IF            ; check if Timer 2 flag is set

                                GOTO        $-1                                                         ; if clear, check again if Timer 2 flag is set

                                                                                BCF                                          PIR1, TMR2IF                                          ; clear the Timer 2 flag

                                                                                MOVLW                  b'00000111'                                                            ; move 00000111 to W

                                                                                ANDWF                   T2CON, F                                                 ; and W with TSCON to set TOUTPS1-3 to 0000 and postscale timer 2 by 1:1

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

WAIT_500US:

                                                                                BANKSEL                 TMR2                                                                      ; select the bank containing TMR2

                                                                                CLRF                        TMR2                                                                      ; clear the timer TMR2

                                                                                MOVLW                  b'01001000'                                                            ; move 01001000 to W

                                                                                IORWF                    T2CON, F                                                 ; or W with T2CON to set TOUTPS1-3 to 1001 and postscale timer 2 by 1:10, timer effectively at 500kHz

                                                                                BANKSEL                 PR2                                                                                          ; select the bank containing PR2

                                                                                MOVLW                  b'11110111'                                                            ; d'247'

                                                MOVWF       PR2                     ; move 11111001 from W to PR2 (Timer 2 Flag set every 1/500kHz * (249+1)ticks = 500us)

                                                                                BANKSEL                 PIR1                         ; select bank containing PIR1

                                                                                BTFSS       PIR1, TMR2IF            ; check if Timer 2 flag is set

                                GOTO        $-1                                                         ; if clear, check again if Timer 2 flag is set

                                                                                BCF                                          PIR1, TMR2IF                                          ; clear the Timer 2 flag

                                                                                MOVLW                  b'00000111'                                                            ; move 00000111 to W

                                                                                ANDWF                   T2CON, F                                                 ; and W with TSCON to set TOUTPS1-3 to 0000 and postscale timer 2 by 1:1

                                                                                RETURN                                                                                                                  ; return to line after subroutine was called

 

 

 

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

;               END THE PROGRAM!!!!

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

 

                                                                                END

Main Page

Back to the top