From 34ba1d0838b70899855b3eca896c7852edd010be Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Sat, 10 Apr 2010 13:15:09 +0100 Subject: [PATCH] ioport: Added a way to get to the IRQ via register addresses 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 --- simavr/sim/avr_ioport.c | 31 +++++++++++++++++++++++++++++++ simavr/sim/avr_ioport.h | 10 ++++++++++ 2 files changed, 41 insertions(+) diff --git a/simavr/sim/avr_ioport.c b/simavr/sim/avr_ioport.c index 2aed5e3..a2710f6 100644 --- a/simavr/sim/avr_ioport.c +++ b/simavr/sim/avr_ioport.c @@ -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) diff --git a/simavr/sim/avr_ioport.h b/simavr/sim/avr_ioport.h index fe583a1..af20083 100644 --- a/simavr/sim/avr_ioport.h +++ b/simavr/sim/avr_ioport.h @@ -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; -- 2.39.5