I2CLCD
Driver for HD44780 LCD via I2C interface
 All Functions Groups Pages
twimaster.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 #include <inttypes.h>
10 #include <compat/twi.h>
11 #include "i2cmaster.h"
12 #include "main.h"
13 
14 /* I2C clock in Hz */
15 #define SCL_CLOCK 100000L
16 
17 
18 /*************************************************************************
19  Initialization of the I2C bus interface. Need to be called only once
20 *************************************************************************/
21 void i2c_init(void)
22 {
23  /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
24 
25  TWSR = 0; /* no prescaler */
26  TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */
27 
28 }/* i2c_init */
29 
30 
31 /*************************************************************************
32  Issues a start condition and sends address and transfer direction.
33  return 0 = device accessible, 1= failed to access device
34 *************************************************************************/
35 unsigned char i2c_start(unsigned char address)
36 {
37  uint8_t twst;
38 
39  // send START condition
40  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
41 
42  // wait until transmission completed
43  while(!(TWCR & (1<<TWINT)));
44 
45  // check value of TWI Status Register. Mask prescaler bits.
46  twst = TW_STATUS & 0xF8;
47  if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
48 
49  // send device address
50  TWDR = address;
51  TWCR = (1<<TWINT) | (1<<TWEN);
52 
53  // wail until transmission completed and ACK/NACK has been received
54  while(!(TWCR & (1<<TWINT)));
55 
56  // check value of TWI Status Register. Mask prescaler bits.
57  twst = TW_STATUS & 0xF8;
58  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
59 
60  return 0;
61 
62 }/* i2c_start */
63 
64 
65 /*************************************************************************
66  Issues a start condition and sends address and transfer direction.
67  If device is busy, use ack polling to wait until device is ready
68 
69  Input: address and transfer direction of I2C device
70 *************************************************************************/
71 void i2c_start_wait(unsigned char address)
72 {
73  uint8_t twst;
74 
75 
76  while ( 1 )
77  {
78  // send START condition
79  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
80 
81  // wait until transmission completed
82  while(!(TWCR & (1<<TWINT)));
83 
84  // check value of TWI Status Register. Mask prescaler bits.
85  twst = TW_STATUS & 0xF8;
86  if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
87 
88  // send device address
89  TWDR = address;
90  TWCR = (1<<TWINT) | (1<<TWEN);
91 
92  // wail until transmission completed
93  while(!(TWCR & (1<<TWINT)));
94 
95  // check value of TWI Status Register. Mask prescaler bits.
96  twst = TW_STATUS & 0xF8;
97  if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
98  {
99  /* device busy, send stop condition to terminate write operation */
100  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
101 
102  // wait until stop condition is executed and bus released
103  while(TWCR & (1<<TWSTO));
104 
105  continue;
106  }
107  //if( twst != TW_MT_SLA_ACK) return 1;
108  break;
109  }
110 
111 }/* i2c_start_wait */
112 
113 
114 /*************************************************************************
115  Issues a repeated start condition and sends address and transfer direction
116 
117  Input: address and transfer direction of I2C device
118 
119  Return: 0 device accessible
120  1 failed to access device
121 *************************************************************************/
122 unsigned char i2c_rep_start(unsigned char address)
123 {
124  return i2c_start( address );
125 
126 }/* i2c_rep_start */
127 
128 
129 /*************************************************************************
130  Terminates the data transfer and releases the I2C bus
131 *************************************************************************/
132 void i2c_stop(void)
133 {
134  /* send stop condition */
135  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
136 
137  // wait until stop condition is executed and bus released
138  while(TWCR & (1<<TWSTO));
139 
140 }/* i2c_stop */
141 
142 
143 /*************************************************************************
144  Send one byte to I2C device
145 
146  Input: byte to be transfered
147  Return: 0 write successful
148  1 write failed
149 *************************************************************************/
150 unsigned char i2c_write( unsigned char data )
151 {
152  uint8_t twst;
153 
154  // send data to the previously addressed device
155  TWDR = data;
156  TWCR = (1<<TWINT) | (1<<TWEN);
157 
158  // wait until transmission completed
159  while(!(TWCR & (1<<TWINT)));
160 
161  // check value of TWI Status Register. Mask prescaler bits
162  twst = TW_STATUS & 0xF8;
163  if( twst != TW_MT_DATA_ACK) return 1;
164  return 0;
165 
166 }/* i2c_write */
167 
168 
169 /*************************************************************************
170  Read one byte from the I2C device, request more data from device
171 
172  Return: byte read from I2C device
173 *************************************************************************/
174 unsigned char i2c_readAck(void)
175 {
176  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
177  while(!(TWCR & (1<<TWINT)));
178 
179  return TWDR;
180 
181 }/* i2c_readAck */
182 
183 
184 /*************************************************************************
185  Read one byte from the I2C device, read is followed by a stop condition
186 
187  Return: byte read from I2C device
188 *************************************************************************/
189 unsigned char i2c_readNak(void)
190 {
191  TWCR = (1<<TWINT) | (1<<TWEN);
192  while(!(TWCR & (1<<TWINT)));
193 
194  return TWDR;
195 
196 }/* i2c_readNak */