diff --git a/firmware/Makefile b/firmware/Makefile index 875c3a4..af8b59d 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -13,21 +13,29 @@ all: master slave master: cd masterchip; $(MAKE) $(MFLAGS) +clean-master: + cd masterchip; $(MAKE) $(MFLAGS) clean + flash-master: cd masterchip; $(MAKE) $(MFLAGS) flash fuses-master: cd masterchip; $(MAKE) $(MFLAGS) fuses + slave: cd slavechip; $(MAKE) $(MFLAGS) +clean-slave: + cd slavechip; $(MAKE) $(MFLAGS) clean + flash-slave: cd slavechip; $(MAKE) $(MFLAGS) flash fuses-slave: cd slavechip; $(MAKE) $(MFLAGS) fuses + clean: cd masterchip; $(MAKE) $(MFLAGS) clean cd slavechip; $(MAKE) $(MFLAGS) clean diff --git a/firmware/slavechip/i2c_simple.c b/firmware/slavechip/i2c_simple.c index f946064..1965d49 100644 --- a/firmware/slavechip/i2c_simple.c +++ b/firmware/slavechip/i2c_simple.c @@ -1,23 +1,97 @@ - #include #include "i2c_simple.h" - - -void i2c_init(){ - //TODO: implement +void i2c_init() +{ + TWBR = 0;//bit rate + TWSR = 0;//Prescaler + + TWAR = 0x80;//our address 1000 000, don't listen to general call + TWAMR = 0; + + TWCR = TWEA | TWEN;/* TWINT clear -> we must do something; unset TWSTA manually!, TWSTO */ + //TWDR - data } -uint8_t i2c_read(uint8_t addr, uint8_t len, uint8_t *data){ - return 0; //TODO: implement +uint8_t i2c_read(uint8_t addr, uint8_t len, uint8_t *data) +{ + TWCR &= ~TWSTO; + TWCR |= TWINT | TWSTA; + while(~TWCR & TWINT) {;}/* get bus access */ + /* no error possible */ + + TWDR = addr | 1; + TWCR &= ~(TWSTA | TWSTO); + TWCR |= TWINT; + while(~TWCR & TWINT) {;}/* transmit address */ + /* possible results: ACK, NAK, abitration lost */ + if(TW_STATUS == TW_MR_SLA_NACK) + { + TWCR |= TWINT | TWSTO; + return 0; + } + else if(TW_STATUS == TW_MR_ARB_LOST) {return 0;} + + uint8_t done = 0; + while(done + 1 < len) + { + TWCR |= TWEA | TWINT;/* send ack after byte */ + while(~TWCR & TWINT) {;}/* read data */ + data[done] = TWDR; + done++; + TWCR |= TWINT; + } + + TWCR &= ~TWEA; + TWCR |= TWINT;/* send nak after byte */ + while(~TWCR & TWINT) {;}/* read data */ + data[done] = TWDR; + done++; + TWCR |= TWINT | TWSTO; + return done; } -uint8_t i2c_write(uint8_t addr, uint8_t len, uint8_t *data){ - return 0; //TODO: implement +uint8_t i2c_write(uint8_t addr, uint8_t len, uint8_t *data) +{ + TWCR &= ~TWSTO; + TWCR |= TWINT | TWSTA; + while(~TWCR & TWINT) {;}/* get bus access */ + /* no error possible */ + + TWDR = addr; + TWCR &= ~(TWSTA | TWSTO); + TWCR |= TWINT; + while(~TWCR & TWINT) {;}/* transmit address */ + /* possible results: ACK, NAK, abitration lost */ + if(TW_STATUS == TW_MT_SLA_NACK) + { + TWCR |= TWINT | TWSTO; + return 0; + } + else if(TW_STATUS == TW_MT_ARB_LOST) {return 0;} + + uint8_t done = 0; + while(done < len) + { + TWDR = data[done]; + TWCR |= TWINT; + while(~TWCR & TWINT) {;}/* write data */ + /* possible results: ACK, NAK, abitration lost */ + if(TW_STATUS == TW_MT_DATA_NACK) + { + TWCR |= TWINT | TWSTO; + return done; + } + else if(TW_STATUS == TW_MT_ARB_LOST) {return done;} + done++; + } + + TWCR |= TWINT | TWSTO; + return done; } -uint8_t i2c_write_read(uint8_t addr, uint8_t writelen, uint8_t* writedata, uint8_t readlen, - uint8_t* readdata){ - return 0; //TODO: implement +uint8_t i2c_write_read(uint8_t addr, uint8_t writelen, uint8_t *writedata, uint8_t readlen, uint8_t *readdata) +{ + return 0; //TODO: implement } diff --git a/firmware/slavechip/i2c_simple.h b/firmware/slavechip/i2c_simple.h index c7aee5f..2e76444 100644 --- a/firmware/slavechip/i2c_simple.h +++ b/firmware/slavechip/i2c_simple.h @@ -1,7 +1,5 @@ - - - - +#ifndef I2C_SIMPLE_H +#define I2C_SIMPLE_H /* initializes i2c interface (master, 400kHz) */ void i2c_init(); @@ -13,5 +11,6 @@ uint8_t i2c_read(uint8_t addr, uint8_t len, uint8_t *data); uint8_t i2c_write(uint8_t addr, uint8_t len, uint8_t *data); /* writes, followed by a repeated start and a read */ -uint8_t i2c_write_read(uint8_t addr, uint8_t writelen, uint8_t* writedata, uint8_t readlen, - uint8_t* readdata); +uint8_t i2c_write_read(uint8_t addr, uint8_t writelen, uint8_t *writedata, uint8_t readlen, uint8_t *readdata); + +#endif