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/11/06 07:29] – laurenceb | code:i2c_eeprom [2009/03/20 04:50] (current) – laurenceb | ||
---|---|---|---|
Line 11: | Line 11: | ||
void init_i2c() | void init_i2c() | ||
{ | { | ||
- | TWBR=(u08)((float)F_CPU/ | + | TWBR=(u08)(((float)F_CPU/ |
} // | } // | ||
void 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)&& | ||
I2Cerr|=1; | I2Cerr|=1; | ||
Line 24: | Line 29: | ||
void i2cstop() | void i2cstop() | ||
{ | { | ||
+ | u16 timeout=1; | ||
TWCR = (1<< | TWCR = (1<< | ||
- | while (!(TWCR & (1<< | + | while (!(TWCR & (1<< |
+ | timeout++; | ||
+ | if(!timeout) | ||
+ | I2Cerr|=64; | ||
} | } | ||
void i2cwrite(u08 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) & ((TWSR & 0xF8) !=TW_MR_SLA_ACK) ) | + | timeout++; |
+ | if(!timeout) | ||
+ | I2Cerr|=32; | ||
+ | if ( ((TWSR& | ||
I2Cerr|=2; | I2Cerr|=2; | ||
} | } | ||
- | u08 i2cread(u08 | + | u08 i2cread(u08 |
{ | { | ||
u16 timeout=1; | u16 timeout=1; | ||
- | TWCR=AK; | + | TWCR=ak; |
- | while (!(TWCR & (1<< | + | while |
timeout++; | timeout++; | ||
if(!timeout) | if(!timeout) | ||
- | I2Cerr|=8; | + | I2Cerr|=8; |
- | if((TWSR & 0xF8) !=TW_MR_DATA_ACK) | + | if(((TWSR & 0xF8) !=TW_MR_DATA_ACK) && ((TWSR & 0xF8) !=TW_MR_DATA_NACK)) |
I2Cerr|=4; | I2Cerr|=4; | ||
return TWDR; | return TWDR; | ||
Line 53: | Line 66: | ||
//Designed for 12 byte records atm | //Designed for 12 byte records atm | ||
- | void set_address(u32 * address) // | + | void set_address(u32 * address) // |
{ | { | ||
i2cstart(); | i2cstart(); | ||
- | i2cwrite(SLA_W|(((*address)>> | + | i2cwrite(SLA_W|(((*address)>> |
i2cwrite((u08)((*address)>> | i2cwrite((u08)((*address)>> | ||
i2cwrite((u08)(*address)); | i2cwrite((u08)(*address)); | ||
Line 66: | Line 79: | ||
for(n=0; | for(n=0; | ||
{ | { | ||
- | if(!((u08)*address)&0xEF) //check the address for overflow for the 7 LSB | + | if(!((u08)*address)) //check the address for overflow for the 8 LSB (Atmel) |
{ | { | ||
i2cstop(); | i2cstop(); | ||
- | _delay_loop_2( (u16) ( (float)F_CPU*0.003/4.0 ) );// | + | _delay_loop_2( (u16) ( (float)F_CPU*0.006/4.0 ) );// |
set_address(address); | set_address(address); | ||
} | } | ||
Line 81: | Line 94: | ||
datasize--; | datasize--; | ||
i2cstart(); | i2cstart(); | ||
- | i2cwrite(SLA_R|(((*address)>> | + | i2cwrite(SLA_R|((u08)((*address)>> |
- | for(n=0; | + | for(n=0; |
{ | { | ||
destination[n]=i2cread(_AK_); | destination[n]=i2cread(_AK_); | ||
(*address)++; | (*address)++; | ||
- | if(!(u16)*address) //we reached the end of the block | + | /*if(!(u16)(*address)) //we reached the end of the block |
{ | { | ||
i2cstop(); | i2cstop(); | ||
set_address(address); | set_address(address); | ||
- | } | + | }This isn't needed on the Atmel chips*/ |
} | } | ||
- | destination[datasize+1]=i2cread(_NAK_); | + | destination[datasize]=i2cread(_NAK_); |
+ | i2cstop(); | ||
+ | (*address)++; | ||
} | } | ||
+ | |||
u32 findtop() // | u32 findtop() // | ||
{ | { | ||
- | u32 top=0; //half way through rounded to nearest | + | u32 top=12*((u32)1<< |
- | u08 n; | + | u08 n, |
- | for(n=17;n;) //start by probing half way through | + | u16 place=1<< |
+ | for(n=14;endcond;) //start by probing half way through | ||
{ | { | ||
- | n--; | ||
- | top+=1<< | ||
- | top = 12*( (u32) (top/12) ); | ||
set_address(& | set_address(& | ||
+ | if(n) | ||
+ | n--; | ||
+ | else | ||
+ | endcond=FALSE; | ||
+ | i2cstart(); | ||
+ | i2cwrite(SLA_R); | ||
if(i2cread(_NAK_)==MAGIC_NUMBER) // | if(i2cread(_NAK_)==MAGIC_NUMBER) // | ||
- | top-=1<< | + | place&=~(1<<n); //clear the nth bit in the place holder |
+ | if(n) | ||
+ | place|=(1<< | ||
+ | i2cstop(); | ||
+ | if(place> | ||
+ | place=10922; | ||
+ | top = 12*( (u32)place ); | ||
} | } | ||
- | top =12*( (u32) (top/12) ); //make sure our answer is rounded correctly | + | set_address(& |
+ | i2cstart(); | ||
+ | i2cwrite(SLA_R); | ||
+ | if(i2cread(_NAK_)!=MAGIC_NUMBER) //check the location to make sure its blank | ||
+ | place++; | ||
+ | top = 12*( (u32)place ); | ||
return top; | return top; | ||
} | } | ||
Line 116: | Line 147: | ||
u08 magic=MAGIC_NUMBER; | u08 magic=MAGIC_NUMBER; | ||
u32 n=0; | u32 n=0; | ||
- | for(n=0; | + | for(; |
{ | { | ||
- | set_address(& | + | /* |
- | write_data(& | + | set_address(& |
+ | i2cwrite(magic); //write the data | ||
+ | if((u08)n> | ||
+ | { | ||
+ | i2cstop(); | ||
+ | _delay_loop_2( (u16) ( (float)F_CPU*0.006/4.0 ) );//delay 6 ms for page write | ||
+ | }*/ | ||
+ | if(!((u08)n)) // | ||
+ | { | ||
+ | i2cstop(); | ||
+ | _delay_loop_2( (u16) ( (float)F_CPU*0.006/ | ||
+ | set_address(& | ||
+ | } | ||
+ | i2cwrite(magic); | ||
+ | wdt_reset(); | ||
} | } | ||
+ | i2cstop(); | ||
} | } | ||
#endif | #endif | ||
Line 126: | Line 172: | ||
===== I2Cmem.h ===== | ===== I2Cmem.h ===== | ||
- | <code c># | + | <code c># |
- | # | + | # |
#include " | #include " | ||
- | #include " | ||
- | #include " | ||
- | #include " | ||
- | #include " | ||
- | #include " | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | #define BAUDRATE (int)9600 // | ||
- | #define DELTA_TIME (float)0.02 // | ||
- | #define DELAY _delay_loop_2((u16)((float)F_CPU/ | ||
- | #define SET PORTD |= 0x10 // | ||
- | #define CLEAR PORTD &= ~0x10 | ||
- | //kalman filter - NOTE: these constants are airframe specific | + | #define SLA_W 0b10100000 //microchip 24LC515 |
- | # | + | # |
- | # | + | #define SCL 100000 |
+ | #define _AK_ (1<< | ||
+ | # | ||
- | # | + | # |
- | #define PWM_COUNT_TIME (u16)((float)F_CPU*0.0005/ | + | |
- | #define I_C -0.001 // | + | void init_i2c(); |
- | #define P_C -0.3 | + | void i2cstart(); |
- | #define D_C -0.5 | + | void i2cstop(); |
- | #define INTEGRAL_LIMIT 0.2/ | + | void i2cwrite(u08 c); |
- | + | u08 i2cread(u08 AK); | |
- | #define SCALEHEIGHT | + | void set_address(u32* address); |
- | #define WEIGHTINGFACTOR | + | void write_data(u08 * c, u08 datasize, u32*address); |
- | + | void read_data(u08 * destination, | |
- | #define read_rate | + | u32 findtop(); |
- | #define read_temp (u08)0b10011100 | + | void painteeprom(); |
- | #define read_melexis | + | |
- | + | ||
- | #define gyro_null 1012 | + | |
- | + | ||
- | #define altitudelimit 10000 // | + | |
- | #define timelimit 30 // | + | |
- | + | ||
- | #define targeteast (float)(-1.0*Deg2rad) //target waypoint ~ Cambridge | + | |
- | #define targetnorth | + | |
- | + | ||
- | #define Rad2deg 180.0/ | + | |
- | #define Deg2rad PI/180.0 | + | |
- | + | ||
- | #define PRINT_COMMA rprintfChar(pgm_read_byte(& | + | |
- | + | ||
- | #define battery_factor (float)0.02505 // | + | |
- | #define battery_chan 0x00 // | + | |
- | + | ||
- | #define toggle_pin PIND=0x20 // | + | |
- | + | ||
- | #define BAUDDIV | + | |
- | + | ||
- | #define radio_cts bit_is_set(PIND,2) // | + | |
- | + | ||
- | #define led_left PORTC = ((PORTC & ~0x0C) | 0x04) | + | |
- | #define led_right PORTC = ((PORTC & ~0x0C) | 0x08) | + | |
- | + | ||
- | #define USER_PRESENT !(PINC& | + | |
- | + | ||
- | #define cutter_on PORTD|=(1<< | + | |
- | #define cutter_off PORTD& | + | |
- | + | ||
- | #define DISABLE_SMPS PORTD|=(1<< | + | |
- | #define ENABLE_SMPS PORTD& | + | |
- | + | ||
- | #define GYRO_OFF PORTB|=1<< | + | |
- | #define GYRO_ON PORTB& | + | |
- | + | ||
- | #ifdef ADCSRA | + | |
- | #ifndef ADCSR | + | |
- | #define ADCSR | + | |
- | #endif | + | |
- | #endif | + | |
- | #ifdef ADATE | + | |
- | #define ADFR ADATE | + | |
- | #endif | + | |
- | #ifdef GROUND | + | |
- | #define enable_ground_control TIMSK1|=(1<< | + | |
- | #define disable_ground_control TIMSK1& | + | |
- | #define PULSE_MIN 0.001*F_CPU/ | + | |
- | #define PULSE_MAX 0.002*F_CPU/ | + | |
- | #define GROUND_LED_ON PORTD|=(1<< | + | |
- | #define GROUND_LED_OFF PORTD& | + | |
- | #define GROUND_LED_SET PORTD& | + | |
- | #endif | + | |
- | + | ||
- | typedef struct | + | |
- | { | + | |
- | float vup; | + | |
- | float vnorth; | + | |
- | float veast; | + | |
- | float time; | + | |
- | float altitude; | + | |
- | float longitude; | + | |
- | float latitude; | + | |
- | u08 packetflag; | + | |
- | u08 status; | + | |
- | u08 nosats; | + | |
- | } gps_type; | + | |
- | + | ||
- | void put_char(unsigned char c); // | + | |
- | void suart_send(char c); | + | |
- | void run_ground_control(); | + | |
- | void _delay_10ms(char time); | + | |
- | float driftfactor(int altitude); | + | |
</ | </ |
code/i2c_eeprom.1225956559.txt.gz · Last modified: 2008/11/06 07:29 by laurenceb