;***************************************************************************
;* Routines to set all the time registers of the 8583 I2C RTC klok
;*
;* Autor	: H. Vos
;* Date	: 04-02-98
;*
;* E-mail		: hugo@hvos.myweb.nl
;* 
;*
;***************************************************************************
;
; Routine for setting the proper hour vallue to the 8583 clock chip
;
;***************************************************************************

set_hour:

	ldi	Ax, Dispclear		; Set display cursor function
	ldi	Bx, disp_CTRL
	rcall	disp_lcd

	ldi	Ax, low(rtc)		; write tekst to te display
	ldi	Bx, high(rtc)
	ldi	Cx, $00
	rcall	Str2disp	

	ldi	Ax, low(uren)
	ldi	Bx, high(uren)
	ldi	Cx, $40
	rcall	Str2disp

	ldi	Ax, $46
	ldi	Bx, $0A	
	rcall	disp_space

	ldi	Ax, PCF8583
	ldi	Bx, $04
	rcall	I2C_regread		; read register Bx from device Ax

	mov	Cx, Ax			; store read data into Cx

start_hourset:

	rcall	Key_released

	ldi	Ax, $48
	mov	Bx, Cx
	rcall	Disp_DECval

	mov	Ax, Cx				; Load DEC clock vallue into Ax
	ldi	Bx, $00				; Load Bx with min DEC vallue
	ldi	Cx, $24				; Load Cx with max DEC vallue

	rcall	moddecval			 
	mov	Cx, Ax				; Save new vallue into Cx

	cpi	Bx, $00
	breq	start_hourset

	push	Bx				; save lastkey pressed vallue

	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $04				; load Bx with I2C device reg. nummer
						; Cx already loaded with hour vallue
	rcall	I2C_regstore

	pop	Bx
	cpi	Bx, select_key			; check if lastkey was select
	breq	set_min				; if so, start set min vallue

	rjmp	endtimeset			; otherwise jump back to display time and temp
		
;***************************************************************************
;
; Routine for setting the proper minute vallue to the 8583 clock chip
;
;***************************************************************************

set_min:

	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $04				; load Bx with I2C device reg. nummer
						; Cx already loaded with hour vallue
	rcall	I2C_regstore			; save hour vallue

	rcall	Key_released

	ldi	Ax, low(min)
	ldi	Bx, high(min)
	ldi	Cx, $40
	rcall	Str2disp

	ldi	Ax, $48
	ldi	Bx, $08
	rcall	disp_space
	
	ldi	Ax, PCF8583
	ldi	Bx, $03				;
	rcall	I2C_regread			; read register Bx from device Ax

	mov	Cx, Ax				; store read data into Cx

start_minset:

	rcall	Key_released

	ldi	Ax, $49
	mov	Bx, Cx
	rcall	Disp_DECval

	mov	Ax, Cx				; Load DEC clock vallue into Ax
	ldi	Bx, $00				; load Bx with min DEC vallue
	ldi	Cx, $60				; load Cx with max DEC vallue

	rcall	moddecval
	mov	Cx, Ax				; Save new vallue into Cx

	cpi	Bx, $00
	breq	start_minset

	push	Bx				; save lastkey pressed vallue

	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $03				; load Bx with I2C device reg. nummer
						; Cx already loaded with hour vallue
	rcall	I2C_regstore

	pop	Bx
	cpi	Bx, select_key			; check if lastkey was select
	breq	set_month			; if so, start set min vallue

	rjmp	endtimeset			; otherwise jump back to display time

;***************************************************************************
;
; Routine for setting the proper month vallue to the 8583 clock chip
;
;***************************************************************************

set_month:
	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $03				; load Bx with I2C device reg. nummer
						; Cx already loaded with hour vallue
	rcall	I2C_regstore			; save hour vallue
	
	rcall	Key_released

	ldi	Ax, low(maand)
	ldi	Bx, high(maand)
	ldi	Cx, $40
	rcall	Str2disp

	ldi	Ax, $46
	ldi	Bx, $0A
	rcall	disp_space

	ldi	Ax, PCF8583
	ldi	Bx, $06				; read month
	rcall	I2C_regread			; read register Bx from device Ax
	andi	Ax, 0b00011111			; Remove weekday information

	mov	Cx, Ax				; store read data into Cx

start_monthset:

	rcall	Key_released

	mov	Bx, Cx				; display low nibble of vallue
	ldi	Ax, $47
	rcall	disp_DECval

	mov	Ax, Cx				; Load DEC clock vallue into Ax
	ldi	Bx, $01				; load Bx with min DEC vallue
	ldi	Cx, $13				; load Cx with max DEC vallue

	rcall	moddecval
	mov	Cx, Ax				; Save new vallue into Cx

	cpi	Bx, $00
	breq	start_monthset

	push	Bx				; save lastkey pressed vallue
	
	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $06				; Read I2C device register
	rcall	I2C_regread

	andi	Ax, 0b11100000			; Clear lower 6 bits
	or	Cx, Ax				; Load Cx with new register vallue
	ldi	Ax, PCF8583			; Load Ax with I2C device address
	ldi	Bx, $06				; load Bx with I2C device reg. nummer
						
	rcall	I2C_regstore

	pop	Bx
	cpi	Bx, select_key			; check if lastkey was select
	breq	set_day				; if so, start set day vallue

	rjmp	endtimeset			; otherwise jump back to display time


;***************************************************************************
;
; Routine for setting the proper day vallue to the 8583 clock chip
;
;***************************************************************************

set_day:

	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $06				; Read I2C device register
	rcall	I2C_regread

	andi	Ax, 0b11100000			; Clear lower 6 bits
	or	Cx, Ax				; Load Cx with new register vallue

	ldi	Ax, PCF8583			; Load Ax with I2C device address
	ldi	Bx, $06				; load Bx with I2C device reg. nummer
	rcall	I2C_regstore

	rcall	Key_released

	ldi	Ax, low(dag)
	ldi	Bx, high(dag)
	ldi	Cx, $40
	rcall	Str2disp

	ldi	Ax, PCF8583
	ldi	Bx, $05				; read date/year register
	rcall	I2C_regread			; read register Bx from device Ax

	andi	Ax, 0b00111111			; remove year information from data
	mov	Cx, Ax				; store read data into Cx

start_dayset:

	rcall	Key_released

	mov	Bx, Cx			; display low nibble of vallue
	ldi	Ax, $4E
	rcall	disp_DECval

	mov	Ax, Cx
	ldi	Bx, $01
	ldi	Cx, $32

	rcall	moddecval
	mov	Cx, Ax				; Save new vallue into Cx

	cpi	Bx, $00
	breq	start_dayset

	push	Bx				; save lastkey pressed vallue
	
	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $05				; Read I2C device register
	rcall	I2C_regread

	andi	Ax, 0b11000000			; Clear lower 6 bits
	push	Cx				; Save Cx to stack
	or	Cx, Ax				; Load Cx with new register vallue
	ldi	Ax, PCF8583			; Load Ax with I2C device address
	ldi	Bx, $05				; load Bx with I2C device reg. nummer
	rcall	I2C_regstore
	pop	Cx				; Get old Cx vallue from stack

	pop	Bx
	cpi	Bx, select_key			; check if lastkey was select
	breq	set_dayweek			; if so, start set dayweek vallue

	rjmp	endtimeset			; otherwise jump back to display time

;***************************************************************************
;
; Routine for setting the proper day vallue to the 8583 clock chip
;
;***************************************************************************

set_dayweek:

	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $05				; Read I2C device register
	rcall	I2C_regread

	andi	Ax, 0b11000000			; Clear lower 6 bits
	or	Cx, Ax

	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $05				; load Bx with I2C device reg. nummer
						; Cx already loaded with hour vallue
	rcall	I2C_regstore

	rcall	Key_released
	
	ldi	Ax, low(dag_w)
	ldi	Bx, high(dag_w)
	ldi	Cx, $40
	rcall	Str2disp

	ldi	Ax, PCF8583
	ldi	Bx, $06				; read month/Weekday
	rcall	I2C_regread			; read register Bx from device Ax
	andi	Ax, 0b11100000			; remove month information from data
	swap	Ax				; swap high nibble to low nibble
	lsr	Ax				; and rotate one bt right
	
	mov	Cx, Ax				; store read data into Cx

start_dayweekset:

	rcall	Key_released			; check for no key pressed

	push	Cx				; save "day of week" to stack
;	mov	Ax, Cx				; load reg contens into Ax
;	lsl	Ax				; multiply vallue by two
;	mov	Cx, Ax
	lsl	Cx
	ldi	Ax, low(dagen)
	ldi	Bx, high(dagen)
	rcall	calcpointer
	mov	Z_low, Ax
	mov	Z_high, Bx

	lpm	
	adiw	Z_low, $01
			
	mov	Bx, R0				; load 1st CHR to display
	ldi	Ax, $4d
	rcall	dispCHR

	lpm				
	mov	Bx, R0				; load 2nd CHR to display
	ldi	Ax, $4e
	rcall	dispCHR

	pop	Cx				; restore "day of week" value into Cx reg	mov	Ax, Cx
	mov	Ax, Cx				; and move it to Ax reg.
	ldi	Bx, $00				; load min value into Bx and
	ldi	Cx, $07				; max value +1 into Cx reg

	rcall	moddecval
	mov	Cx, Ax				; Save new vallue into Cx

	cpi	Bx, $00
	breq	start_dayweekset

	push	Bx				; save lastkey pressed vallue
	
	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $06				; Read I2C device register
	rcall	I2C_regread

	andi	Ax, 0b00011111			; Clear lower 6 bits

	push	Cx				; Save Cx on stack
	swap	Cx
	lsl	Cx
	or	Cx, Ax				; Load Cx with new register vallue
	ldi	Ax, PCF8583			; Load Ax with I2C device address
	ldi	Bx, $06				; load Bx with I2C device reg. nummer
	rcall	I2C_regstore
	pop	Cx

	pop	Bx
	cpi	Bx, select_key			; check if lastkey was select
	breq	set_year			; if so, start set dayweek vallue

	rjmp	endtimeset			; otherwise jump back to display time


;***************************************************************************
;
; Routine for setting the proper year vallue to the 8583 clock chip
;
;***************************************************************************

set_year:

	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $06				; Read I2C device register
	rcall	I2C_regread

	andi	Ax, 0b00011111			; Clear lower 6 bits
	swap	Cx
	lsl	Cx
	or	Cx, Ax				; Load Cx with new register vallue
	ldi	Ax, PCF8583			; Load Ax with I2C device address
	ldi	Bx, $06				; load Bx with I2C device reg. nummer
	rcall	I2C_regstore
	
	rcall	Key_released

	ldi	Ax, low(Jaar)
	ldi	Bx, high(Jaar)
	ldi	Cx, $40
	rcall	Str2disp

	ldi	Ax, $47				; Load Ax with display position
	ldi	Bx, $32				; Load Bx with "2"
	rcall	DispCHR
	
	inc	Ax				; go to next display position
	ldi	Bx, $30				; Load Bx with "0"
	rcall	DispCHR

	ldi	Ax, PCF8583
	ldi	Bx, $FF				; read year information from RTC SRAM location
	rcall	I2C_regread			; read register Bx from device Ax
	rcall	HEX2DEC				; convert value to DEC value
	mov	Cx, Ax				; store read data into Cx

start_yearset:

	rcall	Key_released			; Check for no key's pressed anymore

	ldi	Ax, $49
	mov	Bx, Cx
	rcall	disp_DECval
	
	mov	Ax, Cx				; Load current DEC val into Ax
	ldi	Bx, $00				; Load min. DEC val into Bx reg
	ldi	Cx, $99				; Load max. DEC val into Cx
	rcall	moddecval
	mov	Cx, Ax				; Save new vallue into Cx

	cpi	Bx, $00				; check for end of modification
	breq	start_yearset			; if not, then loop again

	mov	Ax, Cx				; mov new value to Ax
	rcall	DEC2HEX				; and convert it into HEX val
	mov	Cx, Ax				; and move back to Cx reg.
	push	Cx				; and save on stack
	
	ldi	Ax, PCF8583			; load Ax with I2C device adres
	ldi	Bx, $FF				; Read I2C device register
	rcall	I2C_regstore			; save new year into in SRAM
	
	ldi	Ax, PCF8583
	ldi	Bx, $05
	rcall	I2C_regread
	
	
	andi	Ax, 0b00111111			; Clear bit[6:7]
	pop	Cx
	andi	Cx, 0b00000011			; Remove Bit[2:7]
	swap	Cx
	lsl	Cx
	lsl	Cx
	or	Cx, Ax				; Load Cx with new register vallue
	ldi	Ax, PCF8583			; Load Ax with I2C device address
	ldi	Bx, $05				; load Bx with I2C device reg. nummer
	rcall	I2C_regstore
	rjmp	endtimeset

;***************************************************************************
;
; Routine to converd a DEC vallue in ADCII vallue and display it
;
;	Ax = start display position
;	Bx = Dec vallue to display	
;
; Return:
;	
;	none
;
;***************************************************************************

disp_DECval:

	push	Bx

	andi	Bx, $F0		; select 10th number of DEC vallue
	swap	Bx
	subi	Bx, $D0		; calculate ASCII vallue
	push	Ax
	rcall	dispCHR		; and display it on the LCD.

	pop	Ax
	pop	Bx
	andi	Bx, $0F		; select 1th number of DEC vallue
	subi	Bx, $D0		; and calculate ASCII vallue
	inc	Ax
	rcall	dispCHR		; and dislpay it on the LCD.

	ret

endtimeset:

	ret
