// This is a step translator for AVR microcontrollers // Copyright 2005 Jeff Epler // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include #include /* Pin assignments: Inputs: PINB0 - Z step PINB1 - A sftep PINB2 - X direction PINB3 - Y direction PINB4 - Z direction PINB5 - A direction PIND2 - X step PIND3 - Y step Outputs: PORTA0..PORTA3 - X windings PORTA4..PORTA7 - Y windings PORTC0..PORTC3 - Z windings XXX: must disable JTAG in high fuse byte PORTC4..PORTC7 - A windings */ /* Motors are active-low, half-step excitation, windings in order */ #define HALFSTEP #ifdef HALFSTEP uint8_t motor_steps[] PROGMEM = {0xe, 0xc, 0xd, 0x9, 0xb, 0x3, 0x7, 0x6}; #else uint8_t motor_steps[] PROGMEM = {0xc, 0x9, 0x3, 0x6}; #endif #define STEP(x) PRG_RDB(motor_steps + x) #define motor_nsteps (sizeof(motor_steps) / sizeof(motor_steps[0])) register uint8_t sx __asm__("r8"), sy __asm__("r9"), sz __asm__("r10"), sa __asm__("r11"); static inline void step_motor_x(int dir) { if(dir) sx = (sx + 1) % motor_nsteps; else sx = (sx + motor_nsteps - 1) % motor_nsteps; PORTA = (PORTA & 0xf0) | STEP(sx); } static inline void step_motor_y(int dir) { if(dir) sy = (sy + 1) % motor_nsteps; else sy = (sy + motor_nsteps - 1) % motor_nsteps; PORTA = (PORTA & 0x0f) | (STEP(sy) << 4); } static inline void step_motor_z(int dir) { if(dir) sz = (sz + 1) % motor_nsteps; else sz = (sz + motor_nsteps - 1) % motor_nsteps; PORTC = (PORTC & 0xf0) | STEP(sz); } static inline void step_motor_a(int dir) { if(dir) sa = (sa + 1) % motor_nsteps; else sa = (sa + motor_nsteps - 1) % motor_nsteps; PORTC = (PORTC & 0x0f) | (STEP(sa) << 4); } static inline void reset_t0(void) { TCNT0 = 0xff; } static inline void reset_t1(void) { TCNT1H = 0xff; TCNT1L = 0xff; } SIGNAL(SIG_INTERRUPT0) { step_motor_x(PINB & _BV(2)); } SIGNAL(SIG_INTERRUPT1) { step_motor_y(PINB & _BV(3)); } SIGNAL(SIG_OVERFLOW0) { reset_t0(); step_motor_z(PINB & _BV(4)); } SIGNAL(SIG_OVERFLOW1) { reset_t1(); step_motor_a(PIND & _BV(4)); } static inline int ioinit(void) { MCUCSR |= 1<