_HMstrFinal.asm
; Final Project - Terman Pond Flotilla
; ME218C
; -----------------------------------------------------------------
;
;
list P=PIC16F690
#include "p16F690.inc"
__config (_CP_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _INTOSCIO)
; Variable declared here
; --------------------------------------------------------------------
#include vars.h
; Beginning of Program
; --------------------------------------------------------------------
org 0
goto Main
org 5
; ******************************************************************************
; Interrupt
; ******************************************************************************
; ******************************************************************************
; If you add new interrupts, then check to make sure you end in bank 0!!!
Interrupt:
; PUSH
MOVWF W_TEMP ; Copy W to TEMP register
SWAPF STATUS, W ; Swap status to be saved into W
banksel PORTA
MOVWF STATUS_TEMP ; Save status to STATUS_TEMP register
; ISR
BTFSC PIR1, RCIF
CALL EUSART_Rx_Int
BTFSC INTCON, T0IF
CALL Timer0_Int
; POP
SWAPF STATUS_TEMP, W ; Swap nibbles in STATUS_TEMP register
; and place result into W
MOVWF STATUS ; Move W into STATUS register
; (sets bank to original state)
SWAPF W_TEMP, F ; Swap nibbles in W_TEMP and place result in W_TEMP
SWAPF W_TEMP, W ; Swap nibbles in W_TEMP and place result into W
RETFIE
EUSART_Rx_Int:
; Clear flag first
BCF PIR1, RCIF
BTFSC COM_rxFlag, 3
GOTO AllFlagsClear
BTFSC COM_rxFlag, 2
GOTO CheckFor0x81
BTFSC COM_rxFlag, 1
GOTO CheckFor0x08
BTFSC COM_rxFlag, 0
GOTO CheckFor0x00
CheckFor0x7E: MOVLW 0x7E
SUBWF RCREG, W
BTFSS STATUS, Z
GOTO SomethingWrong
BSF COM_rxFlag, 0
RETURN
CheckFor0x00: MOVF RCREG, F
BTFSS STATUS, Z
GOTO SomethingWrong
BSF COM_rxFlag, 1
RETURN
CheckFor0x08: MOVLW 0x08
SUBWF RCREG, W
BTFSS STATUS, Z
GOTO SomethingWrong
BSF COM_rxFlag, 2
RETURN
CheckFor0x81: MOVLW 0x81
SUBWF RCREG, W
BTFSS STATUS, Z
GOTO SomethingWrong
BSF COM_rxFlag, 3
RETURN
AllFlagsClear:
; Read data into appropriate index of receiving buffer
MOVLW COM_rxBuffAddr
ADDWF COM_rxIndex, W
MOVWF FSR
; Read data
MOVF RCREG, W
MOVWF INDF
; Increment the index
INCF COM_rxIndex, F
MOVF COM_rxIndex, W
SUBLW COM_rxLn
BTFSS STATUS, Z
; index is not equal to array length, just return
RETURN
; index is equal to array length, API frame is done
CLRF COM_rxFlag
CLRF COM_rxIndex
BSF COM_rxFlag, COM_rxDone
RETURN
SomethingWrong:
CLRF COM_rxIndex
CLRF COM_rxFlag
RETURN
Timer0_Int:
BCF INTCON, T0IF
DECFSZ Timer0Count, F
RETURN
; If the counter finished, reset it and set a flag
MOVLW Timer0Max
MOVWF Timer0Count
BSF Timer0Flag, 0
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#include adc.h
#include helminits.h
#include xbee_comm.h
#include ibutton.h
#include synch.h
Initialize:
banksel ANSEL
CLRF ANSEL
CLRF ANSELH
; Setup ADC
CALL ADC_Init
; Set to 8 MHz
CALL Clock_Init
; Setup EUSART
CALL EUSART_Init
; Setup PWM
CALL PWM_Init
; Setup SPI
CALL SPI_Init
; Setup LEDs
CALL LED_Init
; Setup Switches/buttons
CALL Input_Init
; Setup Timer0
CALL Timer0_Init
; Enable Interrupts
banksel INTCON
BSF INTCON, GIE
BSF INTCON, PEIE
RETURN
InitializeGameStates:
banksel PORTA
CLRF FLAG
MOVLW 0x01
MOVWF PING_Data2
CLRF PING_Data3
CLRF CraftAddrH
CLRF CraftAddrL
CLRF COM_rxIndex
CLRF COM_rxFlag
CLRF StandDownTimer2
MOVLW 0x00
MOVWF COM_frameid
MOVLW 0x01
MOVWF COM_options
; RESET TEAM, CRAFT#, ACTIVE BASE, STAND DOWN INDICATORS
MOVLW 0xff
MOVWF SPI_TXDATA
CALL SPI_Transmit
RETURN
;********************************************************************************
;********************************************************************************
; Main Loop
; --------------------------------------------------------------------
; Continuously loops and handles the program
; Looks for a button press, looks for a received message on EUSART
; If slave select raised transmits message or ack
;********************************************************************************
;********************************************************************************
Main:
CALL Initialize
CALL InitializeGameStates
CALL Waiting_for_iButton
CALL ToggleLED
CALL Waiting_for_Sync
CALL ToggleLED
; WAIT FOR THE GAME TO START HERE
PNT:
BTFSC FLAG, Hard_Reset_Flag
GOTO Main
CALL CheckTimer0Flag
CALL CheckInputs
CALL SetupNavRegs
CALL APIRx
GOTO PNT
Check_Team:
banksel PORTA
MOVLW b'10001001' ; red
MOVWF SPI_TXDATA
BTFSC iButtonReadingM, 0
GOTO $+3
MOVLW b'10001000' ; blue
MOVWF SPI_TXDATA
CALL SPI_Transmit
RETURN
Indicate_Craft_Num:
; INDICATE CRAFT NUM HERE
banksel PORTA
MOVLW 0x04
MOVWF PING_Data2
MOVF CraftAddrL, W
MOVWF PING_Data3
MOVWF SPI_TXDATA
CALL SPI_Transmit
RETURN
; Interpret the user inputs to the helm to get water speed, specials, speed, and direction
CheckInputs:
; Get Speed
ADC_SelectChan ADC_AN4
BSF ADCON0,GO ;Start conversion
BTFSC ADCON0,GO ;Is conversion done?
GOTO $-1 ;No, test again
banksel PORTA
MOVF ADRESH, W ;Read upper 8 bits
MOVWF Speed
; Put speed in PWM
banksel CCPR1L
MOVWF CCPR1L
banksel PORTA
; Are we going backwards or forwards?
RRF Speed, W ; Divide by two and store in W
ANDLW 0x7F
; Forwwards - add to 8, Backwards - subtract from 8
BTFSS PORTA, 3
GOTO Forwards
Backwards: SUBLW 0x80
MOVWF Speed ; Store new speed
GOTO GetDir
Forwards: ADDLW 0x80
MOVWF Speed
; Get Direction
GetDir: ADC_SelectChan ADC_AN6
BSF ADCON0,GO ;Start conversion
BTFSC ADCON0,GO ;Is conversion done?
GOTO $-1 ;No, test again
banksel PORTA
MOVF ADRESH, W ;Read upper 8 bits
MOVWF Direction
; Direction calibration
MOVLW b'01000000'
SUBWF Direction, F
BTFSS STATUS, C
CALL Set_Direction_Min
RLF Direction, F
BTFSC STATUS, C
CALL Set_Direction_Max
GOTO GetWaterS
Set_Direction_Min:
MOVLW 0x00
MOVWF Direction
GOTO GetWaterS
Set_Direction_Max:
MOVLW 0xff
MOVWF Direction
; Get Specials Inputs
BTFSS PORTC, 3
GOTO $+3
BSF Specials, 0
GOTO $+2
BCF Specials, 0
BTFSS PORTC, 4
GOTO $+3
BSF Specials, 1
GOTO $+2
BCF Specials, 1
; Get Water strength
GetWaterS: ADC_SelectChan ADC_AN5
BSF ADCON0,GO ;Start conversion
BTFSC ADCON0,GO ;Is conversion done?
GOTO $-1 ;No, test again
banksel PORTA
MOVF ADRESH, W ;Read upper 8 bits
MOVWF WaterStrength
BTFSS PORTA, 2
GOTO $+3
BTFSS FLAG, End_Game_Flag
RETURN
; if End_Game command received, disable water strength
CLRF WaterStrength
RETURN
; Once all ship control parameters are known, setup navigation registers
; to hold the data for transfer over the Xbee
SetupNavRegs:
; Setup Navigation Byte 1 with speed and direction info
banksel PORTA
MOVF Speed, W
MOVWF NavByte1
RRF NavByte1, F
RRF NavByte1, F
RRF NavByte1, F
RRF NavByte1, F
MOVLW 0x0F
ANDWF NavByte1, F
MOVLW 0xF0
ANDWF Direction, W
IORWF NavByte1, F
; Setup Navigation Byte 2 with water strength info
MOVF WaterStrength, W
MOVWF NavByte2
RRF NavByte2, F
RRF NavByte2, F
RRF NavByte2, F
RRF NavByte2, F
MOVLW 0x0F
ANDWF NavByte2, F
; Setup specials
BTFSS Specials, 0
GOTO $+3
BSF NavByte2, 5
GOTO $+2
BCF NavByte2, 5
BTFSS Specials, 1
GOTO $+3
BSF NavByte2, 6
GOTO $+2
BCF NavByte2, 6
RETURN
; TransmitNoAxn
; --------------------------------------------------------------------
; Sends a no action command (helm to craft) as defined in Comm. protocol.
TransmitNoAxn:
banksel PORTA
MOVLW 0x88
MOVWF NavByte1
MOVLW 0x00
MOVWF NavByte2
CALL TransmitNav
RETURN
; To use this function, first load NavByte1 and NavByte2 with the navigation
; data the helm needs to transmit, then call this function.
TransmitNav:
CALL SetAddressToShip
banksel PORTA
MOVLW 0x02
MOVWF COM_data1
MOVF NavByte1, W
; MOVLW 0x88
MOVWF COM_data2
MOVF NavByte2, W
; MOVLW 0x88
MOVWF COM_data3
CALL API_TxPacket
RETURN
APIRx:
banksel PORTA
; Check whether an API packet is received
BTFSS COM_rxFlag, COM_rxDone
RETURN
BCF COM_rxFlag, COM_rxDone
CALL ToggleLED
; A packet has been received, what is it?
MOVLW COM_craft
SUBWF COM_rxData1, W
BTFSC STATUS, Z
; It's from the craft
GOTO API_Craft
MOVLW COM_adm
SUBWF COM_rxData1, W
BTFSC STATUS, Z
; It's admiral
GOTO API_Admiral
; It's garbage, return
RETURN
API_Admiral:
CALL CheckAdmAddr
ADDLW 0x00
BTFSS STATUS, Z
RETURN
; It is from the admiral's address
MOVF COM_rxData2, W
BTFSS STATUS, Z
RETURN
; Is it start game?
MOVLW COM_startgame
SUBWF COM_rxData3, W
BTFSC STATUS, Z
GOTO AdmStartgame
; Is it end game?
MOVLW COM_endgame
SUBWF COM_rxData3, W
BTFSC STATUS, Z
GOTO AdmEndgame
; Is it blue goal?
MOVLW COM_bluegoal
SUBWF COM_rxData3, W
BTFSC STATUS, Z
GOTO AdmBluegoal
; Is it red goal?
MOVLW COM_redgoal
SUBWF COM_rxData3, W
BTFSC STATUS, Z
GOTO AdmRedgoal
; Is it hard reset?
MOVLW COM_hardreset
SUBWF COM_rxData3, W
BTFSC STATUS, Z
GOTO AdmHardreset
; Is ping?
MOVLW COM_ping
SUBWF COM_rxData3, W
BTFSC STATUS, Z
GOTO AdmPing
RETURN
; We set the game state so we can play, but first respond with ack
; to admiral
AdmStartgame:
CALL SetAddressToAdmiral
CALL SendAckToAddress
BSF FLAG, Start_Game_Flag
RETURN
; We set the game state to end game mode, but first respond with ack
; to admiral
AdmEndgame:
CALL SetAddressToAdmiral
CALL SendAckToAddress
BSF FLAG, End_Game_Flag
RETURN
; Indicate that the blue goal is active - send to slave over SPI
AdmBluegoal:
banksel PORTA
MOVLW b'10000011' ; Turn off ActiveRed LED
MOVWF SPI_TXDATA
CALL SPI_Transmit
MOVLW b'10001010' ; Turn on ActiveBlue LED
MOVWF SPI_TXDATA
CALL SPI_Transmit
; NEED TO INDICATE active base HERE ****************************************************************
RETURN
; Indicate that the red goal is active - send to slave over SPI
AdmRedgoal:
banksel PORTA
; INDICATE active base HERE
MOVLW b'10001011' ; Turn on ActiveRed LED
MOVWF SPI_TXDATA
CALL SPI_Transmit
MOVLW b'10000010' ; Turn off ActiveBlue LED
MOVWF SPI_TXDATA
CALL SPI_Transmit
RETURN
; Set the hard reset flag
AdmHardreset:
BSF FLAG, Hard_Reset_Flag
RETURN
; Send back the correct ping data
AdmPing:
CALL SetAddressToAdmiral
MOVLW COM_pingresp
MOVWF COM_data1
MOVF PING_Data2, W
MOVWF COM_data2
MOVF PING_Data3, W
MOVWF COM_data3
CALL API_TxPacket
RETURN
; The only command we really want is stand down, since matched would happen
; during waiting for synch section of code
API_Craft:
CALL CheckCraftAddr
ADDLW 0x00
BTFSS STATUS, Z
RETURN
; Is it garbage?
MOVF COM_rxData2, W
BTFSS STATUS, Z
; If byte 2 is not 0x00, then garbage, return
RETURN
; Is it stand down?
MOVLW COM_sdreceived
SUBWF COM_rxData3, W
BTFSS STATUS, Z
RETURN
; It's a stand down command, implement it here
; What we want to do is send an ack to the craft and then send no actions
; for 10 seconds
CALL SetAddressToShip
CALL SendAckToAddress
BSF FLAG, StandDown_Flag
RETURN
SendAckToAddress:
MOVLW COM_ack
MOVWF COM_data1
MOVF COM_rxData2, W
MOVWF COM_data2
MOVF COM_rxData3, W
MOVWF COM_data3
CALL API_TxPacket
RETURN
; SPI_Transmit
; --------------------------------------------------------------------
; Transmits to SPI, no slave select
SPI_Transmit:
; Ensure Bank 1
BSF STATUS,RP0
BCF STATUS,RP1
BTFSS SSPSTAT, BF ; Has data been received(transmit complete)?
GOTO $-1
; Bank 0
BCF STATUS,RP0
MOVF SSPBUF, W ; WREG reg = contents of SSPBUF
MOVWF SPI_RXDATA ; Save in user RAM, if data is meaningful
MOVF SPI_TXDATA, W ; W reg = contents of TXDATA
MOVWF SSPBUF ; New data to xmit
RETURN
CheckTimer0Flag:
banksel PORTA
BTFSS Timer0Flag, 0
RETURN
; Flag is set, then clear it and transmit something
BCF Timer0Flag, 0
; Toggle LED
CALL ToggleLED
; Are we getting a new stand down command? If so reset the timer.
BTFSS FLAG, StandDown_Flag
GOTO NoNewStandDown
BCF FLAG, StandDown_Flag
MOVLW StandDownTimer2Max
MOVWF StandDownTimer2
NoNewStandDown:
; Are we standing down? If the stand down timer2 is zero, then we aren't
; standing down. If it's more than zero, then we are standing down and
; we can decrement the stand down timer so that we eventually leave stand
; down.
MOVF StandDownTimer2, W
BTFSS STATUS, Z
GOTO StandingDown
CALL Indicate_No_Stand_Down
; Not standing down. Has the game started?
BTFSS FLAG, Start_Game_Flag
GOTO $+3
; It's started, so transmit a nav command
CALL TransmitNav
RETURN
; CALL TransmitNoAxn
CALL TransmitNav
RETURN
StandingDown:
; We're standing down. Simply send a no action and then decrement the counter
CALL TransmitNoAxn
CALL Indicate_Stand_Down
DECF StandDownTimer2, F
RETURN
Indicate_Stand_Down:
MOVLW b'10001100'
MOVWF SPI_TXDATA
CALL SPI_Transmit
; NEED TO INDICATE STAND DOWN HERE ****************************************************************
RETURN
Indicate_No_Stand_Down:
MOVLW b'10000100'
MOVWF SPI_TXDATA
CALL SPI_Transmit
; NEED TO INDICATE STAND DOWN HERE ****************************************************************
RETURN
ToggleLED:
banksel PORTA
BTFSS PORTA, 1
GOTO $+3
BCF PORTA, 1
RETURN
BSF PORTA, 1
RETURN
END
ibutton.h
; ******************************************************************************
; ******************************************************************************
; Functions for iButton
; ******************************************************************************
; ******************************************************************************
iWAIT:
BTFSS PIR1, TMR1IF
GOTO iWAIT
RETURN
TIMER1_Init:
banksel OSCCON
BSF OSCCON, IRCF0
BSF OSCCON, IRCF1
BSF OSCCON, IRCF2
banksel T1CON
BCF T1CON, TMR1CS ; use internal clock (Fosc/4)
BCF T1CON, T1CKPS0 ; set prescale value as 1:1
BCF T1CON, T1CKPS1
BSF T1CON, TMR1ON ; Enable Timer 1
; BCF T1CON, TMR1GE
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iButton_Init:
banksel ANSEL
BCF ANSEL, ANS0
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
READ_iButton:
; Have we received something? All we care about is admiral ping
BTFSC COM_rxFlag, COM_rxDone
CALL CheckIfAdmiralPingIbutton
; banksel TRISA ; set the pin as an output
BCF STATUS, RP1
BSF STATUS, RP0
BCF TRISA, 0
; banksel PORTA ; set the line low
BCF STATUS, RP1
BCF STATUS, RP0
BCF iButtonPin
; banksel TMR1L ; wait for 500 usec
BCF STATUS, RP1
BCF STATUS, RP0
MOVLW 0xd5 ;232-19
XORLW 0xFF
MOVWF TMR1L
MOVLW 0xFC ; 768
MOVWF TMR1H
BCF PIR1, TMR1IF
CALL iWAIT
; banksel TRISA ; set the pin as an input
BCF STATUS, RP1
BSF STATUS, RP0
BSF TRISA, 0
; banksel TMR1L ; wait for 50 usec
BCF STATUS, RP1
BCF STATUS, RP0
MOVLW 0x4e ; 100-22
XORLW 0xFF
MOVWF TMR1L
MOVLW 0xFF
MOVWF TMR1H
BCF PIR1, TMR1IF
CALL iWAIT
; banksel PORTA ; read the pin
BCF STATUS, RP1
BCF STATUS, RP0
BTFSC iButtonPin
GOTO READ_iButton ; if no iButton found, repeat
RETURN ; if iButton is found, proceed to reset
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CheckIfAdmiralPingIbutton:
MOVLW COM_adm
SUBWF COM_rxData1, W
BTFSS STATUS, Z
; It's not admiral command
RETURN
; It is admiral
CALL CheckAdmAddr
ADDLW 0x00
BTFSS STATUS, Z
RETURN
; Address matches admiral, now is it ping?
MOVF COM_rxData2, W
BTFSS STATUS, Z
RETURN
MOVLW COM_ping
SUBWF COM_rxData3, W
BTFSS STATUS, Z
CALL AdmPing
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RESET_iButton:
; banksel TRISA ; set the pin as an output
BCF STATUS, RP1
BSF STATUS, RP0
BCF TRISA, 0
; banksel PORTA ; set the line low
BCF STATUS, RP1
BCF STATUS, RP0
BCF iButtonPin
; banksel TMR1L ; wait for 500 usec
MOVLW 0xd5 ;232-19
XORLW 0xFF
MOVWF TMR1L
MOVLW 0xFC ; 768
MOVWF TMR1H
BCF PIR1, TMR1IF
CALL iWAIT
NOP
NOP
NOP
NOP
NOP
NOP
; banksel PORTA ; set the line high
BCF STATUS, RP1
BCF STATUS, RP0
BSF iButtonPin
; banksel TMR1L ; wait for 500 usec
MOVLW 0xd5 ;232-19
XORLW 0xFF
MOVWF TMR1L
MOVLW 0xFC ; 768
MOVWF TMR1H
BCF PIR1, TMR1IF
CALL iWAIT
NOP
;goto RESET_iButton
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SEND_READ_COMMAND:
; banksel TMR1L
BCF STATUS, RP1
BCF STATUS, RP0
MOVLW 0x33
MOVWF readROMcommand
MOVLW 8
MOVWF CNT
SEND_LOOP: ; send read ROM command
RRF readROMcommand, f
BTFSS STATUS, C
GOTO WRITE_0
GOTO WRITE_1
CHECK_END_OF_SEND_LOOP:
DECFSZ CNT, f
GOTO SEND_LOOP
RETURN
WRITE_1:
; banksel TRISA ; set the pin as an output
BCF STATUS, RP1
BSF STATUS, RP0
BCF TRISA, 0
; banksel PORTA ; set the line low
BCF STATUS, RP1
BCF STATUS, RP0
BCF iButtonPin
NOP ; wait for 5 usec
NOP
NOP
banksel TRISA ; set the pin as an input
BSF TRISA, 0
; banksel TMR1L ; wait for 70 usec
BCF STATUS, RP1
BCF STATUS, RP0
MOVLW 0x70 ;140-28
XORLW 0xFF
MOVWF TMR1L
MOVLW 0xFF
MOVWF TMR1H
BCF PIR1, TMR1IF
CALL iWAIT
NOP
NOP
NOP
GOTO CHECK_END_OF_SEND_LOOP
WRITE_0:
; banksel TRISA ; set the pin as an output
BCF STATUS, RP1
BSF STATUS, RP0
BCF TRISA, 0
; banksel PORTA ; set the line low
BCF STATUS, RP1
BCF STATUS, RP0
BCF iButtonPin
; banksel TMR1L ; wait for 60 usec
MOVLW 0x68 ;120-16
XORLW 0xFF
MOVWF TMR1L
MOVLW 0xFF
MOVWF TMR1H
BCF PIR1, TMR1IF
CALL iWAIT
; banksel TRISA ; set the pin as an input
BCF STATUS, RP1
BSF STATUS, RP0
BSF TRISA, 0
; banksel TMR1L ; wait for 15 usec
BCF STATUS, RP1
BCF STATUS, RP0
MOVLW 0x04 ;30-26
XORLW 0xFF
MOVWF TMR1L
MOVLW 0xFF
MOVWF TMR1H
BCF PIR1, TMR1IF
CALL iWAIT
NOP
NOP
GOTO CHECK_END_OF_SEND_LOOP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
READ_iButton_data:
; banksel TMR1L
BCF STATUS, RP1
BCF STATUS, RP0
MOVLW 0x18 ;24
MOVWF CNT
READ_LOOP:
; banksel TRISA ; set the pin as an output
BCF STATUS, RP1
BSF STATUS, RP0
BCF TRISA, 0
; banksel PORTA ; set the line low
BCF STATUS, RP1
BCF STATUS, RP0
BCF iButtonPin
; banksel TMR1L ; wait for 5 usec
NOP
NOP
NOP
NOP
; banksel TRISA ; set the pin as an input
BCF STATUS, RP1
BSF STATUS, RP0
BSF TRISA, 0
; banksel TMR1L ; wait for 10 usec
NOP
NOP
NOP
NOP
NOP
NOP
NOP
; banksel TMR1L
BCF STATUS, RP1
BCF STATUS, RP0
RRF iButtonReadingM, f ; shift the reading to get it ready for the next bit
RRF iButtonReadingH, f
BTFSC STATUS, C
GOTO SETHI
BCF iButtonReadingM, 7
GOTO NEXT
SETHI BSF iButtonReadingM, 7
; banksel PORTA ; read the pin
NEXT BCF STATUS, RP1
BCF STATUS, RP0
BTFSC iButtonPin
GOTO READ_1 ; if high, reading is 1
BCF iButtonReadingH, 7 ; if low, reading is 0
CHECK_END_OF_READ_LOOP:
; banksel TMR1L ; wait for 60 usec
BCF STATUS, RP1
BCF STATUS, RP0
MOVLW 0x5c ;120-28
XORLW 0xFF
MOVWF TMR1L
MOVLW 0xFF
MOVWF TMR1H
BCF PIR1, TMR1IF
CALL iWAIT
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ CNT, f
GOTO READ_LOOP
RETURN
READ_1:
BSF iButtonReadingH, 7
GOTO CHECK_END_OF_READ_LOOP
Waiting_for_iButton:
CALL TIMER1_Init
CALL iButton_Init
start_iButton:
CALL READ_iButton
CALL RESET_iButton
CALL SEND_READ_COMMAND
CALL READ_iButton_data
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
adc.h
ADC_AN4 equ B'00010001'
ADC_AN5 equ B'00010101'
ADC_AN6 equ B'00011001'
Acquis_Time:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RETURN
ADC_SelectChan macro byte
BCF STATUS, RP1
BCF STATUS, RP0
MOVLW byte ;Left justify, Vdd Vref, AN2, On
MOVWF ADCON0
CALL Acquis_Time ;Acquisiton delay
endm
helminits.h
;
; Clock_Init
;
;
Clock_Init:
banksel OSCCON
BSF OSCCON, IRCF0
BSF OSCCON, IRCF1
BSF OSCCON, IRCF2
RETURN
ADC_Init:
; Ensure bank 1
BCF STATUS, RP1
BSF STATUS, RP0
MOVLW B'01010000' ; clock select Fosc/16
MOVWF ADCON1
; Setup the analog pins
BSF TRISC, 0 ; Set RC0 to input
BSF TRISC, 1 ; Set RC1 to input
BSF TRISC, 2 ; Set RC2 to input
; Ensure bank 2
BSF STATUS, RP1
BCF STATUS, RP0
BSF ANSEL, 4
BSF ANSEL, 5
BSF ANSEL, 6
RETURN
;
; SPI_Init
; --------------------------------------------------------------------
; Routine to initialize SPI on the PIC.
SPI_Init:
; Handle all the ANSEL and TRIS pins for SPI
; We already handle this in the parent initialize function
; banksel ANSELH
; BCF ANSELH, ANS8; Turn off AD on SS
; BCF ANSELH, ANS9; Turn off AD on SDO
; BCF ANSELH, ANS10; Turn off AD on SDI/SDA
banksel TRISA
BSF TRISB, TRISB4; Set SDI/SDA line as input
BCF TRISC, TRISC7; Set SDO line as output
; Are we master or slave
BCF TRISB, TRISB6; Set SCK line as output for Master
banksel SSPSTAT
CLRF SSPSTAT; SMP = 0, CKE = 0, clear status bits
BSF SSPSTAT, CKE; CKE = 1
banksel SSPCON
MOVLW 0x32 ; Set up SPI port, Master mode, CLK/64
MOVWF SSPCON ; Mode 3 (CKE = 1, CKP = 1)
; Data sampled in middle (SMP = 0, Master mode)
; banksel PIE1
; BSF PIE1, SSPIE ; Enable SSP interrupt
; banksel INTCON
; BSF INTCON, GIE ; Enable enabled interrupts
; banksel PIR1
; BCF PIR1, SSPIF ; Clear interrupt flag
; Set up the Slave Select lines as outputs raised high
banksel PORTA
BSF PORTC, 6
banksel TRISA
BCF TRISC, TRISC6; Set SS line as output
; Should be ready to transmit
banksel SSPBUF
MOVLW 0x55
MOVWF SSPBUF ; New data to xmit
RETURN
;
; EUSART_Init routine.
; --------------------------------------------------------------------
; Routine to initialize the EUSART peripheral on the PIC
EUSART_Init:
; Clear analog for RB5
; This is already handled for us in parent initialize function
; banksel ANSEL
; BCF ANSELH, ANS11
banksel TXSTA
; Choose 8 bit asynchronous /16
BCF TXSTA, SYNC
BSF TXSTA, BRGH
BCF BAUDCTL, BRG16
; Choose a 9600 Baud rate (10 MHz clock)
; MOVLW 0x0C
;MOVLW 64
;MOVLW 0x40
; Choose a 9600 Baud rate (8 MHz clock)
MOVLW 0x33
MOVWF SPBRG
; Enable 8-bit tx
BCF TXSTA, TX9
; Enable transmit
BSF TXSTA, TXEN
; Enable serial port
banksel RCSTA
BSF RCSTA, SPEN
; Enable 8-bit rx
BCF RCSTA, RX9
; Enable receive
BSF RCSTA, CREN
; Enable interrupt
banksel PIE1
BSF PIE1, RCIE
RETURN
;
; PWM_Init routine
; --------------------------------------------------------------------
; Routine to initialize PWM on the PIC
PWM_Init:
; Ensure Bank 1
BSF STATUS, RP0
BCF STATUS, RP1
; Disable PWM pin
BSF TRISC, TRISC5 ; Set C5 to input
; Set PWM Period
MOVLW 0xFF
MOVWF PR2
; Configure CCP for PWM
BCF STATUS, RP0 ; Select bank 0
MOVLW 0x3C
MOVWF CCP1CON
; Set PWM duty cycle
MOVLW 0x00
MOVWF CCPR1L
; Configure and start Timer2
BCF PIR1, TMR2IF ; Clear Timer2 interrupt flag
BSF T2CON, T2CKPS0 ; Set Timer2 prescale value to 4
BSF T2CON, TMR2ON ; Turn Timer2 on
; Enable PWM output after new PWM cycle started
PWM_Pt_1: BTFSS PIR1, TMR2IF
GOTO PWM_Pt_1
BSF STATUS, RP0 ; Select bank 1
BCF TRISC, TRISC5 ; Set C5 to output
RETURN
;
; Timer0_Init routine
; --------------------------------------------------------------------
; Routine to initialize Timer0 on the PIC
Timer0_Init:
; Ensure bank 1
BSF STATUS, RP0
BCF STATUS, RP1
; Set as timer
BCF OPTION_REG, T0CS
; Set prescaler to timer 0
BCF OPTION_REG, PSA
; 1:256 prescaler
BSF OPTION_REG, PS0
BSF OPTION_REG, PS1
BSF OPTION_REG, PS2
; Clear the flag
BCF INTCON, T0IF
; Enable the interrupt
BSF INTCON, T0IE
; Reset the counter and flag
BCF STATUS, RP0
MOVLW Timer0Max
MOVWF Timer0Count
CLRF Timer0Flag
RETURN
LED_Init:
banksel PORTA
BCF PORTA, 1
banksel TRISA
BCF TRISA, 1
RETURN
Input_Init:
; Water shooting and forwards/backwards
banksel TRISA
BSF TRISA, 2
BSF TRISA, 3
; Specials
BSF TRISC, 3
BSF TRISC, 4
RETURN
synch.h
Waiting_for_Sync:
banksel PORTA
MOVLW 0x02
MOVWF PING_Data2 ; update status for ping command
; Setup to broadcast ibutton data
Broadcast_iButton_data:
CALL SetAddressToBroadcast
MOVLW 0x01
MOVWF COM_data1
MOVF iButtonReadingH, W
MOVWF COM_data2
MOVF iButtonReadingM, W
MOVWF COM_data3
CALL API_TxPacket
CALL Wait
; Check if we've received a message. At this point all we care about
; receiving are matched from the ship, or ping from the admiral
BTFSS COM_rxFlag, COM_rxDone
GOTO Broadcast_iButton_data
BCF COM_rxFlag, COM_rxDone
; Received a packet, now let's check if it's a matched command
MOVLW COM_craft
SUBWF COM_rxData1, W
BTFSS STATUS, Z
; Now check if it's an admiral ping
GOTO CheckIfAdmiralPing
MOVF COM_rxData2, W
BTFSS STATUS, Z
GOTO Broadcast_iButton_data
MOVLW COM_matched
SUBWF COM_rxData3, W
BTFSS STATUS, Z
GOTO Broadcast_iButton_data
; It is a matched command! Respond to it here
; First let's save the address of the craft
MOVF COM_rxAddrH, W
MOVWF CraftAddrH
MOVF COM_rxAddrL, W
MOVWF CraftAddrL
; Now let's setup ping data to respond
MOVWF PING_Data3
MOVLW 0x04
MOVWF PING_Data2
CALL Check_Team
CALL Indicate_Craft_Num
RETURN
CheckIfAdmiralPing:
MOVLW COM_adm
SUBWF COM_rxData1, W
BTFSS STATUS, Z
; It's not admiral command
GOTO Broadcast_iButton_data
; It is admiral
CALL CheckAdmAddr
ADDLW 0x00
BTFSS STATUS, Z
GOTO Broadcast_iButton_data
; Address matches admiral, now is it ping?
MOVF COM_rxData2, W
BTFSS STATUS, Z
GOTO Broadcast_iButton_data
MOVLW COM_ping
SUBWF COM_rxData3, W
BTFSS STATUS, Z
CALL AdmPing
GOTO Broadcast_iButton_data
Wait:
banksel Timer1
MOVLW 0xFF; setup the first counter for waiting
MOVWF Timer2
Wait2: MOVLW 0xFF; setup the second counter for waiting
MOVWF Timer1
Wait1: NOP
NOP
DECFSZ Timer1, F; decrement first counter, if zero loop
GOTO Wait1; is done
DECFSZ Timer2, F; decrement second counter, if zero loop
GOTO Wait2; is done
RETURN
vars.h
; Utility Variables
BIT0HI equ 0x01
BIT1HI equ 0x02
BIT2HI equ 0x04
Timer0Max equ 0x0A
EndGame equ 0x04
BlueGoal equ 0x08
RedGoal equ 0x10
HardReset equ 0x40
Ping equ 0x80
StartGame equ 0x02
AdmiralAddrH equ 0xBC
AdmiralAddrL equ 0xFF
; Literals for ibutton
RedTeam equ 0x00
BlueTeam equ 0xff
; Locations in memory
SPI_RXDATA equ 0x20
SPI_TXDATA equ 0x21
Timer1 equ 0x22
Timer2 equ 0x23
COM_addrs_msb equ 0x24
COM_addrs_lsb equ 0x25
COM_data1 equ 0x26
COM_data2 equ 0x27
COM_data3 equ 0x28
COM_frameid equ 0x29
COM_options equ 0x2A
COM_checksum equ 0x2B
COM_rxBuffAddr equ 0x2C
COM_rxAddrH equ 0x2C
COM_rxAddrL equ 0x2D
COM_rxData1 equ 0x30
COM_rxData2 equ 0x31
COM_rxData3 equ 0x32
COM_rxIndex equ 0x34
COM_rxFlag equ 0x35
COM_rxDone equ 7
W_TEMP equ 0x36
STATUS_TEMP equ 0x37
Timer0Count equ 0x38
Timer0Flag equ 0x39
Speed equ 0x3A
Direction equ 0x3B
WaterStrength equ 0x3C
NavByte1 equ 0x3D
NavByte2 equ 0x3E
CraftAddrH equ 0x3F
CraftAddrL equ 0x40
FLAG equ 0x41
End_Game_Flag equ 0
Hard_Reset_Flag equ 1
Start_Game_Flag equ 2
StandDown_Flag equ 4
PING_Data2 equ 0x42
PING_Data3 equ 0x43
StandDownTimer2 equ 0x45
StandDownTimer2Max equ 0x1F
Specials equ 0x46
; variables for iButton
readROMcommand equ 0x50
CNT equ 0x51
iButtonReadingH equ 0x52
iButtonReadingM equ 0x53
iButtonReadingL equ 0x54
Team equ 0x55
#define iButtonPin PORTA, 0
xbee_comm.h
API_Start equ 0x7E
API_NoRsp equ 0x00
API_Tx16b equ 0x01
API_TxResult equ 0x89
API_Rx16b equ 0x81
API_Broadcast equ 0xFF
COM_lnth_msb equ 0x00
COM_lnth_lsb equ 0x08
COM_rxLn equ 0x08
; Types of messages
COM_nav equ 0x02
COM_adm equ 0x04
COM_ibutton equ 0x01
COM_craft equ 0x08
COM_pingresp equ 0x10
COM_ack equ 0x80
; Ship to helm message tags
COM_matched equ 0x01
COM_sdreceived equ 0x02
; Admiral to helm message tags
COM_startgame equ 0x02
COM_endgame equ 0x04
COM_bluegoal equ 0x08
COM_redgoal equ 0x10
COM_hardreset equ 0x40
COM_ping equ 0x80
EUSART_txL macro byte
CALL Wt_USART_TxRdy
banksel TXREG
MOVLW byte
MOVWF TXREG
endm
EUSART_txF macro file
CALL Wt_USART_TxRdy
banksel TXREG
MOVF file, W
MOVWF TXREG
endm
ChecksumCalc macro
; Ensure Bank 0
BCF STATUS,RP0
BCF STATUS,RP1
; Start setting up the checksum
MOVLW API_Tx16b
MOVWF COM_checksum
MOVF COM_frameid, W
ADDWF COM_checksum, F
MOVF COM_options, W
ADDWF COM_checksum, F
MOVF COM_addrs_msb, W
ADDWF COM_checksum, F
MOVF COM_addrs_lsb, W
ADDWF COM_checksum, F
MOVF COM_data1, W
ADDWF COM_checksum, F
MOVF COM_data2, W
ADDWF COM_checksum, F
MOVF COM_data3, W
ADDWF COM_checksum, F
COMF COM_checksum, F
endm
; Wait til the transfer buffer is ready
; --------------------------------------------------------------------
; Routine that waits until the EUSART is ready to transmit another byte of data
Wt_USART_TxRdy:
banksel TXSTA ; wait til tranfer register ready
BTFSS TXSTA, TRMT ; check state of transmit buffer
GOTO $-1
RETURN
API_TxPacket:
ChecksumCalc
EUSART_txL API_Start
EUSART_txL COM_lnth_msb
EUSART_txL COM_lnth_lsb
EUSART_txL API_Tx16b
EUSART_txF COM_frameid
EUSART_txF COM_addrs_msb
EUSART_txF COM_addrs_lsb
EUSART_txF COM_options
EUSART_txF COM_data1
EUSART_txF COM_data2
EUSART_txF COM_data3
EUSART_txF COM_checksum
RETURN
SetAddressToBroadcast:
MOVLW 0xFF
MOVWF COM_addrs_msb
MOVWF COM_addrs_lsb
RETURN
SetAddressToAdmiral:
MOVLW AdmiralAddrH
MOVWF COM_addrs_msb
MOVLW AdmiralAddrL
MOVWF COM_addrs_lsb
RETURN
SetAddressToShip:
MOVF CraftAddrH, W
MOVWF COM_addrs_msb
MOVF CraftAddrL, W
MOVWF COM_addrs_lsb
RETURN
CheckAdmAddr:
banksel PORTA
MOVLW AdmiralAddrH
SUBWF COM_rxAddrH, W
BTFSS STATUS, Z
RETLW 0xFF
MOVLW AdmiralAddrL
SUBWF COM_rxAddrL, W
BTFSS STATUS, Z
RETLW 0xFF
RETLW 0x00
CheckCraftAddr:
banksel PORTA
MOVF CraftAddrH, W
SUBWF COM_rxAddrH, W
BTFSS STATUS, Z
RETLW 0xFF
MOVF CraftAddrL, W
SUBWF COM_rxAddrL, W
BTFSS STATUS, Z
RETLW 0xFF
RETLW 0x00
Helm_Slv.asm
; Final Project - Terman Pond Flotilla
;
list P=PIC16F690
#include "p16F690.inc"
; #include pwm.h
__config (_CP_OFF & _WDT_OFF & _PWRTE_ON & _INTOSCIO)
;
; Variable Definitions
; ---------------------------------------------------------------
; Utility Variables
BIT0HI equ 0x01
BIT1HI equ 0x02
BIT2HI equ 0x04
Tmr0ServMax equ 0x3F
Timer0Max equ 0xFF
#define ServoPin PORTA,1
MotorSpeedMask equ 0xE0
; Locations in memory
SPI_RXDATA equ 0x20
SPI_TXDATA equ 0x21
Timer1 equ 0x22
Timer2 equ 0x23
W_TEMP equ 0x24
STATUS_TEMP equ 0x25
INPUT equ 0x26
CNT equ 0x27
CLOCKBIT equ 0
INPUTBIT equ 1
CYCLEBIT equ 2
CraftNumBit equ 3
TeamBlue equ 4 ; PORT C
TeamRed equ 1 ; PORT A
ActiveBlue equ 5 ; PORT A
ActiveRed equ 4 ; PORT A
StandDown equ 0 ; PORT A
; Beginning of Program
; --------------------------------------------------------------------
org 0
goto Main
org 5
goto Interrupt
;
; Tables
; --------------------------------------------------------------------
; Lookup table for bit pattern to write to Port C output
END_TBL:
LCDTable:
ADDWF PCL, F
RETLW b'11111111'
RETLW b'11101101'
RETLW b'00011001'
RETLW b'10001001'
RETLW b'11000101'
RETLW b'10000011'
RETLW b'00000011'
RETLW b'11101001'
RETLW b'00000001'
RETLW b'11000001'
RETLW b'00100000'
RETLW b'11101100'
RETLW b'00011000'
Clock_Init:
banksel OSCCON
BSF OSCCON, IRCF0
BSF OSCCON, IRCF1
BSF OSCCON, IRCF2
RETURN
;
; SPI_Init
; -------------------------------------------------------------------
; Routine to initialize SPI on the PIC.
SPI_Init:
; Handle all the ANSEL and TRIS pins for SPI
banksel ANSELH
BCF ANSELH, ANS8; Turn off AD on SS
BCF ANSELH, ANS9; Turn off AD on SDO
BCF ANSELH, ANS10; Turn off AD on SDI/SDA
banksel TRISA
BSF TRISB, TRISB4; Set SDI/SDA line as input
BCF TRISC, TRISC7; Set SDO line as output
BSF TRISC, TRISC6; Set SS line as input
; Are we master or slave
BSF TRISB, TRISB6; Set SCK line as input for Slave
banksel SSPSTAT
CLRF SSPSTAT; SMP = 0, CKE = 0, clear status bits
BSF SSPSTAT, CKE; CKE = 1
banksel SSPCON
BCF SSPCON, SSPEN
MOVLW 0x35 ; Set up SPI port, Slave mode (SS), enable
MOVWF SSPCON ; Mode 3 (CKE = 1, CKP = 1)
; (SMP cleared for slave mode)
banksel PIE1
BSF PIE1, SSPIE ; Enable SSP interrupt
banksel PIR1
BCF PIR1, SSPIF ; Clear interrupt flag
; Should be ready to transmit
RETURN
LED_Init:
banksel ANSEL
CLRF ANSELH
CLRF ANSEL
banksel PORTA
CLRF PORTA
banksel TRISA
CLRF TRISA
BCF TRISC, CLOCKBIT
BCF TRISC, INPUTBIT
BCF TRISC, CYCLEBIT
BCF TRISC, CraftNumBit
BCF TRISC, TeamBlue
banksel PORTC
BCF PORTC, TeamBlue
BCF PORTC, CLOCKBIT
BCF PORTC, INPUTBIT
BCF PORTC, CYCLEBIT
BCF PORTC, CraftNumBit
CLRF SPI_RXDATA
CALL CraftNumCtrl
RETURN
;
; Initialize routine.
; --------------------------------------------------------------------
Initialize:
; Setup Clock
CALL Clock_Init
; Setup SPI
CALL SPI_Init
; Setup LEDs
CALL LED_Init
; Enable Interrupts
banksel INTCON
BSF INTCON, GIE
BSF INTCON, PEIE
RETURN
;********************************************************************************
;********************************************************************************
; Main Loop
; --------------------------------------------------------------------
; Continuously loops and handles the program
; Looks for a button press, looks for a received message on EUSART
; If slave select raised transmits message or ack
;********************************************************************************
;********************************************************************************
Main:
CALL Initialize
PNT_2:
NOP
GOTO PNT_2
;
; Interrupt Service Routine
; ***********************************************************************
; ***** The PIC's one and only ISR... =( ******************************
; ***********************************************************************
Interrupt:
; PUSH
MOVWF W_TEMP ; Copy W to TEMP register
SWAPF STATUS, W ; Swap status to be saved into W
banksel PORTA
MOVWF STATUS_TEMP ; Save status to STATUS_TEMP register
; ISR
banksel PIR1
BTFSC PIR1, SSPIF
CALL SPI_Int
; POP
banksel PORTA
SWAPF STATUS_TEMP, W ; Swap nibbles in STATUS_TEMP register
; and place result into W
MOVWF STATUS ; Move W into STATUS register
; (sets bank to original state)
SWAPF W_TEMP, F ; Swap nibbles in W_TEMP and place result in W_TEMP
SWAPF W_TEMP, W ; Swap nibbles in W_TEMP and place result into W
RETFIE
; SPI_Int
; --------------------------------------------------------------------
; ISR that receives/transmits from SPI, but primary purpose is to receive
SPI_Int:
BCF PIR1, SSPIF
banksel PORTA
MOVF SSPBUF, W ; WREG reg = contents of SSPBUF
MOVWF SPI_RXDATA ; Save in user RAM, if data is meaningful
MOVF SPI_TXDATA, W ; W reg = contents of TXDATA
MOVWF SSPBUF ; New data to xmit
; Process the command
MOVLW 0xff
SUBWF SPI_RXDATA, w
BTFSC STATUS, Z
GOTO Initialize
BTFSC SPI_RXDATA, 7
GOTO LEDCtrl
GOTO CraftNumCtrl
LEDCtrl:
BTFSC SPI_RXDATA, 2
GOTO CheckStandDown
BTFSC SPI_RXDATA, 1
GOTO CheckActiveBase
GOTO CheckTeam
CheckActiveBase:
BTFSC SPI_RXDATA, 0
GOTO CtrlActiveRed
GOTO CtrlActiveBlue
CheckTeam:
BTFSC SPI_RXDATA, 0
GOTO CtrlTeamRed
GOTO CtrlTeamBlue
CtrlActiveRed:
BTFSC SPI_RXDATA, 3
GOTO IndicateActiveRed
BCF PORTA, ActiveRed
RETURN
IndicateActiveRed:
BSF PORTA, ActiveRed
RETURN
CtrlActiveBlue:
BTFSC SPI_RXDATA, 3
GOTO IndicateActiveBlue
BCF PORTA, ActiveBlue
RETURN
IndicateActiveBlue:
BSF PORTA, ActiveBlue
RETURN
CtrlTeamRed:
BTFSC SPI_RXDATA, 3
GOTO IndicateTeamRed
BCF PORTA, TeamRed
RETURN
IndicateTeamRed:
BSF PORTA, TeamRed
RETURN
CtrlTeamBlue:
BTFSC SPI_RXDATA, 3
GOTO IndicateTeamBlue
BCF PORTC, TeamBlue
RETURN
IndicateTeamBlue:
BSF PORTC, TeamBlue
RETURN
CheckStandDown:
BTFSC SPI_RXDATA, 3
GOTO IndicateStandDown
BCF PORTA, StandDown
RETURN
IndicateStandDown:
BSF PORTA, StandDown
RETURN
CraftNumCtrl:
; ERROR CHECKING : data only btwn 1 and 12
MOVLW 0x13
SUBWF SPI_RXDATA, W
BTFSC STATUS, C
RETURN
MOVF SPI_RXDATA, W
CALL LCDTable
banksel PORTA
MOVWF INPUT
MOVLW 0x00
BTFSS INPUT, 7
CALL LEDOff
ADDWF PCL, F
BSF PORTC, INPUTBIT
CALL PULSE
MOVLW 0x00
BTFSS INPUT, 6
CALL LEDOff
ADDWF PCL, F
BSF PORTC, INPUTBIT
CALL PULSE
MOVLW 0x00
BTFSS INPUT, 5
CALL LEDOff
ADDWF PCL, F
BSF PORTC, INPUTBIT
CALL PULSE
MOVLW 0x00
BTFSS INPUT, 4
CALL LEDOff
ADDWF PCL, F
BSF PORTC, INPUTBIT
CALL PULSE
MOVLW 0x00
BTFSS INPUT, 3
CALL LEDOff
ADDWF PCL, F
BSF PORTC, INPUTBIT
CALL PULSE
MOVLW 0x00
BTFSS INPUT, 2
CALL LEDOff
ADDWF PCL, F
BSF PORTC, INPUTBIT
CALL PULSE
MOVLW 0x00
BTFSS INPUT, 1
CALL LEDOff
ADDWF PCL, F
BSF PORTC, INPUTBIT
CALL PULSE
MOVLW 0x00
BTFSS INPUT, 0
CALL LEDOff
ADDWF PCL, F
BSF PORTC, INPUTBIT
CALL PULSE
BSF PORTC, CYCLEBIT
NOP
BCF PORTC, CYCLEBIT
MOVLW 0x0A
SUBWF SPI_RXDATA, W
BTFSC STATUS, C
GOTO $+3
BCF PORTC, CraftNumBit
RETURN
BSF PORTC, CraftNumBit
RETURN
LEDOff:
BCF PORTC, INPUTBIT
RETLW 0x01
PULSE:
BSF PORTC, CLOCKBIT
nop
BCF PORTC, CLOCKBIT
RETURN
Wait:
banksel Timer1
MOVLW 0xFF; setup the first counter for waiting
MOVWF Timer2
Wait2:
MOVLW 0xFF; setup the second counter for waiting
MOVWF Timer1
Wait1:
NOP
DECFSZ Timer1, F; decrement first counter, if zero loop
GOTO Wait1; is done
DECFSZ Timer2, F; decrement second counter, if zero loop
GOTO Wait2; is done
RETURN
END