/* // DDA step driver for Alegro 3955 8x microstep PWM bridge chip. // This module is designed to be called at a fixed (rapid) rate and // will advance the A3955 from 0 to 7 microsteps based on the // accumulated fractions of a step provided as global aruguments. // This module deals correctly with forward and reverse step // directions (count up & down) and maintains a current open loop // step displacement count for each axis. */ /* #include *** not a std c lib */ /* Define required parallel printer ports */ #define PAR_BASE 0x378 #define PAR_DATA PAR_BASE #define PAR_CTL (PAR_BASE+2) /* Define parallel ctl port gate bits // Note that these are inverted: Writing a one // to the control port results in a Lo output. */ #define DEC_GATE 0x01 #define RA_GATE 0x02 #define PWR_DN 0x04 long x_fract, /* Fraction of a motor step to take every // clock tick. Ranges from 0 to 7 steps per // tick. Scaled integer, fractional part // ranges from ( 0..2^28 ) */ x_acc, /* Accumulates fractions of motor steps, when // an integer number of steps are accumulated // the the stepper motor state is advanced // from 1 to 7 microsteps. */ x_location, /* Accumulates the total number of microsteps // on either side of 'zero' */ y_fract, y_acc, y_location, Sec, mSec, uSec; /* loop delay counts */ char x_state, /* Current A3955 motor winding states */ y_state, step, index; static /* Table of A3955 phase, d2, d1 & d0 bits */ char stepbits[] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x7, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0xF, 0xF, 0xE, 0xD }; dda() { long n, uSec15; /* Setup 15 uSec delay loop value */ uSec15 = uSec * 15; /* Insure both latchs are 'closed' and // set the driver motor current to low */ outp( PAR_CTL, DEC_GATE|RA_GATE|PWR_DN ); /* First we update the step accumulator, then // extract the integer portion of the scaled // fraction and use that to update the motor // state, clear the integer portion of the // step accumulator, and lastly update the // accumulated location. */ x_acc += x_fract; /* If there is no change required in the Dec // motor we skip the rest of the Dec code, this // saves time and retaines the power down status */ if( index = x_acc >> 28 ) { x_acc -= x_acc & 0xf0000000; x_state += index; x_location += index; /* Now we build the coil current and phase // control bits for the current motor state. */ step = ( stepbits[ x_state & 0x1f] << 4 ) /* Bridge drive A */ | ( stepbits[(x_state+24) & 0x1f] ); /* Bridge drive B */ /* Output the step bits to the printer port, then // open the DEC latch gate, delay to insure latch // setup timeing is met, then drop the latch gate // and return the driver chip current to high. // **future versions should read back the // comand reg and then AND out DEC_GATE & PWR_DN */ outp( PAR_DATA, step ); outp( PAR_CTL, RA_GATE ); for( n=0; n> 28 ) { y_acc -= y_acc & 0xf0000000; y_state += index; y_location += index; step = ( stepbits[ y_state & 0x1f] << 4 ) | ( stepbits[(y_state+24) & 0x1f] ); outp( PAR_DATA, step ); outp( PAR_CTL, DEC_GATE ); for( n=0; n