; I2C (TWI) master interface.
; This is part of the Z80-CP/M emulator written by Sprite_tm.
;
-; Copyright (C) 2010 Leo C.
+; Copyright (C) 2013 Leo C.
;
; This file is part of avrcpm.
;
; $Id$
;
-#if I2C
+#if I2C_SUPPORT
/* General TWI Master status codes */
#define TWI_START 0x08 /* START has been transmitted */
;
; wait ready:
; (1<<TWIE)|(1<<TWSTO)
-;
+;
+;----------------------------------------------------------------------
+;
+;i2c_result < 0 Error.
+; -1 general/unknown error
+; -2 time out
+; >= 0 No error
+; > 0 status tbd.
+;
;----------------------------------------------------------------------
.dseg
ldd temp2,z+oi2ci_idx
inm8 temp,TWSR
-
cpi temp,TWI_START
breq i2ci_START
cpi temp,TWI_REP_START
i2ci_MTX_ADR_ACK:
i2ci_MTX_DATA_ACK:
ldd temp,z+oi2c_bufcnt
- cp temp2,temp
- brsh i2ci_12
+ cp temp2,temp ;all bytes tranmited?
+ brsh i2ci_12 ; yes
add zl,temp2
adc zh,_0
inc temp2
- ldd temp,z+oi2c_buf
+ ldd temp,z+oi2c_buf ;next byte
outm8 TWDR,temp
ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)
rjmp i2ci_end
i2ci_12:
- std z+oi2c_result,_255
- rjmp i2ci_default
+ std z+oi2c_result,_0 ;done
+ rjmp i2ci_default ;stop transceiver
i2ci_MRX_DATA_ACK:
add zl,temp2
rjmp i2ci_end
i2ci_MRX_DATA_NACK:
- std z+oi2c_result,_255 ;result = 1
+ std z+oi2c_result,_0 ;result = ok
add zl,temp2
adc zh,_0
inm8 temp,TWDR
ldi temp,I2C_BR
outm8 TWBR,temp
outm8 TWDR,_255 ;
- ldi temp,(1<<TWEN) ;Enable TWI, disable Interupts.
+ ldi temp,(1<<TWEN) ;Enable TWI, disable TWI interrupt.
outm8 TWCR,temp
- ldi temp,1
- sts i2c_result,temp
+ sts i2c_result,_0
ret
;------------------------------------------------------------------
i2c_waitready:
- push temp
-i2c_b:
+
+ ldi temp,30
+ sts delay_timer1,temp
+i2c_wrl:
inm8 temp,TWCR
andi temp,(1<<TWIE)|(1<<TWSTO)
- brne i2c_b
- pop temp
+ breq i2c_wre
+ lds temp,delay_timer1
+ tst temp
+ brne i2c_wrl
+
+ ldi temp,-2
+ sts i2c_result,temp
+i2c_wre:
+ tst temp
ret
;------------------------------------------------------------------
;
i2c_write:
- rcall i2c_waitready
+ rcall i2c_waitready
+ brmi i2c_we
push zh
push zl
push xh
push xl
-#if 0
- rcall printstr
- .db '\r', 'W', 0,0
- mov temp,temp2
- rcall printhex
- rcall printstr
- .db ": ", 0,0
- rcall dbg_hexdump_line
-#endif
-
ldiw x,i2c_result
- st x+,_0 ;result = 0
+ st x+,_255 ;result = not ok
st x+,temp2 ;store size
ld temp,z+
cbr temp,0x01
pop xh
pop zl
pop zh
+i2c_we:
ret
; temp: return (fail = 0, else succsess)
i2c_read:
+
rcall i2c_waitready
+ brmi i2c_re
push zh
push zl
push xh
push xl
ldiw x,i2c_result
- st x+,_0 ;result = 0
+ st x+,_255 ;result = not ok
st x+,temp2 ;store size
ld temp,z
sbr temp,0x01
rcall i2c_waitready
-#if 0
- rcall printstr
- .db '\r', 'R', 0,0
- mov temp,temp2
- rcall printhex
- rcall printstr
- .db ": ", 0,0
-#endif
-
lds temp,i2c_result
- tst temp
- breq i2c_ex ;
+ sbrc temp,7
+ rjmp i2c_ex ;
i2c_rl:
ld temp,x+
st z+,temp
brne i2c_rl
i2c_ex:
- lds temp,i2c_result
pop xl
pop xh
pop zl
pop zh
-#if 0
- rcall dbg_hexdump_line
-#endif
+i2c_re:
+ lds temp,i2c_result
ret
;------------------------------------------------------------------
.cseg
vi2c_stat_get:
- lds temp,vi2c_stat
+ lds temp,i2c_result
ret
vi2c_param_get:
;
vi2c_read:
+
rcall i2c_waitready
+ brmi vi2c_rex
ldiw z,i2c_var
- std z+oi2c_result,_0 ;result = 0
+ std z+oi2c_result,_255 ;result = not ok
lds temp3,vi2c_blen
std z+oi2c_bufcnt,temp3 ;store size
adiw z,oi2c_buf
rcall i2c_waitready
lds temp,i2c_result
- tst temp
- breq vi2c_ex ;
+ sbrc temp,7
+ rjmp vi2c_rex ;
vi2c_rl:
ld temp,z+
lcall dram_write_pp
dec temp3
brne vi2c_rl
-vi2c_ex:
+vi2c_rex:
ret
;------------------------------------------------------------------
;
vi2c_write:
+
rcall i2c_waitready
+ brmi vi2c_wex
ldiw z,i2c_var
- std z+oi2c_result,_0 ;result = 0
+ std z+oi2c_result,_255 ;result = not ok
lds temp3,vi2c_blen
std z+oi2c_bufcnt,temp3 ;store size
adiw z,oi2c_buf
; Enable TWI, TWI int and initiate start condition
ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
outm8 TWCR,temp
-
+vi2c_wex:
ret
+;------------------------------------------------------------------
+
vi2c_ctrl:
cpi temp,1
brne vi2c_c1
- rcall vi2c_read
- rjmp vi2c_ce0
+ rjmp vi2c_read
+
vi2c_c1:
cpi temp,2
- breq vi2c_c2
- ldi temp,0xff
- rjmp vi2c_ce
+ brne vi2c_c2
+ rjmp vi2c_write
vi2c_c2:
- rcall vi2c_write
-vi2c_ce0:
- lds temp,i2c_result
- com temp
vi2c_ce:
- sts vi2c_stat,temp
ret
;------------------------------------------------------------------
ret
-#endif /* I2C */
+#endif /* I2C_SUPPORT */
;------------------------------------------------------------------
; vim:set ts=8 noet nowrap