diff --git a/lambda/Makefile b/lambda/Makefile index 5525397..8da700c 100644 --- a/lambda/Makefile +++ b/lambda/Makefile @@ -3,7 +3,7 @@ MCU = atmega328p # Currently supported are 1 MHz and 8 MHz -F_CPU = 8000000 +F_CPU = 1000000 # Also try BAUD = 19200 or 38400 if you're feeling lucky. BAUD = 9600 diff --git a/lambda/airgate.c b/lambda/airgate.c index fbd7243..550086c 100644 --- a/lambda/airgate.c +++ b/lambda/airgate.c @@ -6,21 +6,23 @@ */ #include +#include #include #include #include #include #include "airgate.h" #include "integers.h" +#include "interrupts.h" // TODO pins /* Direction */ volatile static int8_t dir = 0; +/* Target position */ +volatile static uint8_t target = 0; /* Current position */ volatile static uint16_t pos = 0; -/* Target position */ -volatile static int16_t target = 0; /* Steps remaining */ volatile static uint16_t steps = 0; /* Steps done */ @@ -52,7 +54,7 @@ // set start speed OCR2A = speed; // start timer2 - TCCR2B |= (1 << CS22) | (1 << CS21); + TCCR2B |= TIMER2_PRESCALE; } /** @@ -70,14 +72,13 @@ * the motor. */ static void set(void) { - int16_t diff = (target << SCALE) - pos; + stop(); + int16_t diff = (((int16_t)target) << SCALE) - pos; if (diff != 0) { dir = MAX(-1, MIN(diff, 1)); speed = MIN_SPEED; - ATOMIC_BLOCK(ATOMIC_FORCEON) { - steps = abs(diff); - ramp = MIN(MIN_SPEED - MAX_SPEED, steps >> 1); - } + steps = abs(diff); + ramp = MIN(MIN_SPEED - MAX_SPEED, steps >> 1); start(); } } @@ -95,33 +96,35 @@ OCR2A = speed; } else { done = 0; - stop(); // move to new target position if necessary set(); - if (pos == 0) { - // driver sleep mode - // TODO when is it best to do this? - PORTC &= ~(1 << PC5); - } } } void setAirgate(uint8_t const position) { + if (position == target) { + return; + } + target = position; + bool idle = false; ATOMIC_BLOCK(ATOMIC_FORCEON) { - if (position == target) { - return; - } - target = position; if (steps > 0) { // motor busy - decelerate and move to target position when stopped steps = MIN(ramp, steps); } else { // move to target position - set(); + idle = true; } } + if (idle) { + set(); + } } uint8_t getAirgate(void) { return target; } + +void setSleepMode(void) { + PORTC &= ~(1 << PC5); +} diff --git a/lambda/airgate.h b/lambda/airgate.h index 6fbf49f..cab1454 100644 --- a/lambda/airgate.h +++ b/lambda/airgate.h @@ -36,4 +36,9 @@ */ uint8_t getAirgate(void); +/** + * Sets the driver in sleep mode. + */ +void setSleepMode(void); + #endif /* AIRGATE_H_ */ diff --git a/lambda/interrupts.h b/lambda/interrupts.h index 436faa1..385cff0 100644 --- a/lambda/interrupts.h +++ b/lambda/interrupts.h @@ -22,6 +22,8 @@ // #define TIMER1_CTC_TOP 15 // 2 kHz is less noisy on the small piezo beeper #define TIMER1_COMP_MATCH 31 + // timer2 clock prescaler/32 = 32.25 kHz @ 1MHz + #define TIMER2_PRESCALE (1 << CS21) | (1 << CS20) #elif F_CPU == 8000000 // timer0 clock prescaler/1024 = 7.812 kHz @ 8 MHz #define TIMER0_PRESCALE (1 << CS02) | (1 << CS00) @@ -33,6 +35,8 @@ // #define TIMER1_CTC_TOP 15 // 2 kHz is less noisy on the small piezo beeper #define TIMER1_COMP_MATCH 31 + // timer2 clock prescaler/256 = 32.25 kHz @ 8MHz + #define TIMER2_PRESCALE (1 << CS22) | (1 << CS21) #endif /**