UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


code:i2c_eeprom

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
code:i2c_eeprom [2008/11/06 07:29] laurencebcode:i2c_eeprom [2009/03/20 04:50] (current) laurenceb
Line 11: Line 11:
 void init_i2c() void init_i2c()
 { {
- TWBR=(u08)((float)F_CPU/(2*SCL)-8.0); //sets the correct clock rate defined as SCL+ TWBR=(u08)(((float)F_CPU/(2.0*(float)SCL))-8.0);//sets the correct clock rate defined as SCL
 } //we dont need to enable the hardware - its done in write } //we dont need to enable the hardware - its done in write
  
 void i2cstart() void i2cstart()
 { {
 + u16 timeout=1;
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //send start  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //send start
- while (!(TWCR & (1<<TWINT))); //wait for a start to be transmitted+ 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))  if (((TWSR & 0xF8) != TW_START)&&((TWSR & 0xF8) != TW_REP_START))
  I2Cerr|=1; //error  I2Cerr|=1; //error
Line 24: Line 29:
 void i2cstop() void i2cstop()
 { {
 + u16 timeout=1;
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
- while (!(TWCR & (1<<TWSTO))); //wait for stop to be sent+ 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) void i2cwrite(u08 c)
 { {
 + u16 timeout=1;
  TWDR = c; //load the data  TWDR = c; //load the data
  TWCR = (1<<TWINT)|(1<<TWEN);  TWCR = (1<<TWINT)|(1<<TWEN);
- while (!(TWCR & (1<<TWINT))); //wait for it to be sent + while (!(TWCR & (1<<TWINT)) && timeout) //wait for it to be sent 
- if ( ((TWSR & 0xF8) !=TW_MT_SLA_ACK) & ((TWSR & 0xF8) !=TW_MR_SLA_ACK) )+ 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  I2Cerr|=2; //error
 } }
  
-u08 i2cread(u08 AK)+u08 i2cread(u08 ak)
 { {
  u16 timeout=1;  u16 timeout=1;
- TWCR=AK+ TWCR=ak
- while (!(TWCR & (1<<TWINT)) & timeout)+ while ((!(TWCR & (1<<TWINT))) && timeout)
  timeout++; //wait for it to be recieved  timeout++; //wait for it to be recieved
  if(!timeout)  if(!timeout)
- I2Cerr|=8; //timeout out waiting for data error + I2Cerr|=8; //timeout out waiting for data response error 
- 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) //Sets an address from a paointer cannot switch between physical devices+void set_address(u32 * address) //Sets an address from a pointer can select the correct physical device but reqires idle bus
 { {
  i2cstart();  i2cstart();
- i2cwrite(SLA_W|(((*address)>>13)&0x08)); //the block+ i2cwrite(SLA_W|(((*address)>>15)&0x02)); //the block
  i2cwrite((u08)((*address)>>8)); //address write MSB  i2cwrite((u08)((*address)>>8)); //address write MSB
  i2cwrite((u08)(*address)); //address write LSB  i2cwrite((u08)(*address)); //address write LSB
Line 66: Line 79:
  for(n=0;n<datasize;n++,(*address)++)  for(n=0;n<datasize;n++,(*address)++)
  {  {
- if(!((u08)*address)&0xEF) //check the address for overflow for the LSB+ if(!((u08)*address)) //check the address for overflow for the LSB (Atmel)
  {  {
  i2cstop(); //triggers a page write  i2cstop(); //triggers a page write
- _delay_loop_2( (u16) ( (float)F_CPU*0.003/4.0 ) );//delay ms for page write+ _delay_loop_2( (u16) ( (float)F_CPU*0.006/4.0 ) );//delay ms for page write
  set_address(address); //set the new address  set_address(address); //set the new address
  }  }
Line 81: Line 94:
  datasize--;  datasize--;
  i2cstart();  i2cstart();
- i2cwrite(SLA_R|(((*address)>>13)&0x08)); //set read to the correct block + i2cwrite(SLA_R|((u08)((*address)>>15)&0x02)); //set read to the correct block 
- for(n=0;n<datasize;n++)+ for(n=0;n<datasize;n++) //the eeproms address pointer should have been setup already
  {  {
  destination[n]=i2cread(_AK_);  destination[n]=i2cread(_AK_);
  (*address)++; //increment our pointer  (*address)++; //increment our pointer
- 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_); //send NAK for the last byte recieved+ destination[datasize]=i2cread(_NAK_); //send NAK for the last byte recieved 
 + i2cstop(); 
 + (*address)++;
 } }
 +
  
 u32 findtop() //Find the address of record number where we enter painted eeprom u32 findtop() //Find the address of record number where we enter painted eeprom
 { {
- u32 top=0; //half way through rounded to nearest 12 + u32 top=12*((u32)1<<13); //half way through rounded down to 12 
- u08 n; + u08 n,endcond=TRUE; 
- for(n=17;n;) //start by probing half way through+ u16 place=1<<13
 + for(n=14;endcond;) //start by probing half way through - place is in records
  {  {
- n--; 
- top+=1<<n; //trial setting of bit 
- top = 12*( (u32) (top/12) ); //round down to nearest 12 
  set_address(&top); //the probe address  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 //need to decr here to get 1 byte resolution
 + i2cstart(); //read the slave
 + i2cwrite(SLA_R);
  if(i2cread(_NAK_)==MAGIC_NUMBER) //see if its painted  if(i2cread(_NAK_)==MAGIC_NUMBER) //see if its painted
- top-=1<<n; //clear the nth bit+ place&=~(1<<n); //clear the nth bit in the place holder 
 + if(n) 
 + place|=(1<<(n-1)); //set the next bit 
 + i2cstop(); 
 + if(place>10922) 
 + place=10922; 
 + top = 12*( (u32)place ); //place is in units of 12
  }  }
- top =12*( (u32) (top/12) ); //make sure our answer is rounded correctly+ set_address(&top); 
 + 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; //magic is our painting value  u08 magic=MAGIC_NUMBER; //magic is our painting value
  u32 n=0;  u32 n=0;
- for(n=0;n<131072;n+=11) //need to skip 11 bytes between each write location+ for(;n<131072;n++/*n+=12*/) //this writes every (12th) byte
  {  {
- set_address(&n); //set the eeproms internal address register + /* 
- write_data(&magic,1,&n); //write the data+ 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 
 + }*/ 
 + if(!((u08)n)) //this code is for writing every byte 
 +
 + i2cstop(); 
 + _delay_loop_2( (u16) ( (float)F_CPU*0.006/4.0 ) );//delay 6 ms for page write 
 + set_address(&n); 
 +
 + i2cwrite(magic); 
 + wdt_reset();
  }  }
 + i2cstop();
 } }
 #endif #endif
Line 126: Line 172:
  
 ===== I2Cmem.h ===== ===== I2Cmem.h =====
-<code c>#include "global.h" +<code c>#include <util/twi.h> //I2C registers 
-#include "avrlibdefs.h"+#include <util/delay_basic.h> //wait delay loop for page write
 #include "avrlibtypes.h" #include "avrlibtypes.h"
-#include "matrix.h" 
-#include "kalman.h" 
-#include "TSIP.h" 
-#include "rprintf.h" 
-#include "i2cmem.h" 
-#include <avr/io.h> 
-#include <stdlib.h> 
-#include <math.h> 
-#include <avr/interrupt.h> 
-#include <avr/wdt.h> 
-#include <util/delay_basic.h> 
-#include <avr/eeprom.h> 
-#include <avr/pgmspace.h> 
-  
-#define BAUDRATE (int)9600 //9600 baud for lassen iq 
-#define DELTA_TIME (float)0.02 //20ms 
-#define DELAY _delay_loop_2((u16)((float)F_CPU/(4.0*(float)BAUDRATE))) //delay for suart routine 
-#define SET PORTD |= 0x10 //PORTD.4 is the tx 
-#define CLEAR PORTD &= ~0x10 
  
-//kalman filter - NOTE: these constants are airframe specific +#define SLA_W 0b10100000 //microchip 24LC515   
-#define CONTROL_GAIN (float)PI/4.0 //full control input of 1 gives ~ this turn rate +#define SLA_R 0b10100001 
-#define DAMPING_CONSTANT (float)0.3 //approx how fast oscillations die down as faction per second+#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 TOP_COUNT (u16)((float)F_CPU*DELTA_TIME/8.0) //timer1 pwm frequency +#define MAGIC_NUMBER 255 //painting value
-#define PWM_COUNT_TIME (u16)((float)F_CPU*0.0005/8.0) //500us+
  
-#define I_C -0.001 //control loop +void init_i2c()
-#define P_C -0.3 +void i2cstart(); 
-#define D_C -0.5 +void i2cstop(); 
-#define INTEGRAL_LIMIT 0.2/I_C //integral servo shift limited to 1/5 of full scale range +void i2cwrite(u08 c); 
- +u08 i2cread(u08 AK); 
-#define SCALEHEIGHT (float)(-1.0/160.0) //optimised descent- 1/( atm scale height in 100m units * 2) - http://en.wikipedia.org/wiki/Scale_height +void set_address(u32address); 
-#define WEIGHTINGFACTOR (float)(20.0)/(1012000.0)//time to drop 100m at STP/one radian expressed as meters on earth surface +void write_data(u08 cu08 datasizeu32*address); 
-  +void read_data(u08 * destination, u08 datasize, u32*address); 
-#define read_rate (u08)0b10010100 //gyro specific +u32 findtop(); 
-#define read_temp (u08)0b10011100 +void painteeprom();
-#define read_melexis (u08)0x80 +
- +
-#define gyro_null 1012 +
-  +
-#define altitudelimit 10000 //flight termination conditions +
-#define timelimit 30 //NOTE: for debug +
-  +
-#define targeteast (float)(-1.0*Deg2rad) //target waypoint ~ Cambridge +
-#define targetnorth (float)(52.0*Deg2rad) +
-  +
-#define Rad2deg 180.0/PI //bloody obvious +
-#define Deg2rad PI/180.0 +
- +
-#define PRINT_COMMA rprintfChar(pgm_read_byte(&comma)) //prints a comma +
-  +
-#define battery_factor (float)0.02505 //for measuring battery voltage- checked from test +
-#define battery_chan 0x00 //ADC0 +
-  +
-#define toggle_pin PIND=0x20 //led on port D.5 +
-  +
-#define BAUDDIV  (u16)( ((float)F_CPU/(BAUDRATE*16UL)) -1 )//baud divider +
- +
-#define radio_cts bit_is_set(PIND,2) //hardwarehowever its wired up +
- +
-#define led_left PORTC = ((PORTC & ~0x0C) | 0x04) +
-#define led_right PORTC = ((PORTC & ~0x0C) | 0x08) +
- +
-#define USER_PRESENT !(PINC&0x02) +
- +
-#define cutter_on PORTD|=(1<<7) //release mechanism (hot resistor off mosfet) +
-#define cutter_off PORTD&=~(1<<7) +
- +
-#define DISABLE_SMPS PORTD|=(1<<6) //turns the SMPS for the servo on/off - never send pwm if its off +
-#define ENABLE_SMPS PORTD&=~(1<<6) +
- +
-#define GYRO_OFF PORTB|=1<<1 //SS line +
-#define GYRO_ON PORTB&=~(1<<1) +
- +
-#ifdef ADCSRA +
- #ifndef ADCSR +
- #define ADCSR   ADCSRA +
- #endif +
-#endif +
-#ifdef ADATE +
- #define ADFR    ADATE +
-#endif +
-#ifdef GROUND +
- #define enable_ground_control TIMSK1|=(1<<ICIE1) //enables the input capture interrupt +
- #define disable_ground_control TIMSK1&=~(1<<ICIE1) //disables input capture interrupt +
- #define PULSE_MIN 0.001*F_CPU/8 //pwm must be in the range 1 to 2 ms +
- #define PULSE_MAX 0.002*F_CPU/+
- #define GROUND_LED_ON PORTD|=(1<<3+
- #define GROUND_LED_OFF PORTD&=~(1<<3) +
- #define GROUND_LED_SET PORTD&(1<<3) +
-#endif +
-  +
-typedef struct +
-+
- float vup; +
- float vnorth; +
- float veast; +
- float time; +
- float altitude; +
- float longitude; +
- float latitude; +
- u08 packetflag; //packetflag lets us see when our packet has been updated +
- u08 status; +
- u08 nosats; +
-} gps_type; +
-  +
-void put_char(unsigned char c); //talk to the UART +
-void suart_send(char c); +
-void run_ground_control(); +
-void _delay_10ms(char time); +
-float driftfactor(int altitude);+
 </code> </code>
code/i2c_eeprom.1225956559.txt.gz · Last modified: 2008/11/06 07:29 by laurenceb

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki