// a negative bias in the uint32_t conversion that results in long-term
// negative drift.
uint16_t steps = round(fabs(travel_steps));
- uint32_t ticks_per_step = seg_clocks / (steps + 0.5);
+ // TODO why do we need to multiply by 2 here?
+ uint32_t ticks_per_step = seg_clocks / (steps + 0.5) * 2;
// Find the clock rate that will fit the required number of steps
- if (ticks_per_step & 0xffff8000UL) {
+ if (ticks_per_step & 0xffff0000UL) {
ticks_per_step /= 2;
seg_clocks /= 2;
- if (ticks_per_step & 0xffff8000UL) {
+ if (ticks_per_step & 0xffff0000UL) {
ticks_per_step /= 2;
seg_clocks /= 2;
- if (ticks_per_step & 0xffff8000UL) {
+ if (ticks_per_step & 0xffff0000UL) {
ticks_per_step /= 2;
seg_clocks /= 2;
- if (ticks_per_step & 0xffff8000UL) m->timer_clock = 0; // Off
+ if (ticks_per_step & 0xffff0000UL) m->timer_clock = 0; // Off
else m->timer_clock = TC_CLKSEL_DIV8_gc;
} else m->timer_clock = TC_CLKSEL_DIV4_gc;
} else m->timer_clock = TC_CLKSEL_DIV2_gc;
} else m->timer_clock = TC_CLKSEL_DIV1_gc;
- m->timer_period = ticks_per_step * 2; // TODO why do we need x2 here?
+ m->timer_period = ticks_per_step;
m->steps = seg_clocks / ticks_per_step; // Compute actual steps
// Setup the direction, compensating for polarity.
- if (0 <= travel_steps) // positive direction
- m->direction = DIRECTION_CW ^ m->polarity;
-
+ if (0 <= travel_steps) m->direction = DIRECTION_CW ^ m->polarity;
else {
m->direction = DIRECTION_CCW ^ m->polarity;
- m->steps = -m->steps;
+ m->steps *= -1;
}
}
uint8_t st_runtime_isbusy() {return st.busy;}
+/// Interrupt handler for calling move exec function.
+/// ADC channel 0 triggered by load ISR as a "software" interrupt.
+ISR(ADCB_CH0_vect) {
+ mp_exec_move();
+}
+
+
/// Step timer interrupt routine
/// Dequeue move and load into stepper struct
ISR(STEP_TIMER_ISR) {
// If there are no more moves
if (!st.move_ready) {
TIMER_STEP.PER = STEP_TIMER_POLL;
-
- sei(); // Enable interupts
mp_exec_move();
return;
}
st.prep_dwell = 0; // clear dwell
st.move_ready = false; // flip the flag back
- // Exec and prep next move
- sei(); // Enable interupts
- mp_exec_move();
+ // Use ADC as a "software" interrupt to prep next move
+ ADCB_CH0_INTCTRL = ADC_CH_INTLVL_LO_gc; // trigger LO interrupt
+ ADCB_CTRLA = ADC_ENABLE_bm | ADC_CH0START_bm;
}