Jump To:

            HELM:           

Communications                Program Flow            Pseudocode              Code Listing

                        Control Inputs                                                         Pseudocode              Code Listing

                        Display                                                                      Pseudocode              Code Listing

            CRAFT:

                                    Communications                Program Flow            Pseudocode              Code Listing

                        Propeller / Pump                                                     Pseudocode              Code Listing

                        Rudder / Turret                                                       Pseudocode              Code Listing

OTHER:

                        iButton                                                                      Pseudocode              Code Listing

                        SPIMaster example                                                Pseudocode              Code Listing

 

 

 

Brief explanation of each module’s purpose:

 

Helm Communication – Handles game state machine and helm communication with admiral. Acquires user inputs via SPI from the Control Input Board. Sends navigation commands to Craft Com Board.

 

Helm Control Inputs -  Runs A->D on analog inputs. Aggregates all user inputs and sends them over SPI to Helm Com Board.

 

Helm Display-  Writes out appropriate numbers to a shift register in order to indicate controlling boat number, team affiliation, and active base. This code is implemented on the Com PIC and runs inside the Helm Communication module.

 

Craft Communications-  Handles game state machine and craft communication with admiral. Relays navigation commands received from helm and transmits them by SPI to the Acutator Control Board.

 

Craft Prop/Pump-  One of two PICs on the Actuator Control Board. Receives SPI commands from the Craft Com Board. Accordingly sets the propeller direction and PWM and the pump PWM.

 

Craft Rudder/Turret-  One of two PICs on the Actuator Control Board. Receives SPI commands from the Craft Com Board. Accordingly sets the servo pulse width for the rudder and runs the stepper motor for the turret.

 

iButton-  This code is placed in both Com Boards to read an iButton and populate three data registers with the serial number of the iButton.

 

SPIMaster-  This code is used to test any other module that receives SPI as a Slave. Writes out known values to its slave.

 

 

Back to Top!

 

------------------------------------------------------------------------------------------------------------------------------------------------------------

Helm Program Flow

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Back to Top!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Helm Communication PIC Pseudocode

;variables

bytes_to_ignore equ 0x22   ;to store the address information received

message_received equ 0x23  ;to store the data received

message_to_send equ 0x24  ;to store the data to send

RFdata0_received equ 0x25   ;to store the data received

RFdata1_received equ 0x26   ;to store the data received  

RFdata2_received equ 0x27   ;to store the data received

RFdata0_to_send equ 0x28   ;to store the data to_send

RFdata1_to_send equ 0x29   ;to store the data to_send  

RFdata2_to_send equ 0x2A   ;to store the data to_send

Source_Address_First equ 0x2B ;the most significant byte to address

Source_Address_Second equ 0x2C ;the least significant byte to address

Destination_Address_First equ 0x2D ;the most significant byte to address

Destination_Address_Second equ 0x2E ;the least significant byte to address 

ten_sec_timer_CNT1 equ 0x2F

ten_sec_timer_CNT2 equ 0x30  ;CNT1 * CNT2 = total count

#define ten_sec_timer_PER1 0x26  ;=38

#define ten_sec_timer_PER2 0x0A  ;=10  ;total target count = 38*10 = 380

ten_sec_TimeUp equ 0x31  ;the flag to indicate that 10s time is up, when = 0xff 

Goal_Color equ 0x32; bit 6,7 indicate which base is active, the other bits are 0 

temp equ 0x33; temporary space to store intermediate data

sum equ 0x34   ;to store the sum value

check_sum equ 0x35    ; to store the check sum value 

MyBoatAddress equ 0x36  ;to store the least significant byte of paired boat address

GameState equ 0x37  ;game state 

W_TEMP equ 0x70     ; to store w value for interrupts return

STATUS_TEMP equ 0x71  ; to store STATUS value for interrupts return 

ReceiveIndex equ 0x3F ;the index to indicate where I am in the 11 byte frame

#define RX_START 0x40 ;Location of first byte received

;all addresses in between are used

#define RX_END 0x4B ;Location of last byte received 

COUNTER equ 0x60

COUNTER2 equ 0x61 

Navi equ 0x63

Speci equ 0x64 

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

;;;;;;;;;;;;i-buttom variables and #defines;;;;;;;;;;;;;;;;;;;;

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

#define IBUTTON_PORT  PORTA

#define IBUTTON_PIN    0

#define TRISIBUTTON    TRISA 

#define IBUTTON_INPUT  0x01

#define IBUTTON_OUTPUT  0x00

#define IBUTTON_HI   0x01

#define IBUTTON_LO   0x00 

FIRST_BYTE  equ    0x66

SECOND_BYTE  equ    0x67

THIRD_BYTE  equ    0x68

TEMP   equ    0x69

SECOND_BYTE_CHECK  equ    0x6A

THIRD_BYTE_CHECK  equ    0x6B 
 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;variables and #defines for team display on helm;;;;;;;;;;;;;;;;

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

#define SHIFT_PORT PORTC

#define SHIFT_DATA_BIT 3

#define SHIFT_CLOCK_BIT 4 
 

CRAFT_NUMBER equ  0x6C

CRAFT_TEAM  equ  0x6D ; bit 0 high for red, low for blue - can be taken from somewhere else later 

#define TENS_BIT 4 ;bit in assembled bytethat controls the tens place on the display

#define RED_TEAM_BIT 5 ;bit in assembled byte to indicate blue team

#define BLUE_TEAM_BIT 6 ;bit in assembled byte to indicate red team

ASSEMBLED_BYTE equ  0x6E ;byte to shift out 
 
 

org 0

goto Main

org 4

goto ISR

org 5 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;program starts;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

Interrupt service routine:

ISR:

      Save current w register value

      Save current STATUS register value 

      Check if the interrupt is caused by SCI or Timer0 overflow

      If (caused by SCI), use RF data process service routine

      If (caused by Timer0), use 10 sec timer process service routine 
 

RF receive interrupt service routine:

      store the received RF data in the proper place of array in RAM

      Load ReceiveIndex to FSR

      movwf FSR 

      Read data from RCREG, store the data in INDF(address is determined by the value of ReceiveIndex) 

      Test if the data received is the start byte

      If yes, ReceiveIndex = RAM place for second RF byte

      Else increase ReceiveIndex

      If ReceiveIndex = RAM place for last RF byte, ReceiveIndex = RAM place for first RF byte 

End of RF receive interrupt service routine 
 
 

timer0 interrupt service routine, for 10 sec time out:

      increase three_sec_timer_CNT 

      if ten_sec_timer_CNT1 = 38:

            clear ten_sec_timer_CNT1

            increase ten_sec_timer_CNT2

      endif 

      if ten_sec_timer_CNT2 = 10:

            clear ten_sec_timer_CNT2

            write 0xff to ten_sec_TimeUp, indicating a 10 sec time up

      endif 

      clear TIMER0 overflow flag

End of timer0 interrupt service routine 
 

      Restore the value of STATUS register

      Restore the value of w register

      Return from interrupt

End of INT function 
 

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

Function to move address and data information into variables:

Get_Data_Function:

      Save the most significant byte of the sender’s address in variable Source_Address_First

      Save the least significant byte of the sender’s address in variable Source_Address_Second

      Save the first byte of the 3 bytes of real data in variable RFdata0_received

      Save the second byte of the 3 bytes of real data in variable RFdata1_received

      Save the third byte of the 3 bytes of real data in variable RFdata2_received 

Return

End of Get_Data_Function 

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

Function to erase address and data information

once this function is called, all 0s will be returned from Get_data_function, unless there has been another RF transmission received

Erase_Data_Function:

      Write all 0’s to the RF data recording array in RAM

Return

End of Erase_Data_Function 
 

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

initialization function

Init:

initilize variables:

      set the value of ReceiveIndex to point to where the starting byte of RF frame is stored 

initialize timer 1, use internal oscillator by default

      set timer 1 prescale to be 1:8

      turn on timer 1 

set port CCP1 for output compare 

initialize timer 2, for output compare

      set prescale and postscale of timer2 to be 16, and turn on timer2 

set port A, B, C as non-analog pins

set port A, B, C as non-analog pins 

set RC6 as output to do slave select

set RC7 for SPI output

RC0 is general input, for determine whether the data received from control pannel is Navigation or Special Function byte

set RB6 as output for SPI clock

set RB4 as input for SPI in

;RC1, RC2 are outputs to show active base on the helm

;RC3, RC4 are Outputs to the shift register to do the taem number and team color display on the helm

set PA0 as input for i-buttom reading 
 
 

initiate SCI:

      set baud rate to be 9600:

      BRGH=0

      Use asynchronous communication

      BRG16 ;BRG16=1

      SPBRG = 64

      baud rate = 9615

      enable SPI transmission

      enable serial port

      enable SPI receiving 

initiate SPI:

      setting timer2:

      TMR2 freq = Fosc/64/49

 turn on timer2, prescaler 1:16, post scaler 1:1

SMP = 0, CKE = 0

      SSPEN, CKP=1, CLK freq = TMR2 output/2

      Clear SPI receive register full falg

      select drive-pump control PIC

      send out boat stop signal to the PIC controlling the actuators

      Clear SPI Receive Register:  

interrupts enables:

      enable gloable interrupt enable

      enable peripheral interrupt enable

      enable SCI receive interrupt 

goal color LEDs both off

return

End of function initialization 
 
 
 

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

data transmit function

Transmit_Function:

      check timer, ensure that this transmit is more than 200ms later than last one 

      send start byte, wait for transmission over by calling wait_for_transmssion_over 

      send LENGTH_MSB, wait for transmission over 

      send LENGTH_LSB, wait for transmission over 

      send API_TX, wait for transmission over 

      send FRAME_ID, wait for transmission over 

      send Destination_Address_First, wait for transmission over 

      send Destination_Address_Second, wait for transmission over 

      send 0x01 for the option byte, wait for transmission over 

      send RFdata0_to_send, wait for transmission over 

      send RFdata1_to_send, wait for transmission over 

      send RFdata1_to_send, wait for transmission over 

      calculate check sum value 

      send check sum value, wait for transmission over 

      clear timer 1 flag

return

end of Transmit_Function 
 

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

the function to wait until the trasmit shift register of PIC is empty

wait_for_transmssion_over:

      keep reading TRMT flag in TXSTA, until it is set

return

end of function wait_for_transmssion_over 

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

data transmit function without waiting for 200 ms after last transmission

No_Wait_Transmit_Function:

      send start byte, wait for transmission over by calling wait_for_transmssion_over 

      send LENGTH_MSB, wait for transmission over 

      send LENGTH_LSB, wait for transmission over 

      send API_TX, wait for transmission over 

      send FRAME_ID, wait for transmission over 

      send Destination_Address_First, wait for transmission over 

      send Destination_Address_Second, wait for transmission over 

      send 0x01 for the option byte, wait for transmission over 

      send RFdata0_to_send, wait for transmission over 

      send RFdata1_to_send, wait for transmission over 

      send RFdata1_to_send, wait for transmission over 

      calculate check sum value 

      send check sum value, wait for transmission over

return

end of Transmit_Function 
 

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

;;;;;;;;;;;;;;;;;;;;;;i-buttom functions;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

End of i-buttom functions 

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

;;;;;;;;;;;;;;Functions to display team NO and clor on helm;;;;;;;;;;;;

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

End of Functions to display team NO and clor on helm 
 
 

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

;;;;;Game Control Function;;;;;;;

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

the master game control function of the helm:

Game_Control:

      Check the value of GameState

      Case WaitForIbuttom, use Wait_For_Ibuttom_State service 

      Case WaitForSync, use Wait_For_Sync_State service 

      Case WaitForGame, use Wait_For_Game_State service 

      Case Game, use Game_State service 

      Case HardReset, use Hard_Reset_State service 

      Case BoatStandDown, use Boat_Stand_Down_State service 

      Case EndGame, use End_Game_State service

return 
 

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

;;;;;Game State Functions;;;;;;;

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

the wait for ibuttom state

Wait_For_Ibuttom_State:

      Keep waiting for first ibuttom read in, store the first i-buttom reading also in another place for later comparison 

      Keep waiting for second ibuttom read in 

      Keep waiting for third ibuttom read in 

      If the three times get the same value, and the value is neither 0xff nor 0x00, store ibuttom data, return from this function 

      Else go back to the start of this function

End of Wait_For_Ibuttom_State 

Once read i-buttom, broadcast i-buttom, until sense a match from my boat

Wait_For_Sync_State:

      broadcast i-buttom signal 

      call Get_Data_Function  

      check the value of RFdata0_received:

      if WATERCRAFT, goto respond_boat

      if ADMIRAL, goto respond_admiral

return 

respond_boat:

      check if the signal from the boat is a matched signal:

      if yes, record the boat’s address in MyBoatAddress 

      display team number and color on the helm:

      write the value of MyBoatAddress in CRAFT_NUMBER

      write the value of SECOND_BYTE in CRAFT_TEAM

      call  TRANSLATE ;takes craft number in binary (lower nibble) translates to 5 bits for BCD  

      call ADD_TEAM ;adds team affiliation to assembled byte

      call SHIFT_BYTE ;shift byte out on C0-1 

      set GameState to be WaitForGame

end of respond_boat 

respond_admiral:

      check if the signal is a ping request

      if yes, call Ping_Respond_Function

      call Erase_Data_Function

return

End of Wait_For_Sync_State 
 

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

Wait_For_Game_State: 

      check is there is Ping, StartGame command from admiral or i-buttom matched signal from my boat:

      call check_signal

      call StopBoat

return 

check_signal:

      call Get_Data_Function

      check if the signal is from admiral

      if yes, goto ping_or_startgame  ;if from admiral, it could be ping or start game command

return 

ping_or_startgame:

      check if the signal is for game start

      if yes, goto case_start_game, which will then change game state to 'game' 

      check if the signal is for ping

      if is for ping, then respond to the admiral

return 

case_start_game:

      first erase signal in array to avoid multiple acknowledgements

      call Erase_Data_Function

      acknowledge GAME_START to the admiral 

      change game state to 'game'

return

End of Wait_For_Game_State 

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

;general in-game state

Game_State:

      call Get_Data_Function 

      check if the signal is from boat

      if (is WATERCRAFT), call WaterCraft_Respond_Function function, else keep checking if it's other situation 

      check if the signal is from Admiral

      if (is Admiral), call Admiral function, else keep checking if it's other situation 

      call Boat_Control to send control signal through ZigBee to my boat

return

End of function Game_State 

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

End_Game_State:

almost everything is the same with in-game state, except Boat_Control will check the game state and decide wether to activate special functions

      call Game_State

return 

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

2 possible commands the helm is likely to receive and respond to: from watercraft and admiral

WaterCraft_Respond_Function:

      Check if the signal is STAND_DOWN_RECEIVED, if yes, goto case_BoatStandDown 

Else return from function 

case_BoatStandDown:

      clear the received RF data, so later I can check if there is a new transmission from my boat

      call Erase_Data_Function

      acknowledge to the boat 

      start timing for 10 sec, LEDs start flashing:

      call Turn_On_10s_Timer 

      change GameState to ‘BoatStandDown’

return 

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

Admiral_Function:

      check if the signal received is BLUE_GOAL, if yes, goto case_BLUE_GOAL 

      check if the signal received is RED_GOAL, if yes, goto case_RED_GOAL 

      check if the signal received is ADMIRAL_PING, if yes, goto case_admiral_ping 
 

      check if the signal received is HARD_RESET, if yes, goto case_hard_reset 

      check if the signal received is END_GAME, if yes, goto case_END_GAME

return 

case_BLUE_GOAL:

      light the blue LED:

      set bit 7 of Goal_Color

      clear bit 6 of Goal_Color

      set RC1

      clear RC2

return 

case_RED_GOAL

      light the red LED:

      set bit 6 of Goal_Color

      clear bit 7 of Goal_Color

      set RC2

      clear RC1

return 

case_HARD_RESET:

      change GameState to ‘HardReset’

return 

case_ADMIRAL_PING:

      call Erase_Data_Function

      call Ping_Respond_Function

return 

case_END_GAME

      call Erase_Data_Function

      acknowledge to the admiral

change GameState to ‘EndGame’

return

end of Admiral_Function 

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

get the command from control panel through SPI

send out navigation command to boat in 5Hz rate

decide wether to activate special function based on wether in Game state or End-Game state 

Boat_Control: 

      first check whether GameState is ‘Game’ of ‘EndGame’, if ‘Game’, activate spetial function, else deactivate 

      else stop the boat

return 

special_fun_on:

      get the command from the control panel by calling Get_Control_Sig

      send the control signal to Zigbee with special functions on

return 

special_fun_off:

      get the command from the control panel by calling Get_Control_Sig

      send the control signal to Zigbee with special functions off

return 
 

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

the function to get signal from the control pannel through SPI

Get_Control_Sig: 

Send Data through SPI, start SPI clock

Wait for receive complete

Get received data

Check the state of RC0 read in, if High, meaning this is navigation byte, goto Get_Navi

If low, meaning this is special function byte, goto Get_Speci 

Get_Navi:

      Store the received data from SPI in Navi

RETURN 
 

Get_Speci

      Store the received data from SPI in Speci

RETURN 
 

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

GameState_equ_ibuttom:

      Change GameState to ‘WaitForIbuttom’

return 

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

Boat_Stand_Down_State:

      call Get_Data_Function

      check if there is a new data from my boat:

      if not, goto Check_Timer, else check if the data is another STAND_DOWN_RECEIVED:

      if not goto Check_Timer, else clear the received RF data, so later I can check if there is a new transmission from my boat 

      if receive another STAND_DOWN_RECEIVED from my boat:

      call Erase_Data_Function

      acknowledge to the boat again

return 

Check_Timer:

      ;call StopBoat

      check 10 sec time up flag

      if time is not up, return from function

      if time up, call Turn_Off_10s_Timer, clear 10 sec timer flag, change GmeState to ‘Game’

return 
 

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

start to count for 10 seconds, when time up, ten_sec_TimeUp will change to 0xff

Turn_On_10s_Timer:

      start 10 sec timer:

      set the slowest option

      clear ten_sec_TimeUp

      clear ten_sec_timer_CNT1

      clear ten_sec_timer_CNT2

      enable timer0 interrupt

return 

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

stop timer, reset time up flag and counters

Turn_Off_10s_Timer:

      stop 10 sec timer

      turn off timer 0

      clear ten_sec_TimeUp

      clear ten_sec_timer_CNT1

      clear ten_sec_timer_CNT2

      disable timer0 interrupt

return 

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

Hard_Reset_State:

      call StopBoat to stop all actuators

      game state go back to waiting for i-buttom

return 

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

Ping_Respond_Function:

      Check GameState:

      Case WaitForIbuttom, respond accordinglyreturn

      Case WaitForSync, respond accordinglyreturn 

      Other Cases, respond accordinglyreturn

return  

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

Send out No_ACTION to boat in 5Hz rate

StopBoat:

      send 0x02, 0x88, 0x00 to my boat

return 

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

Main function

Main: 

Use some loops to delay for 16ms to wait for power up 

call Init 

initial game state to be ‘WaitForIbuttom’ 

Loop:

      call Game_Control

goto Loop 
 

END of program 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Helm Communication PIC Code Listing

                                             
list P=PIC16F690
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Protocol Rev C constants
; note: use of MSB and LSB implies Byte, not Bit in this.
; Rev A, Brian Hachtmann, May 09 2008
 
        ; 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:  change this to non-zero if you wish 
        ; your xBee to respond with a Tx Status message
#define        FRAME_ID                       0x00    
 
        ; Addresses
#define        ADMIRAL_ADDRESS_MSB    0xBC
#define        ADMIRAL_ADDRESS_LSB    0xFF
 
#define        HELM_MSB                       0xBC                   
#define        CRAFT_MSB                      0xAF
 
        ; for ME218C Data Byte 0 Header
#define        IBUTTON                0x01
#define        NAVIGATION                     0x02
#define        ADMIRAL                0x04
#define        WATERCRAFT                     0x08
#define        PING_RESPONSE          0x10
#define        ACK                            0x80
 
        ; Admiral Messages
#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_PING           0x80
 
        ; 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
 
        ; Ping Responses
#define WAITING_IBUTTON                       0x01
#define WAITING_PAIR                          0x02
#define PAIRED                                        0x04
 
        ;game states
#define WaitForIbuttom 0x01
#define WaitForSync 0x08
#define WaitForGame 0x02
#define Game 0x03
#define HardReset 0x04
#define BoatStandDown 0x05
#define Ping 0x06
#define EndGame 0x07
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
#include "p16F690.inc"
__config (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC)
 
;variables
bytes_to_ignore equ 0x22   ;to store the address information received
message_received equ 0x23  ;to store the data received
message_to_send equ 0x24  ;to store the data to send
RFdata0_received equ 0x25   ;to store the data received
RFdata1_received equ 0x26   ;to store the data received   
RFdata2_received equ 0x27   ;to store the data received 
RFdata0_to_send equ 0x28   ;to store the data to_send
RFdata1_to_send equ 0x29   ;to store the data to_send   
RFdata2_to_send equ 0x2A   ;to store the data to_send 
Source_Address_First equ 0x2B ;the most significant byte to address
Source_Address_Second equ 0x2C ;the least significant byte to address
Destination_Address_First equ 0x2D ;the most significant byte to address
Destination_Address_Second equ 0x2E ;the least significant byte to address
 
ten_sec_timer_CNT1 equ 0x2F
ten_sec_timer_CNT2 equ 0x30  ;CNT1 * CNT2 = total count
#define ten_sec_timer_PER1 0x26  ;=38
#define ten_sec_timer_PER2 0x0A  ;=10  ;total target count = 38*10 = 380
ten_sec_TimeUp equ 0x31  ;the flag to indicate that 10s time is up, when = 0xff
 
Goal_Color equ 0x32; bit 6,7 indicate which base is active, the other bits are 0
 
temp equ 0x33; temporary space to store intermediate data
sum equ 0x34   ;to store the sum value
check_sum equ 0x35    ; to store the check sum value
 
MyBoatAddress equ 0x36  ;to store the least significant byte of paired boat address
GameState equ 0x37  ;game state
 
W_TEMP equ 0x70     ; to store w value for interrupts return
STATUS_TEMP equ 0x71  ; to store STATUS value for interrupts return
 
ReceiveIndex   equ     0x3F    ;the index to indicate where I am in the 11 byte frame
#define RX_START       0x40    ;Location of first byte received
;all addresses in between are used
#define RX_END  0x4B    ;Location of last byte received
 
COUNTER equ 0x60
COUNTER2 equ 0x61
 
Navi equ 0x63
Speci equ 0x64
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;i-buttom variables and #defines;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
#define IBUTTON_PORT           PORTA
#define IBUTTON_PIN                           0
#define TRISIBUTTON                           TRISA
 
#define IBUTTON_INPUT          0x01
#define IBUTTON_OUTPUT         0x00
#define IBUTTON_HI                    0x01
#define IBUTTON_LO                    0x00
 
FIRST_BYTE             equ                            0x66
SECOND_BYTE            equ                            0x67
THIRD_BYTE             equ                            0x68
TEMP                   equ                            0x69
SECOND_BYTE_CHECK              equ                            0x6A
THIRD_BYTE_CHECK               equ                            0x6B
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;variables and #defines for team display on helm;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
#define SHIFT_PORT PORTC
#define SHIFT_DATA_BIT 3
#define SHIFT_CLOCK_BIT 4
 
 
CRAFT_NUMBER   equ            0x6C 
CRAFT_TEAM             equ            0x6D    ; bit 0 high for red, low for blue - can be taken from somewhere else later
 
#define TENS_BIT 4     ;bit in assembled bytethat controls the tens place on the display
#define RED_TEAM_BIT 5 ;bit in assembled byte to indicate blue team
#define BLUE_TEAM_BIT 6        ;bit in assembled byte to indicate red team
ASSEMBLED_BYTE equ            0x6E    ;byte to shift out
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;program starts;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
org 0
goto Main
org 4
goto ISR
org 5
 
;interrupt service routine
ISR: ;push
        movwf W_TEMP
        swapf STATUS, w
        movwf STATUS_TEMP
 
;test is RF receive interrupt
        banksel PIR1   ;bank 0
        btfsc PIR1, RCIF
        goto RF_Receive_INT
;test if timer0 interrupt
        btfsc INTCON, T0IF
        goto Timer_INT
;else jump out of interrupt
        goto end_of_INT
 
;RF receive interrupt service routine
RF_Receive_INT:
banksel RCREG  ;go to bank 0
 
        movf    ReceiveIndex,W ;Load ReceiveIndex to FSR
        movwf   FSR     
 
        banksel        RCREG
        movf    RCREG,W ;Read data to W
 
        movwf   INDF    ;Store data in proper place
;       sublw   START_BYTE
;       btfss   STATUS,Z       ;Test for a start byte                
;       goto    end_of_INT
        call    IncReceive     ;Already in bank 0
        goto    end_of_INT
 
;
;       Increments the ReceiveIndex variable to the next valid memory location
;
 
IncReceive:    
        banksel        RCREG
        movf    ReceiveIndex,W ;Test to see if index is at the end of
        sublw   RX_END  ;receive registers
        btfsc   STATUS,Z       ;If it is, load RX_START-1 into receive index
        call    CarryReceive
        incf    ReceiveIndex,F ;If index is not at end, increment receive index
 
        return
 
;
;       Called when Receive Index needs to be reset
;
 
CarryReceive:
        movlw   RX_START-1
        movwf   ReceiveIndex
        return
 
;timer0 interrupt service routine
Timer_INT:
;toggle RC1 for debug
        banksel PORTC
        movf PORTC, w
        xorlw b'00000010'
        movwf PORTC
        
        BANKSEL ten_sec_timer_CNT1
        INCF ten_sec_timer_CNT1, f
        MOVF ten_sec_timer_CNT1,W      
        SUBLW ten_sec_timer_PER1
        BTFSS STATUS,Z                                                                      
        goto end_of_timer0_INT 
 
        banksel PORTC
        movf PORTC, w
        xorlw b'00000100'
        movwf PORTC            
                       
        CLRF ten_sec_timer_CNT1
 
        INCF ten_sec_timer_CNT2, f
        MOVF ten_sec_timer_CNT2,W      
        SUBLW ten_sec_timer_PER2
        BTFSS STATUS,Z                                                                       
        goto end_of_timer0_INT                
 
;if ten_sec_timer_CNT1 = 38 and ten_sec_timer_CNT2 = 10:                    
        CLRF ten_sec_timer_CNT2
        movlw 0xFF
        movwf ten_sec_TimeUp  ;set this value so the main program know that 10-second time is up
        
end_of_timer0_INT:
;clear TIMER0 flag
        bcf INTCON, T0IF
        goto end_of_INT
        
end_of_INT:
 
        swapf STATUS_TEMP, w
        movwf STATUS
        swapf W_TEMP, f
        swapf W_TEMP, w
        RETFIE
;end of INT function
 
;function to move address and data infromation into variables
Get_Data_Function:
        banksel RCREG  ;bank 0
        movlw 0x44
        movwf   FSR
        movf    INDF,W
        movwf Source_Address_First
 
        movlw 0x45
        movwf   FSR
        movf    INDF,W
        movwf Source_Address_Second
 
        movlw 0x48
        movwf   FSR
        movf    INDF,W
        movwf RFdata0_received
 
        movlw 0x49
        movwf   FSR
        movf    INDF,W
        movwf RFdata1_received
 
        movlw 0x4A
        movwf   FSR
        movf    INDF,W
        movwf RFdata2_received
return
 
;function to erase address and data infromation
;once this function is called, all 0s will be returned from Get_data_function, unless there has been another transmission
Erase_Data_Function:
        banksel RCREG  ;bank 0
        movlw 0x44
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        movlw 0x45
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        movlw 0x48
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        movlw 0x49
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        movlw 0x4A
        movwf   FSR
        movlw 0x00
        movwf INDF
return
 
;initialization function
Init:
;init variables:
banksel RCREG  ;bank 0
movlw   RX_START
movwf   ReceiveIndex
 
;initialize timer 1, use internal oscillator by default
BSF T1CON, T1CKPS0   ;set timer 1 prescale to be 1:8
BSF T1CON, T1CKPS1
BSF T1CON, TMR1ON    ;turn on timer 1
 
BcF CCP1CON, CCP1M0  ;set port CCP1 for output compare
BsF CCP1CON, CCP1M1
BcF CCP1CON, CCP1M2
BsF CCP1CON, CCP1M3
 
;initialize timer 2, for output compare
movlw b'11111111'
movwf T2CON  ;set prescale and postscale of timer2 to be 16, and turn on timer2
 
;Pin initialization
;go to bank 2
BCF STATUS, 5
BSF STATUS, 6  
clrf ANSEL    ;set port A, B, C as non-analog pins
clrf ANSELH   ;set port A, B, C as non-analog pins
 
;go to bank 1
BSF STATUS, 5
BCF STATUS, 6 
;set RC6 as output to do slave select
;set RC7 for SPI output
;RC5 is input capture for transmitting start
;RC0 is general input, for determine whether the data received from control pannel is Navigation or Special Function byte
;RC1, RC2 are outputs to show active base on the helm
;RC3, RC4 are Outputs to the shift register to do the taem number and team color display on the helm
MOVLW b'00100001'
MOVWF TRISC 
;set RB6 as output for SPI clock
bcf TRISB, 6
;set RB4 as input for SPI in
bsf TRISB, 4
 
;set PA0 as input for i-buttom reading
BSF TRISA, 0
;set PA1, PA2 as input, not used for now
BSF TRISA, 1
BSF TRISA, 2
 
 
;initiate SCI:
;currently in bank 1
;set baud rate to be 9600:
bcf TXSTA, BRGH  ;BRGH=0
bcf TXSTA, SYNC  ;asynchronous
bsf BAUDCTL, BRG16 ;BRG16=1
;caution! change this back to 0x40 when move the PIC to the Helm Xbee Board
movlw 0x40 ;SPBRG = 64
movwf SPBRG  ;baud rate = 9615
 
bsf TXSTA, TXEN ;enable transmission
 
;go to bank 0
BCF STATUS, 5
BCF STATUS, 6  
 
bsf RCSTA, SPEN  ;enable serial port
bsf RCSTA, CREN  ;enable receiving
 
;initiate SPI: ;not used for now, the setting is suitable for 10MHz crystal
;setting timer2:
banksel PR2
movlw 0x30   ;TMR2 freq = Fosc/64/49    ;change back to 30 later!
movwf PR2
banksel T2CON
movlw b'00000111' ;turn on timer2, prescaler 1:16, post scaler 1:1
movwf T2CON
 
                               BANKSEL                SSPSTAT
                               CLRF                   SSPSTAT                ;SMP = 0, CKE = 0
 
                               BANKSEL                SSPCON
                               MOVLW                  0x33                   ;SSPEN, CKP=1, CLK freq = TMR2 output/2
                               MOVWF                  SSPCON
 
                               BANKSEL                PIR1
                               BCF                            PIR1,SSPIF
;go back to bank 0
                               BANKSEL                SSPBUF
 
                               MOVF                   SSPBUF,w         ;receive and transmit OFF for the first time
                               MOVLW                  0xFF
                               MOVWF                  SSPBUF
 
ClearReceiveReg:       
        BANKSEL RCREG   ; Make sure that the receive register is clear
        MOVF    RCREG,W
        BANKSEL PIR1
        BTFSC   PIR1,RCIF
        GOTO    ClearReceiveReg
                               
;interrupts enables
banksel INTCON
bsf INTCON, GIE  ;enable gloable interrupt enable
bsf INTCON, PEIE  ;enable peripheral interrupt enable
banksel PIE1
bsf PIE1, RCIE  ;enable SCI receive interrupt
banksel TXREG ;go back to bank 0
;PORTC output 0 upon initialization
movlw 0x00
movwf PORTC
;clear Goal_Color
movlw 0x00
movwf Goal_Color
 
return
;end of function initialization
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;data transmit function
Transmit_Function:
        banksel RCREG ;bank 0
 
back3:
        btfss PIR1, TMR1IF  ;check timer, ensure that this transmit is more than 200ms later than last one
        goto back3
 
;send start byte
        movlw START_BYTE
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw LENGTH_MSB
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw LENGTH_LSB
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw API_TX
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw FRAME_ID
        movwf TXREG
        call wait_for_transmssion_over
 
        movf Destination_Address_First, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf Destination_Address_Second, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw 0x01   ;0x01 for the option byte, to not request acknowledgement
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata0_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata1_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata2_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
;calculate check sum value
        movlw 0x00
        movwf sum
        movlw API_TX
        addwf sum, f
        movlw FRAME_ID
        addwf sum, f
        movf Destination_Address_First, w
        addwf sum, f
        movf Destination_Address_Second, w
        addwf sum, f
        movlw 0x01
        addwf sum, f
        movf RFdata0_to_send, w
        addwf sum, f
        movf RFdata1_to_send, w
        addwf sum, f
        movf RFdata2_to_send, w
        addwf sum, f
;check_sum = 0xff - sum
        movf sum, w
        sublw 0xff
        movwf check_sum
        
        movf check_sum, w
        movwf TXREG
        call wait_for_transmssion_over
 
        bcf PIR1, TMR1IF   ;clear timer 1 flag
return
 
;the function to wait until the trasmit shift register of PIC is empty
wait_for_transmssion_over:
;goto bank 1
        BSF STATUS, 5
        BCF STATUS, 6 
 
wait_transmssion:
        btfsc TXSTA, TRMT
        goto end_of_wait_transmssion
        goto wait_transmssion
 
end_of_wait_transmssion:
;go back to bank 0
        BCF STATUS, 5
        BCF STATUS, 6 
return
;end of function wait_for_transmssion_over
 
No_Wait_Transmit_Function:
        banksel RCREG ;bank 0
 
;send start byte
        movlw START_BYTE
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw LENGTH_MSB
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw LENGTH_LSB
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw API_TX
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw FRAME_ID
        movwf TXREG
        call wait_for_transmssion_over
 
        movf Destination_Address_First, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf Destination_Address_Second, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw 0x01   ;0x01 for the option byte, to not request acknowledgement
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata0_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata1_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata2_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
;calculate check sum value
        movlw 0x00
        movwf sum
        movlw API_TX
        addwf sum, f
        movlw FRAME_ID
        addwf sum, f
        movf Destination_Address_First, w
        addwf sum, f
        movf Destination_Address_Second, w
        addwf sum, f
        movlw 0x01
        addwf sum, f
        movf RFdata0_to_send, w
        addwf sum, f
        movf RFdata1_to_send, w
        addwf sum, f
        movf RFdata2_to_send, w
        addwf sum, f
;check_sum = 0xff - sum
        movf sum, w
        sublw 0xff
        movwf check_sum
        
        movf check_sum, w
        movwf TXREG
        call wait_for_transmssion_over
 
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;i-buttom functions;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
LoadIButtonBytes:
                ; Set Ports A and C to digital
                BANKSEL         ANSEL
                CLRF            ANSEL
                               CLRF                   ANSELH
 
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
WaitForIButton:
                               ;CALL                  MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
                               
                               ;CALL                  LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Compensated_Wait500us
;;;;;;;;;;;;;;;code add by me to do admiral ping response;;;;;;;;;;;;;;;;;;;;;;
;the following code takes 15us to execute for 10MHz Crystal
        call Get_Data_Function
        movf RFdata0_received, w
        sublw ADMIRAL   ;check if the Header Data is for Admiral
        ;if (is Admiral), call Admiral function, else keep checking if it's other situation
        btfss STATUS, Z
goto No_ping
        
 
        movf RFdata2_received, w
        sublw ADMIRAL_PING ;check if the Header Data is for ADMIRAL_PING
        ;if (is ADMIRAL_PING), change game state
        btfsc STATUS, Z
goto No_ping
        call Erase_Data_Function
        call Ping_Respond_Function ;erase get_data value at the meantime
 
No_ping:
;;;;;;;;;;;;;;;code add by me to do admiral ping response;;;;;;;;;;;;;;;;;;;;;;
 
                               ;CALL                  MakeIBUTTONInput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_INPUT
                               MOVWF                  TRISIBUTTON
                               CALL                   Wait50us
 
                               ; Check if pin is LO --> iButton Present
                               BANKSEL                IBUTTON_PORT
                               BTFSC                  IBUTTON_PORT,IBUTTON_PIN
                               GOTO                   WaitForIButton ;Repeat until found
                               
                               ;Once found then:              
                               CALL                   ConductReset
                               
                               CALL                   ReadROM 
 
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               
                               BANKSEL                THIRD_BYTE
                               MOVF                   THIRD_BYTE,0
                               MOVWF                  FIRST_BYTE
 
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                              CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               
                               BANKSEL                THIRD_BYTE
                               MOVF                   THIRD_BYTE,0
                               MOVWF                  SECOND_BYTE
 
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
 
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
 
                               return
 
 
ConductReset:
;                              CALL                   MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
;                              CALL                   LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait500us
;                              CALL                   RaiseIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BSF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait500us
                               RETURN
 
ReadROM:
; Send ReadROM command
; Need to send 0x33 = 00110011, LSB first
                               CALL                   SendIBUTTONHI
                               CALL                   SendIBUTTONHI
                               CALL                   SendIBUTTONLO
                               CALL                   SendIBUTTONLO
                               CALL                   SendIBUTTONHI
                               CALL                   SendIBUTTONHI
                               CALL                   SendIBUTTONLO
                               CALL                   SendIBUTTONLO
                               RETURN
 
ReadBit:
; Begin reading
;                              CALL                   MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
;                              CALL                   LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait5us
 
;                              CALL                   MakeIBUTTONInput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_INPUT
                               MOVWF                  TRISIBUTTON
 
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               
                               BANKSEL                IBUTTON_PORT
                               BTFSC                  IBUTTON_PORT,IBUTTON_PIN
                               GOTO                   RECEIVE_BIT_HI
                               GOTO                   RECEIVE_BIT_LO
RECEIVE_BIT_HI:
                               BANKSEL                THIRD_BYTE
                               RRF                            THIRD_BYTE,1
                               NOP
                               NOP
                               BSF                            THIRD_BYTE,7
                               CALL                   Wait60us
                               RETURN
 
RECEIVE_BIT_LO:
                               BANKSEL                THIRD_BYTE
                               RRF                            THIRD_BYTE,1
                               NOP
                               NOP
                               BCF                            THIRD_BYTE,7
                               CALL                   Wait50us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               RETURN
 
 
 
SendIBUTTONHI:
;                              CALL                   MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
;                              CALL                   LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait5us
 
;                              CALL                   MakeIBUTTONInput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_INPUT
                               MOVWF                  TRISIBUTTON
 
                               CALL                   Wait70us
 
                               RETURN
 
SendIBUTTONLO:
;                              CALL                   MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
;                              CALL                   LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait60us
 
;                              CALL                   MakeIBUTTONInput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_INPUT
                               MOVWF                  TRISIBUTTON
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               RETURN         
 
Wait5us:
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
                               RETURN
 
Wait1s:
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
 
 
        
 
Wait500us:
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               RETURN
 
Compensated_Wait500us:
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait5us
                               ;CALL                  Wait5us
                               ;CALL                  Wait5us
                               ;CALL                  Wait5us
                               RETURN
 
Wait50us:
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
 
                               RETURN
 
Wait70us:
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               NOP
                               NOP
                               NOP
                               NOP
 
                               RETURN
 
Wait60us:
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               CALL                   Wait5us
                               
                               RETURN
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;Functions to display team NO and clor on helm;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TRANSLATE:
;if value <10, convert to c0-3, C4 low
        movlw   0x0A
        subwf   CRAFT_NUMBER, W        ;subtract 9 from craft number
        btfsc   STATUS, 0                      ;will be set if (number - 9) < 0
        goto    TEN_PLUS
        bcf            CRAFT_NUMBER, TENS_BIT ;ensure lights for 10s place not on
        goto    TRANSLATE_COMPLETE
 
;if value >10, convert to <10, C4 high
TEN_PLUS:
        movlw   0x0A                           
        subwf   CRAFT_NUMBER, F        ;subtract 9 from craft number (10s place represented by other lights)
        bsf            CRAFT_NUMBER, TENS_BIT
 
TRANSLATE_COMPLETE:
        movf    CRAFT_NUMBER,W
        movwf   ASSEMBLED_BYTE         ;start forming the assdembled byte
        return
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
ADD_TEAM:
        banksel CRAFT_TEAM
        btfss   CRAFT_TEAM,0           ;check team bit - wherever it is in main code
        goto    BLUE_TEAM
        goto    RED_TEAM
 
;set team bits 
BLUE_TEAM:                     
        bsf            ASSEMBLED_BYTE, BLUE_TEAM_BIT
        bcf            ASSEMBLED_BYTE, RED_TEAM_BIT
        return
 
RED_TEAM:
        bsf            ASSEMBLED_BYTE, RED_TEAM_BIT
        bcf            ASSEMBLED_BYTE, BLUE_TEAM_BIT
        return
        
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
SHIFT_BYTE:
        banksel ASSEMBLED_BYTE
 
        call    SET_SHIFT_DATA
        call    PULSE_SHIFT_REG
 
        rrf            ASSEMBLED_BYTE,F
        call    SET_SHIFT_DATA
        call    PULSE_SHIFT_REG        
 
        rrf            ASSEMBLED_BYTE,F
        call    SET_SHIFT_DATA
        call    PULSE_SHIFT_REG 
 
        rrf            ASSEMBLED_BYTE,F
        call    SET_SHIFT_DATA
        call    PULSE_SHIFT_REG 
 
        rrf            ASSEMBLED_BYTE,F
        call    SET_SHIFT_DATA
        call    PULSE_SHIFT_REG 
 
        rrf            ASSEMBLED_BYTE,F
        call    SET_SHIFT_DATA
        call    PULSE_SHIFT_REG 
 
        rrf            ASSEMBLED_BYTE,F
        call    SET_SHIFT_DATA
        call    PULSE_SHIFT_REG 
 
        rrf            ASSEMBLED_BYTE,F
        call    SET_SHIFT_DATA
        call    PULSE_SHIFT_REG 
 
 
        return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
SET_SHIFT_DATA:
        btfss   ASSEMBLED_BYTE,0
        goto    SET_LOW
        goto    SET_HIGH
 
SET_LOW:
        bcf            SHIFT_PORT,SHIFT_DATA_BIT      ;set data bit to bit 0 of assembled byte
        goto    SET_COMPLETE
        
SET_HIGH:
        bsf            SHIFT_PORT,SHIFT_DATA_BIT
 
SET_COMPLETE
 
        return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
PULSE_SHIFT_REG:
        banksel SHIFT_PORT
        bsf            SHIFT_PORT,SHIFT_CLOCK_BIT
        nop
        nop
        bcf            SHIFT_PORT,SHIFT_CLOCK_BIT
        return
 
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;Game Control Function;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Game_Control:
        banksel RCREG  ;bank 0
        movf GameState, w
        sublw WaitForIbuttom
        btfsc STATUS, Z
        goto Wait_For_Ibuttom_State  ;wait for i-buttom state
 
        movf GameState, w
        sublw WaitForSync
        btfsc STATUS, Z
        goto Wait_For_Sync_State  ;have read i-buttom, wait for syncronize state
 
        movf GameState, w
        sublw WaitForGame
        btfsc STATUS, Z
        goto Wait_For_Game_State  ;Wait_For_Game game state
 
        movf GameState, w
        sublw Game
        btfsc STATUS, Z
        goto Game_State  ;normal in Game down game state
 
        movf GameState, w
        sublw HardReset
        btfsc STATUS, Z
        goto Hard_Reset_State  ;Hard_Reset game state
 
        movf GameState, w
        sublw BoatStandDown
        btfsc STATUS, Z
        goto Boat_Stand_Down_State  ;Boat_Stand_Down game state
 
        movf GameState, w
        sublw EndGame
        btfsc STATUS, Z
        goto End_Game_State  ;EndGame game state
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;Game State Functions;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;the wait for ibuttom state
Wait_For_Ibuttom_State:
        banksel RCREG   ;bank 0
retest_ibuttom:
        call LoadIButtonBytes
        ;store the first i-buttom reading also in another place for later comparison
        movf SECOND_BYTE, w
        movwf SECOND_BYTE_CHECK
        movf THIRD_BYTE, w
        movwf THIRD_BYTE_CHECK
 
        ;ibuttom reading for second time
        call LoadIButtonBytes
        ;check if reading is the same with last time
        movf SECOND_BYTE, w
        subwf SECOND_BYTE_CHECK, w
        btfss STATUS, Z
goto retest_ibuttom
        movf THIRD_BYTE, w
        subwf THIRD_BYTE_CHECK, w
        btfss STATUS, Z
goto retest_ibuttom
 
        ;ibuttom reading for third time
        call LoadIButtonBytes
        ;check if reading is the same with last time
        movf SECOND_BYTE, w
        subwf SECOND_BYTE_CHECK, w
        btfss STATUS, Z
goto retest_ibuttom
        movf THIRD_BYTE, w
        subwf THIRD_BYTE_CHECK, w
        btfss STATUS, Z
goto retest_ibuttom
 
        movf THIRD_BYTE, w
        sublw 0x00
        btfsc STATUS, Z
goto retest_ibuttom
 
        movf THIRD_BYTE, w
        sublw 0xFF
        btfsc STATUS, Z
goto retest_ibuttom
 
        movlw WaitForSync
        movwf GameState
return
 
;once read i-buttom, broadcast i-buttom, until sense a match from my boat
Wait_For_Sync_State:
        banksel RCREG  ;bank 0
 
        ;broadcast i-buttom signal
        movlw 0xff
        movwf Destination_Address_First
        movlw 0xff
        movwf Destination_Address_Second
        movlw IBUTTON
        movwf RFdata0_to_send
        movf THIRD_BYTE, w
        movwf RFdata1_to_send
        movf SECOND_BYTE, w
        movwf RFdata2_to_send
        call No_Wait_Transmit_Function
 
        bcf PIR1, TMR1IF   ;clear timer 1 flag        
back4:
        btfsc PIR1, TMR1IF  ;check timer, ensure that this transmit is more than 200ms later than last one
        return
 
        call Get_Data_Function  ;get the rf data
        movf RFdata0_received, w
        sublw WATERCRAFT
        btfsc STATUS, Z
goto respond_boat
 
        movf RFdata0_received, w
        sublw ADMIRAL   ;check if the Header Data is for Admiral
        btfsc STATUS, Z
goto respond_admiral
goto back4
 
 
respond_boat:
        movf RFdata1_received, w
        sublw MATCHED_1
        btfss STATUS, Z
goto back4
 
        movf RFdata2_received, w
        sublw MATCHED_2
        btfss STATUS, Z
goto back4
 
        ;if reach here, mean my helm has gotten a MATCH reply from my boat, record its address
        movf Source_Address_Second, w
        movwf MyBoatAddress
 
        ;display team number and color on the helm
        movf MyBoatAddress, w
        movwf CRAFT_NUMBER
        movf SECOND_BYTE, w
        movwf CRAFT_TEAM
        call    TRANSLATE      ;takes craft number in binary (lower nibble) translates to 5 bits for BCD           
        call    ADD_TEAM       ;adds team affiliation to assembled byte
        call    SHIFT_BYTE     ;shift byte out on C0-1
 
        ;go to in-game state
        movlw WaitForGame;change back to WaitForGame after testing!!!!!
        movwf GameState
goto back4
 
;;;;end of function
        
respond_admiral:
        movf RFdata2_received, w
        sublw ADMIRAL_PING ;check if the Header Data is for ADMIRAL_PING
        btfsc STATUS, Z
        call case_ADMIRAL_PING
        call Erase_Data_Function
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Wait_For_Game_State:
 
        banksel RCREG  ;bank 0
 
;check is there is Ping, StartGame command or i-buttom signal from my boat, 
        call check_signal
        call StopBoat
return
 
;check is there is Ping, StartGame command or i-buttom signal from my boat, 
;i-buttom has not been done yet
check_signal:
        call Get_Data_Function
        movf RFdata0_received, w
        sublw ADMIRAL   ;check if the signal is from admiral
        btfsc STATUS, Z
        goto ping_or_startgame  ;if from admiral, it could be ping or start game command
return
 
ping_or_startgame:
        movf RFdata2_received, w
        sublw START_GAME        ;check if the signal is for game start
        btfsc STATUS, Z
        goto case_start_game  ;if is for game start, then cange game stat to 'game'
        
        movf RFdata2_received, w
        sublw ADMIRAL_PING      ;check if the signal is for ping
        btfsc STATUS, Z
        goto case_ADMIRAL_PING ;if is for ping, then respond
return
        
case_start_game:
;first erase signal to avoid multiple acknowledgements
        call Erase_Data_Function
        ;acknowledge to the boat
        movlw ADMIRAL_ADDRESS_MSB
        movwf Destination_Address_First
        movlw ADMIRAL_ADDRESS_LSB
        movwf Destination_Address_Second
        movlw ACK
        movwf RFdata0_to_send
        movlw 0x00
        movwf RFdata1_to_send
        movlw START_GAME
        movwf RFdata2_to_send
        call Transmit_Function
        movlw Game
        movwf GameState
return
        
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;general in-game state
Game_State:
        banksel RCREG  ;bank 0
        call Get_Data_Function
 
        movf RFdata0_received, w
        sublw WATERCRAFT        ;check if the Header Data is from boat
        ;if (is WATERCRAFT), call WaterCraft_Respond_Function function, else keep checking if it's other situation
        btfsc STATUS, Z
        call WaterCraft_Respond_Function
 
        movf RFdata0_received, w
        sublw ADMIRAL   ;check if the Header Data is for Admiral
        ;if (is Admiral), call Admiral function, else keep checking if it's other situation
        btfsc STATUS, Z
        call Admiral_Function
 
        call Boat_Control
return
;end of function Game_State
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
End_Game_State:
;almost everything is the same with in-game state, except Boat_Control will check the game state and decide wether to activate special functions
        call Game_State
return
 
;2 possible commands the helm is likely to receive and respond to: from watercraft and admiral
WaterCraft_Respond_Function:
        banksel RCREG  ;bank 0
 
        movf RFdata2_received, w
        sublw STAND_DOWN_RECEIVED_2
        btfsc STATUS, Z
        goto case_BoatStandDown        
return
 
case_BoatStandDown:
        ;clear the received RF data, so later I can check if there is a new transmission from my boat
        call Erase_Data_Function
        ;acknowledge to the boat
        movlw CRAFT_MSB
        movwf Destination_Address_First
        movf MyBoatAddress, w
        movwf Destination_Address_Second
        movlw ACK
        movwf RFdata0_to_send
        movlw STAND_DOWN_RECEIVED_1
        movwf RFdata1_to_send
        movlw STAND_DOWN_RECEIVED_2
        movwf RFdata2_to_send
        call Transmit_Function
 
;start timing for 10 sec, LEDs start flashing
        call Turn_On_10s_Timer
 
        movlw BoatStandDown
        movwf GameState
return
        
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Admiral_Function:
        banksel RCREG  ;bank 0
 
        movf RFdata2_received, w
        sublw BLUE_GOAL  
        btfsc STATUS, Z
        goto case_BLUE_GOAL
 
        movf RFdata2_received, w
        sublw RED_GOAL 
        btfsc STATUS, Z
        goto case_RED_GOAL
 
        movf RFdata2_received, w
        sublw HARD_RESET 
        btfsc STATUS, Z
        goto case_HARD_RESET
 
        movf RFdata2_received, w
        sublw ADMIRAL_PING ;check if the Header Data is for ADMIRAL_PING
        ;if (is ADMIRAL_PING), change game state
        btfsc STATUS, Z
        goto case_ADMIRAL_PING
 
        movf RFdata2_received, w
        sublw END_GAME 
        btfsc STATUS, Z
        goto case_END_GAME
return
 
case_BLUE_GOAL:
;light the blue LED
        banksel PORTC ;bank 0
        bsf Goal_Color, 7
        bcf Goal_Color, 6
        bsf PORTC, 1
        bcf PORTC, 2
return
 
case_RED_GOAL
;light the red LED
        banksel PORTC ;bank 0
        bsf Goal_Color, 6
        bcf Goal_Color, 7
        bsf PORTC, 2
        bcf PORTC, 1
return
 
case_HARD_RESET:
        movlw HardReset
        movwf GameState
return
 
case_ADMIRAL_PING:
        call Erase_Data_Function
        call Ping_Respond_Function
return
 
case_END_GAME
        call Erase_Data_Function
        ;acknowledge to the admiral
        movlw ADMIRAL_ADDRESS_MSB
        movwf Destination_Address_First
        movlw ADMIRAL_ADDRESS_LSB
        movwf Destination_Address_Second
        movlw ACK
        movwf RFdata0_to_send
        movlw 0x00
        movwf RFdata1_to_send
        movlw END_GAME
        movwf RFdata2_to_send
        call Transmit_Function
        movlw EndGame
        movwf GameState
return
 
;end of Admiral_Function
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Boat_Control:
;get the command from control pannel
;send out navigation command to boat in 5Hz rate
;decide wether to activate special function based on wether in Game state or End-Game state
 
        movf GameState, w
        sublw Game
        btfsc STATUS, Z
        goto special_fun_on  ;normal in Game down game state
 
        movf GameState, w
        sublw EndGame
        btfsc STATUS, Z
        goto special_fun_off  ;EndGame game state
 
        call StopBoat   ;else stop the boat
return
 
special_fun_on:
        call Get_Control_Sig
        movlw CRAFT_MSB
        movwf Destination_Address_First
        movf MyBoatAddress,w
        movwf Destination_Address_Second
        movlw NAVIGATION
        movwf RFdata0_to_send
        movf Navi, w
        movwf RFdata1_to_send
        movf Speci, w
        movwf RFdata2_to_send
        call Transmit_Function 
return
 
special_fun_off:
        call Get_Control_Sig
        movlw CRAFT_MSB
        movwf Destination_Address_First
        movf MyBoatAddress,w
        movwf Destination_Address_Second
        movlw NAVIGATION
        movwf RFdata0_to_send
        movf Navi, w
        movwf RFdata1_to_send
        movlw 0x00
        movwf RFdata2_to_send
        call Transmit_Function 
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;the function to get signal from the control pannel through SPI
Get_Control_Sig:
 
 
                               movlw                  0x00    
 
                               BANKSEL                SSPBUF
                               MOVWF                  SSPBUF         ;Send Data
 
                               BANKSEL                SSPSTAT
                               BTFSS                  SSPSTAT,BF     ;Wait for receive complete
                               GOTO                   $-1
 
                               BANKSEL                SSPBUF         ;Get received data
                               MOVF                   SSPBUF,w
                               movwf message_received
 
                               btfsc PORTC, 0
                               goto Get_Navi
                               goto Get_Speci
 
 
Get_Navi:
                               BANKSEL                Navi
                               movf message_received, w
                               MOVWF                  Navi
RETURN
 
 
Get_Speci
                               BANKSEL                Speci
                               movf message_received, w  
                               MOVWF                  Speci
 
RETURN
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
GameState_equ_ibuttom:
        movlw WaitForIbuttom
        movwf GameState
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Boat_Stand_Down_State:
        banksel RCREG
        call Get_Data_Function
;check if there is new data from my boat
        movf RFdata0_received, w
        sublw WATERCRAFT        ;check if the Header Data is from boat
        btfss STATUS, Z
        goto Check_Timer
 
        movf RFdata2_received, w
        sublw STAND_DOWN_RECEIVED_2
        btfss STATUS, Z
        goto Check_Timer
 
        ;if receive another STAND_DOWN_RECEIVED from my boat. clear the received RF data, so later I can check if there is a new transmission from my boat
        call Erase_Data_Function
        ;if receive another STAND_DOWN_RECEIVED from my boat, acknowledge to the boat again
        movlw CRAFT_MSB
        movwf Destination_Address_First
        movf MyBoatAddress, w
        movwf Destination_Address_Second
        movlw ACK
        movwf RFdata0_to_send
        movlw STAND_DOWN_RECEIVED_1
        movwf RFdata1_to_send
        movlw STAND_DOWN_RECEIVED_2
        movwf RFdata2_to_send
        call Transmit_Function
return
 
Check_Timer:
;transmit boat stop
        ;call StopBoat
        banksel RCREG   ;bank 0
;check 10 sec time up flag
        movf ten_sec_TimeUp, w
        sublw 0xff
        btfsc STATUS, Z
        goto Time_Up
return
 
Time_Up:
        call Turn_Off_10s_Timer
 
;LEDs stop flashing, display former goal color
        btfsc Goal_Color, 7
        call case_BLUE_GOAL
        btfsc Goal_Color, 6
        call case_RED_GOAL
;change game state
        movlw Game
        movwf GameState
return
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;start to count for 10 seconds, when time up, ten_sec_TimeUp will change to 0xff
Turn_On_10s_Timer:
;start 10 sec timer
        banksel OPTION_REG ;bank 1
        movlw b'00000111'
        movwf OPTION_REG
        banksel RCREG ;bank 0
        movlw 0x00
        movwf ten_sec_TimeUp
        movlw 0x00
        movwf ten_sec_timer_CNT1
        movlw 0x00
        movwf ten_sec_timer_CNT2
;enable timer0 interrupt
        bsf INTCON, T0IE
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;stop timer, reset time up flag and counters
Turn_Off_10s_Timer:
;stop 10 sec timer
        banksel OPTION_REG ;bank 1
;turn off timer 0
        movlw b'11111111'
        movwf OPTION_REG
        banksel RCREG ;bank 0
;clear time up flag
        movlw 0x00
        movwf ten_sec_TimeUp
;claer counters
        movlw 0x00
        movwf ten_sec_timer_CNT1
        movlw 0x00
        movwf ten_sec_timer_CNT2
;disable timer0 interrupt
        bcf INTCON, T0IE
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Hard_Reset_State:
        banksel RCREG
        call StopBoat   ;stop all actuators
        movlw WaitForIbuttom   ;game state go back to waiting for i-buttom
        movwf GameState
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Ping_Respond_Function:
        banksel RCREG  ;bank 0
        movlw ADMIRAL_ADDRESS_MSB
        movwf Destination_Address_First
        movlw ADMIRAL_ADDRESS_LSB
        movwf Destination_Address_Second
        movlw PING_RESPONSE
        movwf RFdata0_to_send
 
        movf GameState, w
        sublw WaitForIbuttom
        btfsc STATUS, Z
        goto no_ibuttom  ;normal game state
 
        movf GameState, w
        sublw WaitForSync
        btfsc STATUS, Z
        goto Unpaired  ;normal game state
 
        movlw 0x04
        movwf RFdata1_to_send
        movf MyBoatAddress, w
        movwf RFdata2_to_send
        call No_Wait_Transmit_Function
return
 
no_ibuttom:
        movlw 0x01
        movwf RFdata1_to_send
        movlw 0x00
        movwf RFdata2_to_send
        call No_Wait_Transmit_Function
return  
 
Unpaired:
        movlw 0x02
        movwf RFdata1_to_send
        movlw 0x00
        movwf RFdata2_to_send
        call No_Wait_Transmit_Function
return  
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
StopBoat:
;send out No_ACTION to boat in 5Hz rate
        banksel RCREG ;bank 0
        movlw CRAFT_MSB
        movwf Destination_Address_First
        movf MyBoatAddress,w
        movwf Destination_Address_Second
        movlw NAVIGATION
        movwf RFdata0_to_send
        movlw 0x88
        movwf RFdata1_to_send
        movlw 0x00
        movwf RFdata2_to_send
        call Transmit_Function
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Main:
 
;delay to wait for power up
LONG_DELAY:
        movlw   0xFF           ; ~16ms        
        movwf   COUNTER
LOOP3:  
        movlw   0xFF
        nop
        nop
        nop                    
        movwf   COUNTER2
LOOP2:  
        decfsz  COUNTER2,f
        goto    LOOP2          
 
 
        decfsz  COUNTER,f
        goto    LOOP3
        
;Input capture Init, I/O pins Init, SCI Init
call Init
 
;initial game state
movlw WaitForIbuttom
movwf GameState
movlw 0x09
movwf MyBoatAddress
 
movlw 0xab
movwf SECOND_BYTE
movlw 0xab
movwf THIRD_BYTE
 
movlw 0x00
movwf RFdata0_received             
movlw 0x00
movwf RFdata1_received
movlw 0x00
movwf RFdata2_received
 
movlw 0x00
movwf RFdata0_to_send       
movlw 0x00
movwf RFdata1_to_send 
movlw 0x00
movwf RFdata2_to_send 
 
 
 
;call case_BoatStandDown
 
Loop:
 
call Game_Control
 
 
 
goto Loop
 
 
 
END

 

Back to Top!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Helm Control Inputs Pseudocode

Initialize

      A0 as output for byte type select (movement or special)

      B4,6 and C6,7 for SSP

      C0-2 as analog inputs

      C3-5 as digital inputs

 

Main

Delay for power ramp up

Configure I/)

Initialize SSP

Configure AD

      Set Tad speed, set left justified, set Vdd as reference, enable

 

While(1)

      Load data into SSP register

      Service AD conversions

      If all AD conversions complete

            Assemble new special byte

            Assemble new movement byte    

 

Load new data

If SSP data has been read

      Switch byte type in register

 

 

Service AD conversions

If conversion complete

      Start next conversion

If all 3 conversions done

      Set conversions done flag

 

           

Assemble special byte

Clear special byte register

Add limit switch values for turret

If fire button depressed

      Load AD value from pump into special byte

 

Assemble movement byte

Clear movement byte register

Convert speed AD value into movement command nibble

Add to byte

Convert direction AD value into movement command nibble

Add to byte

 

Back to Top!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Helm Control Inputs Code Listing

 

; Nathan Parkhill, Mark Malhotra, Shaoqing Xiang

;218c project code to take in all helm inputs and assemble 2 bytes according to the comm spec

      list  P=PIC16F690

#include "P16F690.inc"

    __config (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC& _MCLRE_OFF)

 

      org 0

      goto MAIN

      org 5

TABLE:

 

 

MAIN:

;Bit defines

PORTA_DIR       equ     b'00000000' ;a0 for spi

PORTB_DIR       equ     b'01010000' ;b4 and b6 for spi

PORTC_DIR       equ     b'01111111' ;c0-5 for inputs, c6 and c7 for spi

 

ANSEL_LOW         equ         b'01110000' ;analog on C 0-2

ANSEL_HI          equ         0x00        ;no analog

 

ADCON1_VALUES     equ         b'01010000' ;sets 16Tosc <10mhz oscillator

 

SPECIAL_MASK equ         b'00110000' ; turret special inputs on C4,5

MSNIBBLE_MASK     equ         b'00001111'

LSNIBBLE_MASK     equ         b'11110000'

FIRE_BIT          equ         3

AD_CHANNEL_MASK   equ         b'11000011'

 

SPEED_AD_CHAN     equ         b'00010100' ;an5             

DIR_AD_CHAN       equ         b'00010000' ;an4             

PUMP_AD_CHAN equ         b'00011000' ;an6

 

MOVEMENT_BYTE     equ                     0x30

SPECIAL_BYTE equ                     0x31

 

PUMP_ADCONV       equ                     0x32

SPEED_ADCONV equ                     0x33

DIR_ADCONV        equ                     0x34

 

BYTE_TO_CONVERT   equ                     0x35

CONVERTED_BYTE    equ                     0x36

 

LAST_CONVERSION   equ                     0x37

 

FLAG_REGISTER     equ                     0x38

AD_DONE_FLAG equ                     b'00000001'

 

SSP_ID_PORT       equ                     PORTA

SSP_ID_BIT        equ                     0

 

COUNTER           equ                     0x39

COUNTER2          equ                     0x3A

TEMP              equ                     0x40

 

BIN1_UPPER_BOUND  equ         b'01100100'

BIN2_UPPER_BOUND  equ         b'01101100'

BIN3_UPPER_BOUND  equ         b'01110110'

BIN4_UPPER_BOUND  equ         b'10001100'

BIN5_UPPER_BOUND  equ         b'10010110'

BIN6_UPPER_BOUND  equ         b'10011111'

 

FIRST_BIN_OUTPUT  equ         b'00000000'

SECOND_BIN_OUTPUT equ         b'00000011'

THIRD_BIN_OUTPUT  equ         b'00000101'

FOURTH_BIN_OUTPUT equ         b'00001000'

FIFTH_BIN_OUTPUT  equ         b'00001011'

SIXTH_BIN_OUTPUT  equ         b'00001101'

SEVENTH_BIN_OUTPUT equ         b'00001111'

 

;wait for power ramp-up

      call LONG_DELAY

      call LONG_DELAY

      call LONG_DELAY

      call  LONG_DELAY

      call  LONG_DELAY

 

;configure I/0

      banksel ANSEL

      movlw   ANSEL_LOW       ;set analog select on all bits

      movwf   ANSEL

      movlw ANSEL_HI

      movwf   ANSELH

     

      banksel     TRISA

      movlw       PORTA_DIR       ;set port A directions

      movwf       TRISA

      movlw       PORTB_DIR         ;set port B directions

      movwf       TRISB

      movlw       PORTC_DIR       ;Set port C directions

      movwf       TRISC

      banksel     PORTA

 

;init SSP

      call  InitSSP

 

;configure AD

      banksel     ADCON1

      movlw ADCON1_VALUES ;sets Tad speed

      movwf ADCON1

     

      banksel     ADCON0

      bcf         ADCON0,7    ;set left justified

      bcf         ADCON0,6    ;set vdd as ref

      bsf         ADCON0,0    ;enable AD

 

      movlw 0x06

      movwf LAST_CONVERSION         ;start at last conversion

 

      ;load dummy movement byte for first read  

      BANKSEL           SSPBUF

      MOVLW       b'00110111'

      MOVWF       SSPBUF

     

      BANKSEL           SSP_ID_PORT

      BSF               SSP_ID_PORT,SSP_ID_BIT

     

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

;main code

TOP:

;     banksel     MOVEMENT_BYTE

;     movlw       0xAA

;     movwf       MOVEMENT_BYTE

;     movlw       0x10

;     movwf       SPECIAL_BYTE

;     MOVWF       SSPBUF

      call        LOAD_NEW_DATA

 

      call        SERVICE_AD

     

      BANKSEL     FLAG_REGISTER

      btfss       FLAG_REGISTER, AD_DONE_FLAG ;if AD done flag

      goto        CONVERSION_IN_PROGRESS

 

      call        ASSEMBLE_SPECIAL

      call        ASSEMBLE_MOVEMENT

 

      BANKSEL     PORTA

      BCF         PORTA,1    

 

      ;put movement in buffer

      bcf         FLAG_REGISTER, AD_DONE_FLAG    ;clear AD done flag

     

      bsf         PORTC,7

 

CONVERSION_IN_PROGRESS:

 

      goto TOP

 

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

 

InitSSP:

      BANKSEL     SSPSTAT

      CLRF        SSPSTAT     ;SMP = 0, CKE = 0

 

      BANKSEL     SSPCON

 

      BSF         SSPCON,SSPEN

      BSF         SSPCON,CKP

      BSF         SSPCON,SSPM2

      BSF         SSPCON,SSPM0     

 

      BANKSEL     SSPBUF

      MOVF        SSPBUF,W

      MOVWF       SSPBUF

 

      RETURN

 

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

;Updates unread data in the ssp buffer

LOAD_NEW_DATA:

 

;     BANKSEL     SSPSTAT

;     BTFSC       SSPSTAT,BF  ;Wait for receive complete

;     GOTO        DATA_READ

 

      BANKSEL     SSPSTAT

      BTFSC       SSPSTAT,BF        ;if ssp read

      CALL        CHANGE_FLAG       ;change flag

 

      BANKSEL     SSP_ID_PORT

      BTFSC       SSP_ID_PORT,SSP_ID_BIT

      GOTO        LoadMovement

      GOTO        LoadSpecial

LoadMovement:

      BANKSEL     SSPBUF

      MOVF        MOVEMENT_BYTE,W

      MOVWF       SSPBUF

      BSF         SSP_ID_PORT,SSP_ID_BIT

      RETURN

LoadSpecial:

      BANKSEL     SSPBUF

      MOVF        SPECIAL_BYTE,W

      MOVWF       SSPBUF

      BCF         SSP_ID_PORT,SSP_ID_BIT

      RETURN

 

CHANGE_FLAG:

      BANKSEL     PORTA       ;set A1

      BSF         PORTA,1          

 

      BANKSEL     SSP_ID_PORT

      BTFSC       SSP_ID_PORT,SSP_ID_BIT  ;check A0

      GOTO        CLEAR_FLAG                     ;if set, clear

      BSF         SSP_ID_PORT,SSP_ID_BIT  ;if clear,set

      RETURN

CLEAR_FLAG:

      BCF         SSP_ID_PORT,SSP_ID_BIT

      RETURN

 

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

 

SERVICE_AD:

      btfsc ADCON0,GO         ;if conversion complete

      goto NOT_COMPLETE

     

      movf LAST_CONVERSION,W

      xorlw 0x06

      btfsc STATUS,Z

      goto  START_SPEED_CONV

 

      movf LAST_CONVERSION,W

      xorlw 0x04

      btfsc STATUS,Z

      goto  START_DIR_CONV

 

      movf LAST_CONVERSION,W

      xorlw 0x05

      btfsc STATUS,Z

      goto  START_PUMP_CONV

      goto  NOT_COMPLETE

 

START_SPEED_CONV:

      banksel     ADRESH

      movf  ADRESH,W          ;move top byte of AD

      movwf PUMP_ADCONV ;to pump because that was last conversion (6)

 

      movf  ADCON0,W

      andlw AD_CHANNEL_MASK ; clear ad channel bits

      iorlw SPEED_AD_CHAN     ;set AD channel bits

      movwf ADCON0

 

      call  ACQ_DELAY

           

      bsf   ADCON0,GO         ;start conversion

      movlw 0x04              ;update which conversion in progress

      movwf LAST_CONVERSION

 

      bsf   FLAG_REGISTER, AD_DONE_FLAG;all 3 complete set AD done flag

      goto NEW_AD_STARTED

 

START_DIR_CONV:

      banksel     ADRESH

      movf  ADRESH,W          ;move top byte of AD

      movwf SPEED_ADCONV;to pump because that was last conversion (6)

     

      movf  ADCON0,W

      andlw AD_CHANNEL_MASK ; clear ad channel bits

      iorlw DIR_AD_CHAN ;set AD channel bits

      movwf ADCON0

 

      call  ACQ_DELAY

           

      bsf   ADCON0,GO         ;start conversion

      movlw 0x05              ;update which conversion in progress

      movwf LAST_CONVERSION

 

      goto NEW_AD_STARTED

 

START_PUMP_CONV:

      banksel     ADRESH

      movf  ADRESH,W          ;move top byte of AD

      movwf DIR_ADCONV;to pump because that was last conversion (6)

     

      movf  ADCON0,W

      andlw AD_CHANNEL_MASK ; clear ad channel bits

      iorlw PUMP_AD_CHAN      ;set AD channel bits

      movwf ADCON0

 

      call  ACQ_DELAY

     

      bsf   ADCON0,GO         ;start conversion

      movlw 0x06              ;update which conversion in progress

      movwf LAST_CONVERSION

     

      goto NEW_AD_STARTED

     

NOT_COMPLETE:

NEW_AD_STARTED:

 

      return

 

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

 

LONG_DELAY:

      movlw 0xFF        ; ~16ms          

      movwf COUNTER

LOOP3:     

      movlw 0xFF             

      movwf COUNTER2

LOOP2:     

      decfsz      COUNTER2,f

      goto  LOOP2      

 

      decfsz      COUNTER,f

      goto  LOOP3

     

      return

 

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

 

ACQ_DELAY:

      movlw 0x60              ;96 loops ~24uS or maybe 48

      movwf COUNTER

LOOP:

      decfsz      COUNTER,f

      goto  LOOP

     

      return

 

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

 

ASSEMBLE_SPECIAL:

     

      banksel SPECIAL_BYTE

      clrf  SPECIAL_BYTE

      movf  PORTC,W                 ;read switch value

      andlw SPECIAL_MASK ;Pull values for special bits

      iorwf SPECIAL_BYTE,F    ;add switch values to special byte

     

      btfss PORTC,FIRE_BIT    ;only add pump values if fire button depressed

      goto NOT_FIRING

      swapf PUMP_ADCONV,W     ;import 8 bit pump AD with swapped nibbles to put the nibble we want in the lower nibble

      andlw MSNIBBLE_MASK     ; kill MS 4 bits (leaves just the coarsest 4 bits from conversion)

      iorwf SPECIAL_BYTE,F    ; add to special byte

 

NOT_FIRING:

      bsf   SPECIAL_BYTE,7

      return

 

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

 

ASSEMBLE_MOVEMENT:

     

      banksel MOVEMENT_BYTE

      clrf  MOVEMENT_BYTE

 

      comf  SPEED_ADCONV,W                

      movwf BYTE_TO_CONVERT         ;prepare speed for conversion

      call  CONVERT_TO_MVMT         ;convert speed

      movf  CONVERTED_BYTE,W

      movwf MOVEMENT_BYTE     ;move converted value into movement byte

 

      movf  DIR_ADCONV,W

      movwf BYTE_TO_CONVERT         ;prepare direction for conversion

      call CONVERT_TO_MVMT         ;convert direction

      swapf CONVERTED_BYTE,W        ;swap nibbles to move direction to ms nibble

      iorwf MOVEMENT_BYTE,F                ;add to movement byte (CONVERT_TO_MVMT returns 0000 in upper nibble)

     

      return

 

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

     

CONVERT_TO_MVMT:  ;splits the movement into 7 possible bins based on AD level

 

FIRST_BIN_CHECK:

      movlw BIN1_UPPER_BOUND

      subwf BYTE_TO_CONVERT, W;subtract bin upper limit from AD value

      btfsc STATUS, C         ;will be set if (number - bin upper) < 0

      goto  SECOND_BIN_CHECK  ;number was not in this bin   

      movlw FIRST_BIN_OUTPUT

      movwf CONVERTED_BYTE

 

      goto  VALUE_DETERMINED

 

SECOND_BIN_CHECK:

      movlw BIN2_UPPER_BOUND

      subwf BYTE_TO_CONVERT, W;subtract bin upper limit from AD value

      btfsc STATUS, C         ;will be set if (number - bin upper) < 0

      goto  THIRD_BIN_CHECK

      movlw SECOND_BIN_OUTPUT

      movwf CONVERTED_BYTE

 

      goto  VALUE_DETERMINED

 

THIRD_BIN_CHECK:

      movlw BIN3_UPPER_BOUND

      subwf BYTE_TO_CONVERT, W;subtract bin upper limit from AD value

      btfsc STATUS, C         ;will be set if (number - bin upper) < 0

      goto  FOURTH_BIN_CHECK

      movlw THIRD_BIN_OUTPUT

      movwf CONVERTED_BYTE

 

      goto  VALUE_DETERMINED

 

FOURTH_BIN_CHECK:

      movlw BIN4_UPPER_BOUND

      subwf BYTE_TO_CONVERT, W;subtract bin upper limit from AD value

      btfsc STATUS, C         ;will be set if (number - bin upper) < 0

      goto  FIFTH_BIN_CHECK

      movlw FOURTH_BIN_OUTPUT

      movwf CONVERTED_BYTE

     

      goto  VALUE_DETERMINED

 

FIFTH_BIN_CHECK:

      movlw BIN5_UPPER_BOUND

      subwf BYTE_TO_CONVERT, W;subtract bin upper limit from AD value

      btfsc STATUS, C         ;will be set if (number - bin upper) < 0

      goto  SIXTH_BIN_CHECK

      movlw FIFTH_BIN_OUTPUT

      movwf CONVERTED_BYTE

      goto  VALUE_DETERMINED

 

SIXTH_BIN_CHECK:

      movlw BIN6_UPPER_BOUND

      subwf BYTE_TO_CONVERT, ;subtract bin upper limit from AD value

      btfsc STATUS, C         ;will be set if (number - bin upper) < 0

      goto  SEVENTH_BIN_CHECK

      movlw SIXTH_BIN_OUTPUT

      movwf CONVERTED_BYTE

      goto  VALUE_DETERMINED

 

SEVENTH_BIN_CHECK:

      movlw SEVENTH_BIN_OUTPUT

      movwf CONVERTED_BYTE

 

VALUE_DETERMINED:

      return

 

end

 

 

Back to Top!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

Helm Display Pseudocode

Initialize

      C0,1 as data and clock for shift register (digital outputs)

 

Main Code

      Translate craft number

      Add team affiliation to byte

      Shift byte out to register

 

Translate craft number

      If craft number <10

            Set lower nibble with craft number

            Set tens bit low

      If craft number >10

            Subtract 10 from craft number

            Set lower nibble with craft number

            Set tens bit high

 

Add team affiliation

      If team is red

            Set red team bit, clear blue team bit

      If team is blue

            Set blue team bit, clear red team bit

 

Shift byte out

      Select assembled byte

     

      Until Byte is done

            Set data line with bit 0 of assembled byte

            Pulse clock line

            Rotate bits in assembled byte so next bit is in position 0

 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Helm Display Code Listing

 

; Nathan Parkhill, Mark Malhotra, Shaoqing Xiang

;218c project code to take in 4 bit value and a team value and output to 2 digits of a 7 segment led display via a shift register and bcd

      list  P=PIC16F690

#include "P16F690.inc"

    __config (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC& _MCLRE_OFF) ;only disabled masterclear b/c needed as input

 

      org 0

      goto MAIN

      org 5

TABLE:

 

MAIN:

;Bit defines

PORTA_DIR       equ     b'00001111' ;inputs on a to take in number to convert- comes from ibutton translation in actual program

PORTC_DIR       equ     b'00000100' ;c3 input for go switch- also testing.  need C0-1 as outputs for shift register

 

MSB_MASK          equ         b'00001111'

 

SHIFT_PORT        equ         PORTC

SHIFT_DATA_BIT    equ         0

SHIFT_CLOCK_BIT   equ         1

 

CRAFT_NUMBER equ         0x30

CRAFT_TEAM        equ         0x31  ; bit 0 high for red, low for blue - can be taken from somewhere else later

 

TRANSLATED_BYTE   equ         0x32

TENS_BIT          equ         4     ;bit in assembled bytethat controls the tens place on the display

RED_TEAM_BIT equ         5     ;bit in assembled byte to indicate blue team

BLUE_TEAM_BIT     equ         6     ;bit in assembled byte to indicate red team

ASSEMBLED_BYTE    equ         0x32  ;byte to shift out

 

;configure I/0

      banksel ANSEL

      movlw   0x00            ;clear analog select on all bits (only need C0-1)

      movwf   ANSEL

      movwf   ANSELH

     

      banksel     TRISA

      movlw       PORTA_DIR       ;set port B directions

      iorwf       TRISA,F

      movlw       PORTC_DIR       ;Set port C directions

      movwf       TRISC

      banksel     PORTA

      movlw 0x00

      movwf PORTC           ;set all outputs to 0

 

      ;set blue team for testing

      bcf         CRAFT_TEAM,0

 

;main code

TOP:

;take in value from switches

      clrf  ASSEMBLED_BYTE

      movf  PORTA,W                 ;read switch value

      andlw MSB_MASK          ;lose top 4 bits

      movwf CRAFT_NUMBER

 

      call TRANSLATE   ;takes craft number in binary (lower nibble) translates to 5 bits for BCD

           

      call  ADD_TEAM    ;adds team affiliation to assembled byte

 

      call  SHIFT_BYTE  ;shift byte out on C0-1

     

      btfss PORTC,2           ;wait for button push

      goto  $-1

 

      goto TOP

 

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

TRANSLATE:

;if value <10, convert to c0-3, C4 low

      movlw       0x0A

      subwf       CRAFT_NUMBER, W         ;subtract 9 from craft number

      btfsc STATUS, 0               ;will be set if (number - 9) < 0

      goto  TEN_PLUS

      bcf         CRAFT_NUMBER, TENS_BIT  ;ensure lights for 10s place not on

      goto TRANSLATE_COMPLETE

 

;if value >10, convert to <10, C4 high

TEN_PLUS:

      movlw 0x0A                   

      subwf CRAFT_NUMBER, F         ;subtract 9 from craft number (10s place represented by other lights)

      bsf         CRAFT_NUMBER, TENS_BIT

 

TRANSLATE_COMPLETE:

      movf  CRAFT_NUMBER,W

      movwf ASSEMBLED_BYTE          ;start forming the assdembled byte

      return

 

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

 

ADD_TEAM:

      banksel     CRAFT_TEAM

      btfss CRAFT_TEAM,0      ;check team bit - wherever it is in main code

      goto  BLUE_TEAM

      goto  RED_TEAM

 

;set team bits

BLUE_TEAM:             

      bsf         ASSEMBLED_BYTE, BLUE_TEAM_BIT

      bcf         ASSEMBLED_BYTE, RED_TEAM_BIT

      return

 

RED_TEAM:

      bsf         ASSEMBLED_BYTE, RED_TEAM_BIT

      bcf         ASSEMBLED_BYTE, BLUE_TEAM_BIT

      return

     

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

 

SHIFT_BYTE:

      banksel     ASSEMBLED_BYTE

 

      call  SET_SHIFT_DATA

      call  PULSE_SHIFT_REG

 

      rrf         ASSEMBLED_BYTE,F

      call  SET_SHIFT_DATA

      call  PULSE_SHIFT_REG        

 

      rrf         ASSEMBLED_BYTE,F

      call  SET_SHIFT_DATA

      call  PULSE_SHIFT_REG  

 

      rrf         ASSEMBLED_BYTE,F

      call  SET_SHIFT_DATA

      call  PULSE_SHIFT_REG  

 

      rrf         ASSEMBLED_BYTE,F

      call  SET_SHIFT_DATA

      call  PULSE_SHIFT_REG  

 

      rrf         ASSEMBLED_BYTE,F

      call  SET_SHIFT_DATA

      call  PULSE_SHIFT_REG  

 

      rrf         ASSEMBLED_BYTE,F

      call  SET_SHIFT_DATA

      call  PULSE_SHIFT_REG  

 

      rrf         ASSEMBLED_BYTE,F

      call  SET_SHIFT_DATA

      call  PULSE_SHIFT_REG  

 

      return

 

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

 

SET_SHIFT_DATA:

      btfss ASSEMBLED_BYTE,0

      goto  SET_LOW

      goto  SET_HIGH

 

SET_LOW:

      bcf         SHIFT_PORT,SHIFT_DATA_BIT      ;set data bit to bit 0 of assembled byte

      goto  SET_COMPLETE

     

SET_HIGH:

      bsf         SHIFT_PORT,SHIFT_DATA_BIT

 

SET_COMPLETE

 

      return

 

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

 

PULSE_SHIFT_REG:

      banksel SHIFT_PORT

      bsf         SHIFT_PORT,SHIFT_CLOCK_BIT

      nop

      nop

      bcf         SHIFT_PORT,SHIFT_CLOCK_BIT

      return

 

end

 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Boat Program Flow

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

\

 

 

 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Boat Communication PIC Pseudocode

Variable definition:

bytes_to_ignore equ 0x22   ;to store the address information received

message_received equ 0x23  ;to store the data received

message_to_send equ 0x24  ;to store the data to send

RFdata0_received equ 0x25   ;to store the data received

RFdata1_received equ 0x26   ;to store the data received  

RFdata2_received equ 0x27   ;to store the data received

RFdata0_to_send equ 0x28   ;to store the data to_send

RFdata1_to_send equ 0x29   ;to store the data to_send  

RFdata2_to_send equ 0x2A   ;to store the data to_send

Source_Address_First equ 0x2B ;the most significant byte to address

Source_Address_Second equ 0x2C ;the least significant byte to address

Destination_Address_First equ 0x2D ;the most significant byte to address

Destination_Address_Second equ 0x2E ;the least significant byte to address 

drive_pump equ 0x30;  ;the re-structured data to send to the drive, pump control PIC through SPI

ID_stepper_servo equ 0x31; ;the re-structured data to send to the servo, stepper control PIC through SPI

team_ID equ 0x32; bit 6,7 indicate our boat's ID, the other bits are 0 

temp equ 0x33; temporary space to store intermediate data

sum equ 0x34   ;to store the sum value

check_sum equ 0x35    ; to store the check sum value 

MyHelmAddress equ 0x36  ;to store the least significant byte of paired helm address

GameState equ 0x37  ;game state 

three_sec_timer_CNT equ 0x38

#define three_sec_timer_PER 0x72  ;=114 

W_TEMP equ 0x70     ; to store w value for interrupts return

STATUS_TEMP equ 0x71  ; to store STATUS value for interrupts return 

ReceiveIndex equ 0x3F ;the index to indicate where I am in the 11 byte frame

#define RX_START 0x40 ;Location of first byte received

;all ram space in between are used

#define RX_END 0x4B ;Location of last byte received 

COUNTER equ 0x60

COUNTER2 equ 0x61 

i-buttom variables:

#define IBUTTON_PORT  PORTA

#define IBUTTON_PIN    0

#define TRISIBUTTON    TRISA 

#define IBUTTON_INPUT  0x01

#define IBUTTON_OUTPUT  0x00

#define IBUTTON_HI   0x01

#define IBUTTON_LO   0x00 

FIRST_BYTE  equ    0x66

SECOND_BYTE  equ    0x67

THIRD_BYTE  equ    0x68

TEMP   equ    0x69

SECOND_BYTE_CHECK  equ    0x6A

THIRD_BYTE_CHECK  equ    0x6B 

org 0

goto Main

org 4

goto ISR

org 5 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;program starts;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

Interrupt service routine:

ISR:

      Save current w register value

      Save current STATUS register value 

      Check if the interrupt is caused by SCI or Timer0 overflow

      If (caused by SCI), use RF data process service routine

      If (caused by Timer0), use 3 sec timer process service routine 
 

RF receive interrupt service routine:

      clear the 3 sec time out counter

      store the received RF data in the proper place of array in RAM

      Load ReceiveIndex to FSR

      movwf FSR 

      Read data from RCREG, store the data in INDF(address is determined by the value of ReceiveIndex) 

      Test if the data received is the start byte

      If yes, ReceiveIndex = RAM place for second RF byte

      Else increase ReceiveIndex

      If ReceiveIndex = RAM place for last RF byte, ReceiveIndex = RAM place for first RF byte 

End of RF receive interrupt service routine 
 
 

timer0 interrupt service routine, for 3 sec time out:

      increase three_sec_timer_CNT 

      if three_sec_timer_CNT = 114:

            clear three_sec_timer_CNT

            write navigation stop to RF data

      endif

      clear TIMER0 flag 

End of timer0 interrupt service routine 
 

      Restore the value of STATUS register

      Restore the value of w register

      Return from interrupt

End of INT function 

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

Function to move address and data information into variables:

Get_Data_Function:

      Save the most significant byte of the sender’s address in variable Source_Address_First

      Save the least significant byte of the sender’s address in variable Source_Address_Second

      Save the first byte of the 3 bytes of real data in variable RFdata0_received

      Save the second byte of the 3 bytes of real data in variable RFdata1_received

      Save the third byte of the 3 bytes of real data in variable RFdata2_received 

Return

End of Get_Data_Function 

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

Function to erase address and data information

once this function is called, all 0s will be returned from Get_data_function, unless there has been another RF transmission received

Erase_Data_Function:

      Write all 0’s to the RF data recording array in RAM

Return

End of Erase_Data_Function 

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

initialization function

Init:

initilize variables:

      set the value of ReceiveIndex to point to where the starting byte of RF frame is stored 

initialize timer 1, use internal oscillator by default

      set timer 1 prescale to be 1:8

      turn on timer 1 

set port CCP1 for output compare 

initialize timer 2, for output compare

      set prescale and postscale of timer2 to be 16, and turn on timer2 

set port A, B, C as non-analog pins

set port A, B, C as non-analog pins 

set RC6 as output to do slave select

set RC7 for SPI output

RC0 is general output for PIC select

set RB6 as output for SPI clock

set RB4 as input for SPI in

set PA0 as input for i-buttom reading 

initiate SCI:

      set baud rate to be 9600:

      BRGH=0

      Use asynchronous communication

      BRG16 ;BRG16=1

      SPBRG = 64

      baud rate = 9615

      enable SPI transmission

      enable serial port

      enable SPI receiving 

initiate SPI:

      setting timer2:

      TMR2 freq = Fosc/64/49

 turn on timer2, prescaler 1:16, post scaler 1:1

SMP = 0, CKE = 0

      SSPEN, CKP=1, CLK freq = TMR2 output/2

      Clear SPI receive register full falg

      select drive-pump control PIC

      send out boat stop signal to the PIC controlling the actuators

      Clear SPI Receive Register:  

interrupts enables:

      enable gloable interrupt enable

      enable peripheral interrupt enable

      enable SCI receive interrupt 

portC output all low

return

End of function initialization 
 
 

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

data transmit function

Transmit_Function:

      check timer, ensure that this transmit is more than 200ms later than last one 

      send start byte, wait for transmission over by calling wait_for_transmssion_over 

      send LENGTH_MSB, wait for transmission over 

      send LENGTH_LSB, wait for transmission over 

      send API_TX, wait for transmission over 

      send FRAME_ID, wait for transmission over 

      send Destination_Address_First, wait for transmission over 

      send Destination_Address_Second, wait for transmission over 

      send 0x01 for the option byte, wait for transmission over 

      send RFdata0_to_send, wait for transmission over 

      send RFdata1_to_send, wait for transmission over 

      send RFdata1_to_send, wait for transmission over 

      calculate check sum value 

      send check sum value, wait for transmission over 

      clear timer 1 flag

return

end of Transmit_Function 
 

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

the function to wait until the trasmit shift register of PIC is empty

wait_for_transmssion_over:

      keep reading TRMT flag in TXSTA, until it is set

return

end of function wait_for_transmssion_over 
 
 

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

;;;;;;;;;;;;;;;;;;;;;;i-buttom functions;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      see stand-alone iButton reader code for explanations

End of i-buttom functions 
 

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

;;;;;Game Control Function;;;;;;;

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

the master game control function of the boat:

Game_Control:

      Check the value of GameState

      Case WaitForIbuttom, use Wait_For_Ibuttom_State service 

      Case WaitForSync, use Wait_For_Sync_State service 

      Case Normal, use Normal_State service 

      Case StandDown, use Stand_Down_State service 

      Case HardReset, use Hard_Reset_State service 

      Case SoftReset, use Soft_Reset_State service

return 

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

;;;;;Game State Functions;;;;;;;

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

the wait for ibuttom state

Wait_For_Ibuttom_State:

      Keep waiting for first ibuttom read in, store the first i-buttom reading also in another place for later comparison 

      Keep waiting for second ibuttom read in 

      Keep waiting for third ibuttom read in 

      If the three times get the same value, and the value is neither 0xff nor 0x00, store ibuttom data, return from this function 

      Else go back to the start of this function

End of Wait_For_Ibuttom_State 
 

Once read i-buttom, try to match with my helm

Wait_For_Sync_State:

      call Get_Data_Function

      check the value of RFdata0_received:

      if IBUTTOM, goto check_ibuttom

      if ADMIRAL, goto respond_admiral

return 

check_ibuttom:

      check if the received ibuttom signal is the same with the boat’s, if yes, record the sender’s address as MyHelmAddress 

      send back MATCHED signal to my helm 

      set GameState to be Normal 

      turn on timer0 for 3 sec time out, from now on, if the boat doen’t receive any RF signal in 3 seconds, it will stop all actuators: 

      initialize timer0 to be slowest, clear three_sec_timer_CNT 

      enable timer0 interrupt 

show team affiliation on the boat by calling Determine_team 

return 

respond_admiral:

      check if the signal is a ping request

      if yes, call Ping_Respond_Function

      call Erase_Data_Function

return 

End of Wait_For_Sync_State 

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

function to decide which team I'm in based on i-buttom reading

Determine_team:

      test SECOND_BYTE to be even or odd number

      if odd, goto red

      if even, goto blue

return 

red:

      RC1 output High

      RC2 output Low

return 

blue:

      RC2 output High

      RC1 output Low

Return

End of Determine_team 

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

General in-game state

Normal_State:

      call Get_Data_Function 

      check if the signal is I-buttom broadcast

      if (is I-buttom), call i-buttom function, else keep checking if it's other situation 

      check if the signal is for navigation command from my helm

      if (is navigation), call navigation function, else keep checking if it's other situation 

      check if the signal is from Admiral

      if (is Admiral), call Admiral function, else keep checking if it's other situation

return 

3 possible commands the boat is likely to receive and respond to: ibuttom, navigation, and admiral: 

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

I_Buttom_Respond:

      first check if the i-buttom boadcast is from my helm, if not, discard

      if address is not my helm's, just return

      if address is my helm's, send MATCH to it again

return

end of function Normal_State 
 

Navigation_Function:

      check if the Navigation Data is really from my helm to prevent responding to other guys' possible bad signal

      if not from my helm, just jump out of function 

 else re-structure the RFdata1 and RFdata2 to get drive_pump byte:

      put pump bits in the lower nibble of drive_pump

      put drive bits in the upper nibble of drive_pump 

      put direction bits in the lower nibble of ID_stepper_servo

      put special function bits in bit 4, 5 of ID_stepper_servo 

      send drive_pump and ID_stepper_servo through SPI to the two lower level PICs which control the actuators

      call Talk_To_Mark

return

End of Navigation_Function 
 

the function to talk to the two actuator-control PICs

Talk_To_Mark:

      Set RC0, slave select drive-pump control PIC

      wait for SPI ready to send new data

      Wait for last receive complete

      Get received data

      send data to PIC1 trough SPI 

      wait for some time 

      clear RC0, slave select ID_stepper_servo control PIC

      wait for SPI ready to send new data

      Wait for last receive complete

      Get received data

      send data to PIC2 trough SPI 

      wait for some time

return

End of talk to mark 
 

Admiral_Function:

      banksel RCREG  ;bank 0 

      check if the signal received is STAND_DOWN, if yes, goto case_stand_down 

      check if the signal received is HARD_RESET, if yes, goto case_hard_reset 

      check if the signal received is ADMIRAL_PING, if yes, goto case_admiral_ping 
 

      check if the signal received is HARD_RESET, if yes, goto case_hard_reset 

      check if the signal received is SOFT_RESET, if yes, goto case_soft_reset 
 

case_stand_down:

      change GameState to ‘StandDown’

return 

case_hard_reset:

      change GameState to ‘HardReset’

return 

case_soft_reset:

      change GameState to ‘SoftReset’

return 

case_admiral_ping:

      call Erase_Data_Function

      call Ping_Respond_Function

return

end of Admiral_Function 

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

Stand_Down_State:

      call StopBoat to stop all actuators 

      acknowledge to the admiral

      send STAND_DOWN_RECEIVED to Admiral

      check if helm acknowledges:

      if yes, change GameState back to ‘Normal

      else return from function 

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

Hard_Reset_State:

      call StopBoat to stop all actuators

      change GameState back to ‘WaitForIbuttom’

return 

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

Soft_Reset_State:

      call StopBoat to stop all actuators

      send back acknowledgement to admiral

      change GameState back to ‘Normal

return 

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

Ping_Respond_Function:

      Check GameState:

      Case WaitForIbuttom, respond accordinglyreturn

      Case WaitForSync, respond accordinglyreturn 

      Other Cases, respond accordinglyreturn

return   

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

StopBoat:

      put 0x80 in drive_pump

      put 0x08 in ID_stepper_servo

      call Talk_To_Mark

return 

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

Main function

Main: 
 

Use some loops to delay for 16ms to wait for power up 

call Init 

initial game state to be ‘WaitForIbuttom’ 

call StopBoat 

Loop:

      call Game_Control

goto Loop 

END of program

Back to Top!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Boat Communication PIC Code Listing

 

list P=PIC16F690
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Protocol Rev C constants
; note: use of MSB and LSB implies Byte, not Bit in this.
; Rev A, Brian Hachtmann, May 09 2008
 
        ; 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:  change this to non-zero if you wish 
        ; your xBee to respond with a Tx Status message
#define        FRAME_ID                       0x00    
 
        ; Addresses
#define        ADMIRAL_ADDRESS_MSB    0xBC
#define        ADMIRAL_ADDRESS_LSB    0xFF
 
#define        HELM_MSB                       0xBC                   
#define        CRAFT_MSB                      0xAF
 
        ; for ME218C Data Byte 0 Header
#define        IBUTTON                0x01
#define        NAVIGATION                     0x02
#define        ADMIRAL                0x04
#define        WATERCRAFT                     0x08
#define        PING_RESPONSE          0x10
#define        ACK                            0x80
 
        ; Admiral Messages
#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_PING           0x80
 
        ; 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
 
        ; Ping Responses
#define WAITING_IBUTTON                       0x01
#define WAITING_PAIR                          0x02
#define PAIRED                                        0x04
 
        ;game states
#define WaitForIbuttom 0x01
#define WaitForSync 0x07
#define Normal 0x02
#define StandDown 0x03
#define HardReset 0x04
#define SoftReset 0x05
#define Ping 0x06
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
#include "p16F690.inc"
__config (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC)
 
;variables
bytes_to_ignore equ 0x22   ;to store the address information received
message_received equ 0x23  ;to store the data received
message_to_send equ 0x24  ;to store the data to send
RFdata0_received equ 0x25   ;to store the data received
RFdata1_received equ 0x26   ;to store the data received   
RFdata2_received equ 0x27   ;to store the data received 
RFdata0_to_send equ 0x28   ;to store the data to_send
RFdata1_to_send equ 0x29   ;to store the data to_send   
RFdata2_to_send equ 0x2A   ;to store the data to_send 
Source_Address_First equ 0x2B ;the most significant byte to address
Source_Address_Second equ 0x2C ;the least significant byte to address
Destination_Address_First equ 0x2D ;the most significant byte to address
Destination_Address_Second equ 0x2E ;the least significant byte to address
 
drive_pump equ 0x30;  ;the re-structured data to send to the drive, pump control PIC through SPI
ID_stepper_servo equ 0x31; ;the re-structured data to send to the servo, stepper control PIC through SPI
team_ID equ 0x32; bit 6,7 indicate our boat's ID, the other bits are 0
 
temp equ 0x33; temporary space to store intermediate data
sum equ 0x34   ;to store the sum value
check_sum equ 0x35    ; to store the check sum value
 
MyHelmAddress equ 0x36  ;to store the least significant byte of paired helm address
GameState equ 0x37  ;game state
 
three_sec_timer_CNT equ 0x38
#define three_sec_timer_PER 0x72  ;=114
 
W_TEMP equ 0x70     ; to store w value for interrupts return
STATUS_TEMP equ 0x71  ; to store STATUS value for interrupts return
 
ReceiveIndex   equ     0x3F    ;the index to indicate where I am in the 11 byte frame
#define RX_START       0x40    ;Location of first byte received
;all ram space in between are used
#define RX_END  0x4B    ;Location of last byte received
 
COUNTER equ 0x60
COUNTER2 equ 0x61
 
;i-buttom variables
#define IBUTTON_PORT           PORTA
#define IBUTTON_PIN                           0
#define TRISIBUTTON                           TRISA
 
#define IBUTTON_INPUT          0x01
#define IBUTTON_OUTPUT         0x00
#define IBUTTON_HI                    0x01
#define IBUTTON_LO                    0x00
 
FIRST_BYTE             equ                            0x66
SECOND_BYTE            equ                            0x67
THIRD_BYTE             equ                            0x68
TEMP                   equ                            0x69
SECOND_BYTE_CHECK              equ                            0x6A
THIRD_BYTE_CHECK               equ                            0x6B
 
org 0
goto Main
org 4
goto ISR
org 5
 
;interrupt service routine
ISR: ;push
        movwf W_TEMP
        swapf STATUS, w
        movwf STATUS_TEMP
 
;test is RF receive interrupt
        banksel PIR1   ;bank 0
        btfsc PIR1, RCIF
        goto RF_Receive_INT
;test if timer0 interrupt
        btfsc INTCON, T0IF
        goto Timer_INT
;else jump out of interrupt
        goto end_of_INT
 
;RF receive interrupt service routine
RF_Receive_INT:
banksel RCREG  ;go to bank 0
;clear the 3 sec time out counter
        movlw 0x00
        movwf three_sec_timer_CNT
 
        movf    ReceiveIndex,W ;Load ReceiveIndex to FSR
        movwf   FSR     
 
        banksel        RCREG
        movf    RCREG,W ;Read data to W
 
        movwf   INDF    ;Store data in proper place
        movf INDF, w
        sublw   START_BYTE
        btfsc   STATUS,Z       ;Test for a start byte                
        call    index_zero
        call    IncReceive     ;Already in bank 0
        goto    end_of_INT
 
index_zero:
        movlw   RX_START
        movwf   ReceiveIndex
return  
 
;
;       Increments the ReceiveIndex variable to the next valid memory location
;
 
IncReceive:    
        banksel        RCREG
        movf    ReceiveIndex,W ;Test to see if index is at the end of
        sublw   RX_END  ;receive registers
        btfsc   STATUS,Z       ;If it is, load RX_START-1 into receive index
        call    CarryReceive
        incf    ReceiveIndex,F ;If index is not at end, increment receive index
 
        return
 
;
;       Called when Receive Index needs to be reset
;
 
CarryReceive:
        movlw   RX_START-1
        movwf   ReceiveIndex
        return
 
;timer0 interrupt service routine, for 3 sec time out
Timer_INT:
        BANKSEL three_sec_timer_CNT
        INCF three_sec_timer_CNT, f
        MOVF three_sec_timer_CNT, W    
        SUBLW three_sec_timer_PER
        BTFSS STATUS,Z                                                                      
        goto end_of_timer0_INT 
               
        CLRF three_sec_timer_CNT
;if three_sec_timer_CNT = 114, write navigation stop to RF data, no function calls
        ;toggle RC2 for debug
        banksel PORTC
        movf PORTC, w
        xorlw b'00000100'
        movwf PORTC    
 
        ;toggle RC1 for debug
        banksel PORTC
        movf PORTC, w
        xorlw b'00000010'
        movwf PORTC    
 
;write navigation 'stop' to RF data
        banksel RCREG  ;bank 0
        movlw 0x48
        movwf   FSR
        movlw 0x02
        movwf INDF
 
        movlw 0x49
        movwf   FSR
        movlw 0x88
        movwf INDF
 
        movlw 0x4A
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        
end_of_timer0_INT:
;clear TIMER0 flag
        bcf INTCON, T0IF
        goto end_of_INT
        
end_of_INT:
 
        swapf STATUS_TEMP, w
        movwf STATUS
        swapf W_TEMP, f
        swapf W_TEMP, w
        RETFIE
;end of INT function
 
 
;function to move address and data infromation into variables
Get_Data_Function:
        banksel RCREG  ;bank 0
        movlw 0x44
        movwf   FSR
        movf    INDF,W
        movwf Source_Address_First
 
        movlw 0x45
        movwf   FSR
        movf    INDF,W
        movwf Source_Address_Second
 
        movlw 0x48
        movwf   FSR
        movf    INDF,W
        movwf RFdata0_received
 
        movlw 0x49
        movwf   FSR
        movf    INDF,W
        movwf RFdata1_received
 
        movlw 0x4A
        movwf   FSR
        movf    INDF,W
        movwf RFdata2_received
return
 
;function to erase address and data infromation
;once this function is called, all 0s will be returned from Get_data_function, unless there has been another transmission
Erase_Data_Function:
        banksel RCREG  ;bank 0
        movlw 0x44
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        movlw 0x45
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        movlw 0x48
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        movlw 0x49
        movwf   FSR
        movlw 0x00
        movwf INDF
 
        movlw 0x4A
        movwf   FSR
        movlw 0x00
        movwf INDF
return
 
;initialization function
Init:
;init variables:
banksel RCREG  ;bank 0
movlw   RX_START
movwf   ReceiveIndex
 
;initialize timer 1, use internal oscillator by default
BSF T1CON, T1CKPS0   ;set timer 1 prescale to be 1:8
BSF T1CON, T1CKPS1
BSF T1CON, TMR1ON    ;turn on timer 1
 
BcF CCP1CON, CCP1M0  ;set port CCP1 for output compare
BsF CCP1CON, CCP1M1
BcF CCP1CON, CCP1M2
BsF CCP1CON, CCP1M3
 
;initialize timer 2, for output compare
movlw b'11111111'
movwf T2CON  ;set prescale and postscale of timer2 to be 16, and turn on timer2
 
;go to bank 2
BCF STATUS, 5
BSF STATUS, 6  
clrf ANSEL    ;set port A, B, C as non-analog pins
clrf ANSELH   ;set port A, B, C as non-analog pins
 
;go to bank 1
BSF STATUS, 5
BCF STATUS, 6 
;set RC6 as output to do slave select
;set RC7 for SPI output
;RC5 is input capture for transmitting start
;RC0 is general output for PIC select
MOVLW b'00100000'
MOVWF TRISC 
;set RB6 as output for SPI clock
bcf TRISB, 6
;set RB4 as input for SPI in
bsf TRISB, 4
 
;set PA0, PA1, PA2 as input for address reading  
BSF TRISA, 0
BSF TRISA, 1
BSF TRISA, 2
 
 
;initiate SCI:
;currently in bank 1
;set baud rate to be 9600:
bcf TXSTA, BRGH  ;BRGH=0
bcf TXSTA, SYNC  ;asynchronous
bsf BAUDCTL, BRG16 ;BRG16=1
movlw 0x40    ;SPBRG = 64
movwf SPBRG  ;baud rate = 9615
 
bsf TXSTA, TXEN ;enable transmission
 
;go to bank 0
BCF STATUS, 5
BCF STATUS, 6  
 
bsf RCSTA, SPEN  ;enable serial port
bsf RCSTA, CREN  ;enable receiving
 
;initiate SPI:
;setting timer2:
banksel PR2
movlw 0x30   ;TMR2 freq = Fosc/64/49
movwf PR2
banksel T2CON
movlw b'00000111' ;turn on timer2, prescaler 1:16, post scaler 1:1
movwf T2CON
 
                               BANKSEL                SSPSTAT
                               CLRF                   SSPSTAT                ;SMP = 0, CKE = 0
 
                               BANKSEL                SSPCON
                               MOVLW                  0x33                   ;SSPEN, CKP=1, CLK freq = TMR2 output/2
                               MOVWF                  SSPCON
 
                               BANKSEL                PIR1
                               BCF                            PIR1,SSPIF
;go back to bank 0
                               BANKSEL                SSPBUF
                               bsf PORTC, 0  ;select drive-pump control PIC
                               MOVF                   SSPBUF,w         ;receive and transmit OFF for the first time
                               MOVLW                  0x80
                               MOVWF                  SSPBUF
 
ClearReceiveReg:       
        BANKSEL RCREG   ; Make sure that the receive register is clear
        MOVF    RCREG,W
        BANKSEL PIR1
        BTFSC   PIR1,RCIF
        GOTO    ClearReceiveReg
                               
;interrupts enables
banksel INTCON
bsf INTCON, GIE  ;enable gloable interrupt enable
bsf INTCON, PEIE  ;enable peripheral interrupt enable
banksel PIE1
bsf PIE1, RCIE  ;enable SCI receive interrupt
banksel TXREG ;go back to bank 0
movlw 0x00
movwf PORTC  ;portC output all low
return
;end of function initialization
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;data transmit function
Transmit_Function:
        banksel RCREG ;bank 0
 
back3:
        btfss PIR1, TMR1IF  ;check timer, ensure that this transmit is more than 200ms later than last one
        goto back3
 
;send start byte
        movlw START_BYTE
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw LENGTH_MSB
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw LENGTH_LSB
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw API_TX
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw FRAME_ID
        movwf TXREG
        call wait_for_transmssion_over
 
        movf Destination_Address_First, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf Destination_Address_Second, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movlw 0x01   ;0x01 for the option byte, to not request acknowledgement
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata0_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata1_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
        movf RFdata2_to_send, w
        movwf TXREG
        call wait_for_transmssion_over
 
;calculate check sum value
        movlw 0x00
        movwf sum
        movlw API_TX
        addwf sum, f
        movlw FRAME_ID
        addwf sum, f
        movf Destination_Address_First, w
        addwf sum, f
        movf Destination_Address_Second, w
        addwf sum, f
        movlw 0x01
        addwf sum, f
        movf RFdata0_to_send, w
        addwf sum, f
        movf RFdata1_to_send, w
        addwf sum, f
        movf RFdata2_to_send, w
        addwf sum, f
;check_sum = 0xff - sum
        movf sum, w
        sublw 0xff
        movwf check_sum
        
        movf check_sum, w
        movwf TXREG
        call wait_for_transmssion_over
 
        bcf PIR1, TMR1IF   ;clear timer 1 flag
return
 
;the function to wait until the trasmit shift register of PIC is empty
wait_for_transmssion_over:
;goto bank 1
        BSF STATUS, 5
        BCF STATUS, 6 
 
wait_transmssion:
        btfsc TXSTA, TRMT
        goto end_of_wait_transmssion
        goto wait_transmssion
 
end_of_wait_transmssion:
;go back to bank 0
        BCF STATUS, 5
        BCF STATUS, 6 
return
;end of function wait_for_transmssion_over
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;i-buttom functions;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
LoadIButtonBytes:
                ; Set Ports A and C to digital
                BANKSEL         ANSEL
                CLRF            ANSEL
                               CLRF                   ANSELH
 
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
WaitForIButton:
                               ;CALL                  MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
                               
                               ;CALL                  LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Compensated_Wait500us
;;;;;;;;;;;;;;;code add by me to do admiral ping response;;;;;;;;;;;;;;;;;;;;;;
;the following code takes 15us to execute for 10MHz Crystal
        call Get_Data_Function
        movf RFdata0_received, w
        sublw ADMIRAL   ;check if the Header Data is for Admiral
        ;if (is Admiral), call Admiral function, else keep checking if it's other situation
        btfss STATUS, Z
goto No_ping
        
 
        movf RFdata2_received, w
        sublw ADMIRAL_PING ;check if the Header Data is for ADMIRAL_PING
        ;if (is ADMIRAL_PING), change game state
        btfsc STATUS, Z
goto No_ping
        call Erase_Data_Function
        call Ping_Respond_Function ;erase get_data value at the meantime
 
No_ping:
;;;;;;;;;;;;;;;code add by me to do admiral ping response;;;;;;;;;;;;;;;;;;;;;;
 
                               ;CALL                  MakeIBUTTONInput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_INPUT
                               MOVWF                  TRISIBUTTON
                               CALL                   Wait50us
 
                               ; Check if pin is LO --> iButton Present
                               BANKSEL                IBUTTON_PORT
                               BTFSC                  IBUTTON_PORT,IBUTTON_PIN
                               GOTO                   WaitForIButton ;Repeat until found
                               
                               ;Once found then:              
                               CALL                   ConductReset
                               
                               CALL                   ReadROM 
 
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               
                               BANKSEL                THIRD_BYTE
                               MOVF                   THIRD_BYTE,0
                               MOVWF                  FIRST_BYTE
 
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               
                               BANKSEL                THIRD_BYTE
                               MOVF                   THIRD_BYTE,0
                               MOVWF                  SECOND_BYTE
 
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
                               CALL                   ReadBit
 
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
 
                               return
 
 
ConductReset:
;                              CALL                   MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
;                              CALL                   LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait500us
;                              CALL                   RaiseIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BSF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait500us
                               RETURN
 
ReadROM:
; Send ReadROM command
; Need to send 0x33 = 00110011, LSB first
                               CALL                   SendIBUTTONHI
                               CALL                   SendIBUTTONHI
                               CALL                   SendIBUTTONLO
                               CALL                   SendIBUTTONLO
                               CALL                   SendIBUTTONHI
                               CALL                   SendIBUTTONHI
                               CALL                   SendIBUTTONLO
                               CALL                   SendIBUTTONLO
                               RETURN
 
ReadBit:
; Begin reading
;                              CALL                   MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
;                              CALL                   LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait5us
 
;                              CALL                   MakeIBUTTONInput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_INPUT
                               MOVWF                  TRISIBUTTON
 
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               
                               BANKSEL                IBUTTON_PORT
                               BTFSC                  IBUTTON_PORT,IBUTTON_PIN
                               GOTO                   RECEIVE_BIT_HI
                               GOTO                   RECEIVE_BIT_LO
RECEIVE_BIT_HI:
                               BANKSEL                THIRD_BYTE
                               RRF                            THIRD_BYTE,1
                               NOP
                               NOP
                               BSF                            THIRD_BYTE,7
                               CALL                   Wait60us
                               RETURN
 
RECEIVE_BIT_LO:
                               BANKSEL                THIRD_BYTE
                               RRF                            THIRD_BYTE,1
                               NOP
                               NOP
                               BCF                            THIRD_BYTE,7
                               CALL                   Wait50us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               RETURN
 
 
 
SendIBUTTONHI:
;                              CALL                   MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
;                              CALL                   LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait5us
 
;                              CALL                   MakeIBUTTONInput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_INPUT
                              MOVWF                  TRISIBUTTON
 
                               CALL                   Wait70us
 
                               RETURN
 
SendIBUTTONLO:
;                              CALL                   MakeIBUTTONOutput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_OUTPUT
                               MOVWF                  TRISIBUTTON
 
;                              CALL                   LowerIBUTTON
                               BANKSEL                IBUTTON_PORT
                               BCF                            IBUTTON_PORT,IBUTTON_PIN
 
                               CALL                   Wait60us
 
;                              CALL                   MakeIBUTTONInput
                               BANKSEL                TRISIBUTTON
                               MOVLW                  IBUTTON_INPUT
                               MOVWF                  TRISIBUTTON
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               RETURN         
 
Wait5us:
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
                               RETURN
 
Wait1s:
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
                               CALL                   Wait500us
 
 
        
 
Wait500us:
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               RETURN
 
Compensated_Wait500us:
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait50us
                               CALL                   Wait5us
                               ;CALL                  Wait5us
                               ;CALL                  Wait5us
                               ;CALL                  Wait5us
                               RETURN
 
Wait50us:
                              CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
                               NOP
 
                              RETURN
 
Wait70us:
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               NOP
                               NOP
                               NOP
                               NOP
 
                               RETURN
 
Wait60us:
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               CALL                   Wait5us
                               CALL                   Wait5us
                               CALL                   Wait5us
 
                               CALL                   Wait5us
                               
                               RETURN
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;Game Control Function;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Game_Control:
        banksel RCREG  ;bank 0
        movf GameState, w
        sublw WaitForIbuttom
        btfsc STATUS, Z
        goto Wait_For_Ibuttom_State  ;wait for i-buttom state
 
        banksel RCREG  ;bank 0
        movf GameState, w
        sublw WaitForSync
        btfsc STATUS, Z
        goto Wait_For_Sync_State  ;have read i-buttom, wait for syncronize state
 
        movf GameState, w
        sublw Normal 
        btfsc STATUS, Z
        goto Normal_State  ;normal game state
 
        movf GameState, w
        sublw StandDown
        btfsc STATUS, Z
        goto Stand_Down_State  ;stand down game state
 
        movf GameState, w
        sublw HardReset
        btfsc STATUS, Z
        goto Hard_Reset_State  ;hard_reset game state
 
        movf GameState, w
        sublw SoftReset
        btfsc STATUS, Z
        goto Soft_Reset_State  ;soft_reset game state
 
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;Game State Functions;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;the wait for ibuttom state
Wait_For_Ibuttom_State:
        banksel RCREG   ;bank 0
retest_ibuttom:
        call LoadIButtonBytes
        ;store the first i-buttom reading also in another place for later comparison
        movf SECOND_BYTE, w
        movwf SECOND_BYTE_CHECK
        movf THIRD_BYTE, w
        movwf THIRD_BYTE_CHECK
 
        ;ibuttom reading for second time
        call LoadIButtonBytes
        ;check if reading is the same with last time
        movf SECOND_BYTE, w
        subwf SECOND_BYTE_CHECK, w
        btfss STATUS, Z
goto retest_ibuttom
        movf THIRD_BYTE, w
        subwf THIRD_BYTE_CHECK, w
        btfss STATUS, Z
goto retest_ibuttom
 
        ;ibuttom reading for third time
        call LoadIButtonBytes
        ;check if reading is the same with last time
        movf SECOND_BYTE, w
        subwf SECOND_BYTE_CHECK, w
        btfss STATUS, Z
goto retest_ibuttom
        movf THIRD_BYTE, w
        subwf THIRD_BYTE_CHECK, w
        btfss STATUS, Z
goto retest_ibuttom
 
        movf THIRD_BYTE, w
        sublw 0x00
        btfsc STATUS, Z
goto retest_ibuttom
 
        movf THIRD_BYTE, w
        sublw 0xFF
        btfsc STATUS, Z
goto retest_ibuttom
 
        movlw WaitForSync
        movwf GameState
return
 
;once read i-buttom, try to match with my helm
Wait_For_Sync_State:
        banksel RCREG  ;bank 0
        call Get_Data_Function  ;get the rf data
;if i-buttom
        movf RFdata0_received, w
        sublw IBUTTON 
        btfsc STATUS, Z
goto check_ibuttom
 
;if admiral ping
        movf RFdata0_received, w
        sublw ADMIRAL   ;check if the Header Data is for Admiral
        btfsc STATUS, Z
goto respond_admiral
return
 
check_ibuttom:
        movf THIRD_BYTE, w
        subwf RFdata1_received, w
        btfss STATUS, Z
return
 
        movf SECOND_BYTE, w
        subwf RFdata2_received, w
        btfss STATUS, Z
return
 
        ;if reach here, mean it's my helm's signal, record it's address
        movf Source_Address_Second, w
        movwf MyHelmAddress
 
        ;send back MATCHED signal
        movlw HELM_MSB
        movwf Destination_Address_First
        movf MyHelmAddress, w
        movwf Destination_Address_Second
        movlw WATERCRAFT
        movwf RFdata0_to_send
        movlw MATCHED_1
        movwf RFdata1_to_send
        movlw MATCHED_2
        movwf RFdata2_to_send
        call Transmit_Function 
 
        ;go to in-game state
        movlw Normal
        movwf GameState
 
;turn on timer0 for 3 sec time out
        banksel OPTION_REG ;bank 1
        movlw b'00000111'
        movwf OPTION_REG
        banksel RCREG ;bank 0
        movlw 0x00
        movwf three_sec_timer_CNT
;enable timer0 interrupt
        bsf INTCON, T0IE
;show team affiliation on the boat
        call Determine_team  
return
 
respond_admiral:
        movf RFdata2_received, w
        sublw ADMIRAL_PING ;check if the Header Data is for ADMIRAL_PING
        btfsc STATUS, Z
        call Ping_Respond_Function
        call Erase_Data_Function
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;function to decide which team I'm in based on i-buttom reading
Determine_team:
        banksel RCREG  ;bank 0
        btfsc SECOND_BYTE, 0  ;test if even or odd number
        goto red
        goto blue
return
 
red:
        bsf PORTC, 1
        bcf PORTC, 2
return
 
blue:
        bsf PORTC, 2
        bcf PORTC, 1
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;general in-game state
Normal_State:
        banksel RCREG  ;bank 0
        call Determine_team 
        call Get_Data_Function  ;get the rf data
 
        movf RFdata0_received, w
        sublw IBUTTON ;check if the Header Data is for I-buttom
        ;if (is I-buttom), call i-buttom function, else keep checking if it's other situation
        btfsc STATUS, Z
        goto I_Buttom_Respond
 
        movf RFdata0_received, w
        sublw NAVIGATION ;check if the Header Data is for navigation
        ;if (is navigation), call navigation function, else keep checking if it's other situation
        btfsc STATUS, Z
        goto Navigation_Function
 
        movf RFdata0_received, w
        sublw ADMIRAL   ;check if the Header Data is for Admiral
        ;if (is Admiral), call Admiral function, else keep checking if it's other situation
        btfsc STATUS, Z
        goto Admiral_Function
return
 
;3 possible commands the boat is likely to receive and respond to: ibuttom, navigation, and admiral:
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I_Buttom_Respond:
;first check if the i-buttom boadcast is from my helm, if not, discard
        banksel RCREG  ;bank 0
        movf Source_Address_Second, w
        sublw MyHelmAddress
        btfss STATUS, Z
return  ;if address is not my helm's, just return
        ;if address is my helm's, send MATCH to it again
        movlw HELM_MSB
        movwf Destination_Address_First
        movf MyHelmAddress, w
        movwf Destination_Address_Second
        movlw WATERCRAFT
        movwf RFdata0_to_send
        movlw MATCHED_1
        movwf RFdata1_to_send
        movlw MATCHED_2
        movwf RFdata2_to_send
        call Transmit_Function 
return
;end of function Normal_State
 
 
Navigation_Function:
banksel TXREG  ;bank 0
 
        movf Source_Address_Second, w
        sublw MyHelmAddress     ;check if the Navigation Data is really from my helm
        ;to prevent responding to other guys' possible bad signal
        btfss STATUS, Z
        ;if not from my helm, just jump out of function
return
 
;re-structure the RFdata1 and RFdata2 to get drive_pump byte
movf RFdata1_received, w
movwf drive_pump
swapf drive_pump, f  ;now the drive signal is in upper 4 bits
movlw 0xF0
andwf drive_pump, f  ;now the lower 4 bits in drive_pump are all 0's
movf RFdata2_received, w
movwf temp
movlw 0x0F
andwf temp, f  ;now the upper 4 bits in temp are all 0's
movf temp, w
iorwf drive_pump, f  ;now the upper 4 bits is drive signal, lower 4 bits are the pump signal, ready to send through SPI
 
 
;re-structure the RFdata1 and RFdata2 to get ID_stepper_servo byte
movf team_ID, w
movwf ID_stepper_servo ;upper 2 bits in ID_stepper_servo is team ID
movlw b'11000000'
andwf ID_stepper_servo, f  ;ensure the lower 6 bits in ID_stepper_servo are all 0's
movf RFdata2_received, w
movwf temp
movlw b'00110000'
andwf temp, f  ;now the upper 2 bits and lower 4 bits in temp are all 0's
movf temp, w
iorwf ID_stepper_servo, f ;now ID and stepper information is in ID_stepper_servo
movf RFdata1_received, w
movwf temp
swapf temp, f  ;now the direction signal is in lower 4 bits of temp
movlw b'00001111'
andwf temp, f  ;now the upper 4 bits in temp are all 0's
movf temp, w
iorwf ID_stepper_servo, f ;now ID and stepper and direction information are in ID_stepper_servo, ready to send through SPI
 
;send the re-structured data to Mark's two PICs
call Talk_To_Mark
 
return
;end of Navigation_Function
 
;the function to talk to mark's two PICs
Talk_To_Mark:
        banksel TXREG  ;bank 0
        bsf PORTC, 0  ;select drive-pump control PIC
        ;wait for SPI ready to send new data
        BANKSEL SSPSTAT
        wait_for_SPI1:
        BTFSS SSPSTAT,BF       ;Wait for last receive complete
        GOTO wait_for_SPI1
        BANKSEL SSPBUF         ;Get received data
        MOVF SSPBUF,w
        movf drive_pump, w
        movwf SSPBUF  ;send data to PIC1 trough SPI
 
        bcf PIR1, TMR1IF  ;clear the output compare flag
        before:             
        btfss PIR1, TMR1IF
        goto before
 
        bcf PORTC, 0  ;select ID_stepper_servo control PIC
        ;wait for SPI ready to send new data
        BANKSEL SSPSTAT
        wait_for_SPI2:
        BTFSS SSPSTAT,BF       ;Wait for last receive complete
        GOTO wait_for_SPI2
        BANKSEL SSPBUF         ;Get received data
        MOVF SSPBUF,w
        movf ID_stepper_servo, w
        movwf SSPBUF  ;send data to PIC2 trough SPI
 
        bcf PIR1, TMR1IF  ;clear the output compare flag
        before2:
        btfss PIR1, TMR1IF
        goto before2
return
;end of talk to mark
 
 
Admiral_Function:
        banksel RCREG  ;bank 0
 
        movf RFdata2_received, w
        sublw STAND_DOWN ;check if the Header Data is for stand-down
        ;if (is stand-down), change game state
        btfsc STATUS, Z
        goto case_stand_down
 
        movf RFdata2_received, w
        sublw HARD_RESET ;check if the Header Data is for HARD_RESET
        ;if (is HARD_RESET), change game state
        btfsc STATUS, Z
        goto case_hard_reset
 
        movf RFdata2_received, w
        sublw ADMIRAL_PING ;check if the Header Data is for ADMIRAL_PING
        ;if (is ADMIRAL_PING), change game state
        btfsc STATUS, Z
        goto case_admiral_ping
 
        movf RFdata2_received, w
        sublw SOFT_RESET ;check if the Header Data is for SOFT_RESET
        ;if (is SOFT_RESET), change game state
        btfsc STATUS, Z
        goto case_soft_reset
return
 
case_stand_down:
        movlw StandDown
        movwf GameState
return
 
case_hard_reset:
        movlw HardReset
        movwf GameState
return
 
case_soft_reset:
        movlw SoftReset
        movwf GameState
return
 
case_admiral_ping:
        call Erase_Data_Function
        call Ping_Respond_Function
return
;end of Admiral_Function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Stand_Down_State:
        banksel RCREG
        call StopBoat   ;stop all actuators
 
        ;acknowledge to the admiral
        movlw ADMIRAL_ADDRESS_MSB
        movwf Destination_Address_First
        movlw ADMIRAL_ADDRESS_LSB
        movwf Destination_Address_Second
        movlw ACK
        movwf RFdata0_to_send
        movlw 0x00
        movwf RFdata1_to_send
        movlw 0x01
        movwf RFdata2_to_send
        call Transmit_Function
 
        movlw HELM_MSB
        movwf Destination_Address_First
        movf MyHelmAddress, w
        movwf Destination_Address_Second
        movlw WATERCRAFT
        movwf RFdata0_to_send
        movlw STAND_DOWN_RECEIVED_1
        movwf RFdata1_to_send
        movlw STAND_DOWN_RECEIVED_2
        movwf RFdata2_to_send
        call Transmit_Function
 
        ;check if helm acknowledges
        call Get_Data_Function
        movf RFdata0_received, w
        sublw ACK
        btfsc STATUS, Z
        goto HelmAcked  ;normal game state
return
 
HelmAcked:
        movlw Normal   ;game state go back to normal
        movwf GameState
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Hard_Reset_State:
        banksel RCREG
        call StopBoat   ;stop all actuators
        movlw WaitForIbuttom   ;game state go back to waiting for i-buttom
        movwf GameState
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Soft_Reset_State:
        banksel RCREG
        call StopBoat   ;stop all actuators
        ;send back acknowledgement
        movlw ADMIRAL_ADDRESS_MSB
        movwf Destination_Address_First
        movlw ADMIRAL_ADDRESS_LSB
        movwf Destination_Address_Second
        movlw ACK
        movwf RFdata0_to_send
        movf RFdata1_received, w
        movwf RFdata1_to_send
        movf RFdata2_received, w
        movwf RFdata2_to_send
        call Transmit_Function
        movlw Normal   ;game state go back to normal
        movwf GameState
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
Ping_Respond_Function:
        banksel RCREG  ;bank 0
        movlw ADMIRAL_ADDRESS_MSB
        movwf Destination_Address_First
        movlw ADMIRAL_ADDRESS_LSB
        movwf Destination_Address_Second
        movlw PING_RESPONSE
        movwf RFdata0_to_send
 
        movf GameState, w
        sublw WaitForIbuttom
        btfsc STATUS, Z
        goto no_ibuttom  ;normal game state
 
        movf GameState, w
        sublw WaitForSync
        btfsc STATUS, Z
        goto Unpaired  ;normal game state
 
        movlw 0x04
        movwf RFdata1_to_send
        movf MyHelmAddress, w
        movwf RFdata2_to_send
        call Transmit_Function 
return
 
no_ibuttom:
        movlw 0x01
        movwf RFdata1_to_send
        movlw 0x00
        movwf RFdata2_to_send
        call Transmit_Function
return  
 
Unpaired:
        movlw 0x02
        movwf RFdata1_to_send
        movlw 0x00
        movwf RFdata2_to_send
        call Transmit_Function
return  
        
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
StopBoat:
        banksel RCREG
        movlw 0x80  ;boat stop, pump off
        movwf drive_pump
        movlw 0x08  ;team ID led off, stepper off, servo rest in the middle
        movwf ID_stepper_servo
        call Talk_To_Mark
return
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 
Main:
 
;delay to wait for power up
LONG_DELAY:
        movlw   0xFF           ; ~16ms        
        movwf   COUNTER
LOOP3:  
        movlw   0xFF
        nop
        nop
        nop                    
        movwf   COUNTER2
LOOP2:  
        decfsz  COUNTER2,f
        goto    LOOP2          
 
 
        decfsz  COUNTER,f
        goto    LOOP3
        
;Input capture Init, I/O pins Init, SCI Init
call Init
 
;initial game state
movlw WaitForIbuttom
movwf GameState
movlw 0x09
movwf MyHelmAddress
 
movlw 0xab
movwf SECOND_BYTE
movlw 0xab
movwf THIRD_BYTE
 
movlw 0x00
movwf RFdata0_received             
movlw 0x00
movwf RFdata1_received
movlw 0x00
movwf RFdata2_received
 
movlw 0x00
movwf RFdata0_to_send          
movlw 0x00
movwf RFdata1_to_send   
movlw 0x00
movwf RFdata2_to_send   
 
movlw 0x00
movwf team_ID
call StopBoat
Loop:
 
call Game_Control
;call Normal_State
 
;call Wait_For_Sync_State
;call Navigation_Function
;       call Get_Data_Function  ;get the rf data
;call Talk_To_Mark
;call Transmit_Function
 
;       movf RFdata0_received, w
;       sublw ADMIRAL   ;check if the Header Data is for Admiral
        ;if (is Admiral), call Admiral function, else keep checking if it's other situation
;       btfss STATUS, Z
;goto Loop
 
;       movf RFdata2_received, w
;       sublw ADMIRAL_PING ;check if the Header Data is for ADMIRAL_PING
        ;if (is ADMIRAL_PING), change game state
;       btfss STATUS, Z
;goto Loop
 
;       call Ping_Respond_Function
 
 
goto Loop
 
END

 

 

 

 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Propeller / Pump Chip Pseudocode

 

Purpose – To set a PWM duty cycle for a propeller and pump based on data received through SPI on a PIC 16F690. We desire two channels so it will be software driven since hardware supports only 1 channel of PWM

 

Module Level Defines:

·          TMR2_SCALE,  prescaler, etc. to set Freq = 5 MHz

·          TMR2_PER,  number of clock ticks

·          PWM_FULL,  designates resolution of PWM duty cycle

·          PORTC_RESET,  designates which pins are used for PWM

·          COUNTER,  for-loop index

·          PARSE_REG,  location for next command to be parsed

·          PWM1,  duty cycle for PWM chan 1

·          PWM2,  duty cycle for PWM chan 2

·          TMR_COUNTER,  for-loop index

·          TMR_COUNTER2,  for-loop index

 

Main:

·          Wait for chip to start-up completely

·          Initialize Pins:

§         Set all to digital

§         Set all to output, except C6, B4-6 (clock, data-in, SS)

§         Clear PWM registers

·          Initialize SSP:

§         SMP = 0, CKE = 0, CKP = 1

§         SS enabled, Slave

·          Initialize Timer2

§         Set prescaler and post scaler to get >20 kHz freq

§         Clear Timer2 interrupt flag

·          Raise all lines enabled for PWM

·          Parse the initial values for the PWM channels

·          Loop through expirations of the timer

·          Whenever timer has expired a number of times equal to a PWM duty cycle, lower that line

·          Whenever timer has expired a number of times equal to the full PWM period, raise all lines

·          Continually check for new command from SPI

Parse:

·          MSB of  command sets direction for propeller

·          Next 3 MSBs set the 3 bit duty cycle of PWM1

·          4 LSBs indicate pump PWM. Ignore LSB and set 3 MSBs as PWM2 duty cycle

 

 

Back to Top!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Propeller / Pump Chip Code Listing

 

                list            P=PIC16F690

                #include "p16F690.inc"            

                __config        (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC)

 

                org             0

                GOTO            Main

                org             5

 

TMR2_SCALE                    equ                                                       b'00000100'         ; Freq = 20 Mhz/4 *(1/1)*(1/1)

TMR2_PER                         equ                                                       b'00000001'         ;Set timer period

 

PWM_FULL                        equ                                                       b'00000111' ; number of timer expirations for a full PWM period

PORTC_RESET                 equ                                                       b'00000111' ; what to write to port c at start of each period

 

; PWM REGISTERS

COUNTER                                          equ                                                       0x20

PARSE_REG                     equ                                                       0x21                      ; register for command from SPI

PWM1                                  equ                                                       0x22                      ; duty for the propeller

PWM2                                  equ                                                       0x23                      ; duty for the pump

 

; DELAY TIMER

TMR_COUNTER                equ                                                       0x24                      ; for-loop index

TMR_COUNTER2              equ                                                       0x25                      ; for-loop index

 

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

 

Main:

                               CALL                    LONG_DELAY    ; wait for chip to start up

        CALL        InitPins       ; Initialize pins

                               CALL                    InitSSP                  ; Init SPI

        BANKSEL                   PIR1                      ;Start with timer not expired

                               BCF                                      PIR1,TMR2IF

 

                               ; Initialize Timer for Freq > 20 kHz

                               BANKSEL                           T2CON

                               MOVLW                               TMR2_SCALE    ;Set the scalers                  

                               MOVWF                               T2CON

                               BANKSEL                           PR2                      

                               MOVLW                               TMR2_PER          ;Set the period

                               MOVWF                               PR2

 

                               ; Raise all lines for PWM

                               BANKSEL                           PORTC

                               MOVLW                               PORTC_RESET

                               MOVWF                               PORTC

                               BANKSEL                           COUNTER

                               CLRF                    COUNTER

 

                               ;Set INITIAL SPEED AND WATER POWER

                               ; Each PWM set to duty = 0

                               BANKSEL                           PARSE_REG

                               MOVLW                               b'10000000'

                               MOVWF                               PARSE_REG

                               ; Command parsed - loaded into PWM duty cycle registers

                               CALL                    PARSE 

 

                               ; Skip SPI read and timer expire for first reading

                               GOTO                   ENTER_PWM

 

DO_PWM:

                               ;Check for a new PWM setting

                               BANKSEL                           SSPSTAT

                               BTFSS                  SSPSTAT,BF      ;Wait for receive complete

                               GOTO                   NO_SETTING

                              

                               ; Put received byte into location for next command to parse

                               BANKSEL                           SSPBUF

                               MOVF                   SSPBUF,W

                               BANKSEL                           PARSE_REG                     

                               MOVWF                               PARSE_REG

 

                               ; Write the same data back to the buffer, minus one

                               BANKSEL                           SSPBUF

                               ADDLW                0xFF

                               MOVWF                               SSPBUF

                               ; Used for testing validity of received data

 

                               ; Only parse data if the PIC is selected

                               BANKSEL                           PORTB

                               BTFSC                 PORTB,5                             ; Check if SS enabled

                               CALL                    PARSE

 

                               GOTO                   NO_SETTING

 

NO_SETTING:

                               BANKSEL                           PIR1

                               BTFSS                  PIR1,TMR2IF       ;Wait for expire

                               GOTO                   $-1

                               BCF                                      PIR1,TMR2IF       ;Clear expire

                               ; With current timner period this expiration is nearly equivalent to a single NOP

 

                               ; counter ++

                               BANKSEL                           COUNTER

                               INCF                      COUNTER, W

                               MOVWF                               COUNTER

 

ENTER_PWM:

                               BANKSEL                           COUNTER

                               MOVF                   COUNTER,W      

                               SUBLW                PWM_FULL

                               ; If counter = pwm full

                               BTFSC                 STATUS,Z

                              ; raise all PWM lines

                               CALL                    RAISE_ALL_ACTIVE

 

                               BANKSEL                           COUNTER

                               MOVF                   COUNTER,W      

                               SUBWF                PWM1,0                              

                               ; If counter = PWM 1 duty

                               BTFSC                 STATUS,Z

                               ; Lower PWM 1

                               CALL                    LOWER_PWM1

 

                               BANKSEL                           COUNTER

                               MOVF                   COUNTER,W

                               SUBWF                PWM2,0                              

                               ; If counter = pwm 2 duty

                               BTFSC                 STATUS,Z

                               ; Lower PWM 2

                               CALL                    LOWER_PWM2

 

                               ; Repeat -- look for new command, then handle timer

                               GOTO                   DO_PWM            

 

; PWM1 is at port C0

LOWER_PWM1:

                               BANKSEL                           PORTC

                               BCF                                      PORTC,0

                               RETURN

 

' PWM2 is at port C1

LOWER_PWM2:

                               BANKSEL                           PORTC

                               BCF                                      PORTC,1

                               RETURN

 

; Check which PWM lines are not set to duty = 0

; Raise only those lines that are active

RAISE_ALL_ACTIVE:

                               ; Check for any active PWM lines

                               ; Makes sure duty cycle of 0 is upheld

                               BANKSEL                           PWM1

                               MOVF                   PWM1,1

                              BTFSS                  STATUS,Z

                               BSF                                      PORTC,0

 

                               MOVF                   PWM1,1

                               BTFSC                 STATUS,Z

                               BCF                                      PORTC,0

 

                               MOVF                   PWM2,1

                               BTFSS                  STATUS,Z

                               BSF                                      PORTC,1

 

                               MOVF                   PWM2,1

                               BTFSC                 STATUS,Z

                               BCF                                      PORTC,1

 

;  Reset counter for start of next period

                               BANKSEL                           COUNTER

                               CLRF                    COUNTER

                               GOTO                   ENTER_PWM

 

 

PARSE:

               ; Handle command received by SPI

                               CALL                    SET_DRIVE_PWM                          

                               CALL                    SET_PUMP_PWM

                               RETURN

 

; Handle 4 MSBs

SET_DRIVE_PWM:

                               BANKSEL                           PARSE_REG

                               ; MSB controls direction

                               BTFSC                 PARSE_REG,7

                               GOTO                   FORWARD

                               GOTO                   REVERSE

 

FORWARD:

                               BANKSEL                           PORTC

                               ; direction sets value on IN1 and IN2 on H-bridge

                               BSF                                      PORTC,3

                               BANKSEL                           PARSE_REG

                               SWAPF                PARSE_REG,0

                               ANDLW                b'00000111'

                               ; Write bits 4-6 to PWM1 duty cycle

                               MOVWF                               PWM1

                               MOVWF                               PORTA ; for debugging

                               RETURN

                              

REVERSE:                         

                               BANKSEL                           PORTC

                               ; direction sets value on IN1 and IN2 for H-bridge

                               BCF                                      PORTC,3

                               BANKSEL                           PARSE_REG

                               SWAPF                PARSE_REG,0

                               ; duty cycle is inverted for reverse, 000 is full reverse

                               ;                                                                                   111 is zero reverse

                               XORLW                b'00000111'         ; toggle to get duty cycle

                               ANDLW                b'00000111' ; but only last 3 bits

                               MOVWF                               PWM1

                               MOVWF                               PORTA

                               RETURN

 

; 4 LSBs control pump PWM

; LSB discarded to keep 3 bit PWM

SET_PUMP_PWM:

                               BANKSEL                           PARSE_REG

                               RRF                                      PARSE_REG,0

                               ANDLW                b'00000111'

                               BANKSEL                           PWM2

                               MOVWF                               PWM2

                               RETURN

 

 

; Arbitrary long delay

LONG_DELAY:

                               CALL                    DELAY

                               CALL                    DELAY

                               CALL                    DELAY

                               CALL                    DELAY

                               CALL                    DELAY

                               RETURN                             

 

DELAY:

               movlw     0xFF                      ; ~16ms                

               movwf    TMR_COUNTER

LOOP3:

               movlw     0xFF                                    

               movwf    TMR_COUNTER2

LOOP2:

               decfsz    TMR_COUNTER2,f

               goto        LOOP2                

 

               decfsz    TMR_COUNTER,f

               goto        LOOP3

              

               return                    

                              

 

 

 

; Initialization sequence

InitPins:

                ; Set Ports A and C to digital

                BANKSEL         ANSEL

                CLRF            ANSEL

                                                             CLRF                                   ANSELH

 

                                                             ; Set Data Directions

                                                             BANKSEL                                           TRISA

                                                             CLRF                                   TRISA

                                                             CLRF                                   TRISB

                                                             CLRF                                   TRISC

                                                             BSF                                                     TRISC,6                ; SS

                                                             BSF                                                     TRISB,5                ; PIC select = SS

                                                             BSF                                                     TRISB,6                ; clock

                                                             BSF                                                     TRISB,4                ; data in

 

                                                             ; Clear all PWM values

                                                             BANKSEL                                           PWM1

                                                             CLRF                                   PWM1

                                                             CLRF                                   PARSE_REG

                                                             CLRF                                   PWM2

 

                RETURN

 

 

InitSSP:

                                                             BANKSEL                                           SSPSTAT

                                                             CLRF                                   SSPSTAT                                           ;SMP = 0, CKE = 0

 

                                                             BANKSEL                                           SSPCON

                                                             BSF                                                     SSPCON,SSPEN

                                                             BSF                                                     SSPCON,CKP

                                                             BSF                                                     SSPCON,SSPM2

                                                             ; CKP = 1

                                                             ; SS enabled, Slave

                                                            

                                                             ; Read and write buffer once to insure it is fresh

                                                             BANKSEL                                           SSPBUF

                                                             MOVF                                  SSPBUF,W

                                                             MOVWF                                              SSPBUF

 

                                                             RETURN

 

                END

 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Rudder / Turret Chip Pseudocode

 

Purpose – To set a the servo angle and make the turret step based on commands received via SPI on the PIC16F690.

 

Main:

·          Wait for chip to start-up completely

·          Initialize Pins:

§         Set all to digital

§         Set all to output, except C6, B4-6 (clock, data-in, SS)

§         Clear PWM registers

·          Initialize SSP:

§         SMP = 0, CKE = 0, CKP = 1

§         SS enabled, Slave

·          Parse the initial values

·          Loop through a counter

·          Whenever counter reaches a number of times equal to a PWM duty cycle, lower that line

·          Take a step each period if it has been requested

·          De-energize stepper if hasn’t changed in a while

·          Continually check for new command from SPI

Parse:

·          Bits 4 and 5 set which direction and whether or not to step

·          Bits 0-3 set the servo angle

 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Rudder / Turret Chip Code Listing

 

                list            P=PIC16F690

                #include "p16F690.inc"            

                __config        (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC)

 

                org             0

                GOTO            Main

                org             5

 

PWM_FULL                        equ                                                       b'00001111';d'31'

DUTY_MASK                      equ                                                       b'00001111'

 

; PWM stuff

COUNTER1                        equ                                                       0x22

COUNTER2                        equ                                                       0x23

COUNTER1_INIT                equ                                                       b'11100000'  ; controls frequency of servo

PULSE_PERIOD               equ                                                       b'00011111'         ; full length of period including hi and lo time

PULSE_WIDTH                  equ                                                       0x24                      ; currently commanded length of pulse width, from 0 to 16

PULSE_WIDTH_OFFSET               equ                                       b'00001110'  ; controls offset. Adds to pulse_width to prevent jamming servo at edges

 

; Stepper

STEPS_LEFT                     equ                                                       0x25       ; number of steps still to take

STEP_DIR                           equ                                                       0x26       ;bit 0 is HI for Forward Step, LO for Reverse Step

C_TEMP                                             equ                                                       0x27      

STEP_INDEX                     equ                                                       0x28       ; current index in step table

STEP_OFF_COUNT         equ                                                       0x2B       ; number of cycles no step has occurred

STEP_OFF                         equ                                                       b'00001111'         ; value to write stepper to de-energize

STEPS_TAKEN                 equ                                                       0x2C      ; running counter of number of steps taken. Used to prevent winding

MAX_STEPS                      equ                                       b'00001111'         ; only allow 15 steps to right

MIN_STEPS                        equ                                                       b'11110000'  ; only allow a displacement of 15 steps to the left

 

;Delay timer

TMR_COUNTER                equ                                                       0x29

TMR_COUNTER2              equ                                                       0x2A

 

; COM REGISTERS

PARSE_REG                     equ                                                       0x21       ; next command to parse

 

 

; LOOKUP TABLE

FullStep:

                ADDWF           PCL,F                      

                RETLW           b'00000110'              ;Step 0

                RETLW           b'00001010'              ;     1

                RETLW           b'00001001'              ;     2

                RETLW           b'00000101'              ;     3

 

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

 

Main:

                               CALL                    LONG_DELAY    ; wait for chip to start up

        CALL        InitPins       ;Initialize pins

                               CALL                    InitSSP                  ; Initialize SPI

              

; Set up counters for the Servo pulse-width   

                               BANKSEL                           COUNTER1

                               MOVLW                               COUNTER1_INIT

                               MOVWF                               COUNTER1

                               CLRF                    COUNTER2

 

; Set up stepper indexing

                               CLRF                    STEP_INDEX

                               CLRF                    STEPS_LEFT

                               CLRF                    STEP_OFF_COUNT

                               CLRF                    STEPS_TAKEN 

                               CLRF                    PULSE_WIDTH

 

; Initial values to set everything:

; take 1 step right

; center the rudder

                              BANKSEL                           PARSE_REG

                               MOVLW                               b'10011000'         ;Run servo with pulse width ~1.5 ms, take 1 step,led2 on

                               MOVWF                               PARSE_REG

                               CALL                    PARSE 

 

LOOP:

 

CHECK:

                               ;Check for a new PWM setting

                               BANKSEL                           SSPSTAT

                               BTFSS                  SSPSTAT,BF      ;Wait for receive complete

                               GOTO                   AFTER_PARSE

              

                               BANKSEL                           SSPBUF                              ;if ssp flag set

                               MOVF                   SSPBUF,W          ;read ssp

                               BANKSEL                           PARSE_REG     

                               MOVWF                               PARSE_REG      ;move to parse register

 

                               ; subtract one for debugging

                               BANKSEL                           SSPBUF

                               ADDLW                0xFF                      ;write dummy reply into SSP buffer

                               MOVWF                               SSPBUF

 

                               ; check to see if pic has ben enabled

                               BANKSEL                           PORTB

                               BTFSS                  PORTB,5                             ; Check if SS enabled

                               CALL                    PARSE                 ;parse if this pic selected

 

 

AFTER_PARSE:

 

                               ; Servo Pulse-Width counter

                               BANKSEL                           COUNTER1

                               INCFSZ                 COUNTER1,1      ;increment servo counter

                              GOTO                   LOOP                    ;if counter not 0 return

 

                               ;Reset counter 1

                               BANKSEL                           COUNTER1

                               MOVLW                               COUNTER1_INIT                ;reinitialize counter

                               MOVWF                               COUNTER1

                               INCF                      COUNTER2,1                     ;increment second counter

 

                               ; Check if an entire period has expired, thus requiring to set the line HI for new period

                               MOVF                   COUNTER2,W                   

                               SUBWF                PULSE_PERIOD,W           ;check if counter 2 has reached pulse period

                               BTFSS                  STATUS,Z

                               ; If entire period has not expired, then we must check if the pulse width has expired

                               GOTO                   LOWER_PULSE                ;lower pulse if period not over

                              

                               ; If it has expired, set servo pin high and take a single step

                               BANKSEL                           PORTC

                               BSF                                      PORTC,4                                            ;set servo pin high

 

                               CALL                    TakeStep

 

                               BANKSEL                           COUNTER2                                                                                                                        ;clear counter2

                               CLRF                    COUNTER2

                               GOTO                   LOOP

 

 

LOWER_PULSE:              

                               BANKSEL                           COUNTER2

                               MOVF                   COUNTER2,W                   

                               SUBWF                PULSE_WIDTH,W                             ;check if counter 2 has reached pulse width requested by SPI

                               BTFSS                  STATUS,Z

                               GOTO                   LOOP                   

                               BANKSEL                           PORTC

                               BCF                                      PORTC,4

                               GOTO                   LOOP

 

 

TakeStep:

                               ;Don't step if no steps are left

                               BANKSEL                           STEPS_LEFT

                               MOVF                   STEPS_LEFT,1                                                                                                             ;move steps_left to itself

                               BTFSC                 STATUS,Z                                                                                                                          ;check if it was zero

                               GOTO                   TurnStepperOffTimer                                                                                                     ;De-energize coils if not taking steps

 

                               ;If steps have been requested, but at angle limit,

                               ;              ignore one direction

                               BANKSEL                           STEP_DIR

                               BTFSS                  STEP_DIR,0

                               GOTO                   HANDLE_REVERSE

                               GOTO                   HANDLE_FORWARD

 

HANDLE_FORWARD:

                               BANKSEL                           STEPS_TAKEN

                               MOVLW                               MAX_STEPS

                               SUBWF                STEPS_TAKEN,W

                               BTFSC                 STATUS,Z

                               GOTO                   StepperAtLimit

                               GOTO                   ACTUALLY_TAKE_STEP

 

HANDLE_REVERSE:

                               BANKSEL                           STEPS_TAKEN

                               MOVLW                               MIN_STEPS

                               SUBWF                STEPS_TAKEN,W

                               BTFSC                 STATUS,Z

                               GOTO                   StepperAtLimit   

                               GOTO                   ACTUALLY_TAKE_STEP

 

ACTUALLY_TAKE_STEP:

                               ;There are steps left to take, and we are not at the limits

                               DECF                   STEPS_LEFT,1

                               CLRF                    STEP_OFF_COUNT

                               ;Figure out which direction

                               BTFSC                 STEP_DIR,0

                               GOTO                   StepForward

                               GOTO                   StepReverse                      

 

StepForward    

                                                             BANKSEL                                           PORTC

                                                             MOVF                                  PORTC,W

                                                             ANDLW                               b'11110000'

                                                              MOVWF                                              C_TEMP

 

                BANKSEL         0

                INCF            STEP_INDEX,W          ;index++

                ANDLW           0x03                          ;4 states

                MOVWF           STEP_INDEX

                CALL            FullStep         ;retrieve value

                                                              IORWF                                 C_TEMP,W

                MOVWF           PORTC                    ;set port C

 

                                                             BANKSEL                                           STEPS_TAKEN

                                                             INCF                                     STEPS_TAKEN,F

 

                                                             RETURN

; Step Backwards

StepReverse    

                                                             BANKSEL                                           PORTC

                                                             MOVF                                  PORTC,W

                                                             ANDLW                               b'11110000'

                                                             MOVWF                                              C_TEMP

 

                BANKSEL         0

                DECF            STEP_INDEX,W        ;index--

                ANDLW           0x03                          ;4 states

                MOVWF           STEP_INDEX

                CALL            FullStep         ;retrieve value

                                                             IORWF                                 C_TEMP,W

                MOVWF           PORTC                    ;set port C

 

                                                             BANKSEL                                           STEPS_TAKEN

                                                             DECF                                   STEPS_TAKEN,F

 

                                                             RETURN

 

StepperAtLimit:

                                                             ; Clear any steps left to take

                                                             ; This allows immediate response

                                                             ; to steps in opposite direction

                                                             BANKSEL                                           STEPS_LEFT

                                                             CLRF                                   STEPS_LEFT

 

 

TurnStepperOffTimer:

                                                             ; Time to de-energixe stepper after no use

                                                             BANKSEL                                           STEP_OFF_COUNT

                                                             INCFSZ                                STEP_OFF_COUNT,F

                                                             RETURN

TurnStepperOff:

                                                             ; Preserve vals on Port C not used for stepper

                                                             BANKSEL                                           PORTC

                                                             MOVF                                  PORTC,W

                                                             ANDLW                               b'11110000'

                                                             MOVWF                                              C_TEMP

 

                BANKSEL         0

                                                             MOVLW                                              STEP_OFF

                                                             IORWF                                 C_TEMP,W

                MOVWF           PORTC                    ;set port C

                                                             RETURN

 

TurnStepperOn:

                BANKSEL         0

                MOVF            STEP_INDEX,W       ;get index

                CALL            FullStep         ;retrieve value

                                                             IORWF                                 C_TEMP,W

                MOVWF           PORTC                    ;set port C

                                                             RETURN

 

 

 

; Parse a single byte into led, servo, stepper command

PARSE:

 

STEP_CMD:

                               BANKSEL                           PARSE_REG

                               BTFSS                  PARSE_REG,4

                               GOTO                   ReverseCommand

                               GOTO                   ForwardCommand

 

ReverseCommand:

                               BTFSS                  PARSE_REG,5                  ; Reject 00

                               GOTO                   SERVO_CMD                    ;Ignore if not forward or reverse step

 

                               BANKSEL                           STEP_DIR

                               BCF                                      STEP_DIR,0

                               INCF                      STEPS_LEFT,1  ;Take 1 step reverse

                               GOTO                   SERVO_CMD

 

ForwardCommand:

                               BTFSC                 PARSE_REG,5                  ; Reject 11

                               GOTO                   SERVO_CMD

 

                               BANKSEL                           STEP_DIR

                               BSF                                      STEP_DIR,0

                               INCF                      STEPS_LEFT,1  ;Take 1 step forward

                               GOTO                   SERVO_CMD

 

SERVO_CMD:

                               ; Take 4 LSBs

                               ; Add Offset

                               BANKSEL                           PARSE_REG

                               MOVF                   PARSE_REG,0

                               ANDLW                DUTY_MASK

                               ADDLW                PULSE_WIDTH_OFFSET

                               MOVWF                               PULSE_WIDTH

                               RETURN                             

 

; Arbitrary long delay

LONG_DELAY:

                               CALL                    DELAY

                               CALL                    DELAY

                               CALL                    DELAY

                               CALL                    DELAY

                               CALL                    DELAY

                               RETURN                             

DELAY:

               movlw     0xFF                                    

               movwf    TMR_COUNTER

LOOP3:

               movlw     0xFF                                    

               movwf    TMR_COUNTER2

LOOP2:

               decfsz    TMR_COUNTER2,f

               goto        LOOP2                

 

               decfsz    TMR_COUNTER,f

               goto        LOOP3

               return                    

 

 

; Initialization sequence

InitPins:

                ; Set Ports A and C to digital

                BANKSEL         ANSEL

                CLRF            ANSEL

                                                             CLRF                                   ANSELH

 

                                                             ; Set Data Directions

                                                             BANKSEL                                           TRISA

                                                             CLRF                                   TRISA

                                                             CLRF                                   TRISB

                                                             CLRF                                   TRISC

                                                             BSF                                                     TRISC,6 ; SS

                                                             BSF                                                     TRISB,5 ; SS

                                                             BSF                                                     TRISB,6 ; CLK

                                                             BSF                                                     TRISB,4 ; SDI

 

                                                             ; Clear all PWM values

                                                             BANKSEL                                           PARSE_REG

                                                             CLRF                                   PARSE_REG

 

                                                             ; Clear PORTA

                                                             BANKSEL                                           PORTA

                                                             CLRF                                   PORTA

 

                RETURN

 

InitSSP:

                                                             BANKSEL                                           SSPSTAT

                                                             CLRF                                   SSPSTAT                                           ;SMP = 0, CKE = 0

 

                                                              BANKSEL                                           SSPCON

                                                             BSF                                                     SSPCON,SSPEN

                                                             BSF                                                     SSPCON,CKP

                                                             BSF                                                     SSPCON,SSPM2

                                                             ; CKP = 1

                                                             ; SS enabled, Slave

                                                            

                                                             ; Read and write buffer once to make sure its fresh

                                                             BANKSEL                                           SSPBUF

                                                             MOVF                                  SSPBUF,W

                                                             MOVWF                                              SSPBUF

 

                                                             RETURN

 

                END

 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

iButton Reading Pseudocode

 

Purpose – Two wait for an iButton to be attached and then read out the first three bytes of its serial number

 

Configuration:

·          No watchdog timer

·          High speed, external oscillator.  Crystal @ 20 MHz

 

Module-level Defines:

·          IBUTTON_PORT,  port A,B, or C where iButton com happens

·          IBUTTON_PIN,  pin on A,B, or C where iButton com happens

·          TRISIBUTTON,  link to data direction register for that port

 

·          IBUTTON_INPUT,  what to write to TRIS to set to input

·          IBUTTON_OUTPUT,  what to write to TRIS to set to output

·          IBUTTON_HI  ,  what to write to PORT to set HI

·          IBUTTON_LO,  what to write to PORT to set LO

 

·          FIRST_BYTE,  register to place first read byte in

·          SECOND_BYTE,  register for second byte

·          THIRD_BYTE, register for third byte

·          TEMP, temporary location for operations on received bytes

 

Main:

·          Set Port to digital

·          Set Pin to output

·          Set Pin LO

·          Wait 500 us

·          Set Pin input

·          Check if Pin is LO

§         Yes à continue

§         No à repeat from Main

·          Conduct a Reset:

§         Set Pin to output

§         Set Pin LO

§         Wait 500 us

§         Set Pin HI

§         Wait 500 us

·          Command ReadROM

§         Send HI

·        Set Pin to output

·        Set Pin LO

·        Wait 5 us

·        Set Pin to input

·        Wait 70 us

§         Send HI

§         Send LO

·        Set Pin output

·        Set Pin LO

·        Wait 60 us

·        Set Pin input

·        Wait 15 us

§         Send LO

§         Send HI

§         Send HI

§         Send LO

§         Send LO

·          Read three bytes one bit at a time, save in appropriate registers

§         Each bit:

·        Set Pin to output

·        Set Pin LO

·        Wait 5 us

·        Set Pin to input

·        Wait 10 us

·        Test Pin

o       If HI à bit is HI. Store it

o       If LO à bit is LO.  Store it

·        Wait 60 us

                list            P=PIC16F690


 

Back to Top!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

iButton Reading Code Listing

 

                list            P=PIC16F690

                #include "p16F690.inc"            

                __config        (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _MCLRE_OFF)

 

                org             0

                GOTO            LoadIButtonBytes

                org             5

 

; Read iButton on the following PIN of the following PORT

IBUTTON_PORT      equ                     PORTA

IBUTTON_PIN             equ                      0

 

; Register to set direction of PIN for iButton

TRISIBUTTON             equ                      TRISA

 

; Value to set iButton HI, LO, input, or output

IBUTTON_INPUT           equ                      0x01

IBUTTON_OUTPUT          equ                      0x00

IBUTTON_HI              equ                      0x01

IBUTTON_LO              equ                      0x00

 

; Location to store each byte from iButton serial no.

FIRST_BYTE        equ                     0x20

SECOND_BYTE       equ                     0x21

THIRD_BYTE        equ                     0x22

 

; Temp directory for operations on bytes

TEMP              equ                     0x23

 

LoadIButtonBytes:

                ; Set Ports A and C to digital

                BANKSEL         ANSEL

                CLRF            ANSEL

                        CLRF              ANSELH

 

WaitForIButton:

                        ;CALL             MakeIBUTTONOutput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_OUTPUT

                        MOVWF             TRISIBUTTON

                       

                        ;CALL             LowerIBUTTON

                        BANKSEL                  IBUTTON_PORT

                        BCF                      IBUTTON_PORT,IBUTTON_PIN

 

                        CALL              Wait500us

 

                        ;CALL             MakeIBUTTONInput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_INPUT

                        MOVWF             TRISIBUTTON

                        CALL              Wait50us

 

                        ; Check if pin is LO --> iButton Present

                        BANKSEL                  IBUTTON_PORT

                        BTFSC             IBUTTON_PORT,IBUTTON_PIN

                        GOTO              WaitForIButton    ;Repeat until found

                       

                        ; Once found then:      

                        CALL              ConductReset

                       

                        ;  Send Read ROM command

                        CALL              ReadROM    

 

                        ; Read first 8 bits

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

 

                        ; Move this first byte from third_byte to first_byte

                        BANKSEL                  THIRD_BYTE

                        MOVF              THIRD_BYTE,0

                        MOVWF             FIRST_BYTE

 

                        ; Rwad 8 bits of second byte

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

 

                        ; Move second received byte from third_byte to second_byte

                        BANKSEL                  THIRD_BYTE

                        MOVF              THIRD_BYTE,0

                        MOVWF             SECOND_BYTE

 

                        ; Read 8 bits of third byte --> already saved in correct place

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

                        CALL              ReadBit

 

                        ; Wait 200 us before continuing

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

 

                        ; Repeat forever

                        GOTO              WaitForIButton

 

 

ConductReset:

;                       CALL              MakeIBUTTONOutput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_OUTPUT

                        MOVWF             TRISIBUTTON

 

;                       CALL              LowerIBUTTON

                        BANKSEL                  IBUTTON_PORT

                        BCF                      IBUTTON_PORT,IBUTTON_PIN

 

                        CALL              Wait500us

;                       CALL              RaiseIBUTTON

                        BANKSEL                  IBUTTON_PORT

                        BSF                      IBUTTON_PORT,IBUTTON_PIN

 

                        CALL              Wait500us

                        RETURN

 

                       

ReadROM:

; Send ReadROM command

; Need to send 0x33 = 00110011, LSB first

                        CALL              SendIBUTTONHI

                        CALL              SendIBUTTONHI

                        CALL              SendIBUTTONLO

                        CALL              SendIBUTTONLO

                        CALL              SendIBUTTONHI

                        CALL              SendIBUTTONHI

                        CALL              SendIBUTTONLO

                        CALL              SendIBUTTONLO

                        RETURN

 

ReadBit:

; Begin reading

;                       CALL              MakeIBUTTONOutput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_OUTPUT

                        MOVWF             TRISIBUTTON

 

;                       CALL              LowerIBUTTON

                        BANKSEL                  IBUTTON_PORT

                        BCF                      IBUTTON_PORT,IBUTTON_PIN

 

                        CALL              Wait5us

 

;                       CALL              MakeIBUTTONInput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_INPUT

                        MOVWF             TRISIBUTTON

 

                        CALL              Wait5us

                        CALL              Wait5us

 

                        ; Check if line is HI or LO

                        BANKSEL                  IBUTTON_PORT

                        BTFSC             IBUTTON_PORT,IBUTTON_PIN

                        GOTO              RECEIVE_BIT_HI

                        GOTO              RECEIVE_BIT_LO

RECEIVE_BIT_HI:

                        ; Rotate into place this received vbit

                        BANKSEL                  THIRD_BYTE

                        RRF                      THIRD_BYTE,1

                        NOP

                        NOP

                        BSF                      THIRD_BYTE,7

                        ; Wait 60 us

                        CALL              Wait60us

                        RETURN

 

RECEIVE_BIT_LO:

                        ; Rotate into place this received vbit

                        BANKSEL                  THIRD_BYTE

                        RRF                      THIRD_BYTE,1

                        NOP

                        NOP

                        BCF                      THIRD_BYTE,7

                        ; Wait 60 us

                        CALL              Wait60us

                        RETURN

 

SendIBUTTONHI:

;                       CALL              MakeIBUTTONOutput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_OUTPUT

                        MOVWF             TRISIBUTTON

 

;                       CALL              LowerIBUTTON

                        BANKSEL                  IBUTTON_PORT

                        BCF                      IBUTTON_PORT,IBUTTON_PIN

 

                        CALL              Wait5us

 

;                       CALL              MakeIBUTTONInput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_INPUT

                        MOVWF             TRISIBUTTON

 

                        CALL              Wait70us

 

                        RETURN

 

SendIBUTTONLO:

;                       CALL              MakeIBUTTONOutput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_OUTPUT

                        MOVWF             TRISIBUTTON

 

;                       CALL              LowerIBUTTON

                        BANKSEL                  IBUTTON_PORT

                        BCF                      IBUTTON_PORT,IBUTTON_PIN

 

                        CALL              Wait60us

 

;                       CALL              MakeIBUTTONInput

                        BANKSEL                  TRISIBUTTON

                        MOVLW             IBUTTON_INPUT

                        MOVWF             TRISIBUTTON

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        RETURN           

 

Wait5us:

            ; Use NOPs for most reliable timing

            ; takes 18 NOPs for 5 us

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

 

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

 

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

 

                        NOP

                        NOP

                        NOP

                        RETURN

 

Wait1s:

      ; Not actually 1 sec,  just a long time

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

                        CALL              Wait500us

     

 

Wait500us:

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        CALL              Wait50us

                        ; requires some tuning because of rounding errors

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        RETURN

 

Wait50us:

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        ; requires some tuning because of rounding errors

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

 

 

                        RETURN

 

Wait70us:

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

                        ; requires some tuning because of rounding errors

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

                        NOP

 

                        RETURN

 

Wait60us:

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

 

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

 

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

 

                        CALL              Wait5us

                        CALL              Wait5us

                        CALL              Wait5us

 

                        ; requires some tuning because of rounding errors

                        CALL              Wait5us

                       

                        RETURN

 

                ENDORT,SHIFT_CLOCK_BIT

      nop

      nop

      bcf         SHIFT_PORT,SHIFT_CLOCK_BIT

      return

 

Back to Top!

 

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

SPIMaster Pseudocode

 

Purpose – A stand-alone module to test the ability to send data by SPI from a PIC16F690.

 

Configuration:

·          No watchdog timer

·          High speed, external oscillator.  Crystal @ 20 MHz

 

Module-level Variables:

·          TX_BYTE,  register used to store the byte for master to send out

·          RX_BYTE,  register to store byte received from slave

·          COUNTER,  register for a for-loop counter

·          COUNTER2,  register for a for-loop counter

 

Main:

·          Wait a while for the chip to start-up completely

·          Initialize pins:

§         Set Ports A,B, and C to digital

§         Set Ports A,B, and C to outputs

§         Data input (SDI) line is automatically made input

·          Initialize SSP:

§         Set SMP = 0, CKE = 0, CKP = 1

§         Set clock speed to TMR2/2

§         Set to master

·          Initialize Timer2:

§         Set prescaler and postscaler to get period ~250 us

§         Enable timer2

·          Place a desired byte to transmit into TX_BYTE

·          Transmit Byte:

§         Clear not slave select line for desired slave PIC

§         Load SSP Buffer with TX_BYTE

§         Wait for the transfer to complete

§         Place the received byte into RX_BYTE

·          Wait a while and then repeat transmit (possibly with a different byte)

 

Back to Top!

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

SPIMaster Code Listing

 

                list            P=PIC16F690

                #include "p16F690.inc"            

                __config        (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC)

 

                org             0

                GOTO            Main

                org             5

 

TX_BYTE                                            equ                                                       0x20       ; Register for byte to send

RX_BYTE                                           equ                                                       0x21       ; Register for received byte

COUNTER                                          equ                                                       0x22       ; Index for for-loop

COUNTER2                        equ                                                       0x23       ; Index for for-loop

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

 

Main:

                                                             CALL                                    Wait1sec              ; Wait for PIC to start-up completely

                CALL            InitPins          ; Initialize pins

                                                             CALL                                    InitSSP                  ; Intialize SPI                                                                                                      

 

                                                             BANKSEL                                           TX_BYTE

                                                             movlw                                   b'10001011'

                                                             MOVWF                                              TX_BYTE

                                                             CALL                                    Transmit                              

                                                             CALL                                    Wait1sec                                                           

SendAndReceive:

                                                             BANKSEL                                           RX_BYTE

                                                             movf                                      RX_BYTE,W

                                                             MOVWF                                              TX_BYTE

                                                             CALL                                    Transmit                              

                                                             CALL                                    Wait1sec             

                                                             GOTO                                   SendAndReceive

                                                            

Transmit:

                                                             ; Move byte to send into W

                                                             BANKSEL                                           TX_BYTE

                                                             MOVF                                  TX_BYTE,0                                        

                                                             ; Place byte in SSP buffer

                                                             BANKSEL                                           SSPBUF

                                                             MOVWF                                              SSPBUF                              ;Send Data

 

                                                             BANKSEL                                           SSPSTAT

                                                             BTFSS                                 SSPSTAT,BF      ;Wait for receive complete

                                                             GOTO                                   $-1

                                                             ; Put received data into RX_BYTE

                                                             BANKSEL                                           SSPBUF                              ;Get received data

                                                             MOVF                                  SSPBUF,W

                                                             BANKSEL                                           RX_BYTE

                                                             MOVWF                                              RX_BYTE

 

                                                             RETURN

 

 

 

; Initialization sequence

InitPins:

                ; Set Ports A, B, C to digital

                BANKSEL         ANSEL

                CLRF            ANSEL

                                                             CLRF                                   ANSELH

 

                                                             BANKSEL                                           TRISA

                                                             CLRF                                   TRISA

                                                             BANKSEL                                           TRISC

                                                             BCF                                                     TRISC,7                ;SDO

                                                             BANKSEL                                           TRISB

                                                             BCF                                                     TRISB,6                ;SCK --> MASTER

                                                             BCF                                                     TRISB,5                ;SS manual

                RETURN

 

InitSSP:

                                                             BANKSEL                                           SSPSTAT

                                                             CLRF                                   SSPSTAT                                           ;SMP = 0, CKE = 0

 

                                                             BANKSEL                                           SSPCON

                                                             MOVLW                                              0x33                                     ;SSPEN, CKP=1, TMR2/2, Master

                                                             MOVWF                                              SSPCON

 

                                                             ; Set up timer 2 with period  ~250 us

                                                             BANKSEL                                           PR2

                                                             MOVLW                                              0x30

                                                             MOVWF                                              PR2                                     

                                                             BANKSEL                                           T2CON

                                                             MOVLW                                              b'00000111'

                                                             MOVWF                                              T2CON

 

                                                             ; Read and write SSPBUF once to clear out bad data

                                                             BANKSEL                                           SSPBUF

                                                             MOVF                                  SSPBUF,0

                                                             MOVLW                                              0xFF

                                                             MOVWF                                              SSPBUF

                                                             RETURN                                                                                                         

 

; Sets the slave select line to choose the PIC controlling the propeller and pump                                               

TalkToProp:

                                                             BANKSEL                                           PORTB

                                                             BSF                                                     PORTB,5

                                                             RETURN

 

; Sets the slave select line to choose the PIC controlling the rudder and turret

TalkToRudder:

                                                             BANKSEL                                           PORTB

                                                             BCF                                                     PORTB,5

                                                             RETURN

 

 

Wait1sec:

                               ; Arbitrarily long delay - BLOCKING CODE!

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

                                                             CALL                                    WaitAWhile

 

                                                             RETURN

 

WaitAWhile:

                                                             BANKSEL                                           COUNTER

                                                             CLRF                                   COUNTER

                                                             CLRF                                   COUNTER2

LOOP                                   INCFSZ                                COUNTER,1   ; i++

                                                             GOTO                                   LOOP

                                                             INCFSZ                                COUNTER2,1      ; j++

                                                             GOTO                                   LOOP

                                                             RETURN                                                            

 

                                                             END

 

Back to Top!