IIC_BUS MACRO
BULK_PATCH_IIC
CALL DEMORA_20MS
CALL RECARGA2
BTFSC DATO
RETURN
bcf INTCON,GIE ;DESACTIVAMOS LAS INTERRUPCIONES
CALL RESET_DIRECCION ;APUNTA AL PAD 00, HABRA QUE BUSCAR LA FORMA DE SELECIONAR ENTRE VARIOS CADA 255 BYTES
IIC_MEMO_READ
BANKSEL SSPCON
CALL IIC_START ;ENVIA LA CONDICION DE START
MOVLW B'10100001' ;CONTROL BYTE--> |STARTBIT|1|0|1|0|A2|A1|A0|1 AUNQUE EN EL MANUAL ESTA A 0 PARA R/W |ACK<---este lo devuelve el esclavo|
CALL IIC_ENVIA ;Y SE LO ENVIA A LA EEPROM
CALL IIC_ADRESS ;MANDA DIRH,ESPERA ACK,MANDA DIRL, ESPERA ACK = |0|0|0|0|0|0|0|0|ACK|0|0|0|0|0|0|0|0|ACK|_DATO_8BITS_|ACK|_DATO_8BITS_|ACK|
SIGUE_READ
BANKSEL SSPCON
BSF SSPCON, CKP ;INICIA EL RELOJ
BANKSEL SSPCON2
BSF SSPCON2,RCEN ;activa la recepcion
BTFSC SSPCON2,RCEN ;ESPERA A TERMINAR LA RECEPCION
GOTO $-1
BTFSS SSPSTAT,BF ;dato disponible en SSPBUF para ser leido?
GOTO $-1 ;no, esperar
CALL IIC_SEND_ACK ;DEVUELVE EL ACK PARA QUE SEA VALIDO
BANKSEL SSPCON
BCF SSPCON, CKP ;Y APAGA EL RELOJ
BANKSEL DIRL
INCFSZ DIRL,F ;UNA VEZ LLEGA DE 255-0 SALE DE LA RUTINA
GOTO GUARDA_PADS
CALL IIC_STOP
BSF INTCON,GIE
IIC_STOP
BANKSEL SSPCON2
BSF SSPCON, CKP ;INICIA EL RELOJ
BSF SSPCON2,PEN ;INICIA EL ESTADO STOP EN SDA SCL
BTFSC SSPCON2,PEN
GOTO $-1 ;ESPERA A QUE TERMINE
BANKSEL SSPCON
BCF SSPCON, CKP ;Y APAGA EL RELOJ
RETURN
IIC_SEND_NACK
BANKSEL SSPCON2
BSF SSPCON2,ACKDT ;A UNO PARA NO-ACK
BSF SSPCON2,ACKEN ;CON ESTO ACTIVAMOS LA SECUENCIA DE ACKDT(ANTERIOR)
BTFSC SSPCON2,ACKEN
GOTO $-1 ;Y ESPERAMOS A QUE LA TERMINE
RETURN ;VUELVE
IIC_SEND_ACK
BANKSEL SSPCON2
BCF SSPCON2,ACKDT ;A CERO PARA ACK
BSF SSPCON2,ACKEN ;CON ESTO ACTIVAMOS LA SECUENCIA DE ACKDT(ANTERIOR)
BTFSC SSPCON2,ACKEN
GOTO $-1 ;Y ESPERAMOS A QUE LA TERMINE
RETURN ;VUELVE
GUARDA_PADS
BANKSEL SSPBUF
MOVF SSPBUF,W
BANKSEL REG_MUESTRA
MOVWF REG_MUESTRA
CALL ESCRITURA_EEPROM_IIC ;Y GUARDA EL DATO EN LA EEPROM
GOTO SIGUE_READ
IIC_IDLE
BANKSEL SSPSTAT
BTFSC SSPSTAT,R_W
GOTO $-1
movf SSPCON2,w ; POR QUE SE HACE ESTO SI POR UN CASUAL LA PRIMERA VEZ NO SE PONE A UNO Z A LA SIGUIENTE TAMPOCO
andlw 0x1F
btfss STATUS,Z
goto $-3
RETURN
ESCRITURA_EEPROM_IIC
BANKSEL DIRL
MOVF DIRL,W ;Data Memory
BANKSEL EEADR
MOVWF EEADR ;Address to write
CLRW
ADDWF EEADR,F ;DE ESTA FORMA SE COMIENZA A CONTAR DESDE EL REGISTRO DE POTES
GOTO CONTINUA_ESCRITURA
IIC_ADRESS
BANKSEL DIRH
; MOVF DIRH,W
clrw
CALL IIC_ENVIA
BANKSEL DIRL
; MOVF DIRL,W
clrw
CALL IIC_ENVIA
RETURN
IIC_ENVIA
CALL IIC_IDLE ;ESERA A QUE TERMINE LA ULTIMA TRANSMISION
BANKSEL SSPBUF
MOVWF SSPBUF ;CARGA EL DATO EN SSPBUFF
BSF SSPCON, CKP ;NO HABRIA QUE ACTIVAR AQUÍ EL RELOJ PARA QUE EMPIEZE A ENVIAR
BANKSEL SSPSTAT
btfsc SSPSTAT,R_W ;esperar a que termine el envio
goto $-1
btfss SSPCON2,ACKSTAT ;checkear ack
GOTO NO_ACK
SALE_NCK
BANKSEL PIR1
btfss PIR1,SSPIF ;esperar finalizacion del noveno clock
goto $-1
bcf PIR1,SSPIF ;BAJA LA BANDERA
BCF SSPCON, CKP ;Y TRAS TERMINAR DE RRECONOCER EL ACK APAGAR EL RELOJ
RETURN
NO_ACK
BANKSEL DIRL
MOVLW .255
MOVWF DIRL
goto SALE_NCK ;ESTO OBLIGA A SALIR DE LA RUTINA AL SOBREPASAR LOS 255
RESET_DIRECCION
BANKSEL DIRH ;CARGAMOS EN LOS REGISTROS DE DIRECCION A LA QUE QUEREMOS ACCEDER
CLRF DIRH ;DE MOMENTO DIRECCION 00
CLRF DIRL
RETURN
IIC_START
CALL IIC_IDLE
BANKSEL SSPCON2
BSF SSPCON, CKP ;PRIMERO INICIA EL RELOJ
BSF SSPCON2, SEN ;INICIA START
BTFSC SSPCON2,SEN ;
GOTO $-1 ;ESPERA A QUE TERMINE
BANKSEL PIR1
BTFSS PIR1,SSPIF ;ESPERA A LA BANDERA POR INTRRUPCION
GOTO $-1
BCF PIR1,SSPIF ;Y LA BAJA
BCF SSPCON, CKP ;Y APAGA EL RELOJ
RETURN
ENDM
;------------------------------------------