3 #include <avr/interrupt.h>
27 ST_ARBLOST_MATCH = 0x68,
29 ST_ARBLOST_GENMATCH = 0x78,
30 ST_SLAVE_RD_ACK = 0x80,
31 ST_SLAVE_RD_NACK = 0x88,
32 ST_SLAVE_GENRD_ACK = 0x90,
33 ST_SLAVE_GENRD_NACK = 0x98,
34 ST_SLAVE_STARTSTOP = 0xa0,
35 ST_SLAVE_SLA_WR_ACK = 0xa8,
36 ST_SLAVE_ARBLOST_WR_ACK = 0xb0,
37 ST_SLAVE_WR_ACK = 0xb8,
38 ST_SLAVE_WR_NACK = 0xc0,
39 ST_SLAVE_LAST_WR_ACK = 0xc8
51 #define TWINT_BIT (1 << TWINT)
52 #define TWEA_BIT (1 << TWEA)
53 #define TWSTA_BIT (1 << TWSTA)
54 #define TWSTO_BIT (1 << TWSTO)
55 #define TWEN_BIT (1 << TWEN)
56 #define TWIE_BIT (1 << TWIE)
58 #define I2C_START() (TWCR = TWINT_BIT | TWSTA_BIT | TWEN_BIT | TWIE_BIT)
59 #define I2C_STOP() (TWCR = TWINT_BIT | TWSTO_BIT | TWEN_BIT | TWIE_BIT)
60 #define I2C_WRITE() (TWCR = TWINT_BIT | TWEN_BIT | TWIE_BIT)
61 #define I2C_READ_ACK() (TWCR = TWINT_BIT | TWEA_BIT | TWEN_BIT | TWIE_BIT)
62 #define I2C_READ_NACK() (TWCR = TWINT_BIT | TWEN_BIT | TWIE_BIT)
64 static unsigned char i2c_addr, i2c_subaddr;
65 static volatile unsigned char i2c_mode;
66 static int i2c_seq, i2c_ndata;
67 static unsigned char *i2c_data;
69 static void (*async_func)(void);
73 TWBR = 10; /* 10 with 1x prescaler should make it about 100khz */
74 TWSR = 0; /* prescaler 1x */
77 TWCR = 0; /* I2C disabled by default */
83 void i2c_write(unsigned char addr, unsigned char subaddr, unsigned char *data, int ndata)
85 i2c_addr = addr & 0xfe;
86 i2c_subaddr = subaddr;
87 i2c_mode = I2C_MASTER_WRITE;
94 void i2c_read(unsigned char addr, unsigned char subaddr, unsigned char *buf, int size)
96 i2c_addr = addr & 0xfe;
97 i2c_subaddr = subaddr;
98 i2c_mode = I2C_MASTER_READ;
105 void i2c_handle_send(void)
107 unsigned char state = TWSR & 0xf8;
112 case ST_REP_START: /* 0x10 */
113 /* repeated start, same as start, but also increment i2c_seq */
115 case ST_START: /* 0x8 */
116 /* start initiated, write the slave address */
117 //printf("DBG i2c SLA: %x\n", (unsigned int)i2c_addr);
122 case ST_SLA_W_ACK: /* 0x18 */
123 /* slave addr sent and ACKed, send subaddr or data */
125 /* this is the first packet, send subaddr */
134 /* done sending, send stop */
141 case ST_SLA_W_NACK: /* 0x20 */
142 /* slave addr sent but not ACKed, abort */
145 printf("i2c: NACK after SLA+W\n");
148 case ST_WR_ACK: /* 0x28 */
149 /* data (or subaddr) sent and ACKed, send more data (or restart) if available */
152 /* subaddr was sent, send repeated start */
156 /* data was sent, send more data or stop */
167 case ST_WR_NACK: /* 0x30 */
168 /* data (or subaddr) sent but not ACKed */
170 /* NACK after subaddr, abort */
171 printf("i2c: NACK after subaddr\n");
173 /* NACK after data */
175 printf("i2c: NACK with %d pending\n", i2c_ndata);
182 case ST_ARBLOST: /* 0x38 */
183 /* arbitration lost */
184 printf("i2c: arb lost\n");
188 case ST_INVALID: /* 0 */
189 printf("i2c: invalid start/stop\n");
195 printf("i2c: unexpected state (W): 0x%x\n", state);
201 void i2c_handle_recv(void)
203 unsigned char state = TWSR & 0xf8;
208 case ST_START: /* 0x8 */
209 TWDR = i2c_addr; /* start a *write* (we need to send the subaddress before reading) */
213 case ST_REP_START: /* 0x10 */
214 /* repeated start, now we can issue the actual read */
219 case ST_SLA_W_ACK: /* 0x18 */
220 /* SLA+W means we just started the write part, need to send the subaddress */
226 /* slave addr sent but not ACKed, abort */
229 printf("i2c: NACK after SLA+W (R)\n");
232 case ST_WR_ACK: /* 0x28 */
233 /* the subaddress write was ACKed, rep-start to issue the read */
238 /* the subaddress write was not ACKed, abort */
241 printf("i2c: NACK after subaddr (R)\n");
244 case ST_SLA_R_ACK: /* 0x40 */
245 /* SLA+R was ACKed send ACK to start receiving */
249 case ST_RD_ACK: /* 0x50 */
250 /* ... or last read was ACKed, again read next and ACK for more */
252 if(--i2c_ndata > 0) {
259 case ST_SLA_R_NACK: /* 0x48 */
260 /* SLA+R was sent but ACK was not received, abort */
263 printf("i2c: NACK after SLA+R\n");
266 case ST_RD_NACK: /* 0x58 */
267 /* read without ACK, we get this after we send a NACK, or this is the last byte (?) */
276 case ST_ARBLOST: /* 0x38 */
277 /* arbitration lost */
278 printf("i2c: arb lost\n");
282 case ST_INVALID: /* 0 */
283 printf("i2c: invalid start/stop\n");
289 printf("i2c: unexpected state (R): 0x%x\n", state);
298 case I2C_MASTER_WRITE:
302 case I2C_MASTER_READ:
313 void i2c_async(void (*donecb)(void))
318 void i2c_check_async(void)
320 if(async_func && i2c_mode == I2C_IDLE) {
328 TWCR = 0; /* make sure the AVR i2c hardware is disabled */
329 DDRC = 0x20; /* ... and drive SCL pin low */
333 void i2c_release(void)
340 if(i2c_mode != I2C_IDLE) {