0% found this document useful (0 votes)
27 views12 pages

AVR311: Using The TWI Module As I C Slave: Features

This document describes a TWI slave implementation using a hardware TWI module in AVR microcontrollers. It provides a C code driver for a TWI slave that is compatible with the I2C protocol and supports both standard and fast modes. The driver handles transmission and interrupts and can wake from sleep on address recognition.

Uploaded by

uwbg.ycion44
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views12 pages

AVR311: Using The TWI Module As I C Slave: Features

This document describes a TWI slave implementation using a hardware TWI module in AVR microcontrollers. It provides a C code driver for a TWI slave that is compatible with the I2C protocol and supports both standard and fast modes. The driver handles transmission and interrupts and can wake from sleep on address recognition.

Uploaded by

uwbg.ycion44
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

AVR311: Using the TWI module as I2C slave

Features 8-bit
• C-code driver for TWI slave
• Compatible with Philips' I2C protocol Microcontrollers
• Uses the hardware TWI module
• Interrupt driven transmission
• Supports both Standard mode and Fast mode
• Wake up from all sleep modes on own address recognition
Application Note

Introduction
The Two Wire serial Interface (TWI) is compatible with Philips' I2C protocol. The
bus was developed to allow simple, robust and cost effective communication
between integrated circuits in electronics. The strengths of the TWI bus includes
the capability of addressing up to 128 devices on the same bus, arbitration, and the
possibility to have multiple masters on the bus.
A hardware TWI module is included in most of the AVR devices available.
This application note describes a TWI slave implementation, in form of a full-
featured driver and an example of usage for this driver. The driver handles
transmission according to both Standard mode (<100kbps) and Fast mode
(<400kbps).

Rev. 2565D-AVR-08/09
Theory
This section gives a short description of the TWI interface in general and the TWI
module on the megaAVR’s. For more detailed information refer to the datasheets.

Two-wire serial Interface The Two-wire Serial Interface (TWI) is ideally suited for typical microcontroller
applications. The TWI protocol allows the systems designer to interconnect up to 128
individually addressable devices using only two bi-directional bus lines, one for clock
(SCL) and one for data (SDA). The only external hardware needed to implement the
bus is a single pull-up resistor for each of the TWI bus lines. All devices connected to
the bus have individual addresses, and mechanisms for resolving bus contention are
inherent in the TWI protocol.

Figure 1. TWI Bus Interconnection.


VCC

Device 1 Device 2 Device 3 ........ Device n R1 R2

SDA

SCL

The TWI bus is a multi-master bus where one or more devices, capable of taking
control of the bus, can be connected. Only Master devices can drive both the SCL
and SDA lines while a Slave device is only allowed to issue data on the SDA line.
Data transfer is always initiated by a Bus Master device. A high to low transition on
the SDA line while SCL is high is defined to be a START condition or a repeated start
condition.

Figure 2. TWI Address and Data Packet Format

Addr MSB Addr LSB R/W ACK Data MSB Data LSB ACK

SDA

SCL
1 2 7 8 9 1 2 7 8 9

START SLA+R/W Data Byte STOP

2 AVR311
2565D-AVR-08/09
AVR311
A START condition is always followed by the (unique) 7-bit slave address and then by
a Data Direction bit. The Slave device addressed now acknowledges to the Master by
holding SDA low for one clock cycle. If the Master does not receive any acknowledge
the transfer is terminated. Depending of the Data Direction bit, the Master or Slave
now transmits 8-bit of data on the SDA line. The receiving device then acknowledges
the data. Multiple bytes can be transferred in one direction before a repeated START
or a STOP condition is issued by the Master. The transfer is terminated when the
Master issues a STOP condition. A STOP condition is defined by a low to high
transition on the SDA line while the SCL is high.
If a Slave device cannot handle incoming data until it has performed some other
function, it can hold SCL low to force the Master into a wait-state.
All data packets transmitted on the TWI bus are 9 bits long, consisting of one data
byte and an acknowledge bit. During a data transfer, the master generates the clock
and the START and STOP conditions, while the receiver is responsible for
acknowledging the reception. An Acknowledge (ACK) is signaled by the receiver
pulling the SDA line low during the ninth SCL cycle. If the receiver leaves the SDA
line high, a NACK is signaled.

The AVR TWI Module The TWI module is comprised of several sub modules, as shown in Figure 3. All
registers drawn in a thick line are accessible through the AVR data bus.
Figure 3. Overview of the TWI module in the AVR devices.
SCL SDA
Slew-rate Spike Slew-rate Spike
Control Filter Control Filter

Bus Interface Unit Bit Rate Generator


START / STOP
Spike Suppression Prescaler
Control

Address/Data Shift Bit Rate Register


Arbitration detection Ack
Register (TWDR) (TWBR)

Address Match Unit Control Unit


TWI Unit

Address Register Status Register Control Register


(TWAR) (TWSR) (TWCR)

State Machine and


Address Comparator
Status control

3
2565D-AVR-08/09
Control Unit The AVR TWI module can operate in both Master and Slave mode. The mode of
operation is distinguished by the TWI status codes in the TWI Status Register
(TWSR) and by the use of certain bits in the TWI Control Register (TWCR).
A set of predefined status codes covers the different states that the TWI can be in
when a TWI event occurs. The status codes are divided in Master and Slave codes
and further in receive and transmit related codes. Status codes for Bus Error and Idle
also exist.
The TWI module operates as a state machine and is event driven: if a START
CONDITION followed by a TWI address matches the address in the Slave’s TWI
Address Register (TWAR) the TWINT flag is set, resulting in the execution of the
corresponding interrupt (if Global Interrupt and TWI interrupts are enabled). The
firmware of the Slave responds by reading the status code in TWSR and responding
accordingly. All TWI events will set the TWINT flag, and the firmware must respond
based on the status in TWSR.
As long as the TWINT Flag is set, the SCL line is held low. This allows the application
software to complete its tasks before allowing the TWI transmission to continue.
The TWINT Flag is set in the following situations:
• After the TWI has transmitted a START/REPEATED START condition
• After the TWI has transmitted SLA+R/W
• After the TWI has transmitted an address byte
• After the TWI has lost arbitration
• After the TWI has been addressed by own Slave address or general call
• After the TWI has received a data byte
• After a STOP or REPEATED START has been received while still addressed as a
Slave.
• When a bus error has occurred due to an illegal START or STOP condition

Bit Rate Generator The Bite Rate Generator unit controls the period of SCL when operating in a Master
mode. The SCL period is controlled by settings in the TWI Bit Rate Register (TWBR)
and the Prescaler bits in the TWI Status Register (TWSR). Slave operation does not
depend on Bit Rate or Prescaler settings, but the CPU clock frequency in the Slave
must be at least 16 times higher than the SCL frequency. Table 1 shows minimum
CPU clock speeds for normal and high speed TWI transmission.
Table 1. Minimum CPU clock frequencies versus SCL frequencies.
CPU Clock frequency [MHz] SCL frequency [kHz]
>6.4 400
>1.6 100

SCL and SDA Pins Both TWI lines (SDA and SCL) are bi-directional, therefore outputs connected to the
TWI bus must be of an open-drain or an open-collector type. Each line must be
connected to the supply voltage via a pull-up resistor. A line is then logic high when
none of the connected devices drives the line, and logic low if one or more drives the
line low.
The output drivers contain a slew-rate limiter. The input stages contain a spike
suppression unit removing spikes shorter than 50 ns. Note that the internal pull-ups in
the AVR pads can be enabled by setting the PORT bits corresponding to the SCL and

4 AVR311
2565D-AVR-08/09
AVR311
SDA pins, as explained in the I/O Port section. The internal pull-ups can in some
systems eliminate the need for external ones.
Figure 4 shows how to connect the TWI units to the TWI bus. The value of Rp
depends on VCC and the bus capacitance (typically 4.7 k).

Figure 4. TWI connection.


Vcc

Rp

SCL
TWI Slave
TWI Slave
TWI Master TWI Slave
SDA

Address Match Unit The Address Match unit is only used in slave mode, and checks if the received
address bytes match the 7-bit address in the TWI Address Register (TWAR). Upon an
address match, the Control Unit is informed, allowing correct action to be taken. The
TWI may or may not acknowledge its address, depending on settings in the TWCR.
On devices with a TWI Address Mask Register (TWAMR) the Address Match unit can
react on a masked subset of addresses.
Although the clock system to the TWI is turned off in all sleep modes, the interface
can still acknowledge its own Slave address or the general call address by using the
TWI Bus clock as a clock source. The part will then wake up from sleep and the TWI
will hold the SCL clock low during the wake up and until the TWINT Flag is cleared.
Bus Interface Unit This unit contains the Data and Address Shift Register (TWDR), a START/STOP
Controller and Arbitration detection hardware. The TWDR contains the address or
data bytes to be transmitted, or the address or data bytes received. In addition it also
contains a register containing the (N)ACK bit to be transmitted or received. Note that
after waking up from sleep the content of TWDR is undefined. I.e. on devices with
multi slave address support it is not possible to use the TWDR content to determine
what slave address that triggered the device to wake up from sleep.
The START/STOP Controller is responsible for generation and detection of START,
REPEATED START, and STOP conditions. The START/STOP controller is able to
detect START and STOP conditions even when the AVR MCU is in one of the sleep
modes, enabling the MCU to wake up if addressed by a Master. If the TWI has
initiated a transmission as Master, the Arbitration Detection hardware continuously
monitors the transmission trying to determine if arbitration is in process. If the TWI
has lost an arbitration, the Control Unit is informed. Correct action can then be taken
and appropriate status codes generated.

5
2565D-AVR-08/09
Implementation
The implemented code in this application note is a pure slave driver. The TWI
modules also support master operation. See “AVR315 TWI Master Implementation”
for a sample of a master driver. The master and slave drivers could be merged to one
combined master and slave driver, but this is not the scope of this application note.
The slave driver c-code consists of three files.
• TWI_Slave.c
• TWI_Slave.h
• Main.c
There is an example on how to use of the driver in the main.c file. The TWI_Slave.h
file must be included in the main application and contains all function declarations and
defines for all TWI status codes. The TWI status code defines can be used to
evaluate error messages and to take appropriate actions. The file TWI_Slave.c
contains all the driver functions.
Some devices have an additional TWI Address Mask Register (TWAMR) that enables
a device to respond to several TWI slave addresses. A customized version of the
standard implementation described here, is included in the application note
attachment.
Functions The driver consists of the TWI Interrupt Service Routine and several functions. All
functions are available for use outside the driver file scope. Some of them are
however also used internally by the driver it self. All functions in the driver are listed in
Table 2. The actual code sizes for the functions, compiled with the IAR compiler are
listed in Table 4.

Table 2. Description of functions in the TWI Slave driver.


Function name Description
void TWI_Slave_Initialise Call this function to set up the TWI slave to its initial standby state.
( uchar ownSlaveAddress ) Remember to enable interrupts from the main application after
initializing the TWI. Pass both the slave address and the requrements
for triggering on a general call in the same byte. Use e.g. this notation
when calling this function:
TWI_Slave_Initialise((TWI_slaveAddress<<TWI_ADR_BITS)
| (TRUE<<TWI_GEN_BIT));
The TWI module is configured to NACK on any requests. Use a
TWI_Start_Transceiver function to start the TWI.
void TWI_Start_Transceiver_With_Data Call this function to send a prepared message, or start the Transceiver
( uchar *message, uchar messageSize) for reception. Include a pointer to the data to be sent if a SLA+W is
received. The data will be copied to the TWI buffer. Also include how
many bytes that should be sent. Note that unlike the similar Master
function, the Address byte is not included in the message buffers. The
function will hold execution (loop) until the TWI_ISR has completed
with the previous operation, then initialize the next operation and return.
void TWI_Start_Transceiver( ) Call this function to start the Transceiver without specifing new
transmission data. Usefull for restarting a transmission, or just starting
the transceiver for reception. The driver will reuse the data previously
put in the transceiver buffers. The function will hold execution (loop)
until the TWI_ISR has completed with the previous operation, then
initialize the next operation and return.

6 AVR311
2565D-AVR-08/09
AVR311
uchar TWI_Transceiver_Busy( ) Call this function to test if the TWI_ISR is busy transmitting.
uchar TWI_Get_State_Info( ) Call this function to fetch the state information of the previous operation.
The function will hold execution (loop) until the TWI_ISR has completed
with the previous operation. If there was an error, then the function will
return the TWI State code.
uchar TWI_Get_Data_From_Transceiver Call this function to read out the received data from the TWI transceiver
( uchar *message, uchar messageSize) buffer. I.e. first call TWI_Start_Transceiver to get the TWI Transceiver
to fetch data. Then Run this function to collect the data when they have
arrived. Include a pointer to where to place the data and the number of
bytes to fetch in the function call. The function will hold execution (loop)
until the TWI_ISR has completed with the previous operation, before
reading out the data and returning. If there was an error in the previous
transmission the function will return the TWI State code.
__interrupt void TWI_ISR( ) This function is the Interrupt Service Routine (ISR), and automatically
called when the TWI interrupt is triggered; that is whenever a TWI event
has occurred. This function should not be called directly from the main
application.

Table 3. Description of the driver register byte containing status information from the
last transceiver operation. Available as bit fields within a byte.
TWI_statusReg Description
TWI_statusReg.lastTransOK Set to 1 when an operation has completed
successfully.
TWI_statusReg.RxDataInBuf This setting is only valid if lastTransOK is set to 1.
Set to 1 when data has been received and stored
in the transceiver buffer. I.e. if 0 then it was a
transmission.
TWI_statusReg.genAddressCall This setting is only valid if RxDataInBuf is set to 1.
It is set to 1 when the reception was a General
Call. I.e. if 0 then it was an Address Match.

Table 4. Code sizes with the IAR 3.10 compiler.


TWI Master functions [bytes]
TWI_Slave_Initialise( ) 12
TWI_Transceiver_Busy( ) 6
TWI_Get_State_Info( ) 12
TWI_Start_Transceiver_With_Data( ) 68
TWI_Start_Transceiver ( ) 8
TWI_ TWI_Get_Data_From_Transceiver ( ) 62
TWI_ISR( ) 162
335

Figure 5 shows flowcharts of the process of receiving and transmitting data over the
TWI interface through the drivers. Data is passed through parameters to the functions
while the status of an operation is available trough a global status variable. Figure 6
contains the flowchart for the TWI driver it self. A more detailed description of the
actions for each event/state in the TWI Interrupt Service Routine can be found in a
flowchart in Figure 7. In Figure 7 the left column contains the different states/events

7
2565D-AVR-08/09
the TWI state machine can be in when entering the Interrupt. A case switch executes
the different actions dependant on the cause of the interrupt call.
The transceiver uses only one transmission buffer. At any time a message from the
master will be processed on this buffer. I.e. a Master Write will overwrite the content,
while a Master Read will transmit the content of this buffer.
When calling the Start Transceiver function the complete message is copied into the
transceiver buffer. Then it enables the TWI interrupt to initiate the transceiver. The
Interrupt then takes care of the complete transmission and disables itself when the
transmission is completed, or if an error state occurs. The driver can this way poll the
interrupt enable bit to check if a transmission is complete. The main application is
only allowed to access the global transceiver variables while the TWI transceiver is
not busy. The interrupt stores eventual error states in a variable that is available for
the main application through a function call.
Note that the driver puts the TWI module in passive mode after each transceiver
operation. This is to enable the application to read and interpreted the message from
the master before responding to any new requests. All new messages from the
master coming before the TWI slave is restarted will therefore be NACKed on. It is
therefore important that the master gives the slave enough time to respond before
sending the next message.
In the “Combined” flowchart in Figure 5 there is suggested a place to add error
handling code. Note that if this is not implemented in this example, then an error state
will lead to a restart of the slave transceiver which could be a way of handling an error
transmission.

8 AVR311
2565D-AVR-08/09
AVR311
Figure 5. Calling the TWI driver from the application.
TWI Slave TWI Slave Combined TWI Slave
receive data transmit data receive and transmit

Initialize TWI with Initialize TWI with Initialize TWI with


slave address slave address slave address
Last
transmission went
Enable Enable Enable No ok?
Global Interrupts Global Interrupts Global Interrupts
Interpret errormessag
and prepare
Yes appropriate action
Start Transceiver Start Transceiver with Start Transceiver
pointer to data and
number of bytes to send
Data in RxBuffer?
Do something useful
while waiting for
TWI transceiver to Return
complete
TWI Busy? Yes

Get data from Get data from


Transceiver transceiver
No

Return Interpret data and


prepare appropriate
action

Next TWI
Yes operation will be a No
Master Read?

Yes

Start Transeiver with Start Transeiver


pointer to data and
number of bytes to send

Do something usefull
while waiting for
TWI transceiver to
complete

9
2565D-AVR-08/09
Figure 6. TWI driver functions.
TWI Get data from TWI Start Transceiver
TWI Get State Info TWI Start Transceiver TWI Interrupt
Transceiver with Data

Wait until TWI Interrupt is Wait until TWI Interrupt is Wait until TWI Interrupt Wait until TWI Interrupt TWI state machine
disabled disabled is disabled is disabled taking care of the
complete
transmission/
reception
Return (TWI state) Copy transmit buffer
Transceiver No and message size, to
operation completed internal driver buffer
with success? Disables it self when
transmission completed
Yes or error state detected
Clear statusReg & Clear statusReg &
TWIstate TWIstate
Copy data from internal
driver buffer Return
Enable TWI interrupt Enable TWI interrupt

Clear DataInRxBuf bit in


statusReg
Return Return

Return ( Transceiver
operation completed with
success? )

10 AVR311
2565D-AVR-08/09
AVR311
Figure 7. TWI interrupt service routine
TWI Interrupt

Own SLA+R has


been received;
ACK has been returned

Reset bufferPointer
Data byte in TWDR has
been transmitted;
ACK has been received
Copy data from current
buffer position to data
register. Post incr pointer.
General call address has
been received;
ACK has been returned
Set General Call bit
in statusReg
Own SLA+W has
been received;
ACK has been returned
Reset bufferPointer
Previously addressed with
own SLA+W;
data has been received;
ACK has been returned Set DataInRxBuf bit
in statusReg
Previously addressed with
general call;
data has been received;
ACK has been returned
Copy data from data
A STOP condition or register to current buffer
repeated START condition position. Post incr pointer.
has been received while
still addressed as Slave
Set Success bit
in statusReg
Data byte in TWDR has
been transmitted;
NACK has been received

Previously addressed with buffer Yes


own SLA+W; pointer = expected
data has been received; msgSize?
NACK has been returned
No Set Success bit
Previously addressed with
in statusReg
general call;
data has been received;
NACK has been returned
Store TWI state infomation
Last data byte in TWDR
has been transmitted
(TWEA = “0”);
ACK has been received

Bus error due to an illegal Disable TWI interrupt Clear TWI interrupt flag
START or STOP condition

Error States

Return

11
2565D-AVR-08/09
Disclaimer
Headquarters International
Atmel Corporation Atmel Asia Atmel Europe Atmel Japan
2325 Orchard Parkway Unit 1-5 & 16, 19/F Le Krebs 9F, Tonetsu Shinkawa Bldg.
San Jose, CA 95131 BEA Tower, Millennium City 5 8, Rue Jean-Pierre Timbaud 1-24-8 Shinkawa
USA 418 Kwun Tong Road BP 309 Chuo-ku, Tokyo 104-0033
Tel: 1(408) 441-0311 Kwun Tong, Kowloon 78054 Saint-Quentin-en- Japan
Fax: 1(408) 487-2600 Hong Kong Yvelines Cedex Tel: (81) 3-3523-3551
France Fax: (81) 3-3523-7581
Tel: (852) 2245-6100
Tel: (33) 1-30-60-70-00
Fax: (852) 2722-1369
Fax: (33) 1-30-60-71-11

Product Contact

Web Site Technical Support Sales Contact


http://www.atmel.com/ avr@atmel.com www.atmel.com/contacts

Literature Request
www.atmel.com/literature

Disclaimer: The information in this document is provided in connection with Atmel products. No license, express or implied, by estoppel or otherwise, to any
intellectual property right is granted by this document or in connection with the sale of Atmel products. EXCEPT AS SET FORTH IN ATMEL’S TERMS AND
CONDITIONS OF SALE LOCATED ON ATMEL’S WEB SITE, ATMEL ASSUMES NO LIABILITY WHATSOEVER AND DISCLAIMS ANY EXPRESS, IMPLIED
OR STATUTORY WARRANTY RELATING TO ITS PRODUCTS INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE, SPECIAL OR INCIDENTAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,
BUSINESS INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OR INABILITY TO USE THIS DOCUMENT, EVEN IF ATMEL HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Atmel makes no representations or warranties with respect to the accuracy or completeness of the
contents of this document and reserves the right to make changes to specifications and product descriptions at any time without notice. Atmel does not make any
commitment to update the information contained herein. Unless specifically provided otherwise, Atmel products are not suitable for, and shall not be used in,
automotive applications. Atmel’s products are not intended, authorized, or warranted for use as components in applications intended to support or sustain life.

© 2009 Atmel Corporation. All rights reserved. Atmel®, Atmel logo and combinations thereof, AVR® and others, are the registered
trademarks or trademarks of Atmel Corporation or its subsidiaries. Other terms and product names may be trademarks of others.

2565D-AVR-08/09

You might also like