Skip to content

Commit

Permalink
Get rid of defered enabling of the step interrupt again.
Browse files Browse the repository at this point in the history
This makes the code cleaner and the reduction of code
probably easily compensates for keeping global interrupts
enabled for a bit longer. Talked to macscifi about this.

Saves about 300 bytes of binary size.
  • Loading branch information
Traumflug committed Nov 21, 2011
1 parent fcd11a6 commit 53490bb
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 52 deletions.
13 changes: 5 additions & 8 deletions dda.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -482,8 +482,6 @@ void dda_start(DDA *dda) {
Next, we work out how long until our next step using the selected acceleration algorithm and set the timer. Next, we work out how long until our next step using the selected acceleration algorithm and set the timer.
Then we decide if this was the last step for this move, and if so mark this dda as dead so next timer interrupt we can start a new one. Then we decide if this was the last step for this move, and if so mark this dda as dead so next timer interrupt we can start a new one.
Finally we de-assert any asserted step pins. Finally we de-assert any asserted step pins.
\todo take into account the time that interrupt takes to run
*/ */
void dda_step(DDA *dda) { void dda_step(DDA *dda) {
uint8_t endstop_stop; ///< Stop due to endstop trigger uint8_t endstop_stop; ///< Stop due to endstop trigger
Expand Down Expand Up @@ -598,10 +596,11 @@ void dda_step(DDA *dda) {
} }


#if STEP_INTERRUPT_INTERRUPTIBLE #if STEP_INTERRUPT_INTERRUPTIBLE
// since we have sent steps to all the motors that will be stepping and the rest of this function isn't so time critical, // Since we have sent steps to all the motors that will be stepping
// this interrupt can now be interruptible // and the rest of this function isn't so time critical, this interrupt
// however we must ensure that we don't step again while computing the below, so disable *this* interrupt but allow others to fire // can now be interruptible by other interrupts.
// disableTimerInterrupt(); // The step interrupt is disabled before entering dda_step() to ensure
// that we don't step again while computing the below.
sei(); sei();
#endif #endif


Expand Down Expand Up @@ -695,8 +694,6 @@ void dda_step(DDA *dda) {
else else
steptimeout = 0; steptimeout = 0;


cli();

#ifdef ACCELERATION_RAMPING #ifdef ACCELERATION_RAMPING
// we don't hit maximum speed exactly with acceleration calculation, so limit it here // we don't hit maximum speed exactly with acceleration calculation, so limit it here
// the nice thing about _not_ setting dda->c to dda->c_min is, the move stops at the exact same c as it started, so we have to calculate c only once for the time being // the nice thing about _not_ setting dda->c to dda->c_min is, the move stops at the exact same c as it started, so we have to calculate c only once for the time being
Expand Down
20 changes: 4 additions & 16 deletions dda_queue.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -74,13 +74,10 @@ void queue_step() {
current_movebuffer->live = current_movebuffer->waitfor_temp = 0; current_movebuffer->live = current_movebuffer->waitfor_temp = 0;
serial_writestr_P(PSTR("Temp achieved\n")); serial_writestr_P(PSTR("Temp achieved\n"));
} }

#if STEP_INTERRUPT_INTERRUPTIBLE
sei();
#endif
} }
else { else {
// NOTE: dda_step makes this interrupt interruptible after steps have been sent but before new speed is calculated. // NOTE: dda_step makes this interrupt interruptible for some time,
// see STEP_INTERRUPT_INTERRUPTIBLE.
dda_step(current_movebuffer); dda_step(current_movebuffer);
} }
} }
Expand Down Expand Up @@ -135,18 +132,9 @@ void enqueue_home(TARGET *t, uint8_t endstop_check, uint8_t endstop_stop_cond) {
SREG = save_reg; SREG = save_reg;


if (isdead) { if (isdead) {
timer1_compa_deferred_enable = 0;
next_move(); next_move();
if (timer1_compa_deferred_enable) { // Compensate for the cli() in setTimer().
uint8_t save_reg = SREG; sei();
cli();
CLI_SEI_BUG_MEMORY_BARRIER();

TIMSK1 |= MASK(OCIE1A);

MEMORY_BARRIER();
SREG = save_reg;
}
} }
} }


Expand Down
46 changes: 20 additions & 26 deletions timer.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ volatile uint8_t clock_flag_10ms = 0;
volatile uint8_t clock_flag_250ms = 0; volatile uint8_t clock_flag_250ms = 0;
volatile uint8_t clock_flag_1s = 0; volatile uint8_t clock_flag_1s = 0;


volatile uint8_t timer1_compa_deferred_enable = 0;

/// comparator B is the system clock, happens every TICK_TIME /// comparator B is the system clock, happens every TICK_TIME
ISR(TIMER1_COMPB_vect) { ISR(TIMER1_COMPB_vect) {
// set output compare register to the next clock tick // set output compare register to the next clock tick
Expand Down Expand Up @@ -83,7 +81,6 @@ ISR(TIMER1_COMPA_vect) {


// disable this interrupt. if we set a new timeout, it will be re-enabled when appropriate // disable this interrupt. if we set a new timeout, it will be re-enabled when appropriate
TIMSK1 &= ~MASK(OCIE1A); TIMSK1 &= ~MASK(OCIE1A);
timer1_compa_deferred_enable = 0;


// stepper tick // stepper tick
queue_step(); queue_step();
Expand All @@ -92,19 +89,7 @@ ISR(TIMER1_COMPA_vect) {
#ifdef DEBUG_LED_PIN #ifdef DEBUG_LED_PIN
WRITE(DEBUG_LED_PIN, 0); WRITE(DEBUG_LED_PIN, 0);
#endif #endif


// Enable the timer1_compa interrupt, if needed,
// but only do it after disabling global interrupts.
// This will cause push any possible timer1a interrupt
// to the far side of the return, protecting the
// stack from recursively clobbering memory.

cli();
CLI_SEI_BUG_MEMORY_BARRIER();

if (timer1_compa_deferred_enable) {
TIMSK1 |= MASK(OCIE1A);
}
return; return;
} }


Expand Down Expand Up @@ -136,17 +121,20 @@ void timer_init()
} }


#ifdef HOST #ifdef HOST
/// specify how long until the step timer should fire /*! Specify how long until the step timer should fire.
\param delay in CPU ticks
This enables the step interrupt, but also disables interrupts globally.
So, if you use it from inside the step interrupt, make sure to do so
as late as possible. If you use it from outside the step interrupt,
do a sei() after it to make the interrupt actually fire.
*/
void setTimer(uint32_t delay) void setTimer(uint32_t delay)
{ {
// save interrupt flag // save interrupt flag
uint8_t sreg = SREG; uint8_t sreg = SREG;
uint16_t step_start = 0; uint16_t step_start = 0;


// disable interrupts
cli();
CLI_SEI_BUG_MEMORY_BARRIER();

// re-enable clock interrupt in case we're recovering from emergency stop // re-enable clock interrupt in case we're recovering from emergency stop
TIMSK1 |= MASK(OCIE1B); TIMSK1 |= MASK(OCIE1B);


Expand Down Expand Up @@ -184,14 +172,20 @@ void setTimer(uint32_t delay)
OCR1A = step_start; OCR1A = step_start;
} }


// Defer the enabling of the timer1_CompA interrupts. // Enable this interrupt, but only do it after disabling

// global interrupts. This will cause push any possible
timer1_compa_deferred_enable = 1; // timer1a interrupt to the far side of the return, protecting the
// stack from recursively clobbering memory.
cli();
CLI_SEI_BUG_MEMORY_BARRIER();
TIMSK1 |= MASK(OCIE1A);

} else { } else {
// TODO: as the interrupt is designed to fire only once,
// doing a setTimer(0) should be obsolete.
// flag: move has ended // flag: move has ended
next_step_time = 0; next_step_time = 0;
TIMSK1 &= ~MASK(OCIE1A); TIMSK1 &= ~MASK(OCIE1A);
timer1_compa_deferred_enable = 0;
} }


// restore interrupt flag // restore interrupt flag
Expand Down
2 changes: 0 additions & 2 deletions timer.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ extern volatile uint8_t clock_flag_10ms;
extern volatile uint8_t clock_flag_250ms; extern volatile uint8_t clock_flag_250ms;
extern volatile uint8_t clock_flag_1s; extern volatile uint8_t clock_flag_1s;


extern volatile uint8_t timer1_compa_deferred_enable;

// If the specific bit is set, execute the following block exactly once // If the specific bit is set, execute the following block exactly once
// and then clear the flag. // and then clear the flag.
#define ifclock(F) for (;F;F=0 ) #define ifclock(F) for (;F;F=0 )
Expand Down

0 comments on commit 53490bb

Please sign in to comment.