Appendix J: Assembly Language for the ANS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Alternative Navigation System
;
; This program will poll a pedometer, check the bearing on
the step taken, store it,
; and when the computer signals transmit this data to the
computer.
;
; By: Charles LaPierre 195138
; Masters Thesis Electrical Engineering
; Original Date: Dec 12, 1997 K Series
; Date: Feb. 24, 1998 J Series modifications
; Date: Mar. 21, 1998 compass modifications for signed
8-bit accumulator
; Date: Apr. 01, 1998 new debounce routine with internal
Timer Interrupts
; Date: Apr. 08, 1998 fixes to pedometer & calibrate
compass
; ROM used : 573 bytes
; Stack used : 10 bytes (ISR)
; : 2 bytes (delay_loop Subroutine)
; RAM used : 32 bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Compass
eoc_compass equ 0 ;port B pin 0 connects the EOC pin
from the compass
clock_compass equ 1 ;port B pin 1 connects the SCLK pin
from the compass
data_compass equ 2 ;port B pin 2 connects the SD0 pin
from the compass
poll_compass equ 3 ;port B pin 3 connects the P/C pin
from the compass
cal_compass equ 4 ;port B pin 4 connects the CAL pin
from the compass
power_compass equ 5 ;port B pin 5 connects the VCC pin
from the compass
sw1_cal_compass equ 1 ;port A pin 1 connects to SW1 to
initiate compass calibration
reset_compass equ 6 ;port A pin 6 connects the RESET
pin from the compass
select_compass equ 7 ;port A pin 7 connects the SS pin
from the compass
compass_port_B equ $01 ;port B's location (Compass is on
Port B)
compass_port_A equ $00 ;port A's location (reset & select
are on Port A)
;Serial Communication
send_data equ 0 ;port A pin 0 Computer requests Data
data_serial equ 4 ;port A pin 4 Sends serial
communication to the comp.
control_serial equ 5 ;port A pin 5 controls GPS/Backup
to the serial port
serial_port equ $00 ;port A's location (Serial
communication is on Port A)
;MASK Options MOR
MORaddr equ $7F1;location of MOR's address
MOR_options equ $24 ;SOSCD = 0 Short Oscillator delay
disabled
;EPMSEC = 0 access to EPROM array
;OSCRES = 1 crystal oscillation configuration
;SWAIT = 0 STOP
;SWPDI = 0 enable pulldown transistors
;PIRQ = 1 Port A's pins 0-3 are IRQ's
;Level = 0 Negative edge triggered Interrupt
;COPEN = 0 Cop disabled
;TIMER Options
Timer_addr equ $08 ;location of Timer Status & Control
Register
Enable_Timer equ 4 ;Real Time Interrupt Enabled
Reset_T_Flag equ 2 ;Real Time Interrupt Flag Reset
;Set RT0=0 & RT1 to 1, so that we get an interrupt
;every 32.8ms
;Port A configuration
PORTA_dataReg equ $00 ;Port A's Data Register
PullDown_A equ $10 ;port A's Pulldown Register
DDRA equ $04 ;port A's Data Direction Register
DDRA_options equ $F0 ;pin 7 1 - SS output
;pin 6 1 - RESET output
;pin 5 1 - Control output
;pin 4 1 - Output output
;pin 3 0 - NC input
;pin 2 0 - NC input
;pin 1 0 - SW1 input
;pin 0 0 - Computer input
PORTA_INIT equ $C0 ;Must set the proper state before we
;set port A pins as output
;pin 7 1 -SS
;pin 6 1 -RESET
;pin 5 0 -Control
;pin 4 0 -Data output
;pins 3-0 0 -these are inputs
;Port B configuration
PORTB_dataReg equ $01 ;Port B's Data Register
PullDown_B equ $11 ;Port B's Pulldown Register
DDRB equ $05 ;port B's Data Direction Register
DDRB_options equ $3A ;pin 5 1 - VCC compass output
;pin 4 1 - CAL compass output
;pin 3 1 - PC compass output
;pin 2 0 - SD0 compass input
;pin 1 1 - SCLK compass output
;pin 0 0 - EOC compass input
PORTB_INIT equ $1A ;Must set the proper state before we
;set port B pins as output
;pin 5 0 -VCC initially 0
;pin 4 1 -CAL compass
;pin 3 1 -PC compass
;pin 2 0 -SD0 input Don't care
;pin 1 1 -SCLK compass
;pin 0 0 -EOC input Don't care
;state configuration
state_lb equ 0 ;1'st bit
state_hb equ 1 ;2'th bit
;degree data
eighth equ 0 ;1'st bit
ninth equ 1 ;2'nd bit
neg_step equ 2 ;3'rd bit (negative step taken)
;ISR
IRQ_Status equ $0A ;location of IRQ Status/control Reg.
IRQ_dis_en equ 7 ;enable / disable interrupts
IRQ_clear equ 1 ;clear interrupt flag
isrtemp_lb equ 0 ;mask bit
isrtemp_hb equ 1 ;mask bit
;Directions Storage Array
dir_used equ $11 ;Uses 18 memory locations to store
directions
dir_res equ $0A ;each 10 degree resolution
;Delay Timings
delay_eoc equ $16 ;delay to wait after EOC goes high
(indicating valid data)
delay_cal equ $30 ;delay to calibrate compass (~
200ms)
delay_data equ $08 ;delay to retrieve data from
compass
delay_pc equ $16 ;delay to hold PC low. for compass
delay_power equ $01 ;delay long enough for pins to be
set high.
delay_inner equ $FF ;inner loop 255 times
delay_half_sec equ $70 ;delay for ~ 1/2 a second for
calibration & testing
;Program locations
RAMStart equ $00C0 ;Start of on chip RAM
ROMStart equ $0300 ;Start of on chip EPROM
ROMEnd equ $07CF ;End of on chip EPROM
Vectors equ $07F8 ;Start of Reset/Interrupt vectors
COPR equ $07F0 ;COP's Reset Register location
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; RAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Ram used 33 bytes
ORG RAMStart
state RMB 1 ;Internal State of the machine
;0-Nothing
;1-Step occurring
;2-Waiting for direction (i.e. step already occurred)
;3-Step occurring & Waiting for direction
step_count RMB 1 ;# of steps occurred while waiting
for a direction (max 127)
char_send RMB 1 ;Current character sending out serial
port
CRC RMB 1 ;CRC control
temp RMB 1 ;temp storage variable used as a mask
and a counter
degrees RMB 1 ;bit 0 is 8'th bit test, bit 1 is
9'th bit test, bit 2 is
;negative step taken
indexoffset RMB 1 ;shifting the directions offset
because of signed problems.
directions RMB dir_used+1 ;18 element array for
storing the # of steps in any
;direction with 10 degree resolution
tempa RMB 1 ;temp storage place to store A reg.
tempx RMB 1 ;temp storage place to store X reg.
tempisrx RMB 1 ;temp storage place in ISR to store X
reg.
tempisr RMB 1 ;temp storage signifying which data
type being sent
delay_outer RMB 1 ;outer loop delay timing
stepcomp RMB 1 ;step occurred while sending to the
computer
cal_check RMB 1 ;debouncing of calibration switch
ped_timer RMB 1 ;After x * (8.2 ms) uninterrupted
interrupts a step occurred.
ped_timing RMB 1 ;pedometer debounce timing (default
205ms, can range 106ms-xxxms)
ped_debounce RMB 1 ;non 0 if an interrupt from pedometer
occurs during the
;205 ms This is our debouncing of the switch.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MAIN PROGRAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Main program
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG ROMStart
; Initalize the RAM, and set the Ports & interrupts
; uses 69 bytes
start RSP ;Reset Stack Pointer
CLRA ;clear the accumulator
CLRX ;clear the x reg
CLI ;clear interrupt mask
;portA
LDA #PORTA_INIT ;Initialize Port A's Data register
STA PORTA_dataReg ;set the Port's data reg. before
changing the DDRA
CLRA ;set all output pins to have pulldowns
STA Pulldown_A
LDA #DDRA_options ;port A's Input / Output pins
STA DDRA ;store in the DDRA the ports options
;portB
LDA #PORTB_INIT ;Initialize Port B's Data register
STA PORTB_dataReg ;set the Port's data reg. before
changing the DDRB
CLRA ;set all output pins to have pulldowns on port B
STA PullDown_B
LDA #DDRB_options ;port B's Input / Output pins
STA DDRB ;store in the DDRB the ports options
;timer
BCLR 0,Timer_addr ;set RT0 to 0 for the 8.2ms interrupt
BCLR 1,Timer_addr ;Set RT1 to 0 for the 8.2ms interrupt
BCLR Enable_Timer,Timer_addr;disable interrupts until a
step occurs
BSET Reset_T_Flag,Timer_addr;clear the interrupt flag for
the timer
;ram
LDX #RAMStart ;location of RAM
clear_ram CLR 0,X ;clear the RAM
INCX ;go to next RAM location
BNE clear_ram ;(Since RAM is from C0-FF once inc past
FF we get 00
;in the X reg.)
;power up compass with CAL,PC,Reset,and SS high so as to
not hang the compass.
BSET cal_compass,compass_port_B;
BSET poll_compass,compass_port_B;
BSET reset_compass,compass_port_A;
BSET select_compass,compass_port_A;
LDX #delay_power ;wait a min time for pins to go high
STX delay_outer ;set outer loop delay
JSR delay_loop ;may not need this.
BSET power_compass,compass_port_B;turn on the power to
compass
LDA #$19 ;(25dec 25*8.2ms = 205ms)
STA ped_timing ;debounce timing is default at 205ms
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main program loop
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;6 bytes
main BRSET state_hb,state,compass ;are we waiting
for a direction
;is state == 2 || state == 3
;exit poll compass if we are not
;waiting for a direction
main_end JMP main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; delay_loop
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; delays for compass timing etc.
; 14 bytes used
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay_loop LDX delay_outer ;outer loop timing (memory
location)
delay_i LDA #delay_inner;inner loop 255
delay_j NOP ;2cycles
NOP ;2cycles
TSTA ;3cycles
DECA ;3cycles
BNE delay_j ;3cycles
DECX ;3cycles
BNE delay_i ;3cycles
RTS ;return from Subroutine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; poll compass
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; poll compass uses 106 bytes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
compass BRCLR eoc_compass,compass_port_B,main_end ;Is
EOC high
;indicating a direction is available
LDA #delay_eoc ;timing delay for valid data
STA delay_outer
JSR delay_loop ;must wait a min. of 10ms before
;getting data from compass
BCLR select_compass,compass_port_A ;lower SS
JMP get_dir ;reads in high/low byte & sets neg dir. if
high byte
fin_dir BSET select_compass,compass_port_A ;raise SS
BRSET ninth,degrees,deg256_360;degrees is between 256-360
BRSET eighth,degrees,deg128_255;degrees is between 128 and
255
deg0_127 BCLR neg_step,degrees ;we have a positive step
LDX #$00 ;no offset (0 - 127 degrees) (positive
direction)
STX indexoffset ;store the 0
JMP store_dir ;store the direction
deg128_255 CMP #$34 ;52 dec are we between 0 & 51
BHS deg180_255 ;or between 52 & 127
deg128_179 BCLR neg_step,degrees ;we have a positive step
ADD #$08 ;shift the dec # between 8 & 59 degrees
LDX #$0C ;index offset is 12dec so degree range
jumps to
;128 degrees to 179 degrees (positive direction)
STX indexoffset ;store the offset
JMP store_dir ;store the new direction
deg180_255 BSET neg_step,degrees ;we have a negative step
SUB #$34 ;52 dec shift the dec # between 0 & 75
degrees
;(but in the negative direction)
LDX #$00 ;no offset
STX indexoffset ;store the offset
JMP store_dir ;store the direction
deg256_360 BSET neg_step,degrees ;we have a negative step
ADD #$06 ;add six to the degrees for axis shifting
;degrees is 6 & 109
LDX #$07 ;index offset shift so new degrees is
shifted from
;76 - 179 degrees (but in negative direction)
STX indexoffset ;store the offset
JMP store_dir ;store the direction
store_dir CLRX ;acc has a number between (0 &
180) and test bit 7 tells
;us if its + or -
;we need to do a divide by multiple subtracts of 10
div_loop CMP #dir_res ;is the # in the accumulator
<10
BLO found_spot ;we found the position in the indexed array
of directions
INCX ;move to next array position
SUB #dir_res ;reduce the direction by 10 degrees to find
offset into
;array
JMP div_loop ;loop until acc <10
found_spot TXA ;get the current index
ADD indexoffset ;add the offset to index
TAX ;store in the x reg.
LDA step_count ;get step count
BRCLR neg_step,degrees,pos_dir ;we have a positive direction
NEGA ;make the steps negative which indicates a
negative dir.
pos_dir ADD directions,X;add the current directions
(steps) to the current steps
;in that direction
;step_count = step_count + directions[x] (where x=0-17)
STA directions,X;store new steps in direction array
CLR step_count ;clear the step count
BCLR state_hb,state ;state=state-2
;waiting for direction goes to nothing & waiting for
;direction & step goes to waiting for step
JMP main_end ;finished poll_compass
;;;;;;;;;
;get_dir;
;;;;;;;;;
;71 bytes
;the clocking is not even, but the compass can handle it.
get_dir CLRA ;char_storage location
STA degrees ;clear the degrees
LDX #delay_data ;timing for outloop
STX delay_outer
LDX #$10 ;loop counter
byte_loop STA tempa
STX tempx
JSR delay_loop
delay_comp1 BCLR clock_compass,compass_port_B ;[5]lower
clock
JSR delay_loop
delay_comp2 LDA tempa
LDX tempx
BSET clock_compass,compass_port_B ;[5]raise clock
BRSET data_compass,compass_port_B,byte_high ;[5]get bit
byte_low CLC ;[2]clear the carry for shift
JMP rotate ;[2]low byte finished
byte_high SEC ;[2]set the carry for shift
JMP rotate ;[2]timing
rotate ROLA ;[3]rotate in the data bytes
CPX #$08 ;[2]are we on the 1'st bit in Low byte
BEQ test_eight ;[3]check for bit being set
CPX #$09 ;[2]are we on the 8'th bit in High byte
BEQ test_nine ;[3]check for high bit being negative
DECX ;[3]loop = loop -1
BNE byte_loop ;[3]loop until we get all bytes
JMP fin_dir ;jump to the high byte read
test_nine DECX ;[3]loop-1
TSTA ;[3]check to see if we have a negative
direction
BEQ byte_loop ;[3]we have a + direction, get next byte
BSET ninth,degrees;[5]we have a 1 in the ninth spot.
CLRA ;[3]clear the accumulator
JMP byte_loop ;[2]
test_eight DECX ;[3]loop-1
BRCLR data_compass,compass_port_B,eight_not
;[5]check to see if we have a 1 from the 8'th bit in
BSET eighth,degrees;[5]we have a 1 in the eighth spot
eight_not CLRA ;[3]clear the accumulator
JMP byte_loop ;[2]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Interrupt Service Routines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ISR uses 256 bytes
; ISR uses 5 bytes of stack space
;
; IRQ line tied to the Pedometer
; PA0 line tied to the computer request data (RTS)
; PA1 line tied to the calibrate compass switch SW1
; PA2 line used for debugging debounce routine sets timing
to 106.6ms
; PA3 line used to increment debounce timing by 8.2ms each
time in.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;28 bytes
ISR BCLR IRQ_dis_en,IRQ_Status ;disable interrupts
BRSET send_data,serial_port,Send_JMP;did the computer cause
interrupt?
BRSET sw1_cal_compass,compass_port_A,Reset_Comp;did SW1
cause interrupt?
BIL Pedometer ;pedometer cause interrupt
BRSET 2,compass_port_A,Set_106ms;reset debounce routine to
106.6ms
BRSET 3,compass_port_A,Inc_deb;add 8.2ms to debounce routine
ISR_fin BSET IRQ_clear,IRQ_Status ;clear current
interrupts
BSET IRQ_dis_en,IRQ_Status ;re-enable interrupts
RTI ;return from ISR
;;;;;;;;;;;
;Pedometer;
;;;;;;;;;;;
;18 bytes
Pedometer BRCLR Enable_Timer,Timer_addr,start_timer;first
hit of pedometer
;enable the timer to debounce pedometer
INC ped_debounce;only 106ms+ of uninterrupted steps is
considered a step
JMP ISR_fin ;finished here
start_timer BSET state_lb,state ;change state was 0 goto 1,
was 2 goto 3;
BSET Enable_Timer,Timer_addr;enable the timer interrupt
CLR ped_debounce;clear the debounce routine
JMP ISR_fin ;finished
;;;;;;;;;;;;;;;;;;;
;calibrate compass;
;;;;;;;;;;;;;;;;;;;
;69 bytes
Reset_Comp LDA cal_check ;did we already calibrate
BNE ISR_fin ;debouncing possible here
LDA #delay_cal ;outer loop delay for calibrating the
compass
STA delay_outer
BCLR reset_compass,compass_port_A;reset the compass
JSR delay_loop ;delay 1
BSET reset_compass,compass_port_A;toggle line
JSR delay_loop ;delay 2
BCLR cal_compass,compass_port_B;calibrate compass
JSR delay_loop ;delay 3
BSET cal_compass,compass_port_B;finished calibrating part A
wait_switch BRSET
sw1_cal_compass,compass_port_A,wait_switch;wait for user
;release the switch
LDA #delay_half_sec; wait 1/2 a second before testing
STA delay_outer
JSR delay_loop ;delay 4
wait_180 BRCLR
sw1_cal_compass,compass_port_A,wait_180;wait for user to
;turn 180 degrees and pulse the switch again
BCLR cal_compass,compass_port_B;calibrate compass
LDA #delay_cal ;outer loop delay for calibrating the
compass
STA delay_outer
JSR delay_loop ;delay 5
BSET cal_compass,compass_port_B;finished calibrating part B
reset_fin BRSET
sw1_cal_compass,compass_port_A,reset_fin;wait till switch
is released
LDA #delay_half_sec; wait 1/2 a second for bouncing to
settle
STA delay_outer
JSR delay_loop ;delay 6
BSET IRQ_clear,IRQ_Status;clear current interrupts because
;calibrating the compass caused more interrupts.
INC cal_check ;just a check to make sure we don't go in
twice
;this gets reset after the computer asks for the
;data.
JMP ISR_fin ;Done
;jump point
;2 bytes
Send_JMP JMP Send_Comp; out of rang for branch.
;;;;;;;;;;;;;;;;;;;;;;;;;
;Reset debounce to 106.6ms;
;;;;;;;;;;;;;;;;;;;;;;;;;
;16 bytes
;This routine will reset the debounce timing to 106.6ms
Set_106ms LDA #$0D ;0D=13dec (13 * 8.2ms = 106.6ms)
STA ped_timing ;set the new debounce time interval to 124ms
wait_106 BRSET 2,compass_port_A,wait_106;wait for user
to exit
LDA #delay_half_sec; wait 1/2 a second for bouncing to
settle
STA delay_outer
JSR delay_loop ;delay 6
JMP ISR_fin ;Done
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Increment debounce by 8.2ms;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;30 bytes
;This routine will keep looping and each time SW1 (CAL
Compass) is pushed an
;extra 8.2ms is added onto the debounce timing for the
pedometer.
;exits by user releasing PA3
Inc_deb BRSET sw1_cal_compass,compass_port_A,add_ms;use
cal compass switch
BRSET 3,compass_port_A,Inc_deb;wait until user releases PA3
LDA #delay_half_sec; wait 1/2 a second for bouncing to
settle
STA delay_outer
JSR delay_loop ;delay
JMP ISR_fin ;Done
add_ms INC ped_timing ;increments by 8.2ms
wait_sw1 BRSET
sw1_cal_compass,compass_port_A,wait_sw1;wait for user
LDA #delay_half_sec; wait 1/2 a second for bouncing to
settle
STA delay_outer
JSR delay_loop ;delay
JMP Inc_deb ;loop back
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;step occurred while sending data to the computer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;5 bytes
step_w_comp BCLR 0,stepcomp ;clear the step flag
JMP Pedometer ;get the step which happened in the send
routine
;;;;;;;;;;;;;;;;;;;;;;;
;Send Data to Computer;
;;;;;;;;;;;;;;;;;;;;;;;
;114 bytes
Send_Comp BSET control_serial,serial_port ; stop GPS from
transmitting
CLR tempisrx ;used in CRC check so it must be set to 0
CLR CRC ;clear the CRC value
BSET isrtemp_lb,tempisr ;Mask bits 01 = header being sent
BCLR isrtemp_hb,tempisr ;
LDA #$AA ;header=10101010
JMP send_byte ;send the header
end_header LDA #$10 ;[2] 16 dec. delay loop to keep
timing from header to body
;character sent (172 between successive char)
;(28 of which has or will be wasted getting to body char
; & executing the JMP command)
;144 cycles to waist
keep_t_h0 TSTA ;3-|
DECA ;3 |loop 16*9=144 (144+28=172)
BNE keep_t_h0 ;3-|
NOP ;[2] part of 28
NOP ;[2] part of 28
LDX #dir_used ;[2]loop through all directions
BCLR isrtemp_lb,tempisr;[5]tempisr=xxxx xx10
BSET isrtemp_hb,tempisr;[5]10=body bytes being sent
send_dir LDA directions,X;[4]get the current loop_count
steps Acc = directions[x]
STX tempisrx ;[4]we need the X reg to transmit the data
JMP send_byte ;[2]send the data byte
end_byte LDX tempisrx ;[3]get the current loop count
DECX ;[3]count=count-1
BMI send_crc ;[3]finished sending all characters
LDA #$09 ;[2]9dec.delay loop to keep timing for body
data
;characters sent (172 between successive char)
;19 of which has or will be wasted getting to body char
;172-19=153 cycles to waist in delay loop
keep_t_d0 BIL step_d0 ;
3--|
BCLR 1,stepcomp ;do nothing timing filler 5| |loop
BRA dec_aa ; 3| |17*9
step_d0 BSET 0,stepcomp ;signal that a step occurred
5 :|=153
BRA dec_aa ; 3 :|
dec_aa DECA ;
3 |
BNE keep_t_d0 ; 3--|
TSTA ;[3]
TSTA ;[3]
JMP send_dir ;[2]send next direction
;now calc. & send CRC
send_crc BCLR isrtemp_lb,tempisr;[5]temp=xXXx xx00
BCLR isrtemp_hb,tempisr;[5]00=CRC being sent
LDA #$08 ;[2]8dec.delay loop to keep timing from
body to CRC
;character sent (172 between successive char)
;(38 of which has or will be wasted getting to CRC char.
;172-36=136 cycles to waist
keep_t_crc BIL step_crc ;
3--|
BCLR 1,stepcomp ;do nothing timing filler 5| |loop
BRA dec_aaa ; 3| |17*8
step_crc BSET 0,stepcomp ;signal that a step occurred
5 :|=136
BRA dec_aaa ; 3 :|
dec_aaa DECA ;
3 |
BNE keep_t_crc ; 3--|
NOP ;[2]
NOP ;[2]
TSTA ;[3]extra delay part of 36
cycles
TSTA ;[3]needed this extra delay (part of the
32cycles)
LDA CRC ;[3]get CRC
JMP send_byte ;[2]send CRC
end_crc LDX #dir_used ;[2]17 dec. Clear the
directions array
clear_loop CLR directions,X;[6]directions[x]=0 |
DECX ;[3]x=x-1 |(12x18=216)
BPL clear_loop ;[3]loop till X=-1 |
end_send BCLR control_serial,serial_port ; allow GPS to
resume transmitting
BRSET 0,stepcomp,step_w_comp;signal that a step occurred
jump to pedometer
CLR cal_check ;allow the compass to be re-calibrated again
JMP ISR_fin ;Done
;;;;;;;;;;;
;Send_byte;
;;;;;;;;;;;
;66 bytes
send_byte STA char_send ;save the character
4 |
ADD CRC ;add current char to the CRC 3 |
NOP ;timing 3 |entering
STA CRC ;save new CRC value 4 |send_byte
LDX #9 ;8 data bits 2 |=18
cycles
CLC ;clear carry start bit 2 |
put_data_b BCC send_0 ;if carry is a 0 send a 0
3----------|
BSET data_serial,serial_port ;send a 1 5: |
BRA delay1bit ;skip sending a 0 3: |
send_0 BCLR data_serial,serial_port ;send a 0
5| |
BRA delay1bit ;put here to keep timing |
;constant between bits send 3| |
delay1bit LDA #$0A ;10dec.
2 |Main
delay_send BIL step_data ;
3--| |bit
BCLR 1,stepcomp ;do nothing timing filler 5| |loop
|sending
BRA dec_a ; 3| |17*10
|loop
step_data BSET 0,stepcomp ;signal that a step occurred
5 :| |
BRA dec_a ; 3 :| |
dec_a DECA ;
3 |=170 |38+170
BNE delay_send ; 3--|
|=208 cycles
NOP ; 2
|between bits
TSTA ; 3 |
TSTA ; 3
|Therefore
TSTA ; 3
|before JMP
TSTA ; 3
|to routine
ROR char_send ;send next bit of character 5
|208-36=172
; |36=10exiting
DECX ;loop through all bits of the
|+26entering
;character 3 |must be used
BNE put_data_b ;end loop
3----------|between
send_stop TSTA ;delay 3 cycles due to not
| header & body
;doing a BCC as when sending | & CRC
;data 3 |leaving |
BSET data_serial,serial_port ;send stop bit 5
|send_byte|-send stop
BRSET isrtemp_lb,tempisr,wait_head; 01= header 5 |--header
=5 cycles
BRSET isrtemp_hb,tempisr,end_byte ;10= send_char5 |--body
=10 cycles**
JMP end_crc ;00=CRC called this routine 2 |--crc
=12 cycles
wait_head TSTA ;[3] keep timing the same
|5+3 = 8
JMP end_header ;[2] adds 5 cycles to header |2 = 10
cycles**
;timing == body timing...
;crc doesn't matter since were done at that point
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; TIMER Interrupt Service Routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ISR uses 51 bytes
; ISR uses 5 bytes of stack space
;
; This timing routine is called every 8.2ms after the
initial step occurs from
; the pedometer. While the pedometer is bouncing, this
routine keeps resetting
; until the pedometer is bounce free for 124+ms(default is
205 ms)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TIMER BSET Reset_T_Flag,Timer_addr;clear the
interrupt flag
LDA ped_debounce;did an interrupt occur during this 8.2 ms?
BEQ inc_timer ;add 1 to the timing routine
CLR ped_debounce;clear the debounce flag
CLR ped_timer ;start the 100ms over again.
RTI ;keep doing this until we get x ms of no
bounces
inc_timer INC ped_timer ;add 1 to the timer until we
have x or (8.2 ms * x)
LDA ped_timer ;get # of times into this routine
CMP ped_timing ;is this the xth time in?
BEQ step_taken ;123ms+ of no bounces from pedometer,
therefor step taken
RTI ;<x times in here.
step_taken BCLR Enable_Timer,Timer_addr;disable timer
interrupt
CLR ped_timer ;reset timer counter to 0
INC step_count ;steps taken ++
BRSET state_hb,state,ped_state;if we have state=3
;state not 1 ie. already polled compass just exit
;poll the compass to get direction for state
BCLR poll_compass,compass_port_B ;lower P/C
LDX #delay_pc ;wait at least 10ms before raising PC
STX delay_outer
JSR delay_loop
BSET poll_compass,compass_port_B ;raise P/C
ped_state BSET state_hb,state ;xxxx xx1x
BCLR state_lb,state ;xxxx xxx0
;change state to wait for compass
;state 1 or 3 becomes 2 (Waiting for direction)
fin_ped RTI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Vectors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG Vectors
FDB TIMER ;timer interrupt routine
FDB ISR ;IRQ vector
FDB start ;SWI (not used)
FDB start ;Reset vector