misc: Point to correct simavr include dirs
[simavr] / simavr / sim / sim_irq.h
index 6c5e945..d3ac30b 100644 (file)
 
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Internal IRQ system
  * 
- * This subsystem allow any piece of code to "register" a hook to be called when an IRQ is
+ * 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 wich case any oiece of code can be notified when a pin has changed state
+ * 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 particylar IRQ
+ * notify hook twice on one particular IRQ
  * 
  * IRQ calling order is not defined, so don't rely on it.
  * 
  */
 struct avr_irq_t;
 
-typedef void (*avr_irq_notify_t)(struct avr_irq_t * irq, uint32_t value, void * param);
+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;
-       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_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
+       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
+       IRQ_FLAG_INIT           = (1 << 3), //!< this irq hasn't been used yet
 };
 
 /*
+ * IRQ Pool structure
+ */
+typedef struct avr_irq_pool_t {
+       int count;                                              //!< number of irqs living in the pool
+       struct avr_irq_t ** irq;                //!< irqs belonging in this pool
+} avr_irq_pool_t;
+
+/*!
  * Public IRQ structure
  */
 typedef struct avr_irq_t {
-       uint32_t                        irq;
-       uint32_t                        value;
-       uint8_t                         flags;  // IRQ_*
-       avr_irq_hook_t *        hook;
+       struct avr_irq_pool_t * pool;   // TODO: migration in progress
+       const char * name;
+       uint32_t                        irq;            //!< any value the user needs
+       uint32_t                        value;          //!< current value
+       uint8_t                         flags;          //!< IRQ_* flags
+       struct avr_irq_hook_t * hook;   //!< list of hooks to be notified
 } 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);
+//! allocates 'count' IRQs, initializes their "irq" starting from 'base' and increment
+avr_irq_t *
+avr_alloc_irq(
+               avr_irq_pool_t * pool,
+               uint32_t base,
+               uint32_t count,
+               const char ** names /* optional */);
+void
+avr_free_irq(
+               avr_irq_t * irq,
+               uint32_t count);
+
+//! init 'count' IRQs, initializes their "irq" starting from 'base' and increment
+void
+avr_init_irq(
+               avr_irq_pool_t * pool,
+               avr_irq_t * irq,
+               uint32_t base,
+               uint32_t count,
+               const char ** names /* optional */);
+//! '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);
+//! this connects a "source" IRQ to a "destination" IRQ
+void
+avr_connect_irq(
+               avr_irq_t * src,
+               avr_irq_t * dst);
+void
+avr_unconnect_irq(
+               avr_irq_t * src,
+               avr_irq_t * dst);
 
-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
-void avr_connect_irq(avr_irq_t * src, avr_irq_t * dst);
-void avr_irq_register_notify(avr_irq_t * irq, avr_irq_notify_t notify, void * param);
+//! register a notification 'hook' for 'irq' -- 'param' is anything that your want passed back as argument
+void
+avr_irq_register_notify(
+               avr_irq_t * irq,
+               avr_irq_notify_t notify,
+               void * param);
+
+void
+avr_irq_unregister_notify(
+               avr_irq_t * irq,
+               avr_irq_notify_t notify,
+               void * param);
+
+#ifdef __cplusplus
+};
+#endif
 
 #endif /* __SIM_IRQ_H__ */