microstrain_imu.c

Go to the documentation of this file.
00001 
00039 #include <includes.h>
00040 
00041 //Global variables for MicroStrain IMU software receive buffer
00042 unsigned char msimu_read_buffer[128];   //FIFO read buffer for data from UART
00043 unsigned char msimu_rb_index1 = 0;      //Points to location of next received byte
00044 unsigned char msimu_rb_index2 = 0;      //Points to location of oldest unused rec. byte
00045 //If Index2 = Index1, buffer contains no unused data.
00046 
00047 //Global variables for MicroStrain IMU software transmit buffer
00048 unsigned char msimu_trans_buffer[128];    //FIFO transmit buffer for data to UART
00049 unsigned char msimu_tb_index1 = 0;      //Points to location of next byte to be added to buffer
00050 unsigned char msimu_tb_index2 = 0;      //Points to location of oldest byte not yet transmitted
00051 //If Index2 = Index1, buffer contains no unsent data.
00052 
00053 unsigned long msimu_data_buffer[20]; //Holds untyped data from the imu
00054 
00055 MSIMU_COMMAND msimu_continuous_command;
00056                       
00057 //Initializes the imu with a command in continuous mode
00063 void msimu_init(MSIMU_COMMAND command)
00064 {
00065   msimu_set_continuous(command);
00066 }
00067 
00075 int msimu_get_length(MSIMU_COMMAND command){
00076   int length = 0;
00077   switch (command){
00078     case MSIMU_RAW_ACCEL_ANG_RATE: length = 31; break;
00079     case MSIMU_EULER_ANGS_ANG_RATE: length = 31; break;
00080     default: length = 31;
00081   }
00082   return length;
00083 }
00084 
00089 void msimu_isr(void) __irq
00090 { 
00091   unsigned long int interrupt_id, line_status;
00092   unsigned short int i;
00093 
00094   interrupt_id = U1IIR;
00095   //test_counter++;
00096   
00097   switch (interrupt_id & 0xE) //Look at bits 1 - 3 of U1IIR
00098   {
00099    case 4:  //receive data available (>=8 bytes in hardware receive FIFO, as set in U1FCR)
00100      for (i=0;i<8;i++)
00101      {
00102        line_status = U1LSR;
00103        msimu_read_buffer[msimu_rb_index1] = U1RBR;  //Put new data in next buffer location
00104        msimu_rb_index1 = (++msimu_rb_index1 & 127);   //Increment index; roll over to 0 after reaching 127  
00105 
00106        if (msimu_rb_index1 == msimu_rb_index2)      //software receive software overflow
00107        {
00108          msimu_rb_index1 = (--msimu_rb_index1 & 127); //overwrite most recent byte
00109          error_occurred(ERROR_MSIMU_RX_OF);
00110        }  
00111      }
00112    break;
00113 
00114    case 12: //character time-out - at least one left-over byte in hardware receive FIFO
00115      line_status = U1LSR;
00116      msimu_read_buffer[msimu_rb_index1] = U1RBR;  //Put new data in next buffer location
00117      msimu_rb_index1 = (++msimu_rb_index1 & 127);   //Increment index; roll over to 0 after reaching 127  
00118 
00119      if (msimu_rb_index1 == msimu_rb_index2)    //software receive buffer overflow
00120      {
00121        msimu_rb_index1 = (--msimu_rb_index1 & 127);  //overwrite most recent byte
00122        error_occurred(ERROR_MSIMU_RX_OF);
00123      }  
00124    
00125    break;
00126    
00127    case 2:  //transmitter hardware FIFO empty
00128      for (i=0;i<16;i++)   //Move up to 16 bytes (FIFO capacity) to FIFO
00129      {
00130        if (msimu_tb_index1 != msimu_tb_index2)  //Transmit software FIFO not empty
00131        {
00132        U1THR = msimu_trans_buffer[msimu_tb_index2]; //Transmit oldest byte from software FIFO
00133        msimu_tb_index2 = ((++msimu_tb_index2) & 127);   //Increment Index2, roll over at 128
00134        }
00135        else
00136        {
00137        U1IER &= ~(1<<1);    //Disable tranmitter holding register empty interrupt, bit 1
00138        break;
00139        }
00140      }   
00141    break;
00142    
00143    case 6:  //receive line status interrupt
00144     line_status = U1LSR;
00145     switch(line_status & 30){
00146       case 1: //Overrun Error(OE)
00147         //mcu_led_red_blink(500);
00148         break;
00149       case 2: //Parity Error(PE)
00150         //mcu_led_green_blink(500);
00151         break;
00152       case 4: //Framing Error(FE)
00153         //mcu_led_red_blink(2000);
00154         break;
00155       case 8: //Break Interrupt(BI)
00156         //mcu_led_green_blink(2000);
00157         break;
00158     }
00159    break; 
00160        
00161   }      
00162   
00163   VICVectAddr = 0;    //Reset interrupt priorities
00164 }  
00165 
00170 void msimu_set_continuous(MSIMU_COMMAND command){
00171   unsigned char c = command;
00172   unsigned char bytes[] = {0xC4,0xC1,0x29,0x00};
00173   bytes[3] = c;
00174   msimu_continuous_command = command;
00175   msimu_send_all(bytes, 4);
00176 }
00177 
00183 void msimu_send_all(unsigned char *bytes, unsigned int length)
00184 {
00185   unsigned int i;
00186   if ((length <= 16))   //length must be smaller than 16-byte FIFO and FIFO must be empty
00187   {                   
00188     if (U1LSR & (1<<5)){
00189       for (i=0;i<length;i++){
00190         U1THR = *(bytes + i);
00191       } 
00192     } else {
00193       error_occurred(ERROR_MSIMU_TX_FULL);
00194     }
00195   } else {
00196     error_occurred(ERROR_MSIMU_NUM_BYT);
00197   }
00198 }
00199 
00207 float msimu_get_data_float(MSIMU_DATA index){
00208   void *vpointer;
00209   float *fpointer;
00210   float data;
00211   vpointer = msimu_data_buffer + index;
00212   fpointer = vpointer; 
00213   data = *fpointer;
00214   return data;
00215 }
00216 
00224 int msimu_get_data_int(MSIMU_DATA index){
00225   return (int)msimu_data_buffer[index];
00226 }
00227 
00232 void msimu_update(void){msimu_parse_buffer();}
00233 
00238 void msimu_parse_buffer(void)
00239 {
00240   unsigned short int tempindex1 = 0, tempindex2 = 0, i;
00241   unsigned long int cal_checksum = 0, rec_checksum = 0, ulitemp = 0;
00242   int data_count = 0;
00243   int packet_length = 0;
00244   packet_length = msimu_get_length(msimu_continuous_command);//Number of bytes in this specific return packet
00245       
00246   tempindex2 = msimu_rb_index2;
00247   if (tempindex2 > msimu_rb_index1)
00248   {
00249     tempindex1 = msimu_rb_index1 + 128;
00250   }
00251   else
00252   {
00253     tempindex1 = msimu_rb_index1;
00254   }
00255 
00256   while ((msimu_read_buffer[tempindex2 & 127] != msimu_continuous_command) && ((tempindex1 - tempindex2) > packet_length))
00257   {
00258     tempindex2++;       //Find first byte in buffer equal to command
00259                   //while still leaving enough data to parse a full packet
00260                   //Leading characters that don't match are discarded
00261   }
00262   
00263   
00264   msimu_rb_index2 = (tempindex2 & 127);   //Adjust Index2 to point to first potential
00265                         //command byte or last character checked,
00266                         //thus skipping over any leading
00267                         //unrecognized characters.
00268     
00269   //COMMAND byte found? Parse first packet
00270   if (msimu_read_buffer[msimu_rb_index2] == msimu_continuous_command && ((tempindex1 - tempindex2) > packet_length))
00271   {
00272     //Calculate checksum
00273     cal_checksum = 0;
00274     
00275     for (i = 0; i < (packet_length-2); i++)
00276     {
00277       cal_checksum += msimu_read_buffer[(msimu_rb_index2 + i) & 127];   
00278     }
00279     
00280     cal_checksum &= 0xFFFF;     //truncate calculated checksum to 16 bits, to match received checksum
00281     
00282     //read in received checksum from end of potential packet
00283     rec_checksum = msimu_read_buffer[(msimu_rb_index2 + packet_length - 1) & 127];
00284     rec_checksum |= ((msimu_read_buffer[(msimu_rb_index2 + packet_length - 2) & 127])<<8);
00285         
00286     //Valid packet found? Parse and put received values into global variables
00287     if (cal_checksum == rec_checksum)
00288     {   
00289         i = 1;
00290         while (i < packet_length - 2) {
00291           ulitemp = (unsigned long int)msimu_read_buffer[(msimu_rb_index2 + i++) & 127];
00292           ulitemp <<= 8;
00293           ulitemp |= (unsigned long int)msimu_read_buffer[(msimu_rb_index2 + i++) & 127];
00294           ulitemp <<= 8;
00295           ulitemp |= (unsigned long int)msimu_read_buffer[(msimu_rb_index2 + i++) & 127];
00296           ulitemp <<= 8;
00297           ulitemp |= (unsigned long int)msimu_read_buffer[(msimu_rb_index2 + i++) & 127];  
00298           msimu_data_buffer[data_count] = ulitemp;
00299           data_count++; 
00300         }
00301       
00302       //Advance pointer to next unread buffer location
00303       msimu_rb_index2 = ((msimu_rb_index2 + packet_length) & 127);
00304     }
00305     
00306     else  //not a valid packet - look for next potential command byte
00307     {
00308       msimu_rb_index2 = (++msimu_rb_index2 & 127);  //Move one step past old potential command byte in buffer
00309     }
00310     
00311   }
00312 }
Generated on Tue Jun 29 16:36:14 2010 by  doxygen 1.6.3