1 ; I2C (TWI) master interface.
2 ; This is part of the Z80-CP/M emulator written by Sprite_tm.
4 ; Copyright (C) 2013 Leo C.
6 ; This file is part of avrcpm.
8 ; avrcpm is free software: you can redistribute it and/or modify it
9 ; under the terms of the GNU General Public License as published by
10 ; the Free Software Foundation, either version 3 of the License, or
11 ; (at your option) any later version.
13 ; avrcpm is distributed in the hope that it will be useful,
14 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ; GNU General Public License for more details.
18 ; You should have received a copy of the GNU General Public License
19 ; along with avrcpm. If not, see <http://www.gnu.org/licenses/>.
26 /* General TWI Master status codes */
27 #define TWI_START 0x08 /* START has been transmitted */
28 #define TWI_REP_START 0x10 /* Repeated START has been transmitted */
29 #define TWI_ARB_LOST 0x38 /* Arbitration lost */
31 /* TWI Master Transmitter status codes */
32 #define TWI_MTX_ADR_ACK 0x18 /* SLA+W has been transmitted and ACK received */
33 #define TWI_MTX_ADR_NACK 0x20 /* SLA+W has been transmitted and NACK received */
34 #define TWI_MTX_DATA_ACK 0x28 /* Data byte has been transmitted and ACK received */
35 #define TWI_MTX_DATA_NACK 0x30 /* Data byte has been transmitted and NACK received */
37 /* TWI Master Receiver status codes */
38 #define TWI_MRX_ADR_ACK 0x40 /* SLA+R has been transmitted and ACK received */
39 #define TWI_MRX_ADR_NACK 0x48 /* SLA+R has been transmitted and NACK received */
40 #define TWI_MRX_DATA_ACK 0x50 /* Data byte has been received and ACK transmitted */
41 #define TWI_MRX_DATA_NACK 0x58 /* Data byte has been received and NACK transmitted */
43 /* TWI Miscellaneous status codes */
44 #define TWI_NO_STATE 0xF8 /* No relevant state information available */
45 #define TWI_BUS_ERROR 0x00 /* Bus error due to an illegal START or STOP condition */
48 #define I2C_BR ((F_CPU / (2 * I2C_CLOCK)) - 8) /* I2C Bit Rate */
50 ;----------------------------------------------------------------------
52 ; TWINT: TWI Interrupt Flag
53 ; TWEA: TWI Enable Acknowledge Bit
54 ; TWSTA: TWI START Condition Bit
55 ; TWSTO: TWI STOP Condition Bit
56 ; TWEN: TWI Enable Bit
57 ; TWIE: TWI Interrupt Enable
59 ; (1<<TWEN)|(1<<TWIE)|(1<<TWINT)
60 ; (1<<TWEN)|(1<<TWIE)|(1<<TWINT)| (1<<TWEA)
61 ; (1<<TWEN)|(1<<TWIE)|(1<<TWINT)
64 ; (1<<TWEN)| (1<<TWINT)| (1<<TWSTO)
70 ; (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
71 ; (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
72 ; (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
73 ; (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
76 ; (1<<TWIE)|(1<<TWSTO)
78 ;----------------------------------------------------------------------
80 ;i2c_result < 0 Error.
81 ; -1 general/unknown error
86 ;----------------------------------------------------------------------
105 ;------------------------------------------------------------------
120 ldd temp2,z+oi2ci_idx
125 cpi temp,TWI_REP_START
127 cpi temp,TWI_MTX_ADR_ACK
128 breq i2ci_MTX_ADR_ACK
129 cpi temp,TWI_MTX_DATA_ACK
130 breq i2ci_MTX_DATA_ACK
131 cpi temp,TWI_MRX_ADR_ACK
132 breq i2ci_MRX_ADR_ACK
133 cpi temp,TWI_MRX_DATA_ACK
134 breq i2ci_MRX_DATA_ACK
135 cpi temp,TWI_MRX_DATA_NACK
136 breq i2ci_MRX_DATA_NACK
141 clr temp2 ;reset buffer pointer
144 ldd temp,z+oi2c_bufcnt
145 cp temp2,temp ;all bytes tranmited?
150 ldd temp,z+oi2c_buf ;next byte
152 ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)
156 std z+oi2c_result,_0 ;done
157 rjmp i2ci_default ;stop transceiver
170 ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)
173 ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)
177 std z+oi2c_result,_0 ;result = ok
185 ldi temp,(1<<TWEN)|(1<<TWINT)|(1<<TWSTO)
198 ;------------------------------------------------------------------
204 ldi temp,(1<<TWEN) ;Enable TWI, disable TWI interrupt.
210 ;------------------------------------------------------------------
215 sts delay_timer1,temp
218 andi temp,(1<<TWIE)|(1<<TWSTO)
220 lds temp,delay_timer1
230 ;------------------------------------------------------------------
232 ; z: Pointer to the data to write.
233 ; First byte is slave address
234 ; temp2: Number of bytes to write including address byte.
247 st x+,_255 ;result = not ok
248 st x+,temp2 ;store size
258 ; Enable TWI, TWI int and initiate start condition
259 ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
270 ;------------------------------------------------------------------
272 ; z: Pointer to data buffer.
273 ; First byte of buffer is slave address
274 ; temp2: Number of bytes to write including address byte.
276 ; temp: return (fail = 0, else succsess)
288 st x+,_255 ;result = not ok
289 st x+,temp2 ;store size
294 ; Enable TWI, TWI int and initiate start condition
295 ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
318 ;------------------------------------------------------------------
349 ;------------------------------------------------------------------
351 ; x: Pointer to the data buffer.
352 ; First byte is slave address
353 ; temp3: Number of bytes to write including address byte.
362 std z+oi2c_result,_255 ;result = not ok
364 std z+oi2c_bufcnt,temp3 ;store size
372 ; Enable TWI, TWI int and initiate start condition
373 ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
390 ;------------------------------------------------------------------
392 ; x: Pointer to the data to write.
393 ; First byte is slave address
394 ; temp2: Number of bytes to write including address byte.
402 std z+oi2c_result,_255 ;result = not ok
404 std z+oi2c_bufcnt,temp3 ;store size
416 ; Enable TWI, TWI int and initiate start condition
417 ldi temp,(1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
422 ;------------------------------------------------------------------
438 ;------------------------------------------------------------------
442 ; make a buffer on stack
443 push _255 ;place holder for input value
446 ldi temp,0x20 ;pcf8574 address (7 bit)
449 push temp ;slave address
452 pop temp ;remove slave address from stack
453 pop temp ;return input value
457 ; make a buffer on stack
458 push temp ;output value
461 ldi temp,0x20 ;pcf8574 address (7 bit)
464 push temp ;slave address
467 pop temp ;remove buffer from stack
472 #endif /* I2C_SUPPORT */
473 ;------------------------------------------------------------------
474 ; vim:set ts=8 noet nowrap