list P=PIC16F690
#include "p16F690.inc"
__config (_CP_OFF & _WDT_OFF & _PWRTE_ON
& _HS_OSC)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; #defines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#define NUMBER_OF_BYTES 0x0B
#define DEBUG_DATA1 0x00
#define DEBUG_DATA2 0x00
#define DEBUG_DATA3 0x00
; 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
; 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
#define STAND_DOWN_RECEIVED_BIT 1
; 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
; navigation command bytes
#define COMMAND_1 0x8A ; Mag Sens 1 Straight, Slow Forward
#define COMMAND_2 0x8F ; Mag Sens 2 Straight, Full Forward
#define COMMAND_3 0x86 ; Mag Sens 3 Straight, Slow Backward
#define COMMAND_4 0x80 ; Mag Sens 4 Straight, Full Backward
#define COMMAND_5 0xFA ; Mag Sens 5 Right, Slow Speed
#define COMMAND_6 0xFF ; Mag Sens 6 Right, Full Speed
#define COMMAND_7 0x0A ; Mag Sens 7 Left, Slow Speed
#define COMMAND_8 0x0F ; Mag Sens 8 Left, Full Speed
#define COMMAND_9 0x88 ; Mag Sens 9 Straight Stop
#define COUNT_200MS 0x0F ; counter for reading sensors and sending
navigation data
; special commands bits
#define SPECIAL_1 4 ; Special One bit
for Cup Presence
#define SPECIAL_2 5 ; Special Two bit for Voice sensor
; water command bytes
#define WATER_ON 0x0F ; Water is set on
#define WATER_OFF 0x00 ; Water is set off
; stand down constants
#define NUM_STAND_DOWN_MSG 40 ;
Number of Stand down NO_ACTION messages that need to be sent for 10 sec.
;LED
#define PAIRED_BOAT_1 0x01
#define PAIRED_BOAT_2 0x02
#define PAIRED_BOAT_3 0x03
#define PAIRED_BOAT_4 0x04
#define PAIRED_BOAT_5 0x05
#define PAIRED_BOAT_6 0x06
#define PAIRED_BOAT_7 0x07
#define PAIRED_BOAT_8 0x08
#define PAIRED_BOAT_9 0x09
#define PAIRED_BOAT_10 0x10
#define PAIRED_BOAT_11 0x11
#define PAIRED_BOAT_12 0x12
#define BOAT_1 0x02
#define BOAT_2 0x04
#define BOAT_3 0x08
#define BOAT_4 0x10
#define BOAT_5 0x40
#define BOAT_6 0x80
#define BOAT_7 0x02
#define BOAT_8 0x04
#define BOAT_9 0x08
#define BOAT_10 0x10
#define BOAT_11 0x40
#define BOAT_12 0x80
#define RED_TEAM 0x02
#define BLUE_TEAM 0x04
#define RED_ACTIVE_ZONE 0x08
#define BLUE_ACTIVE_ZONE 0x10
#define IBUTTON_READ 0x02
#define BOAT_MATCHED 0x04
#define PLAYING_GAME 0x08
#define STAND_DOWN_LED 0x10
#define BOAT_NUMBER_1 0x0F
#define BOAT_NUMBER_2 0x02
#define TEAM 0x04
#define ACTIVE_ZONE 0x08
#define PLAY_STATUS 0xFF
#define TEAM_OFF 0x40 ; TEAM command type
#define ACTIVE_ZONE_OFF 0x80 ; ACTIVE_ZONE command
type
#define STATUS_OFF 0x40 ; PLAY_STATUS command
type
#define BOAT_OFF 0x80 ; PLAY_STATUS command
type
#define LED_MUX_LINE 0 ; RA0 on the helm xbee
PIC to control the MUX to the Radio and the LED PIC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; location and variable definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TRISA_BITS equ b'00000000' ;
all PORTA outputs
TRISB_BITS equ b'00100000' ;
all PORTB outputs except bit 5
TRISC_BITS equ b'11111000' ;
all PORTC bits are inputs
PIC_BAUDRATE equ d'129' ;
calculated baudrate = 9615 so X = 129 for 20MHz clock
RX_DATA_HEADER equ 0x22 ;
RX data header byte
RX_DATA_BYTE1 equ 0x23 ;
RX data byte 1
RX_DATA_BYTE2 equ 0x24 ;
RX data byte 2
TX_DATA_HEADER equ 0x25 ;
TX data header byte
TX_DATA_BYTE1 equ 0x26 ;
TX data byte 1
TX_DATA_BYTE2 equ 0x27 ;
TX data byte 2
;SEND_BYTE_COUNT equ 0x28 ;
counter from 0 to 11
RECEIVE_BYTE_COUNT equ 0x29
CHECKSUM equ 0x30 ;
checksum
DEST_ADDRESS_MSB equ 0x31
DEST_ADDRESS_LSB equ 0x32
DATA_RECEIVED equ 0x33
W_TEMP equ 0x34
STATUS_TEMP equ 0x35
SOURCE_ADDRESS_MSB equ 0x36
SOURCE_ADDRESS_LSB equ 0x37
PING_RESPONSE_BYTE1 equ 0x38
PING_RESPONSE_BYTE2 equ 0x39
PAIRED_ADDRESS_MSB equ 0x40
PAIRED_ADDRESS_LSB equ 0x41
; iButton Bit Definitions
IBUTTON_BYTE0 equ 0x42 ;
location for 1st byte of iButton serial number (contains bits 0-8), family byte
IBUTTON_BYTE1 equ 0x43 ;
location for 2nd byte of iButton serial number (contains bits 9-16), 1st keeper
byte
IBUTTON_BYTE2 equ 0x44 ; location for 3rd byte of iButton
serial number (contains bits 17-24), 2nd keeper byte
DELAY_COUNTER equ 0x45 ;
location for delay counter
READ_BYTE_COUNTER equ 0x46 ;
location for read byte counter
READ_BIT_COUNTER equ 0x47 ;
location for read bit counter
PING_COUNTER equ 0x48 ;
counter for states (waiting for iButton, waiting to be matched, executing
commands and playing game
RX_COMMAND_COUNTER equ 0x49 ;
counter for command (start game, end game)
TIMER2_COUNTER equ 0x50
SPECIAL_BYTE equ 0x51
NAVIGATION_BYTE equ 0x52
; LED bit definitions
LED_COMMAND_TYPE equ 0x53
LED_TYPE equ 0x54
; Stand Down Counter
STAND_DOWN_COUNTER equ 0x55
; 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
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
MOVWF TRISB
MOVLW TRISC_BITS ;
write TRISC_BITS to W
MOVWF TRISC ;
write TRISC_BITS from W to TRISA
intialize_general:
BANKSEL 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 DATA_RECEIVED
CLRF RX_COMMAND_COUNTER
CLRF TIMER2_COUNTER
CLRF NAVIGATION_BYTE
CLRF SPECIAL_BYTE
CLRF STAND_DOWN_COUNTER
; MOVLW 0xFF
; MOVWF NAVIGATION_BYTE
; MOVWF SPECIAL_BYTE
initialize_interrupts:
BANKSEL INTCON ;
select bank containing INTCON
BSF INTCON,
GIE ;
enable global interrupts
BSF INTCON,
PEIE ;
enable interrupts
BANKSEL PIE1 ;
select bank containing PIE1
BSF PIE1,
RCIE ;
enable EUSART receive interrupt
initialize_comm:
BANKSEL RCSTA
BSF RCSTA,
SPEN ;
enable serial port
BSF RCSTA,
CREN ;
enable receive
BANKSEL 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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TEST CODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LOOP:
; prepare to
ping back "waiting for ibutton"
CLRF PING_COUNTER
BSF PING_COUNTER,
PING_WAIT_IBUTTON_BIT
MOVLW PING_WAIT_IBUTTON_BYTE1
MOVWF PING_RESPONSE_BYTE1
MOVLW PING_WAIT_IBUTTON_BYTE2
MOVWF PING_RESPONSE_BYTE2
CALL WAIT_FOR_IBUTTON ; wait for ibutton
; prepare to
ping back "waiting to be paired"
CLRF PING_COUNTER
BSF PING_COUNTER,
PING_WAIT_MATCH_BIT
MOVLW PING_WAIT_MATCH_BYTE1
MOVWF PING_RESPONSE_BYTE1
MOVLW PING_WAIT_MATCH_BYTE2
MOVWF PING_RESPONSE_BYTE2
CALL WAIT_FOR_BOAT_HELM_MATCH ; wait for helm boat match
; prepare to
ping back "paired with Boat_"
CALL DISPLAY_BOAT_NUMBER ; display Boat# LED
CLRF PING_COUNTER
BSF PING_COUNTER,
PING_PAIRED_BIT
MOVLW PING_PAIRED_BYTE1
MOVWF PING_RESPONSE_BYTE1
MOVF PAIRED_ADDRESS_LSB, W
MOVWF PING_RESPONSE_BYTE2
BANKSEL PIR1
BCF RX_COMMAND_COUNTER,
START_GAME_BIT ; clear
start_game_bit on RX_COMMAND_COUNTER
BCF RX_COMMAND_COUNTER,
STAND_DOWN_BIT ; clear END_GAME
bit on RX_COMMAND_COUNTER
; once boat
and helm are matched, go into EXECUTE_COMMANDS where it waits for Start Game
command from the admiral
; to start
the playing game
GOTO EXECUTE_COMMANDS
GOTO LOOP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHECK FOR IBUTTON SUBROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WAIT_FOR_IBUTTON:
CHECK_FOR_IBUTTON:
BTFSC RX_COMMAND_COUNTER,
ADMIRAL_PING_BIT
CALL TRANSMIT_PONG
BTFSC RX_COMMAND_COUNTER,
HARD_RESET_BIT ;
check HARD_RESET_BIT of RX_COMMAND_COUNTER byte
GOTO HARD_RESETTING ; if the stand down bit is set,
go to HARD_RESETTING
CALL IBUTTON_PIN_TO_OUTPUT ; set iButton pin to output
BANKSEL 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
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
CALL IBUTTON_PIN_TO_OUTPUT ; set iButton pin to output
BANKSEL PORTB
BCF PORTB,
IBUTTON_BIT ;
set the line low
CALL WAIT_500US ;
wait 500us
BANKSEL 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 PIR1
CLRF IBUTTON_BYTE0
CLRF IBUTTON_BYTE1
CLRF IBUTTON_BYTE2
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
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
MOVF IBUTTON_BYTE0, W ; move iButton
byte 0 to itself
SUBLW IBUTTON_FAMILY1 ;
subtract IBUTTON_FAMILY1 (0x01) from IBUTTON_BYTE0
BTFSC STATUS,Z ;
test bit Z of STATUS register
GOTO DISPLAY_IBUTTON_BYTE ; if IBUTTON_BYTE0 = IBUTTON_FAMILY1 (0x01),
prepare to send the iButton bytes
MOVF IBUTTON_BYTE0, W ; move iButton
byte 0 to itself
SUBLW IBUTTON_FAMILY2 ;
subtract IBUTTON_FAMILY2 (0x09) from IBUTTON_BYTE0
BTFSC STATUS, Z ;
test bit Z of STATUS register
GOTO DISPLAY_IBUTTON_BYTE ; if IBUTTON_BYTE0 = IBUTTON_FAMILY2 (0x09),
prepare to send the iButton bytes
GOTO CHECK_FOR_IBUTTON ; if IBUTTON_BYTE0 is not
IBUTTON_FAMILY1 or IBUTTON_FAMILY2, an error occured, check for the ibutton
again
DISPLAY_IBUTTON_BYTE:
CALL LED_IBUTTON_READ
BANKSEL PORTA
BTFSS IBUTTON_BYTE1, 0 ; check bit 0 of
IBUTTON_BYTE1
CALL LED_BLUE_TEAM ; if it is
clear, light blue Team LED, set red TEAM LED
BANKSEL PORTA
BTFSC IBUTTON_BYTE1, 0 ; if it is set,
light red Team LED
CALL LED_RED_TEAM ; set red
TEAM LED
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IBUTTON SUBROUTINES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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 FUNCTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WAITING FOR BOAT/HELM MATCH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WAIT_FOR_BOAT_HELM_MATCH:
INITIALIZE_DELAY:
BANKSEL TMR2 ;
select the bank containing TMR2
CLRF TMR2 ;
clear the timer TMR2
MOVLW b'01111111' ;
move 01111111 to W
IORWF T2CON, F ;
or W with T2CON to set TOUTPS1-3 to 1111 and postscale timer 2 by 1:16
BANKSEL PR2 ;
select the bank containing PR2
MOVLW b'11111111' ;
d'256'
MOVWF PR2 ; move 11111111 from W to
PR2 (Timer 2 Flag set every 0.0131072 sec = 13.1 ms)
BANKSEL PIE1 ;
select bank containing PIE1
BSF PIE1,
TMR2IE
BANKSEL PIR1
CLRF TIMER2_COUNTER
BROADCAST_IBUTTON:
BANKSEL PORTA
BCF PORTA, 2
BTFSC RX_COMMAND_COUNTER,
ADMIRAL_PING_BIT
CALL TRANSMIT_PONG
BTFSC RX_COMMAND_COUNTER,
HARD_RESET_BIT ;
check HARD_RESET_BIT of RX_COMMAND_COUNTER byte
GOTO HARD_RESETTING ; if the stand down bit is set,
go to HARD_RESETTING
BANKSEL PIR1
MOVF TIMER2_COUNTER, W
SUBLW COUNT_200MS
BTFSS STATUS, Z ;
test bit Z of STATUS register
GOTO BROADCAST_IBUTTON ;
if Z = 0, TIMER2_COUNTER is not COUNT_200MS, go back to BROADCAST_IBUTTON
MOVLW BROADCAST_MSB
MOVWF DEST_ADDRESS_MSB
MOVLW BROADCAST_LSB
MOVWF DEST_ADDRESS_LSB
; MOVLW CRAFT_MSB
; MOVWF DEST_ADDRESS_MSB
; MOVLW CRAFT_LSB
; MOVWF DEST_ADDRESS_LSB
MOVLW IBUTTON_HEADER
MOVWF TX_DATA_HEADER
MOVF IBUTTON_BYTE2, W
MOVWF TX_DATA_BYTE1
MOVF IBUTTON_BYTE1, W
MOVWF TX_DATA_BYTE2
CALL TRANSMIT
CLRF TIMER2_COUNTER
CHECK_FOR_MATCHED_MSG:
BANKSEL PIR1
BTFSS RX_DATA_HEADER,
WATERCRAFT_HEADER_BIT ; check if
RX_DATA_HEADER is a WATERCRAFT_HEADER
GOTO BROADCAST_IBUTTON ; if Z = 0, the
RX_DATA_HEADER is not a WATERCRAFT_HEADER, go back to broadcasting the iButton
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 MATCHED_1 ;
subtract RX_DATA_BYTE1 from MATCHED_1
BTFSS STATUS, Z ;
check the Z bit of the status register
GOTO BROADCAST_IBUTTON ; if Z = 0, the
RX_DATA_BYTE1 is not MATCHED_1, go back to broadcasting the iButton
MOVF RX_DATA_BYTE2, W ; if Z = 1, the
RX_DATA_BYTE1 is MATCHED_1, check for MATCHED_2, move RX_DATA_BYTE2 to W
SUBLW MATCHED_2 ;
subtract RX_DATA_BYTE2 from MATCHED_2
BTFSS STATUS, Z ;
check the Z bit of the status register
GOTO BROADCAST_IBUTTON ; if Z = 0, the
RX_DATA_BYTE2 is not MATCHED_2, go back to broadcasting the iButton
GOTO SAVE_PAIRED_ADDRESS ; if Z = 1, the RX_DATA_BYTE2
is MATCHED_2, the boat with matching iButton has responded, save the boat's
address
SAVE_PAIRED_ADDRESS:
BANKSEL PIR1
BANKSEL PORTA
BSF PORTA,
2
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
CALL TRANSMIT_NO_ACTION ; transmit no action
BANKSEL PORTA
CALL LED_BOAT_MATCHED ; turn Boat Matched LED
on
RETURN
DISPLAY_BOAT_NUMBER:
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_1 ; subtract W
from PAIRED_BOAT_1
BTFSC STATUS, Z ;
test bit Z of STATUS register
CALL LED_BOAT1 ; if Z
= 1, received data is PAIRED_BOAT_1 so set BOAT 1 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_2 ; subtract W from
PAIRED_BOAT_2
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT2 ; if Z = 1, received data is
PAIRED_BOAT_2 so set BOAT 2 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_3 ; subtract W from PAIRED_BOAT_3
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT3 ; if Z = 1, received data is
PAIRED_BOAT_3 so set BOAT 3 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_4 ; subtract W from PAIRED_BOAT_4
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT4 ; if Z = 1, received data is
PAIRED_BOAT_4 so set BOAT 4 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_5 ; subtract W from
PAIRED_BOAT_5
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT5 ; if Z = 1, received data is
PAIRED_BOAT_5 so set BOAT 5 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_6 ; subtract W from
PAIRED_BOAT_6
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT6 ; if Z = 1, received data is
PAIRED_BOAT_6 so set BOAT 6 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_7 ; subtract W from
PAIRED_BOAT_7
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT7 ; if Z = 1, received data is
PAIRED_BOAT_7 so set BOAT 7 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_8 ; subtract W from
PAIRED_BOAT_8
BTFSC STATUS, Z ;
test bit Z of STATUS register
CALL LED_BOAT8 ; if Z = 1, received data is
PAIRED_BOAT_8 so set BOAT 8 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_9 ; subtract W from
PAIRED_BOAT_9
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT9 ; if Z = 1, received data is
PAIRED_BOAT_9 so set BOAT 9 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_10 ; subtract W from
PAIRED_BOAT_10
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT10 ; if Z = 1, received data is
PAIRED_BOAT_10 so set BOAT 10 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_11 ; subtract W from
PAIRED_BOAT_11
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT11 ; if Z = 1, received data is
PAIRED_BOAT_11 so set BOAT 11 LED
BANKSEL PORTA
MOVF PAIRED_ADDRESS_LSB, W
SUBLW PAIRED_BOAT_12 ; subtract W from
PAIRED_BOAT_12
BTFSC STATUS, Z ; test bit Z of
STATUS register
CALL LED_BOAT12 ; if Z = 1, received data is
PAIRED_BOAT_12 so set BOAT 12 LED
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TRANSMIT SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; transmit
data packet to LED PIC
TRANSMIT_LED_PIC:
; sent
START_BYTE
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVLW START_BYTE ;
CALL LED_TRANSMIT_BYTE ; send the byte to LED PIC
; send LED
Command Type
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVF LED_COMMAND_TYPE,W
CALL LED_TRANSMIT_BYTE ; send the byte to LED PIC
; send LED
type
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVF LED_TYPE,W
CALL LED_TRANSMIT_BYTE ; send the byte to LED PIC
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
BSF PORTA, LED_MUX_LINE ; set the mux line to communicate with
Radio
RETURN
; transmits
data packet to Xbee Radio
TRANSMIT:
CALL CALCULATE_CHECKSUM
; start
sending the data packet
; send
START_BYTE
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVLW START_BYTE
CALL TRANSMIT_BYTE ; send the byte to xbee radio
; send
LENGTH_MSB
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVLW LENGTH_MSB ;
0x00
CALL TRANSMIT_BYTE ; send the byte
; send
LENGTH_LSB
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVLW LENGTH_LSB ;
0x08
CALL TRANSMIT_BYTE ; send the byte
; send API_TX
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVLW API_TX ;
0x01
CALL TRANSMIT_BYTE ; send the byte
; send
FRAME_ID
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVLW FRAME_ID ;
0x00
CALL TRANSMIT_BYTE ; send the byte
; send
ADDRESS_MSB
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVF DEST_ADDRESS_MSB,W
CALL TRANSMIT_BYTE ; send the byte
; send
ADDRESS_LSB
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVF DEST_ADDRESS_LSB,W
CALL TRANSMIT_BYTE ; send the byte
; send
OPTIONS
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVLW OPTIONS ;
0x01
CALL TRANSMIT_BYTE ; send the byte
; send
TX_DATA_HEADER
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVF TX_DATA_HEADER,W
CALL TRANSMIT_BYTE ;
send the byte
; send
TX_DATA_BYTE1
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVF TX_DATA_BYTE1,W
CALL TRANSMIT_BYTE ; send the byte
; send
TX_DATA_BYTE2
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVF TX_DATA_BYTE2,W
CALL TRANSMIT_BYTE ; send the byte
; send
CHECKSUM
CALL WAIT_FOR_TSR_EMPTY ; wait for TSR to empty
BANKSEL PORTA
MOVF CHECKSUM,W
CALL TRANSMIT_BYTE ; send the 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 ; save
the result as CHECKSUM
RETURN
WAIT_FOR_TSR_EMPTY:
BANKSEL TXSTA
BTFSS TXSTA, TRMT ; check of TSR is
empty
GOTO WAIT_FOR_TSR_EMPTY ; if full, go back to waiting for it to
empty
RETURN ;
otherwise, return
TRANSMIT_BYTE:
BANKSEL PORTA
BSF PORTA, LED_MUX_LINE ; set mux line HI to transmit to XBee
Radio
BANKSEL
TXREG
MOVWF TXREG
RETURN
LED_TRANSMIT_BYTE:
BANKSEL PORTA
BCF PORTA, LED_MUX_LINE ; set mus line LO to transmit to LED PIC
BANKSEL
TXREG
MOVWF TXREG
RETURN
TRANSMIT_NO_ACTION:
BANKSEL PIR1
MOVF PAIRED_ADDRESS_MSB, W ; set destination address as
paired boat
MOVWF DEST_ADDRESS_MSB
MOVF PAIRED_ADDRESS_LSB, W ; set destination address as paired boat
MOVWF DEST_ADDRESS_LSB
MOVLW NAVIGATION_HEADER ; set header as navigation header
MOVWF TX_DATA_HEADER
MOVLW NO_ACTION_1 ; set data byte 1 as no
action byte 1
MOVWF TX_DATA_BYTE1
MOVLW NO_ACTION_2 ; set data byte 2 as no
action byte 2
MOVWF TX_DATA_BYTE2
CALL TRANSMIT ; tranmist data
packet
RETURN
CLEAR_OVERRUN_ERROR:
BANKSEL RCSTA
BCF RCSTA,
CREN ;
disable receive
NOP
BSF RCSTA,
CREN ;
re-enable receive to clear the overrun error
BANKSEL PORTA
INCF RECEIVE_BYTE_COUNT, F
RETURN
LED_BOAT1:
BANKSEL PORTA
MOVLW BOAT_NUMBER_1
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_1
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
NOP
RETURN
LED_BOAT2:
BANKSEL PORTA
MOVLW BOAT_NUMBER_1
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_2
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
NOP
RETURN
LED_BOAT3:
BANKSEL PORTA
MOVLW BOAT_NUMBER_1
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_3
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
NOP
RETURN
LED_BOAT4:
BANKSEL PORTA
MOVLW BOAT_NUMBER_1
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_4
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT5:
BANKSEL PORTA
MOVLW BOAT_NUMBER_1
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_5
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT6:
BANKSEL PORTA
MOVLW BOAT_NUMBER_1
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_6
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
NOP
RETURN
LED_BOAT7:
BANKSEL PORTA
MOVLW BOAT_NUMBER_2
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_7
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT8:
BANKSEL PORTA
MOVLW BOAT_NUMBER_2
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_8
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT9:
BANKSEL PORTA
MOVLW BOAT_NUMBER_2
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_9
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT10:
BANKSEL PORTA
MOVLW BOAT_NUMBER_2
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_10
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT11:
BANKSEL PORTA
MOVLW BOAT_NUMBER_2
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_11
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT12:
BANKSEL PORTA
MOVLW BOAT_NUMBER_2
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_12
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_RED_TEAM:
BANKSEL PORTA
MOVLW TEAM
MOVWF LED_COMMAND_TYPE
MOVLW RED_TEAM
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BLUE_TEAM:
BANKSEL PORTA
MOVLW TEAM
MOVWF LED_COMMAND_TYPE
MOVLW BLUE_TEAM
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_RED_ACTIVE_ZONE:
BANKSEL PORTA
MOVLW ACTIVE_ZONE
MOVWF LED_COMMAND_TYPE
MOVLW RED_ACTIVE_ZONE
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BLUE_ACTIVE_ZONE:
BANKSEL PORTA
MOVLW ACTIVE_ZONE
MOVWF LED_COMMAND_TYPE
MOVLW BLUE_ACTIVE_ZONE
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_IBUTTON_READ:
BANKSEL PORTA
MOVLW PLAY_STATUS
MOVWF LED_COMMAND_TYPE
MOVLW IBUTTON_READ
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT_MATCHED:
BANKSEL PORTA
MOVLW PLAY_STATUS
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_MATCHED
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_PLAYING_GAME:
BANKSEL PORTA
MOVLW PLAY_STATUS
MOVWF LED_COMMAND_TYPE
MOVLW PLAYING_GAME
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_STAND_DOWN:
BANKSEL PORTA
MOVLW PLAY_STATUS
MOVWF LED_COMMAND_TYPE
MOVLW STAND_DOWN_LED
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_BOAT_OFF:
BANKSEL PORTA
MOVLW PLAY_STATUS
MOVWF LED_COMMAND_TYPE
MOVLW BOAT_OFF
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_STATUS_OFF:
BANKSEL PORTA
MOVLW PLAY_STATUS
MOVWF LED_COMMAND_TYPE
MOVLW STATUS_OFF
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_ACTIVE_ZONE_OFF:
BANKSEL PORTA
MOVLW ACTIVE_ZONE
MOVWF LED_COMMAND_TYPE
MOVLW ACTIVE_ZONE_OFF
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
LED_TEAM_OFF:
BANKSEL PORTA
MOVLW TEAM
MOVWF LED_COMMAND_TYPE
MOVLW TEAM_OFF
MOVWF LED_TYPE
CALL TRANSMIT_LED_PIC
RETURN
TRANSMIT_PONG:
BANKSEL PORTA
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 ; set header as
ping response header
MOVWF TX_DATA_HEADER
MOVF PING_RESPONSE_BYTE1, W ; set data byte 1
as ping response byte 1
MOVWF TX_DATA_BYTE1
MOVF PING_RESPONSE_BYTE2, W ; set data byte 2
as ping response byte 2
MOVWF TX_DATA_BYTE2
CALL TRANSMIT ;
transmit data packet
BANKSEL PORTA
BCF RX_COMMAND_COUNTER,
ADMIRAL_PING_BIT ; clear
ADMIRAL_PING_BIT after transmiting
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
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
BTFSC PIR1, TMR2IF
GOTO INCREMENT_TIMER2_COUNTER
GOTO RESTORE_REGISTERS
;
enter other interrupt flag checks here
RECEIVE:
BANKSEL RCSTA ;
select the bank containing RCSTA
MOVF RCREG, W ;
copy the RCREG register to W
BTFSC RCSTA, OERR ;
check for overrun error
CALL CLEAR_OVERRUN_ERROR ; if overrun
error occured, go to CLEAR_OVERRUN_ERROR
BANKSEL PORTA
MOVWF DATA_RECEIVED ; save the
content of w register to DATA_RECEIVED
MOVF RECEIVE_BYTE_COUNT,W ; get variable to switch on
CALL RX_JUMP_TABLE ; call jump
table
; GOTO CHECK_STAND_DOWN_BIT
MOVF RECEIVE_BYTE_COUNT, F
BTFSS STATUS, Z
GOTO RESTORE_REGISTERS
GOTO CHECK_IF_ACK_REQUIRED ; changed from
check ack reqd
INCREMENT_TIMER2_COUNTER:
BANKSEL PIR1
INCF TIMER2_COUNTER, F
BANKSEL PIR1
BCF PIR1,
TMR2IF
GOTO RESTORE_REGISTERS
;CHECK_STAND_DOWN_BIT
; BTFSC RX_COMMAND_COUNTER,
STAND_DOWN_BIT
; GOTO RESTORE_REGISTERS
; GOTO CHECK_IF_ACK_REQUIRED
CHECK_IF_ACK_REQUIRED:
; BOAT will
only have to send responses to the ADMIRAL
BANKSEL PIR1
BTFSC RX_DATA_HEADER,
WATERCRAFT_HEADER_BIT
GOTO CHECK_WATERCRAFT_MSG ; if
bit is set, go to check for the type of watercraft message
BTFSC RX_DATA_HEADER,
ADMIRAL_HEADER_BIT ; check if the
RX_DATA_HEADER is an ADMIRAL_HEADER
GOTO CHECK_ADMIRAL_MSG ; if Z = 0,
the received data is not from the admiral, no response required
GOTO RESTORE_REGISTERS ;
if z = 0, the source address is not admiral address
CHECK_WATERCRAFT_MSG:
BANKSEL PORTA
MOVF SOURCE_ADDRESS_LSB, W ; move the source
address lsb to W
SUBWF PAIRED_ADDRESS_LSB, W ; subtract W
from PAIRED_ADDRESS_LSB
BTFSS STATUS, Z ;
check bit z of status register
GOTO RESTORE_REGISTERS ; go
to restore register if the message is not from the boat
BTFSC RX_DATA_BYTE2,
STAND_DOWN_RECEIVED_BIT ; check if
the STAND_DOWN_BIT is set
GOTO RESPOND_TO_STAND_DOWN ; if a
stand down command was sent, respond accordingly
GOTO RESTORE_REGISTERS
CHECK_ADMIRAL_MSG:
BANKSEL
PIR1
MOVF SOURCE_ADDRESS_LSB, W ; move the source
address lsb to W
SUBLW ADMIRAL_ADDRESS_LSB ; subtract W
from ADMIRAL_ADDRESS_LSB
BTFSS STATUS, Z ;
check bit z of status register
GOTO RESTORE_REGISTERS ; if
the message is not from the admiral, go back to restoring registers
BTFSC RX_DATA_BYTE2,
BLUE_GOAL_BIT ; if a blue goal active
command was sent
GOTO RESPOND_TO_RED_GOAL ;
set the blue Active Zone LED
BTFSC RX_DATA_BYTE2, RED_GOAL_BIT ; if a red goal active
command was sent
GOTO RESPOND_TO_BLUE_GOAL
GOTO SET_ADDRESS_TO_ADMIRAL
SET_ADDRESS_TO_ADMIRAL:
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
GOTO DETERMINE_RESPONSE_TYPE
DETERMINE_RESPONSE_TYPE:
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,
START_GAME_BIT
GOTO RESPOND_TO_START_GAME ; if
a start game command was sent, respond accordingly
BTFSC RX_DATA_BYTE2, END_GAME_BIT ; if an end game command was
sent, command the boat to stop
GOTO RESPOND_TO_END_GAME ;
by sending a no action command
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 PIR1
BSF RX_COMMAND_COUNTER,
ADMIRAL_PING_BIT
GOTO RESTORE_REGISTERS
RESPOND_TO_RED_GOAL:
BANKSEL PIR1
BSF RX_COMMAND_COUNTER,
RED_GOAL_BIT
BCF RX_COMMAND_COUNTER,
BLUE_GOAL_BIT
GOTO RESTORE_REGISTERS
RESPOND_TO_BLUE_GOAL:
BANKSEL PIR1
BCF RX_COMMAND_COUNTER,
RED_GOAL_BIT
BSF RX_COMMAND_COUNTER,
BLUE_GOAL_BIT
GOTO RESTORE_REGISTERS
RESPOND_TO_HARD_RESET:
BANKSEL PIR1
BSF RX_COMMAND_COUNTER,
HARD_RESET_BIT
GOTO RESTORE_REGISTERS
RESPOND_TO_STAND_DOWN:
BANKSEL PIR1
BSF RX_COMMAND_COUNTER,
STAND_DOWN_BIT ;
set STAND_DOWN_BIT of RX_COMMAND_COUNTER byte
GOTO RESTORE_REGISTERS ;
if none of these checks happened, an error occured, ignore the ping
RESPOND_TO_START_GAME:
BANKSEL PIR1
BSF RX_COMMAND_COUNTER,
START_GAME_BIT ;
set START_GAME_BIT of RX_COMMAND_COUNTER byte
GOTO RESTORE_REGISTERS ;
if none of these checks happened, an error occured, ignore the ping
RESPOND_TO_END_GAME:
BANKSEL PIR1
BSF RX_COMMAND_COUNTER,
END_GAME_BIT ;
set END_GAME_BIT of RX_COMMAND_COUNTER byte
GOTO RESTORE_REGISTERS ;
if none of these checks happened, an error occured, ignore the ping
RESTORE_REGISTERS:
BANKSEL PIR1
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
JUMP TABLE FOR SAVING RECEIVED DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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 ; increment
Jump Table Variable
MOVF DATA_RECEIVED, W
MOVWF SOURCE_ADDRESS_MSB ; save
DATA_RECEIVED as SOURCE_ADDRESS_MSB
RETURN
; save source
address LSB byte
Case5:
BANKSEL PORTA ;
select the bank containing PORTA
INCF RECEIVE_BYTE_COUNT, F ; increment
Jump Table Variable
MOVF DATA_RECEIVED, W
MOVWF SOURCE_ADDRESS_LSB ; save
DATA_RECEIVED as SOURCE_ADDRESS_LSB
RETURN
; discard
RSSI byte
Case6:
BANKSEL PORTA ;
select the bank containing PORTA
INCF RECEIVE_BYTE_COUNT, F ; increment
Jump Table Variable
RETURN
; discard
Options byte
Case7:
BANKSEL PORTA ;
select the bank containing PORTA
INCF RECEIVE_BYTE_COUNT, F ; increment
Jump Table Variable
RETURN
; save RF
data header byte
Case8:
BANKSEL PORTA ;
select the bank containing PORTA
INCF RECEIVE_BYTE_COUNT, F ; increment
Jump Table Variable
MOVF DATA_RECEIVED, W
MOVWF RX_DATA_HEADER ; save
DATA_RECEIVED as RX_DATA_HEADER
RETURN
Case9:
BANKSEL PORTA ;
select the bank containing PORTA
INCF RECEIVE_BYTE_COUNT, F ; increment
Jump Table Variable
MOVF DATA_RECEIVED, W
MOVWF RX_DATA_BYTE1 ;
save DATA_RECEIVED as RX_DATA_BYTE1
RETURN
Case10:
BANKSEL PORTA ;
select the bank containing PORTA
INCF RECEIVE_BYTE_COUNT, F ; increment
Jump Table Variable
MOVF DATA_RECEIVED, W
MOVWF RX_DATA_BYTE2 ;
save DATA_RECEIVED as 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SENSOR READ SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXECUTE_COMMANDS:
INITIALIZE_INT_TMR2:
BANKSEL TMR2 ;
select the bank containing TMR2
CLRF TMR2 ;
clear the timer TMR2
MOVLW b'01111111' ;
move 01111111 to W
IORWF T2CON, F ;
or W with T2CON to set TOUTPS1-3 to 1111 and postscale timer 2 by 1:16
BANKSEL PR2 ;
select the bank containing PR2
MOVLW b'11111111' ;
d'256'
MOVWF PR2 ; move 11111111 from W to PR2 (Timer 2 Flag set
every 0.0131072 sec = 13.1 ms)
BANKSEL PIE1 ;
select bank containing PIE1
BSF PIE1, TMR2IE
BANKSEL TIMER2_COUNTER
CLRF TIMER2_COUNTER
WAIT_FOR_GAME_START:
BTFSC RX_COMMAND_COUNTER,
ADMIRAL_PING_BIT
CALL TRANSMIT_PONG
BTFSC RX_COMMAND_COUNTER,
HARD_RESET_BIT ;
check HARD_RESET_BIT of RX_COMMAND_COUNTER byte
GOTO HARD_RESETTING ;
if the stand down bit is set, go to HARD_RESETTING
BTFSC RX_COMMAND_COUNTER,
START_GAME_BIT ;
check START_GAME_BIT of RX_COMMAND_COUNTER byte
GOTO SEND_START_GAME_ACK ;
if the start game bit is set, go to INITIALIZE_HELM_INPUT
BANKSEL PORTA
MOVF TIMER2_COUNTER, W
SUBLW COUNT_200MS
BTFSS STATUS, Z ;
test bit Z of STATUS register
GOTO WAIT_FOR_GAME_START ; if Z = 0, TIMER2_COUNTER is
not COUNT_200MS, go back to WAIT_FOR_GAME_START
CALL TRANSMIT_NO_ACTION ; Command to send no action
CLRF TIMER2_COUNTER
GOTO WAIT_FOR_GAME_START
SEND_START_GAME_ACK:
BANKSEL PIR1
MOVLW ACK_HEADER ; prepare acknowledgement
back to the admiral
MOVWF TX_DATA_HEADER
MOVLW NO_ACTION_2 ; set data byte 1 as 0x00
MOVWF TX_DATA_BYTE1
MOVLW START_GAME ; set data byte 2 as
start game
MOVWF TX_DATA_BYTE2
MOVLW ADMIRAL_ADDRESS_MSB ;
set the destination address to admiral address
MOVWF DEST_ADDRESS_MSB
MOVLW ADMIRAL_ADDRESS_LSB ;
set the destination address to admiral address
MOVWF DEST_ADDRESS_LSB
CALL TRANSMIT ;
transmit the acknowledgement data packet to admiral
INITIALIZE_HELM_INPUT:
BANKSEL PORTA
CALL LED_PLAYING_GAME ; turn Playing Game LED on
CALL DISPLAY_BOAT_NUMBER ; display boat# on LED
BANKSEL TRISC ; Select TRIS bank
BCF PORTA,1
MOVLW b'11111000' ; 3 LSB output for MUX Control
MOVWF TRISC ; Set TRISC bits
BANKSEL PORTC ; Go to Bank 0
MOVLW COMMAND_9 ; Move Command 9 to W
MOVWF TX_DATA_BYTE1 ; Move W to Navigation Byte
CLRF TX_DATA_BYTE2 ; Set special byte to all zeros
PLAY_GAME:
BANKSEL PIR1
BTFSC RX_COMMAND_COUNTER,
END_GAME_BIT ;
check END_GAME_BIT of RX_COMMAND_COUNTER byte
GOTO GAME_OVER ;
if the end game bit is set, go to GAME_OVER
BTFSC RX_COMMAND_COUNTER,
STAND_DOWN_BIT ;
check STAND_DOWN_BIT of RX_COMMAND_COUNTER byte
CALL SEND_STAND_DOWN_ACK ; if the stand
down bit is set, go to STANDING_DOWN
BTFSC RX_COMMAND_COUNTER,
STAND_DOWN_BIT ;
check STAND_DOWN_BIT of RX_COMMAND_COUNTER byte
GOTO STANDING_DOWN ; if the stand down bit is set,
go to STANDING_DOWN
BTFSC RX_COMMAND_COUNTER,
HARD_RESET_BIT ;
check HARD_RESET_BIT of RX_COMMAND_COUNTER byte
GOTO HARD_RESETTING ;
if the stand down bit is set, go to HARD_RESETTING
;
check if the 200ms has passed since the last transmit, if not, then go back to
PLAY_GAME
BANKSEL PIR1
MOVF TIMER2_COUNTER, W
SUBLW COUNT_200MS
BTFSS STATUS, Z ; test bit Z of STATUS register
GOTO PLAY_GAME ;
if Z = 0, TIMER2_COUNTER is not COUNT_200MS, go back to PLAY_GAME
;
check for active goal
BTFSC RX_COMMAND_COUNTER,
RED_GOAL_BIT ; check if
RED_GOAL_BIT is set
CALL LED_BLUE_ACTIVE_ZONE ; if set, turn
Blue Active Zone LED on
BTFSC RX_COMMAND_COUNTER,
BLUE_GOAL_BIT ; check if
BLUE_GOAL_BIT is set
CALL LED_RED_ACTIVE_ZONE ; if set,
turn Red Active Zone LED on
BTFSC RX_COMMAND_COUNTER,
ADMIRAL_PING_BIT ; check if admiral
has pinged
CALL TRANSMIT_PONG ;
if pinged, then ping back
CALL NAV_SENSOR_READ ; read
magnetic sensors for Navigation Byte
CALL SPECIAL_SENSOR_READ ; read special sensors for
Special Byte
MOVLW NAVIGATION_HEADER
MOVWF TX_DATA_HEADER ; set header as
Navigation Header
MOVF NAVIGATION_BYTE, W
MOVWF TX_DATA_BYTE1
MOVF SPECIAL_BYTE, W
MOVWF TX_DATA_BYTE2
MOVF PAIRED_ADDRESS_MSB, W ; set destination address as
paired boat address
MOVWF DEST_ADDRESS_MSB
MOVF PAIRED_ADDRESS_LSB, W ; set destination address as paired boat
address
MOVWF DEST_ADDRESS_LSB
CALL TRANSMIT ; transmit the
data packet
BANKSEL PIR1
CLRF TIMER2_COUNTER ; clear
TIMER2_COUNTER
BANKSEL PIR1
GOTO PLAY_GAME
GAME_OVER:
BTFSC RX_COMMAND_COUNTER,
HARD_RESET_BIT ;
check HARD_RESET_BIT of RX_COMMAND_COUNTER byte
GOTO HARD_RESETTING ;
if the stand down bit is set, go to HARD_RESETTING
BTFSC RX_COMMAND_COUNTER,
END_GAME_BIT ;
check END_GAME_BIT of RX_COMMAND_COUNTER byte
CALL SEND_END_GAME_ACK ;
if the end game bit is set, send End Game Acknowledgemtn
BTFSC RX_COMMAND_COUNTER,
ADMIRAL_PING_BIT ;
check ADMIRAL_PING_BIT of RX_COMMAND_COUNTER byte
CALL TRANSMIT_PONG ;
if the bit is set, go to TRANSMIT_PONG to ping back
BCF RX_COMMAND_COUNTER,
END_GAME_BIT ;
clear END_GAME BIT
CALL LED_TEAM_OFF ;
turn Team LEDs off
CALL LED_STATUS_OFF ;
turn Status LEDs off
CALL LED_ACTIVE_ZONE_OFF ;
turn Active Zone LEDs off
CALL LED_BOAT_MATCHED ;
leave BoatMatched LED on
CALL LED_IBUTTON_READ ;
leave ibutton Read LED on
CALL DISPLAY_BOAT_NUMBER ;
leave Boat# LED on
BANKSEL PIR1
CLRF SPECIAL_BYTE
MOVF TIMER2_COUNTER, W
SUBLW COUNT_200MS
BTFSS STATUS, Z ;
test bit Z of STATUS register
GOTO GAME_OVER ; if Z =
0, TIMER2_COUNTER is not COUNT_200MS, go back to PLAY_GAME
CALL NAV_SENSOR_READ ; if Z
= 1, TIMER2_COUNTER is COUNT_200MS
MOVLW NAVIGATION_HEADER ; set header as Navigation
header
MOVWF TX_DATA_HEADER
MOVF NAVIGATION_BYTE, W
MOVWF TX_DATA_BYTE1 ; set data
byte 1 as Navitagion Byte from sensors
MOVF SPECIAL_BYTE, W
MOVWF TX_DATA_BYTE2 ; set data
byte 2 as Special Byte from sensors
MOVF PAIRED_ADDRESS_MSB, W
MOVWF DEST_ADDRESS_MSB ; set destination
address as paired boat
MOVF PAIRED_ADDRESS_LSB, W
MOVWF DEST_ADDRESS_LSB ; set destination
address as paired boat
CALL TRANSMIT ;
send the data packet
BANKSEL PIR1
CLRF TIMER2_COUNTER ;
clear the timer2_counter
GOTO GAME_OVER
STANDING_DOWN:
BANKSEL PIR1
BTFSC RX_COMMAND_COUNTER,
END_GAME_BIT ;
check END_GAME_BIT of RX_COMMAND_COUNTER byte
GOTO GAME_OVER ;
if the end game bit is set, go to GAME_OVER
BTFSC RX_COMMAND_COUNTER,
HARD_RESET_BIT ;
check HARD_RESET_BIT of RX_COMMAND_COUNTER byte
GOTO HARD_RESETTING ;
if the stand down bit is set, go to HARD_RESETTING
;
otherwise, continue playing game
BTFSC RX_COMMAND_COUNTER,
ADMIRAL_PING_BIT
CALL TRANSMIT_PONG
BANKSEL PIR1
MOVF TIMER2_COUNTER, W ; move TIMER2_COUNTER
to W
SUBLW COUNT_200MS ; subtract
COUNT_200MS from W
BTFSS STATUS, Z ;
test bit Z of STATUS register
GOTO STANDING_DOWN ;
if Z = 0, TIMER2_COUNTER is not COUNT_200MS, go back to PLAY_GAME
BANKSEL PIR1
INCF STAND_DOWN_COUNTER, F ; Record number of
messages sent during stand down
CALL TRANSMIT_NO_ACTION ; sent no action
BANKSEL PIR1
CLRF TIMER2_COUNTER ;
clear Timer2_counter
BANKSEL PIR1
MOVF STAND_DOWN_COUNTER, W ; Move Stand Down
counter to W
SUBLW NUM_STAND_DOWN_MSG ; Subtract 50 from
Stand down Counter (number of messages in 10 sec at 5 Hz)
BTFSS STATUS,Z ;
Skip if Zero (meaning end of Stand Down)
GOTO STANDING_DOWN ;
if 10 seconds hasn't passed, go back to STANDING_DOWN
CLRF STAND_DOWN_COUNTER ; Clear Stand
Down counter
CALL LED_STATUS_OFF ;
turn Status LEDs off
CALL LED_IBUTTON_READ ; leave Ibutton Read LED on
CALL LED_BOAT_MATCHED ; leave Boat matched LED on
CALL LED_PLAYING_GAME ; leave Playing Game LED on
CALL DISPLAY_BOAT_NUMBER ; leave Boat# LED on
BANKSEL PIR1
BCF RX_COMMAND_COUNTER,
STAND_DOWN_BIT ; clear
STAND_DOWN_BIT on RX_COMMAND_COUNTER
GOTO PLAY_GAME
; ;
turn on LEDs
; BTFSC STATUS,Z ;
Skip if result not zero (meaning result of SUBLW not zero and no status since
then)
; CALL LED_STATUS_OFF
; BTFSC STATUS,Z ;
Skip if result not zero (meaning result of SUBLW not zero and no status since
then)
; CALL LED_IBUTTON_READ
; BTFSC STATUS,Z ;
Skip if result not zero (meaning result of SUBLW not zero and no status since
then)
; CALL LED_BOAT_MATCHED
; BTFSC STATUS,Z ;
Skip if result not zero (meaning result of SUBLW not zero and no status since
then)
; CALL LED_PLAYING_GAME
; BTFSC STATUS,Z ;
Skip if result not zero (meaning result of SUBLW not zero and no status since
then)
; CALL DISPLAY_BOAT_NUMBER
;
check for if the game had started before the stand down command
; BTFSS STATUS,Z ;
Skip if result not zero (meaning result of SUBLW not zero and no status since
then)
; GOTO STANDING_DOWN
; BTFSC STATUS, Z
; BCF RX_COMMAND_COUNTER,STAND_DOWN_BIT ; Clear Stand Down bit
;
; BTFSC RX_COMMAND_COUNTER,
START_GAME_BIT
; GOTO PLAY_GAME ;
Return to Playing game
; GOTO WAIT_FOR_GAME_START
;
HARD_RESETTING:
BANKSEL PORTA
CALL LED_STATUS_OFF ; turn all status LEDs off
CALL LED_TEAM_OFF ; turn Team LEDs off
CALL LED_ACTIVE_ZONE_OFF ; turn Active Zone LEDs off
CALL LED_BOAT_OFF ; turn Boat # LEDs off
;
clear all the variables
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 DATA_RECEIVED
CLRF RX_COMMAND_COUNTER
CLRF TIMER2_COUNTER
CLRF NAVIGATION_BYTE
CLRF SPECIAL_BYTE
GOTO MAIN ; go back to main and wait for
ibutton
SEND_STAND_DOWN_ACK:
;transmit the
acknowledgement data packet to admiral
BANKSEL PIR1
MOVLW ACK_HEADER ; set header to ack header ;
prepare acknowledgement back to the admiral
MOVWF TX_DATA_HEADER
MOVLW STAND_DOWN_RECEIVED_1 ; set data byte 1 to stand down
received byte 1
MOVWF TX_DATA_BYTE1
MOVLW STAND_DOWN_RECEIVED_2 ; set datea bye 2 to stand down
receiver byte 2
MOVWF TX_DATA_BYTE2
MOVF PAIRED_ADDRESS_MSB, W ; set the destination address to
admiral address
MOVWF DEST_ADDRESS_MSB
MOVF PAIRED_ADDRESS_LSB, W ; set the destination address to admiral
address
MOVWF DEST_ADDRESS_LSB
CALL TRANSMIT ; transmit the
data packet ;
transmit the acknowledgement data packet to admiral
CALL LED_STATUS_OFF ; turn off status LEDs
CALL LED_IBUTTON_READ ; leave iButton Read LED on
CALL LED_BOAT_MATCHED ; leave Boat Matched LED on
CALL LED_STAND_DOWN ; leave Stand Down
LED on
CALL DISPLAY_BOAT_NUMBER ; leave Boat# LED on
BANKSEL PIR1
RETURN
SEND_END_GAME_ACK:
; transmit
End Game acknowledgement to Admiral
BANKSEL PIR1
MOVLW ACK_HEADER ; set header to ack header
;
prepare acknowledgement back to the admiral
MOVWF TX_DATA_HEADER
MOVLW NO_ACTION_2 ; set data byte 1 to 0x00
MOVWF TX_DATA_BYTE1
MOVLW END_GAME
MOVWF TX_DATA_BYTE2 ; set data byte 2 to End_Game
byte
MOVLW ADMIRAL_ADDRESS_MSB ; set the destination address to admiral
address
MOVWF DEST_ADDRESS_MSB
MOVLW ADMIRAL_ADDRESS_LSB ; set the destination address to admiral
address
MOVWF DEST_ADDRESS_LSB
CALL TRANSMIT ; transmit the
data packet ;
transmit the acknowledgement data packet to admiral
RETURN
NAV_SENSOR_READ:
BANKSEL PORTC ; Change to the Port bank
BTFSS PORTC,4 ;
Skip next instruction if Mag Sens 9 is set
CALL CYCLE_MAG_SENSE ; Read
all other magnet sensors
BTFSC PORTC,4 ;
Skip next instruction if Mag Sens 9 is clear
MOVLW COMMAND_9 ; Move command
for sensor 9 to W
MOVWF NAVIGATION_BYTE ;
Set Nav Byte to position 9
RETURN
CYCLE_MAG_SENSE:
BANKSEL PORTC ; Set BANKSEL to Port bank
MOVLW 0xF8 ; Set 0xF8 to W (all high
except 3LSB)
ANDWF PORTC,F ; Clear 3 LSB for PORTC (Set MUX to
0)
NOP
NOP
BTFSC PORTC,3 ; Skip if mux
input is low
MOVLW COMMAND_1 ; Move in Command for position 1
BTFSC PORTC,3 ; Skip if mux
input is low
RETURN
INCF PORTC, F ; Increment PORTC
NOP
NOP
BTFSC PORTC,3 ; Skip if mux
input is low
MOVLW COMMAND_2 ; Move in Command for position 1
BTFSC PORTC,3 ; Skip if mux
input is low
RETURN
INCF PORTC, F ; Increment PORTC
NOP
NOP
BTFSC PORTC,3 ; Skip if mux
input is low
MOVLW COMMAND_3 ; Move in Command for position 1
BTFSC PORTC,3 ; Skip if mux
input is low
RETURN
INCF PORTC, F ; Increment PORTC
NOP
NOP
BTFSC PORTC,3 ; Skip if mux
input is low
MOVLW COMMAND_4 ; Move in Command for position 1
BTFSC PORTC,3 ; Skip if mux
input is low
RETURN
INCF PORTC, F ; Increment PORTC
NOP
NOP
BTFSC PORTC,3 ; Skip if mux
input is low
MOVLW COMMAND_5 ; Move in Command for position 1
BTFSC PORTC,3 ; Skip if mux
input is low
RETURN
INCF PORTC, F ; Increment PORTC
NOP
NOP
BTFSC PORTC,3 ; Skip if mux
input is low
MOVLW COMMAND_6 ; Move in Command for position 1
BTFSC PORTC,3 ; Skip if mux
input is low
RETURN
INCF PORTC, F ; Increment PORTC
NOP
NOP
BTFSC PORTC,3 ; Skip if mux
input is low
MOVLW COMMAND_7 ; Move in Command for position 1
BTFSC PORTC,3 ; Skip if mux
input is low
RETURN
INCF PORTC, F ; Increment PORTC
NOP
NOP
BTFSC PORTC,3 ; Skip if mux
input is low
MOVLW COMMAND_8 ; Move in Command for position 1
BTFSC PORTC,3 ; Skip if mux
input is low
RETURN
MOVLW COMMAND_9 ; Move in No Motion Command
RETURN
; SPECIALS
assumes matching between desired 0 and Low signal
SPECIAL_SENSOR_READ:
BANKSEL PORTC ; Select Port
Bank
BTFSC PORTC,5 ;
Skip if gun low
MOVLW WATER_ON ; Move Water ON to W
BTFSS PORTC,5 ;
Skip if Gun Signal High
MOVLW WATER_OFF ; Move Water OFF to W
MOVWF SPECIAL_BYTE ; Move Water command into
Special Byte
BTFSC PORTC,6 ;
Skip if Bottle not present
BSF SPECIAL_BYTE,
SPECIAL_1 ;
Set the special 1 bit
BTFSS PORTC,6 ;
Skip if Bottle present
BCF SPECIAL_BYTE, SPECIAL_1 ; Clear the special
1 bit
BTFSC PORTC,7 ;
Skip if Voice present
BSF SPECIAL_BYTE,
SPECIAL_2 ;
Set the special 2 bit
BTFSS PORTC,7 ;
Skip if Voice not present
BCF SPECIAL_BYTE, SPECIAL_2 ; Clear the
special 2 bit
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
END PROGRAM !!!!!!!!!!!!!! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
END
list P=PIC16F690
#include
"p16F690.inc"
__config (_CP_OFF & _WDT_OFF & _PWRTE_ON
& _HS_OSC)
#define CLOCK_LINE_SR1 0
#define DATA_LINE_SR1 1
#define CLOCK_LINE_SR2 2
#define DATA_LINE_SR2 3
#define IBUTTON_READ_LED_BIT 4
#define BOAT_MATCHED_LED_BIT 5
#define PLAYING_GAME_LED_BIT 6
#define STAND_DOWN_LED_BIT 7
#define RED_TEAM_BIT_B4 4
#define BLUE_TEAM_BIT_B6 6
#define RED_ZONE_BIT_A0 0
#define BLUE_ZONE_BIT_A1 1
#define BOAT_1 0x02
#define BOAT_2 0x04
#define BOAT_3 0x08
#define BOAT_4 0x10
#define BOAT_5 0x40
#define BOAT_6 0x80
#define BOAT_1_BIT 1
#define BOAT_2_BIT 2
#define BOAT_3_BIT 3
#define BOAT_4_BIT 4
#define BOAT_5_BIT 6
#define BOAT_6_BIT 7
#define BOAT_7 0x02
#define BOAT_8 0x04
#define BOAT_9 0x08
#define BOAT_10 0x10
#define BOAT_11 0x40
#define BOAT_12 0x80
#define BOAT_7_BIT 1
#define BOAT_8_BIT 2
#define BOAT_9_BIT 3
#define BOAT_10_BIT 4
#define BOAT_11_BIT 6
#define BOAT_12_BIT 7
#define RED_TEAM 0x02
#define BLUE_TEAM 0x04
#define TEAM_OFF 0x40
#define ACTIVE_ZONE_OFF 0x80
#define RED_ACTIVE_ZONE 0x08
#define BLUE_ACTIVE_ZONE 0x10
#define RED_TEAM_BIT 1
#define BLUE_TEAM_BIT 2
#define RED_ACTIVE_ZONE_BIT 3
#define BLUE_ACTIVE_ZONE_BIT 4
#define TEAM_OFF_BIT 6
#define ACTIVE_ZONE_OFF_BIT 7
#define IBUTTON_READ 0x02
#define BOAT_MATCHED 0x04
#define PLAYING_GAME 0x08
#define STAND_DOWN_LED 0x10
#define STATUS_OFF 0x40
#define BOAT_OFF 0x80
#define IBUTTON_READ_BIT 1
#define BOAT_MATCHED_BIT 2
#define PLAYING_GAME_BIT 3
#define STAND_DOWN_BIT 4
#define STATUS_OFF_BIT 6
#define BOAT_OFF_BIT 7
#define START_BYTE 0x7E
#define BOAT_NUMBER_1 0x0F
#define BOAT_NUMBER_2 0x02
#define TEAM 0x04
#define ACTIVE_ZONE 0x08
#define PLAY_STATUS 0xFF
; Bit Definitions
TRISA_BITS equ b'00000000' ;
all PORTA outputs
TRISB_BITS equ b'00100000' ; all PORTB outputs except bit 5
TRISC_BITS equ b'00000000' ;
all PORTC bits are inputs
PIC_BAUDRATE equ d'129' ;
calculate baudrate = 9765 so X = 129
RECEIVE_BYTE_COUNT equ 0x22
COMMAND_TYPE equ 0x23
LED_TYPE equ 0x24
W_TEMP equ 0x25
STATUS_TEMP equ 0x26
DATA_RECEIVED equ 0x27
;RC0 clock
line for shift register 1
;RC1 data
line for shift register 1
;RC2 clock
line for shift register 2
;RC3 data
line for shift register 2
;RB4 red team
;RB6 blue
team
;RA0 red team
active zone
;RA1 blue
team active zone
;RC4 ibutton
read
;RC5 boat
matched
;RC6 playing
game
;RC7 stand
down
; 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
MAIN:
INITIALIZE:
clear_ansel_bits:
BANKSEL ANSEL ; select bank containing
ANSEL
CLRF ANSEL ; clears analog bits
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
MOVWF TRISB
MOVLW TRISC_BITS ;
write TRISC_BITS to W
MOVWF TRISC ;
write TRISC_BITS from W to TRISA
BANKSEL PORTC
CLRF PORTC
CLRF PORTB
CLRF PORTA
CLRF RECEIVE_BYTE_COUNT
CLRF COMMAND_TYPE
CLRF LED_TYPE
;clear all of
pins on shift register 1
initialize_sr1:
BCF PORTC, DATA_LINE_SR1 ; clear port C0
CALL CLOCK_PULSE_SR1 ; send clock pulse
to shift register 1
BCF PORTC, DATA_LINE_SR1 ; clear port C0
CALL CLOCK_PULSE_SR1 ; send clock pulse
to shift register 1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
; clear all
of pins on shift register 2
initialize_sr2:
BCF PORTC, DATA_LINE_SR2 ; clear port C1
CALL CLOCK_PULSE_SR2 ; send clock pulse
to shift register 2
BCF PORTC, DATA_LINE_SR2 ; clear port C1
CALL CLOCK_PULSE_SR2 ; send clock pulse
to shift register 2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
set_baudrate:
BANKSEL SPBRGH
CLRF SPBRGH ; set SPBRGH byte to
0
MOVLW PIC_BAUDRATE ; write the
contents of PIC_BAUDRATE to W
MOVWF SPBRG ;
set x = 31 and calculated baudrate = 9765
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_comm:
BANKSEL RCSTA
BSF RCSTA, SPEN ; enable
serial port for receive
BANKSEL RCSTA
BSF RCSTA, CREN ; enable
receive
initialize_interrupts:
BANKSEL INTCON ;
select bank containing INTCON
BSF INTCON, GIE ; enable
global interrupts
BSF INTCON, PEIE ; enable
interrupts
BANKSEL PIE1 ;
select bank containing PIE1
BSF PIE1, RCIE ;
enable interrupts
LOOP:
GOTO LOOP
;--------------
subroutines ----------------;
CLOCK_PULSE_SR1:
BSF PORTC, CLOCK_LINE_SR1 ; set clock line
for shift register 1 high
NOP
NOP
BCF PORTC, CLOCK_LINE_SR1 ; set clock line
for shift register 1 low
NOP
NOP
RETURN
CLOCK_PULSE_SR2:
BSF PORTC, CLOCK_LINE_SR2 ; set clock line
for shift register 2 high
NOP
BCF PORTC, CLOCK_LINE_SR2 ; set clock line
for shift register 2 low
NOP
RETURN
;---------------------------------------------
Interrupt Service Routine ------------------------------------------;
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
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
MOVWF DATA_RECEIVED ; save the
content of w register to DATA_RECEIVED
MOVF RECEIVE_BYTE_COUNT,W ; get variable to switch on
CALL RX_JUMP_TABLE ; call jump
table
GOTO CHECK_LED
CHECK_LED:
BANKSEL PIR1
MOVF COMMAND_TYPE, W ; move
COMMAND_TYPE to w
SUBLW BOAT_NUMBER_1 ;
subtract W from START_BYTE
BTFSC STATUS, Z ;
test bit Z of STATUS register
GOTO SET_BOAT_NUMBER_1 ; if Z = 1, received
data is BOAT_NUMBER_1
MOVF COMMAND_TYPE, W ; move
COMMAND_TYPE to w
SUBLW BOAT_NUMBER_2 ;
subtract W from START_BYTE
BTFSC STATUS, Z ;
test bit Z of STATUS register
GOTO SET_BOAT_NUMBER_2 ; if Z = 1, received
data is BOAT_NUMBER_2
MOVF COMMAND_TYPE, W ; move
COMMAND_TYPE to w
SUBLW TEAM ; subtract w
from TEAM
BTFSC STATUS, Z ;
if Z = 1, received data is TEAM
GOTO SET_TEAM ;
command type is TEAM type so go to SET_TEAM
MOVF COMMAND_TYPE, W ;
otherwise, keep checking
SUBLW ACTIVE_ZONE ; subtract
w from ACTIVE_ZONE
BTFSC STATUS, Z ;
if z = 1, received data is ACTIVE_ZONE
GOTO SET_ACTIVE_ZONE ;
command type is ACTIVE_ZONE so go to ACTIVE_ZONE
MOVF COMMAND_TYPE, W ;
otherwise, keep checking
SUBLW PLAY_STATUS ;
subtract w from PLAY_STATUS
BTFSC STATUS, Z ; if z = 1, received data is
PLAY_STATUS
GOTO SET_PLAY_STATUS ;
command type is play status, so go to PLAY_STATUS
GOTO RESTORE_REGISTERS ; exit interrupt
service routine
SET_BOAT_NUMBER_1:
BTFSC LED_TYPE, BOAT_1_BIT ; check if BOAT_1_BIT of
LED TYPE is set
GOTO LED_BOAT1 ; if
set, go to LED_BOAT1
BTFSC LED_TYPE, BOAT_2_BIT ; check if BOAT_2_BIT of
LED Type is set
GOTO LED_BOAT2 ; if
set, go to LED_BOAT2
BTFSC LED_TYPE, BOAT_3_BIT ; check if BOAT_3_BIT of
LED Type is set
GOTO LED_BOAT3 ; if
set, go to LED_BOAT3
BTFSC LED_TYPE, BOAT_4_BIT ; check if BOAT_4_BIT of
LED Type is set
GOTO LED_BOAT4 ; if
set, go to LED_BOAT4
BTFSC LED_TYPE, BOAT_5_BIT ; check if BOAT_5_BIT of
LED Type is set
GOTO LED_BOAT5 ; if
set, go to LED_BOAT5
BTFSC LED_TYPE, BOAT_6_BIT ; check if BOAT_6_BIT of
LED Type is set
GOTO LED_BOAT6 ; if
set, go to LED_BOAT6
GOTO RESTORE_REGISTERS ; exit interrupt
service routine
SET_BOAT_NUMBER_2:
BTFSC LED_TYPE, BOAT_7_BIT ; check if BOAT_7_BIT of
LED Type is set
GOTO LED_BOAT7 ; if
set, go to LED_BOAT7
BTFSC LED_TYPE, BOAT_8_BIT ; check if BOAT_8_BIT of
LED Type is set
GOTO LED_BOAT8 ; if
set, go to LED_BOAT8
BTFSC LED_TYPE, BOAT_9_BIT ; check if BOAT_9_BIT of
LED Type is set
GOTO LED_BOAT9 ; if
set, go to LED_BOAT9
BTFSC LED_TYPE, BOAT_10_BIT ; check if BOAT_10_BIT of
LED Type is set
GOTO LED_BOAT10 ; if
set, go to LED_BOAT10
BTFSC LED_TYPE, BOAT_11_BIT ; check if BOAT_11_BIT of
LED Type is set
GOTO LED_BOAT11 ; if
set, go to LED_BOAT11
BTFSC LED_TYPE, BOAT_12_BIT ; check if BOAT_12_BIT of
LED Type is set
GOTO LED_BOAT12 ; if
set, go to LED_BOAT12
GOTO RESTORE_REGISTERS
SET_TEAM:
BTFSC LED_TYPE, RED_TEAM_BIT ; check if RED_TEAM_BIT is set
GOTO LED_RED_TEAM ; if set, go
to LED_RED_TEAM
BTFSC LED_TYPE, BLUE_TEAM_BIT ; check if
BLUE_TEAM_BIT is set
GOTO LED_BLUE_TEAM ; if set, go
to LED_BLUE_TEAM
BTFSC LED_TYPE, TEAM_OFF_BIT ; check if TeAM_OFF_BIT is set
GOTO LED_TEAM_OFF ; if set, go
to LED_TEAM_OFF
GOTO RESTORE_REGISTERS ; exit interrupt
service routine
SET_ACTIVE_ZONE:
BTFSC LED_TYPE,
RED_ACTIVE_ZONE_BIT ; check if
RED_ACTIVE_ZONE_BIT is set
GOTO LED_RED_ACTIVE_ZONE ; if set, go to
LED_RED_ACTIVE_XONE
BTFSC LED_TYPE,
BLUE_ACTIVE_ZONE_BIT ;
check if BLUE_ACTIVE_ZONE_BIT is set
GOTO LED_BLUE_ACTIVE_ZONE ; if set, go to
LED_BLUE_ACTIVE_ZONE
BTFSC LED_TYPE,
ACTIVE_ZONE_OFF_BIT ; check if
ACTIVE_ZONE_OFF_BIT
GOTO LED_ACTIVE_ZONE_OFF ; if set, go to
LED_ACTIVE_ZONE_OFF
GOTO RESTORE_REGISTERS ; exit interrupt
service routine
SET_PLAY_STATUS:
BTFSC LED_TYPE, IBUTTON_READ_BIT ; check if IBUTTON_READ_BIT is set
GOTO LED_IBUTTON_READ ; if set, go to
LED_IBUTTON_READ
BTFSC LED_TYPE, BOAT_MATCHED_BIT ; check if BOAT_MATCHED_BIT is set
GOTO LED_BOAT_MATCHED ; if set, go to
LED_BOAT_MATCHEd
BTFSC LED_TYPE, PLAYING_GAME_BIT ; check if PLAYING_GAME_BIT is set
GOTO LED_PLAYING_GAME ; if set, go to
LED_PLAYING_GAME
BTFSC LED_TYPE, STAND_DOWN_BIT ; check if STAND_DOWN_BIT is set
GOTO LED_STAND_DOWN ; if
set, go to LED_STAND_DOWN
BTFSC LED_TYPE, STATUS_OFF_BIT ; check if STATUS_OFF_BIT is set
GOTO LED_PLAY_STATUS_OFF ; if set, go to
LED_PLAY_STATUS_OFF
BTFSC LED_TYPE, BOAT_OFF_BIT ; check if BOAT_OFF_BIT is set
GOTO LED_BOAT_OFF ; if set, go
to LED_BOAT_OFF
GOTO RESTORE_REGISTERS ; exit interrupt
service routine
; turn
iButton Read LED on
LED_IBUTTON_READ:
BANKSEL PORTC
BCF PORTC, BOAT_MATCHED_LED_BIT
NOP
NOP
NOP
BSF PORTC,
IBUTTON_READ_LED_BIT
GOTO RESTORE_REGISTERS ; exit interrupt
service routine
; turn Boat
Matched LED on
LED_BOAT_MATCHED:
BANKSEL PORTC
NOP
NOP
BSF PORTC,
BOAT_MATCHED_LED_BIT
GOTO RESTORE_REGISTERS
; turn
Playing game LED on
LED_PLAYING_GAME:
BANKSEL PORTC
NOP
NOP
BSF PORTC,
PLAYING_GAME_LED_BIT
GOTO RESTORE_REGISTERS
; turn Stand
Down LED on
LED_STAND_DOWN:
BANKSEL PORTC
NOP
NOP
BSF PORTC,
STAND_DOWN_LED_BIT
GOTO RESTORE_REGISTERS
; turn Boat 8
LED on
LED_BOAT8:
BANKSEL PORTC
NOP
BSF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
GOTO RESTORE_REGISTERS
; turn Boat 7
LED on
LED_BOAT7:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BSF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
GOTO RESTORE_REGISTERS
; turn Boat 6
LED on
LED_BOAT6:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BSF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
GOTO RESTORE_REGISTERS
; turn Boat 5
LED on
LED_BOAT5:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BSF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
GOTO RESTORE_REGISTERS
; turn Boat 4
LED on
LED_BOAT4:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BSF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
GOTO RESTORE_REGISTERS
; turn Boat 3
LED on
LED_BOAT3:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BSF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
GOTO RESTORE_REGISTERS
; turn Boat 2
LED on
LED_BOAT2:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BSF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
GOTO RESTORE_REGISTERS
; turn Boat 1
LED on
LED_BOAT1:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BSF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
GOTO RESTORE_REGISTERS
; turn Boat
12 LED on
LED_BOAT12:
BANKSEL PORTC
NOP
BSF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
GOTO RESTORE_REGISTERS
; turn Boat
11 LED on
LED_BOAT11:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BSF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
GOTO RESTORE_REGISTERS
; turn Boat
10 LED on
LED_BOAT10:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BSF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
GOTO RESTORE_REGISTERS
; turn Boat 9
LED on
LED_BOAT9:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BSF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
GOTO RESTORE_REGISTELRS
; turn Red
Team LED on
LED_RED_TEAM:
BANKSEL PORTB
NOP
BCF PORTB, BLUE_TEAM_BIT_B6
NOP
BSF PORTB, RED_TEAM_BIT_B4
GOTO RESTORE_REGISTERS
; turn Blue
Team LED on
LED_BLUE_TEAM:
BANKSEL PORTB
NOP
BCF PORTB, RED_TEAM_BIT_B4
NOP
BSF PORTB,
BLUE_TEAM_BIT_B6
GOTO RESTORE_REGISTERS
; turn Red
Active Zone LED on
LED_RED_ACTIVE_ZONE:
BANKSEL PORTA
;CLRF PORTA
NOP
BCF PORTA, BLUE_ZONE_BIT_A1
NOP
BSF PORTA, RED_ZONE_BIT_A0
GOTO RESTORE_REGISTERS
; turn Blue
Active Zone LED on
LED_BLUE_ACTIVE_ZONE:
BANKSEL PORTA
BCF PORTA, RED_ZONE_BIT_A0
;CLRF PORTA
NOP
BSF PORTA, BLUE_ZONE_BIT_A1
GOTO RESTORE_REGISTERS
; turn all of
play status LEDs off
LED_PLAY_STATUS_OFF:
BANKSEL PORTC
CLRF PORTC
GOTO RESTORE_REGISTERS
; turn all of
Team LEDs off
LED_TEAM_OFF:
BANKSEL PORTB
CLRF PORTB
GOTO RESTORE_REGISTERS
; turn all of
Active Zone LEDs off
LED_ACTIVE_ZONE_OFF:
BANKSEL PORTA
CLRF PORTA
GOTO RESTORE_REGISTERS
; turn all of
Boat Number LEDs off
LED_BOAT_OFF:
BANKSEL PORTC
NOP
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR1
CALL CLOCK_PULSE_SR1
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
BCF PORTC, DATA_LINE_SR2
CALL CLOCK_PULSE_SR2
GOTO RESTORE_REGISTERS
CLEAR_OVERRUN_ERROR:
BCF RCSTA, CREN ;
disable receive
NOP
BSF RCSTA, CREN ;
re-enable receive to clear the overrun error
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
;---------------------------------------------RX
Jump Table---------------------------------------------------------;
; 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
; save type
of command
Case1:
BANKSEL PORTA ;
select the bank containing PORTA
INCF RECEIVE_BYTE_COUNT, F
MOVF DATA_RECEIVED, W
MOVWF COMMAND_TYPE
RETURN
; save
command
Case2:
BANKSEL PORTA ;
select the bank containing PORTA
INCF RECEIVE_BYTE_COUNT, F
MOVF DATA_RECEIVED, W
MOVWF LED_TYPE
CLRF RECEIVE_BYTE_COUNT
RETURN
Error_Detected:
BANKSEL PORTA ;
select the bank containing PORTA
CLRF RECEIVE_BYTE_COUNT
RETURN
END