stepper: Introduce and use gpio_out_toggle_noirq()
The gpio_out_toggle() function in the sam3x8e and stm32f1 code was only valid if it was called with irqs disabled. Commits018c5daa
and9c52ad43
enabled the lcd code which called gpio_out_toggle() with irqs enabled. This could cause corruption of the gpio state. Introduce a gpio_out_toggle_noirq() function that will only be invoked with irqs disabled, and fix gpio_out_toggle() on sam3x8e and stm32f1 so that it safe to call even if irqs are enabled. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
907cfb9105
commit
70068985a7
|
@ -63,11 +63,17 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_out_toggle(struct gpio_out g)
|
gpio_out_toggle_noirq(struct gpio_out g)
|
||||||
{
|
{
|
||||||
g.regs->in = g.bit;
|
g.regs->in = g.bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gpio_out_toggle(struct gpio_out g)
|
||||||
|
{
|
||||||
|
gpio_out_toggle_noirq(g);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_out_write(struct gpio_out g, uint8_t val)
|
gpio_out_write(struct gpio_out g, uint8_t val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@ struct gpio_out {
|
||||||
uint8_t bit : 8;
|
uint8_t bit : 8;
|
||||||
};
|
};
|
||||||
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
||||||
|
void gpio_out_toggle_noirq(struct gpio_out g);
|
||||||
void gpio_out_toggle(struct gpio_out g);
|
void gpio_out_toggle(struct gpio_out g);
|
||||||
void gpio_out_write(struct gpio_out g, uint8_t val);
|
void gpio_out_write(struct gpio_out g, uint8_t val);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ struct gpio_out {
|
||||||
uint8_t pin;
|
uint8_t pin;
|
||||||
};
|
};
|
||||||
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
||||||
|
void gpio_out_toggle_noirq(struct gpio_out g);
|
||||||
void gpio_out_toggle(struct gpio_out g);
|
void gpio_out_toggle(struct gpio_out g);
|
||||||
void gpio_out_write(struct gpio_out g, uint8_t val);
|
void gpio_out_write(struct gpio_out g, uint8_t val);
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ static uint_fast8_t
|
||||||
soft_pwm_toggle_event(struct timer *timer)
|
soft_pwm_toggle_event(struct timer *timer)
|
||||||
{
|
{
|
||||||
struct soft_pwm_s *s = container_of(timer, struct soft_pwm_s, timer);
|
struct soft_pwm_s *s = container_of(timer, struct soft_pwm_s, timer);
|
||||||
gpio_out_toggle(s->pin);
|
gpio_out_toggle_noirq(s->pin);
|
||||||
s->flags ^= SPF_ON;
|
s->flags ^= SPF_ON;
|
||||||
uint32_t waketime = s->timer.waketime;
|
uint32_t waketime = s->timer.waketime;
|
||||||
if (s->flags & SPF_ON)
|
if (s->flags & SPF_ON)
|
||||||
|
|
|
@ -7,6 +7,7 @@ struct gpio_out {
|
||||||
uint32_t pin;
|
uint32_t pin;
|
||||||
};
|
};
|
||||||
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
||||||
|
void gpio_out_toggle_noirq(struct gpio_out g);
|
||||||
void gpio_out_toggle(struct gpio_out g);
|
void gpio_out_toggle(struct gpio_out g);
|
||||||
void gpio_out_write(struct gpio_out g, uint8_t val);
|
void gpio_out_write(struct gpio_out g, uint8_t val);
|
||||||
|
|
||||||
|
|
|
@ -104,11 +104,17 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_out_toggle(struct gpio_out g)
|
gpio_out_toggle_noirq(struct gpio_out g)
|
||||||
{
|
{
|
||||||
gpio_out_write(g, !(*g.reg & g.bit));
|
gpio_out_write(g, !(*g.reg & g.bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gpio_out_toggle(struct gpio_out g)
|
||||||
|
{
|
||||||
|
gpio_out_toggle_noirq(g);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_out_write(struct gpio_out g, uint8_t val)
|
gpio_out_write(struct gpio_out g, uint8_t val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@ struct gpio_out {
|
||||||
uint32_t bit;
|
uint32_t bit;
|
||||||
};
|
};
|
||||||
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
||||||
|
void gpio_out_toggle_noirq(struct gpio_out g);
|
||||||
void gpio_out_toggle(struct gpio_out g);
|
void gpio_out_toggle(struct gpio_out g);
|
||||||
void gpio_out_write(struct gpio_out g, uint8_t val);
|
void gpio_out_write(struct gpio_out g, uint8_t val);
|
||||||
|
|
||||||
|
|
|
@ -69,12 +69,20 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_out_toggle(struct gpio_out g)
|
gpio_out_toggle_noirq(struct gpio_out g)
|
||||||
{
|
{
|
||||||
Pio *regs = g.regs;
|
Pio *regs = g.regs;
|
||||||
regs->PIO_ODSR ^= g.bit;
|
regs->PIO_ODSR ^= g.bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gpio_out_toggle(struct gpio_out g)
|
||||||
|
{
|
||||||
|
irqstatus_t flag = irq_save();
|
||||||
|
gpio_out_toggle_noirq(g);
|
||||||
|
irq_restore(flag);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_out_write(struct gpio_out g, uint8_t val)
|
gpio_out_write(struct gpio_out g, uint8_t val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@ struct gpio_out {
|
||||||
uint32_t bit;
|
uint32_t bit;
|
||||||
};
|
};
|
||||||
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
||||||
|
void gpio_out_toggle_noirq(struct gpio_out g);
|
||||||
void gpio_out_toggle(struct gpio_out g);
|
void gpio_out_toggle(struct gpio_out g);
|
||||||
void gpio_out_write(struct gpio_out g, uint8_t val);
|
void gpio_out_write(struct gpio_out g, uint8_t val);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val) {
|
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val) {
|
||||||
return (struct gpio_out){.pin=pin};
|
return (struct gpio_out){.pin=pin};
|
||||||
}
|
}
|
||||||
|
void gpio_out_toggle_noirq(struct gpio_out g) {
|
||||||
|
}
|
||||||
void gpio_out_toggle(struct gpio_out g) {
|
void gpio_out_toggle(struct gpio_out g) {
|
||||||
}
|
}
|
||||||
void gpio_out_write(struct gpio_out g, uint8_t val) {
|
void gpio_out_write(struct gpio_out g, uint8_t val) {
|
||||||
|
|
|
@ -88,7 +88,7 @@ stepper_load_next(struct stepper *s, uint32_t min_next_time)
|
||||||
}
|
}
|
||||||
if (m->flags & MF_DIR) {
|
if (m->flags & MF_DIR) {
|
||||||
s->position = -s->position + m->count;
|
s->position = -s->position + m->count;
|
||||||
gpio_out_toggle(s->dir_pin);
|
gpio_out_toggle_noirq(s->dir_pin);
|
||||||
} else {
|
} else {
|
||||||
s->position += m->count;
|
s->position += m->count;
|
||||||
}
|
}
|
||||||
|
@ -108,24 +108,24 @@ stepper_event(struct timer *t)
|
||||||
if (CONFIG_NO_UNSTEP_DELAY) {
|
if (CONFIG_NO_UNSTEP_DELAY) {
|
||||||
// On slower mcus it is possible to simply step and unstep in
|
// On slower mcus it is possible to simply step and unstep in
|
||||||
// the same timer event.
|
// the same timer event.
|
||||||
gpio_out_toggle(s->step_pin);
|
gpio_out_toggle_noirq(s->step_pin);
|
||||||
uint16_t count = s->count - 1;
|
uint16_t count = s->count - 1;
|
||||||
if (likely(count)) {
|
if (likely(count)) {
|
||||||
s->count = count;
|
s->count = count;
|
||||||
s->time.waketime += s->interval;
|
s->time.waketime += s->interval;
|
||||||
gpio_out_toggle(s->step_pin);
|
gpio_out_toggle_noirq(s->step_pin);
|
||||||
if (s->flags & SF_HAVE_ADD)
|
if (s->flags & SF_HAVE_ADD)
|
||||||
s->interval += s->add;
|
s->interval += s->add;
|
||||||
return SF_RESCHEDULE;
|
return SF_RESCHEDULE;
|
||||||
}
|
}
|
||||||
uint_fast8_t ret = stepper_load_next(s, 0);
|
uint_fast8_t ret = stepper_load_next(s, 0);
|
||||||
gpio_out_toggle(s->step_pin);
|
gpio_out_toggle_noirq(s->step_pin);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On faster mcus, it is necessary to schedule the unstep event
|
// On faster mcus, it is necessary to schedule the unstep event
|
||||||
uint32_t min_next_time = timer_read_time() + UNSTEP_TIME;
|
uint32_t min_next_time = timer_read_time() + UNSTEP_TIME;
|
||||||
gpio_out_toggle(s->step_pin);
|
gpio_out_toggle_noirq(s->step_pin);
|
||||||
s->count--;
|
s->count--;
|
||||||
if (likely(s->count & 1))
|
if (likely(s->count & 1))
|
||||||
// Schedule unstep event
|
// Schedule unstep event
|
||||||
|
|
|
@ -72,11 +72,19 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_out_toggle(struct gpio_out g)
|
gpio_out_toggle_noirq(struct gpio_out g)
|
||||||
{
|
{
|
||||||
LL_GPIO_TogglePin(g.regs, g.bit);
|
LL_GPIO_TogglePin(g.regs, g.bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gpio_out_toggle(struct gpio_out g)
|
||||||
|
{
|
||||||
|
irqstatus_t flag = irq_save();
|
||||||
|
gpio_out_toggle_noirq(g);
|
||||||
|
irq_restore(flag);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_out_write(struct gpio_out g, uint8_t val)
|
gpio_out_write(struct gpio_out g, uint8_t val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@ struct gpio_out {
|
||||||
uint32_t bit;
|
uint32_t bit;
|
||||||
};
|
};
|
||||||
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
|
||||||
|
void gpio_out_toggle_noirq(struct gpio_out g);
|
||||||
void gpio_out_toggle(struct gpio_out g);
|
void gpio_out_toggle(struct gpio_out g);
|
||||||
void gpio_out_write(struct gpio_out g, uint8_t val);
|
void gpio_out_write(struct gpio_out g, uint8_t val);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue