Move ring buffer implemented and (preliminarily) tested. Look ahead not yet done.

This commit is contained in:
Adrian Bowyer 2013-05-24 22:03:48 +01:00
parent 080443f0f4
commit 557ea85073
3 changed files with 81 additions and 76 deletions

99
Move.h
View file

@ -55,53 +55,19 @@ class DDA
//*********************************************************************************************
/*
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);
boolean Add(float currentPosition[], float targetPosition[], float& u, float& v);
DDA* Get();
private:
boolean Empty();
boolean Full();
boolean getLock();
void releaseLock();
private:
Platform* platform;
DDA* ring[RING_LENGTH];
volatile char addPointer;
@ -130,8 +96,10 @@ class Move
Platform* platform;
GCodes* gCodes;
DDA* dda;
DDARingBuffer* ddaRingBuffer;
unsigned long lastTime;
boolean active;
boolean moveWaiting;
float currentFeedrate;
float currentPosition[AXES]; // Note - drives above AXES are always relative moves
float nextMove[DRIVES + 1]; // Extra is for feedrate
@ -164,37 +132,60 @@ inline boolean DDARingBuffer::getLock()
inline void DDARingBuffer::releaseLock()
{
if(!locked)
platform->Message(HOST_MESSAGE, "Attempt to unlock already unlocked ring buffer.\n");
platform->Message(HOST_MESSAGE, "Attempt to unlock an already unlocked ring buffer!\n");
locked = false;
return;
}
inline void DDARingBuffer::Add(float currentPosition[], float targetPosition[], float& u, float& v)
inline boolean DDARingBuffer::Add(float currentPosition[], float targetPosition[], float& u, float& v)
{
if(getLock())
{
if(Full())
{
platform->Message(HOST_MESSAGE, "Attempt to overfill ring buffer.\n");
return;
releaseLock();
return false;
}
if(ring[addPointer]->Active())
{
platform->Message(HOST_MESSAGE, "Attempt to alter an active ring buffer entry!\n");
releaseLock();
return false;
}
if(!ring[addPointer]->Init(currentPosition, targetPosition, u, v))
{
// Throw it away
releaseLock();
return true;
}
ring[addPointer]->Init(currentPosition, targetPosition, u, v);
addPointer++;
if(addPointer >= RING_LENGTH)
addPointer = 0;
releaseLock();
return true;
}
return false;
}
inline DDA* DDARingBuffer::Get()
{
DDA* result = NULL;
if(getLock())
{
if(Empty())
{
platform->Message(HOST_MESSAGE, "Attempt to use empty ring buffer.\n");
return ring[getPointer]; // Safer than NULL
releaseLock();
return NULL;
}
DDA* d = ring[getPointer];
result = ring[getPointer];
getPointer++;
if(getPointer >= RING_LENGTH)
getPointer = 0;
return d;
releaseLock();
return result;
}
return NULL;
}
inline boolean DDARingBuffer::Empty()
@ -217,7 +208,21 @@ inline boolean DDARingBuffer::Full()
inline void Move::Interrupt()
{
if(dda == NULL)
{
dda = ddaRingBuffer->Get();
if(dda != NULL)
dda->Start(true);
return;
}
if(dda->Active())
{
dda->Step(true);
return;
}
dda = NULL;
}

View file

@ -25,7 +25,8 @@ Move::Move(Platform* p, GCodes* g)
active = false;
platform = p;
gCodes = g;
dda = new DDA(this, platform);
dda = NULL;
ddaRingBuffer = new DDARingBuffer(this, platform);
}
void Move::Init()
@ -80,6 +81,7 @@ void Move::Init()
lastTime = platform->Time();
currentFeedrate = START_FEED_RATE;
moveWaiting = false;
active = true;
}
@ -98,20 +100,23 @@ void Move::Spin()
void Move::Qmove()
{
if(!gCodes->ReadMove(nextMove))
return;
//FIXME
float u = 0.0; // This will provoke the code to select the jerk values.
float v = 0.0;
boolean work = dda->Init(currentPosition, nextMove, u, v);
if(moveWaiting)
{
if(ddaRingBuffer->Add(currentPosition, nextMove, u, v))
{
for(char i = 0; i < AXES; i++)
currentPosition[i] = nextMove[i];
currentFeedrate = nextMove[DRIVES];
moveWaiting = false;
}
return;
}
if(work)
dda->Start(true);
moveWaiting = gCodes->ReadMove(nextMove);
}
void Move::GetCurrentState(float m[])
@ -411,8 +416,8 @@ void DDA::Step(boolean noTest)
stepCount++;
active = stepCount < totalSteps;
if(!active && noTest) //???
platform->SetInterrupt(-1);
if(!active && noTest)
platform->SetInterrupt(STANDBY_INTERRUPT_RATE);
}
//****************************************************************************************************

View file

@ -152,15 +152,10 @@ Licence: GPL
#define BAUD_RATE 115200 // Communication speed of the USB if needed.
#define STANDBY_INTERRUPT_RATE 200 // Microseconds
/****************************************************************************************************/
//class RepRap;
void TC3_Handler();
class Platform
{
public:
@ -388,7 +383,7 @@ void Platform::InitialiseInterrupts()
TC_Configure(TC1, 0, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
TC1->TC_CHANNEL[0].TC_IER=TC_IER_CPCS;
TC1->TC_CHANNEL[0].TC_IDR=~TC_IER_CPCS;
NVIC_DisableIRQ(TC3_IRQn);
SetInterrupt(STANDBY_INTERRUPT_RATE);
}
inline void Platform::SetInterrupt(long t)