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

expected bug in handling TIM3 (pulse width) in stepper.c #50

Open
mstrens opened this issue Jun 24, 2018 · 3 comments
Open

expected bug in handling TIM3 (pulse width) in stepper.c #50

mstrens opened this issue Jun 24, 2018 · 3 comments

Comments

@mstrens
Copy link

mstrens commented Jun 24, 2018

In TIM2_IRQHandler from stepper.c, after DIRECTION pins are written, interrupts on TIM3 are enabled with code
NVIC_EnableIRQ(TIM3_IRQn);
Still, TIM3->CNT is not reset to 0. As TIM3 was not disabled (only reset to 0 by his IRQ handler), CNT can have any value.
So we can't be sure that the step pulse will have the expected delay.
To solve this, I think you have to force a reload of TIM3 registers and clear interrupts just before enabling interrupt again.
So add
TIM3->EGR = TIM_PSCReloadMode_Immediate;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
just before
NVIC_EnableIRQ(TIM3_IRQn);

Then, I think also that lines
TIM3->SR &= ~(1<<0); // clear UIF flag
TIM3->CNT = 0;
can be removed from TIM3_IRQHandler

@robomechs
Copy link

Сould you explain it in more detail?
As I understand, if it's run at first time TIM3->CNT is 0.
Then in any case the TIM3->CNT will be reset in the interrupt "void TIM3_IRQHandler(void)", until the next "NVIC_EnableIRQ(TIM3_IRQn);" call. Isn't it?

@mstrens
Copy link
Author

mstrens commented Jul 14, 2018

TIM3 is a timer used to fix the width of the step pulse.
So TIM3 should be reset to 0 when the step start (a rising pulse on some pulse pins for non inverted signal).
When TIM3 reach a defined value (say 100 for this exemple), it will call an interrupt that will stop the step pulse ( setting the pins to 0 for non inverted signal).
When the TIM3 interrupt fires, CNT is set to 0 but as TIM3 is not stopped (it is only the interrupt that are disabled). So it continues to count from 0 up to the 100. This continues always in the background.
It does not generate new interrupt because TIM3 interrupt are disable.
The problem is that when a new start step will be generated, CNT can have any value (between 0 and 100). If CNT is e.g. at 60 when the new step starts, then TIM3 interrupt will be called when CNT reach 100. So it will be 40 (100-60) clocks later instead of the expected 100 clocks. So the pulse will be to short and there is a risk that it is discarded by the driver.
To fix this bug, CNT must be reset each time a new step start (just before enabling the interrupt again)

@robomechs
Copy link

robomechs commented Jul 15, 2018

ok, you are absolutely right! I've checked it with logic analizer.
My changes:

  1. in void stepper_init()
    TIM3->CR1 &= ~TIM_CR1_CEN;
    TIM3->CNT = 0;
    NVIC_EnableIRQ(TIM3_IRQn);
    //NVIC_DisableIRQ(TIM3_IRQn);
  2. in TIM2_IRQHandler
    line 496
    //NVIC_EnableIRQ(TIM3_IRQn);
    TIM3->CR1 |= TIM_CR1_CEN;
  3. in TIM3_IRQHandler
    TIM3->CR1 &= ~TIM_CR1_CEN;
    TIM3->SR &= ~(1<<0); // clear UIF flag
    TIM3->CNT = 0;
    //NVIC_DisableIRQ(TIM3_IRQn);

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

No branches or pull requests

2 participants