misc: Typos
[simavr] / simavr / sim / sim_twi.h
1 /*
2         sim_twi.h
3
4         Internal TWI/i2c slave/master subsystem
5
6         You can have a "bus" to talk to a bunch of "slaves"
7         
8         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
9
10         This file is part of simavr.
11
12         simavr is free software: you can redistribute it and/or modify
13         it under the terms of the GNU General Public License as published by
14         the Free Software Foundation, either version 3 of the License, or
15         (at your option) any later version.
16
17         simavr is distributed in the hope that it will be useful,
18         but WITHOUT ANY WARRANTY; without even the implied warranty of
19         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20         GNU General Public License for more details.
21
22         You should have received a copy of the GNU General Public License
23         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
24  */
25
26 #ifndef SIM_TWI_H_
27 #define SIM_TWI_H_
28
29 #include <stdint.h>
30 #include "sim_irq.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 /*
37  * The TWI system is designed to be representing the same state as 
38  * a TWI/i2c bus itself. So each "state" of the bus is an IRQ sent
39  * by the master to the slave, with a couple sent from the
40  * slave to the master.
41  * This is designed to decorelate the operations on the "bus" so
42  * the firmware has time to "run" before acknowledging a byte, for
43  * example.
44  * 
45  * IRQ Timeline goes as follow  with an example transaction that
46  * does write address, write register, read a byte after a i2c restart
47  * then stops the transaction.
48  * 
49  * Master:      START   MOSI    START   MISO    ACK     STOP
50  * Slave:               ACK             ACK             ACK             MISO    
51  */
52 enum twi_state_e {
53         TWI_MASTER_STOP = 0,
54         TWI_MASTER_START,                       // master does a start with address
55         TWI_MASTER_MOSI,                        // master i2c write
56         TWI_MASTER_MISO,                        // master i2c read
57         TWI_MASTER_ACK,                         // master i2c ACK after a i2c read
58         TWI_MASTER_STATE_COUNT,
59
60         TWI_SLAVE_MISO = 0,                     // slave i2c read.
61         TWI_SLAVE_ACK,                          // slave acknowledges TWI_MASTER_MOSI
62         TWI_SLAVE_STATE_COUNT,  
63 };
64
65 #define TWI_ADDRESS_READ_MASK   0x01
66
67 typedef struct twi_slave_t {
68         avr_irq_t               irq[TWI_SLAVE_STATE_COUNT];
69
70         struct twi_bus_t * bus; // bus we are attached to
71         struct twi_slave_t * next;      // daisy chain on the bus
72         
73         uint32_t                address;        // can specify up to 4 matching addresses here
74         int                             match;          // we are selected on the bus
75         int                             index;          // byte index in the transaction
76         
77         uint8_t                 latch;          // last received byte
78 } twi_slave_t;
79
80
81 typedef struct twi_bus_t {
82         avr_irq_t               irq[TWI_MASTER_STATE_COUNT];
83         
84         struct twi_slave_t * slave;     // daisy chain on the bus
85         struct twi_slave_t * peer;      // during a transaction, this is the selected slave
86
87         uint8_t                 latch;          // last received byte
88         uint8_t                 ack;            // last received ack
89 } twi_bus_t;
90
91 void twi_bus_init(twi_bus_t * bus);
92 int twi_bus_start(twi_bus_t * bus, uint8_t address);
93 int twi_bus_write(twi_bus_t * bus, uint8_t data);
94 uint8_t twi_bus_read(twi_bus_t * bus);
95 void twi_bus_stop(twi_bus_t * bus);
96
97 void twi_slave_init(twi_slave_t * slave, uint8_t address, void * param);
98 void twi_slave_detach(twi_slave_t * slave);
99
100 #ifdef __cplusplus
101 };
102 #endif
103
104 #endif /*  SIM_TWI_H_ */