; ; ODIN Motion Control Emergency Stop Extension ; ; Copyright (c) 2009 Michael Buesch ; ; 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" ; CPU_HZ is 8MHz .def zero = r0 ; Always zero'd .def sregsave = r1 ; Scratch register for SREG in 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 econditions = r23 ; Scratch register to store E-STOP conditions .def sigtimer = r24 ; Input signal conditioning timer counter .def tov1_clear_mask = r25 ; Holds mask to clear TOV1 .equ CHGPUMP_IN_PIN = PIND ; Charge pump signal from EMC .equ CHGPUMP_IN_BIT = 3 .equ MSPINDLESTOP_IN_PIN = PIND ; Master Spindle stop signal from EMC .equ MSPINDLESTOP_IN_BIT = 4 .equ MSPINDLERUN_OUT_PORT = PORTB ; Master Spindle enable signal to spindle Relais .equ MSPINDLERUN_OUT_BIT = 0 .equ ESTOP_IN_PIN = PIND ; E-STOP signal from EMC .equ ESTOP_IN_BIT = 5 .equ ESTOP_OUT_PORT = PORTD ; E-STOP signal to EMC .equ ESTOP_OUT_BIT = 6 .equ ESTOPBTN_PIN = PIND ; E-STOP push button .equ ESTOPBTN_BIT = 7 .equ JOINTBRAKE_PORT = PORTB ; Joints brake signal output to LMDs .equ JOINTBRAKE_BIT = 1 ; E-STOP conditions .equ ECOND_FROMEMC = 0 .equ ECOND_FROMBUTTON = 1 .equ ECOND_FROMCHGPUMP = 2 ; 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 ; cpsne - Compare and skip if not equal - Inverted cpse .macro cpsne cpse @0, @1 cpse r0, r0 .endm .cseg .org 0x000 rjmp reset .org INT1addr rjmp interrupt_int1 .org OC2addr rjmp interrupt_timer2_oc .org 0x026 ;******************************************* ;*** INT1 interrupt handler *** ;******************************************* interrupt_int1: ; No need to save SREG. Nobody changes flags. out TCNT1H, zero ; Reset the charge pump monitor timer out TCNT1L, zero out TIFR, tov1_clear_mask ; Clear the overflow flag reti ;******************************************* ;*** TIMER2 OC interrupt handler *** ;******************************************* interrupt_timer2_oc: in sregsave, SREG cpse sigtimer, zero ; Decrement the counter, if it's bigger than zero. dec sigtimer out SREG, sregsave reti ;********************************************* ;*** Check for charge pump monitor timeout *** ;*** Returns t0=1 => timeout *** ;*** t0=0 => no timeout *** ;********************************************* check_charge_pump_timeout: cli ; Get charge pump monitor timer state in t0, TCNT1L in t1, TCNT1H sei in t2, TIFR sbrc t2, TOV1 ; Charge pump timer overflow rjmp __chg_pump_timeout ldi t2, 10 ; Timeout, if bigger cp t0, t2 ; Charge pump monitor timeout? cpc t1, zero brsh __chg_pump_timeout ldi t0, 0 ret __chg_pump_timeout: ldi t0, 1 ret ;******************************************* ;*** 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, (1<= 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