commit a07a0b55dc3f1d479ec434e29c0c402b132c33a9
Author: Julian Binder <jabinder@andrew.cmu.edu>
Date:   Sun Nov 4 16:51:30 2012 -0500

    wrote code for the stepper motor. Requires that the caller calls init with
    the time that the function returned by the init function will be called.
    then the user must call this function at the given constant time interval
    this allows for sweep to work.
    Library also allows for independent control of the stepper.

diff --git a/scout_avr/src/stepper.cpp b/scout_avr/src/stepper.cpp
new file mode 100644
index 0000000..15176fb
--- /dev/null
+++ b/scout_avr/src/stepper.cpp
@@ -0,0 +1,119 @@
+extern "C"
+{
+#include <avr/io.h>
+}
+#include "stepper.h"
+
+/*  Stepper Motor:
+ *  Provides interface to stepper motor.
+ *  Can set direction. Outputs pulse to stepper upon call of step func
+ *  Also provides variable speed sweep
+ */
+
+struct step_t {
+  unsigned int speed; // time between steps in ms for sweep. Mininum 40ms
+  unsigned int sweep_us; //time between calls to sweep  
+  unsigned int time;
+  int pos; // position in rotation.
+  int dir; // direction. -1 CCW. 1 CW. 0 OFF
+  int ccw;
+  int cw;
+} volatile step;
+
+
+func step_init(unsigned int call_us)
+{
+  /* set update time for sweep */
+  step.sweep_us = call_us;
+  
+  /* init pos and time to 0 */
+  step.pos = 0;
+  step.time = 0;
+
+  //set control pins as output
+  DDRD |= ((1<<S_STEP) | (1<<S_DIR));
+  DDRB |= ((1<<S_MS));
+
+  //initiate to full steps
+  PORTB &= (~(1<<S_MS));
+ 
+  //initiate the step pin to be low. stepper steps on low to high
+  PORTD &= (~(1<<S_STEP));
+
+  //return function pointer to sweep to be called ever sweep_us uS. 
+  return &(step_sweep);
+}
+
+/* set direction pin */
+void step_dir(int dir)
+{
+  step.dir = dir;
+  switch(dir)
+  {
+    case 1:
+         PORTD |= (1<<S_DIR);
+      break;
+    case -1:
+         PORTD &= (~(1<<S_DIR));
+      break;
+  }
+}
+
+void step_halfstep()
+{
+  if(dir==0) return; //do not step if not enabled
+  PORTB |= (1<<S_MS); //enable microstepping
+  _asm_(
+    "nop"
+    "nop"
+    "nop"
+    "nop"
+  );//wait 250 ns for microstepping to enable
+  PORTD |= (1<<S_STEP); //step once
+  WAIT_US(1); //conform with step timing
+  PORTD &= (~(1<<S_STEP)); //bring the step bin back down
+  PORTB &= (~(1<<S_MS)); //disable microstepping
+  if(dir==1) step.pos++; //keep track of position. 1/2 step so add/sub 1
+  else step.pos--;
+}
+
+void step_fullstep()
+{
+  if(dir==0) return; //do not step if not enabled
+  PORTD |= (1<<S_STEP); //step once 
+  WAIT_US(2); //conform with step timing
+  PORTD &= (~(1<<S_STEP)); //bring the step bin back down
+  if(dir==1) step.pos+=2; // full step so add/sub 2
+  else step.pos-=2;
+}
+
+void step_flush()
+{
+  PORTD &= (~(1<<S_STEP)); //bring the step bin back down
+}
+
+/* tick every speed ms in sweep mode */
+void step_sweep_speed(unsigned int speed)
+{
+  if(speed<40) step.speed = 40000;
+  else step.speed = speed*1000;
+}
+
+
+//ccw must be less than 0 and cw must be greater than 0
+void step_sweep_bounds(int ccw, int cw)
+{
+  step.ccw = ccw;
+  step.cw = cw;
+}
+
+void step_sweep()
+{
+  step.time += sweep_us;
+  if(step.time >= speed)
+  {
+    step_halfstep();
+    if((dir == 1) && (step.cw <= pos)) dir=-1;
+    else if((dir == -1) && (step.ccw >= pos)) dir=1;
+  }
+}
diff --git a/scout_avr/src/stepper.h b/scout_avr/src/stepper.h
new file mode 100644
index 0000000..a2368f7
--- /dev/null
+++ b/scout_avr/src/stepper.h
@@ -0,0 +1,27 @@
+#ifndef _STEPPER_H_
+#define _STEPPER_H_
+
+#define S_STEP    PD6
+#define S_DIR     PD7
+
+#define S_MS      PB7
+
+//define the type func as a pointer to a void function with no parameters
+typedef void (*func)();
+
+/*returns a funciton pointer that must be called at regular intervals
+* as specified by the call_us argument
+*/
+func step_init(unsigned int call_us);
+
+
+void step_direction(int dir);
+void step_halfstep();
+void step_fullstep();
+void step_flush();
+void step_sweep_speed(unsigned int speed);
+void step_sweep_bounds(int ccw, int cw);
+void step_sweep();
+
+
+#endif
