Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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