
;----------------------------------------------------------------------------
;                            macro i2c bus  master
;----------------------------------------------------------------------------
	
;-------------------------------------------------------------------------
;microsec       funzione: attesa in loop
;               ripete (op1 volte ciclo di 9,75 micsec) + 6,5 micsec
;-------------------------------------------------------------------------

	.macro microsec op1,?micro_1
	
	down
	ldi macro,op1           ;esterno 6,5 micsec
micro_1
	dec     macro           ;ciclo =9,75 micsec
	jrnz    micro_1
	.endm

;-------------------------------------------------------------------------
; sda_hight     setta SDA                     
;------------------------------------------------------------------------
	.macro  sda_high
	ld      macro,a
	set     SDA,bk_pc                       ; SDA =1 su portac
	ld      a,bk_pc     
	ld      drc,a
	ld      a,macro
	.endm

;-------------------------------------------------------------------------
; sda_low     resetta SDA                     
;------------------------------------------------------------------------
	.macro  sda_low
	ld      macro,a
	res     SDA,bk_pc       ;SDA  =0 su porta c
	ld      a,bk_pc     
	ld      drc,a
	ld      a,macro
	.endm

;-------------------------------------------------------------------------
; sda_test      funzione: test SDA prima di comunicare
;               SDA invariato se=0 attende
;                             se=1 prosegue
; NB: nel ciclo viene ricaricato il watchdog
;-------------------------------------------------------------------------
	.macro sda_test ?sda_te1
	
	res     SDA,ddrc        ;sda =0-0-0=in test SDA prima di sda_te1
sda_te1 
	down
	jrr     SDA,drc,sda_te1 ;se SDA=0 wait
	set SDA,ddrc
	.endm

;-------------------------------------------------------------------------
; scl_hight     setta SCL                     
;------------------------------------------------------------------------
	.macro  scl_high
	ld      macro,a
	set     SCL,bk_pc                       ;SCL  =1 su porta c
	ld      a,bk_pc     
	ld      drc,a
	ld      a,macro
	.endm

;-------------------------------------------------------------------------
; scl_low      resetta SCL                     
;------------------------------------------------------------------------
	.macro  scl_low
	ld      macro,a
	res     SCL,bk_pc                       ;SCL  =0 su porta c
	ld      a,bk_pc     
	ld      drc,a
	ld      a,macro
	.endm




;___________________________________________________________________________
;                  I2C BUS   MASTER
;___________________________________________________________________________
; NOTE : - 12c_wrim routine per master per scrittura su slave
;          nell'indirizzo di slave viene dalla routine resettato RDWR
;          
;        - i2c_rem routine per master per lettura da slave
;          nell'indirizzo di slave viene dalla routine settato RDWR
;
;        - se si vuole realizzare un combined format nel programma
;       principale si deve chiamare prima 12c_wrim e relativi dati per
;       scrivere su slave (es. indirizzo memoria) e poi i2c_rem e
;       relativi dati per leggere da slave
;       - il master dopo la sequenza di START, che determina (se sono st6) 
;       negli slave la richiesta di int.portc, testa la linea SDA
;       se SDA =1 master procede con invio address
;       se SDA =0 master attende slave che disimpegni SDA???che per effetto
;       del pullup esterno va a 1
;       master attende quindi fino a che lo slave pi— lento non ha liberato
;       SDA
;===========================================================================





;------------------------------------------------------------------------------
;i2c_wrim: routine scrittura master
;       scrive bytecount bytes attraverso 12cbus sulla periferica di
;       indirizzo y partendo a leggere i dati da inviare da locazione
;       x se si verifica ACK error viene ritentata la comunicazione TRY
;       volte. Esauriti i tentativi ret.
;       bit 0 di indirizzo perifarica viene resettato (0=WRITE)
;
;sequenza: START - TEST SDA???(SCL) - ADDRESS - ACK (slave) - (attesa slave) -
;       - DATA BYTES - ACK (slave) - n BYTES - n ACK (slave) - STOP
;
;all'inizio:    x deve contenere locazione del 1øbyte da trasmettere da tx
;               y deve contenere l'indirizzo della periferica chiamata
;               bytecount deve contenere numero di bytes da inviare                   
;
;               SDA = 1-0-0  SCL = 1-0-0
;nella rout.:   stack3 conterr… il byte data trattato
;       w conterr… numero bytes da inviare
;       y conterr… numero bit da inviare (usato in write)
;       error conterr… bit ACK_ERR corrispondente a errore ack (wr_ack)
;       stack 4 conterr… TRY (numero tentativi in caso di ack error)
;       stack 2 conterr… copia backup byte in trasmissione
;alla fine:     SDA 1-0-0
;               SCL 1-0-0
;------------------------------------------------------------------------------
i2c_wrim   
	down
	sda_high

	ld a,x
	ld stack2,a     ;backup indirizzo di partenza
	ld a,bytecount
	ld w,a          ;backup numero bytes
	ldi stack4,TRY  ;in stack2??? numero tentativi in caso di errore ack
try_w
	res ACK_ERR,flag          ;toglie condizione di errore
	ld      a,stack2
	ld      x,a             ;in x indirizzo salvato
	ld      a,bytecount
	ld      w,a             ;carica in w numero bytes
	down

;-------------------------------------------------------
;       CONDIZIONE DI START
;-------------------------------------------------------

	scl_high                ;SCL = 1 (1-0-1)
	sda_low                 ;SDA = 0 (1-0-0)
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	scl_low                 ;SCL = 0 (1-0-0)
	microsec 4              ;macro ritardo 4*9,5+ 6,5=44,4 micsec
				;ritardo per routine slave

	sda_test                
				;testa come input SCL se=0 attende
				;se =1 prosegue SDA SCL invariati
				;NO se scl=input va alto in pull-up
				;e legge wait
;-------------------------------------------------------
; trasmette byte corrispondente a indirizzo periferica
;-------------------------------------------------------

	res     RDWR,y          ;bit RDWR=0 = scrittura su periferica
	ld      a,y
	ld      stack3,a        ;in stack3 byte(indirizzo) da inviare
	call    write
	microsec 10             ;attende elaborazione slave 10*9,5+6,5=101,5
				;?????? only for slave? ????????
	call    wr_ack
	jrr     ACK_ERR,flag,i2c_wri1 ;ack=ok salta
	dec     stack4          ;gestione ack error dopo TRY tentativi
	jrnz    i2c_wri2
	jp      i2c_wri5        ;trasmetti stop ed esci
	;ret             ;abbandona
i2c_wri2
	jp      try_w
i2c_wri1

;-------------------------------------------------------
;send data
;-------------------------------------------------------


sndloop:
	down
	ld      a,(x)
	ld      stack3,a                ;in stack3 dato da inviare
	call    write
	call    wr_ack

	jrr     ACK_ERR,flag,i2c_wri3  ;ack=ok salta
	dec     stack4          ;gestione error dopo TRY tentativi
	jrnz    i2c_wri4                
	ret                     ;abbandona se esauriti nø TRY tentativi
i2c_wri4
	jp      try_w           ;riprova
i2c_wri3
	inc     x               ;indirizzo nuovo byte
	dec     w               ;nø bytes da trasmettere
	jrz    i2c_wri5
	jp      sndloop
i2c_wri5

;-------------------------------------------------------
;condizione di stop
;-------------------------------------------------------

	sda_low         ;sda =1-0-0
	nop
	nop
	nop
	scl_high        ;scl =1-0-1
	nop
	nop
	nop
	sda_high        ;sda =1-0-1
	nop
	nop
	nop
	scl_low         ;scl =1-0-0
	nop
	nop
	nop
	sda_low         ;sda =1-0-0
	nop
	nop
	nop
	ret             ;end of i2c_wri1 routine




;-------------------------------------------------------
;i2c_rem:       routine in master per leggere da slave
;               legge byterx bytes attraverso i2cbus sulla periferica di
;               indirizzi y salvando nel master i dati letti iniziando
;               da locazione x
;               se si verifica ack error viene ritentata la comunicazione
;               ripartendo da capo recuperando i dati di partenza salvati per
;               try volte. Esauriti i tentativi ret.
;               bit 0 di indirizzo periferica viene settato (1=write)
;
;sequenza:      START - TEST SDA - ADDRESS - ACK(slave) - (attesa slave) -
;               - DATA BYTES (slave) - ACK (master) n BYTES (slave) - 
;               ACK (master) - STOP
;nota:  master quando legge da slave riceve bytes e trsmette ACK,
;       l'ultimo byte trasmesso da master ci• serve al master per comunicare
;       a slave che ha finito di leggere e che seguir… solo STOP.
;       Nel caso di comunicazione con NS st6 la situazione viene prodotta ma
;       non utilizzata in quanto sia master che slave sanno il Nø dei
;       bytes (byterx) trattati.
;all'inizio:    x deve contenere indirizzo locazione in master dove salvare il
;               1ø byte ricevuto dallo slave
;               y deve contenere l'indirizzo della periferica chiamata
;               byterx deve conteere numero bytes da ricevere
;               SDA = 1-0-0
;               SCL = 1-0-0
;nella rout.:   stack3 conterr… il byte data trattato
;               w conterr… numero bytes da ricevere
;               v conterr… numero bit da ricevere (usato in write)
;               error conterr… bit ACK_ERR corrispondent a errore acl (wr_ack)
;               stack4 conterr… TRy (numero tentativi in caso di ack error)
;               stack2 conterr… copia backup byte in trasmissione
;alla fine:
;               SDA = 1-0-0
;               SCL = 1-0-0
;-------------------------------------------------------
i2c_rem
	down
	sda_high                ;sda =1 (1-0-1)
	ld      a,x
	ld      stack2,a        ;backup indirizzo di partenza
	ld      a,byterx
	ld      w,a             ;backup numero bytes
	ldi     stack4,TRY      ;in tsack2 numero tentativi possibili
try_w1
	res     ACK_ERR,flag   ;toglie condizione di errore
	ld      a,stack2
	ld      x,a             ;carica in x indirizzo salvato
	ld      a,byterx
	ld      w,a             ;carica in w numero bytes

	down

;-------------------------------------------------------
;       CONDIZIONE DI START
;-------------------------------------------------------

	scl_high                ;SCL = 1 (1-0-1)
	sda_low                 ;SDA = 0 (1-0-0)
	scl_low                 ;SCL = 0 (1-0-0)
	microsec 4              ;macro ritardo 4*9,5+ 6,5=44,4 micsec
				;ritardo per routine slave
				;?? only slave? ????????????????
	sda_test                
				;testa come input SCL se=0 attende
				;se =1 prosegue SDA SCL invariati
				;NO se scl=input va alto in pull-up
				;e legge wait

;-------------------------------------------------------
; trasmette byte corrispondente a indirizzo periferica
;-------------------------------------------------------

	set     RDWR,y          ;bit RDWR=1 = lettura da periferica
	ld      a,y
	ld      stack3,a        ;in stack3 byte(indirizzo) da inviare
	call    write
	microsec 10             ;attende elaborazione slave 10*9,5+6,5=101,5
	call    wr_ack
	jrr     ACK_ERR,flag,i2c_rem1 ;ack=ok salta
	dec     stack4          ;gestione ack error dopo TRY tentativi
	jrnz     i2c_rem2
	jp      rx_end          ;trasmetti stop ed esci
	;ret             ;abbandona
i2c_rem2
	jp      try_w1  ;??????????? o try_w???
i2c_rem1
;-----------------------------------------
;SDA = input
;-----------------------------------------
	res     SDA,ddrc                ;SDA = 0-0-1 = input
	microsec 2              ;ritardo 2*9,5+6,5=25,5micsec
				;serve per rout.int. slave
;----------------------------------------
;lettura byte da slave
;-----------------------------------------------------
rx_loop
	call    read            ;legge byte da periferica
	ld      a,stack3        ;carica nella locazione
	ld      (x),a           ;puntata da x il byte
	inc     x               ;ricevuto
	call    rd_ack          ;genera master ack
	dec     byterx       ;conta bytes da rx
	jrz     rx_end          ;se ultimo byte, esci
	jp      rx_loop
rx_end

;--------------------------------------------
;condizione di stop
;--------------------------------------------
	sda_low                 ;SDA =0-0-0
	nop
	nop
	nop
	set     SDA,ddrc        ;SDA =1-0-0 out
	nop
	nop
	nop
	scl_high                ;SCL =1-0-1
	nop
	nop
	nop
	sda_high                ;SDA =1-0-1
	nop
	nop
	nop
	scl_low                 ;SCL =1-0-0
	nop
	nop
	nop
	sda_low                 ;SDA =1-0-0
	nop
	nop
	nop
	ret                     ;end of i2c_rem routine

;---------------------------------------------------------
;write: trasmette byte su linea SDA i2c bus
;all'inizio;    stack3 contiene byte da scrivere
;               SDA =1-0-0 = out = 0
;               SCL =1-0-0 = out = 0
;alla fine:     v conterr… NUMBITS cioŠ numero bit da inviare
;               SDA = 1-0-ultimo bit trasmesso
;               SCL = 1-0-0
;---------------------------------------------------------

write
	down
	ldi     v,NUMBITS
wr_loop
	ld      a,stack3        ;for v times...
	rlc     a
	ld      stack3,a        ;next bit into carry flag
	jrnc    wr_0            ;se bit=0 write 0
wr_1                            ;altrimenti write 1
	set     SDA,bk_pc
	jp      wr_snd
wr_0
	res     SDA,bk_pc
wr_snd                          ;send out bit
	ld      a,bk_pc
	ld      drc,a           ;in uscita dato SDA=bit
	scl_high                ;SCL=1
				;durata clock 19,5
	scl_low                 ;SCL=0
	dec     v
	jrz     wr_end          
	jp      wr_loop
wr_end
	ret


;--------------------------------------------------------------
;wr_ack: come master verifica se da parte della periferica viene generato ack
;        invia impulso di clock relativo
;        se si verifica errore di ack viene settato ACK_ERR di error
;alla fine:     error conterr… eventuale errore di ack
;               SDA = 1-0-1
;               SCL = 1-0-0
;---------------------------------------------------------------
wr_ack
	sda_high                ;SDA=1 (1-0-1)
	res     SDA,ddrc        ;SDA = 0-0-1 in
	scl_high                ;scl = 1 (1-0-1)
	jrs     SDA,drc,wr_fail ;se SDA =1 allora error
	jp      end_wr
wr_fail
	set     ACK_ERR,flag 
end_wr
	scl_low                 ;scl=0 (1-0-0)
	set     SDA,ddrc        ;SDA = 1-0-1 = output
	ret


;---------------------------------------------------------
;read:  riceve byte su linea SDA i2c bus
;       salva byte ricevuto in locazione puntata da x
;all'inizio
;       SDA = 0-0-1 in
;       SCL = 1-0-0 out
;       v conterr… NUMBITS cioŠ numero bit da inviare
;alla fine:     stack3 conterr… byte trasmesso
;       SDA = 0-0-ultimo bit trasmesso
;       SCL = 1-0-0 out
;---------------------------------------------------------
read
	down
	ldi     v,NUMBITS
	clr     stack3          ;stack3 conterr… data
rd_loop                         ;per v volte
	ld      a,stack3        ;get leastest result
	rlc     a               ;shift input bits
	ld      stack3,a        ;salva dato
	microsec 2              ;ritardo 2*9,5+6,5=25,5 micsec
				;serve per rout. int. slave
	scl_high                ;SCL = 1 (1-0-1)
	jrs     SDA,drc,rd_1    ;test SDA
rd_0
	res     0,stack3        ;input was 0 clr bit
	jp      rd_next
rd_1
	set     0,stack3        ;input was one, set bit
rd_next
	scl_low                 ;SCL=0 (1-0-0)
	dec     v               ;conta bits
	jrz     rd_end          ;dopo 8 esce
	jp      rd_loop
rd_end
	ret

;---------------------------------------------------------
;rd_ack: come master genera un master ack su SDA e relativo clock su SCL
;       alla fine dell'ultimo byte ricevuto dallo slave il master non
;       invier… il relativo ack (SDA rimane=1) ci• per avvisare lo slave
;       della fine della comunicazione in modo tale che lo slave possa
;       liberare SDA per consentire al master l'invio dello stop NO
;
;all'inizio:    SDA =0-0(1oppure ultimo bit trasmesso da slave) in
;               SCL =1-0-0 out
;alla fine
;               SDA = 0-0-0 = in
;               SCL = 1-0-0 = out
;---------------------------------------------------------
rd_ack
	set     SDA,ddrc        ;SDA = 1-0-1 output
	sda_low                 ;SDA = 1-0-0 acknowledge bit is zero
	scl_high                ;SCL = 1-0-1
	scl_low                 ;SCL = 1-0-0
end_rd
	res     SDA,ddrc        ;SDA = 0-0-0 input
	ret                     ;end of read_acknowledge

;----------------------- END OF I2C BUS MASTER -----------------------------




;----------------------------------------------------------------------------
; macro i2c bus slave
;----------------------------------------------------------------------------
;------------------------------------------------------------------------
; wait_r_e       ;attende rising edge su SCK
;------------------------------------------------------------------------
	.macro  wait_r_e ?wait_re       ;attende rising edge su SCK
wait_re        
	down
	jrr     SCK,drc,wait_re         ;$       
	.endm
;------------------------------------------------------------------------
; wait_f_e       ;attende falling edge su SCK
;------------------------------------------------------------------------
	.macro  wait_f_e ?wait_fe       ;attende falling edge su SCK
wait_fe        
	down
	jrs     SCK,drc,wait_fe         ;$         
	.endm
;------------------------------------------------------------------------
; sda_hight     setta SDA                     
;------------------------------------------------------------------------
	.macro  sda_high
	ld      macro,a
	set     SDA,bk_pc               ; SDA =1 su portac
	ld      a,bk_pc     
	ld      drc,a
	ld      a,macro
	.endm
;------------------------------------------------------------------------
; sda_low     resetta SDA                     
;------------------------------------------------------------------------
	.macro  sda_low
	ld      macro,a
	res     SDA,bk_pc               ;SDA  =0 su porta c
	ld      a,bk_pc     
	ld      drc,a
	ld      a,macro
	.endm
;------------------------------------------------------------------------
; sck_hight     setta SCK                     
;------------------------------------------------------------------------
	.macro  sck_high
	ld      macro,a
	set     SCK,bk_pc               ;SCK  =1 su porta c
	ld      a,bk_pc     
	ld      drc,a
	ld      a,macro
	.endm
;------------------------------------------------------------------------
; sck_low      resetta SCK                     
;------------------------------------------------------------------------
	.macro  sck_low
	ld      macro,a
	res     SCK,bk_pc               ;SCK  =0 su porta c
	ld      a,bk_pc     
	ld      drc,a
	ld      a,macro
	.endm
;------------------------------------------------------------------------
;sby_mast                          ;pone master in sby 45,5 micsec
;------------------------------------------------------------------------
	.macro sby_mast                 ;pone master in sby 45,5 micsec
	ld      macro,a
	set      SDA,ddrc               ;SDA come out      |  SDA=  1      
	res     SDA,orc                 ;                  |        0
	res     SDA,bk_pc               ;SDA =0 su porta c |        0
	ld      a,bk_pc                 ;drc gia'=0?       | out-open-col=0
	ld      drc,a                   ;                  |
	ld      a,macro
	.endm
;------------------------------------------------------------------------
; go_mast       SDA= input         ; master puo' partire
;------------------------------------------------------------------------
	.macro  go_mast                 ; master puo' partire
	res     SDA,ddrc                ;SDA come input no pull-up          
	.endm


;___________________________________________________________________________
;                  I2C BUS   SLAVE
;___________________________________________________________________________
; NOTE : - con interrupt viene intercettato START e messo master in sby
;          tenendo SDA a 0 . Master aspettera' che SDA vada a 1
;          va testato bit START di flag nel main x sapere se master chiama
;        - viene confrontato indirizzo periferica (se errato esce) e
;          deciso (con i 2 indirizzi che si differenziano solo x RDWR)
;          se master vuole scrivere o leggere  da slave.   
;                                                                 
;        _ se scrive master genera SCK e SDA e slave genera ack
;        - se legge  master genera SCK e ack e slave genera SDA              
;          in questo caso quando master richiede l'ultimo byte allo slave  non
;          generera' il relativo ack e lo slave sapra' cosi' che seguira' lo stop
;          (verra' settato STOP di flag a significare attesa di stop)
;          in questo caso non usato xche' contando i bytes si sa quando stop
;
;===========================================================================

;------------------------------------------------------------------------------
;rdst_i2c : Legge stringa in i2c bus confronta address periferica verifica
;           se master vuole leggere o scrivere
;           Memorizza il byte trattato stack3                      
;           flag  memorizza richieste
;                                  
;           v contatore bit (in rdbt_i2c)
;           x locazione memoria puntata  all'inizio deve puntare Iøreg rx o tx
;           bytecount numero bytes da rx o tx                          
;       NB: Chiamare questa funzione subito dopo aver intercettato una
;           start_sequence nel main_program
;
;da int. (sby_mast) SDA = 1-0-0  SCK = 0-0-0
;------------------------------------------------------------------------------
rdst_i2c   
	ldi     ior,00h                 ;interrupt tutti off
	res     START,flag              ;START eseguito elimina richiesta start
	go_mast                         ;master puo' proseguire SDA=0-0-0
	call    rdbt_i2c                ;Legge 1ø byte  in a      byte
	ld      stack3,a                ;backup byte letto
	cpi     a,SLAVE_AW              ;slave address scrittura?
	jrnz    rdst_i0                 ;se no esci
	jp      sla_rx                  ;master chiede di scrivere in slave
rdst_i0 
	
	ld      a,stack3
	cpi     a,SLAVE_AR              ;slave address lettura?
	jrz     sla_tx                  ;master chiede leggere da slave
	jp      rdst_i3                 ;se non corrispondono gli indirizzi esce
;----------------------------------------------------------------------------
; master legge da slave       (slave = tx)
;---------------------------------------------------------------------------


sla_tx  
	ldi     bytecount,NUMBYTET      ;numero bytes tx
	ldi     x,PRI_TXI2              ;punta Iø reg da trasmettere
	
	call    ack_wr                  ;se si' dai conferma al master con ack
			
lp_sltx
	ldi     drbr,10h               ;RAM pag.2
	ld      a,(x)                   ;byte da tx
	ld      stack3,a                ;
	call    write_sl                ;trasmetti byte
	call    ack_sl                  ;genera ack
	inc     x                       ;                         
	dec     bytecount               ;conta bytes
	jrnz    lp_sltx
	
	jp      rdst_i4                 ; se finiti attendi stop 
	       

;----------------------------------------------------------------------------
; master scrive su slave           (slave = rx)
;---------------------------------------------------------------------------


sla_rx  
	ldi     bytecount,NUMBYTER      ;numero bytes rx
	ldi     x,PRI_RXI2              ;punta locazione dove salvare Iøbyte rx
	call    ack_wr                  ;se si' dai conferma al master con ack
lp_str
	call    rdbt_i2c                ;Leggi byte in a byte
	ldi     drbr,10h               ;RAM pag.2
	ld      (x),a                   ;x = locazione Iø byte    rx 
	call    ack_wr                  ;genera ack
	inc     x                       ;                         
	dec     bytecount               ;conta bytes
	jrz     rdst_i4
	jp      lp_str

;--------------------------------------------------------------------------
; attesa stop
;-------------------------------------------------------------------------

rdst_i4
	down
	wait_r_e                        ;Attende fronte di salita di SCK |
	jrr     SDA,drc,rdst_i4         ;attende "      "    "    "  SDA | stop
	
;---------------------------------------------------------------------------
; uscita 
;---------------------------------------------------------------------------

rdst_i3
			     
;--------------------------------------------------------------------------
;ripristino porta c
;------------------------------------------------------------------------
	res     SDA,ddrc        ;  0
	set     SDA,orc         ;  1     in interrupt
	res     SDA,bk_pc       ;  0
	
	res     SCK,ddrc        ;  0
	res     SCK,orc         ;  0      in con pull-up
	res     SCK,bk_pc       ;  0
	
	ld      a,bk_pc         ;
	ld      drc,a           ;
;---------------------------------------------------------------------------
	ldi     ior,10h               ;Pronto ad intercettare start_sequence
	res     STOP,flag
	res     START,flag         ;
	ret

;=============================================================================
;------------------------------------------------------------------------------
;rdbt_i2c : Legge byte in IIC bus
;           inizio SDA=0-0-0   SCK=0-0-0
;           fine SDA - SCK invariati solo lettura
;           a              conterra' il byte ricevuto
;           v  contatore bit
;------------------------------------------------------------------------------
rdbt_i2c    
	ldi     v,NUMBITS
rdbt_i2          
	sla     a                       ; da r.ed. di master a lettura 26mics
	wait_r_e                        ;Attende fronte di salita di SCK
	jrr     SDA,drc,rdbt_i1         ;a.LSB=SDA
			  
	set     0,a                     ;
rdbt_i1 
	wait_f_e                        ;Attende fronte di discesa di SCK
	dec     v
	jrz     rdbt_i0         
	jp      rdbt_i2
rdbt_i0   
	ret



;------------------------------------------------------------------------------
;       Funzione: genera ACKnowledge per il master
;
;       inizio   SDA =0-0-0  SCK=0-0-0
;       fine     SDA =0-0-0  SCK=0-0-0
;
;------------------------------------------------------------------------------
ack_wr    
	set     SDA,ddrc                 ;SDA =1-0-0 = out               
	wait_r_e                        ;Attende fronte di salita di SCK
	wait_f_e                        ;Attende fronte di discesa di SCK
	res     SDA,ddrc                 ;SDA = 0-0-0 = input           
					;
	ret





;--------------------------------------------------------------------------
;write_sl : come slave trasmette byte su linea SDA i2c bus
;           SCK generato da master
;all'inizio  stack3 contiene byte da scrivere
;durante     SDA = out = dato
;            SCK = in       
;            v conterra' NUMBITS cioe' numero bit da inviare
;alla fine   SDA = 0-0-ultimo bit       
;            SCK = 0-0-0
;----------------------------------------------------------------------------  
write_sl
	ldi     v,NUMBITS   
	set     SDA,ddrc                   ;SDA =1-0-0 =out
wr_loop:                                        ;for "v" times...
	ld      a,stack3
	rlc     a                           ; next bit into carry flag
	ld      stack3,a
	jrnc    wr_0                       ;if bit is 0, write_0
wr_1:                                         ;else write_1
	set     SDA,bk_pc   
	jp      wr_snd
wr_0:
	res     SDA,bk_pc   
wr_snd:                                   ;now send out bit
	ld      a,bk_pc     
	ld      drc,a                     ;in uscita il dato  SDA=bit
	
	wait_r_e                        ;Attende fronte di salita
	wait_f_e                        ;Attende fronte di discesa c'era un;
	
	dec     v      
	jrz     wr_end                    ;tutti bits tx allora out     
	jp      wr_loop                   ;next bit

wr_end:
	res     SDA,ddrc                   ;SDA =0-0-ultimo bit = input
	
	ret
;---------------------------------------------------------------------------
;ack_sl: come slave  verifica se da parte del  master      viene generato ack
;        riceve impulso di clock relativo
;        se si verifica ack = 1 = ultimo byte trasmesso (ora non serve)
;        SDA - SCK invariati solo lettura
;alla fine                                          
;                    
;                      
;---------------------------------------------------------------------------
ack_sl
	wait_r_e                        ;Attende fronte di salita di SCK
					;
	jrr     SDA,drc,ack_sl1         ;ack = 0 = ok
	set     STOP,flag               ;richiesta stop se ultimo byte tx
ack_sl1 
	ret


;fine copia ??????????????????????????????????
;___________________________________________________________________________        
;                      FINE I2C BUS
;---------------------------------------------------------------------------        

