abs_enc.c

Go to the documentation of this file.
00001 
00050 #include <includes.h>
00051 
00052 static volatile AE_ID ae_current_encoder; 
00053 static AE_ENCODER ae_encoders[2]; 
00054 static volatile AE_STATUS ae_status = AE_DONE; 
00065 void ae_init_encoder(AE_ID encoder_id, int zero, int rpm, int cpr){
00066   if (encoder_id < AE_LAST){
00067     AE_ENCODER* encoder = &(ae_encoders[encoder_id]);
00068     encoder->read = 1;
00069     encoder->value = 0;
00070     encoder->zero = zero;
00071     encoder->delta = (int)((float)rpm * (float)cpr / (60.0 * 1000.0 * SCHED_SPEED)) + 5;
00072   } else {
00073     error_occurred(ERROR_AE_INVALID_ID);
00074   }
00075 }
00076 
00083 void ae_update(void)
00084 {                                                       
00085   if (ae_encoders[AE_1].read){ //if reading from encoder 1 or both encoder 1 and 2
00086     ae_read(AE_1); //begin read from encoder 1
00087     ae_status = AE_NOT_DONE; 
00088   } else if (ae_encoders[AE_2].read){ //if only reading from encoder 2
00089     ae_read(AE_2); //begin read from encoder 2
00090     ae_status = AE_NOT_DONE;
00091   } //not reading any encoders
00092 }
00093 
00098 static void ae_read(AE_ID encoder_id)
00099 {
00100   S0SPCR |= (1<<7); //enable interrupts
00101   switch (encoder_id){
00102     case AE_1: FIO0CLR = (1<<13); break; //set P0.13 low to read from J3
00103     case AE_2: FIO0SET = (1<<13); break; //set P0.13 high to read from J9
00104     default: error_occurred(ERROR_AE_INVALID_ID); break;
00105   }
00106   ae_current_encoder = encoder_id; //we are currently waiting for data for this encoder
00107   S0SPDR = 0; //send dummy data to begin transfer
00108 }
00109   
00116 int ae_get_pos(AE_ID encoder_id)
00117 {
00118   if (encoder_id < AE_LAST){ //valid encoder id
00119     AE_ENCODER* encoder = &(ae_encoders[encoder_id]);
00120     return encoder->value - encoder->zero;
00121   } else {
00122     error_occurred(ERROR_AE_INVALID_ID);
00123     return 0;
00124   }
00125 } 
00126 
00131 void ae_wait(void){
00132   while (ae_status != AE_DONE) {} 
00133 }
00134 
00140 void ae_isr(void) __irq
00141 {
00142   int int_state = S0SPSR;
00143   int new_data;
00144   AE_ENCODER* enc;
00145   
00146   S0SPINT = 1;            //clear interrupt flag in SPI register
00147   
00148   // ***** READ NEW DATA ***** //
00149   enc = &(ae_encoders[ae_current_encoder]);
00150   new_data = S0SPDR&0x1FFF; //read data from SPI
00151   //make sure data is valid
00152   if (new_data > enc->value + enc->delta){ //over bounds, limit
00153     new_data = enc->value + enc->delta;
00154     error_occurred(ERROR_AE_SPIKE); //report error
00155   } else if (new_data < enc->value - enc->delta){ //below bounds, limit
00156     new_data = enc->value - enc->delta;
00157     error_occurred(ERROR_AE_SPIKE); //report error
00158   }
00159   
00160   enc->value = new_data;
00161   
00162   // ***** START NEXT ENCODER, OR FINISHED ***** //
00163   if (ae_current_encoder == AE_1){ //currently reading data from encoder 1
00164     if (ae_encoders[AE_2].read){ //if also using encoder 2
00165       ae_read(AE_2); //begin read from encoder 2
00166     } else { //otherwise we were only reading from encoder 1
00167       ae_status = AE_DONE; //so we're done!
00168       S0SPCR &= ~(1<<7); //disable interrupts
00169     }
00170   } else if (ae_current_encoder == AE_2){ //currently reading data from encoder 2
00171     ae_status = AE_DONE; //always do encoder 1 then 2, so we're done!
00172     S0SPCR &= ~(1<<7);  //disable interrupts
00173   }
00174   
00175   VICVectAddr = 0;          //acknowledge interrupt, clear vector to interrupt function   
00176 }
00177 
00178 
Generated on Tue Jun 29 16:36:14 2010 by  doxygen 1.6.3