.org 32768 out_val .equ 65535 io_port .equ 128 sda_bit .equ 5 scl_bit .equ 4 ;------------------------------------------------------------------------------ ; Subroutines di basso livello per accesso al bus i2c ; out_val = indirizzo byte comune per scrittura su porta condivisa ; io_port = indirizzo porta di ingresso/uscita ; sda_bit = bit dati in out_val ; scl_bit = bit clock in out_val ; Temporizzazioni minime 5uS, controllo clock stretching. ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ ; Genera uno start o un repeated start i2c ; Input: nessuno ; Output: nessuno ; Alterati: nessuno ;------------------------------------------------------------------------------ i2cstart: PUSH AF LD A,(out_val) SET sda_bit,A OUT (io_port),A NOP SET scl_bit,A OUT (io_port),A NOP RES sda_bit,A OUT (io_port),A NOP RES scl_bit,A OUT (io_port),A NOP LD (out_val),A POP AF RET ;------------------------------------------------------------------------------ ; Genera uno stop i2c ; Input: nessuno ; Output: nessuno ; Alterati: nessuno ;------------------------------------------------------------------------------ i2cstop: PUSH AF LD A,(out_val) RES sda_bit,A OUT (io_port),A NOP SET scl_bit,A OUT (io_port),A NOP SET sda_bit,A OUT (io_port),A LD (out_val),A POP AF RET ;------------------------------------------------------------------------------ ; Trasmette un byte sul bus i2c ; Input: A=byte ; Output: CF=0 ricevuto ack, CF=1 ricevuto nack ; Alterati: flags ;------------------------------------------------------------------------------ i2ctx: PUSH BC PUSH DE LD D,A ; salva dato in D LD E,A ; e una copia anche in E LD B,8 ; 8 bit da trasmettere LD A,(out_val) i2ctxloop: RR D JR C,i2c_tx1 RES sda_bit,A JR i2c_tx2 i2c_tx1: SET sda_bit,A i2c_tx2: OUT (io_port),a NOP SET scl_bit,A OUT (io_port),A LD C,A i2ctxw1: IN A,(io_port) ; /SCL -> ZF BIT scl_bit,A ; per lettura SCL JR Z,i2ctxw1 ; Se stretch attendi LD A,C RES scl_bit,A OUT (io_port),A DJNZ i2ctxloop SET sda_bit,A ; rilascia sda per leggere ack OUT (io_port),a NOP SET scl_bit,A OUT (io_port),A NOP LD C,A i2ctxw2: IN A,(io_port) ; /SCL -> ZF BIT scl_bit,A ; per lettura SCL JR Z,i2ctxw2 ; Se stretch attendi RLA RLA RLA ; CF=ack/nack LD A,C RES scl_bit,A OUT (io_port),A LD (out_val),A LD A,E POP DE POP BC RET ;------------------------------------------------------------------------------ ; Legge un byte dal bus i2c ; Input: CF=0 per ack CF=1 per nack ; Output: A=byte ; Alterati: A ;------------------------------------------------------------------------------ i2crx: PUSH BC PUSH DE PUSH AF PUSH AF LD A,(out_val) SET sda_bit,A ; rilascia sda per leggere i bit OUT (io_port),a LD B,8 ; 8 bit da leggere i2crxloop: SET scl_bit,A OUT (io_port),A NOP LD C,A i2crxw1: IN A,(io_port) ; /SCL -> ZF BIT scl_bit,A ; per lettura SCL JR Z,i2crxw1 ; Se stretch attendi RLA RLA RLA RR D ; salva bit in D LD A,C RES scl_bit,A OUT (io_port),A DJNZ i2crxloop LD C,A POP AF LD A,C JR C,txnack RES sda_bit,A ; sda=0 per invio ack OUT (io_port),A NOP txnack: SET scl_bit,A OUT (io_port),A LD C,A i2crxw2: IN A,(io_port) ; /SCL -> ZF BIT scl_bit,A ; per lettura SCL JR Z,i2crxw2 ; Se stretch attendi LD A,C RES scl_bit,A OUT (io_port),A LD (out_val),A POP AF LD A,D POP DE POP BC RET