Commit 7303c1476425315c570175c9c58208a68d7ee874
authorJakob Gruber <jakob.gruber@gmail.com>
Thu, 23 Aug 2012 11:13:25 +0000 (13:13 +0200)
committerJakob Gruber <jakob.gruber@gmail.com>
Wed, 29 Aug 2012 13:00:46 +0000 (15:00 +0200)
Manual filtering could cause us to miss pin changes when data
is written to PINs while the port is set to input mode (and thus
the PORT register is not updated).

simavr/sim/avr_ioport.c

index 3966996f0f865988beb15cc472bfda1b68d7ea91..6e0966ee2b0e72946d903286b6b2543370330943 100644 (file)
@@ -38,19 +38,14 @@ static uint8_t avr_ioport_read(struct avr_t * avr, avr_io_addr_t addr, void * pa
 static void avr_ioport_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
 {
        avr_ioport_t * p = (avr_ioport_t *)param;
-       uint8_t oldv = avr->data[addr];
 
        avr_core_watch_write(avr, addr, v);
-       if (v != oldv) {
-               //      printf("PORT%c(%02x) = %02x (was %02x)\n", p->name, addr, v, oldv);
-               int mask = v ^ oldv;
-
-               // raise the internal IRQ callbacks
-               for (int i = 0; i < 8; i++)
-                       if (mask & (1 << i))
-                               avr_raise_irq(p->io.irq + i, (v >> i) & 1);
-               avr_raise_irq(p->io.irq + IOPORT_IRQ_PIN_ALL, v);
-       }
+       //      printf("PORT%c(%02x) = %02x (was %02x)\n", p->name, addr, v, oldv);
+
+       // raise the internal IRQ callbacks
+       for (int i = 0; i < 8; i++)
+               avr_raise_irq(p->io.irq + i, (v >> i) & 1);
+       avr_raise_irq(p->io.irq + IOPORT_IRQ_PIN_ALL, v);
 }
 
 /*
@@ -192,6 +187,9 @@ void avr_ioport_init(avr_t * avr, avr_ioport_t * p)
        // allocate this module's IRQ
        avr_io_setirqs(&p->io, AVR_IOCTL_IOPORT_GETIRQ(p->name), IOPORT_IRQ_COUNT, NULL);
 
+       for (int i = 0; i < IOPORT_IRQ_COUNT; i++)
+               p->io.irq[i].flags |= IRQ_FLAG_FILTERED;
+
        avr_register_io_write(avr, p->r_port, avr_ioport_write, p);
        avr_register_io_read(avr, p->r_pin, avr_ioport_read, p);
        avr_register_io_write(avr, p->r_pin, avr_ioport_pin_write, p);