;=======================================================
; Проект 34. Внешняя EEPROM 24C02 по шине I2C (TWI)
; ATmega8, 8 МГц. SDA — PC4, SCL — PC5, подтяжки 4,7 кОм
; Записываем байт в ячейку 0x10 и читаем его обратно
;=======================================================
.include "m8def.inc"

.def tmp  = r16
.def data = r17

.equ EE_W = 0xA0                        ; адрес 24C02 для записи
.equ EE_R = 0xA1                        ; адрес для чтения

.cseg
.org 0x0000
        rjmp    RESET

RESET:
        ldi     tmp, low(RAMEND)
        out     SPL, tmp
        ldi     tmp, high(RAMEND)
        out     SPH, tmp

        ldi     tmp, 0xFF
        out     DDRB, tmp               ; индикация на светодиодах
        ldi     tmp, 32                 ; TWBR: ~100 кГц при 8 МГц
        out     TWBR, tmp

        ;--- запись значения 0x5A в ячейку 0x10 ---
        rcall   TwiStart
        ldi     data, EE_W
        rcall   TwiWrite
        ldi     data, 0x10              ; адрес ячейки
        rcall   TwiWrite
        ldi     data, 0x5A              ; данные
        rcall   TwiWrite
        rcall   TwiStop
        rcall   Delay10ms               ; пауза на цикл записи EEPROM

        ;--- чтение той же ячейки ---
        rcall   TwiStart
        ldi     data, EE_W
        rcall   TwiWrite
        ldi     data, 0x10
        rcall   TwiWrite
        rcall   TwiStart                ; повторный старт
        ldi     data, EE_R
        rcall   TwiWrite
        rcall   TwiReadNack
        rcall   TwiStop
        out     PORTB, data             ; показываем прочитанное

MAIN:
        rjmp    MAIN

TwiStart:
        ldi     tmp, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
        out     TWCR, tmp
TS_W:
        in      tmp, TWCR
        sbrs    tmp, TWINT              ; ждём завершения операции
        rjmp    TS_W
        ret

TwiWrite:
        out     TWDR, data
        ldi     tmp, (1<<TWINT)|(1<<TWEN)
        out     TWCR, tmp
TW_W:
        in      tmp, TWCR
        sbrs    tmp, TWINT
        rjmp    TW_W
        ret

TwiReadNack:
        ldi     tmp, (1<<TWINT)|(1<<TWEN)       ; без ACK — последний байт
        out     TWCR, tmp
TR_W:
        in      tmp, TWCR
        sbrs    tmp, TWINT
        rjmp    TR_W
        in      data, TWDR
        ret

TwiStop:
        ldi     tmp, (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
        out     TWCR, tmp
        ret

Delay10ms:
        ldi     r18, 130
E1:      ldi     r19, 255
E2:      dec     r19
        brne    E2
        dec     r18
        brne    E1
        ret
