; Firmware for Welder Synchron Timer 1-99 Halfwaves
; AT89C2051
; Konstantin Gilsenberg 
; slowolitus@rambler.ru 
; 20.07.2011 

; ---------constants-----------
MAXTIME		EQU 99		;
MINTIME		EQU  1	    ;
PEDDB       EQU 3		;pedal debounce constante
KEYDB	    EQU 5		;key debounce delay    (x10mS)
KEYDA		EQU 70		;key autorepeat delay  (x10mS)	 
KEYARR	    EQU 15		;autorepeat rate       (x10mS)		
KEYFARR		EQU 7		;fast autorepeat rate  (x10mS)
ARCOUNT		EQU 10		;autorepeat to fast autorepeat count

; ----------ports--------------
SEG_A	EQU P1.2		;indicators segment A
SEG_B	EQU P1.3		;indicators segment B
SEG_C	EQU P1.4		;indicators segment C
SEG_D	EQU P1.5		;indicators segment D
SEG_E	EQU P1.6		;indicators segment E
SEG_F	EQU P1.7		;indicators segment F
SEG_G	EQU P3.7		;indicators segment G

SCAN0	EQU TXD			;display scan digit 1
SCAN1	EQU RXD			;display scan digit 2
KEY_UP	EQU T0			;UP   key
KEY_DN	EQU INT1		;DOWN key
PED_IN	EQU T1          ;Pedal input
FIRE	EQU INT0		;Fire out
CP      EQU P3.6		;comparator
;---------- Bit addressing memory
FLAGS   EQU 020H		;flags
TIME	EQU 021H	    ;time set
COUNT   EQU 022H		;time counter
ZERO	EQU 023H		;zero crossing register
COMP    EQU 024H        ;comparator state
PED_ST	EQU 025H		;pedal state prev/curr
KEYDBT	EQU 026H		;key debounce timer
KEYTM	EQU 027H		;key timer
PREV	EQU 028H		;previous key code
REPCNT	EQU 029H		;repeat counter
;---------- Byte addressing memory
UNITS	EQU 030H
TENS    EQU 031H
;---------- Flags-----------------
ON_OFF	EQU FLAGS.0	;timer ON/OFF bit
PRESS	EQU FLAGS.1	;keyboard press bit
DIGIT   EQU FLAGS.2 ;digit
;PEDAL   EQU FLAGS.3 ;pedal press bit
HWAVE   EQU FLAGS.4 ;previous halfwave polarity 
;----------- Work registers------ 
PEDDBT  EQU R6
INTEG   EQU R7
;--------- Vectors Area ------------
org     0000h
		jmp Begin	    ;reset vector
org     0003h
        reti
org     000Bh
        reti
org     0013h
		reti
org     001Bh
		reti
org     0023h
		reti
;---------- Main Program -----------
;--------- Initialisation ----------
using		0
org 		002Bh
Begin: 		clr EA				; interruptions disabled
	    	mov P1,#0FFh
			mov P3,#0FFh
			mov TIME,#MINTIME
			mov COUNT,TIME
			mov DPTR,#FONT
			clr A
			mov PREV,A
			mov COMP,A
			mov PED_ST,A
			mov FLAGS,A
			setb ON_OFF
;------------------------------------
MAIN:	   	mov C,CP		  ;zero crossing detection
			mov A,COMP	     	
			rlc A
			mov COMP,A		  ;save comparator state in COMP
			jnb COMP.0,COM_0
			jnb COMP.1,FRONT
			jmp MAIN
	COM_0:	jnb COMP.1,MAIN			 
				  
	FRONT:	jnb ON_OFF,T_OFF  ;timer is on/off?

			mov A,PED_ST	  ;pedal processing
			cjne A,#00h,REF_1
			jmp SUBR
	REF_1:	cjne A,#01h,REF_2
			jmp REF_4
	REF_2:	cjne A,#02h,REF_3
		  	mov COUNT,TIME		;Timer reload
			jmp SUBR
	REF_3:	mov A,COUNT			;time over?
			jz 	SUBR
			
	REF_4:	jnb COMP.0,NEG  	;check edges (polarity of halfwave)
			jnb HWAVE,SUBR		
			jmp REF_5
	NEG:	jb HWAVE,SUBR 		;negadiv edge detected!
	REF_5:	call PULSE			;thyristor fire
			cpl HWAVE
			dec COUNT
			jmp SUBR

T_OFF:		jnb PED_ST.0,SUBR     ;pedal is pressed?
			call PULSE			 ;thyristor fire
SUBR:		call CK_PEDAL		 ;if timer is off 
			call CK_KEY               
			call INDIC
			jmp MAIN

;--------- Pedal check----------
CK_PEDAL:   setb PED_IN			   		;debounce first step, high frequency
			mov	PEDDBT,#20
			mov A,#0
DEB0:		mov C,PED_IN
			addc A,#0
			djnz PEDDBT,DEB0
			subb A,#10

			jc DEB3
			clr C
			jmp DEB4

;			jc  DEB2
;			cjne INTEG,#0,DEB1			;debounce second step, integration
;			clr C
;			jmp DEB4
;  DEB1:    dec INTEG
;			ret
;  DEB2:	mov A,#PEDDB
;		    subb A,INTEG
;			jc 	DEB3
;			inc INTEG
;			ret

	DEB3:   setb C
	DEB4:   mov A,PED_ST
	        rlc A
			anl A,#03h					  
			mov PED_ST,A				;PED_ST.0 current pedal state, PED_ST.1 previous pedal state
			ret
;-------- 6 ms pulse ------------
PULSE:      clr FIRE
			call WAIT_6ms
			setb  FIRE
			ret
;-------- Wait 6 ms -------------
WAIT_6ms:   mov R4,#12
	  REF2:	mov R3,#255
	  REF1:	djnz R3,REF1
	  		djnz R4,REF2
			ret
;======== Keyboard check ========

CK_KEY:		MOV C,KEY_UP		;keyboard check
			ANL C,KEY_DN
			JC  NP				;jump if no press
			MOV A,#0FFH
			MOV C,KEY_UP
			RLC A
			MOV C,KEY_DN
			RLC A
			CPL A				;ACC.1 - UP, ACC.0 - DN
			MOV R0,A
			XRL A,PREV
			JNZ ND
			MOV A,KEYDBT  		 ; Time over?
			JZ DOV
			DEC KEYDBT
			SJMP W1				;jump if debounce delay is not over
	DOV:	CJNE R0,#1,NDN
			CALL DO_DN			;DOWN pressed
	NDN:	CJNE R0,#2,NUP
			CALL DO_UP			;UP pressed
	NUP:	CJNE R0,#3,NUD
			CALL DO_UD			;UP+DOWN pressed
	NUD:    SETB PRESS
			SJMP W1
	ND:		MOV PREV,R0			;edge detected!
	NP:		CLR PRESS
			MOV KEYDBT,#KEYDB	;debounce timer load

	W1:		MOV A,KEYTM
			JZ W2
	        DEC KEYTM		;advance key timer
	W2:		RET

;UP key processing:

DO_UP:    	JB PRESS,UPH	;jump if key hold
			MOV KEYTM,#KEYDA	;first press, autorepeat delay load
			MOV REPCNT,#0	;autorepeat counter clear
			SJMP UP_DO
	UPH:	MOV A,KEYTM	;KEYTM check
			JNZ UP_RET
			CLR C
			MOV KEYTM,#KEYARR	;load normal repeat rate
			MOV A,REPCNT
			SUBB A,#ARCOUNT	;REPCNT check
			JC UP_DO		;jump if REPCNT < ARCOUNT
			MOV KEYTM,#KEYFARR	;load fast repeat rate
	UP_DO:	MOV A,TIME
			XRL A,#MAXTIME
			JZ UP_RET		;jump if limit
			INC TIME		;time inc.
			INC REPCNT	;autorepeat counter inc.
	UP_RET: RET

;DOWN key processing:

DO_DN:    	JB PRESS,DNH	;jump if key hold
			MOV KEYTM,#KEYDA	;first press, autorepeat delay load
			MOV REPCNT,#0	;autorepeat counter clear
			SJMP DN_DO
	DNH:	MOV A,KEYTM	;KEYTM check
			JNZ DN_RET
			CLR C
			MOV KEYTM,#KEYARR	;load normal repeat rate
			MOV A,REPCNT
			SUBB A,#ARCOUNT	;REPCNT check
			JC DN_DO		;jump if REPCNT < ARCOUNT
			MOV KEYTM,#KEYFARR	;load fast repeat rate
	DN_DO:  MOV A,TIME
			xrl A,#MINTIME
			jz  DN_RET
			DEC TIME		;time dec.
			INC REPCNT	;autorepeat counter inc.
	DN_RET: RET

;UP+DOWN key processing:

DO_UD:		JB PRESS,UD_RET	;no hold mode
			jb ON_OFF,UD_OFF
			setb ON_OFF
			jmp UD_RET
	UD_OFF:	clr ON_OFF
	UD_RET: RET

;------------------Indication-----------------------
INDIC:	  	jb ON_OFF,IND1
			mov UNITS,#0Ah  ; "-"
			mov TENS, #0Ah  ; "-"
			jmp IND2
IND1:      	mov A,TIME		; BCD decoding
			mov B,#10
			div AB
			jnz NZ
			mov TENS,#0Bh   	; blank code
			jmp UN
		NZ: mov TENS,A
		UN:	mov UNITS,B
IND2:       jb DIGIT,IND3
            mov A,UNITS		 ; indicate units
			movc A,@A+DPTR
			call IND
			clr  SCAN0
			jmp IND4	
	IND3:	mov A,TENS		 ; indicate tens
			movc A,@A+DPTR
			call IND
			clr  SCAN1
	IND4:	cpl DIGIT	
			ret

IND:		setb SCAN0
			setb SCAN1
			RRC A
			MOV SEG_A,C
			RRC A
			MOV SEG_B,C
			RRC A
			MOV SEG_C,C
			RRC A
			MOV SEG_D,C
			RRC A
			MOV SEG_E,C
			RRC A
			MOV SEG_F,C
			RRC A
			MOV SEG_G,C
			RET

;Font table
;	            GFEDCBA
FONT:
			DB 11000000B	;code 00H, character 0
			DB 11111001B	;code 01H, character 1
			DB 10100100B	;code 02H, character 2
			DB 10110000B	;code 03H, character 3
			DB 10011001B	;code 04H, character 4
			DB 10010010B	;code 05H, character 5
			DB 10000010B	;code 06H, character 6
			DB 11111000B	;code 07H, character 7
			DB 10000000B	;code 08H, character 8
			DB 10010000B	;code 09H, character 9
			DB 10111111B    ;"-" 
			DB 11111111B	;character blank

END
