Commit 34ba1d0838b70899855b3eca896c7852edd010be
authorMichel Pollet <buserror@gmail.com>
Sat, 10 Apr 2010 12:15:09 +0000 (13:15 +0100)
committerMichel Pollet <buserror@gmail.com>
Sat, 10 Apr 2010 12:15:09 +0000 (13:15 +0100)
Now can do a ioctl to get the port IRQs by oassing the address of
a PORT/PIN/DDR register and a pin number.

Signed-off-by: Michel Pollet <buserror@gmail.com>
2 files changed:
simavr/sim/avr_ioport.c
simavr/sim/avr_ioport.h

index 2aed5e3d3685c315430f46f21d3e4e2a46fd0611..a2710f638081fe36c44aee0bd2997cb6c02bc74f 100644 (file)
@@ -95,9 +95,40 @@ static void avr_ioport_reset(avr_io_t * port)
                avr_irq_register_notify(p->io.irq + i, avr_ioport_irq_notify, p);
 }
 
+static int avr_ioport_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_param)
+{
+       avr_ioport_t * p = (avr_ioport_t *)port;
+       int res = -1;
+
+       switch(ctl) {
+               case AVR_IOCTL_IOPORT_GETIRQ_REGBIT: {
+                       avr_ioport_getirq_t * r = (avr_ioport_getirq_t*)io_param;
+
+                       if (r->bit.reg == p->r_port || r->bit.reg == p->r_pin || r->bit.reg == p->r_ddr) {
+                               // it's us ! check the special case when the "all pins" irq is requested
+                               int o = 0;
+                               if (r->bit.mask == 0xff)
+                                       r->irq[o++] = &p->io.irq[IOPORT_IRQ_PIN_ALL];
+                               else {
+                                       // otherwise fil up the ones needed
+                                       for (int bi = 0; bi < 8; bi++)
+                                               if (r->bit.mask & (1 << bi))
+                                                       r->irq[o++] = &p->io.irq[r->bit.bit + bi];
+                               }
+                               if (o < 8)
+                                       r->irq[o] = NULL;
+                               return o;
+                       }
+               }       break;
+       }
+
+       return res;
+}
+
 static avr_io_t        _io = {
        .kind = "io",
        .reset = avr_ioport_reset,
+       .ioctl = avr_ioport_ioctl,
 };
 
 void avr_ioport_init(avr_t * avr, avr_ioport_t * p)
index fe583a14fc2446b2e5871c759d43746f4159502a..af20083eb3c5ebe72f649e9ba1f375f12ec4cabf 100644 (file)
@@ -35,6 +35,16 @@ enum {
 // add port name (uppercase) to get the real IRQ
 #define AVR_IOCTL_IOPORT_GETIRQ(_name) AVR_IOCTL_DEF('i','o','g',(_name))
 
+
+// this ioctl takes a avr_regbit_t, compares the register address
+// to PORT/PIN/DDR and return the corresponding IRQ(s) if it matches
+typedef struct avr_ioport_getirq_t {
+       avr_regbit_t bit;       // bit wanted
+       avr_irq_t * irq[8];     // result, terminated by NULL if < 8
+} avr_ioport_getirq_t;
+
+#define AVR_IOCTL_IOPORT_GETIRQ_REGBIT AVR_IOCTL_DEF('i','o','g','r')
+
 typedef struct avr_ioport_t {
        avr_io_t        io;
        char name;