irq: Allow boards to define the return type of irq_save()

The AVR wants a uint8_t return type for irq_save(), but other
architectures will generally prefer int.  Allow the board to configure
the size of the flag by introducing an irqstatus_t typedef.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2016-06-08 21:13:53 -04:00
parent 9dd101c26f
commit fa85094cbb
8 changed files with 33 additions and 25 deletions

View File

@ -143,7 +143,7 @@ gpio_out_setup(uint8_t pin, uint8_t val)
if (! regs) if (! regs)
goto fail; goto fail;
uint8_t bit = GPIO2BIT(pin); uint8_t bit = GPIO2BIT(pin);
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
regs->out = val ? (regs->out | bit) : (regs->out & ~bit); regs->out = val ? (regs->out | bit) : (regs->out & ~bit);
regs->mode |= bit; regs->mode |= bit;
irq_restore(flag); irq_restore(flag);
@ -160,7 +160,7 @@ void gpio_out_toggle(struct gpio_out g)
void void
gpio_out_write(struct gpio_out g, uint8_t val) gpio_out_write(struct gpio_out g, uint8_t val)
{ {
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
g.regs->out = val ? (g.regs->out | g.bit) : (g.regs->out & ~g.bit); g.regs->out = val ? (g.regs->out | g.bit) : (g.regs->out & ~g.bit);
irq_restore(flag); irq_restore(flag);
} }
@ -174,7 +174,7 @@ gpio_in_setup(uint8_t pin, int8_t pull_up)
if (! regs) if (! regs)
goto fail; goto fail;
uint8_t bit = GPIO2BIT(pin); uint8_t bit = GPIO2BIT(pin);
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
regs->out = pull_up > 0 ? (regs->out | bit) : (regs->out & ~bit); regs->out = pull_up > 0 ? (regs->out | bit) : (regs->out & ~bit);
regs->mode &= ~bit; regs->mode &= ~bit;
irq_restore(flag); irq_restore(flag);
@ -196,7 +196,7 @@ gpio_pwm_write(struct gpio_pwm g, uint8_t val)
if (g.size8) { if (g.size8) {
*(volatile uint8_t*)g.reg = val; *(volatile uint8_t*)g.reg = val;
} else { } else {
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
*(volatile uint16_t*)g.reg = val; *(volatile uint16_t*)g.reg = val;
irq_restore(flag); irq_restore(flag);
} }
@ -210,7 +210,7 @@ gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val)
if (READP(pwm_pins[chan]) != pin) if (READP(pwm_pins[chan]) != pin)
continue; continue;
const struct gpio_pwm_info *p = &pwm_regs[chan]; const struct gpio_pwm_info *p = &pwm_regs[chan];
uint8_t flags = READP(p->flags), cs; irqstatus_t flags = READP(p->flags), cs;
if (flags & GP_AFMT) { if (flags & GP_AFMT) {
switch (cycle_time) { switch (cycle_time) {
case 0 ... 8*510L - 1: cs = 1; break; case 0 ... 8*510L - 1: cs = 1; break;
@ -240,7 +240,7 @@ gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint8_t val)
shutdown("Can not user timer1 for PWM; timer1 is used for timers"); shutdown("Can not user timer1 for PWM; timer1 is used for timers");
// Setup PWM timer // Setup PWM timer
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
uint8_t old_cs = *regb & 0x07; uint8_t old_cs = *regb & 0x07;
if (old_cs && old_cs != cs) if (old_cs && old_cs != cs)
shutdown("PWM already programmed at different speed"); shutdown("PWM already programmed at different speed");

View File

@ -15,13 +15,15 @@ static inline void irq_enable(void) {
sei(); sei();
} }
static inline uint8_t irq_save(void) { typedef uint8_t irqstatus_t;
static inline irqstatus_t irq_save(void) {
uint8_t flag = SREG; uint8_t flag = SREG;
irq_disable(); irq_disable();
return flag; return flag;
} }
static inline void irq_restore(uint8_t flag) { static inline void irq_restore(irqstatus_t flag) {
barrier(); barrier();
SREG = flag; SREG = flag;
} }

View File

@ -89,7 +89,7 @@ console_pop_input(uint8_t len)
, needcopy - copied); , needcopy - copied);
copied = needcopy; copied = needcopy;
} }
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
if (rpos != readb(&receive_pos)) { if (rpos != readb(&receive_pos)) {
// Raced with irq handler - retry // Raced with irq handler - retry
irq_restore(flag); irq_restore(flag);

View File

@ -52,7 +52,7 @@ timer_init(void)
{ {
if (CONFIG_AVR_CLKPR != -1 && (uint8_t)CONFIG_AVR_CLKPR != CLKPR) { if (CONFIG_AVR_CLKPR != -1 && (uint8_t)CONFIG_AVR_CLKPR != CLKPR) {
// Program the clock prescaler // Program the clock prescaler
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
CLKPR = 0x80; CLKPR = 0x80;
CLKPR = CONFIG_AVR_CLKPR; CLKPR = CONFIG_AVR_CLKPR;
irq_restore(flag); irq_restore(flag);
@ -100,7 +100,7 @@ timer_periodic(void)
uint32_t uint32_t
timer_read_time(void) timer_read_time(void)
{ {
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
uint16_t cur = timer_get(); uint16_t cur = timer_get();
uint32_t last = timer_last; uint32_t last = timer_last;
irq_restore(flag); irq_restore(flag);

View File

@ -30,7 +30,7 @@ move_free(struct move *m)
struct move * struct move *
move_alloc(void) move_alloc(void)
{ {
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
struct move *m = move_free_list; struct move *m = move_free_list;
if (!m) if (!m)
shutdown("Move queue empty"); shutdown("Move queue empty");
@ -231,7 +231,7 @@ void
command_debug_read16(uint32_t *args) command_debug_read16(uint32_t *args)
{ {
uint16_t *ptr = (void*)(size_t)args[0]; uint16_t *ptr = (void*)(size_t)args[0];
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
uint16_t v = *ptr; uint16_t v = *ptr;
irq_restore(flag); irq_restore(flag);
sendf("debug_result val=%hu", v); sendf("debug_result val=%hu", v);
@ -251,7 +251,7 @@ void
command_debug_write16(uint32_t *args) command_debug_write16(uint32_t *args)
{ {
uint16_t *ptr = (void*)(size_t)args[0]; uint16_t *ptr = (void*)(size_t)args[0];
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
*ptr = args[1]; *ptr = args[1];
irq_restore(flag); irq_restore(flag);
} }

View File

@ -3,9 +3,11 @@
#include <stdint.h> #include <stdint.h>
typedef unsigned long irqstatus_t;
void irq_disable(void); void irq_disable(void);
void irq_enable(void); void irq_enable(void);
uint8_t irq_save(void); irqstatus_t irq_save(void);
void irq_restore(uint8_t flag); void irq_restore(irqstatus_t flag);
#endif // irq.h #endif // irq.h

View File

@ -43,7 +43,7 @@ uint8_t
sched_check_periodic(uint16_t time, uint16_t *pnext) sched_check_periodic(uint16_t time, uint16_t *pnext)
{ {
uint16_t next = *pnext, cur; uint16_t next = *pnext, cur;
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
cur = millis; cur = millis;
irq_restore(flag); irq_restore(flag);
if ((int16_t)(cur - next) < 0) if ((int16_t)(cur - next) < 0)
@ -82,7 +82,7 @@ void
sched_timer(struct timer *add) sched_timer(struct timer *add)
{ {
uint32_t waketime = add->waketime; uint32_t waketime = add->waketime;
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
if (sched_is_before(waketime, timer_list->waketime)) { if (sched_is_before(waketime, timer_list->waketime)) {
// This timer is the next - insert at front of list and reschedule // This timer is the next - insert at front of list and reschedule
add->next = timer_list; add->next = timer_list;
@ -105,7 +105,7 @@ sched_timer(struct timer *add)
void void
sched_del_timer(struct timer *del) sched_del_timer(struct timer *del)
{ {
uint8_t flag = irq_save(); irqstatus_t flag = irq_save();
if (timer_list == del) { if (timer_list == del) {
// Deleting the next active timer - delete and reschedule // Deleting the next active timer - delete and reschedule
timer_list = del->next; timer_list = del->next;

View File

@ -16,28 +16,32 @@
* Interrupts * Interrupts
****************************************************************/ ****************************************************************/
uint8_t Interrupt_off; irqstatus_t Interrupt_off;
void irq_disable(void) void
irq_disable(void)
{ {
Interrupt_off = 1; Interrupt_off = 1;
barrier(); barrier();
} }
void irq_enable(void) void
irq_enable(void)
{ {
barrier(); barrier();
Interrupt_off = 0; Interrupt_off = 0;
} }
uint8_t irq_save(void) irqstatus_t
irq_save(void)
{ {
uint8_t flag = Interrupt_off; irqstatus_t flag = Interrupt_off;
irq_disable(); irq_disable();
return flag; return flag;
} }
void irq_restore(uint8_t flag) void
irq_restore(irqstatus_t flag)
{ {
barrier(); barrier();
Interrupt_off = flag; Interrupt_off = flag;