Xmega Application Note | |||||
#include "avr_compiler.h"
Go to the source code of this file.
Data Structures | |
struct | TWI_Slave |
TWI slave driver struct. More... | |
Defines | |
#define | TWIS_RECEIVE_BUFFER_SIZE 8 |
#define | TWIS_SEND_BUFFER_SIZE 8 |
#define | TWIS_STATUS_BUSY 1 |
#define | TWIS_STATUS_READY 0 |
Typedefs | |
typedef struct TWI_Slave | TWI_Slave_t |
TWI slave driver struct. | |
typedef enum TWIS_RESULT_enum | TWIS_RESULT_t |
Enumerations | |
enum | TWIS_RESULT_enum { TWIS_RESULT_UNKNOWN = (0x00<<0), TWIS_RESULT_OK = (0x01<<0), TWIS_RESULT_BUFFER_OVERFLOW = (0x02<<0), TWIS_RESULT_TRANSMIT_COLLISION = (0x03<<0), TWIS_RESULT_BUS_ERROR = (0x04<<0), TWIS_RESULT_FAIL = (0x05<<0), TWIS_RESULT_ABORTED = (0x06<<0) } |
Functions | |
void | TWI_SlaveAddressMatchHandler (TWI_Slave_t *twi) |
TWI address match interrupt handler. | |
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. | |
void | TWI_SlaveInterruptHandler (TWI_Slave_t *twi) |
Common TWI slave interrupt service routine. | |
void | TWI_SlaveReadHandler (TWI_Slave_t *twi) |
TWI slave read interrupt handler. | |
void | TWI_SlaveStopHandler (TWI_Slave_t *twi) |
TWI stop condition interrupt handler. | |
void | TWI_SlaveTransactionFinished (TWI_Slave_t *twi, uint8_t result) |
TWI transaction finished function. | |
void | TWI_SlaveWriteHandler (TWI_Slave_t *twi) |
TWI slave write interrupt handler. |
This file contains the function prototypes and enumerator definitions for various configuration parameters for the XMEGA TWI slave driver.
The driver is not intended for size and/or speed critical code, since most functions are just a few lines of code, and the function call overhead would decrease code performance. The driver is intended for rapid prototyping and documentation purposes for getting started with the XMEGA TWI slave module.
For size and/or speed critical code, it is recommended to copy the function contents directly into your application instead of making a function call.
Copyright (c) 2008, 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.
THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 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.h.
#define TWIS_RECEIVE_BUFFER_SIZE 8 |
#define TWIS_SEND_BUFFER_SIZE 8 |
#define TWIS_STATUS_BUSY 1 |
#define TWIS_STATUS_READY 0 |
Definition at line 66 of file twi_slave_driver.h.
Referenced by TWI_SlaveInitializeDriver(), TWI_SlaveInterruptHandler(), and TWI_SlaveTransactionFinished().
typedef struct TWI_Slave TWI_Slave_t |
TWI slave driver struct.
TWI slave struct. Holds pointer to TWI module and data processing routine, buffers and necessary varibles.
typedef enum TWIS_RESULT_enum TWIS_RESULT_t |
enum TWIS_RESULT_enum |
TWIS_RESULT_UNKNOWN | |
TWIS_RESULT_OK | |
TWIS_RESULT_BUFFER_OVERFLOW | |
TWIS_RESULT_TRANSMIT_COLLISION | |
TWIS_RESULT_BUS_ERROR | |
TWIS_RESULT_FAIL | |
TWIS_RESULT_ABORTED |
Definition at line 70 of file twi_slave_driver.h.
00070 { 00071 TWIS_RESULT_UNKNOWN = (0x00<<0), 00072 TWIS_RESULT_OK = (0x01<<0), 00073 TWIS_RESULT_BUFFER_OVERFLOW = (0x02<<0), 00074 TWIS_RESULT_TRANSMIT_COLLISION = (0x03<<0), 00075 TWIS_RESULT_BUS_ERROR = (0x04<<0), 00076 TWIS_RESULT_FAIL = (0x05<<0), 00077 TWIS_RESULT_ABORTED = (0x06<<0), 00078 } TWIS_RESULT_t;
void TWI_SlaveAddressMatchHandler | ( | TWI_Slave_t * | twi | ) |
TWI address match interrupt handler.
Prepares TWI module for transaction when an address match occures.
twi | The TWI_Slave_t struct instance. |
Definition at line 171 of file twi_slave_driver.c.
References TWI_Slave::abort, TWI_Slave::bytesReceived, TWI_Slave::bytesSent, TWI_Slave::interface, TWI_Slave::result, TWI_Slave::status, TWI_SlaveTransactionFinished(), TWIS_RESULT_ABORTED, TWIS_RESULT_UNKNOWN, and TWIS_STATUS_BUSY.
Referenced by TWI_SlaveInterruptHandler().
00172 { 00173 /* If application signalling need to abort (error occured). */ 00174 if (twi->abort) { 00175 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc; 00176 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED); 00177 twi->abort = false; 00178 } else { 00179 twi->status = TWIS_STATUS_BUSY; 00180 twi->result = TWIS_RESULT_UNKNOWN; 00181 00182 /* Disable stop interrupt. */ 00183 uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA; 00184 twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm; 00185 00186 twi->bytesReceived = 0; 00187 twi->bytesSent = 0; 00188 00189 /* Send ACK, wait for data interrupt. */ 00190 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc; 00191 } 00192 }
void TWI_SlaveDataHandler | ( | TWI_Slave_t * | twi | ) |
TWI data interrupt handler.
Calls the appropriate slave read or write handler.
twi | The TWI_Slave_t struct instance. |
Definition at line 220 of file twi_slave_driver.c.
References TWI_Slave::interface, TWI_SlaveReadHandler(), and TWI_SlaveWriteHandler().
Referenced by TWI_SlaveInterruptHandler().
00221 { 00222 if (twi->interface->SLAVE.STATUS & TWI_SLAVE_DIR_bm) { 00223 TWI_SlaveWriteHandler(twi); 00224 } else { 00225 TWI_SlaveReadHandler(twi); 00226 } 00227 }
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.
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 80 of file twi_slave_driver.c.
References TWI_Slave::abort, TWI_Slave::bytesReceived, TWI_Slave::bytesSent, TWI_Slave::interface, TWI_Slave::Process_Data, TWI_Slave::result, TWI_Slave::status, TWIS_RESULT_UNKNOWN, and TWIS_STATUS_READY.
Referenced by main().
00083 { 00084 twi->interface = module; 00085 twi->Process_Data = processDataFunction; 00086 twi->bytesReceived = 0; 00087 twi->bytesSent = 0; 00088 twi->status = TWIS_STATUS_READY; 00089 twi->result = TWIS_RESULT_UNKNOWN; 00090 twi->abort = false; 00091 }
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.
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 103 of file twi_slave_driver.c.
References TWI_Slave::interface.
Referenced by main().
00106 { 00107 twi->interface->SLAVE.CTRLA = intLevel | 00108 TWI_SLAVE_DIEN_bm | 00109 TWI_SLAVE_APIEN_bm | 00110 TWI_SLAVE_ENABLE_bm; 00111 twi->interface->SLAVE.ADDR = (address<<1); 00112 }
void TWI_SlaveInterruptHandler | ( | TWI_Slave_t * | twi | ) |
Common TWI slave interrupt service routine.
Handles all TWI transactions and responses to address match, data reception, data transmission, bus error and data collision.
twi | The TWI_Slave_t struct instance. |
Definition at line 122 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(), TWIS_RESULT_BUS_ERROR, TWIS_RESULT_FAIL, TWIS_RESULT_TRANSMIT_COLLISION, and TWIS_STATUS_READY.
Referenced by ISR().
00123 { 00124 uint8_t currentStatus = twi->interface->SLAVE.STATUS; 00125 00126 /* If bus error. */ 00127 if (currentStatus & TWI_SLAVE_BUSERR_bm) { 00128 twi->bytesReceived = 0; 00129 twi->bytesSent = 0; 00130 twi->result = TWIS_RESULT_BUS_ERROR; 00131 twi->status = TWIS_STATUS_READY; 00132 } 00133 00134 /* If transmit collision. */ 00135 else if (currentStatus & TWI_SLAVE_COLL_bm) { 00136 twi->bytesReceived = 0; 00137 twi->bytesSent = 0; 00138 twi->result = TWIS_RESULT_TRANSMIT_COLLISION; 00139 twi->status = TWIS_STATUS_READY; 00140 } 00141 00142 /* If address match. */ 00143 else if ((currentStatus & TWI_SLAVE_APIF_bm) && 00144 (currentStatus & TWI_SLAVE_AP_bm)) { 00145 00146 TWI_SlaveAddressMatchHandler(twi); 00147 } 00148 00149 /* If stop (only enabled through slave read transaction). */ 00150 else if (currentStatus & TWI_SLAVE_APIF_bm) { 00151 TWI_SlaveStopHandler(twi); 00152 } 00153 00154 /* If data interrupt. */ 00155 else if (currentStatus & TWI_SLAVE_DIF_bm) { 00156 TWI_SlaveDataHandler(twi); 00157 } 00158 00159 /* If unexpected state. */ 00160 else { 00161 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_FAIL); 00162 } 00163 }
void TWI_SlaveReadHandler | ( | TWI_Slave_t * | twi | ) |
TWI slave read interrupt handler.
Handles TWI slave read transactions and responses.
twi | The TWI_Slave_t struct instance. |
Definition at line 236 of file twi_slave_driver.c.
References TWI_Slave::abort, TWI_Slave::bytesReceived, TWI_Slave::interface, TWI_Slave::Process_Data, TWI_Slave::receivedData, TWI_SlaveTransactionFinished(), TWIS_RECEIVE_BUFFER_SIZE, TWIS_RESULT_ABORTED, and TWIS_RESULT_BUFFER_OVERFLOW.
Referenced by TWI_SlaveDataHandler().
00237 { 00238 /* Enable stop interrupt. */ 00239 uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA; 00240 twi->interface->SLAVE.CTRLA = currentCtrlA | TWI_SLAVE_PIEN_bm; 00241 00242 /* If free space in buffer. */ 00243 if (twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE) { 00244 /* Fetch data */ 00245 uint8_t data = twi->interface->SLAVE.DATA; 00246 twi->receivedData[twi->bytesReceived] = data; 00247 00248 /* Process data. */ 00249 twi->Process_Data(); 00250 00251 twi->bytesReceived++; 00252 00253 /* If application signalling need to abort (error occured), 00254 * complete transaction and wait for next START. Otherwise 00255 * send ACK and wait for data interrupt. 00256 */ 00257 if (twi->abort) { 00258 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc; 00259 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED); 00260 twi->abort = false; 00261 } else { 00262 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc; 00263 } 00264 } 00265 /* If buffer overflow, send NACK and wait for next START. Set 00266 * result buffer overflow. 00267 */ 00268 else { 00269 twi->interface->SLAVE.CTRLB = TWI_SLAVE_ACKACT_bm | 00270 TWI_SLAVE_CMD_COMPTRANS_gc; 00271 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW); 00272 } 00273 }
void TWI_SlaveStopHandler | ( | TWI_Slave_t * | twi | ) |
TWI stop condition interrupt handler.
twi | The TWI_Slave_t struct instance. |
Definition at line 199 of file twi_slave_driver.c.
References TWI_Slave::interface, TWI_SlaveTransactionFinished(), and TWIS_RESULT_OK.
Referenced by TWI_SlaveInterruptHandler().
00200 { 00201 /* Disable stop interrupt. */ 00202 uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA; 00203 twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm; 00204 00205 /* Clear APIF, according to flowchart don't ACK or NACK */ 00206 uint8_t currentStatus = twi->interface->SLAVE.STATUS; 00207 twi->interface->SLAVE.STATUS = currentStatus | TWI_SLAVE_APIF_bm; 00208 00209 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK); 00210 00211 }
void TWI_SlaveTransactionFinished | ( | TWI_Slave_t * | twi, | |
uint8_t | result | |||
) |
TWI transaction finished function.
Prepares module for new transaction.
twi | The TWI_Slave_t struct instance. | |
result | The result of the transaction. |
Definition at line 317 of file twi_slave_driver.c.
References TWI_Slave::result, TWI_Slave::status, and TWIS_STATUS_READY.
Referenced by TWI_SlaveAddressMatchHandler(), TWI_SlaveInterruptHandler(), TWI_SlaveReadHandler(), TWI_SlaveStopHandler(), and TWI_SlaveWriteHandler().
00318 { 00319 twi->result = result; 00320 twi->status = TWIS_STATUS_READY; 00321 }
void TWI_SlaveWriteHandler | ( | TWI_Slave_t * | twi | ) |
TWI slave write interrupt handler.
Handles TWI slave write transactions and responses.
twi | The TWI_Slave_t struct instance. |
Definition at line 282 of file twi_slave_driver.c.
References TWI_Slave::bytesSent, TWI_Slave::interface, TWI_Slave::sendData, TWI_SlaveTransactionFinished(), TWIS_RESULT_BUFFER_OVERFLOW, TWIS_RESULT_OK, and TWIS_SEND_BUFFER_SIZE.
Referenced by TWI_SlaveDataHandler().
00283 { 00284 /* If NACK, slave write transaction finished. */ 00285 if ((twi->bytesSent > 0) && (twi->interface->SLAVE.STATUS & 00286 TWI_SLAVE_RXACK_bm)) { 00287 00288 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc; 00289 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK); 00290 } 00291 /* If ACK, master expects more data. */ 00292 else { 00293 if (twi->bytesSent < TWIS_SEND_BUFFER_SIZE) { 00294 uint8_t data = twi->sendData[twi->bytesSent]; 00295 twi->interface->SLAVE.DATA = data; 00296 twi->bytesSent++; 00297 00298 /* Send data, wait for data interrupt. */ 00299 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc; 00300 } 00301 /* If buffer overflow. */ 00302 else { 00303 twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc; 00304 TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW); 00305 } 00306 } 00307 }
Generated on Tue Aug 11 12:42:13 2009 for AVR1308 Using the XMEGA TWI by ![]() |