/Transportables_Koptertool/PKT/trunk/utils/i2cmaster.h |
---|
0,0 → 1,178 |
#ifndef _I2CMASTER_H |
#define _I2CMASTER_H 1 |
/************************************************************************* |
* Title: C include file for the I2C master interface |
* (i2cmaster.S or twimaster.c) |
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury |
* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $ |
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 |
* Target: any AVR device |
* Usage: see Doxygen manual |
**************************************************************************/ |
#ifdef DOXYGEN |
/** |
@defgroup pfleury_ic2master I2C Master library |
@code #include <i2cmaster.h> @endcode |
@brief I2C (TWI) Master Software Library |
Basic routines for communicating with I2C slave devices. This single master |
implementation is limited to one bus master on the I2C bus. |
This I2c library is implemented as a compact assembler software implementation of the I2C protocol |
which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). |
Since the API for these two implementations is exactly the same, an application can be linked either against the |
software I2C implementation or the hardware I2C implementation. |
Use 4.7k pull-up resistor on the SDA and SCL pin. |
Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module |
i2cmaster.S to your target when using the software I2C implementation ! |
Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion. |
@note |
The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted |
to GNU assembler and AVR-GCC C call interface. |
Replaced the incorrect quarter period delays found in AVR300 with |
half period delays. |
@author Peter Fleury pfleury@gmx.ch http://jump.to/fleury |
@par API Usage Example |
The following code shows typical usage of this library, see example test_i2cmaster.c |
@code |
#include <i2cmaster.h> |
#define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet |
int main(void) |
{ |
unsigned char ret; |
i2c_init(); // initialize I2C library |
// write 0x75 to EEPROM address 5 (Byte Write) |
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode |
i2c_write(0x05); // write address = 5 |
i2c_write(0x75); // write value 0x75 to EEPROM |
i2c_stop(); // set stop conditon = release bus |
// read previously written value back from EEPROM address 5 |
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode |
i2c_write(0x05); // write address = 5 |
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode |
ret = i2c_readNak(); // read one byte from EEPROM |
i2c_stop(); |
for(;;); |
} |
@endcode |
*/ |
#endif /* DOXYGEN */ |
/**@{*/ |
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304 |
#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !" |
#endif |
#include <avr/io.h> |
/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */ |
#define I2C_READ 1 |
/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */ |
#define I2C_WRITE 0 |
/** |
@brief initialize the I2C master interace. Need to be called only once |
@param void |
@return none |
*/ |
extern void i2c_init(void); |
/** |
@brief Terminates the data transfer and releases the I2C bus |
@param void |
@return none |
*/ |
extern void i2c_stop(void); |
/** |
@brief Issues a start condition and sends address and transfer direction |
@param addr address and transfer direction of I2C device |
@retval 0 device accessible |
@retval 1 failed to access device |
*/ |
extern unsigned char i2c_start(unsigned char addr); |
/** |
@brief Issues a repeated start condition and sends address and transfer direction |
@param addr address and transfer direction of I2C device |
@retval 0 device accessible |
@retval 1 failed to access device |
*/ |
extern unsigned char i2c_rep_start(unsigned char addr); |
/** |
@brief Issues a start condition and sends address and transfer direction |
If device is busy, use ack polling to wait until device ready |
@param addr address and transfer direction of I2C device |
@return none |
*/ |
extern void i2c_start_wait(unsigned char addr); |
/** |
@brief Send one byte to I2C device |
@param data byte to be transfered |
@retval 0 write successful |
@retval 1 write failed |
*/ |
extern unsigned char i2c_write(unsigned char data); |
/** |
@brief read one byte from the I2C device, request more data from device |
@return byte read from I2C device |
*/ |
extern unsigned char i2c_readAck(void); |
/** |
@brief read one byte from the I2C device, read is followed by a stop condition |
@return byte read from I2C device |
*/ |
extern unsigned char i2c_readNak(void); |
/** |
@brief read one byte from the I2C device |
Implemented as a macro, which calls either i2c_readAck or i2c_readNak |
@param ack 1 send ack, request more data from device<br> |
0 send nak, read is followed by a stop condition |
@return byte read from I2C device |
*/ |
extern unsigned char i2c_read(unsigned char ack); |
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); |
/**@}*/ |
#endif |
Property changes: |
Added: svn:mime-type |
+text/plain |
\ No newline at end of property |
/Transportables_Koptertool/PKT/trunk/utils/twi_slave.c |
---|
0,0 → 1,373 |
/***************************************************************************** |
* |
* Atmel Corporation |
* |
* File : TWI_Slave.c |
* Compiler : IAR EWAAVR 2.28a/3.10c |
* Revision : $Revision: 2475 $ |
* Date : $Date: 2007-09-20 12:00:43 +0200 (to, 20 sep 2007) $ |
* Updated by : $Author: mlarsson $ |
* |
* Support mail : avr@atmel.com |
* |
* Supported devices : All devices with a TWI module can be used. |
* The example is written for the ATmega16 |
* |
* AppNote : AVR311 - TWI Slave Implementation |
* |
* Description : This is sample driver to AVRs TWI module. |
* It is interupt driveren. All functionality is controlled through |
* passing information to and from functions. Se main.c for samples |
* of how to use the driver. |
* |
****************************************************************************/ |
/*! \page MISRA |
* |
* General disabling of MISRA rules: |
* * (MISRA C rule 1) compiler is configured to allow extensions |
* * (MISRA C rule 111) bit fields shall only be defined to be of type unsigned int or signed int |
* * (MISRA C rule 37) bitwise operations shall not be performed on signed integer types |
* As it does not work well with 8bit architecture and/or IAR |
* Other disabled MISRA rules |
* * (MISRA C rule 109) use of union - overlapping storage shall not be used |
* * (MISRA C rule 61) every non-empty case clause in a switch statement shall be terminated with a break statement |
*/ |
#if defined(__ICCAVR__) |
#include "ioavr.h" |
#include "inavr.h" |
#else |
#include <avr/io.h> |
#include <avr/interrupt.h> |
#endif |
#include "twi_slave.h" |
// Emulate GCC ISR() statement in IAR |
#if defined(__ICCAVR__) |
#define PRAGMA(x) _Pragma( #x ) |
#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void) |
#endif |
static unsigned char TWI_buf[TWI_BUFFER_SIZE]; // Transceiver buffer. Set the size in the header file |
static unsigned char TWI_msgSize = 0; // Number of bytes to be transmitted. |
static unsigned char TWI_state = TWI_NO_STATE; // State byte. Default set to TWI_NO_STATE. |
// This is true when the TWI is in the middle of a transfer |
// and set to false when all bytes have been transmitted/received |
// Also used to determine how deep we can sleep. |
static volatile unsigned char TWI_busy = 0; |
union TWI_statusReg_t TWI_statusReg = {0}; // TWI_statusReg is defined in TWI_Slave.h |
/**************************************************************************** |
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 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_slave_init( unsigned char TWI_ownAddress ) |
{ |
TWAR = TWI_ownAddress; // Set own TWI slave address. Accept TWI General Calls. |
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins. |
(0<<TWIE)|(0<<TWINT)| // Disable TWI Interupt. |
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not ACK on any requests, yet. |
(0<<TWWC); // |
TWI_busy = 0; |
} |
/**************************************************************************** |
Call this function to test if the TWI_ISR is busy transmitting. |
****************************************************************************/ |
unsigned char twi_slave_busy( void ) |
{ |
return TWI_busy; |
} |
/**************************************************************************** |
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. |
****************************************************************************/ |
unsigned char twi_slave_get_status( void ) |
{ |
while ( twi_slave_busy() ) {} // Wait until TWI has completed the transmission. |
return ( TWI_state ); // Return error state. |
} |
/**************************************************************************** |
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_slave_start_with_data( unsigned char *msg, unsigned char msgSize ) |
{ |
unsigned char temp; |
while ( twi_slave_busy() ) {} // Wait until TWI is ready for next transmission. |
TWI_msgSize = msgSize; // Number of data to transmit. |
for ( temp = 0; temp < msgSize; temp++ ) // Copy data that may be transmitted if the TWI Master requests data. |
{ |
TWI_buf[ temp ] = msg[ temp ]; |
} |
TWI_statusReg.all = 0; |
TWI_state = TWI_NO_STATE ; |
TWCR = (1<<TWEN)| // TWI Interface enabled. |
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag. |
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Prepare to ACK next time the Slave is addressed. |
(0<<TWWC); // |
TWI_busy = 1; |
} |
/**************************************************************************** |
Call this function to start the Transceiver without specifing 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. |
****************************************************************************/ |
void twi_slave_start( void ) |
{ |
while ( twi_slave_busy() ) {} // Wait until TWI is ready for next transmission. |
TWI_statusReg.all = 0; |
TWI_state = TWI_NO_STATE ; |
TWCR = (1<<TWEN)| // TWI Interface enabled. |
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag. |
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Prepare to ACK next time the Slave is addressed. |
(0<<TWWC); // |
TWI_busy = 0; |
} |
/**************************************************************************** |
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 TWI State code. |
****************************************************************************/ |
unsigned char twi_slave_get_data( unsigned char *msg, unsigned char msgSize ) |
{ |
unsigned char i; |
while ( twi_slave_busy() ) {} // Wait until TWI is ready for next transmission. |
if( TWI_statusReg.lastTransOK ) // Last transmission completed successfully. |
{ |
for ( i=0; i<msgSize; i++ ) // Copy data from Transceiver buffer. |
{ |
msg[ i ] = TWI_buf[ i ]; |
} |
TWI_statusReg.RxDataInBuf = FALSE; // Slave Receive data has been read from buffer. |
} |
return( TWI_statusReg.lastTransOK ); |
} |
// ********** Interrupt Handlers ********** // |
/**************************************************************************** |
This function is the Interrupt Service Routine (ISR), and 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. |
****************************************************************************/ |
ISR(TWI_vect) |
{ |
static unsigned char TWI_bufPtr; |
switch (TWSR) |
{ |
case TWI_STX_ADR_ACK: // Own SLA+R has been received; ACK has been returned |
// case TWI_STX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned |
TWI_bufPtr = 0; // Set buffer pointer to first data location |
case TWI_STX_DATA_ACK: // Data byte in TWDR has been transmitted; ACK has been received |
TWDR = TWI_buf[TWI_bufPtr++]; |
TWCR = (1<<TWEN)| // TWI Interface enabled |
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte |
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // |
(0<<TWWC); // |
TWI_busy = 1; |
break; |
case TWI_STX_DATA_NACK: // Data byte in TWDR has been transmitted; NACK has been received. |
// I.e. this could be the end of the transmission. |
if (TWI_bufPtr == TWI_msgSize) // Have we transceived all expected data? |
{ |
TWI_statusReg.lastTransOK = TRUE; // Set status bits to completed successfully. |
} |
else // Master has sent a NACK before all data where sent. |
{ |
TWI_state = TWSR; // Store TWI State as errormessage. |
} |
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins |
(1<<TWIE)|(1<<TWINT)| // Keep interrupt enabled and clear the flag |
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Answer on next address match |
(0<<TWWC); // |
TWI_busy = 0; // Transmit is finished, we are not busy anymore |
break; |
case TWI_SRX_GEN_ACK: // General call address has been received; ACK has been returned |
// case TWI_SRX_GEN_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned |
TWI_statusReg.genAddressCall = TRUE; |
case TWI_SRX_ADR_ACK: // Own SLA+W has been received ACK has been returned |
// case TWI_SRX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned |
// Dont need to clear TWI_S_statusRegister.generalAddressCall due to that it is the default state. |
TWI_statusReg.RxDataInBuf = TRUE; |
TWI_bufPtr = 0; // Set buffer pointer to first data location |
// Reset the TWI Interupt to wait for a new event. |
TWCR = (1<<TWEN)| // TWI Interface enabled |
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte |
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Expect ACK on this transmission |
(0<<TWWC); |
TWI_busy = 1; |
break; |
case TWI_SRX_ADR_DATA_ACK: // Previously addressed with own SLA+W; data has been received; ACK has been returned |
case TWI_SRX_GEN_DATA_ACK: // Previously addressed with general call; data has been received; ACK has been returned |
// TODO: What is this? Seems to be no bounds checking! |
TWI_buf[TWI_bufPtr++] = TWDR; |
TWI_statusReg.lastTransOK = TRUE; // Set flag transmission successfull. |
// Reset the TWI Interupt to wait for a new event. |
TWCR = (1<<TWEN)| // TWI Interface enabled |
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte |
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after next reception |
(0<<TWWC); // |
TWI_busy = 1; |
break; |
case TWI_SRX_STOP_RESTART: // A STOP condition or repeated START condition has been received while still addressed as Slave |
// Enter not addressed mode and listen to address match |
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins |
(1<<TWIE)|(1<<TWINT)| // Enable interrupt and clear the flag |
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Wait for new address match |
(0<<TWWC); // |
TWI_busy = 0; // We are waiting for a new address match, so we are not busy |
break; |
case TWI_SRX_ADR_DATA_NACK: // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned |
case TWI_SRX_GEN_DATA_NACK: // Previously addressed with general call; data has been received; NOT ACK has been returned |
case TWI_STX_DATA_ACK_LAST_BYTE: // Last data byte in TWDR has been transmitted (TWEA = �0�); ACK has been received |
// case TWI_NO_STATE // No relevant state information available; TWINT = �0� |
case TWI_BUS_ERROR: // Bus error due to an illegal START or STOP condition |
TWI_state = TWSR; //Store TWI State as errormessage, operation also clears noErrors bit |
TWCR = (1<<TWSTO)|(1<<TWINT); //Recover from TWI_BUS_ERROR, this will release the SDA and SCL pins thus enabling other devices to use the bus |
break; |
default: |
TWI_state = TWSR; // Store TWI State as errormessage, operation also clears the Success bit. |
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins |
(1<<TWIE)|(1<<TWINT)| // Keep interrupt enabled and clear the flag |
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Acknowledge on any new requests. |
(0<<TWWC); // |
TWI_busy = 0; // Unknown status, so we wait for a new address match that might be something we can handle |
} |
} |
/* |
void example(){ |
unsigned char messageBuf[TWI_BUFFER_SIZE]; |
unsigned char TWI_slaveAddress; |
// LED feedback port - connect port B to the STK500 LEDS |
DDRB = 0xFF; // Set to ouput |
PORTB = 0x55; // Startup pattern |
// Own TWI slave address |
TWI_slaveAddress = 0x10; |
// Initialise TWI module for slave operation. Include address and/or enable General Call. |
TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_GEN_BIT) )); |
SEI(); |
// Start the TWI transceiver to enable reseption of the first command from the TWI Master. |
TWI_Start_Transceiver(); |
// This example is made to work together with the AVR315 TWI Master application note. In adition to connecting the TWI |
// pins, also connect PORTB to the LEDS. The code reads a message as a TWI slave and acts according to if it is a |
// general call, or an address call. If it is an address call, then the first byte is considered a command byte and |
// it then responds differently according to the commands. |
// This loop runs forever. If the TWI is busy the execution will just continue doing other operations. |
for(;;) |
{ |
#ifdef POWER_MANAGEMENT_ENABLED |
// Sleep while waiting for TWI transceiver to complete or waiting for new commands. |
// If we have data in the buffer, we can't enter sleep because we have to take care |
// of it first. |
// If the transceiver is busy, we enter idle mode because it will wake up by all TWI |
// interrupts. |
// If the transceiver not is busy, we can enter power-down mode because next receive |
// should be a TWI address match and it wakes the device up from all sleep modes. |
if( ! TWI_statusReg.RxDataInBuf ) { |
if(TWI_Transceiver_Busy()) { |
MCUCR = (1<<SE)|(0<<SM2)|(0<<SM1)|(0<<SM0); // Enable sleep with idle mode |
} else { |
MCUCR = (1<<SE)|(0<<SM2)|(1<<SM1)|(0<<SM0); // Enable sleep with power-down mode |
} |
SLEEP(); |
} else { |
NOP(); // There is data in the buffer, code below takes care of it. |
} |
#else // No power management |
// Here you can add your own code that should be run while waiting for the TWI to finish |
NOP(); // Put own code here. |
#endif |
// Check if the TWI Transceiver has completed an operation. |
if ( ! TWI_Transceiver_Busy() ) |
{ |
// Check if the last operation was successful |
if ( TWI_statusReg.lastTransOK ) |
{ |
// Check if the last operation was a reception |
if ( TWI_statusReg.RxDataInBuf ) |
{ |
TWI_Get_Data_From_Transceiver(messageBuf, 2); |
// Check if the last operation was a reception as General Call |
if ( TWI_statusReg.genAddressCall ) |
{ |
// Put data received out to PORTB as an example. |
PORTB = messageBuf[0]; |
} |
else // Ends up here if the last operation was a reception as Slave Address Match |
{ |
// Example of how to interpret a command and respond. |
// TWI_CMD_MASTER_WRITE stores the data to PORTB |
if (messageBuf[0] == TWI_CMD_MASTER_WRITE) |
{ |
PORTB = messageBuf[1]; |
} |
// TWI_CMD_MASTER_READ prepares the data from PINB in the transceiver buffer for the TWI master to fetch. |
if (messageBuf[0] == TWI_CMD_MASTER_READ) |
{ |
messageBuf[0] = PINB; |
TWI_Start_Transceiver_With_Data( messageBuf, 1 ); |
} |
} |
} |
else // Ends up here if the last operation was a transmission |
{ |
NOP(); // Put own code here. |
} |
// Check if the TWI Transceiver has already been started. |
// If not then restart it to prepare it for new receptions. |
if ( ! TWI_Transceiver_Busy() ) |
{ |
TWI_Start_Transceiver(); |
} |
} |
else // Ends up here if the last operation completed unsuccessfully |
{ |
TWI_Act_On_Failure_In_Last_Transmission( TWI_Get_State_Info() ); |
} |
} |
} |
}*/ |
Property changes: |
Added: svn:mime-type |
+text/plain |
\ No newline at end of property |
/Transportables_Koptertool/PKT/trunk/utils/twi_slave.h |
---|
0,0 → 1,121 |
/***************************************************************************** |
* |
* Atmel Corporation |
* |
* File : TWI_Slave.h |
* Compiler : IAR EWAAVR 2.28a/3.10c |
* Revision : $Revision: 2475 $ |
* Date : $Date: 2007-09-20 12:00:43 +0200 (to, 20 sep 2007) $ |
* Updated by : $Author: mlarsson $ |
* |
* Support mail : avr@atmel.com |
* |
* Supported devices : All devices with a TWI module can be used. |
* The example is written for the ATmega16 |
* |
* AppNote : AVR311 - TWI Slave Implementation |
* |
* Description : Header file for TWI_slave.c |
* Include this file in the application. |
* |
****************************************************************************/ |
/*! \page MISRA |
* |
* General disabling of MISRA rules: |
* * (MISRA C rule 1) compiler is configured to allow extensions |
* * (MISRA C rule 111) bit fields shall only be defined to be of type unsigned int or signed int |
* * (MISRA C rule 37) bitwise operations shall not be performed on signed integer types |
* As it does not work well with 8bit architecture and/or IAR |
* Other disabled MISRA rules |
* * (MISRA C rule 109) use of union - overlapping storage shall not be used |
* * (MISRA C rule 61) every non-empty case clause in a switch statement shall be terminated with a break statement |
*/ |
/**************************************************************************** |
TWI Status/Control register definitions |
****************************************************************************/ |
#define TWI_BUFFER_SIZE 4 // Reserves memory for the drivers transceiver buffer. |
// Set this to the largest message size that will be sent including address byte. |
/**************************************************************************** |
Global definitions |
****************************************************************************/ |
union TWI_statusReg_t // Status byte holding flags. |
{ |
unsigned char all; |
struct |
{ |
unsigned char lastTransOK:1; |
unsigned char RxDataInBuf:1; |
unsigned char genAddressCall:1; // TRUE = General call, FALSE = TWI Address; |
unsigned char unusedBits:5; |
}; |
}; |
extern union TWI_statusReg_t TWI_statusReg; |
/**************************************************************************** |
Function definitions |
****************************************************************************/ |
void twi_slave_init( unsigned char ); |
unsigned char twi_slave_busy( void ); |
unsigned char twi_slave_get_status( void ); |
void twi_slave_start_with_data( unsigned char * , unsigned char ); |
void twi_slave_start( void ); |
unsigned char twi_slave_get_data( unsigned char *, unsigned char ); |
/**************************************************************************** |
Bit and byte definitions |
****************************************************************************/ |
#define TWI_READ_BIT 0 // Bit position for R/W bit in "address byte". |
#define TWI_ADR_BITS 1 // Bit position for LSB of the slave address bits in the init byte. |
#define TWI_GEN_BIT 0 // Bit position for LSB of the general call bit in the init byte. |
#define TRUE 1 |
#define FALSE 0 |
/**************************************************************************** |
TWI State codes |
****************************************************************************/ |
// General TWI Master staus codes |
#define TWI_START 0x08 // START has been transmitted |
#define TWI_REP_START 0x10 // Repeated START has been transmitted |
#define TWI_ARB_LOST 0x38 // Arbitration lost |
// TWI Master Transmitter staus codes |
#define TWI_MTX_ADR_ACK 0x18 // SLA+W has been tramsmitted and ACK received |
#define TWI_MTX_ADR_NACK 0x20 // SLA+W has been tramsmitted and NACK received |
#define TWI_MTX_DATA_ACK 0x28 // Data byte has been tramsmitted and ACK received |
#define TWI_MTX_DATA_NACK 0x30 // Data byte has been tramsmitted and NACK received |
// TWI Master Receiver staus codes |
#define TWI_MRX_ADR_ACK 0x40 // SLA+R has been tramsmitted and ACK received |
#define TWI_MRX_ADR_NACK 0x48 // SLA+R has been tramsmitted and NACK received |
#define TWI_MRX_DATA_ACK 0x50 // Data byte has been received and ACK tramsmitted |
#define TWI_MRX_DATA_NACK 0x58 // Data byte has been received and NACK tramsmitted |
// TWI Slave Transmitter staus codes |
#define TWI_STX_ADR_ACK 0xA8 // Own SLA+R has been received; ACK has been returned |
#define TWI_STX_ADR_ACK_M_ARB_LOST 0xB0 // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned |
#define TWI_STX_DATA_ACK 0xB8 // Data byte in TWDR has been transmitted; ACK has been received |
#define TWI_STX_DATA_NACK 0xC0 // Data byte in TWDR has been transmitted; NOT ACK has been received |
#define TWI_STX_DATA_ACK_LAST_BYTE 0xC8 // Last data byte in TWDR has been transmitted (TWEA = �0�); ACK has been received |
// TWI Slave Receiver staus codes |
#define TWI_SRX_ADR_ACK 0x60 // Own SLA+W has been received ACK has been returned |
#define TWI_SRX_ADR_ACK_M_ARB_LOST 0x68 // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned |
#define TWI_SRX_GEN_ACK 0x70 // General call address has been received; ACK has been returned |
#define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78 // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned |
#define TWI_SRX_ADR_DATA_ACK 0x80 // Previously addressed with own SLA+W; data has been received; ACK has been returned |
#define TWI_SRX_ADR_DATA_NACK 0x88 // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned |
#define TWI_SRX_GEN_DATA_ACK 0x90 // Previously addressed with general call; data has been received; ACK has been returned |
#define TWI_SRX_GEN_DATA_NACK 0x98 // Previously addressed with general call; data has been received; NOT ACK has been returned |
#define TWI_SRX_STOP_RESTART 0xA0 // A STOP condition or repeated START condition has been received while still addressed as Slave |
// TWI Miscellaneous status codes |
#define TWI_NO_STATE 0xF8 // No relevant state information available; TWINT = �0� |
#define TWI_BUS_ERROR 0x00 // Bus error due to an illegal START or STOP condition |
Property changes: |
Added: svn:mime-type |
+text/plain |
\ No newline at end of property |
/Transportables_Koptertool/PKT/trunk/utils/twimaster.c |
---|
0,0 → 1,202 |
/************************************************************************* |
* Title: I2C master library using hardware TWI interface |
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury |
* File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $ |
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 |
* Target: any AVR device with hardware TWI |
* Usage: API compatible with I2C Software Library i2cmaster.h |
**************************************************************************/ |
#include <inttypes.h> |
#include <compat/twi.h> |
#include <i2cmaster.h> |
/* define CPU frequency in Mhz here if not defined in Makefile */ |
#ifndef F_CPU |
#define F_CPU 16000000UL |
#endif |
/* I2C clock in Hz */ |
#define SCL_CLOCK 400000L |
/************************************************************************* |
Initialization of the I2C bus interface. Need to be called only once |
*************************************************************************/ |
void i2c_init(void) |
{ |
/* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ |
TWSR = 0; /* no prescaler */ |
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */ |
}/* i2c_init */ |
/************************************************************************* |
Issues a start condition and sends address and transfer direction. |
return 0 = device accessible, 1= failed to access device |
*************************************************************************/ |
unsigned char i2c_start(unsigned char address) |
{ |
uint8_t twst; |
// send START condition |
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); |
// wait until transmission completed |
while(!(TWCR & (1<<TWINT))); |
// check value of TWI Status Register. Mask prescaler bits. |
twst = TW_STATUS & 0xF8; |
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1; |
// send device address |
TWDR = address; |
TWCR = (1<<TWINT) | (1<<TWEN); |
// wail until transmission completed and ACK/NACK has been received |
while(!(TWCR & (1<<TWINT))); |
// check value of TWI Status Register. Mask prescaler bits. |
twst = TW_STATUS & 0xF8; |
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1; |
return 0; |
}/* i2c_start */ |
/************************************************************************* |
Issues a start condition and sends address and transfer direction. |
If device is busy, use ack polling to wait until device is ready |
Input: address and transfer direction of I2C device |
*************************************************************************/ |
void i2c_start_wait(unsigned char address) |
{ |
uint8_t twst; |
while ( 1 ) |
{ |
// send START condition |
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); |
// wait until transmission completed |
while(!(TWCR & (1<<TWINT))); |
// check value of TWI Status Register. Mask prescaler bits. |
twst = TW_STATUS & 0xF8; |
if ( (twst != TW_START) && (twst != TW_REP_START)) continue; |
// send device address |
TWDR = address; |
TWCR = (1<<TWINT) | (1<<TWEN); |
// wail until transmission completed |
while(!(TWCR & (1<<TWINT))); |
// check value of TWI Status Register. Mask prescaler bits. |
twst = TW_STATUS & 0xF8; |
if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) |
{ |
/* device busy, send stop condition to terminate write operation */ |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); |
// wait until stop condition is executed and bus released |
while(TWCR & (1<<TWSTO)); |
continue; |
} |
//if( twst != TW_MT_SLA_ACK) return 1; |
break; |
} |
}/* i2c_start_wait */ |
/************************************************************************* |
Issues a repeated start condition and sends address and transfer direction |
Input: address and transfer direction of I2C device |
Return: 0 device accessible |
1 failed to access device |
*************************************************************************/ |
unsigned char i2c_rep_start(unsigned char address) |
{ |
return i2c_start( address ); |
}/* i2c_rep_start */ |
/************************************************************************* |
Terminates the data transfer and releases the I2C bus |
*************************************************************************/ |
void i2c_stop(void) |
{ |
/* send stop condition */ |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); |
// wait until stop condition is executed and bus released |
while(TWCR & (1<<TWSTO)); |
}/* i2c_stop */ |
/************************************************************************* |
Send one byte to I2C device |
Input: byte to be transfered |
Return: 0 write successful |
1 write failed |
*************************************************************************/ |
unsigned char i2c_write( unsigned char data ) |
{ |
uint8_t twst; |
// send data to the previously addressed device |
TWDR = data; |
TWCR = (1<<TWINT) | (1<<TWEN); |
// wait until transmission completed |
while(!(TWCR & (1<<TWINT))); |
// check value of TWI Status Register. Mask prescaler bits |
twst = TW_STATUS & 0xF8; |
if( twst != TW_MT_DATA_ACK) return 1; |
return 0; |
}/* i2c_write */ |
/************************************************************************* |
Read one byte from the I2C device, request more data from device |
Return: byte read from I2C device |
*************************************************************************/ |
unsigned char i2c_readAck(void) |
{ |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); |
while(!(TWCR & (1<<TWINT))); |
return TWDR; |
}/* i2c_readAck */ |
/************************************************************************* |
Read one byte from the I2C device, read is followed by a stop condition |
Return: byte read from I2C device |
*************************************************************************/ |
unsigned char i2c_readNak(void) |
{ |
TWCR = (1<<TWINT) | (1<<TWEN); |
while(!(TWCR & (1<<TWINT))); |
return TWDR; |
}/* i2c_readNak */ |
Property changes: |
Added: svn:mime-type |
+text/plain |
\ No newline at end of property |
/Transportables_Koptertool/PKT/trunk/utils/. |
---|
Property changes: |
Added: svn:ignore |
+_old |
+ |
+maniacbug-mighty-1284p-68ed99c |
+ |
+Arduino |
+ |
+_doc |
+ |
+maniacbug-mighty-1284p-68ed99c.zip |