#include #include #include "atm_i2c.h" /* #define PORTC_LED1 0x60 // led 1 #define PORTC_LED2 0x80 // led 2 void toggle_led1(void) { if (PORTC & PORTC_LED1) { PORTC &= ~(PORTC_LED1); } else { PORTC |= (PORTC_LED1); } } void toggle_led2(void) { if (PORTC & PORTC_LED2) { PORTC &= ~(PORTC_LED2); } else { PORTC |= (PORTC_LED2); } } */ static char TWI_state = TWI_IDLE; static char TWI_recv_buf[TWI_RECV_BUFSIZE]; static char TWI_recv_index = 0; static char TWI_send_buf[TWI_SEND_BUFSIZE]; static char TWI_send_index = 0; static char TWI_send_length = 0; /* static inline void TWI_slave_rx(char *buf, char length) { } int count1 = 0; int count2 = 0; static inline char TWI_slave_tx(char *buf, char length) { count1++; count2--; buf[0] = count1 >> 8; buf[1] = count1 & 0xFF; buf[2] = count2 >> 8; buf[3] = count2 & 0xFF; return 4; } */ int twi_parse(void) { switch (TWSR & TWSR_STATUS_MASK) { /* MASTER TRANSMIT MODE */ /* MASTER RECEIVE MODE */ /* SLAVE RECEIVE MODE */ case TWSR_SR_SLA_ACK: case TWSR_SR_SLA_ARB_ACK: case TWSR_SR_GCA_ACK: case TWSR_SR_GCA_ARB_ACK: PORTC = PORTC ^ 0x80; //toggle LED2 on read TWI_state = TWI_SLAVE_RX; TWI_recv_index = 0; TWCR = (TWCR & TWCR_CMD_MASK) | TWCR_TWEA; break; case TWSR_SR_SLA_DATA_ACK: case TWSR_SR_GCA_DATA_ACK: TWI_recv_buf[TWI_recv_index++] = TWDR; if (TWI_recv_index < TWI_RECV_BUFSIZE) TWCR = (TWCR & TWCR_CMD_MASK) | TWCR_TWEA; else TWCR = (TWCR & TWCR_CMD_MASK); break; case TWSR_SR_SLA_DATA_NAK: case TWSR_SR_GCA_DATA_NAK: TWCR = (TWCR & TWCR_CMD_MASK); break; case TWSR_SR_STOP: TWCR = (TWCR & TWCR_CMD_MASK) | TWCR_TWEA; // TWI_slave_rx(TWI_recv_buf, TWI_recv_index); TWI_state = TWI_IDLE; break; /* SLAVE TRANSMIT MODE */ case TWSR_ST_SLA_ACK: case TWSR_ST_SLA_ARB_ACK: TWI_state = TWI_SLAVE_TX; // TWI_send_length = TWI_slave_tx(TWI_send_buf, TWI_SEND_BUFSIZE); TWI_send_length = 3; TWI_send_index = 0; case TWSR_ST_DATA_ACK: TWDR = TWI_send_buf[TWI_send_index++]; if (TWI_send_index < TWI_send_length) TWCR = (TWCR & TWCR_CMD_MASK) | TWCR_TWEA; else TWCR = (TWCR & TWCR_CMD_MASK); break; case TWSR_ST_DATA_NAK: case TWSR_ST_LAST_DATA: PORTC = PORTC ^ 0x60; //toggle LED1 on write TWCR = (TWCR & TWCR_CMD_MASK) | TWCR_TWEA; TWI_state = TWI_IDLE; break; /* MISC STATUS */ case TWSR_GARBAGE: break; case TWSR_BUS_ERROR: TWCR = (TWCR & TWCR_CMD_MASK) | TWCR_TWSTO | TWCR_TWEA; TWI_state = TWI_IDLE; break; } TWCR |= TWCR_TWINT; return TWSR & TWSR_STATUS_MASK; } void twi_init(int bitrate_khz, char addr) { PORTC |= 0x03; TWI_state = TWI_IDLE; /* calculate bitrate and prescale registers (INCOMPLETE- RUN AT 100 kb/s) */ TWBR=0x41; TWSR &= ~(TWSR_PRE_MASK); /* set slave address */ TWAR = (addr<<1) | TWAR_TWGCE; /* enable TWI */ TWCR = TWCR_TWINT | TWCR_TWEA | TWCR_TWEN | TWCR_TWIE; } /* void main(void) { PORTC = 0x0; DDRC = (PORTC_LED1 | PORTC_LED2); twi_init(100, 0x70); #asm("sei") while (1) { toggle_led1(); delay_ms(100); toggle_led2(); }; } */