abs_enc.c File Reference

Absolute Encoder module. More...

Go to the source code of this file.

Functions

int ae_get_pos (AE_ID encoder_id)
 Returns the position of the given encoder.
void ae_init_encoder (AE_ID encoder_id, int zero, int rpm, int cpr)
 Initializes an encoder.
void ae_isr (void)
 The interrupt service routine for the absolute encoder module.
static void ae_read (AE_ID encoder_id)
 Reads in the data for the given encoder.
void ae_update (void)
 Updates the absolute encoder data.
void ae_wait (void)
 Blocks until the current encoder update is complete.

Variables

static volatile AE_ID ae_current_encoder
 The current encoder data is being read from.
static AE_ENCODER ae_encoders [2]
 Currently only using two encoders.
static volatile AE_STATUS ae_status = AE_DONE
 The status of the absolute encoder module.

Detailed Description

Absolute Encoder module.

Reads from two magnetic encoders. For each call to ae_update, all encoders set by ae_init_encoder_* are read from.

Make sure to call ae_init_encoder_* (* = 1 or 2) for the encoders you wish to use. Then call ae_update from every row of the schedule.

B2A_MC: J3 = encoder 1 J9 = encoder 2

Example Hardware and Register Setup:

  // *******************************************************************************
  // SPI0 Setup for Absolute Encoder 
  // *******************************************************************************
  //Set Pinsel bits for controlling SPI0:
  PINSEL0 &= ~(3<<8); //clear pin P0.4
  PINSEL0 &= ~(3<<10); //clear pin P0.5 
  PINSEL0 &= ~(3<<26); //clear pin P0.5
  PINSEL0 |= (1<<8);    //SCKO for SPI0 (clock for data transfer)
  PINSEL0 |= (1<<10);     //MISO for SPI0 (master in slave out data)
  PINSEL0 |= (0<<26);   //set P0_13 to GPIO -- set pin to output
  FIO0DIR |= (1<<13);   //this pin controls multiplexers (SN74LVC1G3157) via the SN74LVC1G07 level shitfer
                              //when P0_13 is low J3 encoder can be read via SPI
                  //when   ''  is high J9 encoder can be read 
  //Set Up SPI Register:
  S0SPCR |= (1<<2) | (0<<8) | (1<<9) | (1<<10) | (1<<11);   //recieve 14 bits of data
  S0SPCR |= (1<<4);       //set clock polarity to active low
  S0SPCR |= (1<<5);       //activate master mode
  S0SPCCR = 60; //set data transfer rate; PCLK / S0SPCCR = 60MHz / 60 = 1MHz

The isr ae_isr will also need to be setup:

  // ************ PRIORITY 10 ******************
  //Absolute Encoder
  VICVectAddr10 = (unsigned long)ae_isr;
  VICVectCntl10 = 0x20 | VIC_SPI0; 
  VICIntEnable = 1 << VIC_SPI0; 
Author:
Nicolas Williamson
Philip Johnson
Date:
July 2009

Definition in file abs_enc.c.


Function Documentation

int ae_get_pos ( AE_ID  encoder_id  ) 

Returns the position of the given encoder.

Position = data - zero_offset.

Parameters:
encoder_id The encoder to read from, either AE_1 (J3) or AE_2 (J9).
Returns:
The latest position of the encoder.

Definition at line 116 of file abs_enc.c.

References error_occurred(), AE_ENCODER::value, and AE_ENCODER::zero.

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 } 

void ae_init_encoder ( AE_ID  encoder_id,
int  zero,
int  rpm,
int  cpr 
)

Initializes an encoder.

Call this for each encoder you wish to use.

Parameters:
encoder_id The id of the encoder to initialize.
zero The zero offset for the encoder. Check what this by starting with it at zero, then moving the shaft to the desired zero position. The output at that position should be the zero.
rpm The max rpm of the shaft the encoder is attached to.
cpr The counts per revolution of the encoder.

Definition at line 65 of file abs_enc.c.

References AE_ENCODER::delta, error_occurred(), AE_ENCODER::read, AE_ENCODER::value, and AE_ENCODER::zero.

00065                                                                   {
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 }

void ae_isr ( void   ) 

The interrupt service routine for the absolute encoder module.

When one encoder has completed its readout, causes an interrupt which will read the data in software.

Definition at line 140 of file abs_enc.c.

References ae_current_encoder, ae_read(), ae_status, AE_ENCODER::delta, error_occurred(), and AE_ENCODER::value.

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 }

static void ae_read ( AE_ID  encoder_id  )  [static]

Reads in the data for the given encoder.

Parameters:
encoder_id The encoder to read from. Either AE_1 (J3) or AE_2 (J9)

Definition at line 98 of file abs_enc.c.

References ae_current_encoder, and error_occurred().

Referenced by ae_isr(), and ae_update().

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 }

void ae_update ( void   ) 

Updates the absolute encoder data.

CALL EVERY SCHEDULE ROW. Reads from the encoders are interrupt driven. If you only want to read once, you can call ae_update, and then use ae_wait which will block until the data has been read.

Definition at line 83 of file abs_enc.c.

References ae_read(), and ae_status.

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 }

void ae_wait ( void   ) 

Blocks until the current encoder update is complete.

Only use in init functions, such as init_software or init_values.

Definition at line 131 of file abs_enc.c.

References ae_status.

00131                   {
00132   while (ae_status != AE_DONE) {} 
00133 }


Variable Documentation

volatile AE_ID ae_current_encoder [static]

The current encoder data is being read from.

Definition at line 52 of file abs_enc.c.

Referenced by ae_isr(), and ae_read().

AE_ENCODER ae_encoders[2] [static]

Currently only using two encoders.

Definition at line 53 of file abs_enc.c.

volatile AE_STATUS ae_status = AE_DONE [static]

The status of the absolute encoder module.

Definition at line 54 of file abs_enc.c.

Referenced by ae_isr(), ae_update(), and ae_wait().

Generated on Tue Jun 29 16:36:14 2010 by  doxygen 1.6.3