UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:i2c_eeprom

This is an old revision of the document!


</code c> #include “i2cmem.h” #ifdef EEPROM

———-General I2C functions————————————————————————- volatile u08 I2Cerr; void init_i2c() { TWBR=(u08)1)-8.0); sets the correct clock rate defined as SCL } we dont need to enable the hardware - its done in write void i2cstart() { u16 timeout=1; TWCR = (1«TWINT)|(1«TWSTA)|(1«TWEN); send start

while (!(TWCR & (1<<TWINT)) && timeout);
	timeout++;							//wait for a start to be transmitted
if(!timeout)
	I2Cerr|=16;							//timeout out waiting for start error
TWCR = (1<<TWEN );							//clear the start condition
if (((TWSR & 0xF8) != TW_START)&&((TWSR & 0xF8) != TW_REP_START))
	I2Cerr|=1;							//error

}

void i2cstop() {

u16 timeout=1;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
while (!(TWCR & (1<<TWSTO)) && timeout);//wait for stop to be sent
	timeout++;
if(!timeout)
	I2Cerr|=64;							//timeout waiting for stop error

}

void i2cwrite(u08 c) {

u16 timeout=1;
TWDR = c;								//load the data
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)) && timeout);//wait for it to be sent
	timeout++;
if(!timeout)
	I2Cerr|=32;							//timeout out waiting for write complete error
if ( ((TWSR&0xF8)!=TW_MT_SLA_ACK)&&((TWSR&0xF8)!=TW_MR_SLA_ACK)&&((TWSR&0xF8)!=TW_MT_DATA_ACK) )
	I2Cerr|=2;							//error

}

u08 i2cread(u08 AK) {

u16 timeout=1;
TWCR=AK;
while ((!(TWCR & (1<<TWINT))) && timeout)
	timeout++;							//wait for it to be recieved
if(!timeout)
	I2Cerr|=8;							//timeout out waiting for data response error
if(((TWSR & 0xF8) !=TW_MR_DATA_ACK) && ((TWSR & 0xF8) !=TW_MR_DATA_NACK))
	I2Cerr|=4;
return TWDR;

}

———-EEPROM specific stuff————————————————————————- Designed for 12 byte records atm

void set_address(u32 * address) Sets an address from a pointer - can select the correct physical device but reqires idle bus { i2cstart(); i2cwrite(SLA_W|2); the block

i2cwrite((u08)((*address)>>8));				//address write MSB
i2cwrite((u08)(*address));				//address write LSB

}

void write_data(u08 * c, u08 datasize, u32 * address)The address will be incremented as the data is written { u08 n; up to 256 bytes can be written at once

for(n=0;n<datasize;n++,(*address)++)
{
	if(!((u08)*address))				//check the address for overflow for the 8 LSB (Atmel)
	{
		i2cstop();				//triggers a page write
		_delay_loop_2( (u16) ( (float)F_CPU*0.006/4.0 ) );//delay 6 ms for page write
		set_address(address);			//set the new address
	}
	i2cwrite(c[n]);					//write the data
}

}

void read_data(u08 * destination, u08 datasize, u32 * address)Reads a block of data from some address { u08 n; datasize–; i2cstart(); i2cwrite(SLA_R|3); set read to the correct block

for(n=0;n<datasize;n++)
{
	destination[n]=i2cread(_AK_);
	(*address)++;					//increment our pointer
	/*if(!(u16)(*address))				//we reached the end of the block
	{
		i2cstop(); 
		set_address(address);
	}This isn't needed on the Atmel chips*/
}
destination[datasize+1]=i2cread(_NAK_);			//send NAK for the last byte recieved
i2cstop();

}

u32 findtop() Find the address of record number where we enter painted eeprom { u32 top=12*4); half way through rounded down to nearest 12

u08 n;
u08 endcond=TRUE;					//used to solve the problem of running with n=0
for(n=16;endcond;)					//start by probing half way through
{
	set_address(&top);				//the probe address
	if(n)
		n--;					//need to decr here to get 1 byte resolution
	else
		endcond=FALSE;				//terminate the loop after completion
	if(i2cread(_NAK_)==MAGIC_NUMBER)		//see if its painted
		top-=1<<n;				//set or clear the nth bit
	else
		top+=1<<n;
	i2cstop();
	top = 12*( (u32) (top/12) );			//round down to nearest 12
}
return top;

}

void painteeprom() Paints every 12th location with the magic number { u08 magic=MAGIC_NUMBER; magic is our painting value

u32 n;
for(n=0;n<131072;n+=12)					//this writes every 12th byte
{
	set_address(&n);
	i2cwrite(magic);				//write the data
	if((u08)n>243)					//our next n will be across a page boundary
	{
		i2cstop();
		_delay_loop_2( (u16) ( (float)F_CPU*0.006/4.0 ) );//delay 6 ms for page write
	}
	wdt_reset();
}

} #endif

</code>

I2Cmem.h

#include <util/twi.h>						//I2C registers
#include <util/delay_basic.h>					//wait delay loop for page write
#include "avrlibtypes.h"
 
#define SLA_W 0b10100000					//microchip 24LC515  
#define SLA_R 0b10100001
#define SCL 100000
#define _AK_ (1<<TWINT)|(1<<TWEN)|(1<<TWEA)	//for setting up I2C read with AK and NAK from master
#define _NAK_ (1<<TWINT)|(1<<TWEN)
 
#define MAGIC_NUMBER 255					//painting value
 
void init_i2c();
void i2cstart();
void i2cstop();
void i2cwrite(u08 c);
u08 i2cread(u08 AK);
void set_address(u32* address);
void write_data(u08 * c, u08 datasize, u32*address);
void read_data(u08 * destination, u08 datasize, u32*address);
u32 findtop();
void painteeprom();
1)
(float)F_CPU/(2.0*(float)SCL
2) , 3)
(*address)»15)&0x02
4)
u32)(((u32)1«16)/12
code/i2c_eeprom.1227338239.txt.gz · Last modified: 2008/11/22 07:17 by laurenceb

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki