misc: Point to correct simavr include dirs
[simavr] / simavr / sim / avr_extint.c
1 /*
2         avr_extint.c
3
4         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "avr_extint.h"
27
28
29 static void avr_extint_irq_notify(struct avr_irq_t * irq, uint32_t value, void * param)
30 {
31         avr_extint_t * p = (avr_extint_t *)param;
32         avr_t * avr = p->io.avr;
33
34         uint8_t mode = avr_regbit_get_array(avr, p->eint[irq->irq].isc, 2);
35         int up = !irq->value && value;
36         int down = irq->value && !value;
37         switch (mode) {
38                 case 0:
39                         // unsupported
40                         break;
41                 case 1:
42                         if (up || down)
43                                 avr_raise_interrupt(avr, &p->eint[irq->irq].vector);
44                         break;
45                 case 2:
46                         if (down)
47                                 avr_raise_interrupt(avr, &p->eint[irq->irq].vector);
48                         break;
49                 case 3:
50                         if (up)
51                                 avr_raise_interrupt(avr, &p->eint[irq->irq].vector);
52                         break;
53         }
54 }
55
56 static void avr_extint_reset(avr_io_t * port)
57 {
58         avr_extint_t * p = (avr_extint_t *)port;
59
60         for (int i = 0; i < EXTINT_COUNT; i++) {
61                 avr_irq_register_notify(p->io.irq + i, avr_extint_irq_notify, p);
62
63                 if (p->eint[i].port_ioctl) {
64                         avr_irq_t * irq = avr_io_getirq(p->io.avr,
65                                         p->eint[i].port_ioctl, p->eint[i].port_pin);
66
67                         avr_connect_irq(irq, p->io.irq + i);
68                 }
69         }
70 }
71
72 static const char * irq_names[EXTINT_COUNT] = {
73         [EXTINT_IRQ_OUT_INT0] = "<int0",
74         [EXTINT_IRQ_OUT_INT1] = "<int1",
75         [EXTINT_IRQ_OUT_INT2] = "<int2",
76         [EXTINT_IRQ_OUT_INT3] = "<int3",
77         [EXTINT_IRQ_OUT_INT4] = "<int4",
78         [EXTINT_IRQ_OUT_INT5] = "<int5",
79         [EXTINT_IRQ_OUT_INT6] = "<int6",
80         [EXTINT_IRQ_OUT_INT7] = "<int7",
81 };
82
83 static  avr_io_t        _io = {
84         .kind = "extint",
85         .reset = avr_extint_reset,
86         .irq_names = irq_names,
87 };
88
89 void avr_extint_init(avr_t * avr, avr_extint_t * p)
90 {
91         p->io = _io;
92
93         avr_register_io(avr, &p->io);
94         for (int i = 0; i < EXTINT_COUNT; i++)
95                 avr_register_vector(avr, &p->eint[i].vector);
96
97         // allocate this module's IRQ
98         avr_io_setirqs(&p->io, AVR_IOCTL_EXTINT_GETIRQ(), EXTINT_COUNT, NULL);
99 }
100