luni64/TeensyDelay

Using channels 4-7 does not work / processor stalls

Buresdynamics opened this issue · 5 comments

I have an issue using timer channels 4-7.
Teensy 3.6
Arduino 1.8.5
Teensyduino 1.4.0

I try to drive up to 8 stepper motors via driver ICs completely independent from each other. This works fine as long as I do not try to use a channel number higher than 3, i.e. more than 4 motors.
Even using only one of the channels 4 to 7 stalls the processor shortly after triggering the channel with the trigger-function. I tried FTM1 and FTM3 without success. Channels 0-3 always work, every combination with at least one channel higher than 3 does immediately not work.
Each channel uses its own ISR assigned by the addDelayChannel function. My code is very simple test code without any other libraries or timer usages.

Could you please try to reconstruct this issue? If I can help with more information please let me know.

Usage of library:

#include <TeensyDelay.h> 

constexpr int ch_A = 0;
constexpr int ch_B = 1;
constexpr int ch_C = 2;
constexpr int ch_D = 3;
//constexpr int ch_E = 4;
//constexpr int ch_F = 5;

//only one ISR shown as example
void MotorA_isr() {
  TeensyDelay::trigger(MotorA.StepPeriod, ch_A);
  MotorA.goTo();
}

void setup() {
  TeensyDelay::begin();
  TeensyDelay::addDelayChannel(MotorA_isr, ch_A);
  TeensyDelay::addDelayChannel(MotorB_isr, ch_B); // setup a delay channel and attach the callback function to it
  TeensyDelay::addDelayChannel(MotorC_isr, ch_C);
  TeensyDelay::addDelayChannel(MotorD_isr, ch_D);
  //TeensyDelay::addDelayChannel(MotorE_isr, ch_E);
  //TeensyDelay::addDelayChannel(MotorF_isr, ch_F);

  TeensyDelay::trigger(MotorA.StepPeriod, ch_A);
  TeensyDelay::trigger(MotorB.StepPeriod, ch_B);
  TeensyDelay::trigger(MotorC.StepPeriod, ch_C);
  TeensyDelay::trigger(MotorD.StepPeriod, ch_D);
  //TeensyDelay::trigger(MotorE.StepPeriod, ch_E);
  //TeensyDelay::trigger(MotorF.StepPeriod, ch_F);

//.......
}

Uncommenting lines 5-6 of each block or assigning channel numbers higher than 3 to ch_A-D leads to the problem.

That's strange I'll have a look at it tomorrow.
Did you try to replace MotorX.goTo() by something simple, say just toggling a pin?

I tried that too. It seems to be completely unimportant what I do in my code. As soon as one of channels 4-7 come into play, problems begin.
The MotorX.goto() function generates a step and then calculates time until the next step. This is done in 0.9 to 1.2us (depends on acceleration calculations) according to measurements with my Logic analyzer (setting a pin high at the beginning of the isr and low at the end with digitalWriteFast()). At the time all motors do the same movement with the same acceleration. This works perfectly with 1-4 Motors (on channels 0-3) without any noticeable interaction. The same setup does not work when the only difference is a change of the channel numbers of the timer.

nachrichten-bild 1926798498
Starting acceleration

nachrichten-bild 1677117373
Full speed

nachrichten-bild 1543990873
ISR duration measurements (both ISR B and D used the same pin here!)

Kind regards,
Michael
(Sorry, totally forgot my name in the first post)

Hi Michael,
I can reproduce the problem. I found a silly bug which should fix the problem. Can you try if the code in the bugfix branch works for you?
Lutz

Hi Lutz,
fantastic, this solved the problem!
As you can see all Motors are running now.
nachrichten-bild 1160738400
Thank you!
Regards,
Michael

Perfect, thanks for finding this.
I'll merge the fix into the main branch