Move ring buffer implemented and (preliminarily) tested. Look ahead not yet done.
This commit is contained in:
parent
080443f0f4
commit
557ea85073
3 changed files with 81 additions and 76 deletions
117
Move.h
117
Move.h
|
@ -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(Full())
|
||||
if(getLock())
|
||||
{
|
||||
platform->Message(HOST_MESSAGE, "Attempt to overfill ring buffer.\n");
|
||||
return;
|
||||
if(Full())
|
||||
{
|
||||
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;
|
||||
}
|
||||
addPointer++;
|
||||
if(addPointer >= RING_LENGTH)
|
||||
addPointer = 0;
|
||||
releaseLock();
|
||||
return true;
|
||||
}
|
||||
|
||||
ring[addPointer]->Init(currentPosition, targetPosition, u, v);
|
||||
addPointer++;
|
||||
if(addPointer >= RING_LENGTH)
|
||||
addPointer = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline DDA* DDARingBuffer::Get()
|
||||
{
|
||||
if(Empty())
|
||||
DDA* result = NULL;
|
||||
if(getLock())
|
||||
{
|
||||
platform->Message(HOST_MESSAGE, "Attempt to use empty ring buffer.\n");
|
||||
return ring[getPointer]; // Safer than NULL
|
||||
if(Empty())
|
||||
{
|
||||
releaseLock();
|
||||
return NULL;
|
||||
}
|
||||
result = ring[getPointer];
|
||||
getPointer++;
|
||||
if(getPointer >= RING_LENGTH)
|
||||
getPointer = 0;
|
||||
releaseLock();
|
||||
return result;
|
||||
}
|
||||
DDA* d = ring[getPointer];
|
||||
getPointer++;
|
||||
if(getPointer >= RING_LENGTH)
|
||||
getPointer = 0;
|
||||
return d;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline boolean DDARingBuffer::Empty()
|
||||
|
@ -217,7 +208,21 @@ inline boolean DDARingBuffer::Full()
|
|||
|
||||
inline void Move::Interrupt()
|
||||
{
|
||||
dda->Step(true);
|
||||
if(dda == NULL)
|
||||
{
|
||||
dda = ddaRingBuffer->Get();
|
||||
if(dda != NULL)
|
||||
dda->Start(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if(dda->Active())
|
||||
{
|
||||
dda->Step(true);
|
||||
return;
|
||||
}
|
||||
|
||||
dda = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
29
Move.ino
29
Move.ino
|
@ -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;
|
||||
}
|
||||
|
||||
for(char i = 0; i < AXES; i++)
|
||||
currentPosition[i] = nextMove[i];
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//****************************************************************************************************
|
||||
|
|
|
@ -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)
|
||||
|
|
Reference in a new issue