From b94ffcd878289cbfff34f58aee3aece6fd768ce1 Mon Sep 17 00:00:00 2001 From: Nidan Date: Fri, 10 Dec 2010 21:10:39 +0000 Subject: [PATCH] i2c implementated --- firmware/i2c_simple.c | 98 +++++++++++++++++++++++++++++++++++++------ firmware/i2c_simple.h | 11 +++-- 2 files changed, 91 insertions(+), 18 deletions(-) diff --git a/firmware/i2c_simple.c b/firmware/i2c_simple.c index f946064..1965d49 100644 --- a/firmware/i2c_simple.c +++ b/firmware/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/i2c_simple.h b/firmware/i2c_simple.h index c7aee5f..2e76444 100644 --- a/firmware/i2c_simple.h +++ b/firmware/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