Quadrotor from scratch
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
1.6 KiB

#include "event.h"
#include "interrupt.h"
#include "types.h"
#include "log.h"
event_handler *event_handler_table[EVENT_MAX+1];
#define EVENT_WORDS ((EVENT_MAX+1+31)/32)
unsigned int event_pending[EVENT_WORDS];
#define EVENT_WORDLEN 32
#define EVENT_WORD(x) (x/EVENT_WORDLEN)
#define EVENT_BIT(x) (x%EVENT_WORDLEN)
#define EVENT_MASK(x) (1<<EVENT_BIT(x))
/*
* This function must be called with interrupts disabled.
* This will normally be the case as it is typically called from within
* an interrupt handler anyway.
*/
void event_set(unsigned int event)
{
if (event > EVENT_MAX)
return;
event_pending[EVENT_WORD(event)] |= EVENT_MASK(event);
}
static int bitset(unsigned int x)
{
x = 0xffffffff - (x-1);
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x = x + (x << 8);
x = x + (x << 16);
return 32 - (x >> 24);
}
bool event_get(unsigned int *event)
{
int i;
unsigned int p;
for (i = 0; i < EVENT_WORDS; i++) {
if ((p = event_pending[i]) != 0) {
p = p & (-p);
*event = bitset(p) + EVENT_WORDLEN*i;
return TRUE;
}
}
return FALSE;
}
void event_clear(unsigned int event)
{
interrupt_block();
event_pending[EVENT_WORD(event)] &= ~EVENT_MASK(event);
interrupt_unblock();
}
bool event_dispatch(void)
{
unsigned int event;
if (event_get(&event)) {
event_clear(event);
if (event_handler_table[event] != NULL) {
log_mark_busy();
(event_handler_table[event])();
log_mark_idle();
}
return TRUE;
}
return FALSE;
}
void event_register(unsigned int event, event_handler *handler)
{
if (event > EVENT_MAX)
return;
event_handler_table[event] = handler;
}