Yes it works now. Made another implementation of the pulse IRQ and all that. We'll see if I keep this or go back to the older. It is IMPORTANT, REQUIRED to use a 4.9 linux kernel for it to work. There are obviously bugs in the RealTek network drivers R8168/R8169 in 5+ kernels. All this work could have been avoided with a 4.9 kernel.

This commit is contained in:
Hakan Bastedt
2024-03-17 22:04:52 +01:00
parent 27475eaecd
commit d4fed6cfe8
3 changed files with 40 additions and 24 deletions

View File

@@ -8,8 +8,9 @@ class StepGen2
public: public:
volatile double_t actualPosition; volatile double_t actualPosition;
volatile int32_t nSteps; volatile int32_t nSteps;
volatile uint32_t timerPulseSteps;
volatile uint32_t timerFrequency; volatile uint32_t timerFrequency;
volatile int32_t timerPosition = 0;
volatile int32_t timerEndPosition = 0;
public: public:
volatile float Tstartf; // Starting delay in secs volatile float Tstartf; // Starting delay in secs
@@ -21,7 +22,7 @@ public:
HardwareTimer *startTimer; // Use timers 10,11,13,14 HardwareTimer *startTimer; // Use timers 10,11,13,14
uint8_t dirPin; uint8_t dirPin;
PinName stepPin; PinName stepPin;
uint32_t Tjitter = 400; // Longest time from IRQ to handling in handleStepper, unit is microseconds uint32_t Tjitter = 350; // Longest time from IRQ to handling in handleStepper, unit is microseconds
uint64_t dbg; uint64_t dbg;
const uint16_t t2 = 5; // DIR is ahead of PUL with at least 5 usecs const uint16_t t2 = 5; // DIR is ahead of PUL with at least 5 usecs
const uint16_t t3 = 3; // Pulse width at least 2.5 usecs const uint16_t t3 = 3; // Pulse width at least 2.5 usecs

View File

@@ -63,11 +63,14 @@ uint32_t StepGen2::handleStepper(uint64_t irqTime, uint16_t nLoops)
Tpulses = abs(nSteps) / frequency; Tpulses = abs(nSteps) / frequency;
} }
updatePos(5); updatePos(5);
return 1;
uint32_t timeSinceISR = (longTime.extendTime(micros()) - irqTime); // Diff time from ISR (usecs) uint32_t timeSinceISR = (longTime.extendTime(micros()) - irqTime); // Diff time from ISR (usecs)
dbg = timeSinceISR; // dbg = timeSinceISR; //
Tstartu = Tjitter + uint32_t(Tstartf * 1e6) - timeSinceISR; // Have already wasted some time since the irq. Tstartu = Tjitter + uint32_t(Tstartf * 1e6) - timeSinceISR; // Have already wasted some time since the irq.
if (nSteps == 0) // Can do this much earlier, but want some calculated data for debugging
return updatePos(1);
timerFrequency = uint32_t(ceil(frequency)); timerFrequency = uint32_t(ceil(frequency));
startTimer->setOverflow(Tstartu, MICROSEC_FORMAT); // All handled by irqs startTimer->setOverflow(Tstartu, MICROSEC_FORMAT); // All handled by irqs
startTimer->refresh(); startTimer->refresh();
@@ -78,12 +81,12 @@ uint32_t StepGen2::handleStepper(uint64_t irqTime, uint16_t nLoops)
void StepGen2::startTimerCB() void StepGen2::startTimerCB()
{ {
startTimer->pause(); // Once is enough. startTimer->pause(); // Once is enough.
digitalWrite(dirPin, nSteps < 0 ? HIGH : LOW); digitalWriteFast(digitalPinToPinName(dirPin), nSteps < 0 ? HIGH : LOW); // nSteps negative => decrease, HIGH
// There will be a short break here for t2 usecs, in the future. // There will be a short break here for t2 usecs, in the future.
timerPulseSteps = abs(nSteps); timerEndPosition += nSteps;
pulseTimer->setMode(pulseTimerChan, TIMER_OUTPUT_COMPARE_PWM2, stepPin); pulseTimer->pause();
pulseTimer->setMode(pulseTimerChan, TIMER_OUTPUT_COMPARE_PWM1, stepPin);
pulseTimer->setOverflow(timerFrequency, HERTZ_FORMAT); pulseTimer->setOverflow(timerFrequency, HERTZ_FORMAT);
// pulseTimer->setCaptureCompare(pulseTimerChan, t3, MICROSEC_COMPARE_FORMAT);
pulseTimer->setCaptureCompare(pulseTimerChan, 50, PERCENT_COMPARE_FORMAT); pulseTimer->setCaptureCompare(pulseTimerChan, 50, PERCENT_COMPARE_FORMAT);
pulseTimer->refresh(); pulseTimer->refresh();
pulseTimer->resume(); pulseTimer->resume();
@@ -91,10 +94,21 @@ void StepGen2::startTimerCB()
void StepGen2::pulseTimerCB() void StepGen2::pulseTimerCB()
{ {
--timerPulseSteps; int16_t dir = digitalReadFast(digitalPinToPinName(dirPin));
if (timerPulseSteps == 0) if (dir == HIGH)
{ timerPosition--;
else
timerPosition++;
int32_t diffPosition = timerEndPosition - timerPosition; // Same "polarity" as nSteps
if (diffPosition == 0)
pulseTimer->pause(); pulseTimer->pause();
else
{
if (diffPosition < 0 && dir == LOW) // Change direction. Should not end up here, but alas
digitalWriteFast(digitalPinToPinName(dirPin), HIGH); // Normal is to be HIGH when decreasing
if (diffPosition > 0 && dir == HIGH) // Change direction. Should not end up here, but alas
digitalWriteFast(digitalPinToPinName(dirPin), LOW); // Normal is to be LOW when increasing
// Normally nothing is needed
} }
} }

View File

@@ -45,8 +45,6 @@ void cb_set_outputs(void) // Master outputs gets here, slave inputs, first opera
// Step2.reqPos(Obj.CommandedPosition2); // Step2.reqPos(Obj.CommandedPosition2);
// Step2.setScale(Obj.StepsPerMM2); // Step2.setScale(Obj.StepsPerMM2);
// Step2.enable(1); // Step2.enable(1);
Obj.ActualPosition1 = Obj.CommandedPosition1; // Step1.actPos();
Obj.ActualPosition2 = Obj.CommandedPosition2; // Step2.actPos();
} }
uint16_t nLoops; uint16_t nLoops;
@@ -78,6 +76,9 @@ void cb_get_inputs(void) // Set Master inputs, slave outputs, last operation
Obj.EncPos = Encoder1.currentPos(); Obj.EncPos = Encoder1.currentPos();
Obj.EncFrequency = Encoder1.frequency(ESCvar.Time); Obj.EncFrequency = Encoder1.frequency(ESCvar.Time);
Obj.IndexByte = Encoder1.getIndexState(); Obj.IndexByte = Encoder1.getIndexState();
float_t ap2 = Obj.ActualPosition2;
Obj.ActualPosition1 = Obj.CommandedPosition1; // Step1.actPos();
Obj.ActualPosition2 = Obj.CommandedPosition2; // Step2.actPos();
uint64_t dTim = nowTime - thenTime; // Debug. Getting jitter over the last 200 milliseconds uint64_t dTim = nowTime - thenTime; // Debug. Getting jitter over the last 200 milliseconds
Tim.push(dTim); Tim.push(dTim);
@@ -93,9 +94,9 @@ void cb_get_inputs(void) // Set Master inputs, slave outputs, last operation
thenTime = irqTime; thenTime = irqTime;
Obj.DiffT = longTime.extendTime(micros()) - irqTime; // max_Tim - min_Tim; // Debug Obj.DiffT = longTime.extendTime(micros()) - irqTime; // max_Tim - min_Tim; // Debug
Obj.D1 = Step2.frequency; Obj.D1 = Step2.frequency;
Obj.D2 = nLoops; Obj.D2 = Step2.nSteps;
Obj.D3 = max_Tim - min_Tim; Obj.D3 = abs(1000 * (ap2 - Obj.CommandedPosition2)); // Step2.actPos();
Obj.D4 = ALEventIRQ; Obj.D4 = Step2.Tstartu;
} }
void ESC_interrupt_enable(uint32_t mask); void ESC_interrupt_enable(uint32_t mask);
@@ -139,8 +140,8 @@ void loop(void)
{ {
nowTime = longTime.extendTime(micros()); nowTime = longTime.extendTime(micros());
/* Read local time from ESC*/ /* Read local time from ESC*/
ESC_read(ESCREG_LOCALTIME, (void *)&ESCvar.Time, sizeof(ESCvar.Time)); // ESC_read(ESCREG_LOCALTIME, (void *)&ESCvar.Time, sizeof(ESCvar.Time));
ESCvar.Time = etohl(ESCvar.Time); // ESCvar.Time = etohl(ESCvar.Time);
DIG_process(ALEventIRQ, DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG | DIG_process(ALEventIRQ, DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG |
DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG); DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
serveIRQ = 0; serveIRQ = 0;
@@ -148,14 +149,14 @@ void loop(void)
ecat_slv_poll(); ecat_slv_poll();
} }
dTime = longTime.extendTime(micros()) - irqTime; dTime = longTime.extendTime(micros()) - irqTime;
if ((dTime > 500 && dTime < 800) || dTime > 5000) // Don't run ecat_slv_poll when expecting to serve interrupt if (dTime > 5000) // Don't run ecat_slv_poll when expecting to serve interrupt
ecat_slv_poll(); ecat_slv_poll();
} }
void sync0Handler(void) void sync0Handler(void)
{ {
ALEventIRQ = ESC_ALeventread(); ALEventIRQ = ESC_ALeventread();
if (ALEventIRQ & ESCREG_ALEVENT_SM2) // if (ALEventIRQ & ESCREG_ALEVENT_SM2)
{ {
serveIRQ = 1; serveIRQ = 1;
irqTime = longTime.extendTime(micros()); irqTime = longTime.extendTime(micros());