MOVEBUFFER_SIZE really does not have to be power of 2

A comment in dda_queue.h says that MOVEBUFFER_SIZE no longer needs to be
a power of 2 in size.  The comment is from a commit in 2011, but only
queue_full seems to be modified to make this true.  Other places in the
code still assume that MOVEBUFFER_SIZE is always a power of 2, wrapping
it with "& (MOVEBUFFER_SIZE-1)".

Add a MB_NEXT(x) macro which can be used to definitively find the next
slot in the queue without using any boolean math.  Replace all the
queue-position functions with new code that uses this MB_NEXT function
instead.

Also change the queue_full function to use this simpler method instead
of the complicated multi-step confusion which it did.
This commit is contained in:
Phil Hord 2015-08-28 15:37:45 -04:00 committed by Markus Hitter
parent 040e95b555
commit 47f0f0045c
1 changed files with 7 additions and 10 deletions

View File

@ -35,14 +35,13 @@ uint8_t mb_tail = 0;
/// The size does not need to be a power of 2 anymore!
DDA BSS movebuffer[MOVEBUFFER_SIZE];
/// Find the next DDA index after 'x', where 0 <= x < MOVEBUFFER_SIZE
#define MB_NEXT(x) ((x) < MOVEBUFFER_SIZE - 1 ? (x) + 1 : 0)
/// check if the queue is completely full
uint8_t queue_full() {
MEMORY_BARRIER();
if (mb_tail > mb_head) {
return (mb_tail - mb_head - 1 == 0);
} else {
return (mb_tail + MOVEBUFFER_SIZE - mb_head - 1 == 0);
}
return MB_NEXT(mb_head) == mb_tail;
}
/// check if the queue is completely empty
@ -107,8 +106,7 @@ void enqueue_home(TARGET *t, uint8_t endstop_check, uint8_t endstop_stop_cond) {
while (queue_full())
delay_us(100);
uint8_t h = mb_head + 1;
h &= (MOVEBUFFER_SIZE - 1);
uint8_t h = MB_NEXT(mb_head);
DDA* new_movebuffer = &(movebuffer[h]);
@ -148,7 +146,7 @@ void enqueue_home(TARGET *t, uint8_t endstop_check, uint8_t endstop_stop_cond) {
/// go to the next move.
/// be aware that this is sometimes called from interrupt context, sometimes not.
/// Note that if it is called from outside an interrupt it must not/can not by
/// Note that if it is called from outside an interrupt it must not/can not
/// be interrupted such that it can be re-entered from within an interrupt.
/// The timer interrupt MUST be disabled on entry. This is ensured because
/// the timer was disabled at the start of the ISR or else because the current
@ -157,8 +155,7 @@ void enqueue_home(TARGET *t, uint8_t endstop_check, uint8_t endstop_stop_cond) {
void next_move() {
while ((queue_empty() == 0) && (movebuffer[mb_tail].live == 0)) {
// next item
uint8_t t = mb_tail + 1;
t &= (MOVEBUFFER_SIZE - 1);
uint8_t t = MB_NEXT(mb_tail);
DDA* current_movebuffer = &movebuffer[t];
// Tail must be set before calling timer_set(), as timer_set() reenables
// the timer interrupt, potentially exposing mb_tail to the timer