typedef struct avr_irq_hook_t {
struct avr_irq_hook_t * next;
int busy; // prevent reentrance of callbacks
-
+
struct avr_irq_t * chain; // raise the IRQ on this too - optional if "notify" is on
avr_irq_notify_t notify; // called when IRQ is raised - optional if "chain" is on
void * param; // "notify" parameter
avr_irq_pool_t * pool,
avr_irq_t * irq)
{
- if ((pool->count & 0xf) == 0) {
- pool->irq = (avr_irq_t**)realloc(pool->irq,
- (pool->count + 16) * sizeof(avr_irq_t *));
+ int insert = 0;
+ /* lookup a slot */
+ for (; insert < pool->count && pool->irq[insert]; insert++)
+ ;
+ if (insert == pool->count) {
+ if ((pool->count & 0xf) == 0) {
+ pool->irq = (avr_irq_t**)realloc(pool->irq,
+ (pool->count + 16) * sizeof(avr_irq_t *));
+ }
+ pool->count++;
}
- pool->irq[pool->count++] = irq;
+ pool->irq[insert] = irq;
irq->pool = pool;
}
avr_irq_t * irq = (avr_irq_t*)malloc(sizeof(avr_irq_t) * count);
avr_init_irq(pool, irq, base, count, names);
for (int i = 0; i < count; i++)
- irq[i].flags |= IRQ_FLAG_ALLOC;
+ irq[i].flags |= IRQ_FLAG_ALLOC;
return irq;
}
{
if (!irq || !notify)
return;
-
+
avr_irq_hook_t *hook = irq->hook;
while (hook) {
if (hook->notify == notify && hook->param == param)
if (hook->chain)
avr_raise_irq(hook->chain, output);
hook->busy--;
- }
+ }
hook = next;
}
// the value is set after the callbacks are called, so the callbacks
/*
* Internal IRQ system
- *
+ *
* This subsystem allows any piece of code to "register" a hook to be called when an IRQ is
* raised. The IRQ definition is up to the module defining it, for example a IOPORT pin change
* might be an IRQ in which case any piece of code can be notified when a pin has changed state
- *
+ *
* The notify hooks are chained, and duplicates are filtered out so you can't register a
* notify hook twice on one particular IRQ
- *
+ *
* IRQ calling order is not defined, so don't rely on it.
- *
+ *
* IRQ hook needs to be registered in reset() handlers, ie after all modules init() bits
* have been called, to prevent race condition of the initialization order.
*/
* Public IRQ structure
*/
typedef struct avr_irq_t {
- struct avr_irq_pool_t * pool; // TODO: migration in progress
- const char * name;
+ struct avr_irq_pool_t * pool;
+ const char * name;
uint32_t irq; //!< any value the user needs
uint32_t value; //!< current value
uint8_t flags; //!< IRQ_* flags