
	include <p12F629.inc>

	__CONFIG	_CP_OFF & _CPD_OFF & _BODEN_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _PWRTE_ON

TxD				equ	0x04			;Transmitter pin position
TxD_Direction	equ	B'00101111'	;GPIO direction
BitDuration		equ	.52			;Bit duration x2 ms (not more than 128)

;********************************
;*			RAM  ZONE			     *
;********************************

	ORG	0x20	;FREE_RAM

Old_H			res	.1	;RS232 bit transmission delay
Old_L			res	.1	;RS232 bit transmission delay
New_H			res	.1	;RS232 bit transmission delay
New_L			res	.1	;RS232 bit transmission delay
HIGH_0_CNT  res	.1	;Low level (logical 0) of the signal - High Byte
LOW_0_CNT  	res	.1	;Low level (logical 0) of the signal - Low Byte
HIGH_1_CNT  res	.1	;High level (logical 1) of the signal - High Byte
LOW_1_CNT  	res	.1	;High level (logical 1) of the signal - Low Byte
OLD	  		res	.1	;Old TMR0 value - used in the Masurement routine
NEW	  		res	.1	;New TMR0 value - used in the Masurement routine
LOOP_C	  	res	.1	;Repetitions of the non-calculated measurements counter 

Counter		res	.1	;Send a character via RS232 routine
							;8 bit Binary to BCD conversion routine
RS232_OUT	res	.1	;Send a character via RS232 routine

BIN_IN		res	.2	;8 bit Binary to BCD conversion routine
BCD_OUT		res	.3	;8 bit Binary to BCD conversion routine

INTEGRATION_C	res	.1	;Repetitions of the calculated measurements counter 
Temperature	res	.3	;Calculated measurements integration accumulator
temp			res	.1	;Help sell for different routines
MASK			res	.1	;Present sensors mask
Pointer		res	.1	;Sensor measurement sequence pointer
CheckPoint	res	.1	;Sensor find sequence pointer
RS232Delay	res	.1	;RS232 bit transmission delay
INT_CNT		res	.1	;Interrupts counter


;Calculation routine working sels
;       binary operation arguments
;
AARGB3	res	.1			; A argument LSByte
AARGB2	res	.1			;
AARGB1 	res	.1			;
AARGB0	res	.1			; A argument MSByte
AARG		equ  AARGB0		; most significant byte of argument A
AEXP		res	.1			; 8 bit biased exponent for argument A
EXP		equ	AEXP		; 8 bit biased exponent
;
SIGN		res	.1			; save location for sign in MSB
FPFLAGS	res	.1			; floating point library exception flags
;
BARGB1	res	.1			; B argument LSByte
BARGB0	res	.1			; B argument MSByte
BARG		equ 	BARGB0	; most significant byte of argument B
BEXP		res	.1			; 8 bit biased exponent for argument B
;
TEMPB1	res	.1			;
TEMPB0	res	.1			;
TEMP		equ	TEMPB0	; temporary storage

Float1	res	.3			; Floating point temporary sell

MSB		equ	7
LSB		equ	0

;Carry/Borrow and Zero bit definitions

        #define CARRY	STATUS,C
        #define ZERO		STATUS,Z

;*******************************************
; PROGRAM ZONE                             *
;*******************************************
	org	0x00		;Reset vector
;Calibrate Osc
	call	0x3FF
	bsf	STATUS,RP0
	movwf	OSCCAL
;	goto	EndOfProgramm
;EndOfProgramm
	goto	Begin

	org	0x04		;Interrupt vector
;*******************************************
; Interrupt on change GPIO service routine *
;*******************************************
	movf		TMR1L,W
	movwf		New_L
	movf		TMR1H,W
	movwf		New_H

	movf		New_L,W
	subwf		TMR1L,W
	btfsc		CARRY
	goto		lab1
	decf		TMR1H,W
	movwf		New_H
lab1
	rlf	INT_CNT,f
	movf	GPIO,w
	movlw	0x08					; Clear interrupt flag
	movwf	INTCON

	retfie

;*********************************************************
;*	Send a character in W (RS232_OUT) via ASIA routine		*
;*********************************************************

SendChar
	movwf	RS232_OUT


	movlw	.11		;Initialize Bit Counter
	movwf	Counter
	bcf	CARRY		;Start bit
	clrwdt
NextBit
	btfss	CARRY
	bcf	GPIO,TxD	
	btfsc	CARRY
	bsf	GPIO,TxD
	movf	RS232Delay,w
	movwf	TMR0

	bsf	CARRY		;Prepare Stop bit	
	rrf	RS232_OUT,f

Wt_del	btfss	TMR0,0x07
	goto	Wt_del

	decfsz	Counter,f
	goto	NextBit	

	bsf	GPIO,TxD	;Stop bit

	retlw	0



;********************************************************************
; Binary To BCD Conversion Routine
; This routine converts a 16 Bit binary Number to a 4 Digit
; BCD Number. 
;
; The 16 bit binary number is input in locations BIN_IN and
; BIN_IN+1 with the high byte in BIN_IN.
; The 4 digit BCD number is returned in BCD_OUT,BCD_OUT+1 with BCD_OUT
; containing the MSD in its left most nibble.
;
;*******************************************************************;

BIN_BCD 
	bcf CARRY	
        movlw .16
        movwf Counter

        clrf BCD_OUT
        clrf BCD_OUT+1
        clrf BCD_OUT+2
   
loop16	rlf BIN_IN+1,f
        rlf BIN_IN,f

        rlf BCD_OUT+2,f
        rlf BCD_OUT+1,f
        rlf BCD_OUT,f

        decfsz Counter,f
        goto adjDEC

	retlw	0

adjDEC  
	movlw	BCD_OUT+2
	movwf FSR
	call adjBCD

	movlw	BCD_OUT+1
	movwf FSR
	call adjBCD

	movlw	BCD_OUT
	movwf FSR
	call adjBCD

	goto loop16

adjBCD  movlw 3
        addwf 0,W
        movwf temp
        btfsc temp,3 ; test if result > 7
        movwf 0
        movlw 30
        addwf 0,W
        movwf temp
        btfsc temp,7 ; test if result > 7
        movwf 0 ; save as MSD
        RETLW 0


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sensor measurements - wait for 0,wait for 1, set Interrupt on change
; The routines are repeared for every input ( 4 times)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SENSOR0
;wait for 0 in order to begin
init_00	
	btfsc GPIO,GP0	;Wait for 0
	goto  init_00
;wait for 1 in order to begin
init_01	
	btfss GPIO,GP0	;Wait for 1
   goto  init_01
	retlw	0x01					; Interrupt on change GP0

SENSOR1
;wait for 0 in order to begin
init_10	
	btfsc GPIO,GP1	;Wait for 0
	goto  init_10
;wait for 1 in order to begin
init_11	
	btfss GPIO,GP1	;Wait for 1
   goto  init_11
	retlw	0x02					; Interrupt on change GP0

SENSOR2
;wait for 0 in order to begin
init_20	
	btfsc GPIO,GP2	;Wait for 0
	goto  init_20
;wait for 1 in order to begin
init_21	
	btfss GPIO,GP2	;Wait for 1
   goto  init_21
	retlw	0x04					; Interrupt on change GP0

SENSOR3
;wait for 0 in order to begin
init_30	
	btfsc GPIO,GP5	;Wait for 0
	goto  init_30
;wait for 1 in order to begin
init_31	
	btfss GPIO,GP5	;Wait for 1
   goto  init_31
	retlw	0x08					; Interrupt on change GP0

;***************************
;*	Send LF, CR routine		*
;***************************
SEND_LF_CR
	movlw	0x0D
	call	SendChar
	movlw	0x0A
	call	SendChar
 	retlw	b'1000'
;******************************
;*	Floating point routine		*
;******************************
	include <FP24.asm>

;******************************
;*	Send U (0x55) routine		*
;******************************
CheckRS232

	movlw	0x55
	call	SendChar
	goto	CheckRS232


;***************************
;*	System configuration		*
;***************************
Begin

	bcf	STATUS,RP0
	movlw	.136-BitDuration
	movwf	RS232Delay

	bsf	GPIO,TxD			;Unactive RS232 transmiter

	movlw	TxD_Direction
	tris	GPIO

	MOVLW  b'00000111'
	movwf	CMCON
	bsf	STATUS,RP0
	MOVLW  b'00000000'	;Internal Pull-ups enabled, Prescaler attached to TMR0, 
								;Internal clock / 2 for TMR0
	movwf	OPTION_REG
	bcf	STATUS,RP0

	movlw  b'00000001'
	movwf	T1CON				; T1 - on; prescaler 1:1; Fosc/4

;************************************************************
;*	Find the position of the sensors connected in the moment	*
;************************************************************
;If RESET preload mask value and wait WDT reset (initial delay)
	btfsc	STATUS,NOT_TO
	goto	FirstPower

	CLRWDT

;WDT time-out occur
	btfsc	CheckPoint,GP0
	goto	CheckGP0

	btfsc	CheckPoint,GP1
	goto	CheckGP1

	btfsc	CheckPoint,GP2
	goto	CheckGP2

	btfsc	CheckPoint,GP3
	goto	CheckGP3

	movf	MASK,f
	btfsc	ZERO
	goto	CheckRS232

	goto	CheckEnd

FirstPower
	clrwdt
	bsf	STATUS,RP0
	movlw	0x37				; Pull-ups on
	movwf	WPU
	bcf	STATUS,RP0
	clrf	MASK
	movlw	b'0001'
	movwf	CheckPoint
wt_wdt	goto	wt_wdt		;Initial delay

CheckGP0
	bsf	STATUS,RP0
	bsf	WPU,GP0			; Pull-up on
	bcf	STATUS,RP0
	bcf	MASK,GP0
	movlw	b'0010'
	movwf	CheckPoint
	btfsc	GPIO,GP0
	goto	CheckGP0
;There is a sensor on GP0
	bsf	MASK,GP0
	bsf	STATUS,RP0
	bcf	WPU,GP0			; Pull-up off
	bcf	STATUS,RP0
CheckGP1
	bsf	STATUS,RP0
	bsf	WPU,GP1			; Pull-up on
	bcf	STATUS,RP0
	bcf	MASK,GP1
	movlw	b'0100'
	movwf	CheckPoint
	btfsc	GPIO,GP1
	goto	CheckGP1
;There is a sensor on GP1
	bsf	MASK,GP1
	bsf	STATUS,RP0
	bcf	WPU,GP1			; Pull-up off
	bcf	STATUS,RP0
CheckGP2
	bsf	STATUS,RP0
	bsf	WPU,GP2			; Pull-up on
	bcf	STATUS,RP0
	bcf	MASK,GP2
	movlw	b'1000'
	movwf	CheckPoint
	btfsc	GPIO,GP2
	goto	CheckGP2
;There is a sensor on GP2
	bsf	MASK,GP2
	bsf	STATUS,RP0
	bcf	WPU,GP2			; Pull-up off
	bcf	STATUS,RP0
CheckGP3
	bsf	STATUS,RP0
	bsf	WPU,GP5			; Pull-up on
	bcf	STATUS,RP0
	bcf	MASK,GP3
	movlw	b'10000'
	movwf	CheckPoint
	btfsc	GPIO,GP5
	goto	CheckGP3
;There is a sensor on GP3
	bsf	MASK,GP3
	bsf	STATUS,RP0
	bcf	WPU,GP5			; Pull-up off
	bcf	STATUS,RP0

CheckEnd
	CLRWDT
	movlw	b'0001'
	movwf	CheckPoint
	clrf	Pointer

;******************************************************
;*	Sensors connected in the moment measurement cycle	*
;******************************************************
new_sensor_M
	bcf	CARRY
	rrf	Pointer,w
	andlw	0x0F				;Test Z bit
	btfsc	ZERO	
	call	SEND_LF_CR		;movlw	b'10000'
	movwf	Pointer
	andwf	MASK,w
	btfsc	ZERO
	goto	new_sensor_M
Sensor_YES
	movlw	.64
	movwf	INTEGRATION_C
	clrf	Temperature
	clrf	Temperature+1
	clrf	Temperature+2

;******************************************************
;*	Raw measurement of the Low and High level pulses	*
;******************************************************
new_64_M
	clrf	LOW_0_CNT
	clrf	HIGH_0_CNT
	clrf	LOW_1_CNT
	clrf	HIGH_1_CNT

;   	LOOP_C=42;
	movlw	.20 ;.42
	movwf	LOOP_C

	movlw	0x01
	movwf	INT_CNT

	btfsc	Pointer,GP0
	call	SENSOR0
	btfsc	Pointer,GP1
	call	SENSOR1
	btfsc	Pointer,GP2
	call	SENSOR2
	btfsc	Pointer,GP3
	call	SENSOR3

	clrf	TMR1L
	clrf	TMR1H
	bsf	STATUS,RP0			; Page 1
	movwf	IOC					; Interrupt on change GP0-3 (W loaded by retlw)
	movlw	0x88					; Interrupt on change enable
	movwf	INTCON
	bcf	STATUS,RP0			; Page 0

SENSOR_A	
	btfss	INT_CNT,1
	goto  SENSOR_A

	movlw	0x01
	movwf	INT_CNT
;	OLD=NEW;
	movf	New_L,W
	movwf	Old_L
	movf	New_H,W
	movwf	Old_H

new_check
SENSOR_B
	btfss		INT_CNT,1
   goto     SENSOR_B

	movlw	0x01
	movwf	INT_CNT
;	OLD=NEW-OLD;
	movf	Old_L,W
	subwf	New_L,W
	btfss	CARRY
	decf	HIGH_0_CNT,f
;	Low Level=Low Level+OLD;
	addwf	LOW_0_CNT,f
	btfsc	CARRY
	incf	HIGH_0_CNT,f
;	OLD=NEW-OLD;
	movf	Old_H,W
	subwf	New_H,W
;	Low Level=Low Level+OLD;
	addwf	HIGH_0_CNT,f
;	OLD=NEW;
	movf	New_L,W
	movwf	Old_L
	movf	New_H,W
	movwf	Old_H

SENSOR_C
	btfss		INT_CNT,1
	goto     SENSOR_C

	movlw	0x01
	movwf	INT_CNT

;	OLD=NEW-OLD;
	movf	Old_L,W
	subwf	New_L,W
	btfss	CARRY
	decf	HIGH_1_CNT,f
;	High Level=High Level+OLD;
	addwf	LOW_1_CNT,f
	btfsc	CARRY
	incf	HIGH_1_CNT,f
;	OLD=NEW-OLD;
	movf	Old_H,W
	subwf	New_H,W
;	High Level=High Level+OLD;
	addwf	HIGH_1_CNT,f
;	OLD=NEW;
	movf	New_L,W
	movwf	Old_L
	movf	New_H,W
	movwf	Old_H

	CLRWDT
	decfsz	LOOP_C,f
	goto		new_check

	movlw	0x00					; Interrupt on change disable
	movwf	INTCON
; Calculate temperature * 100 : {(Pulse * 21276.59574 ) / Period } 
;T=Low Level+High Level
	movf	LOW_1_CNT,w
	addwf	LOW_0_CNT,w
	movwf	AARGB1
	btfsc	CARRY
	incf	HIGH_0_CNT,f
	movf	HIGH_1_CNT,w
	addwf	HIGH_0_CNT,w
	movwf		AARGB0
;       Integer to float conversion
;       Input:  16 bit 2's complement integer right justified in AARGB0, AARGB1
;       Use:    CALL    FLO1624 or      CALL    FLO24
;       Output: 24 bit floating point number in AEXP, AARGB0, AARGB1
	CALL    FLO1624
	movf		AEXP,w
	movwf		Float1+0
	movf		AARGB0,w
	movwf		Float1+1
	movf		AARGB1,w
	movwf		Float1+2

;High Level 
	clrf	AARGB2
	clrf	AARGB3
	movf		HIGH_1_CNT,w
	movwf		AARGB0
	movf		LOW_1_CNT,w
	movwf		AARGB1
;       Integer to float conversion
;       Input:  16 bit 2's complement integer right justified in AARGB0, AARGB1
;       Use:    CALL    FLO1624 or      CALL    FLO24
;       Output: 24 bit floating point number in AEXP, AARGB0, AARGB1
	CALL    FLO1624

	movlw		0x8D
	movwf		BEXP
	movlw		0x26
	movwf		BARGB0
	movlw		0x39
	movwf		BARGB1

;       Floating Point Multiply
;       Input:  24 bit floating point number in AEXP, AARGB0, AARGB1
;               24 bit floating point number in BEXP, BARGB0, BARGB1
;       Use:    CALL    FPM24
;       Output: 24 bit floating point product in AEXP, AARGB0, AARGB1
	CALL    FPM24

	movf		Float1+0,W
	movwf		BEXP
	movf		Float1+1,W
	movwf		BARGB0
	movf		Float1+2,W
	movwf		BARGB1
;       Floating Point Divide
;       Input:  24 bit floating point dividend in AEXP, AARGB0, AARGB1
;               24 bit floating point divisor in BEXP, BARGB0, BARGB1
;       Use:    CALL    FPD24
;       Output: 24 bit floating point quotient in AEXP, AARGB0, AARGB1
	CALL    FPD24
;       Float to integer conversion
;       Input:  24 bit floating point number in AEXP, AARGB0, AARGB1
;       Use:    CALL    INT2416         or      CALL    INT24
;       Output: 16 bit 2's complement integer right justified in AARGB0, AARGB1
   CALL    INT2416

; Substract 6808
	movlw		LOW .6808 	;0x98
	subwf		AARGB1,f
;	movwf		OutT_L
	btfss		CARRY
	decf		AARGB0,f	
	movlw		HIGH .6808	;0x1A
	subwf		AARGB0,f
;	movwf		OutT_H

;Temperature=Temperature + New
	movf	AARGB1,w
	addwf	Temperature+1,f
	btfss	CARRY
	goto	_NoCarry
	movlw	1
	addwf	Temperature,f
	btfsc	CARRY
	incf	Temperature+2,f
_NoCarry
	movf	AARGB0,w
	addwf	Temperature,f
	btfsc	CARRY
	incf	Temperature+2,f
	btfss AARGB0,7					;test for negative
	goto	Pos_temp
	movlw	0xFF						;sign extention
	addwf	Temperature+2,f
Pos_temp

	decfsz	INTEGRATION_C,f
	goto	new_64_M


;Temperature=Temperature/32
	rrf	Temperature+2,f
	rrf	Temperature,f
	rrf	Temperature+1,f
	rrf	Temperature+2,f
	rrf	Temperature,f
	rrf	Temperature+1,f
	rrf	Temperature+2,f
	rrf	Temperature,f
	rrf	Temperature+1,f
	rrf	Temperature+2,f
	rrf	Temperature,f
	rrf	Temperature+1,f
	rrf	Temperature+2,f
	rrf	Temperature,f
	rrf	Temperature+1,f
	rrf	Temperature+2,f
	rrf	Temperature,f
	rrf	Temperature+1,f

;If positive, the first 5 bits should be 0; If negative, the first 5 bits should be 1 (sign bit extention). 

	btfss	Temperature,7
	goto	Pos_Result

Neg_Result

	comf	Temperature,f		;Covert the negatiive value from complementary code
	comf	Temperature+1,f
	incfsz	Temperature+1,f
	goto	Correction
	incf	Temperature,f
Correction

	movlw	'-'		;Write "-" on the display
	call	SendChar

Pos_Result

	movf	Temperature,w
	movwf	BIN_IN
	movf	Temperature+1,w
	movwf	BIN_IN+1

	call	BIN_BCD

	movf	BCD_OUT+0,w
	andlw	0x0F		;Mask
	btfsc	ZERO		;Check for leading 0
	goto	LEAD_01
	addlw	0x30		;Convert in ASCII
	call	SendChar

	swapf	BCD_OUT+1,W	;Load
	andlw	0x0F			;Mask
	addlw 0x30		;Convert in ASCII
	call	SendChar
	goto	LEAD_02
LEAD_01

	swapf	BCD_OUT+1,W	;Load
	andlw	0x0F			;Mask
	btfsc	ZERO			;Check for leading 0
	goto	LEAD_02
	addlw 0x30			;Convert in ASCII
	call	SendChar
LEAD_02
	movf	BCD_OUT+1,W	;Load
	andlw	0x0F			;Mask
	addlw 0x30		;Convert in ASCII
	call	SendChar

	movlw	'.'
	call	SendChar

	swapf	BCD_OUT+2,W	;Load
	andlw	0x0F			;Mask
	addlw 0x30		;Convert in ASCII
	call	SendChar

	movf	BCD_OUT+2,W	;Load
	andlw	0x0F			;Mask
	addlw 0x30		;Convert in ASCII
	call	SendChar

	movlw	' '
	call	SendChar
	goto	new_sensor_M

	End 

