4 Internal TWI/i2c slave/master subsystem
6 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
8 This file is part of simavr.
10 simavr is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 simavr is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with simavr. If not, see <http://www.gnu.org/licenses/>.
27 void twi_bus_init(twi_bus_t * bus)
31 void twi_bus_attach(twi_bus_t * bus, twi_slave_t * slave)
33 twi_slave_detach(slave);
35 slave->next = bus->slave;
39 int twi_bus_start(twi_bus_t * bus, uint8_t address)
41 // if we already have a peer, check to see if it's
42 // still matching, if so, skip the lookup
43 if (bus->peer && twi_slave_match(bus->peer, address))
44 return bus->peer->start(bus->peer, address, 1);
47 twi_slave_t *s = bus->slave;
49 if (twi_slave_match(s, address)) {
50 if (s->start(s, address, 0)) {
61 void twi_bus_stop(twi_bus_t * bus)
63 if (bus->peer && bus->peer->stop)
64 bus->peer->stop(bus->peer);
68 int twi_bus_write(twi_bus_t * bus, uint8_t data)
70 if (!bus->peer || !bus->peer->write)
73 int res = bus->peer->write(bus->peer, data);
75 bus->peer->byte_index++;
79 uint8_t twi_bus_read(twi_bus_t * bus)
81 if (!bus->peer || !bus->peer->read)
84 uint8_t res = bus->peer->read(bus->peer);
86 bus->peer->byte_index++;
90 void twi_slave_init(twi_slave_t * slave, void * param)
95 void twi_slave_detach(twi_slave_t * slave)
97 if (!slave || !slave->bus)
99 twi_slave_t *s = slave->bus->slave;
101 if (s->next == slave) {
103 if (slave->bus->peer == slave)
104 slave->bus->peer = NULL;
106 s->next = slave->next;
115 int twi_slave_match(twi_slave_t * slave, uint8_t address)
117 if (slave->has_address)
118 return slave->has_address(slave, address);
119 return (address & ~1) == (slave->address & ~1);