]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/i2c.c
Merge branch 'chan-fatfs' into fatfs-integration
[z180-stamp.git] / avr / i2c.c
1 /*
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 /*
8 * I2C (TWI) master interface.
9 */
10
11 #include "common.h"
12 #include <avr/interrupt.h>
13 #include <string.h>
14
15 #include "config.h"
16 #include "timer.h"
17 #include "debug.h"
18 #include "i2c.h"
19
20 #define DEBUG_I2C 0
21
22 #define debug_i2c(fmt, args...) \
23 debug_cond(DEBUG_I2C, fmt, ##args)
24
25
26 /* General TWI Master status codes */
27 #define TWI_START 0x08 /* START has been transmitted */
28 #define TWI_REP_START 0x10 /* Repeated START has been transmitted */
29 #define TWI_ARB_LOST 0x38 /* Arbitration lost */
30
31 /* TWI Master Transmitter status codes */
32 #define TWI_MTX_ADR_ACK 0x18 /* SLA+W has been transmitted and ACK received */
33 #define TWI_MTX_ADR_NACK 0x20 /* SLA+W has been transmitted and NACK received */
34 #define TWI_MTX_DATA_ACK 0x28 /* Data byte has been transmitted and ACK received */
35 #define TWI_MTX_DATA_NACK 0x30 /* Data byte has been transmitted and NACK received */
36
37 /* TWI Master Receiver status codes */
38 #define TWI_MRX_ADR_ACK 0x40 /* SLA+R has been transmitted and ACK received */
39 #define TWI_MRX_ADR_NACK 0x48 /* SLA+R has been transmitted and NACK received */
40 #define TWI_MRX_DATA_ACK 0x50 /* Data byte has been received and ACK transmitted */
41 #define TWI_MRX_DATA_NACK 0x58 /* Data byte has been received and NACK transmitted */
42
43 /* TWI Miscellaneous status codes */
44 #define TWI_NO_STATE 0xF8 /* No relevant state information available */
45 #define TWI_BUS_ERROR 0x00 /* Bus error due to an illegal START or STOP condition */
46
47
48 /*
49 * TWINT: TWI Interrupt Flag
50 * TWEA: TWI Enable Acknowledge Bit
51 * TWSTA: TWI START Condition Bit
52 * TWSTO: TWI STOP Condition Bit
53 * TWEN: TWI Enable Bit
54 * TWIE: TWI Interrupt Enable
55 *
56 * (1<<TWEN)|(1<<TWIE)|(1<<TWINT)
57 * (1<<TWEN)|(1<<TWIE)|(1<<TWINT)| (1<<TWEA)
58 * (1<<TWEN)|(1<<TWIE)|(1<<TWINT)
59 *
60 * default:
61 * (1<<TWEN)| (1<<TWINT)| (1<<TWSTO)
62 *
63 * Init:
64 * (1<<TWEN)
65 *
66 * start read/write:
67 * (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
68 * (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
69 * (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
70 * (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
71 *
72 * wait ready:
73 * (1<<TWIE)|(1<<TWSTO)
74 *
75 *
76 *
77 *i2c_result
78 *
79 * 0b10000000 Busy (Transmission in progress)
80 * 0b01000000 Timeout
81 * 0b00001000 Start transmitted
82 * 0b00000100 Slave acknowledged address
83 * 0b00000010 Data byte(s) transmitted/received
84 * 0b00000001 Transmission completed
85 *
86 *
87 *----------------------------------------------------------------------
88 */
89
90 #define TWI_C_DISABLE 0x00
91 #define TWI_C_ENABLE (1<<TWEN)
92
93
94
95 typedef struct i2c_msg_s {
96 uint8_t stat;
97 #define XMIT_DONE (1<<0)
98 #define DATA_ACK (1<<1)
99 #define ADDR_ACK (1<<2)
100 #define START (1<<3)
101 #define TIMEOUT (1<<6)
102 #define BUSY (1<<7)
103 uint8_t idx;
104 uint8_t len;
105 uint8_t buf[CONFIG_SYS_I2C_BUFSIZE];
106 } i2c_msg_t;
107
108 static volatile i2c_msg_t xmit;
109
110 ISR(TWI_vect)
111 {
112 uint8_t tmp_stat;
113 uint8_t tmp_idx;
114 uint8_t next_twcr;
115 uint8_t n;
116
117 tmp_idx = xmit.idx;
118 tmp_stat = xmit.stat;
119
120 uint8_t twsr = TWSR;
121
122 switch (twsr & 0xf8) {
123
124 case TWI_START:
125 case TWI_REP_START:
126 tmp_stat = BUSY | START;
127 tmp_idx = 0; /* reset xmit_buf index */
128
129 if (tmp_idx < xmit.len) { /* all bytes transmited? */
130 TWDR = xmit.buf[tmp_idx];
131 ++tmp_idx;
132 next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT);
133 } else {
134 tmp_stat |= XMIT_DONE;
135 tmp_stat &= ~BUSY;
136 next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO);
137 }
138 break;
139
140 case TWI_MTX_ADR_ACK:
141 case TWI_MTX_DATA_ACK:
142 if ((twsr&0xf8) == TWI_MTX_ADR_ACK)
143 tmp_stat |= ADDR_ACK;
144 else
145 tmp_stat |= DATA_ACK;
146
147 if (tmp_idx < xmit.len) { /* all bytes transmited? */
148 TWDR = xmit.buf[tmp_idx];
149 ++tmp_idx;
150 next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT);
151 } else {
152 tmp_stat |= XMIT_DONE;
153 tmp_stat &= ~BUSY;
154 next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO);
155 }
156 break;
157
158 case TWI_MTX_DATA_NACK:
159 tmp_stat |= XMIT_DONE;
160 tmp_stat &= ~BUSY;
161 next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO);
162 break;
163
164 case TWI_MRX_DATA_ACK:
165 xmit.buf[tmp_idx] = TWDR;
166 ++tmp_idx;
167 /* fall thru */
168 case TWI_MRX_ADR_ACK:
169 if ((twsr&0xf8) == TWI_MRX_ADR_ACK)
170 tmp_stat |= ADDR_ACK;
171 else
172 tmp_stat |= DATA_ACK;
173
174 n = xmit.len-1;
175 if (tmp_idx < n) {
176 next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
177 } else {
178 next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT);
179 }
180 break;
181
182 case TWI_MRX_DATA_NACK:
183 tmp_stat |= ADDR_ACK | DATA_ACK;
184
185 xmit.buf[tmp_idx] = TWDR;
186 ++tmp_idx;
187 /* fall thru */
188 default:
189 tmp_stat &= ~BUSY;
190 next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO);
191 break;
192 }
193
194 xmit.stat = tmp_stat;
195 xmit.idx = tmp_idx;
196
197 debug_i2c("|%02x", twsr);
198 TWCR = next_twcr;
199 }
200
201
202 /*------------------------------------------------------------------*/
203
204 static uint8_t twps;
205 static uint8_t twbr;
206
207
208 static void _init(void)
209 {
210 xmit.stat = 0;
211
212 /* Disable TWI, disable TWI interrupt. */
213 /* (Reset TWI hardware state machine.) */
214 TWCR = TWI_C_DISABLE;
215 _delay_us(5);
216 #if DEBUG_I2C
217 memset((void *) xmit.buf, 0xdf, sizeof(xmit.buf));
218 #endif
219
220 TWDR = 0xff;
221 TWBR = twbr;
222 TWSR = twps & 0x03;
223 TWCR = TWI_C_ENABLE;
224 }
225
226 void i2c_init(uint32_t speed)
227 {
228 twps = 0;
229 uint32_t tmp_twbr = F_CPU /2 / speed - 8;
230
231 while (tmp_twbr > 255) {
232 tmp_twbr >>= 4;
233 twps += 1;
234 }
235 debug_cond((twps > 3), "*** TWCLK too low: %lu Hz\n", speed);
236
237 twbr = (uint8_t) tmp_twbr;
238
239 PRR0 &= ~_BV(PRTWI);
240 _init();
241 }
242
243
244 int_fast8_t i2c_waitready(void)
245 {
246 uint32_t timer = get_timer(0);
247 uint8_t timeout = 0;
248
249 do {
250 if (get_timer(timer) >= 30) {
251 timeout = TIMEOUT;
252 _init();
253 }
254 } while ((TWCR & ((1<<TWIE)|(1<<TWSTO))) != 0 && !timeout);
255
256 xmit.stat |= timeout;
257
258 #if DEBUG_I2C
259 dump_ram((uint8_t *) &xmit, 4, "=== i2c_wait ready: (done)");
260 _delay_ms(30);
261 #endif
262 return xmit.stat;
263 }
264
265 static
266 int i2c_send(uint8_t chip, uint16_t addr, uint8_t alen, uint8_t *buffer, int8_t len)
267 {
268 uint8_t i, n;
269 uint8_t rc;
270
271 rc = i2c_waitready();
272 if ((rc & (BUSY | TIMEOUT)) != 0)
273 return rc;
274
275 xmit.stat = BUSY;
276 xmit.buf[0] = chip<<1;
277 for (i = 1; i < alen+1; i++) {
278 xmit.buf[i] = (uint8_t) addr;
279 addr >>= 8;
280 }
281 for (n = len + i; i < n; i++)
282 xmit.buf[i] = *buffer++;
283 xmit.len = i;
284
285 #if DEBUG_I2C
286 dump_ram((uint8_t *) &xmit, 0x20, "=== i2c_send");
287 _delay_ms(30);
288 #endif
289 /* Enable TWI, TWI int and initiate start condition */
290 TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA);
291
292 rc = xmit.stat;
293
294 return rc;
295 }
296
297 static
298 int i2c_recv(uint8_t chip, uint8_t *buffer, int8_t len)
299 {
300 uint8_t rc;
301
302 rc = i2c_waitready();
303 if ((rc & (BUSY | TIMEOUT)) != 0)
304 return rc;
305
306 xmit.stat = BUSY;
307 xmit.len = len + 1;
308 xmit.buf[0] = (chip<<1) | 1;
309
310 #if DEBUG_I2C
311 dump_ram((uint8_t *) &xmit, 0x20, "=== i2c_recv: before start");
312 _delay_ms(30);
313 #endif
314 /* Enable TWI, TWI int and initiate start condition */
315 TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA);
316 rc = i2c_waitready();
317
318 #if DEBUG_I2C
319 dump_ram((uint8_t *) &xmit, 0x20, "=== i2c_recv: after completion");
320 _delay_ms(30);
321 #endif
322 if (rc & DATA_ACK) {
323 /* at least 1 byte received */
324 for (uint8_t i=1, n=xmit.idx; i < n; i++)
325 *buffer++ = xmit.buf[i];
326 }
327
328 return rc;
329 }
330
331 /*
332 * Read/Write interface:
333 * chip: I2C chip address, range 0..127
334 * addr: Memory (register) address within the chip
335 * alen: Number of bytes to use for addr (typically 1, 2 for larger
336 * memories, 0 for register type devices with only one
337 * register)
338 * buffer: Where to read/write the data
339 * len: How many bytes to read/write
340 *
341 * Returns: 0 on success, not 0 on failure
342 */
343
344 int i2c_write(uint8_t chip, unsigned int addr, uint_fast8_t alen,
345 uint8_t *buffer, uint_fast8_t len)
346 {
347 int rc;
348
349 if ((alen > 2) || (1 + alen + len > CONFIG_SYS_I2C_BUFSIZE)) {
350 debug("** i2c_write: buffer overflow, alen: %u, len: %u\n",
351 alen, len);
352 return -1;
353 }
354
355 i2c_send(chip, addr, alen, buffer, len);
356 rc = i2c_waitready();
357
358 return (rc & XMIT_DONE) != 0;
359 }
360
361 int i2c_read(uint8_t chip, unsigned int addr, uint_fast8_t alen,
362 uint8_t *buffer, uint_fast8_t len)
363 {
364 int rc;
365
366 if ((alen > 2) || (1 + len > CONFIG_SYS_I2C_BUFSIZE)) {
367 debug("** i2c_read: parameter error: alen: %u, len: %u\n",
368 alen, len);
369 return -1;
370 }
371
372 if (alen != 0) {
373 i2c_send(chip, addr, alen, NULL, 0);
374 }
375 rc = i2c_recv(chip, buffer, len);
376
377 return !((rc & (XMIT_DONE|DATA_ACK)) == (XMIT_DONE|DATA_ACK));
378 }