.include "8515def.inc"

;*****************************************************************************************
;	Pins
;*****************************************************************************************

; PD0	Light off switch
; PD1	Light on switch
; PD2	Cooling off switch
; PD3	Cooling on switch
; PD4	FU off switch
; PD5	FU on switch
; PD6	turn left switch
; PD7	turn right switch
; PC0	motor off switch
; PC1	motor on switch

; PA0	Light off led
; PA1	Light on led
; PA2	Cooling off led
; PA3	Cooling on led
; PA4	FU off led
; PA5	FU on led
; PA6	turn left led
; PA7	turn right led
; PC7	motor off led
; PC6	motor on led

; PB0	light on relay
; PB1	cooling on relay
; PB2	FU on relay
; PB3	motor mains turn left relay
; PB4	motor mains on relay
; PB5	FU turn left relay
; PB6	FU turn right relay
; PB7	FU enable relay

;*****************************************************************************************
;	Variables
;*****************************************************************************************

.def	Temp			= r16			; Temporary Variable
.def	DelayTemp 		= r17
.def	Status1			= r18			; Actual State Register
									; Bit	0	1	= light on
									; Bit	1	1	= cooling on
									; Bit	2	1	= FU on
									;			0	= FU off
									; Bit	3	1	= motor on
									; Bit	4	1	= turn left
									;			0	= turn right
									; Bit	6	1	= key action occured

.def	Status2			= r19			; goal state register
									; Bit	0	1	= light on
									; Bit	1	1	= cooling on
									; Bit	2	1	= FU on
									;			0	= FU off
									; Bit	3	1	= motor on
									; Bit	4	1	= turn left
									;			0	= turn right
									; Bit	5	1	= delay routine running
									; Bit	6	1	= delay finished, jump to next actual state
									; Bit	7	1	= timer event occured
.def	TimCount		= r20		; to time the LED blink and turn up/down times
.def	LedBlink		= r21		; for the blinking leds (xor)


;*****************************************************************************************
;	Values
;*****************************************************************************************

.equ	shortdel		= 8				; counter value for short relay delay
.equ	longdel			= 64			; counter value for long motor delay

;*****************************************************************************************
;	Program Code
;*****************************************************************************************
.cseg
.org	$0000

;*****************************************************************************************
;	Interrupt Routines
;*****************************************************************************************

		rjmp	START					; Reset Vector
		reti							; Int0 Pin
		reti							; Int1 Pin
		reti							; Timer 1 Capture
		reti							; Timer 1 Compare A
		reti							; Timer 1 Compare B
		reti							; Timer 1 Overflow
		rjmp	T0OVFROUTINE			; Timer 0 Overflow
		reti							; SPI Transfer Complete
		reti							; UART RX Complete
		reti							; UART UDRE Routine
		reti							; UART TX Complete
		reti							; Analog Comparator

;*****************************************************************************************
;	Program Start
;*****************************************************************************************
START:
		ldi		Temp, low(RAMEND)				; init stack pointer
		out		SPL, Temp
		ldi		Temp, high(RAMEND)
		out		SPH, Temp
		clr		Status1							; set initial program state
		clr		Status2
		clr		LedBlink
		clr		Temp
		out		GIMSK, Temp						; Disable Interrupts Int0 and Int1
		out		UCR, Temp						; RXCIE, TXCIE, UDRIE, RXEN, TXEN, CHR9, RXB8, TXB8
		out		PORTB, Temp						; relay port
		out		DDRD, Temp						; set port D to input (switches)
		out		PORTC, Temp
		ldi		Temp, 0b11000000
		out		DDRC, Temp						; set mixed mode port
		ldi		Temp, 0b10010101				; default led config
		out		PORTA, Temp						; LED port
		sbi		PORTC, 0						; set switch inputs to weak pullup
		sbi		PORTC, 1
		sbi		PORTC, 7						; motor off led on
		ser		Temp
		out		PORTD, Temp						; set switch inputs to weak pullup
		out		DDRB, Temp						; relay port
		out		DDRA, Temp						; LED port
		ldi		Temp, 0b10010101				; set switches off leds
		out		PORTA, Temp
		cbi		PORTC, 6
		sbi		PORTC, 7
		ldi		Temp, 0b00000101				; set timer prescaler to 1024
		out		TCCR0, Temp						;  , , , , ,CS02,CS01,CS00
		ldi		Temp, 0b00000010				; enable timer 0 overflow
		out		TIMSK, Temp						; TOIE1,OCIE1A,OCIE1B, ,TICIE1, ,TOIE0, 
		sei										; enable interrupts

;********************************* MAIN ROUTINE ******************************************		

MAIN:
		sbrc	Status2, 7
		rjmp	MAIN_TIMER_EVENT				; start timer event routine after event occured
		rjmp	MAIN

MAIN_TIMER_EVENT:
		andi	Status2, 0b01111111				; reset timer event state
		rcall	READ_SWITCHES
		sbrc	Status1, 6						; keyboard action occured
		rcall	CHANGE_STATE
		sbrc	Status2, 6						; change state when timer or key routine ready
		rcall	CHANGE_STATE
		rjmp	MAIN

;*****************************************************************************************
;	Interrupt Routines
;*****************************************************************************************

T0OVFROUTINE:							; manage the TimCount value to start different routines
		push	Temp
		sbrs	Status2, 5						; skip if delay routine running
		rjmp	T0OVFROUTINE_NORMAL
		dec		TimCount						; decrease counter register
		mov		Temp, TimCount					; use some bit sequence to time blinking led
		andi	Temp, 0b00000111
		cpi		Temp, 0b00000100				; blink every 8 routines
		brne	T0OVFROUTINE_NO_BLINK
		rcall	LED_BLINK
 T0OVFROUTINE_NO_BLINK:
		cpi		TimCount, 0						; test if zero achieved
		brne	T0OVFROUTINE_NORMAL				; set bit if overflow
		ori		Status2, 0b01000000				; set delay finished bit if overflow
 T0OVFROUTINE_NORMAL:
		ori		Status2, 0b10000000				; set timer event state
		pop		Temp
		reti

;*****************************************************************************************
;	Subroutines
;*****************************************************************************************

READ_SWITCHES:							; read the switches and set the status
		push	Temp
		in		Temp, PIND
		cpi		Temp, 0b11101010
		breq	READ_SWITCHES_NO_D				; no switch at PORTD pressed
		ori		Status1, 0b01000000				; set keyboard action state
		sbrc	Temp, 0
		andi	Status2, 0b11111110				; light off state
		sbrs	Temp, 1
		ori		Status2, 0b00000001				; light on state
		sbrc	Temp, 2
		andi	Status2, 0b11111101				; cooling off state
		sbrs	Temp, 3
		ori		Status2, 0b00000010				; cooling on state
		sbrc	Temp, 4
		andi	Status2, 0b11111011				; FU off state
		sbrs	Temp, 5
		ori		Status2, 0b00000100				; FU on state
		sbrs	Temp, 6
		ori		Status2, 0b00010000				; turn left state
		sbrs	Temp, 7
		andi	Status2, 0b11101111				; turn right state
 READ_SWITCHES_NO_D:
		sbis	PINC, 0							; motor off switch
		rjmp	READ_SWITCHES_C0_RELEASED
		andi	Status2, 0b11110111				; set motor off goal state
		ori		Status1, 0b01000000				; set keyboard sction state
 READ_SWITCHES_C0_RELEASED:
		sbic	PINC, 1							; motor on switch
		rjmp	READ_SWITCHES_C1_RELEASED
		ori		Status2, 0b00001000				; set motor on goal and change actual state bit
		ori		Status1, 0b01000000				; set keyboard action state
 READ_SWITCHES_C1_RELEASED:
		pop		Temp
		ret

CHANGE_STATE:									; change the state depending on keyboard and timer events
		push	Temp
		mov		Temp, Status1					; backup of actual state
		eor		Temp, Status2					; compare actual/goal state
		andi	Temp, 0b00011111				; only use the control bits
		breq	CHANGE_STATE_NO_COOL			; actual=goal, test if delay finished
		sbrs	Temp, 0							; light state changed
		rjmp	CHANGE_STATE_NO_LIGHT			; light state changes immediately
		sbrc	Status2, 0
		rjmp	CHANGE_STATE_LIGHT_ON			; jump to light on
		in		Temp, PINA						; read led port
		andi	Temp, 0b11111101				; light on led off
		ori		Temp, 0b00000001				; light off led on
		out		PORTA, Temp						; write to led port
		in		Temp, PINB						; read relay port
		andi	Temp, 0b11111110				; switch the relay off
		out		PORTB, Temp						; write the relay port
		andi	Status1, 0b11111110				; set actual state
		rjmp	CHANGE_STATE_NO_LIGHT			; go to next test
 CHANGE_STATE_LIGHT_ON:							; switch light and led on
		in		Temp, PINA						; read led port
		andi	Temp, 0b11111110				; light off led off
		ori		Temp, 0b00000010				; light on led on
		out		PORTA, Temp						; write to led port
		in		Temp, PINB						; read relay port
		ori		Temp, 0b00000001				; switch light rel on
		out		PORTB, Temp						; write to relay port
		ori		Status1, 0b00000001				; set actual state
 CHANGE_STATE_NO_LIGHT:
		mov		Temp, Status1					; backup of actual state
		eor		Temp, Status2					; compare actual/goal state
		sbrs	Temp, 1							; cooling state changed
		rjmp	CHANGE_STATE_NO_COOL			; cooling state changes immediately
		sbrc	Status2, 1
		rjmp	CHANGE_STATE_COOL_ON			; jump to cooling on
		in		Temp, PINA						; read led port
		andi	Temp, 0b11110111				; cooling on led off
		ori		Temp, 0b00000100				; cooling off led on
		out		PORTA, Temp						; write to led port
		in		Temp, PINB						; read relay port
		andi	Temp, 0b11111101				; cooling rel off
		out		PORTB, Temp						; write to relay port
		andi	Status1, 0b11111101				; set actual state
		rjmp	CHANGE_STATE_NO_COOL			; go to next state change
 CHANGE_STATE_COOL_ON:
		in		Temp, PINA						; read led port
		andi	Temp, 0b11111011				; cooling off led off
		ori		Temp, 0b00001000				; cooling on led on
		out		PORTA, Temp						; write to led port
		in		Temp, PINB						; read relay port
		ori		Temp, 0b00000010				; cooling rel on
		out		PORTB, Temp						; write to relay port
		ori		Status1, 0b00000010				; set actual state
 CHANGE_STATE_NO_COOL:
		sbrs	Status2, 5						; test if delay routine running
		rjmp	CHANGE_STATE_KEY				; no, test if key pressed
		sbrs	Status2, 6						; yes, check if delay finished
		rjmp	CHANGE_STATE_OUT				; no, go out
		andi	Status2, 0b11011111				; reset delay running bit when delay finished
		rjmp	CHANGE_STATE_DO					; yes, change state
 CHANGE_STATE_KEY:
		sbrs	Status1, 6						; test if key action occured
		rjmp	CHANGE_STATE_OUT				; no, go out
		rjmp	CHANGE_STATE_DO
  C_S_ACT_001_JMP:
		rjmp	C_S_ACT_001
  C_S_ACT_010_JMP:
		rjmp	C_S_ACT_010
  C_S_ACT_011_JMP:
		rjmp	C_S_ACT_011
  C_S_ACT_100_JMP:
		rjmp	C_S_ACT_100
  C_S_ACT_101_JMP:
		rjmp	C_S_ACT_101
  C_S_ACT_110_JMP:
		rjmp	C_S_ACT_110
 CHANGE_STATE_DO:
		mov		Temp, Status1					; reload actual state
		andi	Temp, 0b00011100				; only use the motor state bits
		cpi		Temp, 0b00000100				; check for the different actual states
		brlo	C_S_ACT_000
		breq	C_S_ACT_001_JMP
		cpi		Temp, 0b00001100
		brlo	C_S_ACT_010_JMP
		breq	C_S_ACT_011_JMP
		cpi		Temp, 0b00010100
		brlo	C_S_ACT_100_JMP
		breq	C_S_ACT_101_JMP
		cpi		Temp, 0b00011100
		brlo	C_S_ACT_110_JMP
		rjmp	C_S_ACT_111
 C_S_ACT_000:
		mov		Temp, Status2					; load goal state
		andi	Temp, 0b00011100				; use motor bits only
		sbrc	Temp, 2
		rjmp	C_S_A_000_G_XX1					; all FU on goals result in same next state
		sbrc	Temp, 4
		rjmp	C_S_A_000_G_1X0					; all main left goals result in same next state
		cpi		Temp, 0b00001000
		brlo	C_S_A_000_G_000
		rjmp	C_S_A_000_G_010
  C_S_A_000_G_000:							; goal state achieved
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink
		out		PORTC, Temp
		clr		LedBlink						; clear blinking led
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_000_G_XX1:							; turn FU on
		in		Temp, PINA						; read led port
		andi	Temp, 0b11101111				; FU off led off
		ori		Temp, 0b00100000				; FU on led on
		out		PORTA, Temp						; write led port
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking leds to on
		out		PORTC, Temp						; write led port
		in		Temp, PINB						; read relay port
		andi	Temp, 0b00000111				; safe FU on
		ori		Temp, 0b00000100				; FU on
		out		PORTB, Temp
		clr		LedBlink						; all leds no blink
		ldi		TimCount, shortdel				; load the short delay
		ori		Status2, 0b00100000				; set delay running state
		ori		Status1, 0b00000100				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_000_G_010:							; turn motor on
		in		Temp, PINC						; read led port
		ori		Temp, 0b00000011				; hold pullups
		andi	Temp, 0b01111111				; motor off led off
		out		PORTC, Temp						; write led port
		ldi		LedBlink, 0b01000000			; blink motor on led
		in		Temp, PINB						; read relay port
		andi	Temp, 0b00010011				; save settings
		ori		Temp, 0b00010000				; switch motor on
		out		PORTB, Temp						; write to relay port
		ldi		TimCount, longdel				; use motor delay
		ori		Status2, 0b00100000				; set delay running state
		ori		Status1, 0b00001000				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_000_G_1X0:							; turn left state
		in		Temp, PINA						; read led port
		andi	Temp, 0b01111111				; turn right led off
		ori		Temp, 0b01000000				; turn left led on
		out		PORTA, Temp						; write to led port
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking leds to on
		out		PORTC, Temp						; write 2nd led port
		in		Temp, PINB						; read relay port
		andi	Temp, 0b00001011				; safe settings
		ori		Temp, 0b00001000				; mains left rel on
		out		PORTB, Temp						; write to relay port
		clr		LedBlink						; all leds no blink
		ldi		TimCount, shortdel				; load the short delay
		ori		Status2, 0b00100000				; set delay running state
		ori		Status1, 0b00010000				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
 C_S_ACT_001:
		mov		Temp, Status2					; load goal state
		andi	Temp, 0b00011100				; use motor bits only
		sbrs	Temp, 2							; all FU off goals result in same next state
		rjmp	C_S_A_001_G_XX0
		sbrc	Temp, 4							; 1X1 goals result in 101 next state
		rjmp	C_S_A_001_G_1X1
		cpi		Temp, 0b00001100
		brlo	C_S_A_001_G_001
		breq	C_S_A_001_G_011
  C_S_A_001_G_XX0:							; turn FU off
		in		Temp, PINA						; read led port
		andi	Temp, 0b11011111				; FU on led off
		ori		Temp, 0b00010000				; FU off led on
		out		PORTA, Temp						; write led port
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking leds to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink						; all leds no blink
		in		Temp, PINB						; read relay port
		andi	Temp, 0b00000011				; safe all off
		out		PORTB, Temp
		ldi		TimCount, shortdel				; load the short delay
		ori		Status2, 0b00100000				; set delay running state
		andi	Status1, 0b11111011				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_001_G_001:							; finalise goal state
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking leds to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink						; clear blinking led
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_001_G_011:							; turn FU right on
		in		Temp, PINC						; read led port
		ori		Temp, 0b00000011				; hold pullups
		andi	Temp, 0b01111111				; motor off led off
		out		PORTC, Temp						; write led port
		ldi		LedBlink, 0b01000000			; motor on led blink
		in		Temp, PINB						; read relay port
		andi	Temp, 0b11000111				; safe motor settings
		ori		Temp, 0b11000000				; FU right rel on
		out		PORTB, Temp						; write relay port
		ldi		TimCount, longdel				; load the long delay
		ori		Status2, 0b00100000				; set delay running state
		ori		Status1, 0b00001000				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_001_G_1X1:							; FU turn left
		in		Temp, PINA						; load led port
		andi	Temp, 0b01111111				; FU right led off
		ori		Temp, 0b01000000				; FU left led on
		out		PORTA, Temp						; write led port
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking leds to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink
		ldi		TimCount, shortdel				; load the short delay
		ori		Status2, 0b00100000				; set delay running state
		ori		Status1, 0b00010000				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
 C_S_ACT_010:
		mov		Temp, Status2					; load goal state
		andi	Temp, 0b00011100				; use motor bits only
		cpi		Temp, 0b00001000				; goal state test
		breq	C_S_A_010_G_010					; all goals except 010 result in 000 next
		rjmp	C_S_A_010_G_OFF
  C_S_A_010_G_OFF:							; turn motor off
		in		Temp, PINC						; load led port
		ori		Temp, 0b00000011				; hold pullups
		andi	Temp, 0b10111111				; motor on led off
		out		PORTC, Temp
		ldi		LedBlink, 0b10000000			; blink motor off led
		in		Temp, PINB						; load rel port
		andi	Temp, 0b00000011				; safe all off
		out		PORTB, Temp						; write rel port
		ldi		TimCount, longdel				; load the long delay
		ori		Status2, 0b00100000				; set delay running state
		andi	Status1, 0b11110111				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_010_G_010:							; finalise goal state
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking led to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink						; clear blinking led
		rjmp	CHANGE_STATE_OUT				; go out
 C_S_ACT_011:
		mov		Temp, Status2					; load goal state
		andi	Temp, 0b00011100				; use motor bits only
		cpi		Temp, 0b00001100				; goal state test
		breq	C_S_A_011_G_011
		rjmp	C_S_A_011_G_OFF					; all goals except 010 result in 000 next
  C_S_A_011_G_OFF:							; turn FU motor off
		in		Temp, PINC						; load led port
		ori		Temp, 0b00000011				; hold pullups
		andi	Temp, 0b10111111				; motor on led off
		out		PORTC, Temp
		ldi		LedBlink, 0b10000000			; blink motor off led
		in		Temp, PINB						; load rel port
		andi	Temp, 0b10000111				; save FU off
		out		PORTB, Temp						; write rel port
		ldi		TimCount, longdel				; load the long delay
		ori		Status2, 0b00100000				; set delay running state
		andi	Status1, 0b11110111				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_011_G_011:							; goal state achieved
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking led to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink						; clear blinking led
		rjmp	CHANGE_STATE_OUT				; go out
 C_S_ACT_100:
		mov		Temp, Status2					; load goal state
		andi	Temp, 0b00011100				; use motor bits only
		cpi		Temp, 0b00010000
		breq	C_S_A_100_G_100
		cpi		Temp, 0b00011000
		breq	C_S_A_100_G_110
		rjmp	C_S_A_100_G_OFF					; all other goals result in 000 next
  C_S_A_100_G_OFF:							; from left to right main state
		in		Temp, PINA						; read led port
		andi	Temp, 0b10111111				; left led off
		ori		Temp, 0b10000000				; right led on
		out		PORTA, Temp						; write led port
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking led to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink						; clear all blinking leds
		in		Temp, PINB						; read rel port
		andi	Temp, 0b00000011				; safe all off
		out		PORTB, Temp						; write rel port
		ldi		TimCount, shortdel				; load the short delay
		ori		Status2, 0b00100000				; set delay running state
		andi	Status1, 0b11101111				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_100_G_100:
		in		Temp, PINC
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink
		out		PORTC, Temp
		clr		LedBlink						; clear blinking led
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_100_G_110:							; turn motor on
		in		Temp, PINC						; read led port
		ori		Temp, 0b00000011				; hold pullups
		andi	Temp, 0b01111111				; motor off led off
		out		PORTC, Temp						; write led port
		ldi		LedBlink, 0b01000000			; blink motor on led
		in		Temp, PINB						; read rel port
		andi	Temp, 0b00011011				; safe turn left
		ori		Temp, 0b00010000				; motor on
		out		PORTB, Temp						; write rel port
		ldi		TimCount, longdel				; load the long delay
		ori		Status2, 0b00100000				; set delay running state
		ori		Status1, 0b00001000				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
 C_S_ACT_101:
		mov		Temp, Status2					; load goal state
		andi	Temp, 0b00011100				; use motor bits only
		cpi		Temp, 0b00010100
		breq	C_S_A_101_G_101
		cpi		Temp, 0b00011100
		breq	C_S_A_101_G_111
		rjmp	C_S_A_101_G_OFF					; all other goals result in 001
  C_S_A_101_G_OFF:							; FU left state off
		in		Temp, PINA						; read led port
		andi	Temp, 0b10111111				; left led off
		ori		Temp, 0b10000000				; right led on
		out		PORTA, Temp						; write led port
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking led to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink						; clear blinking leds
		ldi		TimCount, shortdel				; load the long delay
		ori		Status2, 0b00100000				; set delay running state
		andi	Status1, 0b11101111				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_101_G_101:
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking led to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink						; clear blinking led
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_101_G_111:							; FU motor left on
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		andi	Temp, 0b01111111				; motor off led off
		out		PORTC, Temp						; write 2nd led port
		ldi		LedBlink, 0b01000000			; blink motor on led
		in		Temp, PINB						; read rel port
		andi	Temp, 0b10100111				; safety settings
		ori		Temp, 0b10100000				; FU left on
		out		PORTB, Temp						; write rel port
		ldi		TimCount, longdel				; load the long delay
		ori		Status2, 0b00100000				; set delay running state
		ori		Status1, 0b00001000				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
 C_S_ACT_110:
		mov		Temp, Status2					; load goal state
		andi	Temp, 0b00011100				; use motor bits only
		cpi		Temp, 0b00011000				; goal state test
		breq	C_S_A_110_G_110
		rjmp	C_S_A_110_G_OFF					; all other goals result in 100
  C_S_A_110_G_OFF:							; turn motor off
		in		Temp, PINC						; load led port
		ori		Temp, 0b00000011				; hold pullups
		andi	Temp, 0b10111111				; motor on led off
		out		PORTC, Temp
		ldi		LedBlink, 0b10000000			; blink motor off led
		in		Temp, PINB						; load rel port
		andi	Temp, 0b00001011				; safe all off
		out		PORTB, Temp						; write relay port
		ldi		TimCount, longdel				; load the long delay
		ori		Status2, 0b00100000				; set delay running state
		andi	Status1, 0b11110111				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_110_G_110:							; goal state achieved
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking led to on
		out		PORTC, Temp						; write led port
		clr		LedBlink						; clear blinking led
		rjmp	CHANGE_STATE_OUT				; go out
 C_S_ACT_111:
		mov		Temp, Status2					; load goal state
		andi	Temp, 0b00011100				; use motor bits only
		cpi		Temp, 0b00011100
		breq	C_S_A_111_G_111
		rjmp	C_S_A_111_G_OFF					; all other goals result in 101
  C_S_A_111_G_OFF:							; turn FU motor off
		in		Temp, PINC						; load led port
		ori		Temp, 0b00000011				; hold pullups
		andi	Temp, 0b10111111				; motor on led off
		out		PORTC, Temp
		ldi		LedBlink, 0b10000000			; blink motor off led
		in		Temp, PINB						; load rel port
		andi	Temp, 0b10000111				; save FU off
		out		PORTB, Temp						; write rel port
		ldi		TimCount, longdel				; load the long delay
		ori		Status2, 0b00100000				; set delay running state
		andi	Status1, 0b11110111				; set new motor state
		rjmp	CHANGE_STATE_OUT				; go out
  C_S_A_111_G_111:							; goal state achieved
		in		Temp, PINC						; read 2nd led port
		ori		Temp, 0b00000011				; hold pullups
		or		Temp, LedBlink					; reset blinking led to on
		out		PORTC, Temp						; write 2nd led port
		clr		LedBlink						; clear blinking led
		rjmp	CHANGE_STATE_OUT				; go out
 CHANGE_STATE_OUT:
		andi	Status2, 0b00111111				; reset delay finished and timer event bits
		andi	Status1, 0b10111111				; reset key pressed bit
		pop		Temp
		ret

LED_BLINK:								; read the led blink registers and make the
												; the corresponding leds blink
		push	Temp
		in		Temp, PINC						; read 2nd led port
		andi	LedBlink, 0b11000011			; only use the led pins
		eor		Temp, LedBlink					; xor with blinking led
		out		PORTC, Temp						; write new port value
		pop		Temp
		ret