Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch stepper.cpp to allow omitting steppers #4720

Merged

Conversation

thinkyhead
Copy link
Member

If some stepper pins are removed or set to -1 then the stepper functions should not use them.

@thinkyhead thinkyhead merged commit 8241cf9 into MarlinFirmware:RCBugFix Aug 28, 2016
@thinkyhead thinkyhead deleted the rc_allow_stepper_omission branch August 28, 2016 01:36
@Blue-Marlin
Copy link
Contributor

That looks daring to me.
Switching less pins will shorten the on-time of the stepper pulses.

@thinkyhead
Copy link
Member Author

Well that seems silly to me, that the stepper pulse timing is being driven somehow by having happenstance code in the stepper ISR. What about the difference in step pulses between a 16MHz and a 20MHz board? I don't see the code making any special allowances for that 20% faster processor.

@Blue-Marlin
Copy link
Contributor

Reduced to the bare minimum we have:
invert x
invert y
invert z
invert e
invert x
invert y
invert z
invert e

versus maybe

invert x
invert e
invert x
invert e

-> pulse is 50% shorter

omitting only one stepper reduces the on-time by ~25%.

With 4 steppers this seems to be long enough even with a 20MHz processor.
But reducing an other 50%, at least, is questionable.

We already had requests for longer, or adjustable, step pulses for certain types of stepper drivers.
We also have had some nice pictures of oszylograms in the last few month - but i can't remember how big our safety margin was.

Maybe you are not wrong - but without considering the pulse-lenght-change this is daring.

@thinkyhead
Copy link
Member Author

Well, this shouldn't be too tricky to adjust. First question: Would inserting these lines between the start and end of the pulse make the pulses too long?

      #ifndef USBCON
        customizedSerial.checkRx(); // Check for serial chars.
      #endif

We can also move this line in-between them to eat up some cycles…

      step_events_completed++;

Finally, if we know the absolute minimum time required, and we know how much time each STEP_ADD takes, then we can determine the total time used by that code and just insert the appropriate amount of nop macros to make up the difference.

@thinkyhead
Copy link
Member Author

thinkyhead commented Aug 28, 2016

Each pulse begins with a WRITE(STEP_PIN, V). Before the pulses end, there's a long greater than 0 operation, a long integer subtraction from a long addend in RAM, a long addition using a long addend in RAM, and finally the second WRITE(), with its overhead. When using a mixing extruder or ADVANCE the timing is altered by the extra complexity of each. And of course, the compiler can produce more or less optimal code…

Since the real timing is hard to predict, it seems to me that the simplest way to ensure long enough pulses is to provide a configurable extra delay so it can just be tuned when needed.

And, what about the time between the end of a pulse and the start of the next pulse?

@thinkyhead
Copy link
Member Author

thinkyhead commented Aug 28, 2016

Another thing that occurs to me is, since we need to spend extra time in the stepper ISR to get long enough pulses, perhaps there's some other busy-work that we could toss in that needs to be done anyways. But then, this ISR runs at all kinds of rates, from very fast to very slow…

@thinkyhead
Copy link
Member Author

Note that when using the DUAL_[XYZ]_STEPPER options, some of these STEP_ADD and STEP_IF_COUNTER macros are actually pulsing two steppers.

@Blue-Marlin
Copy link
Contributor

I doubt we can make the 'on' pulses too long in single step mode. When in double/quad step mode we should achieve to make low and high about 50/50. As far i can remember from the pictures, this is currently about the case.

@Blue-Marlin
Copy link
Contributor

Yes. Tracing down all that macro levels is a pain.

It has to work in the simplest, fastest case - no advanced, no doubles, no other exras. If that works, the slower cases will also work.

@thinkyhead
Copy link
Member Author

thinkyhead commented Aug 28, 2016

How about using one of the TCNT timers to count the CPU clock? For example (totally idealized)…

uint32_t start = TCNT0; // prescaler = 1

. . . some code . . .

while ((uint32_t)(TCNT0 - start) < 10 * F_CPU / 1000000UL); // 10µs

… or …

uint32_t start = TCNT1; // prescaler = 8

. . . some code . . .

while ((uint32_t)(TCNT1 - start) < 10 * F_CPU / 1000000UL / 8UL); // 10µs

@thinkyhead
Copy link
Member Author

thinkyhead commented Aug 28, 2016

I note that the pulse duration also depends on whether or not a stepper is even benig moved during a particular ISR or steps loop. So there is no way to enforce an "absolute" minimum except by using code like the above at runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants