Added a real example on how to integrate simavr, etc
[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 static int twi_slave_has_address(struct twi_slave_t* p, uint8_t address)
74 {
75         return 0;
76 }
77
78         // handle start conditionto address+w, restart means "stop" wasn't called
79 static int twi_slave_start(struct twi_slave_t* p, uint8_t address, int restart)
80 {
81         return 0;
82 }
83
84         // handle a data write, after a (re)start
85 static int twi_slave_write(struct twi_slave_t* p, uint8_t v)
86 {
87         return 0;
88 }
89
90         // handle a data read, after a (re)start
91 static uint8_t twi_slave_read(struct twi_slave_t* p)
92 {
93         return 0;
94 }
95
96         // stop condition detected
97 static void twi_slave_stop(struct twi_slave_t* p)
98 {
99 }
100
101 static twi_slave_t slave_driver = {
102         .has_address = twi_slave_has_address,
103         .start = twi_slave_start,
104         .stop = twi_slave_stop,
105         .write = twi_slave_write,
106         .read = twi_slave_read
107 };
108
109 void avr_twi_reset(struct avr_io_t *io)
110 {
111         avr_twi_t * p = (avr_twi_t *)io;
112         //avr_irq_register_notify(p->io.irq + TWI_IRQ_INPUT, avr_twi_irq_input, p);
113 }
114
115 static  avr_io_t        _io = {
116         .kind = "twi",
117         .reset = avr_twi_reset,
118 };
119
120 void avr_twi_init(avr_t * avr, avr_twi_t * p)
121 {
122         p->io = _io;
123         avr_register_io(avr, &p->io);
124         avr_register_vector(avr, &p->twi);
125         p->slave = slave_driver;        // get default callbacks
126         twi_slave_init(&p->slave, p);
127         twi_bus_init(&p->bus);
128
129         printf("%s TWI%c init\n", __FUNCTION__, p->name);
130
131         // allocate this module's IRQ
132         p->io.irq_count = TWI_IRQ_COUNT;
133         p->io.irq = avr_alloc_irq(0, p->io.irq_count);
134         p->io.irq_ioctl_get = AVR_IOCTL_TWI_GETIRQ(p->name);
135
136         avr_register_io_write(avr, p->r_twdr, avr_twi_write, p);
137         avr_register_io_read(avr, p->r_twdr, avr_twi_read, p);
138 }
139