summaryrefslogtreecommitdiffstats
path: root/touchprobe/firmware/touchprobe.S
blob: 15f48dd0161e59a358dab80ed772c9368fd8da80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
;
;   CNC touch probe driver
;
;   Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
;
;   This program is free software; you can redistribute it and/or
;   modify it under the terms of the GNU General Public License
;   as published by the Free Software Foundation; either version 2
;   of the License, or (at your option) any later version.
;
;   This program is distributed in the hope that it will be useful,
;   but WITHOUT ANY WARRANTY; without even the implied warranty of
;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;   GNU General Public License for more details.

.listmac
.include "m8def.inc"


.def zero			= r0	; Always zero'd
.def sregsave			= r1	; SREG scratch space for IRQ handlers
.def t0				= r16	; Temp reg 0
.def t1				= r17	; Temp reg 1
.def t2				= r18	; Temp reg 2
.def t3				= r19	; Temp reg 3
.def buzzcount			= r25	; Buzzer duration counter


; Hardware definitions
.equ PROBESW_PIN		= PINC	; Probe switches input
.equ PROBESW1_BIT		= 0	; Trip switch 1
.equ PROBESW2_BIT		= 1	; Trip switch 2
.equ PROBESW3_BIT		= 2	; Trip switch 3
.equ PROBEEN_BIT		= 3	; Probe-enable switch
.equ PROBESW_MASK		= (1<<PROBESW1_BIT)|(1<<PROBESW2_BIT)|(1<<PROBESW3_BIT)
.equ TRIPLED_PORT		= PORTB	; Trip LED
.equ TRIPLED_BIT		= 0
.equ BUZZER_PORT		= PORTB	; Trip buzzer
.equ BUZZER_BIT			= 3
.equ TRIPSIG_PORT		= PORTD	; Trip output signal (to CNC control)
.equ TRIPSIG_BIT		= 7


; Millisecond delay
.macro mdelay ; mdelay(milliseconds)
	push t0
	push t1
	ldi t0, low(@0)
	ldi t1, high(@0)
	rcall __mdelay
	pop t1
	pop t0
.endm

.cseg
.org 0x000
	rjmp reset
.org OC2addr
	rjmp interrupt_timer2_comp

.org 0x026

;*******************************************
;*** Timer 2 overflow interrupt handler  ***
;*******************************************
interrupt_timer2_comp:
	in sregsave, SREG
	dec buzzcount					; Decrement the duration counter
	brne __tm0comp_out				; Duration = zero?
	out TCCR2, zero					; Turn off the buzzer timer
	cbi BUZZER_PORT, BUZZER_BIT			; Ensure buzzer is off
 __tm0comp_out:
	out SREG, sregsave
	reti

; Turn on the buzzer (clobbers t0)
.macro buzzer_poke
	cli
	ldi buzzcount, 250
	out TCCR2, zero
	out TCNT2, zero
	; Set compare match value
	ldi t0, 10
	out OCR2, t0
	; Start Timer2 in CTC mode. Toggle OC2 on compmatch.
	; Frequency = CPU_HZ / 256
	ldi t0, (1<<COM20)|(1<<WGM21)|(1<<CS21)|(1<<CS22)
	sei
	out TCCR2, t0
.endm

;*******************************************
;*** ENTRY POINT                         ***
;*******************************************
reset:
	cli
	clr zero

	; Init the stackpointer
	ldi t0, low(RAMEND)
	out SPL, t0
	ldi t0, high(RAMEND)
	out SPH, t0

	; Setup the port configuration
	ldi t0, 0x00
	out PORTB, t0
	ldi t0, (1<<TRIPLED_BIT)|(1<<BUZZER_BIT)
	out DDRB, t0

	ldi t0, PROBESW_MASK | (1<<PROBEEN_BIT)
	out PORTC, t0
	ldi t0, 0x00
	out DDRC, t0

	ldi t0, 0x00
	out PORTD, t0
	ldi t0, (1<<TRIPSIG_BIT)
	out DDRD, t0

	; Setup interrupt masks
	in t0, TIMSK
	ori t0, (1<<OCIE2)
	out TIMSK, t0

	sei
	; Start in the idle loop
	rjmp enter_idleloop

;*********************************************
;*** Idle loop - The probe is disconnected ***
;*********************************************
enter_idleloop:
	cbi TRIPSIG_PORT, TRIPSIG_BIT			; Deassert trip sig to CNC
	cbi TRIPLED_PORT, TRIPLED_BIT			; Turn off the trip LED
	mdelay 500					; Debounce
idleloop:
	sbis PROBESW_PIN, PROBEEN_BIT
	rjmp enter_probeloop
	rjmp idleloop

;*********************************************
;*** Probe loop - The probe is connected   ***
;*********************************************
enter_probeloop:
	cbi TRIPSIG_PORT, TRIPSIG_BIT			; Deassert trip sig to CNC
	cbi TRIPLED_PORT, TRIPLED_BIT			; Turn off the trip LED
	mdelay 500					; Debounce
probeloop:
	in t0, PROBESW_PIN				; Get the probe switches state
	andi t0, PROBESW_MASK
	cp t0, zero					; Is the probe tripped?
	breq probeloop					; No, check again

	sbi TRIPSIG_PORT, TRIPSIG_BIT			; Forward trip sig to CNC
	sbi TRIPLED_PORT, TRIPLED_BIT			; Turn on the trip LED
	buzzer_poke					; Poke the trip buzzer
	mdelay 20					; Debounce

 waitrelease:						; Wait until probe is released
	sbic PROBESW_PIN, PROBEEN_BIT			; Is the probe still connected?
	rjmp enter_idleloop				; No, enter idle loop
	in t0, PROBESW_PIN				; Get the probe switches state
	andi t0, PROBESW_MASK
	cp t0, zero					; Is the probe still tripped?
	brne waitrelease				; Yep, check again

	cbi TRIPSIG_PORT, TRIPSIG_BIT			; Deassert trip sig to CNC
	cbi TRIPLED_PORT, TRIPLED_BIT			; Turn off the trip LED
	mdelay 50					; Debounce

	rjmp probeloop

;*******************************************
;*** Utility functions                   ***
;*******************************************

.equ DELAY_1MS_TIMERFREQ	= (1 << CS01) ; == CPU_FREQ/8
.equ DELAY_1MS_LOOP		= 80
.equ DELAY_1MS_LOOP_TIMES	= 25
__mdelay:
	push t2
	push t3
	ldi t2, DELAY_1MS_TIMERFREQ	; Enable timer0
	out TCCR0, t2
 __mdelay_loop:
	ldi t2, DELAY_1MS_LOOP_TIMES	; Loop for 1ms
 __mdelay_1ms_loop:
	out TCNT0, zero			; Start TCNT0 at zero
 __mdelay_timer_loop:
	in t3, TCNT0			; Wait for TCNT0 >= DELAY_1MS_LOOP
	cpi t3, DELAY_1MS_LOOP
	brlo __mdelay_timer_loop
	dec t2				; Decrement the 1ms loop counter
	brne __mdelay_1ms_loop
	subi t0, low(1)
	sbci t1, high(1)
	brne __mdelay_loop		; Wait another millisecond
	out TCCR0, zero			; Stop timer0
	pop t3
	pop t2
	ret
bues.ch cgit interface