4 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
6 This file is part of simavr.
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.
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.
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/>.
26 * This block respectfully nicked straight out from the Atmel sample
27 * code for AVR315. Typos and all.
28 * There is no copyright notice on the original file.
30 /****************************************************************************
32 ****************************************************************************/
33 // General TWI Master staus codes
34 #define TWI_START 0x08 // START has been transmitted
35 #define TWI_REP_START 0x10 // Repeated START has been transmitted
36 #define TWI_ARB_LOST 0x38 // Arbitration lost
38 // TWI Master Transmitter staus codes
39 #define TWI_MTX_ADR_ACK 0x18 // SLA+W has been tramsmitted and ACK received
40 #define TWI_MTX_ADR_NACK 0x20 // SLA+W has been tramsmitted and NACK received
41 #define TWI_MTX_DATA_ACK 0x28 // Data byte has been tramsmitted and ACK received
42 #define TWI_MTX_DATA_NACK 0x30 // Data byte has been tramsmitted and NACK received
44 // TWI Master Receiver staus codes
45 #define TWI_MRX_ADR_ACK 0x40 // SLA+R has been tramsmitted and ACK received
46 #define TWI_MRX_ADR_NACK 0x48 // SLA+R has been tramsmitted and NACK received
47 #define TWI_MRX_DATA_ACK 0x50 // Data byte has been received and ACK tramsmitted
48 #define TWI_MRX_DATA_NACK 0x58 // Data byte has been received and NACK tramsmitted
50 // TWI Slave Transmitter staus codes
51 #define TWI_STX_ADR_ACK 0xA8 // Own SLA+R has been received; ACK has been returned
52 #define TWI_STX_ADR_ACK_M_ARB_LOST 0xB0 // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
53 #define TWI_STX_DATA_ACK 0xB8 // Data byte in TWDR has been transmitted; ACK has been received
54 #define TWI_STX_DATA_NACK 0xC0 // Data byte in TWDR has been transmitted; NOT ACK has been received
55 #define TWI_STX_DATA_ACK_LAST_BYTE 0xC8 // Last data byte in TWDR has been transmitted (TWEA = �0�); ACK has been received
57 // TWI Slave Receiver staus codes
58 #define TWI_SRX_ADR_ACK 0x60 // Own SLA+W has been received ACK has been returned
59 #define TWI_SRX_ADR_ACK_M_ARB_LOST 0x68 // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
60 #define TWI_SRX_GEN_ACK 0x70 // General call address has been received; ACK has been returned
61 #define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78 // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
62 #define TWI_SRX_ADR_DATA_ACK 0x80 // Previously addressed with own SLA+W; data has been received; ACK has been returned
63 #define TWI_SRX_ADR_DATA_NACK 0x88 // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
64 #define TWI_SRX_GEN_DATA_ACK 0x90 // Previously addressed with general call; data has been received; ACK has been returned
65 #define TWI_SRX_GEN_DATA_NACK 0x98 // Previously addressed with general call; data has been received; NOT ACK has been returned
66 #define TWI_SRX_STOP_RESTART 0xA0 // A STOP condition or repeated START condition has been received while still addressed as Slave
68 // TWI Miscellaneous status codes
69 #define TWI_NO_STATE 0xF8 // No relevant state information available; TWINT = �0�
70 #define TWI_BUS_ERROR 0x00 // Bus error due to an illegal START or STOP condition
79 avr_regbit_setto_raw(p->io.avr, p->twsr, v);
80 avr_raise_irq(p->io.irq + TWI_IRQ_STATUS, v);
82 avr_raise_interrupt(p->io.avr, &p->twi);
89 return avr_regbit_get_raw(p->io.avr, p->twsr);
92 static avr_cycle_count_t
93 avr_twi_set_state_timer(
95 avr_cycle_count_t when,
98 avr_twi_t * p = (avr_twi_t *)param;
99 _avr_twi_status_set(p, p->next_twstate, 1);
105 * This is supposed to trigger a timer whose duration is a multiple
106 * of 'twi' clock cycles, which should be derived from the prescaler
107 * (100khz, 400khz etc).
108 * Right now it cheats and uses one twi cycle == one usec.
111 _avr_twi_delay_state(
116 p->next_twstate = state;
117 // TODO: calculate clock rate, convert to cycles, and use that
118 avr_cycle_timer_register_usec(
119 p->io.avr, twi_cycles, avr_twi_set_state_timer, p);
129 avr_twi_t * p = (avr_twi_t *)param;
131 uint8_t twen = avr_regbit_get(avr, p->twen);
132 uint8_t twsta = avr_regbit_get(avr, p->twsta);
133 uint8_t twsto = avr_regbit_get(avr, p->twsto);
134 uint8_t twint = avr_regbit_get(avr, p->twi.raised);
136 avr_core_watch_write(avr, addr, v);
138 printf("avr_twi_write %02x START:%d STOP:%d ACK:%d INT:%d TWSR:%02x\n", v,
139 avr_regbit_get(avr, p->twsta),
140 avr_regbit_get(avr, p->twsto),
141 avr_regbit_get(avr, p->twea),
142 avr_regbit_get(avr, p->twi.raised),
143 avr_regbit_get_raw(p->io.avr, p->twsr));
145 if (twen != avr_regbit_get(avr, p->twen)) {
147 if (!twen) { // if we were running, now now are not
148 avr_regbit_clear(avr, p->twea);
149 avr_regbit_clear(avr, p->twsta);
150 avr_regbit_clear(avr, p->twsto);
151 avr_clear_interrupt(avr, p->twi.vector);
152 avr_core_watch_write(avr, p->r_twdr, 0xff);
153 _avr_twi_status_set(p, TWI_NO_STATE, 0);
157 printf("TWEN: %d\n", twen);
162 uint8_t cleared = avr_regbit_get(avr, p->twi.raised);
164 /*int cleared = */avr_clear_interrupt_if(avr, &p->twi, twint);
165 // printf("cleared %d\n", cleared);
167 if (!twsto && avr_regbit_get(avr, p->twsto)) {
168 // generate a stop condition
169 printf("<<<<< I2C stop\n");
171 if (p->state) { // doing stuff
172 if (p->state & TWI_COND_START) {
173 avr_raise_irq(p->io.irq + TWI_IRQ_MOSI,
174 avr_twi_irq_msg(TWI_COND_STOP, p->peer_addr, 1));
179 if (!twsta && avr_regbit_get(avr, p->twsta)) {
180 printf(">>>>> I2C %sstart\n", p->state & TWI_COND_START ? "RE" : "");
181 // generate a start condition
182 if (p->state & TWI_COND_START)
183 _avr_twi_delay_state(p, 3, TWI_REP_START);
185 _avr_twi_delay_state(p, 3, TWI_START);
187 p->state = TWI_COND_START;
191 !avr_regbit_get(avr, p->twsta) &&
192 !avr_regbit_get(avr, p->twsto)) {
193 // writing or reading a byte
194 if (p->state & TWI_COND_ADDR) {
195 if (p->peer_addr & 1)
196 printf("I2C READ byte from %02x\n", p->peer_addr);
198 printf("I2C WRITE byte %02x to %02x\n", avr->data[p->r_twdr], p->peer_addr);
199 // a normal data byte
200 uint8_t msgv = p->peer_addr & 1 ? TWI_COND_READ : TWI_COND_WRITE;
201 if (avr_regbit_get(avr, p->twea))
202 msgv |= TWI_COND_ACK;
204 p->state &= ~TWI_COND_ACK; // clear ACK bit
206 // we send an IRQ and we /expect/ a slave to reply
207 // immediately via an IRQ to set the COND_ACK bit
208 // otherwise it's assumed it's been nacked...
209 avr_raise_irq(p->io.irq + TWI_IRQ_MOSI,
210 avr_twi_irq_msg(msgv, p->peer_addr, avr->data[p->r_twdr]));
212 if (p->peer_addr & 1) { // read ?
213 _avr_twi_delay_state(p, 9,
214 msgv & TWI_COND_ACK ?
215 TWI_MTX_DATA_ACK : TWI_MTX_DATA_NACK);
217 _avr_twi_delay_state(p, 9,
218 p->state & TWI_COND_ACK ?
219 TWI_MTX_DATA_ACK : TWI_MTX_DATA_NACK);
223 printf("I2C Master address %02x\n", avr->data[p->r_twdr]);
225 p->state |= TWI_COND_ADDR;
226 p->peer_addr = avr->data[p->r_twdr];
227 p->state &= ~TWI_COND_ACK; // clear ACK bit
229 // we send an IRQ and we /expect/ a slave to reply
230 // immediately via an IRQ tp set the COND_ACK bit
231 // otherwise it's assumed it's been nacked...
232 avr_raise_irq(p->io.irq + TWI_IRQ_MOSI,
233 avr_twi_irq_msg(TWI_COND_START, p->peer_addr, 0));
235 if (p->peer_addr & 1) { // read ?
236 _avr_twi_delay_state(p, 9,
237 p->state & TWI_COND_ACK ?
238 TWI_MRX_ADR_ACK : TWI_MRX_ADR_NACK);
240 _avr_twi_delay_state(p, 9,
241 p->state & TWI_COND_ACK ?
242 TWI_MTX_ADR_ACK : TWI_MTX_ADR_NACK);
249 * prevent code from rewriting out status bits, since we actualy use them!
252 avr_twi_write_status(
258 avr_twi_t * p = (avr_twi_t *)param;
259 uint8_t sr = avr_regbit_get(avr, p->twsr);
260 uint8_t c = avr_regbit_get(avr, p->twps);
262 avr_core_watch_write(avr, addr, v);
263 avr_regbit_setto(avr, p->twsr, sr); // force restore
265 if (c != avr_regbit_get(avr, p->twps)) {
266 // prescaler bits changed...
272 struct avr_irq_t * irq,
276 avr_twi_t * p = (avr_twi_t *)param;
277 avr_t * avr = p->io.avr;
279 // check to see if we are enabled
280 if (!avr_regbit_get(avr, p->twen))
282 avr_twi_msg_irq_t msg;
285 // receiving an acknowledge bit
286 if (msg.u.twi.msg & TWI_COND_ACK) {
287 printf("I2C received ACK:%d\n", msg.u.twi.data & 1);
288 if (msg.u.twi.data & 1)
289 p->state |= TWI_COND_ACK;
291 p->state &= ~TWI_COND_ACK;
293 // receive a data byte from a slave
294 if (msg.u.twi.msg & TWI_COND_READ) {
295 printf("I2C received %02x\n", msg.u.twi.data);
296 avr->data[p->r_twdr] = msg.u.twi.data;
300 void avr_twi_reset(struct avr_io_t *io)
302 avr_twi_t * p = (avr_twi_t *)io;
303 avr_irq_register_notify(p->io.irq + TWI_IRQ_MISO, avr_twi_irq_input, p);
306 static const char * irq_names[TWI_IRQ_COUNT] = {
307 [TWI_IRQ_MISO] = "8<mosi",
308 [TWI_IRQ_MOSI] = "32>miso",
309 [TWI_IRQ_STATUS] = "8>status",
312 static avr_io_t _io = {
314 .reset = avr_twi_reset,
315 .irq_names = irq_names,
318 void avr_twi_init(avr_t * avr, avr_twi_t * p)
321 avr_register_io(avr, &p->io);
322 avr_register_vector(avr, &p->twi);
324 //printf("%s TWI%c init\n", __FUNCTION__, p->name);
326 // allocate this module's IRQ
327 avr_io_setirqs(&p->io, AVR_IOCTL_TWI_GETIRQ(p->name), TWI_IRQ_COUNT, NULL);
329 avr_register_io_write(avr, p->twen.reg, avr_twi_write, p);
330 avr_register_io_write(avr, p->twsr.reg, avr_twi_write_status, p);