Xmega Application Note


twi_slave_driver.c File Reference

XMEGA TWI slave driver source file. More...

#include "twi_slave_driver.h"
#include "clksys_driver.h"

Include dependency graph for twi_slave_driver.c:

Go to the source code of this file.

Functions

void TWI_process (TWI_Slave_t *twi)
 Process TWI command.
static void TWI_SlaveAddressMatchHandler (TWI_Slave_t *twi)
 TWI address match interrupt handler.
static void TWI_SlaveDataHandler (TWI_Slave_t *twi)
 TWI data interrupt handler.
void TWI_SlaveInitializeDriver (TWI_Slave_t *twi, TWI_t *module, void(*processDataFunction)(void))
 Initalizes TWI slave driver structure.
void TWI_SlaveInitializeModule (TWI_Slave_t *twi, uint8_t address, TWI_SLAVE_INTLVL_t intLevel)
 Initialize the TWI module.
static void TWI_SlaveReadHandler (TWI_Slave_t *twi)
 TWI slave read interrupt handler.
static void TWI_SlaveStopHandler (TWI_Slave_t *twi)
 TWI stop condition interrupt handler.
static void TWI_SlaveTransactionFinished (TWI_Slave_t *twi, uint8_t result)
 TWI transaction finished function.
static void TWI_SlaveWriteHandler (TWI_Slave_t *twi)
 TWI slave write interrupt handler.

Variables

uint8_t twi_data
uint8_t twic_data_reg
uint8_t twic_status_reg


Detailed Description

XMEGA TWI slave driver source file.

Application note:
AVR1320: True 400kHz operation for TWI slave
Documentation
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Copyright (c) 2009 Atmel Corporation. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. The name of Atmel may not be used to endorse or promote products derived from this software without specific prior written permission.

4. This software may only be redistributed and used in connection with an Atmel AVR product.

THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file twi_slave_driver.c.


Function Documentation

void TWI_process ( TWI_Slave_t twi  ) 

Process TWI command.

This function is called out of ISR to process TWI command.

Parameters:
twi The TWI_Slave_t struct instance.

< Clear ACKACT

Definition at line 116 of file twi_slave_driver.c.

References TWI_Slave::bytesReceived, TWI_Slave::bytesSent, TWI_Slave::interface, TWI_Slave::result, TWI_Slave::status, TWI_SlaveAddressMatchHandler(), TWI_SlaveDataHandler(), TWI_SlaveStopHandler(), TWI_SlaveTransactionFinished(), twic_status_reg, TWIS_RESULT_BUS_ERROR, TWIS_RESULT_FAIL, TWIS_RESULT_TRANSMIT_COLLISION, and TWIS_STATUS_READY.

Referenced by ISR().

00117 {
00118    //static uint8_t sent_NACK = 0;      //!< Holds whether NACK has been transmitted
00119    uint8_t currentStatus;
00120    currentStatus = twic_status_reg;
00121 
00122    twi->interface->SLAVE.CTRLB &= ~TWI_SLAVE_ACKACT_bm; 
00123 
00124    /* If bus error. */
00125    if (currentStatus & TWI_SLAVE_BUSERR_bm) {
00126       twi->bytesReceived = 0;
00127       twi->bytesSent = 0;
00128       twi->result = TWIS_RESULT_BUS_ERROR;
00129       twi->status = TWIS_STATUS_READY;
00130    }
00131    else if (currentStatus & TWI_SLAVE_COLL_bm) {
00132       /* If transmit collision. */
00133       twi->bytesReceived = 0;
00134       twi->bytesSent = 0;
00135       twi->result = TWIS_RESULT_TRANSMIT_COLLISION;
00136       twi->status = TWIS_STATUS_READY;
00137    }
00138    else if ((currentStatus & TWI_SLAVE_APIF_bm) && (currentStatus & TWI_SLAVE_AP_bm)) {
00139       /* If address match. */
00140       TWI_SlaveAddressMatchHandler(twi);        
00141    }
00142    else if (currentStatus & TWI_SLAVE_APIF_bm) {
00143       /* If stop (only enabled through slave read transaction). */        
00144       TWI_SlaveStopHandler(twi);
00145    }
00146    else if (currentStatus & TWI_SLAVE_DIF_bm) {
00147       /* If data interrupt. */     
00148       TWI_SlaveDataHandler(twi);
00149    }
00150    else {
00151       /* If unexpected state. */
00152       TWI_SlaveTransactionFinished(twi, TWIS_RESULT_FAIL);
00153    }
00154 }

Here is the call graph for this function:

static void TWI_SlaveAddressMatchHandler ( TWI_Slave_t twi  )  [static]

TWI address match interrupt handler.

Prepares TWI module for transaction when an address match occures.

Parameters:
twi The TWI_Slave_t struct instance.

Definition at line 162 of file twi_slave_driver.c.

References TWI_Slave::bytesReceived, TWI_Slave::bytesSent, TWI_Slave::interface, TWI_Slave::result, TWI_Slave::sendData, TWI_Slave::status, twic_data_reg, TWIS_RESULT_UNKNOWN, and TWIS_STATUS_BUSY.

Referenced by TWI_process().

00163 {
00164    twi->status = TWIS_STATUS_BUSY;
00165    twi->result = TWIS_RESULT_UNKNOWN;
00166 
00167    /* Disable stop interrupt. */
00168    uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00169    twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
00170 
00171    twi->bytesReceived = 0;
00172    twi->bytesSent = 0;
00173 
00174    //init second byte to write
00175    twic_data_reg = twi->sendData[0];    
00176 }

static void TWI_SlaveDataHandler ( TWI_Slave_t twi  )  [static]

TWI data interrupt handler.

Calls the appropriate slave read or write handler.

Parameters:
twi The TWI_Slave_t struct instance.

Definition at line 199 of file twi_slave_driver.c.

References TWI_SlaveReadHandler(), TWI_SlaveWriteHandler(), and twic_status_reg.

Referenced by TWI_process().

00200 {       
00201    if (twic_status_reg & TWI_SLAVE_DIR_bm) {
00202       TWI_SlaveWriteHandler(twi);               
00203    } else {
00204       TWI_SlaveReadHandler(twi);          
00205    }
00206 }

Here is the call graph for this function:

void TWI_SlaveInitializeDriver ( TWI_Slave_t twi,
TWI_t *  module,
void(*)(void)  processDataFunction 
)

Initalizes TWI slave driver structure.

Initialize the instance of the TWI Slave and set the appropriate values.

Parameters:
twi The TWI_Slave_t struct instance.
module Pointer to the TWI module.
processDataFunction Pointer to the function that handles incoming data.

Definition at line 68 of file twi_slave_driver.c.

References TWI_Slave::abort, TWI_Slave::bytesReceived, TWI_Slave::bytesSent, CLKSYS_Disable(), CLKSYS_Enable, CLKSYS_IsReady, CLKSYS_Main_ClockSource_Select(), TWI_Slave::interface, TWI_Slave::Process_Data, TWI_Slave::result, TWI_Slave::status, TWIS_RESULT_UNKNOWN, and TWIS_STATUS_READY.

Referenced by main().

00071 {
00072    twi->interface = module;
00073    twi->Process_Data = processDataFunction;
00074    twi->bytesReceived = 0;
00075    twi->bytesSent = 0;
00076    twi->status = TWIS_STATUS_READY;
00077    twi->result = TWIS_RESULT_UNKNOWN;
00078    twi->abort = false;
00079           
00080    CLKSYS_Enable( OSC_RC32MEN_bm );
00081    do {} while ( CLKSYS_IsReady( OSC_RC32MRDY_bm ) == 0 );
00082         
00083    /* 32MHz Internal RC*/
00084    CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc );
00085         
00086    CLKSYS_Disable( OSC_RC2MEN_bm | OSC_RC32KEN_bm );    
00087 }

Here is the call graph for this function:

void TWI_SlaveInitializeModule ( TWI_Slave_t twi,
uint8_t  address,
TWI_SLAVE_INTLVL_t  intLevel 
)

Initialize the TWI module.

Enables interrupts on address recognition and data available. Remember to enable interrupts globally from the main application.

Parameters:
twi The TWI_Slave_t struct instance.
address Slave address for this module.
intLevel Interrupt level for the TWI slave interrupt handler.

Definition at line 99 of file twi_slave_driver.c.

References TWI_Slave::interface.

Referenced by main().

00102 {
00103    twi->interface->SLAVE.CTRLA = intLevel |
00104                                  TWI_SLAVE_DIEN_bm |
00105                                  TWI_SLAVE_APIEN_bm |
00106                                  TWI_SLAVE_ENABLE_bm;
00107    twi->interface->SLAVE.ADDR = (address<<1);
00108 }

static void TWI_SlaveReadHandler ( TWI_Slave_t twi  )  [static]

TWI slave read interrupt handler.

Handles TWI slave read transactions and responses.

Parameters:
twi The TWI_Slave_t struct instance.

Definition at line 214 of file twi_slave_driver.c.

References TWI_Slave::bytesReceived, TWI_Slave::interface, TWI_Slave::Process_Data, TWI_Slave::receivedData, twic_data_reg, and TWIS_RECEIVE_BUFFER_SIZE.

Referenced by TWI_SlaveDataHandler().

00215 {
00216    /* Enable stop interrupt. */
00217    uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00218    twi->interface->SLAVE.CTRLA = currentCtrlA | TWI_SLAVE_PIEN_bm;
00219 
00220    /* If free space in buffer.*/
00221    if (twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE) {
00222       /* Fetch data */
00223       uint8_t data = twic_data_reg;
00224       twi->receivedData[twi->bytesReceived] = data;
00225       /* Process data. */
00226       twi->Process_Data();
00227       twi->bytesReceived++;
00228    } else {
00229       // We will ignore the overshooting packets.
00230    }
00231         
00232    /* buffer overflow next time*/
00233    if  (!(twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE)){
00234       twi->interface->SLAVE.CTRLB |= TWI_SLAVE_ACKACT_bm;
00235   }
00236 }

static void TWI_SlaveStopHandler ( TWI_Slave_t twi  )  [static]

TWI stop condition interrupt handler.

Parameters:
twi The TWI_Slave_t struct instance.

Definition at line 182 of file twi_slave_driver.c.

References TWI_Slave::interface, TWI_SlaveTransactionFinished(), and TWIS_RESULT_OK.

Referenced by TWI_process().

00183 {
00184    /* Disable stop interrupt. */
00185    uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
00186    twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
00187    uint8_t currentStatus = twi->interface->SLAVE.STATUS;
00188    twi->interface->SLAVE.STATUS = currentStatus | TWI_SLAVE_APIF_bm;
00189 
00190    TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
00191 }

Here is the call graph for this function:

static void TWI_SlaveTransactionFinished ( TWI_Slave_t twi,
uint8_t  result 
) [static]

TWI transaction finished function.

Prepares module for new transaction.

Parameters:
twi The TWI_Slave_t struct instance.
result The result of the transaction.

Definition at line 274 of file twi_slave_driver.c.

References TWI_Slave::result, TWI_Slave::status, and TWIS_STATUS_READY.

Referenced by TWI_process(), TWI_SlaveStopHandler(), and TWI_SlaveWriteHandler().

00275 {
00276    twi->result = result;
00277    twi->status = TWIS_STATUS_READY;
00278 }

static void TWI_SlaveWriteHandler ( TWI_Slave_t twi  )  [static]

TWI slave write interrupt handler.

Handles TWI slave write transactions and responses.

Parameters:
twi The TWI_Slave_t struct instance.

Definition at line 245 of file twi_slave_driver.c.

References TWI_Slave::bytesSent, TWI_Slave::sendData, TWI_SlaveTransactionFinished(), twic_data_reg, twic_status_reg, TWIS_RESULT_BUFFER_OVERFLOW, TWIS_RESULT_OK, and TWIS_SEND_BUFFER_SIZE.

Referenced by TWI_SlaveDataHandler().

00246 {
00247    /* If NACK, slave write transaction finished. */
00248    if ((twi->bytesSent > 0) && (twic_status_reg & TWI_SLAVE_RXACK_bm)) {
00249       //init first byte to write
00250       twic_data_reg = twi->sendData[0];
00251       TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
00252    }
00253    /* If ACK, master expects more data. */
00254    else {
00255       if (twi->bytesSent < TWIS_SEND_BUFFER_SIZE) {
00256          twi->bytesSent++;
00257          uint8_t data = twi->sendData[twi->bytesSent];
00258          twic_data_reg = data;                  
00259       }
00260       else {
00261          /* If buffer overflow. */
00262          TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
00263       }
00264    }
00265 } 

Here is the call graph for this function:


Variable Documentation

uint8_t twi_data

uint8_t twic_data_reg

uint8_t twic_status_reg

Definition at line 57 of file twi_example.c.

Referenced by TWI_process(), TWI_SlaveDataHandler(), and TWI_SlaveWriteHandler().

@DOC_TITLE@
Generated on Tue Jan 19 18:42:00 2010 for AVR1320: True 400kHz operation for TWI slave by doxygen 1.5.8