Streamlined avr_irq subsystem
[simavr] / simavr / sim / sim_irq.h
index c678214..6c5e945 100644 (file)
  * 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.
  */
-// internal structure for a hook, never seen by the notify procs
 struct avr_irq_t;
 
 typedef void (*avr_irq_notify_t)(struct avr_irq_t * irq, uint32_t value, void * param);
 
+// internal structure for a hook, never seen by the notify procs
 typedef struct avr_irq_hook_t {
        struct avr_irq_hook_t * next;
-       void * param;
        int busy;       // prevent reentrance of callbacks
-       avr_irq_notify_t notify;
+       
+       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_hook_t;
 
+enum {
+       IRQ_FLAG_NOT            = (1 << 0),     // change polarity of the IRQ
+       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
+};
+
+/*
+ * Public IRQ structure
+ */
 typedef struct avr_irq_t {
        uint32_t                        irq;
        uint32_t                        value;
+       uint8_t                         flags;  // IRQ_*
        avr_irq_hook_t *        hook;
 } avr_irq_t;
 
 avr_irq_t * avr_alloc_irq(uint32_t base, uint32_t count);
+void avr_free_irq(avr_irq_t * irq, uint32_t count);
+
 void avr_init_irq(avr_irq_t * irq, uint32_t base, uint32_t count);
 void avr_raise_irq(avr_irq_t * irq, uint32_t value);
 // this connects a "source" IRQ to a "destination" IRQ