OK, nur damit wir uns richtig verstehen:
1. Du willst den System I2C Bus der CC1 für Deine Peripherie mitbenutzen, z. B. einen PCF8574 hinhängen
2. Dafür hast Du ein Assembler-Programm, das die System-Routinen I2C_Start, I2C_Write, I2C_Read_Last usw. aufruft.
Dein Assembler-Programm sieht dann (immer) in etwa so aus:
Code:
; EEPROM vom I2C Bus abmelden
jsr I2C_ReadLast
; I2C Bus starten und mein device selektieren
ldx xxx (z. B. $A1)
jsr I2C_Start
; meine Daten zu diesem device senden
ldx xxx (z. B. $A3)
jsr I2C_Write
; vielleicht nochmal was senden
; mein Device abmelden
jsr I2C_Stop
; das EEPROM wieder anmelden
xxxx
3. Problem ist die System Routine I2C_Write, die auch noch mal in I2CStart enthalten ist.
Das sieht im Original so aus:
Code:
;------------------------------------------------
; void I2C_Start ( unsigned char devadr );
global _I2C_Start
signat _I2C_Start,4216
;------------------------------------------------
; Startbedingung nach Init, Write oder Stop moeglich
; Vorbedingung: SCL lo (nach Write) oder
; SCL hi und SDA hi (nach Init und Stop)
; SCL und SDA als Ausgang, SDA nach low ziehen
; = Startbedingung
; warten
_I2C_Start BSET SDA,DIR ; SDA hi ausgeben
BSET SDA,PORT ; Vorbereiten der Startbed.
BSET SCL,PORT ; SCL hi falls lo
BCLR SDA,PORT ; SDA lo -> STARTBEDINGUNG
BCLR SCL,PORT ;
; nach jeder Startbedingung wird sofort
; das Controlbyte geschrieben,
; also weiter bei I2C_Write
;------------------------------------------------
; void I2C_Write ( unsigned char byte );
global _I2C_Write
signat _I2C_Write,4216
;------------------------------------------------
_I2C_Write BSET SDA,DIR ; SDA out
TXA ;
STA writebuf ; merken fuer retry
LDX #8 ; init loop
putnextbit ROLA
BCC lobit ;
BSET SDA,PORT ; hi bit
BRA writeclock
lobit BCLR SDA,PORT ; lo bit
writeclock BSET SCL,PORT ; scl hi
BCLR SCL,PORT ; scl lo
DEX
BNE putnextbit ; loop
; ACK-Bit lesen
; Achtung: ACK ist low-aktiv
BCLR SDA,DIR ; sda als Eingang
BSET SCL,PORT ; scl hi
BRSET SDA,PORT,retrywrite; no ACK -> retry
BCLR SCL,PORT
RTS
; hierher nur bei control byte,
; wenn EEPROM noch nicht bereit
retrywrite BCLR SCL,PORT ;
LDX writebuf
BRA _I2C_Start
4. Diese beiden Routinen musst Du jetzt in Deinen Assembler-Source kopieren und anstelle der beiden Systemroutinen aufrufen.
5. Dann muss Du Dir den Teil "ACK-Bit lesen..." anschauen: Genau der Befehl
BRSET SDA, PORT, retrywrite
stört Dich: Wenn kein ACK da ist, wird unentwegt dasselbe Byte nochmal geschrieben.
6. Jetzt musst Du Dir überlegen, was in diesem Fall BEI DEINER SCHALTUNG passieren soll.
6.1 Du Kannst Dir zum Beispiel sagen: "Mir ist's egal ob das Byte quittiert wird": dann lässt Du den BRSET einfach weg.
6.2 Oder Du könntest den Befehl über eine Schleife paar (hundert) mal wiederholen, und erst dann aufhören.
6.3 Oder Du könntest das Ergebnis (ACK oder NOACK) an die aufrufende CCBASIC Routine zurückgeben, und die überlegt sich das dann.
Lesezeichen