]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/handwired/frenchdev/twimaster.c
Atreus rules.mk and readme (#5678)
[qmk_firmware.git] / keyboards / handwired / frenchdev / 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
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
30    * minimal values in Bit Rate Register (TWBR) and minimal Prescaler
31    * bits in the TWI Status Register should give us maximal possible
32    * I2C bus speed - about 444 kHz
33    *
34    * for more details, see 20.5.2 in ATmega16/32 secification
35    */
36   
37   TWSR = 0;     /* no prescaler */
38   TWBR = 10;    /* must be >= 10 for stable operation */
39
40 }/* i2c_init */
41
42
43 /*************************************************************************      
44   Issues a start condition and sends address and transfer direction.
45   return 0 = device accessible, 1= failed to access device
46 *************************************************************************/
47 unsigned char i2c_start(unsigned char address)
48 {
49     uint8_t   twst;
50
51         // send START condition
52         TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
53
54         // wait until transmission completed
55         while(!(TWCR & (1<<TWINT)));
56
57         // check value of TWI Status Register. Mask prescaler bits.
58         twst = TW_STATUS & 0xF8;
59         if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
60
61         // send device address
62         TWDR = address;
63         TWCR = (1<<TWINT) | (1<<TWEN);
64
65         // wail until transmission completed and ACK/NACK has been received
66         while(!(TWCR & (1<<TWINT)));
67
68         // check value of TWI Status Register. Mask prescaler bits.
69         twst = TW_STATUS & 0xF8;
70         if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
71
72         return 0;
73
74 }/* i2c_start */
75
76
77 /*************************************************************************
78  Issues a start condition and sends address and transfer direction.
79  If device is busy, use ack polling to wait until device is ready
80  
81  Input:   address and transfer direction of I2C device
82 *************************************************************************/
83 void i2c_start_wait(unsigned char address)
84 {
85     uint8_t   twst;
86
87
88     while ( 1 )
89     {
90             // send START condition
91             TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
92     
93         // wait until transmission completed
94         while(!(TWCR & (1<<TWINT)));
95     
96         // check value of TWI Status Register. Mask prescaler bits.
97         twst = TW_STATUS & 0xF8;
98         if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
99     
100         // send device address
101         TWDR = address;
102         TWCR = (1<<TWINT) | (1<<TWEN);
103     
104         // wail until transmission completed
105         while(!(TWCR & (1<<TWINT)));
106     
107         // check value of TWI Status Register. Mask prescaler bits.
108         twst = TW_STATUS & 0xF8;
109         if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) 
110         {           
111             /* device busy, send stop condition to terminate write operation */
112                 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
113                 
114                 // wait until stop condition is executed and bus released
115                 while(TWCR & (1<<TWSTO));
116                 
117             continue;
118         }
119         //if( twst != TW_MT_SLA_ACK) return 1;
120         break;
121      }
122
123 }/* i2c_start_wait */
124
125
126 /*************************************************************************
127  Issues a repeated start condition and sends address and transfer direction 
128
129  Input:   address and transfer direction of I2C device
130  
131  Return:  0 device accessible
132           1 failed to access device
133 *************************************************************************/
134 unsigned char i2c_rep_start(unsigned char address)
135 {
136     return i2c_start( address );
137
138 }/* i2c_rep_start */
139
140
141 /*************************************************************************
142  Terminates the data transfer and releases the I2C bus
143 *************************************************************************/
144 void i2c_stop(void)
145 {
146     /* send stop condition */
147         TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
148         
149         // wait until stop condition is executed and bus released
150         while(TWCR & (1<<TWSTO));
151
152 }/* i2c_stop */
153
154
155 /*************************************************************************
156   Send one byte to I2C device
157   
158   Input:    byte to be transfered
159   Return:   0 write successful 
160             1 write failed
161 *************************************************************************/
162 unsigned char i2c_write( unsigned char data )
163 {       
164     uint8_t   twst;
165     
166         // send data to the previously addressed device
167         TWDR = data;
168         TWCR = (1<<TWINT) | (1<<TWEN);
169
170         // wait until transmission completed
171         while(!(TWCR & (1<<TWINT)));
172
173         // check value of TWI Status Register. Mask prescaler bits
174         twst = TW_STATUS & 0xF8;
175         if( twst != TW_MT_DATA_ACK) return 1;
176         return 0;
177
178 }/* i2c_write */
179
180
181 /*************************************************************************
182  Read one byte from the I2C device, request more data from device 
183  
184  Return:  byte read from I2C device
185 *************************************************************************/
186 unsigned char i2c_readAck(void)
187 {
188         TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
189         while(!(TWCR & (1<<TWINT)));    
190
191     return TWDR;
192
193 }/* i2c_readAck */
194
195
196 /*************************************************************************
197  Read one byte from the I2C device, read is followed by a stop condition 
198  
199  Return:  byte read from I2C device
200 *************************************************************************/
201 unsigned char i2c_readNak(void)
202 {
203         TWCR = (1<<TWINT) | (1<<TWEN);
204         while(!(TWCR & (1<<TWINT)));
205         
206     return TWDR;
207
208 }/* i2c_readNak */