$NOMOD51
$include (C8051F930.inc)      
 
HUMI_NOM		EQU 45		; calibration values: humidity
TEMP_NOM		EQU 19		; calibration value:  temperature (C)
N_NOM			EQU 0x1317		; calibration value:  oscillator period 
		
PMU0CF_Snapshot 	EQU R5
Period_low		EQU LOW(500)	; settings for 35 msec timeout  
Period_high		EQU HIGH(500)	 
Period_dark_low	EQU 0xFE		; setting for the light check period
Period_dark_high	EQU 0xFF						
Light_TH		EQU 0x10		; ambient light intensity threschold
T_0			EQU TEMP_NOM*4

	DSEG 	AT 0x20			; data segment in direct addressable space
Status:	DS 1				; status bits for circular buffer
Counter:	DS 1				; counter for the # of measurements
DB_counter:	DS 1				; calibration counter
AUX:		DS 1				; auxilary temporary bit-addressable storage

	ORG	0x30
bufTemp: 	DS 16				; circular buffer for temperature (8x 2-byte entries)
tempAve_lo:	DS 1				; storage for temperature average sum
tempAve_hi:	DS 1
temp_lo:	DS 1				; temp value 
temp_hi:	DS 1
LCD_cnt:	DS 1				; counter for LCD cycles

	ORG 	0x50
bufHumi:	DS 16				; curcular buffer for humidity
humiAve_lo: DS 1				; storage for humidity average sum
humiAve_hi: DS 1
humi_lo:	DS 1
humi_hi:	DS 1

	CSEG 	AT 0				; interrupt vectors
	ljmp 	Main  			; reset

	ORG	0x2B				; Timer2 ISR
	anl	TMR2CN, #0x3F		; clear Timer2 interrupt flags
	reti

	ORG	0xB3				; code section right after the int. vectors
	USING    0                    ; specify register bank 

main:       
	anl   PCA0MD, #NOT(0x40)      ; disable the WDT
	mov	SP, #0x7F			; setup stack in indirect storage area
	
	acall	Debug_Trap
	acall	Ports_Setup
	acall	Clock_Setup
	acall	RTC_Setup			; initialize oscillators			
	acall	ADC_Setup			; initialize hardware
	acall	Comparator_Setup

	mov	Counter, #1			; initialize conversion counter
	mov	DB_counter, #0
	mov	Status,  #3			; request circ buffers initialization
	mov	AUX, #0
	mov	LCD_cnt, #1
	sjmp	measure

loop: 					; MAIN LOOP
	mov	PMU0CF, #(SLEEP OR RTCAWK) ; set wakeup sources
	nop   				; device is now awake
  	nop
	nop
	nop
	mov	A, PMU0CF			; capture the wake-up source
   	mov 	PMU0CF, #CLEAR		; clear all wake-up source flags

	jnb	ACC.4, $+8			; RESET pin wake-up?
	mov	A, #100			; YES - make a 20 usec delay
	djnz	ACC, $		
   			
	mov	A, #0xFE			; toggle LCD pins
	xrl	P0, A
	mov	A, #0xC1
	xrl	P1, A
	mov	A, #0x7F
	xrl	P2, A

measure:
	djnz	LCD_cnt, loop		; time to perform measurement?
	mov	LCD_cnt, #60		; YES - restore counter
	acall	getTempHumi			; update temp & Humi values on display
	sjmp	loop				; uncomment this line if no light sensor present

	mov	A, Counter			
	cjne	A, #0, loop			; time to check light? 
	acall getLight			; YES - is light ON ?		
	jnc	loop				; YES - continue the main loop

	mov	P0, #0x01			; NO - display off
	mov	P1, #0x3C
	mov	P2, #0x00
	mov	R6, #Period_dark_low	; reassign RTC clock to 2 sek
	mov	R7, #Period_dark_high	; wake-up time
	acall	ALARM_Setup

wait4light:					; and check for light periodically
	acall	LPM				; sleep till the next light test
	acall	getLight			; is it dark yet ?
	jc	wait4light			; YES - keep waiting

	mov	Status,  #3			; NO - request circ buffers initialization
	mov	LCD_cnt, #1			; make immediate measurement
	mov	R6, #Period_low		; reassign RTC clock to its regular
	mov	R7, #Period_high		; wake-up time
	acall	ALARM_Setup
	sjmp	measure			; back to the main loop

;-------------------PROCEDURES-------------------------------------------
Debug_Trap:
	anl	P1MDOUT, #NOT(0x18)	; configure P1:3 and P1:4 for open drain
	mov	P1, #0x18			; pull them up to VCC
	nop
	jnb	P1.3, $			; debug trap
	jnb	P1.4, $			; wait while P1.3 or P1.4 is grounded
	ret

;-----------------------------------------------------------------------
Ports_Setup:
	mov  	P0MDIN,    #0xFE		; analog input on P0.0	
	mov  	P0MDOUT,   #0xFE		; open drain on P0.0
	mov  	P1MDIN,    #0xDB		; analog input on P1.2, P1.5
    	mov  	P1MDOUT,   #0xC3		; open drain on on P1[5:2]
	mov  	P2MDIN,    #0xFF		; digital I/O on P2
    	mov  	P2MDOUT,   #0x7F		; digital input on P2
	mov  	P0SKIP,    #0xFF		; I/O function on P0
    	mov  	P1SKIP,    #0xFF		; I/O function on P1
    	mov  	P2SKIP,    #0xFF		; I/O function on P2
    	mov   SFRPAGE,   #0x0F
    	mov   P1DRV,     #0x40		; high drive strength on COM (P1.6)
    	mov   SFRPAGE,   #0x00
    	mov   XBR2,      #0x40		; enable XBar and weak pull-ups
	mov	P0, 	     #0x01
	mov	P1,        #0x3C		
	mov	P2,        #0x00		; initialize port pins	
	ret

;-----------------------------------------------------------------------
Clock_Setup:
	mov	RTC0KEY, #0xA5		; unlock RTC interface
	mov	RTC0KEY, #0xF1
	mov	RTC0ADR, #(0x10 OR RTC0PIN)	
	mov	RTC0DAT, #0xE7		; self oscillate mode
	nop
	mov	RTC0ADR, #(0x10 OR RTC0XCN)	
	mov	RTC0DAT, #0x00		; disable double bias
	nop
	mov	RTC0ADR, #(0x10 OR RTC0XCF)	
	mov	RTC0DAT, #0x80		; set 4 pF load capacitor
	nop

   	mov	RTC0ADR, #(0x10 OR RTC0CN)	; enable SmaRTClock
	mov	RTC0DAT, #(RTC0EN OR RTC0TR)  

	mov 	RSTSRC,  #0x02		; disable MCD reset, enable VDD monitor
	mov	OSCICN,  #0x0F		; disable internal precision oscillator
	mov	OSCXCN,  #0			; disable external oscillator
	mov	REG0CN,  #0			; disable precision oscillator bias

	mov	CKCON,   #0x12		; set Timer2 system clock
	mov	CLKSEL,  #0x04		; select LPO with 1:1 clock divider
	orl	FLSCL,   #BYPASS		; set the one-shot bypass bit
	mov	FLWR,	   #0x01		; write dummy value
	mov	A, CLKSEL			; wait for the divider setting to be applied
	jnb	ACC.7, $-2		
	mov 	PMU0CF,  #CLEAR
	ret

;-----------------------------------------------------------------------
RTC_Setup:
	mov 	RTC0ADR, #(0x10 + CAPTURE0)	; clear RTC timer
	mov 	RTC0DAT, #0				; autoincrement address
	nop						; feature does not work!
	mov 	RTC0ADR, #(0x10 + CAPTURE1)
	mov 	RTC0DAT, #0
	nop
	mov 	RTC0ADR, #(0x10 + CAPTURE2)
	mov 	RTC0DAT, #0
	nop
	mov 	RTC0ADR, #(0x10 + CAPTURE3)
	mov 	RTC0DAT, #0
	nop
	mov	RTC0ADR, #RTC0CN		; set timer value
	mov	RTC0DAT, #(RTC0EN OR RTC0SET) 
	nop
	mov 	RTC0ADR, #(0x90 OR RTC0CN)
	nop
	nop
	nop
	mov 	A, RTC0DAT			
	anl	A, #RTC0SET			; verify that timer is set
	jnz	$-10

   	mov	RTC0ADR, #(0x10 OR RTC0CN)	; enable SmaRTClock
	mov	RTC0DAT, #(RTC0EN OR RTC0TR)  

	mov	R6, #Period_low
	mov	R7, #Period_high
ALARM_Setup:
   	mov	RTC0ADR, #(0x10 OR RTC0CN)	; disable alarm while
   	mov	RTC0DAT, #(RTC0EN AND NOT(RTC0AEN)) ; updating the regs      
   	nop
	mov 	RTC0ADR, #(0x10 OR ALARM0)	; load alarm regs       
	mov   RTC0DAT, R6
	nop
	mov 	RTC0ADR, #(0x10 OR ALARM1)
	mov	RTC0DAT, R7
	nop
	mov 	RTC0ADR, #(0x10 OR ALARM2)
	mov	RTC0DAT, #0 
	nop
	mov 	RTC0ADR, #(0x10 OR ALARM3)
	mov	RTC0DAT, #0
	nop
   	mov	RTC0ADR, #(0x10 OR RTC0CN)	; enable SmaRTClock
	mov	RTC0DAT, #(RTC0EN OR RTC0TR OR RTC0AEN OR ALRM)  
	ret

;-----------------------------------------------------------------------
ADC_Setup:
   	mov	ADC0CN, #0			; ADC0 disabled, Burst Mode disabled 
	mov 	ADC0CF, #0x11 		; SAR clock = 6.6MHz, gain = 1
   	mov	ADC0AC, #0              ; right-justify results
	ret

;-----------------------------------------------------------------------
Comparator_Setup:
	mov  	CPT0CN, #0x80		; enable comparator
	clr	A
	djnz	ACC, $			; short delay
   	anl  	CPT0CN, #0xCF		; clear comparator flags
    	mov  	CPT0MX, #0x6C		; capacitive touch sense mode, C- = P1.5
    	mov  	CPT0MD, #0x83		; power mode 3
	anl	CPT0CN, #0x7F		; disable comparator
	ret

;-----------------------------------------------------------------------
getLight:
	mov	ADC0MX, #0x00		; select P0.0 as ADC input
	mov	REF0CN, #0x18           ; enable high-speed ref
	mov	ADC0CN, #0x80		; enable ADC

	mov	A, #40			; 10 usec delay		
	dec	A				; 1 cycle
	nop					; 1 cycle
	nop					; 1 cycle
	jnz	$-3				; 2 cycles

	orl	ADC0CN, #0x10		; start conversion
	nop
	nop	
	mov	A, ADC0CN			; poll BUSY flag
	anl	A, #0x10
	jnz	$-5    	

	mov	ADC0CN, #0			; turn off ADC
	mov	REF0CN, #0			; turn off reference

	clr	C
	mov	A, ADC0L			; get conversion result
	subb	A, #Light_TH
	mov	A, ADC0H
	subb	A, #0
	ret

;-----------------------------------------------------------------------
getTempHumi:
	inc	Counter
	jnb	Counter.0, getTemp
	ajmp	getHUMI

getTemp:
	setb	P1.1				; turn sensor on
	mov	R6, #0x20			; use RTC clock to perform a
	mov	R7, #0x00			; 1 msec delay, which is needed
	acall	ALARM_Setup			; for sensor to set up
	acall	LPM   			; enter sleep mode until next alarm
	nop
	mov	R6, #Period_low		; reassign RTC clock to its regular
	mov	R7, #Period_high		; wake-up time
	acall	ALARM_Setup

	mov	ADC0MX, #0x0A		; select P1.2 as ADC input
	mov	REF0CN, #0x18           ; enable high-speed ref
	mov	ADC0CN, #0x80		; enable ADC

	mov	A, #40			; 10 usec delay		
	dec	A				; 1 cycle
	nop					; 1 cycle
	nop					; 1 cycle
	jnz	$-3				; 2 cycles

	orl	ADC0CN, #0x10		; start conversion
	nop
	nop	
	mov	A, ADC0CN			; poll BUSY flag
	anl	A, #0x10
	jnz	$-5    	

	mov	ADC0CN, #0			; turn off ADC
	mov	REF0CN, #0			; turn off reference
	clr	P1.1				; turn off sensor
	mov	R2, ADC0L			; save ADC values in registers
	mov	R3, ADC0H
		
	jnb	Status.0, average_TEMP	; init circ buffer ?
	clr	Status.0			; YES
	mov	R0, #bufTemp		; initialize buffer pointer		
	mov	bufTemp+0, R2		; fill the buffer with
	mov	bufTemp+2, R2		; temp reading (lower byte)
	mov	bufTemp+4, R2
	mov	bufTemp+6, R2
	mov	bufTemp+8, R2
	mov	bufTemp+10, R2
	mov	bufTemp+12, R2
	mov	bufTemp+14, R2
	
	mov	bufTemp+1, R3		; fill the buffer with 
	mov	bufTemp+3, R3		; temp reading (upper byte)
	mov	bufTemp+5, R3
	mov	bufTemp+7, R3
	mov	bufTemp+9, R3
	mov	bufTemp+11, R3
	mov	bufTemp+13, R3
	mov	bufTemp+15, R3	
	
	mov	A, R2
	mov	B, #8				; compose the average sum by
	mul	AB				; multilpying current temp by 8
	mov	tempAve_lo, A
	mov	tempAve_hi, B
	mov	B, #8
	mov	A, ADC0H
	mul	AB
	add	A, tempAve_hi
	mov	tempAve_hi, A
	ajmp	process_TEMP

average_TEMP:
	mov	A, tempAve_lo		; subtract the oldest temp value
	clr	C				; in circular buffer from the 
	subb	A, @R0			; average temp sum
	mov	tempAve_lo, A
	inc	R0				; advance pointer to higher-order byte
	mov	A, tempAve_hi
	subb	A, @R0
	mov	tempAve_hi, A
	
	dec	R0
	mov	@R0, ADC0L			; save new temp in circular buffer
	inc	R0				; update circ buffer pointer
	mov	@R0, ADC0H
	inc	R0
	cjne	R0, #0x40, $+5		; jump over the next instruction
	 mov	R0, #0x30			; take pointer R0 mod 16

	mov	A, tempAve_lo		; update average temp sum
	add	A, ADC0L
	mov	tempAve_lo, A
	mov	A, tempAve_hi
	addc	A, ADC0H
	mov	tempAve_hi, A		; at this point C = 0

	mov	A, tempAve_lo		; average temp sum (div. by 8)	
	rlc	A				; for that we multiply it by 2 
	swap	A				; and swap the nibbles
	anl	A, #0x0F
	mov	R2, A				; R2 contains the lower nibble
	mov	A, tempAve_hi
	rlc	A				; C is not modified since the
	swap	A				; last add
	mov	B, A
	anl	A, #0xF0
	add	A, R2
	mov	R2, A
	mov	A, B				
	anl	A, #0x0F
	mov	R3, A

process_TEMP:
	mov	B, #165			; multiply ADC by 165 (2 bytes x 1 byte)
	mov	A, R2
	mul	AB
	mov	R2, B
	mov	B, #165
	mov	A, R3
	mul	AB
	add	A, R2				; A = lower byte, B = higher byte
	mov	R2, A
      mov  	A, B
      addc	A,  #0
	mov	R3, A				; R3:R2 = ADC_temp * 165 / 256

	mov	A, R2				; subtract 50*4-2 = 198 and round off
	add	A, #0x3A			; 198 = 0xFF3A
	mov	R2, A
	mov	temp_lo, A
	mov	A, R3
	addc	A, #0xFF
	mov	R3, A				; R3:R2 = ADC_temp * 165 / 256 - 200
	mov	temp_hi, A

	mov	C, ACC.7			; divide R3:R2 by 4 (signed) 
	rrc	A
	mov	R3, A
	mov	A, R2
	rrc	A
	mov	R2, A
	mov	A, R3
	mov	C, ACC.7
	rrc	A
	mov	R3, A
	mov	A, R2
	rrc	A				
	mov	R2, A				; R3:R2 = ADC_temp * 165 / 1024 - 50

	mov	A, R3				; check computed data range	
	jnb	ACC.7, $+6			; if R3:R2 < 0, set R2=0
	clr	A
	sjmp	display_TEMP		

	clr	C				; if R3:R2 > 99, set R2=99 
	mov	A, R2
	subb	A, #100
	mov	A, R3
	subb	A, #0
	jc	display_TEMP
	mov	R2, #99					
	
display_TEMP:				; display value in R2
	mov	A, R2
	setb	P1.0				; display the degree symbol
	ajmp	display_Number

;-----------------------------------------------------------------------
getHumi:
	mov  	CPT0CN, #0x80		; enable comparator
	mov	A, #10			; 2 usec delay		
	djnz	ACC, $			; 4 cycles

	anl	FLSCL,  #NOT(BYPASS)	; enable flash one-shot bypass mode
	mov	FLWR,	  #0x01		; write dummy value
	mov	TMR2CN, #0x16		; enable capture of comparator events
	mov	IE,	  #0xA0		; enable Timer2 interrupt
	mov	PCON,   #0x01		; enter idle mode
	mov	humi_lo, TMR2RLL		; get first comparator capture
	mov	humi_hi, TMR2RLH
	mov	PCON,	  #0x01		; wait for the comparator period end
	mov	IE,	  #0x00		; disable interrupts
 	orl	FLSCL,  #BYPASS		; disable flash one-shot bypass mode
	mov	FLWR,	  #0x01		; write dummy value	
	mov	TMR2CN, #0x00		; disable Timer2
	anl	CPT0CN, #0x7F		; disable comparator	 

	clr	C
	mov	A, TMR2RLL			; compute the time stamp difference
	subb	A, humi_lo			; and take its absolute value
	mov	R2, A
	mov	A, TMR2RLH
	subb	A, humi_hi
	mov	R3, A
	jnb	ACC.7, abs
	setb 	C				; compute the absolute value
	mov	A, R2
	addc	A, #0xFF
	mov	R2, A
	mov	A, R3
	addc	A, #0xFF
	mov	R3, A

abs:	
	jnb	Status.1, average_HUMI	; init circ buffer ?
	clr	Status.1			; YES
	mov	R1, #bufHumi		; initialize buffer pointer
	mov	bufHumi, R2			; fill the buffer with the
	mov	bufHumi+2, R2		; humi reading (lower byte)
	mov	bufHumi+4, R2
	mov	bufHumi+6, R2
	mov	bufHumi+8, R2
	mov	bufHumi+10, R2
	mov	bufHumi+12, R2
	mov	bufHumi+14, R2

	mov	bufHumi+1, R3		; fill the buffer with the
	mov	bufHumi+3, R3		; humi reading (higher byte)
	mov	bufHumi+5, R3
	mov	bufHumi+7, R3
	mov	bufHumi+9, R3
	mov	bufHumi+11, R3
	mov	bufHumi+13, R3
	mov	bufHumi+15, R3

	mov	A, R2
	mov	B, #8				; compute the average sum by
	mul	AB				; multilpying R3:R2 by 8
	mov	humiAve_lo, A		; value in R3:R2 remains unchanged
	mov	humiAve_hi, B
	mov	B, #8
	mov	A, R3
	mul	AB
	add	A, humiAve_hi
	mov	humiAve_hi, A
	ajmp	process_HUMI

average_HUMI:
	mov	A, humiAve_lo		; subtract the oldest humi value
	clr	C				; in circular buffer from the 
	subb	A, @R1			; average humi sum
	mov	humiAve_lo, A
	inc	R1				; advance pointer to the higher-order byte
	mov	A, humiAve_hi
	subb	A, @R1
	mov	humiAve_hi, A
	
	dec	R1
	mov	@R1, 2			; save new humi in circular buffer
	inc	R1				; update circ buffer pointer
	mov	@R1, 3			; 2 is direct acces to R2 address, 3 is for R3
	inc	R1
	cjne	R1, #0x60, $+5		; jump over the next instruction
	 mov	R1, #0x50			; take pointer R0 mod 16

	mov	A, humiAve_lo		; update average temp sum
	add	A, R2
	mov	humiAve_lo, A
	mov	A, humiAve_hi
	addc	A, R3
	mov	humiAve_hi, A		; at this point C = 0

	mov	A, humiAve_lo		; average humi sum (div. by 8)	
	rlc	A				; for that we multiply it by 2 
	swap	A				; and swap the nibbles
	anl	A, #0x0F
	mov	R2, A				; R2 contains the lower nibble
	mov	A, humiAve_hi
	rlc	A				; C is not modified since the
	swap	A				; last add
	mov	B, A
	anl	A, #0xF0
	orl	A, R2
	mov	R2, A
	mov	A, B				
	anl	A, #0x0F
	mov	ACC.4, C
	mov	R3, A				; R3:R2 is averaged oscillator period N

process_HUMI:
;	ajmp	calibrate_HUMI		; uncomment this libe for calibration
	clr	C
	mov	A, R2				; subtract N_NOM (16-bit operation)
	subb	A, #LOW(N_NOM)
	mov	R2, A
	mov	A, R3
	subb	A, #HIGH(N_NOM)
	mov	R3, A

	mov	A, R2				; compute (N - N_NOM)*65
	mov	B, #65			; result is at most 16 bits	
	mul	AB
	mov	R2, B
	mov	A, R3
	mov	B, #65
	mul	AB
	add	A, R2				
	mov	R2, A
	mov	A, B				; A:R2 = humi*65 unsigned
	mov	AUX, R3
	jnb 	AUX.7, $+5			; examine the sign bit
	add	A, #-65			; A:R2 = humi*32 signed
	mov	R3, A				; R3:R2 (N - N_NOM) * 65/ 256

	clr	C
	mov	A, temp_lo			; thermo compensation
	subb	A, #LOW(T_0)
	mov	temp_lo, A
	mov	A, temp_hi
	subb	A, #HIGH(T_0)
	mov	AUX, A			; AUX:temp_lo = (T - T_NOM)*4

	mov	A, temp_lo			; compute temp*34 = (T - T_NOM)*136
	mov	B, #34			; result is at most 16 bits	
	mul	AB
	mov	temp_lo, B
	mov	A, AUX
	mov	B, #34
	mul	AB
	add	A, temp_lo			
	mov	temp_lo, A
	mov	A, B				
	jnb 	AUX.7, $+5			; examine the sign bit
	add	A, #-34	
	mov	temp_hi, A			; temp = (T - T_NOM)*136 / 256 signed

	setb	C
	mov	A, temp_lo			; add temperature correction
	addc	A, R2				; to the humidity value
	mov	R2, A				; and rounding off 1
	mov	A, temp_hi
	addc	A, R3
	mov	R3, A	

	mov	C, ACC.7			; get the sign bit
	rrc	A				; divide by 2 (16-bit operation)
	mov	R3, A
	mov	A, R2
	rrc	A
	add	A, #HUMI_NOM		; A = RH in %
	mov	R2, A
	mov	A, R3
	addc	A, #0
	mov	R3, A				; R3:R2 = RH in %

	clr	P1.0				; clear the degree symbol

	mov	A, R3				; check computed data range	
	jnb	ACC.7, $+6			; if R3:R2 < 0, set R2=0
	clr	A
	sjmp	display_Number		

	clr	C				; if R3:R2 > 99, set R2=99 
	mov	A, R2
	subb	A, #100
	mov	A, R3
	subb	A, #0
	mov	A, R2	
	jc	display_Number
	mov	A, #99	

display_Number:				; display number in ACC
	mov	B, #10			
	div	AB				; A=1st digit, B=2nd digit

dn2:
	add	A, ACC			; A *= 2
	mov	R4, A				; A = R4 = table offset of the 1st digit

	mov	DPTR, #table7seg1		; initialize 7-seg table pointer
	movc	A, @A+DPTR			; get code of dig1
	orl	A, #0x01			; preserve analog input pin status
	mov	P0, A
	
	inc	R4				; update table offset
	mov	A, R4
	movc	A, @A+DPTR			; get table value
	mov	P2, A				; send it to the LCD

	mov	A, B				; load 2nd digit to ACC
	add	A, ACC			; A *= 2
	add	A, B				; A *= 3
	mov	R4, A				; A = R4 = table offset of the 2nd digit

	mov	DPTR, #table7seg2		; initialize 7-seg table pointer
	movc	A, @A+DPTR			; get code of dig2
	orl	P0, A				; send it to the LCD	

	inc	R4				; update table pointer
	mov	A, R4
	movc	A, @A+DPTR			; get table value
	mov	C, ACC.7
	mov	P1.7, C			; send it to the LCD

	inc	R4
	mov	A, R4
	movc	A, @A+DPTR			; get table value
	orl	P2, A				; send it to the LCD
	ret

;-----------------------------------------------------------------------
calibrate_HUMI:				; calibration: display HEX value
	mov	A, R2				; of the oscillator period
	jb	DB_counter.0, cal2	
	mov	A, R3				; display high-order byte
	dec	Counter

cal2:
	inc	DB_counter
	mov	B, A
	swap	A
	anl	A, #0x0F
	anl	B, #0x0F
	clr	P1.0				; erase the degree symbol
	ajmp	dn2

;-----------------------------------------------------------------------
LPM:  
	mov	PMU0CF, #(SLEEP OR RSTWK OR RTCAWK) ; wakeup sources
	nop   				; device is now awake
   	nop
	nop
	nop

	mov	PMU0CF_Snapshot, PMU0CF	; capture the wake-up source
   	mov 	PMU0CF, #CLEAR		; clear all wake-up source flags

	mov	RTC0ADR, #(0x90 OR RTC0CN); capture RTC events that occured
	nop					; while PMU0CF was being cleared
	nop
	nop	
	mov	A, RTC0DAT			; RTC0CN_snapshot	
	anl	A, #ALRM
	orl	A, PMU0CF_Snapshot	; add it to the old flags
	mov	PMU0CF_Snapshot, A
   
	mov	A, PMU0CF_Snapshot	; reset pin Wakeup ?
	anl	A, #RSTWK
	jnz	debug_delay1		
	ret					; NO - exit

debug_delay1:
	mov	A, #0x5			; YES - make a 20 usec delay		
	dec	A				; 1 cycle
	nop					; 1 cycle
	jnz	$-2				; 2 cycles    
	ret      

;========================================================================
table7seg1: ; P0    P2			; 7-seg LCD table for the first digit
;	DB	0x0E, 0x70			; codes for 0
	DB	0x00, 0x00			; do not show the leading 0
	DB	0x08, 0x10			; codes for 1
	DB	0x0C, 0x68			; codes for 2
	DB	0x0C, 0x38			; codes for 3
	DB	0x0A, 0x18			; codes for 4
	DB	0x06, 0x38			; codes for 5
	DB	0x06, 0x78			; codes for 6
	DB	0x0C, 0x10			; codes for 7
	DB	0x0E, 0x78			; codes for 8
	DB	0x0E, 0x38			; codes for 9
	DB	0x0E, 0x58			; codes for A
	DB	0x02, 0x78			; codes for b
	DB	0x06, 0x60			; codes for C
	DB	0x08, 0x78			; codes for d
	DB	0x06, 0x68			; codes for E
	DB	0x06, 0x48			; codes for F

table7seg2: ; P0	  P1    P2		; 7-seg LCD table for the second digit
	DB	0xE0, 0x00, 0x07		; codes for 0
	DB	0x80, 0x00, 0x01		; codes for 1
	DB	0xC0, 0x80, 0x06		; codes for 2
	DB	0xC0, 0x80, 0x03		; codes for 3
	DB	0xA0, 0x80, 0x01		; codes for 4
	DB	0x60, 0x80, 0x03		; codes for 5
	DB	0x60, 0x80, 0x07		; codes for 6
	DB	0xC0, 0x00, 0x01		; codes for 7
	DB	0xE0, 0x80, 0x07		; codes for 8
	DB	0xE0, 0x80, 0x03		; codes for 9	
	DB	0xE0, 0x80, 0x05		; codes for A
	DB	0x20, 0x80, 0x07		; codes for b
	DB	0x60, 0x00, 0x06		; codes for C
	DB	0x80, 0x80, 0x07		; codes for d
	DB	0x60, 0x80, 0x06		; codes for E
	DB	0x60, 0x80, 0x04		; codes for F

END