Ring buffer for move queuing added, but not yet in use.

This commit is contained in:
Adrian Bowyer 2013-05-23 23:09:15 +01:00
parent b0ae371ec8
commit 080443f0f4
4 changed files with 147 additions and 0 deletions

View file

@ -58,5 +58,8 @@ Licence: GPL
#define START_FEED_RATE 200
#define GCODE_LENGTH 100 // Maximum lenght of internally-generated G Code string
// Movement stuff
#define RING_LENGTH 10
#endif

124
Move.h
View file

@ -53,6 +53,64 @@ class DDA
volatile boolean active;
};
//*********************************************************************************************
/*
To call the RingBuffer functions the sequences are:
Get:
if(ringBuffer->getLock())
{
if(ringBuffer->Empty())
{
ringBuffer->releaseLock();
// Nothing there - go and do something else...
}
d = Get();
ringBuffer->releaseLock();
// Do something with d and don't do another Get until you have finished with d...
}
Add:
if(ringBuffer->getLock())
{
if(ringBuffer->Full())
{
ringBuffer->releaseLock();
// No room - come back later...
}
ringBuffer->Add(...);
ringBuffer->releaseLock();
}
*/
class DDARingBuffer
{
public:
DDARingBuffer(Move* m, Platform* p);
void Add(float currentPosition[], float targetPosition[], float& u, float& v);
DDA* Get();
boolean Empty();
boolean Full();
boolean getLock();
void releaseLock();
private:
Platform* platform;
DDA* ring[RING_LENGTH];
volatile char addPointer;
volatile char getPointer;
volatile boolean locked;
};
//**************************************************************************************************
class Move
{
public:
@ -81,6 +139,8 @@ class Move
float extruderStepDistances[(1<<(DRIVES-AXES))]; // NB - limits us to 5 extruders
};
//********************************************************************************************************
inline boolean DDA::Active()
{
return active;
@ -91,6 +151,70 @@ inline boolean DDA::VelocitiesAltered()
return velocitiesAltered;
}
//*****************************************************************************************************
inline boolean DDARingBuffer::getLock()
{
if(locked)
return false;
locked = true;
return true;
}
inline void DDARingBuffer::releaseLock()
{
if(!locked)
platform->Message(HOST_MESSAGE, "Attempt to unlock already unlocked ring buffer.\n");
locked = false;
return;
}
inline void DDARingBuffer::Add(float currentPosition[], float targetPosition[], float& u, float& v)
{
if(Full())
{
platform->Message(HOST_MESSAGE, "Attempt to overfill ring buffer.\n");
return;
}
ring[addPointer]->Init(currentPosition, targetPosition, u, v);
addPointer++;
if(addPointer >= RING_LENGTH)
addPointer = 0;
}
inline DDA* DDARingBuffer::Get()
{
if(Empty())
{
platform->Message(HOST_MESSAGE, "Attempt to use empty ring buffer.\n");
return ring[getPointer]; // Safer than NULL
}
DDA* d = ring[getPointer];
getPointer++;
if(getPointer >= RING_LENGTH)
getPointer = 0;
return d;
}
inline boolean DDARingBuffer::Empty()
{
return getPointer == addPointer;
}
// Leave a gap of 2 as the last Get result may still be being processed
inline boolean DDARingBuffer::Full()
{
if(getPointer == 0)
return addPointer == RING_LENGTH - 2;
if(getPointer == 1)
return addPointer == RING_LENGTH - 1;
return addPointer == getPointer - 2;
}
//**********************************************************************************************
inline void Move::Interrupt()
{
dda->Step(true);

View file

@ -414,3 +414,16 @@ void DDA::Step(boolean noTest)
if(!active && noTest) //???
platform->SetInterrupt(-1);
}
//****************************************************************************************************
DDARingBuffer::DDARingBuffer(Move* m, Platform* p)
{
platform = p;
for(addPointer = 0; addPointer < RING_LENGTH; addPointer++)
ring[addPointer] = new DDA(m, p);
addPointer = 0;
getPointer = 0;
locked = false;
}

View file

@ -100,6 +100,10 @@ void RepRap::Spin()
heat->Spin();
}
// This function is never normally called. It is a test to time
// the interrupt function. To activate it, uncomment the line that calls
// this in Platform.ino.
void RepRap::InterruptTime()
{
char buffer[50];
@ -125,6 +129,9 @@ void RepRap::InterruptTime()
// Utilities and storage not part of any class
// Float to a string.
static long precision[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
char* ftoa(char *a, const float& f, int prec)