touchprobe.S 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. ;
  2. ; CNC touch probe driver
  3. ;
  4. ; Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
  5. ;
  6. ; This program is free software; you can redistribute it and/or
  7. ; modify it under the terms of the GNU General Public License
  8. ; as published by the Free Software Foundation; either version 2
  9. ; of the License, or (at your option) any later version.
  10. ;
  11. ; This program is distributed in the hope that it will be useful,
  12. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ; GNU General Public License for more details.
  15. .listmac
  16. .include "m8def.inc"
  17. .def zero = r0 ; Always zero'd
  18. .def sregsave = r1 ; SREG scratch space for IRQ handlers
  19. .def t0 = r16 ; Temp reg 0
  20. .def t1 = r17 ; Temp reg 1
  21. .def t2 = r18 ; Temp reg 2
  22. .def t3 = r19 ; Temp reg 3
  23. .def buzzcount = r25 ; Buzzer duration counter
  24. ; Hardware definitions
  25. .equ PROBESW_PIN = PINC ; Probe switches input
  26. .equ PROBESW1_BIT = 0 ; Trip switch 1
  27. .equ PROBESW2_BIT = 1 ; Trip switch 2
  28. .equ PROBESW3_BIT = 2 ; Trip switch 3
  29. .equ PROBEEN_BIT = 3 ; Probe-enable switch
  30. .equ PROBESW_MASK = (1<<PROBESW1_BIT)|(1<<PROBESW2_BIT)|(1<<PROBESW3_BIT)
  31. .equ TRIPLED_PORT = PORTB ; Trip LED
  32. .equ TRIPLED_BIT = 0
  33. .equ BUZZER_PORT = PORTB ; Trip buzzer
  34. .equ BUZZER_BIT = 3
  35. .equ TRIPSIG_PORT = PORTD ; Trip output signal (to CNC control)
  36. .equ TRIPSIG_BIT = 7
  37. ; Millisecond delay
  38. .macro mdelay ; mdelay(milliseconds)
  39. push t0
  40. push t1
  41. ldi t0, low(@0)
  42. ldi t1, high(@0)
  43. rcall __mdelay
  44. pop t1
  45. pop t0
  46. .endm
  47. .cseg
  48. .org 0x000
  49. rjmp reset
  50. .org OC2addr
  51. rjmp interrupt_timer2_comp
  52. .org 0x026
  53. ;*******************************************
  54. ;*** Timer 2 overflow interrupt handler ***
  55. ;*******************************************
  56. interrupt_timer2_comp:
  57. in sregsave, SREG
  58. dec buzzcount ; Decrement the duration counter
  59. brne __tm0comp_out ; Duration = zero?
  60. out TCCR2, zero ; Turn off the buzzer timer
  61. cbi BUZZER_PORT, BUZZER_BIT ; Ensure buzzer is off
  62. __tm0comp_out:
  63. out SREG, sregsave
  64. reti
  65. ; Turn on the buzzer (clobbers t0)
  66. .macro buzzer_poke
  67. cli
  68. ldi buzzcount, 250
  69. out TCCR2, zero
  70. out TCNT2, zero
  71. ; Set compare match value
  72. ldi t0, 10
  73. out OCR2, t0
  74. ; Start Timer2 in CTC mode. Toggle OC2 on compmatch.
  75. ; Frequency = CPU_HZ / 256
  76. ldi t0, (1<<COM20)|(1<<WGM21)|(1<<CS21)|(1<<CS22)
  77. sei
  78. out TCCR2, t0
  79. .endm
  80. ;*******************************************
  81. ;*** ENTRY POINT ***
  82. ;*******************************************
  83. reset:
  84. cli
  85. clr zero
  86. ; Init the stackpointer
  87. ldi t0, low(RAMEND)
  88. out SPL, t0
  89. ldi t0, high(RAMEND)
  90. out SPH, t0
  91. ; Setup the port configuration
  92. ldi t0, 0x00
  93. out PORTB, t0
  94. ldi t0, (1<<TRIPLED_BIT)|(1<<BUZZER_BIT)
  95. out DDRB, t0
  96. ldi t0, PROBESW_MASK | (1<<PROBEEN_BIT)
  97. out PORTC, t0
  98. ldi t0, 0x00
  99. out DDRC, t0
  100. ldi t0, 0x00
  101. out PORTD, t0
  102. ldi t0, (1<<TRIPSIG_BIT)
  103. out DDRD, t0
  104. ; Setup interrupt masks
  105. in t0, TIMSK
  106. ori t0, (1<<OCIE2)
  107. out TIMSK, t0
  108. sei
  109. ; Start in the idle loop
  110. rjmp enter_idleloop
  111. ;*********************************************
  112. ;*** Idle loop - The probe is disconnected ***
  113. ;*********************************************
  114. enter_idleloop:
  115. cbi TRIPSIG_PORT, TRIPSIG_BIT ; Deassert trip sig to CNC
  116. cbi TRIPLED_PORT, TRIPLED_BIT ; Turn off the trip LED
  117. mdelay 500 ; Debounce
  118. idleloop:
  119. sbis PROBESW_PIN, PROBEEN_BIT
  120. rjmp enter_probeloop
  121. rjmp idleloop
  122. ;*********************************************
  123. ;*** Probe loop - The probe is connected ***
  124. ;*********************************************
  125. enter_probeloop:
  126. cbi TRIPSIG_PORT, TRIPSIG_BIT ; Deassert trip sig to CNC
  127. cbi TRIPLED_PORT, TRIPLED_BIT ; Turn off the trip LED
  128. mdelay 500 ; Debounce
  129. probeloop:
  130. in t0, PROBESW_PIN ; Get the probe switches state
  131. andi t0, PROBESW_MASK
  132. cp t0, zero ; Is the probe tripped?
  133. breq probeloop ; No, check again
  134. sbi TRIPSIG_PORT, TRIPSIG_BIT ; Forward trip sig to CNC
  135. sbi TRIPLED_PORT, TRIPLED_BIT ; Turn on the trip LED
  136. buzzer_poke ; Poke the trip buzzer
  137. mdelay 20 ; Debounce
  138. waitrelease: ; Wait until probe is released
  139. sbic PROBESW_PIN, PROBEEN_BIT ; Is the probe still connected?
  140. rjmp enter_idleloop ; No, enter idle loop
  141. in t0, PROBESW_PIN ; Get the probe switches state
  142. andi t0, PROBESW_MASK
  143. cp t0, zero ; Is the probe still tripped?
  144. brne waitrelease ; Yep, check again
  145. cbi TRIPSIG_PORT, TRIPSIG_BIT ; Deassert trip sig to CNC
  146. cbi TRIPLED_PORT, TRIPLED_BIT ; Turn off the trip LED
  147. mdelay 50 ; Debounce
  148. rjmp probeloop
  149. ;*******************************************
  150. ;*** Utility functions ***
  151. ;*******************************************
  152. .equ DELAY_1MS_TIMERFREQ = (1 << CS01) ; == CPU_FREQ/8
  153. .equ DELAY_1MS_LOOP = 80
  154. .equ DELAY_1MS_LOOP_TIMES = 25
  155. __mdelay:
  156. push t2
  157. push t3
  158. ldi t2, DELAY_1MS_TIMERFREQ ; Enable timer0
  159. out TCCR0, t2
  160. __mdelay_loop:
  161. ldi t2, DELAY_1MS_LOOP_TIMES ; Loop for 1ms
  162. __mdelay_1ms_loop:
  163. out TCNT0, zero ; Start TCNT0 at zero
  164. __mdelay_timer_loop:
  165. in t3, TCNT0 ; Wait for TCNT0 >= DELAY_1MS_LOOP
  166. cpi t3, DELAY_1MS_LOOP
  167. brlo __mdelay_timer_loop
  168. dec t2 ; Decrement the 1ms loop counter
  169. brne __mdelay_1ms_loop
  170. subi t0, low(1)
  171. sbci t1, high(1)
  172. brne __mdelay_loop ; Wait another millisecond
  173. out TCCR0, zero ; Stop timer0
  174. pop t3
  175. pop t2
  176. ret