2004-08-09 Joerg Wunsch * doc/examples/twitest/twitest.c: Make it work on 1 MHz clock. * doc/examples/twitest/twitest.dox: Renumber annotations. Index: doc/examples/twitest/twitest.c =================================================================== RCS file: /cvsroot/avr-libc/avr-libc/doc/examples/twitest/twitest.c,v retrieving revision 1.1 diff -u -u -r1.1 twitest.c --- doc/examples/twitest/twitest.c 18 Dec 2002 22:35:38 -0000 1.1 +++ doc/examples/twitest/twitest.c 9 Aug 2004 21:09:24 -0000 @@ -98,19 +98,33 @@ ioinit(void) { - UCSRB = _BV(TXEN); /* tx enable */ +#if SYSCLK <= 1000000UL + /* + * Note [4] + * Slow system clock, double Baud rate to improve rate error. + */ + UCSRA = _BV(U2X); + UBRR = (SYSCLK / (8 * 9600UL)) - 1; /* 9600 Bd */ +#else UBRR = (SYSCLK / (16 * 9600UL)) - 1; /* 9600 Bd */ +#endif + UCSRB = _BV(TXEN); /* tx enable */ /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ #if defined(TWPS0) /* has prescaler (mega128 & newer) */ TWSR = 0; #endif + +#if SYSCLK < 3600000UL + TWBR = 10; /* smallest TWBR value, see note [5] */ +#else TWBR = (SYSCLK / 100000UL - 16) / 2; +#endif } /* - * Note [4] + * Note [6] * Send character c down the UART Tx, wait until tx holding register * is empty. */ @@ -126,7 +140,7 @@ } /* - * Note [5] + * Note [7] * * Read "len" bytes from EEPROM starting at "eeaddr" into "buf". * @@ -152,7 +166,7 @@ sla = TWI_SLA_24CXX | (((eeaddr >> 8) & 0x07) << 1); /* - * Note [6] + * Note [8] * First cycle: master transmitter mode */ restart: @@ -168,7 +182,7 @@ case TW_START: break; - case TW_MT_ARB_LOST: /* Note [7] */ + case TW_MT_ARB_LOST: /* Note [9] */ goto begin; default: @@ -176,7 +190,7 @@ /* NB: do /not/ send stop condition */ } - /* Note [8] */ + /* Note [10] */ /* send SLA+W */ TWDR = sla | TW_WRITE; TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */ @@ -187,7 +201,7 @@ break; case TW_MT_SLA_NACK: /* nack during select: device busy writing */ - /* Note [9] */ + /* Note [11] */ goto restart; case TW_MT_ARB_LOST: /* re-arbitrate */ @@ -196,7 +210,7 @@ default: goto error; /* must send stop condition */ } - + TWDR = eeaddr; /* low 8 bits of addr */ TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */ while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */ @@ -216,7 +230,7 @@ } /* - * Note [10] + * Note [12] * Next cycle(s): master receiver mode */ TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send (rep.) start condition */ @@ -253,7 +267,7 @@ goto error; } - for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) /* Note [11] */; + for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) /* Note [13] */; len > 0; len--) { @@ -276,7 +290,7 @@ } } quit: - /* Note [12] */ + /* Note [14] */ TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */ return rv; @@ -326,7 +340,7 @@ return -1; begin: - /* Note 13 */ + /* Note [15] */ TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */ while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */ switch ((twst = TW_STATUS)) @@ -361,7 +375,7 @@ default: goto error; /* must send stop condition */ } - + TWDR = eeaddr; /* low 8 bits of addr */ TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */ while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */ @@ -388,7 +402,7 @@ switch ((twst = TW_STATUS)) { case TW_MT_DATA_NACK: - goto error; /* device write protected -- Note [14] */ + goto error; /* device write protected -- Note [16] */ case TW_MT_DATA_ACK: rv++; Index: doc/examples/twitest/twitest.dox =================================================================== RCS file: /cvsroot/avr-libc/avr-libc/doc/examples/twitest/twitest.dox,v retrieving revision 1.4 diff -u -u -r1.4 twitest.dox --- doc/examples/twitest/twitest.dox 23 Jul 2004 21:24:39 -0000 1.4 +++ doc/examples/twitest/twitest.dox 9 Aug 2004 21:09:25 -0000 @@ -123,10 +123,24 @@ \par Note [4] +For slow clocks, enable the 2 x U[S]ART clock multiplier, to improve +the baud rate error. This will allow a 9600 Bd communication using +the standard 1 MHz calibrated RC oscillator. See also the Baud rate +tables in the datasheets. + +\par Note [5] + +The datasheet explains why a minimum TWBR value of 10 should be +maintained when running in master mode. Thus, for system clocks below +3.6 MHz, we cannot run the bus at the intented clock rate of 100 kHz +but have to slow down accordingly. + +\par Note [6] + This function is used by the standard output facilities that are utilized in this example for debugging and demonstration purposes. -\par Note [5] +\par Note [7] In order to shorten the data to be sent over the TWI bus, the 24Cxx EEPROMs support multiple data bytes transfered within a single @@ -136,7 +150,7 @@ would wrap around and start back from 0 when reaching the end of the device). -\par Note [6] +\par Note [8] When reading the EEPROM, a first device selection must be made with write intent (R/~W bit set to 0 indicating a write operation) in order @@ -150,7 +164,7 @@ required when using a true interrupt routine, since as soon as TWINT is re-asserted, the next bus transaction will start. -\par Note [7] +\par Note [9] Since the TWI bus is multi-master capable, there is potential for a bus contention when one master starts to access the bus. Normally, @@ -167,7 +181,7 @@ start condition to be initiated, which will normally be delayed until the currently active master has released the bus. -\par Note [8] +\par Note [10] Next, the device slave is going to be reselected (using a so-called repeated start condition which is meant to guarantee that the bus @@ -176,7 +190,7 @@ order to request the device slave to start transfering data from the slave to the master in the next packet. -\par Note [9] +\par Note [11] If the EEPROM device is still busy writing one or more cells after a previous write request, it will simply leave its bus interface drivers @@ -193,7 +207,7 @@ device is declared to be not responding at all, and an error is returned, will be limited to MAX_ITER. -\par Note [10] +\par Note [12] This is called master receiver mode: the bus master still supplies the SCL clock, but the device slave drives the SDA line with @@ -204,19 +218,19 @@ ACK is handled by setting the TWEA bit in TWCR when starting the current transfer. -\par Note [11] +\par Note [13] The control word sent out in order to initiate the transfer of the next data packet is initially set up to assert the TWEA bit. During the last loop iteration, TWEA is de-asserted so the client will get informed that no further transfer is desired. -\par Note [12] +\par Note [14] Except in the case of lost arbitration, all bus transactions must properly be terminated by the master initiating a stop condition. -\par Note [13] +\par Note [15] Writing to the EEPROM device is simpler than reading, since only a master transmitter mode transfer is needed. Note that the first @@ -228,7 +242,7 @@ at the indicated address. The internal address pointer will be incremented after each write operation. -\par Note [14] +\par Note [16] 24Cxx devices can become write-protected by strapping their ~WC pin to logic high. (Leaving it unconnected is explicitly allowed, and