;---------------------	; Registry pro I2C - namapované pro všechny banky
CBLOCK	0X70
	I2C_DAT
	I2C_CIT
	I2C_STAT
	I2C_ADR1
	I2C_ADR2
	I2C_ADR3
	I2C_DAT1
ENDC

#define	SDA	PORTB,4		; I2C data
#define	SDC	PORTB,5		; I2C Hodiny


;**************************************************************************
;   SW implementace I2C 
;**************************************************************************
;Každa funkce začíná přepnutím na banku 1 a končí přepnutím na banku 0
I2C_WRITE_EEPROM
	CLRF	I2C_STAT
	BCF		I2C_ADR1,0
	CALL	I2C_START
	MOVF	I2C_ADR1,w
	CALL	I2C_SEND
	BTFSC	I2C_ERR
	GOTO	I2C_WRITE_EEPROM_END
	MOVF	I2C_ADR2,w
	CALL	I2C_SEND
	BTFSC	I2C_ERR
	GOTO	I2C_WRITE_EEPROM_END
	MOVF	I2C_ADR3,w
	CALL	I2C_SEND
	BTFSC	I2C_ERR
	GOTO	I2C_WRITE_EEPROM_END
	MOVF	I2C_DAT1,w
	CALL	I2C_SEND
	BTFSC	I2C_ERR
	GOTO	I2C_WRITE_EEPROM_END
	CALL	I2C_STOP
	I2C_WRITE_EEPROM_END
RETURN

I2C_READ_EEPROM
	CLRF	I2C_STAT
	BCF		I2C_ADR1,0
	CALL	I2C_START
	MOVF	I2C_ADR1,w
	CALL	I2C_SEND
	BTFSC	I2C_ERR
	GOTO	I2C_READ_EEPROM_END
	MOVF	I2C_ADR2,w
	CALL	I2C_SEND
	BTFSC	I2C_ERR
	GOTO	I2C_READ_EEPROM_END
	MOVF	I2C_ADR3,w
	CALL	I2C_SEND
	BTFSC	I2C_ERR
	GOTO	I2C_READ_EEPROM_END

	BSF		I2C_ADR1,0
	CALL	I2C_START
	MOVF	I2C_ADR1,w
	CALL	I2C_SEND
	BTFSC	I2C_ERR
	GOTO	I2C_READ_EEPROM_END
	CALL	I2C_RECIVE
	CALL	I2C_STOP
	I2C_READ_EEPROM_END
RETURN

I2C_START ;Odeslání start sekvence
	BSF		STATUS,RP0
	BSF		SDA
	BSF		SDC
	BCF		SDA			;Vynulování dat
	BCF		STATUS,RP0
RETURN
	
I2C_STOP  ;Odeslání stop sekvence
	BSF		STATUS,RP0
	BCF		SDA		;Nastavení dat do nuly
	BSF		SDC 	;Hodiny do 1
	nop
	BSF		SDA		;Pri SCL=1 zvedneme SDA do 1 => Stop
	BCF		STATUS,RP0
RETURN
	
I2C_SEND ;Procedůra na odeslání 8bit slova a vyčkání na ACK
	BSF		STATUS,RP0
	BCF		SDC		;Nastavení SCL do nuly (po start bitu)
	MOVWF	I2C_DAT ;Přesunutí W do I2C_DAT
	MOVLW	D'8'
	MOVWF	I2C_CIT	;Do čítače uložíme 8
	I2C_SEND_LOOP
	BCF		SDC			;Vynulujeme hodiny (při prvním průchod nemá smysl)
	BCF		SDA			;Vynulujeme data na SDA
	RLF		I2C_DAT,f	;Rotujeme daty vlevo přes C
	BTFSC	STATUS,C	;Je C == 1?
	BSF		SDA			;Ano - Nastavíme data do 1
	BSF		SDC			;Nastavíme hodiny
	DECFSZ	I2C_CIT		;Odecteme 1 od čítače a pokud neni nula
	GOTO	I2C_SEND_LOOP	;Jdeme na začátek odesílání
	NOP
	NOP
	BCF		SDC			;Vynulujeme hodiny (odeslání posledního bitu)
	BSF		SDA			;Nastavení DAT do 1 pro čekání na ACK
	NOP
	NOP
	BSF		SDC
	BCF		STATUS,RP0
	I2C_SEND_WAIT_ACK	;Cekani na ACK CCA 1.5ms
	INCF	I2C_CIT		;Pricteni 1 k citeci
	BTFSC	STATUS,Z	;Overeni jestli pretekl citac (pokud ano, cekani na ACK se nezdarilo)
	GOTO	I2C_ERROR	;Skok na proceduru osetrujici chybu
	BTFSC	SDA			;Jsou data v nule? (ACK)
	GOTO	I2C_SEND_WAIT_ACK ;Pokud ne čekáme dál
	BSF		STATUS,RP0	;Nastavení banky 1
	BCF		SDC			;Nastavení SCL do nuly (po přijetí ACK)
	BCF		STATUS,RP0	;Banka 0
RETURN
	
I2C_RECIVE ;Procedůra na přijmutí 8bit slova a potvrzení ACK
	BSF		STATUS,RP0
	BCF		SDC		;Nastavení SDC do nuly
	BSF		SDA		;SDA do 1 (příjem dat)
	MOVLW	D'8'
	MOVWF	I2C_CIT	;Do čítače uložíme 8
	I2C_RECIVE_LOOP
	BSF		SDC		;Nastavíme SDC do 1 
	BCF		STATUS,RP0	;Nastavíme banku 0
	RLF		I2C_DAT,F	;Posuneme přijmaná data o jeden bit do leva
	BCF		I2C_DAT,0	;Vynulujeme poslední bit
	BTFSC	SDA			;Pokud je na dat. zběrnici 1
	BSF		I2C_DAT,0	;Nastavíme poslední bit do 1
	BSF		STATUS,RP0	;Přepneme na banku 1
	BCF		SDC			;Nastavíme SDC do nuly
	DECFSZ	I2C_CIT		;Odecteme 1 od čítače a pokud neni nula
	GOTO	I2C_RECIVE_LOOP	;Jdeme na začátek odesílání
	BCF		SDA			;Nastavíme data do 0 (ACK)
	BSF		SDC			;Nastavíme SDC do 1
	NOP					
	NOP					;Čekání 3cykly (3us)
	NOP
	BCF		SDC			;Nastavíme SDC do 0
	BCF		STATUS,RP0	;Přepneme na banku 0
RETURN

I2C_ERROR	;Procedůra se volá pokud nedojde k přijmutí ACK bitu
	BSF		I2C_ERR		;Nastaví se příznak chyby
	CALL	I2C_STOP	;Pošle se stop byt (po NOACK musí následovat stop bit)
RETURN		
;**************************************************************************