;======================= Subrutina sensor sht11 ======================================
;
;--------------------- LECTURA HUMEDAR -----------------------------------------------
sht11_Humedad	call 	SHT11_start	;Inicio de transmision
		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	readMSB		;lee el byte alto
		call	setACK
		call	readLSB		;lee el byte bajo
		call	setNACK
		call	CalcRH		;Calcula %RH y ajusta linealidad
					;retorna variable RH COMO dato		
		return
	
;------------------- SUBRUTINAS DE CONFIGURACION DEL SHT11 ---------------------------		
sht11_Set8bits	;configura el sensor para trabajar en modo 8 bits
		call 	SHT11_start	;Inicio de transmision
		movlw	b'00000111'
		call	SHT11_CMD	;Envio: Lectura en config interna
		call	waitACK		;espera que llegue ACK desde el sensor
		call	readMSB		;lee el byte alto (Dato)
		call	waitACK
		call	readLSB		;lee el byte bajo (CheckSum)
		call	setNACK

		call 	SHT11_start	;Inicio de transmision
		movlw	b'00000110'
		call	SHT11_CMD	;Envio: Escritura en config interna
		call	waitACK		;espera que llegue ACK desde el sensor
		bsf	RXmsb,0		;pone un 1 en el bit adecuado...
		movf	RXmsb,W		;y carga el stats modificado del sensor
		call	SHT11_CMD	;Envio: modificacion de status
		call	waitACK		;espera que llegue ACK desde el sensor

		return

		;call 	SHT11_start	;Inicio de transmision
		;movlw	b'00000111'
		;call	SHT11_CMD	;Envio: Lectura en config interna
		;call	waitACK		;espera que llegue ACK desde el sensor
		;call	readLSB		;lee el byte bajo
		;call	setNACK
			
		;return


sht11_HeaterON	;conecta el calentador interno anticondensacion
		call 	SHT11_start	;Inicio de transmision
		movlw	b'00000111'
		call	SHT11_CMD	;Envio: Lectura en config interna
		call	waitACK		;espera que llegue ACK desde el sensor
		call	readMSB		;lee el byte alto (Dato)
		call	waitACK
		call	readLSB		;lee el byte bajo (CheckSum)
		call	setNACK	

		call 	SHT11_start	;Inicio de transmision
		movlw	b'00000110'
		call	SHT11_CMD	;Envio: Escritura en config interna
		call	waitACK		;espera que llegue ACK desde el sensor
		bsf	RXmsb,2		;pone un 1 en el bit adecuado...
		movf	RXmsb,W		;y carga el stats modificado del sensor
		call	SHT11_CMD	;Envio: modificacion de status
		call	waitACK		;espera que llegue ACK desde el sensor
		return	

sht11_HeaterOFF	;desconecta el calentador interno anticondensacion
		call 	SHT11_start	;Inicio de transmision
		movlw	b'00000111'
		call	SHT11_CMD	;Envio: Lectura en config interna
		call	waitACK		;espera que llegue ACK desde el sensor
		call	readMSB		;lee el byte alto (Dato)
		call	waitACK
		call	readLSB		;lee el byte bajo (CheckSum)
		call	setNACK	

		call 	SHT11_start	;Inicio de transmision
		movlw	b'00000110'
		call	SHT11_CMD	;Envio: Escritura en config interna
		call	waitACK		;espera que llegue ACK desde el sensor
		bcf	RXmsb,2		;pone un 1 en el bit adecuado...
		movf	RXmsb,W		;y carga el stats modificado del sensor
		call	SHT11_CMD	;Envio: modificacion de status
		call	waitACK		;espera que llegue ACK desde el sensor
		return	
		
sht11_Reset	;Resetea el sensor sht11
		call 	SHT11_start	;Inicio de transmision
		movlw	b'00011110'	;::::::::::::::::::::::::::::::::::::::::::::::::::::00011110
		call	SHT11_CMD	;Envio: Lectura en config interna
		call	RETA1700	;espera de 11mS al menos despues de esta instruccion
		return


;----------- TRANSMISION DE DATO AL SHT11 ------------------------------------		
SHT11_start	bsf	STATUS,5	;banco 1 
		bcf	STATUS,6
		bcf	TRISA,2		;puertos como salida
		bcf	TRISA,1
		bcf	STATUS,5	;banco 0 

		bsf	PORTA,1		;DATA a 1 (por defecto)
		nop			;espera un poco
		nop
		
		bsf	PORTA,2		;CLK
		bcf	PORTA,1		;DATA	(pulso bajo)
		bcf	PORTA,2		;CLK
		bsf	PORTA,2		;CLK
		bsf	PORTA,1		;DATA (por defecto alto)
		bcf	PORTA,2		;CLK

		return


;///////////////////////////////////////////////////////////////////////////
;--------------------- Manda comando AL SHT11 ------------------------------
SHT11_CMD	movwf	CMData		;guarda el comando en variable
		clrf	sincbit
		bcf	STATUS,C	;borra carry
		bsf	STATUS,5	;banco 1
		bcf	TRISA,1		;pone DATA port,0 como salida
		bcf	STATUS,RP0	;banco 0
		
cont_send	rlf	CMData,F	;rota a la izquierda, bit alto en carry

;envio de datos segun el protocolo del sht11
send_data	btfsc	STATUS,C	;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 	0x07		;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
		
ACKrx		bcf	PORTA,2		;SCK  falling edge
		nop
		nop			;5uS de retardo
		nop
		nop
		nop
		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) ----------------------
readMSB		clrf	RXmsb		;limpia registro
		bsf	RXmsb,0		;pone un 1 que indicara en carry el final

leemsb		bcf	PORTA,2		;SCK  falling edge
		bsf	PORTA,2		;SCK  rising edge
		btfss	PORTA,1		;lee data
		goto	es_ceromsb

es_unomsb	rlf	RXmsb,f		;rota a la izquierda
		bsf	RXmsb,0		;pone un 1  en el bit 0
		btfss	STATUS,C	;salio la marca por carry?
		goto	leemsb		;continua y captura el siguiente bit
		return

es_ceromsb	rlf	RXmsb,f		;rota a la izquierda
		bcf	RXmsb,0		;pone un 0  en el bit 0
		btfss	STATUS,C	;salio la marca por carry?
		goto	leemsb		;continua y captura el siguiente bit
		return			;retorna



;//////////////////////////////////////////////////////////////////////////////////
;--------------- LECTURA DE DATOS DESDE EL SHT11 (Byte bajo) ---------------------
readLSB		clrf	RXlsb		;limpia registro
		bsf	RXlsb,0		;pone un 1 que indicara en carry el final

leelsb		bcf	PORTA,2		;SCK  falling edge
		bsf	PORTA,2		;SCK  rising edge
		btfss	PORTA,1		;lee data
		goto	es_cerolsb

es_unolsb	rlf	RXlsb,f		;rota a la izquierda
		bsf	RXlsb,0		;pone un 1  en el bit 0
		btfss	STATUS,C	;salio la marca por carry?
		goto	leelsb		;continua y captura el siguiente bit
		return

es_cerolsb	rlf	RXlsb,f		;rota a la izquierda
		bcf	RXlsb,0		;pone un 0  en el bit 0
		btfss	STATUS,C	;salio la marca por carry?
		goto	leelsb		;continua y captura el siguiente bit
		return			;retorna

	
;///////////////////////////////////////////////////////////////////////////
setACK		bsf	STATUS,5	;banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
		bcf	TRISA,1		;pone DATA port,0 como salida
		bcf	STATUS,5	;banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
			
		bcf	PORTA,2		;SCK  falling edge
		bcf	PORTA,1		;DATA change nivel logico 0
		bsf	PORTA,2		;SCK  rising edge
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		
		;bsf	PORTA,1		;DATA change nivel logico 1(reposo)
		
		bsf	STATUS,5	;banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
		bsf	TRISA,1		;pone DATA port,0 como entrada
		bcf	STATUS,5	;banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
		return


;///////////////////////////////////////////////////////////////////////////
setNACK		bsf	STATUS,5	;banco 1
		bcf	TRISA,1		;pone DATA port,0 como salida
		bcf	STATUS,5	;banco 0
			
		bcf	PORTA,2		;SCK  falling edge
		bsf	PORTA,1		;DATA change nivel logico 0
		bsf	PORTA,2		;SCK  rising edge
		nop
		bcf	PORTA,2		;baja clk
		
		bsf	STATUS,5	;banco 1
		bsf	TRISA,1		;pone DATA port,0 como entrada
		bcf	STATUS,5	;banco 0

		return


;///////////////////////////////////////////////////////////////////////////
;--------------- TRANSFORMA LA HUMEDAD EN UN VALOR ENTENDIBLE ---------------

CalcRH		;RH% calculos de linealidad. (a*RH%+b)/256
		movlw	.0		;0		;MultiplicLO
		movwf	ACCaHI
		movf	RXlsb,W	      	;lectura 8 bits	;MultiplicHI
		movwf	ACCaLO
		
		
		movlw	.108		
		subwf	RXlsb,W
		btfsc	STATUS,C
		goto	calcA2
		
;-------------- Si lectura menor o igual a 107...
calcA1		movlw	.143		;A		;ResultLLO
		movwf	ACCbLO
		movlw	.0		;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	.3		;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	.2
		subwf	ACCcHI,F	;resta 512 al dato alto 

		movlw	.3		;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	.2
		movwf	ACCcHI		;resultado=512
		clrf	ACCcLO
		goto	calccont	;continua con los calculos

		goto	calccont
		
;-------------- Si lectura mayor o igual a 108...
calcA2		movlw	.111		;A		;ResultLLO
		movwf	ACCbLO
		movlw	.0		;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	.11
		addwf	ACCcHI		;suma 11 a MSB
		
		movlw	.77		;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


