;W-760 DS12887 support module

;Constantes:

.equ	SigA	= 0x01		;signature address (at seconds alarm)
.equ	SigV	= 0xDA		;signature value

.DSEG	;Data segment

tms:	.byte 3			;time to set
.equ	tmsHrs	= tms + 0	;hours
.equ	tmsMin	= tms + 1	;minutes
.equ	tmsSec	= tms + 2	;seconds

tmg:	.byte 3			;time to get
.equ	tmgHrs	= tmg + 0	;hours
.equ	tmgMin	= tmg + 1	;minutes
.equ	tmgSec	= tmg + 2	;seconds

.CSEG	;Code segment

;----------------------------------------------------------------------------

;Check RTC signature
;and init RTC if fail:

RTC_I:	ldi	temp,0x01	;time to set init
	sts	tmsSec,temp
	sts	tmsMin,temp
	sts	tmsHrs,temp
	
	ldi	YL,SigA
	rcall	Rd_RTC		;read signature
	cpi	temp,SigV
	breq	SigOK

	ldi	YL,SigA
	ldi	temp,SigV
	rcall	Wr_RTC		;signature init
	rcall	SetRTC		;set RTC

SigOK:	rcall	GetRTC		;get RTC
	ret

;----------------------------------------------------------------------------

;Set new time:
;Input: tmsMin, tmsHrs, tmsSec = 0

SetTm:	clr	temp
	sts	tmsSec,temp	;seconds = 0
	rcall	SetRTC
	rcall	GetRTC
	sei
	ret

;----------------------------------------------------------------------------

;Set RTC:
;Input: tmsSec, tmsMin, tmsHrs

SetRTC:	ldi	temp,0x83	;mode (SET=1, 24/12=1, DSE=1)
	ldi	YL,0x0B		;register B address
	rcall	Wr_RTC		;write data to RTC

	ldi	temp,0x20	;oscillator enable
	ldi	YL,0x0A		;register A address
	rcall	Wr_RTC		;write data to RTC

	lds	temp,tmsSec	;load seconds
	ldi	YL,0x00		;seconds register address
	rcall	Wr_RTC		;write data to RTC

	lds	temp,tmsMin	;load minutes
	ldi	YL,0x02		;minutes register address
	rcall	Wr_RTC		;write data to RTC

	lds	temp,tmsHrs	;load hours
	ldi	YL,0x04		;hours register address
	rcall	Wr_RTC		;write data to RTC

	ldi	temp,0x13	;mode (UIE interrupt=1, 24/12=1, DSE=1)
	ldi	YL,0x0B		;register B address
	rcall	Wr_RTC		;write data to RTC
	ret

;Get RTC:

;----------------------------------------------------------------------------

;Get RTC:
;Out: tmgSec, tmgMin, tmgHrs

GetRTC:	ldi	YL,0x00		;seconds register address
	rcall	Rd_RTC		;read seconds
	sts	tmgSec,temp	;update seconds

	ldi	YL,0x02		;minutes register address
	rcall	Rd_RTC		;read minutes
	sts	tmgMin,temp	;update minutes

	ldi	YL,0x04		;hours register address
	rcall	Rd_RTC		;read hours
	sts	tmgHrs,temp	;hours update

	ldi	YL,0x0C		;register C address
	rcall	Rd_RTC		;read register C to clear interrupt flag
	ret

;----------------------------------------------------------------------------

;Write data to the RTC:
;Input: YL - address, temp - data

Wr_RTC:	Port_DS_1		;DS <- 1
	Port_RW_1		;RW <- 1
	Port_AS_1
	push	temp
	mov	temp,YL
	rcall	WR_Dat		;AD <- ADDRESS
	Port_AS_0		;AS <- 0
	Port_RW_0		;RW <- 0
	pop	temp
	rcall	WR_Dat		;AD <- DATA
	Port_RW_1		;RW <- 1
	ret

;Read data from the RTC:
;Input: YL - address
;Out:   temp  - data

Rd_RTC:	Port_DS_1		;DS <- 1
	Port_RW_1		;RW <- 1
	Port_AS_1
	mov	temp,YL
	rcall	WR_Dat		;AD <- ADDRESS
	Port_AS_0		;AS <- 0
	rcall	PortZ		;perform bus to read	
	Port_DS_0		;DS <- 0
	rcall	RD_Dat		;DATA <- AD
	push	temp
	Port_DS_1		;DS <- 1
	rcall	PortO		;set up port to out
	pop	temp
	ret

;----------------------------------------------------------------------------

;Write RTC data port:
;In: temp - data byte

WR_Dat:	mov	YH,temp
	in	YL,DPORTL
	andi	YL,0xF0
	andi	temp,0x0F
	or	YL,temp
	out	DPORTL,YL	;write DPORTL

	swap	YH
	in	YL,DPORTH
	andi	YL,0xF0
	andi	YH,0x0F
	or	YL,YH
	out	DPORTH,YL	;write DPORTH
	ret

;Perform RTC data port to read:

PortZ:	ldi	temp,DIRBr	
	out	DDRB,temp	;Set PORTB direction to in
	ldi	temp,DIRCr
	out	DDRC,temp	;Set PORTC direction to in
	ret

;Read RTC data port:
;Out: temp - data byte

Rd_Dat:	in	YL,DPORTLr	;read DPORTL
	andi	YL,0x0F
	in	temp,DPORTHr	;read DPORTH
	andi	temp,0x0F
	swap	temp
	or	temp,YL
	ret

;Set up port to out:

PortO:	ldi	temp,DIRB	
	out	DDRB,temp	;Set PORTB direction to out
	ldi	temp,DIRC
	out	DDRC,temp	;Set PORTC direction to out
	ret

