Merge git://gitorious.org/~luki/simavr/lukis-simavr into dev-home
[simavr] / simavr / sim / avr_twi.c
1 /*
2         avr_twi.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 #include <stdio.h>
23 #include "avr_twi.h"
24
25 static uint8_t avr_twi_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
26 {
27         avr_twi_t * p = (avr_twi_t *)param;
28 //      uint8_t v = p->input_data_register;
29 //      p->input_data_register = 0;
30 //      printf("avr_twi_read = %02x\n", v);
31         return 0;
32 }
33
34 static void avr_twi_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
35 {
36         avr_twi_t * p = (avr_twi_t *)param;
37 #if 0
38         if (addr == p->r_spdr) {
39 //              printf("avr_twi_write = %02x\n", v);
40                 avr_core_watch_write(avr, addr, v);
41
42                 if (avr_regbit_get(avr, p->spe)) {
43                         // in master mode, any byte is sent as it comes..
44                         if (avr_regbit_get(avr, p->mstr)) {
45                                 avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, v);
46                         }
47                 }
48         }
49 #endif
50 }
51
52 static void avr_twi_irq_input(struct avr_irq_t * irq, uint32_t value, void * param)
53 {
54         avr_twi_t * p = (avr_twi_t *)param;
55         avr_t * avr = p->io.avr;
56
57         // check to see if we are enabled
58         if (!avr_regbit_get(avr, p->twen))
59                 return;
60 #if 0
61         // double buffer the input.. ?
62         p->input_data_register = value;
63         avr_raise_interrupt(avr, &p->twi);
64
65         // if in slave mode, 
66         // 'output' the byte only when we received one...
67         if (!avr_regbit_get(avr, p->mstr)) {
68                 avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, avr->data[p->r_spdr]);
69         }
70 #endif
71 }
72
73
74         // handle a data write, after a (re)start
75 static int twi_slave_write(struct twi_slave_t* p, uint8_t v)
76 {
77         return 0;
78 }
79
80         // handle a data read, after a (re)start
81 static uint8_t twi_slave_read(struct twi_slave_t* p)
82 {
83         return 0;
84 }
85
86
87 static int avr_twi_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_param)
88 {
89         avr_twi_t * p = (avr_twi_t *)port;
90         int res = -1;
91
92         if (ctl == AVR_IOCTL_TWI_GETSLAVE(p->name)) {
93                 *(twi_slave_t**)io_param = &p->slave;
94         } else if (ctl == AVR_IOCTL_TWI_GETBUS(p->name)) {
95                 *(twi_bus_t**)io_param = &p->bus;
96         }
97
98         return res;
99 }
100
101 void avr_twi_reset(struct avr_io_t *io)
102 {
103         avr_twi_t * p = (avr_twi_t *)io;
104         //avr_irq_register_notify(p->io.irq + TWI_IRQ_INPUT, avr_twi_irq_input, p);
105 }
106
107 static  avr_io_t        _io = {
108         .kind = "twi",
109         .reset = avr_twi_reset,
110         .ioctl = avr_twi_ioctl,
111 };
112
113 void avr_twi_init(avr_t * avr, avr_twi_t * p)
114 {
115         p->io = _io;
116         avr_register_io(avr, &p->io);
117         avr_register_vector(avr, &p->twi);
118 //      p->slave = slave_driver;        // get default callbacks
119         twi_slave_init(&p->slave, 0, p);
120         twi_bus_init(&p->bus);
121
122         //printf("%s TWI%c init\n", __FUNCTION__, p->name);
123
124         // allocate this module's IRQ
125         avr_io_setirqs(&p->io, AVR_IOCTL_TWI_GETIRQ(p->name), TWI_IRQ_COUNT, NULL);
126
127         avr_register_io_write(avr, p->r_twdr, avr_twi_write, p);
128         avr_register_io_read(avr, p->r_twdr, avr_twi_read, p);
129 }
130