2
* ----------------------------------------------------------------------------
3
* "THE BEER-WARE LICENSE" (Revision 42):
4
* <joerg@FreeBSD.ORG> wrote this file. As long as you retain this notice you
5
* can do whatever you want with this stuff. If we meet some day, and you think
6
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
7
* ----------------------------------------------------------------------------
10
/* $Id: twitest.c,v 1.2.2.2 2005/02/07 22:47:46 arcanum Exp $ */
13
* Simple demo program that talks to a 24Cxx I�C EEPROM using the
14
* builtin TWI interface of an ATmega device.
22
#include <compat/twi.h> /* Note [1] */
29
#define F_CPU 14745600UL /* Note [2] */
32
* Compatibility defines. This should work on ATmega8, ATmega16,
33
* ATmega163, ATmega323 and ATmega128 (IOW: on all devices that
34
* provide a builtin TWI interface).
36
* On the 128, it defaults to USART 1.
39
# ifdef UCSR1A /* ATmega128 */
55
* TWI address for 24Cxx EEPROM:
57
* 1 0 1 0 E2 E1 E0 R/~W 24C01/24C02
58
* 1 0 1 0 E2 E1 A8 R/~W 24C04
59
* 1 0 1 0 E2 A9 A8 R/~W 24C08
60
* 1 0 1 0 A10 A9 A8 R/~W 24C16
62
#define TWI_SLA_24CXX 0xa0 /* E2 E1 E0 = 0 0 0 */
65
* Maximal number of iterations to wait for a device to respond for a
66
* selection. Should be large enough to allow for a pending write to
67
* complete, but low enough to properly abort an infinite loop in case
68
* a slave is broken or not present at all. With 100 kHz TWI clock,
69
* transfering the start condition and SLA+R/W packet takes about 10
70
* �s. The longest write period is supposed to not exceed ~ 10 ms.
71
* Thus, normal operation should not require more than 100 iterations
72
* to get the device to respond to a selection.
77
* Number of bytes that can be written in a row, see comments for
78
* ee24xx_write_page() below. Some vendor's devices would accept 16,
79
* but 8 seems to be the lowest common denominator.
81
* Note that the page size must be a power of two, this simplifies the
82
* page boundary calculations below.
87
* Saved TWI status register, for error messages only. We need to
88
* save it in a variable, since the datasheet only guarantees the TWSR
89
* register to have valid contents while the TWINT bit in TWCR is set.
94
* Do all the startup-time peripheral initializations: UART (for our
95
* debug/test output), and TWI clock.
101
#if F_CPU <= 1000000UL
104
* Slow system clock, double Baud rate to improve rate error.
107
UBRR = (F_CPU / (8 * 9600UL)) - 1; /* 9600 Bd */
109
UBRR = (F_CPU / (16 * 9600UL)) - 1; /* 9600 Bd */
111
UCSRB = _BV(TXEN); /* tx enable */
113
/* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
115
/* has prescaler (mega128 & newer) */
119
#if F_CPU < 3600000UL
120
TWBR = 10; /* smallest TWBR value, see note [5] */
122
TWBR = (F_CPU / 100000UL - 16) / 2;
128
* Send character c down the UART Tx, wait until tx holding register
137
loop_until_bit_is_set(UCSRA, UDRE);
145
* Read "len" bytes from EEPROM starting at "eeaddr" into "buf".
147
* This requires two bus cycles: during the first cycle, the device
148
* will be selected (master transmitter mode), and the address
149
* transfered. Address bits exceeding 256 are transfered in the
150
* E2/E1/E0 bits (subaddress bits) of the device selector.
152
* The second bus cycle will reselect the device (repeated start
153
* condition, going into master receiver mode), and transfer the data
154
* from the device to the TWI master. Multiple bytes can be
155
* transfered by ACKing the client's transfer. The last transfer will
156
* be NACKed, which the client will take as an indication to not
157
* initiate further transfers.
160
ee24xx_read_bytes(uint16_t eeaddr, int len, uint8_t *buf)
162
uint8_t sla, twcr, n = 0;
165
/* patch high bits of EEPROM address into SLA */
166
sla = TWI_SLA_24CXX | (((eeaddr >> 8) & 0x07) << 1);
170
* First cycle: master transmitter mode
177
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
178
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
179
switch ((twst = TW_STATUS))
181
case TW_REP_START: /* OK, but should not happen */
185
case TW_MT_ARB_LOST: /* Note [9] */
189
return -1; /* error: not in start condition */
190
/* NB: do /not/ send stop condition */
195
TWDR = sla | TW_WRITE;
196
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
197
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
198
switch ((twst = TW_STATUS))
203
case TW_MT_SLA_NACK: /* nack during select: device busy writing */
207
case TW_MT_ARB_LOST: /* re-arbitrate */
211
goto error; /* must send stop condition */
214
TWDR = eeaddr; /* low 8 bits of addr */
215
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
216
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
217
switch ((twst = TW_STATUS))
222
case TW_MT_DATA_NACK:
229
goto error; /* must send stop condition */
234
* Next cycle(s): master receiver mode
236
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send (rep.) start condition */
237
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
238
switch ((twst = TW_STATUS))
240
case TW_START: /* OK, but should not happen */
252
TWDR = sla | TW_READ;
253
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
254
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
255
switch ((twst = TW_STATUS))
270
for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) /* Note [13] */;
275
twcr = _BV(TWINT) | _BV(TWEN); /* send NAK this time */
276
TWCR = twcr; /* clear int to start transmission */
277
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
278
switch ((twst = TW_STATUS))
280
case TW_MR_DATA_NACK:
281
len = 0; /* force end of loop */
294
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */
304
* Write "len" bytes into EEPROM starting at "eeaddr" from "buf".
306
* This is a bit simpler than the previous function since both, the
307
* address and the data bytes will be transfered in master transmitter
308
* mode, thus no reselection of the device is necessary. However, the
309
* EEPROMs are only capable of writing one "page" simultaneously, so
310
* care must be taken to not cross a page boundary within one write
311
* cycle. The amount of data one page consists of varies from
312
* manufacturer to manufacturer: some vendors only use 8-byte pages
313
* for the smaller devices, and 16-byte pages for the larger devices,
314
* while other vendors generally use 16-byte pages. We thus use the
315
* smallest common denominator of 8 bytes per page, declared by the
316
* macro PAGE_SIZE above.
318
* The function simply returns after writing one page, returning the
319
* actual number of data byte written. It is up to the caller to
320
* re-invoke it in order to write further data.
323
ee24xx_write_page(uint16_t eeaddr, int len, uint8_t *buf)
329
if (eeaddr + len < (eeaddr | (PAGE_SIZE - 1)))
330
endaddr = eeaddr + len;
332
endaddr = (eeaddr | (PAGE_SIZE - 1)) + 1;
333
len = endaddr - eeaddr;
335
/* patch high bits of EEPROM address into SLA */
336
sla = TWI_SLA_24CXX | (((eeaddr >> 8) & 0x07) << 1);
344
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
345
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
346
switch ((twst = TW_STATUS))
348
case TW_REP_START: /* OK, but should not happen */
356
return -1; /* error: not in start condition */
357
/* NB: do /not/ send stop condition */
361
TWDR = sla | TW_WRITE;
362
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
363
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
364
switch ((twst = TW_STATUS))
369
case TW_MT_SLA_NACK: /* nack during select: device busy writing */
372
case TW_MT_ARB_LOST: /* re-arbitrate */
376
goto error; /* must send stop condition */
379
TWDR = eeaddr; /* low 8 bits of addr */
380
TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
381
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
382
switch ((twst = TW_STATUS))
387
case TW_MT_DATA_NACK:
394
goto error; /* must send stop condition */
397
for (; len > 0; len--)
400
TWCR = _BV(TWINT) | _BV(TWEN); /* start transmission */
401
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
402
switch ((twst = TW_STATUS))
404
case TW_MT_DATA_NACK:
405
goto error; /* device write protected -- Note [16] */
416
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */
426
* Wrapper around ee24xx_write_page() that repeats calling this
427
* function until either an error has been returned, or all bytes
431
ee24xx_write_bytes(uint16_t eeaddr, int len, uint8_t *buf)
439
printf("Calling ee24xx_write_page(%d, %d, %p)",
442
rv = ee24xx_write_page(eeaddr, len, buf);
444
printf(" => %d\n", rv);
462
printf("error: TWI status %#x\n", twst);
476
fdevopen(uart_putchar, NULL, 0);
478
for (a = 0; a < 256;)
480
printf("%#04x: ", a);
481
rv = ee24xx_read_bytes(a, 16, b);
485
printf("warning: short read %d\n", rv);
487
for (x = 0; x < rv; x++)
488
printf("%02x ", b[x]);
491
#define EE_WRITE(addr, str) ee24xx_write_bytes(addr, sizeof(str)-1, str)
492
rv = EE_WRITE(55, "The quick brown fox jumps over the lazy dog.");
495
printf("Wrote %d bytes.\n", rv);
496
for (a = 0; a < 256;)
498
printf("%#04x: ", a);
499
rv = ee24xx_read_bytes(a, 16, b);
503
printf("warning: short read %d\n", rv);
505
for (x = 0; x < rv; x++)
506
printf("%02x ", b[x]);