}
void
-avr_raise_irq(
+avr_raise_irq_float(
avr_irq_t * irq,
- uint32_t value)
+ uint32_t value,
+ int floating)
{
if (!irq)
return ;
if (irq->value == output &&
(irq->flags & IRQ_FLAG_FILTERED) && !(irq->flags & IRQ_FLAG_INIT))
return;
- irq->flags &= ~IRQ_FLAG_INIT;
+ irq->flags &= ~(IRQ_FLAG_INIT | IRQ_FLAG_FLOATING);
+ if (floating)
+ irq->flags |= IRQ_FLAG_FLOATING;
avr_irq_hook_t *hook = irq->hook;
while (hook) {
avr_irq_hook_t * next = hook->next;
if (hook->notify)
hook->notify(irq, output, hook->param);
if (hook->chain)
- avr_raise_irq(hook->chain, output);
+ avr_raise_irq_float(hook->chain, output, floating);
hook->busy--;
}
hook = next;
irq->value = output;
}
+void
+avr_raise_irq(
+ avr_irq_t * irq,
+ uint32_t value)
+{
+ avr_raise_irq_float(irq, value, !!(irq->flags & IRQ_FLAG_FLOATING));
+}
+
void
avr_connect_irq(
avr_irq_t * src,
hook = hook->next;
}
}
+
+uint8_t
+avr_irq_get_flags(
+ avr_irq_t * irq )
+{
+ return irq->flags;
+}
+
+void
+avr_irq_set_flags(
+ avr_irq_t * irq,
+ uint8_t flags )
+{
+ irq->flags = flags;
+}
IRQ_FLAG_FILTERED = (1 << 1), //!< do not "notify" if "value" is the same as previous raise
IRQ_FLAG_ALLOC = (1 << 2), //!< this irq structure was malloced via avr_alloc_irq
IRQ_FLAG_INIT = (1 << 3), //!< this irq hasn't been used yet
+ IRQ_FLAG_FLOATING = (1 << 4), //!< this 'pin'/signal is floating
};
/*
uint32_t base,
uint32_t count,
const char ** names /* optional */);
+//! Returns the current IRQ flags
+uint8_t
+avr_irq_get_flags(
+ avr_irq_t * irq );
+//! Sets this irq's flags
+void
+avr_irq_set_flags(
+ avr_irq_t * irq,
+ uint8_t flags );
//! 'raise' an IRQ. Ie call their 'hooks', and raise any chained IRQs, and set the new 'value'
void
avr_raise_irq(
avr_irq_t * irq,
uint32_t value);
+//! Same as avr_raise_irq(), but also allow setting the float status
+void
+avr_raise_irq_float(
+ avr_irq_t * irq,
+ uint32_t value,
+ int floating);
//! this connects a "source" IRQ to a "destination" IRQ
void
avr_connect_irq(