Browse Source
* Implement SWI handler to enable/disable interrupts * Implement event system to deal with kicking non-interrupt codemaster
Gavan Fantom
14 years ago
9 changed files with 171 additions and 3 deletions
@ -0,0 +1,74 @@ |
|||||||
|
#include "event.h" |
||||||
|
#include "interrupt.h" |
||||||
|
#include "types.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)) |
||||||
|
|
||||||
|
void event_set(unsigned int event) |
||||||
|
{ |
||||||
|
if (event > EVENT_MAX) |
||||||
|
return; |
||||||
|
|
||||||
|
interrupt_block(); |
||||||
|
event_pending[EVENT_WORD(event)] |= EVENT_MASK(event); |
||||||
|
interrupt_unblock(); |
||||||
|
} |
||||||
|
|
||||||
|
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(); |
||||||
|
} |
||||||
|
|
||||||
|
void event_dispatch(void) |
||||||
|
{ |
||||||
|
unsigned int event; |
||||||
|
|
||||||
|
if (event_get(&event)) { |
||||||
|
event_clear(event); |
||||||
|
(event_handler_table[event])(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void event_register(unsigned int event, event_handler *handler) |
||||||
|
{ |
||||||
|
if (event > EVENT_MAX) |
||||||
|
return; |
||||||
|
event_handler_table[event] = handler; |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
#ifndef __EVENT_H |
||||||
|
#define __EVENT_H |
||||||
|
|
||||||
|
#include "types.h" |
||||||
|
|
||||||
|
#define EVENT_TIMER 0 |
||||||
|
#define EVENT_I2C_COMPLETE 1 |
||||||
|
|
||||||
|
#define EVENT_MAX 1 |
||||||
|
|
||||||
|
typedef void event_handler(void); |
||||||
|
|
||||||
|
void event_set(unsigned int event); |
||||||
|
bool event_get(unsigned int *event); |
||||||
|
void event_clear(unsigned int event); |
||||||
|
void event_dispatch(void); |
||||||
|
void event_register(unsigned int event, event_handler *handler); |
||||||
|
|
||||||
|
#endif /* __EVENT_H */ |
@ -0,0 +1,10 @@ |
|||||||
|
#ifndef __SWI_H |
||||||
|
#define __SWI_H |
||||||
|
|
||||||
|
#define SWI_INTERRUPT_BLOCK 0 |
||||||
|
#define SWI_INTERRUPT_UNBLOCK 1 |
||||||
|
|
||||||
|
#define swi_call(x) swi_call_(x) |
||||||
|
#define swi_call_(x) __asm(" swi " #x "\n") |
||||||
|
|
||||||
|
#endif /* __SWI_H */ |
Loading…
Reference in new issue