code:i2c_eeprom
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
code:i2c_eeprom [2008/10/27 00:56] – laurenceb | code:i2c_eeprom [2009/03/20 04:50] (current) – laurenceb | ||
---|---|---|---|
Line 2: | Line 2: | ||
- | <code c> | + | <code c># |
- | #include " | + | #ifdef EEPROM |
- | //note that with microchip EEPROM at least, the internal buffer is only 64 bytes in size, so write_data can only accept a maximum of 64 as the size | + | |
+ | //----------General I2C functions------------------------------------------------------------------------- | ||
+ | |||
+ | volatile u08 I2Cerr; | ||
void init_i2c() | void init_i2c() | ||
{ | { | ||
- | TWBR=(u08)((float)F_CPU/ | + | TWBR=(u08)(((float)F_CPU/ |
} // | } // | ||
- | u08 i2cstart() | + | void i2cstart() |
{ | { | ||
+ | u16 timeout=1; | ||
TWCR = (1<< | TWCR = (1<< | ||
- | while (!(TWCR & (1<< | + | while (!(TWCR & (1<< |
+ | timeout++; //wait for a start to be transmitted | ||
+ | if(!timeout) | ||
+ | I2Cerr|=16; | ||
+ | TWCR = (1<< | ||
if (((TWSR & 0xF8) != TW_START)&& | if (((TWSR & 0xF8) != TW_START)&& | ||
- | return | + | I2Cerr|=1; //error |
- | return 0; | + | |
} | } | ||
- | # | + | void i2cstop() |
+ | { | ||
+ | u16 timeout=1; | ||
+ | TWCR = (1<< | ||
+ | while (!(TWCR & (1<< | ||
+ | timeout++; | ||
+ | if(!timeout) | ||
+ | I2Cerr|=64; | ||
+ | } | ||
- | u08 i2cwrite(char c) | + | void i2cwrite(u08 c) |
{ | { | ||
+ | u16 timeout=1; | ||
TWDR = c; | TWDR = c; | ||
TWCR = (1<< | TWCR = (1<< | ||
- | while (!(TWCR & (1<< | + | while (!(TWCR & (1<< |
- | if ((TWSR & 0xF8) !=TW_MT_SLA_ACK) | + | timeout++; |
- | return | + | if(!timeout) |
- | return 0; | + | I2Cerr|=32; |
+ | if ( ((TWSR& | ||
+ | I2Cerr|=2; //error | ||
} | } | ||
+ | u08 i2cread(u08 ak) | ||
+ | { | ||
+ | u16 timeout=1; | ||
+ | TWCR=ak; | ||
+ | while ((!(TWCR & (1<< | ||
+ | timeout++; | ||
+ | if(!timeout) | ||
+ | I2Cerr|=8; | ||
+ | if(((TWSR & 0xF8) !=TW_MR_DATA_ACK) && ((TWSR & 0xF8) !=TW_MR_DATA_NACK)) | ||
+ | I2Cerr|=4; | ||
+ | return TWDR; | ||
+ | } | ||
+ | |||
+ | // | ||
+ | //Designed for 12 byte records atm | ||
+ | |||
+ | void set_address(u32 * address) // | ||
+ | { | ||
+ | i2cstart(); | ||
+ | i2cwrite(SLA_W|(((*address)>> | ||
+ | i2cwrite((u08)((*address)>> | ||
+ | i2cwrite((u08)(*address)); | ||
+ | } | ||
- | u08 write_data(char * c, u16 address, u08 datasize) | + | void write_data(u08 * c, u08 datasize, u32 * address)//The address will be incremented as the data is written |
{ | { | ||
- | u08 n,err; | + | u08 n; //up to 256 bytes can be written at once |
- | err|=i2cstart(); | + | for(n=0; |
- | err|=i2cwrite(SLA_W); | + | |
- | err|=i2cwrite((u08)(address>> | + | |
- | err|=i2cwrite((u08)address); | + | |
- | for(n=0; | + | |
{ | { | ||
- | err|=i2cwrite(c[n]); | + | if(!((u08)*address)) // |
+ | { | ||
+ | i2cstop(); | ||
+ | _delay_loop_2( (u16) ( (float)F_CPU*0.006/ | ||
+ | set_address(address); | ||
+ | } | ||
+ | i2cwrite(c[n]); | ||
} | } | ||
- | i2cstop; | ||
- | return err; | ||
} | } | ||
- | u08 read_data(char * destination, u16 address, u08 datasize) | + | void read_data(u08 * destination, |
{ | { | ||
- | u08 n,err; | + | u08 n; |
datasize--; | datasize--; | ||
- | err|=i2cstart(); | + | i2cstart(); |
- | err|=i2cwrite(SLA_W); | + | i2cwrite(SLA_R|((u08)((*address)>>15)&0x02)); //set read to the correct block |
- | err|=i2cwrite((u08)(address>> | + | for(n=0; |
- | err|=i2cwrite((u08)address); //address write LSB | + | |
- | err|=i2cstart(); | + | |
- | TWDR=SLA_R; | + | |
- | TWCR = (1<< | + | |
- | while (!(TWCR & (1<< | + | |
- | if ((TWSR & 0xF8) !=TW_MR_SLA_ACK) | + | |
- | err|=4; | + | |
- | for(n=0; | + | |
{ | { | ||
- | TWCR=((1<< | + | destination[n]=i2cread(_AK_); |
- | while (!(TWCR & (1<< | + | (*address)++; // |
- | destination[n]=TWDR; | + | /*if(!(u16)(*address)) //we reached |
- | if((TWSR & 0xF8) !=TW_MR_DATA_ACK) | + | { |
- | err|=8; | + | i2cstop(); |
+ | set_address(address); | ||
+ | }This isn't needed on the Atmel chips*/ | ||
} | } | ||
- | TWCR=((1<< | + | destination[datasize]=i2cread(_NAK_); //send NAK for the last byte recieved |
- | while (!(TWCR & (1<< | + | i2cstop(); |
- | destination[datasize+1]=TWDR; //send NAK for the last byte recieved | + | (*address)++; |
- | if((TWSR & 0xF8) !=TW_MR_DATA_NACK) | + | |
- | err|=16; | + | |
- | i2cstop; | + | |
- | return err; | + | |
} | } | ||
+ | |||
+ | u32 findtop() // | ||
+ | { | ||
+ | u32 top=12*((u32)1<< | ||
+ | u08 n, | ||
+ | u16 place=1<< | ||
+ | for(n=14; | ||
+ | { | ||
+ | set_address(& | ||
+ | if(n) | ||
+ | n--; | ||
+ | else | ||
+ | endcond=FALSE; | ||
+ | i2cstart(); | ||
+ | i2cwrite(SLA_R); | ||
+ | if(i2cread(_NAK_)==MAGIC_NUMBER) // | ||
+ | place& | ||
+ | if(n) | ||
+ | place|=(1<< | ||
+ | i2cstop(); | ||
+ | if(place> | ||
+ | place=10922; | ||
+ | top = 12*( (u32)place ); | ||
+ | } | ||
+ | set_address(& | ||
+ | i2cstart(); | ||
+ | i2cwrite(SLA_R); | ||
+ | if(i2cread(_NAK_)!=MAGIC_NUMBER) // | ||
+ | place++; | ||
+ | top = 12*( (u32)place ); | ||
+ | return top; | ||
+ | } | ||
+ | |||
+ | void painteeprom() // | ||
+ | { | ||
+ | u08 magic=MAGIC_NUMBER; | ||
+ | u32 n=0; | ||
+ | for(; | ||
+ | { | ||
+ | /* | ||
+ | set_address(& | ||
+ | i2cwrite(magic); | ||
+ | if((u08)n> | ||
+ | { | ||
+ | i2cstop(); | ||
+ | _delay_loop_2( (u16) ( (float)F_CPU*0.006/ | ||
+ | }*/ | ||
+ | if(!((u08)n)) // | ||
+ | { | ||
+ | i2cstop(); | ||
+ | _delay_loop_2( (u16) ( (float)F_CPU*0.006/ | ||
+ | set_address(& | ||
+ | } | ||
+ | i2cwrite(magic); | ||
+ | wdt_reset(); | ||
+ | } | ||
+ | i2cstop(); | ||
+ | } | ||
+ | #endif | ||
</ | </ | ||
+ | |||
===== I2Cmem.h ===== | ===== I2Cmem.h ===== | ||
- | <code c> | + | <code c># |
- | #include < | + | #include < |
#include " | #include " | ||
Line 88: | Line 179: | ||
#define SLA_R 0b10100001 | #define SLA_R 0b10100001 | ||
#define SCL 100000 | #define SCL 100000 | ||
+ | #define _AK_ (1<< | ||
+ | #define _NAK_ (1<< | ||
+ | |||
+ | #define MAGIC_NUMBER 255 // | ||
void init_i2c(); | void init_i2c(); | ||
- | u08 i2cstart(); | + | void i2cstart(); |
- | u08 i2cwrite(char c); | + | void i2cstop(); |
- | u08 write_data(char * c, u16 address, u08 datasize); | + | void i2cwrite(u08 c); |
- | u08 read_data(char * destination, u16 address, u08 datasize); | + | u08 i2cread(u08 AK); |
+ | void set_address(u32* address); | ||
+ | void write_data(u08 * c, u08 datasize, u32*address); | ||
+ | void read_data(u08 * destination, | ||
+ | u32 findtop(); | ||
+ | void painteeprom(); | ||
</ | </ | ||
- | |||
- |
code/i2c_eeprom.1225068991.txt.gz · Last modified: 2008/10/27 00:56 by laurenceb