
; DEFINICE KONSTANT
; -------------------------------------------------------------

; Porty pro EEPROM 24C64
#DEFINE SCL         PORTA,7
#DEFINE SDA         PORTA,6
#DEFINE SCLDIR      TRISA,7
#DEFINE SDADIR      TRISA,6

EADR        EQU     H'043'          ; Adresa v EEPROM při čtení
EVAL        EQU     H'044'
EBYTE       EQU     H'049'

rot         EQU     H'051'          ; Rotace bytu
ack         EQU     H'052'



; PODPROGRAM eeprom_read
; Přečte EEPROM na zadané adrese a hodnotu uloží do registru EVAL
;
; Vstupní registry: 
;   EADR - adresa
;
; Výstupní registry:
;   EVAL - hodnota
;
; -------------------------------------------------------------
@eeprom_read  
        CALL    @i2c_start

        ; Device Address
        MOVLW   B'10100000'
        CALL    @i2c_write

        ; First Word Address
        MOVLW   H'00'
        CALL    @i2c_write

        ; Second Word Address
        MOVF    EADR,W
        CALL    @i2c_write

        CALL    @i2c_start

        ; Device Address
        MOVLW   B'10100001'
        CALL    @i2c_write

        CALL    @i2c_read
        MOVF    EBYTE,W
        MOVWF   EVAL

        CALL    @i2c_stop

        RETURN

; -------------------------------------------------------------


; PODPROGRAM eeprom_write
; -------------------------------------------------------------
@eeprom_write
        CALL    @i2c_start

        ; Device Address
        MOVLW   B'10100000'
        CALL    @i2c_write

        ; First Word Address
        MOVLW   H'00'
        CALL    @i2c_write

        ; Second Word Address
        MOVLW   H'00'
        CALL    @i2c_write

        ; Zápis dat do EEPROM
        MOVLW   H'99'
        CALL    @i2c_write
        MOVLW   H'00'
        CALL    @i2c_write
        MOVLW   H'00'
        CALL    @i2c_write

        MOVLW   H'00'
        CALL    @i2c_write
        MOVLW   H'66'
        CALL    @i2c_write
        MOVLW   H'00'
        CALL    @i2c_write

        MOVLW   H'00'
        CALL    @i2c_write
        MOVLW   H'00'
        CALL    @i2c_write
        MOVLW   H'33'
        CALL    @i2c_write

        CALL    @i2c_stop

        RETURN
; -------------------------------------------------------------


; I2C
;
; -------------------------------------------------------------
@i2c_read
        MOVLW   8 
        MOVWF   rot             ; Počet rotací

        BSF     STATUS,RP0      
        BSF     SDADIR          ; SDA vstup
        BCF     STATUS,RP0
    
i2c_read_rot
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us

        BCF     STATUS,C        ; Vynulujeme C
        BTFSC   SDA             ; Otestujeme SDA
        BSF     STATUS,C        ; Pokud SDA == 1, nastavíme C

        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SCL             ; SCL = 0

        RLF     EBYTE,1         ; Rotace EBYTE přes C doleva
        DECFSZ  rot,1
        GOTO    i2c_read_rot    ; Cyklus
        

        CALL    @delay_10us     ; Pauza cca 10us

        BCF     SDA             ; SDA = 0
        BSF     STATUS,RP0
        BCF     SDADIR          ; SDA výstup
        BCF     STATUS,RP0

        RETURN

@i2c_send_ack
        BCF     SDA             ; SDA = 0
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SCL             ; SCL = 0

        RETURN

@i2c_write
        MOVWF   EBYTE           ; W do EBYTE
        MOVLW   8           
        MOVWF   rot             ; Počet rotací
i2c_write_rot
        RLF     EBYTE,1         ; Rotace EBYTE o 1 bit doleva přes C

        BTFSS   STATUS,C        ; Otestujeme C a nastavíme SDA
        GOTO    $+3 
        BSF     SDA             ; SDA = 1
        GOTO    $+2 
        BCF     SDA             ; SDA = 0

        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SCL             ; SCL = 0;

        DECFSZ  rot,1           
        GOTO    i2c_write_rot   ; Cyklus
        
        CALL    @delay_10us     ; Pauza cca 10us
        CALL    @i2c_ack        ; ACK

        RETURN

@i2c_start
        BSF     SDA             ; SDA = 1
        BSF     STATUS,RP0
        BCF     SDADIR          ; SDA výstup
        BCF     STATUS,RP0
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SDA             ; SDA = 0
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SCL             ; SCL = 0
        RETURN

@i2c_stop
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SDA             ; SDA = 0
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SDA             ; SDA = 1
        BSF     STATUS,RP0
        BCF     SDADIR          ; SDA vstup
        BCF     STATUS,RP0
        RETURN

@i2c_ack
        BSF     STATUS,RP0      
        BSF     SDADIR          ; SDA vstup
        BCF     STATUS,RP0
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1

        CALL    @delay_10us     ; Pauza cca 10us
        BTFSC   SDA
        GOTO    $-1
        CALL    @delay_10us     ; Pauza cca 10us

        BCF     SCL             ; SCL = 0
        CALL    @delay_10us     ; Pauza cca 10us

        BCF     SDA             
        BSF     STATUS,RP0
        BCF     SDADIR          ; SDA výstup
        BCF     STATUS,RP0
        RETURN

@delay_10us
        GOTO    $+1
        GOTO    $+1
        RETURN
; -------------------------------------------------------------
