2 Implementation

The application note describes the implementation of a TWI master. The driver is written as a standalone driver that easily can be included into the main application. Use the code as an example, or customize it for own use. Defines and status registers are all set in the application note header file.

The driver uses the USI module and standard I/O pin control. No additional resources as timers or any other interrupt sources are needed. The driver ensures correct timing even if it gets any interrupt signals during execution. The execution is however sequential, i.e. all CPU resources are therefore used during transmission.

Figure 2-1. Flowchart of the Transceiver Function. A Flowchart of the Sub Function USI_TWI_Master_Transfer is Found in the Next Figure

The driver consists of these functions:

  • USI_TWI_Master_Initialize
  • USI_TWI_Start_Transceiver_With_Data
  • USI_TWI_Master_Transfer
  • USI_TWI_Master_Stop
  • USI_TWI_Get_State_Info

The USI_TWI_Master_Initialize function is used to set the USI module in TWI mode, and setting the TWI bus in idle/released mode.

The START and RESTART conditions are included into the transceiver function; USI_TWI_Start_Transceiver_With_Data. A flowchart of the function can be found in the figure above. The same function is used for both transmit and receive operations. The transceiver takes a pointer to a transmission buffer as parameter, together with the number of bytes in the buffer. The first location in the buffer must always contain both the address of the slave and the read/write bit determining the transmission type. If the master is requesting data from the slave, the transmit buffer only contains the slave address (with the read bit set), and a data size parameter indicating the number of bytes requested. The transceiver function will put the received data into the transmission buffer.

USI_TWI_Master_Transfer (see the figure below) is called from within USI_TWI_Start_Transceiver_With_Data.

USI_TWI_Master_Stop is called from within USI_TWI_Start_Transceiver_With_Data.

Figure 2-2. Flowchart of the General Transfer Function. The Function is Used by the USI_TWI_Start_Transceiver_With_Data Function in the Figure Above

On completion the transceiver function holds the TWI bus by pulling the SCL line low. A new transmission can be initiated immediately by rerunning the transceiver function. The transceiver function generates error codes if the transmission fails. The codes are listed in the header file and in the table below. Use the function USI_TWI_Get_State_Info to get hold of the error state if the transceiver returns a fail.

Table 2-1. Error Codes Returned from the Transceiver Function
Define name of error code#Description
USI_TWI_NO_DATA0x00Transmission buffer is empty
USI_TWI_DATA_OUT_OF_BOUND0x01Transmission buffer is outside SRAM space
USI_TWI_UE_START_CON0x02Unexpected Start Condition
USI_TWI_UE_STOP_CON0x03Unexpected Stop Condition
USI_TWI_UE_DATA_COL0x04Unexpected Data Collision (arbitration)
USI_TWI_NO_ACK_ON_DATA0x05The slave did not acknowledge all data
USI_TWI_NO_ACK_ON_ADDRESS0x06The slave did not acknowledge the address
USI_TWI_MISSING_START_CON0x07Generated Start Condition not detected on bus
USI_TWI_MISSING_STOP_CON0x08Generated Stop Condition not detected on bus

The driver takes care of the low level communication as transmission/reception of address, data, and ACK/NACK. High level operations like address setting, message interpreting, and data preparation, must be taken care of by the main application. A small sample code of how to use the driver is included.

This implementation does not support TWI bus arbitration. The device using this driver must therefore be the only master on the bus. As according to the TWI standard, all 127 slaves can be addressed individually on the bus. The lack of bus arbitration is not a limit of the USI module, and can be implemented into the driver, but is not in the scope for this application note.

The driver does not use interrupts and uses loops to control the TWI bus activity. To add additional execution control and security one can use a Watchdog Timer. This can prevent unintentional behavior on the TWI bus from blocking the application. All AVR®s have an on-chip Watchdog Timer. For more information on the watchdog timer, check out the application note “AVR132: Using the Enhanced Watchdog Timer” and the datasheets.

The driver has code for both standard and fast mode TWI timing. Set selected mode in the header file of the driver. The default setting is fast mode.