# i2c_slave_1_display.py
# 14.11.2025
# www.g-heinrichs.de

# To do: Testen; Überschrift größer; Ausgabe auf dem Display formatieren

# I2C-Slave zum Lesen eines Bytes; Ausgabe auch auf dem Display des TTGO
# zuerst Slave starten, dann Master

from machine import Pin, SPI
from utime import sleep_us
from sys import exit

import vga1_8x16 as font1
import st7789

spi = SPI(1, baudrate=20000000, polarity=1, sck=Pin(18), mosi=Pin(19))
display = st7789.ST7789(spi, 135, 240,  reset=Pin(23, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(16, Pin.OUT), backlight=Pin(4, Pin.OUT), rotation=3)
# Landscape
display.init()
display.fill(0)  # loeschen; Bildschirm schwarz

SDA = Pin(21, Pin.IN)
SCL = Pin(22, Pin.IN) 
slave_address = 176 # (8-Bit-Schreib-Adresse)

pause = 2 # in us (ggf. abh. von Frequenz des Masters)

######################### Funktionen #########################

def start():
    global SDA
    while SDA.value() or SCL.value(): # warten, bis BEIDE Leitungen auf 0 liegen
        pass
    
def get_bit():
    global SDA
    while SCL.value() == 0: # auf Anfang eines Bit-Signals vom Master warten
        pass
    # (ggf.) ein paar Mikrosekunden warten; m. E. nicht nötig
    # sleep_us(pause)
    bit = SDA.value()
    while SCL.value() == 1: # auf Ende des Bit-Signals vom Master warten
        pass
    sleep_us(pause)
    return bit

def get_byte():
    byte = 0
    for i in range(8): 
        bit = get_bit()
        byte = 2*byte + bit
    return byte


def send_ack_bit(bit): # zieht SDA für 1 Bit-Zeit auf 0 (ACK), wenn bit = True ist, d. h.empfangene Adresse (rec_addr) und Slave-Adresse (slave_address) gleich sind
    # print(bit)
    global SDA
    SDA = Pin(21, Pin.OUT)
    if bit:
        SDA.value(0)   # ACK
    else:
        SDA.value(1)   # NACK
    while SCL.value() == 0: # auf Anfang des SCL-Signals vom Master warten
        pass
    # sleep_us(pause)
    while SCL.value() == 1: # auf Ende des SCL-Signals vom Master warten
        pass
    # sleep_us(pause)
    SDA = Pin(21, Pin.IN)
   
    
######################### Hauptprogramm #########################

print('I2C-Slave gestartet...')
display.text(font1, 'I2C-Slave gestartet...', 10, 10)

start()
rec_addr = get_byte() # gesendete Adresse empfangen und in received_addr speichern
print('empfangene Adresse:', rec_addr)
display.text(font1, 'empf. Adr.:' + str(rec_addr), 10, 30)
if rec_addr == slave_address:
    send_ack_bit(True) # ACK senden        
else:
    send_ack_bit(False) # NACK senden
    print('Adresse falsch : NACK gesendet -> Abbruch')
    display.text(font1, 'Gesendet: NACK', 10, 50)
    exit()
    
# Datenbits empfangen und anzeigen:
data = get_byte()
send_ack_bit(True) # ACK senden
print('Empfangenes Byte:', data)
display.text(font1, 'Empfangen: ' + str(data), 10, 70)



    
    
    
    
    
    
        

