xyControl  0.1
Quadrotor Flight Controller on AVR Basis
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups
twi.c
1 /*************************************************************************
2 * Title: I2C master library using hardware TWI interface
3 * Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
4 * File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $
5 * Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
6 * Target: any AVR device with hardware TWI
7 * Usage: API compatible with I2C Software Library i2cmaster.h
8 **************************************************************************/
9 
10 #include <compat/twi.h>
11 
12 #include <twi.h>
13 
14 /* define CPU frequency in Mhz here if not defined in Makefile */
15 #ifndef F_CPU
16 #define F_CPU 16000000UL
17 #endif
18 
19 /* I2C clock in Hz */
20 #define SCL_CLOCK 400000L
21 
22 
23 /*************************************************************************
24  Initialization of the I2C bus interface. Need to be called only once
25 *************************************************************************/
26 void twiInit(void)
27 {
28  /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
29 
30  TWSR = 0; /* no prescaler */
31  TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */
32 
33 }/* i2c_init */
34 
35 
36 /*************************************************************************
37  Issues a start condition and sends address and transfer direction.
38  return 0 = device accessible, 1= failed to access device
39 *************************************************************************/
40 unsigned char twiStart(unsigned char address)
41 {
42  uint8_t twst;
43 
44  // send START condition
45  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
46 
47  // wait until transmission completed
48  while(!(TWCR & (1<<TWINT)));
49 
50  // check value of TWI Status Register. Mask prescaler bits.
51  twst = TW_STATUS & 0xF8;
52  if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
53 
54  // send device address
55  TWDR = address;
56  TWCR = (1<<TWINT) | (1<<TWEN);
57 
58  // wail until transmission completed and ACK/NACK has been received
59  while(!(TWCR & (1<<TWINT)));
60 
61  // check value of TWI Status Register. Mask prescaler bits.
62  twst = TW_STATUS & 0xF8;
63  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
64 
65  return 0;
66 
67 }/* i2c_start */
68 
69 
70 /*************************************************************************
71  Issues a start condition and sends address and transfer direction.
72  If device is busy, use ack polling to wait until device is ready
73 
74  Input: address and transfer direction of I2C device
75 *************************************************************************/
76 void twiStartWait(unsigned char address)
77 {
78  uint8_t twst;
79 
80 
81  while ( 1 )
82  {
83  // send START condition
84  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
85 
86  // wait until transmission completed
87  while(!(TWCR & (1<<TWINT)));
88 
89  // check value of TWI Status Register. Mask prescaler bits.
90  twst = TW_STATUS & 0xF8;
91  if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
92 
93  // send device address
94  TWDR = address;
95  TWCR = (1<<TWINT) | (1<<TWEN);
96 
97  // wail until transmission completed
98  while(!(TWCR & (1<<TWINT)));
99 
100  // check value of TWI Status Register. Mask prescaler bits.
101  twst = TW_STATUS & 0xF8;
102  if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
103  {
104  /* device busy, send stop condition to terminate write operation */
105  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
106 
107  // wait until stop condition is executed and bus released
108  while(TWCR & (1<<TWSTO));
109 
110  continue;
111  }
112  //if( twst != TW_MT_SLA_ACK) return 1;
113  break;
114  }
115 
116 }/* i2c_start_wait */
117 
118 
119 /*************************************************************************
120  Issues a repeated start condition and sends address and transfer direction
121 
122  Input: address and transfer direction of I2C device
123 
124  Return: 0 device accessible
125  1 failed to access device
126 *************************************************************************/
127 unsigned char twiRepStart(unsigned char address)
128 {
129  return twiStart( address );
130 
131 }/* i2c_rep_start */
132 
133 
134 /*************************************************************************
135  Terminates the data transfer and releases the I2C bus
136 *************************************************************************/
137 void twiStop(void)
138 {
139  /* send stop condition */
140  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
141 
142  // wait until stop condition is executed and bus released
143  while(TWCR & (1<<TWSTO));
144 
145 }/* i2c_stop */
146 
147 
148 /*************************************************************************
149  Send one byte to I2C device
150 
151  Input: byte to be transfered
152  Return: 0 write successful
153  1 write failed
154 *************************************************************************/
155 unsigned char twiWrite( unsigned char data )
156 {
157  uint8_t twst;
158 
159  // send data to the previously addressed device
160  TWDR = data;
161  TWCR = (1<<TWINT) | (1<<TWEN);
162 
163  // wait until transmission completed
164  while(!(TWCR & (1<<TWINT)));
165 
166  // check value of TWI Status Register. Mask prescaler bits
167  twst = TW_STATUS & 0xF8;
168  if( twst != TW_MT_DATA_ACK) return 1;
169  return 0;
170 
171 }/* i2c_write */
172 
173 
174 /*************************************************************************
175  Read one byte from the I2C device, request more data from device
176 
177  Return: byte read from I2C device
178 *************************************************************************/
179 unsigned char twiReadAck(void)
180 {
181  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
182  while(!(TWCR & (1<<TWINT)));
183 
184  return TWDR;
185 
186 }/* i2c_readAck */
187 
188 
189 /*************************************************************************
190  Read one byte from the I2C device, read is followed by a stop condition
191 
192  Return: byte read from I2C device
193 *************************************************************************/
194 unsigned char twiReadNak(void)
195 {
196  TWCR = (1<<TWINT) | (1<<TWEN);
197  while(!(TWCR & (1<<TWINT)));
198 
199  return TWDR;
200 
201 }/* i2c_readNak */