2.1 Functions

The driver consists of the TWI Interrupt Service Routine and several functions. All functions are available for use outside the driver file scope. However, some of them are also used internally by the driver it self. All functions in the driver are listed in the following table.

Table 2-1.  Description of Functions in the TWI Slave Driver
Function name Description

void TWI_Slave_Initialise

(unsigned char ownSlaveAddress )

Call this function to set up the TWI slave to its initial standby state. Remember to enable interrupts from the main application after initializing the TWI. Pass both the slave address and the requirements 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

(unsigned char *message, unsignedchar messageSize)

Call this function to send a prepared message, or start the Transceiver 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 specifying new transmission data. Useful 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.
unsigned char TWI_Transceiver_Busy( )Call this function to test if the TWI_ISR is busy transmitting.
unsigned char 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 TWIState code.

unsigned char TWI_Get_Data_From_Transceiver

(unsigned char *message, unsignedchar messageSize)

Call this function to read out the received data from the TWI transceiver 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 TWIState code.
ISR(TWI_vect)(For GCC)/

__interrupt void TWI_ISR(void)(For IAR)

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.

The following table consists the description of the driver register byte containing status information from the last transceiver operation. Available as bit fields within a byte.

Table 2-2. Description of the Driver Status Register Byte
TWI_statusReg Description
TWI_statusReg.lastTransOKSet to 1 when an operation has completed successfully.
TWI_statusReg.RxDataInBufThis 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.genAddressCallThis 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.

The following Flowchart shows 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. In the flowchart 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.

Figure 2-1. Calling the TWI Driver from the Application

The following flowchart contains the TWI Driver itself. 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.

Figure 2-2. TWI Driver Functions

In the following Flowchart there is a more detailed description of the actions for each event/state in the TWI Interrupt Service Routine. The left column contains the different states/events the TWI state machine can be in when entering the Interrupt. A case switch executes the different actions dependent on the cause of the interrupt call.

Figure 2-3. TWI Interrupt Service Routine