;======================= Subrutina sensor sht11 ======================================
;
;--------------------- LECTURA HUMEDAR -----------------------------------------------
sht11_Humedad	movlw	b'00000101'
		call	SHT11_CMD	;Envio: Lectura de humedad
		call	waitACK		;espera que llegue ACK desde el sensor
		call	adqtime		;espera que pase el tiempo de adquisicion
		call	read
		call	CalcRH		;Calcula %RH y ajusta linealidad
					;retorna variable RH COMO dato		
		return

;--------------------- LECTURA temperatura ------------------------------------------
sht11_Tempera				;	LECTURA TEMPERATURA 2 bytes
		movlw	b'00000111'
		call	SHT11_CMD	;	Envio: Lectura de Temperatura
		call	waitACK		;	espera que llegue ACK desde el sensor
		call	adqtime		;	espera que pase el tiempo de adquisicion
		call	read

		call	CalcRH		;	Calcula %RH y ajusta linealidad, vuelve con el valor en RH

		return	

	
;------------------- SUBRUTINAS DE CONFIGURACION DEL SHT11 ---------------------------		
sht11_Set8bits				;configura el sensor para trabajar en modo 8 bits
		movlw	b'00000110'	
		call	SHT11_CMD	;	Envio: Escritura de registro interno
		call	waitACK		;	espera que llegue ACK desde el sensor
		bcf	status,5
		movlw	b'00000001'	;	pone un 1 en el bit 0 de status... (12 bit RH, 14 bit °T)
		call	SHT11_CMD	;	Envio: modificacion de status
		call	waitACK		;	espera que llegue ACK desde el sensor					
		return
		
sht11_Reset	;Resetea el sensor sht11
		movlw	b'00011101'
		call	SHT11_CMD	;Envio: Lectura en config interna
		call	waitACK		;espera que llegue ACK desde el sensor
		call	RETA1700	;espera de 11mS al menos despues de esta instruccion
		return


;///////////////////////////////////////////////////////////////////////////
;--------------------- Manda comando AL SHT11 ------------------------------
SHT11_CMD	movwf	CMData		;guarda el comando en variable
	
		bsf	STATUS,5	;banco 1 
		bcf	TRISA,2		;puertos como salida
		bcf	TRISA,1

		bcf	STATUS,5	;banco 0 
		bSf	PORTA,1		;DATA a 1 (por defecto)
		bCf	PORTA,2		;CLK

		nop			;espera un poco
		nop
		nop
		nop
		nop

		bsf	PORTA,2		;CLK
		bcf	PORTA,1		;DATA	(pulso bajo)
		bcf	PORTA,2		;CLK
		nop
		bsf	PORTA,2		;CLK
		bsf	PORTA,1		;DATA (por defecto alto)
		bcf	PORTA,2		;CLK

		clrf	sincbit
		bcf	STATUS,C	;borra carry
		bsf	STATUS,5	;banco 1
		bcf	TRISA,1		;pone DATA port,0 como salida
		bcf	STATUS,5	;banco 0

		movlw 	0x00
		MOVWF	sincbit

		
cont_send	rlf	CMData,F	;rota a la izquierda, bit alto en carry

					;envio de datos segun el protocolo del sht11
send_data	btfsc	CMData,7	;comprueba si es 1 o 0
		goto	uno		;

cero		bcf	PORTA,2		;SCK  falling edge -_
		bcf	PORTA,1		;DATA change
		bsf	PORTA,2		;SCK  rising edge  _-
		goto	sht11_compTX	;salta

uno		bcf	PORTA,2		;SCK  falling edge -_
		bsf	PORTA,1		;DATA change
		bsf	PORTA,2		;SCK  rising edge  _-

;Comprobacion para 8 rotaciones, una por bit del comando.
sht11_compTX    movlw 	0x08		;comprobacion 8 bits
                subwf   sincbit,W       ;Compara 
                btfsc   STATUS,Z        ;Es el ultimo?             
                return			;Si,
                incf    sincbit,f       ;Incrementa numero de sincbit
                goto    cont_send	;Vuelve a escribir


;///////////////////////////////////////////////////////////////////////////
;---------------- Espera la llegada de ACK desde el sensor -----------------
waitACK		bsf	STATUS,5	;banco 1
		bsf	TRISA,1		;pone DATA port,0 como entrada
		bcf	STATUS,5	;banco 0	
		nop
		nop
		nop
		nop
		nop

		
ACKrx		bcf	PORTA,2		;SCK  falling edge
		nop
		nop
		nop
		nop			;5uS de retardo

		bsf	PORTA,2		;SCK  rising edge
		btfsc	PORTA,1		;comprueba data
		goto	ACKrx		;NO, bucle
		bcf	PORTA,2		;SCK  falling edge estado bajo por defecto
		return

;ack desde SHT11 detectado y llegada de datos			
adqtime		btfsc	PORTA,1		;comprueba data
		goto	adqtime		;NO, bucle
		return


;///////////////////////////////////////////////////////////////////////////
;------------- LECTURA DE DATOS DESDE EL SHT11 (Byte alto) ----------------------
read			btfsc	PORTA,1
			goto	read
		
			movlw 	0x07
			MOVWF	sincbit

	high_byte	rlf	RXlsb,F
			bcf	RXlsb,0
			bsf	PORTA,2

			btfsc	PORTA,1
			bsf	RXlsb,0

			bcf	PORTA,2

			decfsz	sincbit,F
			goto	high_byte

			bsf	STATUS,5		; register page 1
			bcf	TRISA,1			; SHT11_DATA es salida
			bcf	STATUS,5		; register page 0

			bcf	PORTA,1
			nop
			bsf	PORTA,2
			nop
			bcf	PORTA,2
	
			bsf	STATUS,5		; register page 1
			bsf	TRISA,1			; SHT11_DATA es entrada
			bcf	STATUS,5		; register page 0

			movlw	0X07
			movwf	sincbit

	low_byte	rlf	RXmsb,F
			bcf	RXmsb,0
			bsf	PORTA,2
			btfsc	PORTA,1
			bsf	RXlsb,0

			bcf	PORTA,2

			decfsz	sincbit,F
			goto	low_byte

			bsf	STATUS,5		; register page 1
			bcf	TRISA,1			; SHT11_DATA es salida
			bcf	STATUS,5		; register page 0

			bcf	PORTA,1
			nop
			bsf	PORTA,2
			nop
			bcf	PORTA,2
	
			bsf	STATUS,5		; register page 1
			bsf	TRISA,1			; SHT11_DATA es entrada
			bcf	STATUS,5		; register page 0

			return















;///////////////////////////////////////////////////////////////////////////
;--------------- TRANSFORMA LA HUMEDAD EN UN VALOR ENTENDIBLE ---------------

CalcRH		;RH% calculos de linealidad. (a*RH%+b)/256
		bcf	STATUS,5	;banco 0
		movlw	0x00		;0		;MultiplicLO
		movwf	ACCaHI
		movf	RXlsb,W	      	;lectura 8 bits	;MultiplicHI
		movwf	ACCaLO
		
		
		movlw	b'01101100'		
		subwf	RXlsb,W
		btfsc	STATUS,C
		goto	calcA2
		
;-------------- Si lectura menor o igual a 107...
calcA1		movlw	b'10001111'	;A		;ResultLLO
		movwf	ACCbLO
		movlw	0x00		;A		;ResultHHI
		movwf	ACCbHI
		
		call	D_mpyS 		;multiplica (A*RH)
					;el resultado esta en ACCcHI,ACCcLO		
					;resta 512 del resultado
					;comprueba si el dato es mayor de 512
					;si fuera menor.. pone como resultado 512
					;si es mayor.. resta 2 a MSB que equivale a 512
					;del dato de 16bits		
		movlw	0x03		;resta 2
		subwf	ACCcHI,W	
		btfss	STATUS,C
		goto 	menord2		;mayor de 2


					;si es mayor de 512.. resta 512 al resultado
					;y luego comprueba que el resultado no sea menor de 512
mayord2		movlw	0x02
		subwf	ACCcHI,F	;resta 512 al dato alto 

		movlw	0x03		;si el resultado es 
		subwf	ACCcHI,W	;menor de 512...
		btfss	STATUS,C
		goto 	menord2		;mayor de 2
		goto	calccont	;si es mayor continua


					;si es menor de 2 pone como resultado 512
menord2		movlw	0x02
		movwf	ACCcHI		;resultado=512
		clrf	ACCcLO
		goto	calccont	;continua con los calculos

		goto	calccont
		
;-------------- Si lectura mayor o igual a 108...
calcA2		movlw	b'01101111'	;A		;ResultLLO
		movwf	ACCbLO
		movlw	0x00		;A		;ResultHHI
		movwf	ACCbHI
		
		call	D_mpyS 		;multiplica (A*RH)
		
		;suma 2893 al resultado
		;suma 11 a MSB (mas acarrero de LSB) y 77 a LSB
		
		;MSB=ACCcHI  LSB=ACCcLO para 16bits de resolucion
		
		movlw	b'00001011'
		addwf	ACCcHI		;suma 11 a MSB
		
		movlw	b'01001101'	;suma 77 a LSB y si hay acarreo
		addwf	ACCcLO		;se lo suma a LSB
		
		btfsc	STATUS,C	;comprueba el acarreo
		incf	ACCcHI		;suma el acarreo a MSB
					;no hay acarreo y salta
		


calccont	;continua con el calculo de %RH	
		;ahora divide el resultado de 16bits / 256

		;El resultado completo de 32 bits = ( ACCbHI,ACCbLO,ACCcHI,ACCcLO )

		;el resutlado despues de rotar 8 bits es el mismo que 
		;el byte (ACCcHI) correspondiente al byte 2 menos significativo
		
		
		movf	ACCcHI,W
		movwf	RH		;RH = Relative Humidity
		
		return			;retorna con el resultado calculado
		
;=================================================================================
;*******************************************************************
;                    Double Precision Multiplication
;
;*******************************************************************;
;   Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,ACCc ( 32 bits )
;      (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits )
;      (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits )
;      (c) CALL D_mpy
;      (d) The 32 bit result is in location ( ACCbHI,ACCbLO,ACCcHI,ACCcLO )
;
;               Double Precision Multiply ( 16x16 -> 32 )
;         ( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word
;  in ACCb ( ACCbHI,ACCbLO ) and low word in ACCc ( ACCcHI,ACCcLO ).
;*******************************************************************
;*******************************************************************

D_mpyS                           	;results in ACCb(16 msb's) and ACCc(16 lsb's)
		call    setupmult
		bcf	STATUS,C
mloop   
		rrf     ACCdHI,F       	;rotate d right
		rrf     ACCdLO,F
		btfss   STATUS,C    	;need to add?
		goto    No_add
		movf    ACCaLO,W        ; Addition ( ACCb + ACCa -> ACCb )
		addwf   ACCbLO,F       	;add lsb
		btfsc   STATUS,C    	;add in carry
 		incf    ACCbHI,F
		movf    ACCaHI,W
		addwf   ACCbHI,F       	;add msb

No_add		rrf     ACCbHI,F
		rrf     ACCbLO,F
		rrf     ACCcHI,F
		rrf     ACCcLO,F
		decfsz  temp,F        	 ;loop until all bits checked
		goto    mloop
		goto	end1


;         Double Precision Addition ( ACCb + ACCa -> ACCb )
;
D_add  	        bcf	Flags,C		;Clear temp Carry bit
		movf    ACCaLO,W        ; Addition ( ACCb + ACCa -> ACCb )
		addwf   ACCbLO,F       	;add lsb
		btfsc   STATUS,C    	;add in carry
 		incf    ACCbHI,F
		btfsc	STATUS,C
		bsf	Flags,C	
		movf    ACCaHI,W
		addwf   ACCbHI,F        ;add msb
		btfsc	Flags,C
		bsf	STATUS,C
		return

;*******************************************************************
setupmult  	movlw   .16             ; for 16 shifts
		movwf   temp
		movf    ACCbHI,W        ;move ACCb to ACCd
		movwf   ACCdHI
		movf    ACCbLO,W
		movwf   ACCdLO
		clrf    ACCbHI
		clrf    ACCbLO
		return
;****************************************************************

end1	return


