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