aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2021-09-08 02:23:11 +0100
committerGitHub <noreply@github.com>2021-09-07 18:23:11 -0700
commit60c5bd7b5e0e75f48d9731118b92a3add3342efd (patch)
tree50bf88fc2217fa46f43afb391e92a21cc1ef0330
parent04c0704b280c4847c43b164335e9741b19219131 (diff)
downloadqmk_firmware-60c5bd7b5e0e75f48d9731118b92a3add3342efd.tar.gz
qmk_firmware-60c5bd7b5e0e75f48d9731118b92a3add3342efd.zip
handwired/dactyl - Refactor use of legacy i2c implementation (#14344)
-rw-r--r--keyboards/handwired/dactyl/dactyl.c1
-rw-r--r--keyboards/handwired/dactyl/dactyl.h5
-rw-r--r--keyboards/handwired/dactyl/i2cmaster.h178
-rw-r--r--keyboards/handwired/dactyl/matrix.c99
-rw-r--r--keyboards/handwired/dactyl/rules.mk4
-rw-r--r--keyboards/handwired/dactyl/twimaster.c207
6 files changed, 52 insertions, 442 deletions
diff --git a/keyboards/handwired/dactyl/dactyl.c b/keyboards/handwired/dactyl/dactyl.c
index ff9b4e08a..be815777b 100644
--- a/keyboards/handwired/dactyl/dactyl.c
+++ b/keyboards/handwired/dactyl/dactyl.c
@@ -1,5 +1,4 @@
1#include "dactyl.h" 1#include "dactyl.h"
2#include "i2cmaster.h"
3 2
4#ifdef SWAP_HANDS_ENABLE 3#ifdef SWAP_HANDS_ENABLE
5__attribute__ ((weak)) 4__attribute__ ((weak))
diff --git a/keyboards/handwired/dactyl/dactyl.h b/keyboards/handwired/dactyl/dactyl.h
index 3589e1d3c..f7be886ac 100644
--- a/keyboards/handwired/dactyl/dactyl.h
+++ b/keyboards/handwired/dactyl/dactyl.h
@@ -4,12 +4,11 @@
4#include "quantum.h" 4#include "quantum.h"
5#include <stdint.h> 5#include <stdint.h>
6#include <stdbool.h> 6#include <stdbool.h>
7#include "i2cmaster.h" 7#include "i2c_master.h"
8#include <util/delay.h> 8#include <util/delay.h>
9 9
10#define I2C_ADDR 0b0100000 10#define I2C_ADDR 0b0100000
11#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE ) 11#define I2C_TIMEOUT 100
12#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ )
13#define IODIRA 0x00 // i/o direction register 12#define IODIRA 0x00 // i/o direction register
14#define IODIRB 0x01 13#define IODIRB 0x01
15#define GPPUA 0x0C // GPIO pull-up resistor register 14#define GPPUA 0x0C // GPIO pull-up resistor register
diff --git a/keyboards/handwired/dactyl/i2cmaster.h b/keyboards/handwired/dactyl/i2cmaster.h
deleted file mode 100644
index 3917b9e6c..000000000
--- a/keyboards/handwired/dactyl/i2cmaster.h
+++ /dev/null
@@ -1,178 +0,0 @@
1#ifndef _I2CMASTER_H
2#define _I2CMASTER_H 1
3/*************************************************************************
4* Title: C include file for the I2C master interface
5* (i2cmaster.S or twimaster.c)
6* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
7* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
8* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
9* Target: any AVR device
10* Usage: see Doxygen manual
11**************************************************************************/
12
13#ifdef DOXYGEN
14/**
15 @defgroup pfleury_ic2master I2C Master library
16 @code #include <i2cmaster.h> @endcode
17
18 @brief I2C (TWI) Master Software Library
19
20 Basic routines for communicating with I2C slave devices. This single master
21 implementation is limited to one bus master on the I2C bus.
22
23 This I2c library is implemented as a compact assembler software implementation of the I2C protocol
24 which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c).
25 Since the API for these two implementations is exactly the same, an application can be linked either against the
26 software I2C implementation or the hardware I2C implementation.
27
28 Use 4.7k pull-up resistor on the SDA and SCL pin.
29
30 Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module
31 i2cmaster.S to your target when using the software I2C implementation !
32
33 Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.
34
35 @note
36 The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted
37 to GNU assembler and AVR-GCC C call interface.
38 Replaced the incorrect quarter period delays found in AVR300 with
39 half period delays.
40
41 @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury
42
43 @par API Usage Example
44 The following code shows typical usage of this library, see example test_i2cmaster.c
45
46 @code
47
48 #include <i2cmaster.h>
49
50
51 #define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet
52
53 int main(void)
54 {
55 unsigned char ret;
56
57 i2c_init(); // initialize I2C library
58
59 // write 0x75 to EEPROM address 5 (Byte Write)
60 i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
61 i2c_write(0x05); // write address = 5
62 i2c_write(0x75); // write value 0x75 to EEPROM
63 i2c_stop(); // set stop conditon = release bus
64
65
66 // read previously written value back from EEPROM address 5
67 i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
68
69 i2c_write(0x05); // write address = 5
70 i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
71
72 ret = i2c_readNak(); // read one byte from EEPROM
73 i2c_stop();
74
75 for(;;);
76 }
77 @endcode
78
79*/
80#endif /* DOXYGEN */
81
82/**@{*/
83
84#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
85#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
86#endif
87
88#include <avr/io.h>
89
90/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
91#define I2C_READ 1
92
93/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
94#define I2C_WRITE 0
95
96
97/**
98 @brief initialize the I2C master interace. Need to be called only once
99 @param void
100 @return none
101 */
102extern void i2c_init(void);
103
104
105/**
106 @brief Terminates the data transfer and releases the I2C bus
107 @param void
108 @return none
109 */
110extern void i2c_stop(void);
111
112
113/**
114 @brief Issues a start condition and sends address and transfer direction
115
116 @param addr address and transfer direction of I2C device
117 @retval 0 device accessible
118 @retval 1 failed to access device
119 */
120extern unsigned char i2c_start(unsigned char addr);
121
122
123/**
124 @brief Issues a repeated start condition and sends address and transfer direction
125
126 @param addr address and transfer direction of I2C device
127 @retval 0 device accessible
128 @retval 1 failed to access device
129 */
130extern unsigned char i2c_rep_start(unsigned char addr);
131
132
133/**
134 @brief Issues a start condition and sends address and transfer direction
135
136 If device is busy, use ack polling to wait until device ready
137 @param addr address and transfer direction of I2C device
138 @return none
139 */
140extern void i2c_start_wait(unsigned char addr);
141
142
143/**
144 @brief Send one byte to I2C device
145 @param data byte to be transfered
146 @retval 0 write successful
147 @retval 1 write failed
148 */
149extern unsigned char i2c_write(unsigned char data);
150
151
152/**
153 @brief read one byte from the I2C device, request more data from device
154 @return byte read from I2C device
155 */
156extern unsigned char i2c_readAck(void);
157
158/**
159 @brief read one byte from the I2C device, read is followed by a stop condition
160 @return byte read from I2C device
161 */
162extern unsigned char i2c_readNak(void);
163
164/**
165 @brief read one byte from the I2C device
166
167 Implemented as a macro, which calls either i2c_readAck or i2c_readNak
168
169 @param ack 1 send ack, request more data from device<br>
170 0 send nak, read is followed by a stop condition
171 @return byte read from I2C device
172 */
173extern unsigned char i2c_read(unsigned char ack);
174#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
175
176
177/**@}*/
178#endif
diff --git a/keyboards/handwired/dactyl/matrix.c b/keyboards/handwired/dactyl/matrix.c
index 615621522..a21cd08e1 100644
--- a/keyboards/handwired/dactyl/matrix.c
+++ b/keyboards/handwired/dactyl/matrix.c
@@ -25,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
25#include "util.h" 25#include "util.h"
26#include "matrix.h" 26#include "matrix.h"
27#include "dactyl.h" 27#include "dactyl.h"
28#include "i2cmaster.h" 28#include "i2c_master.h"
29#include "timer.h" 29#include "timer.h"
30 30
31 31
@@ -147,9 +147,6 @@ void init_expander(void) {
147#endif 147#endif
148 } 148 }
149 149
150 expander_status = i2c_start(I2C_ADDR_WRITE); if (expander_status) goto out;
151 expander_status = i2c_write(IODIRA); if (expander_status) goto out;
152
153 /* 150 /*
154 Pin direction and pull-up depends on both the diode direction 151 Pin direction and pull-up depends on both the diode direction
155 and on whether the column register is GPIOA or GPIOB 152 and on whether the column register is GPIOA or GPIOB
@@ -164,50 +161,65 @@ void init_expander(void) {
164 161
165#if (EXPANDER_COL_REGISTER == GPIOA) 162#if (EXPANDER_COL_REGISTER == GPIOA)
166# if (DIODE_DIRECTION == COL2ROW) 163# if (DIODE_DIRECTION == COL2ROW)
167 expander_status = i2c_write(expander_input_pin_mask); if (expander_status) goto out; 164 uint8_t direction[2] = {
168 expander_status = i2c_write(0); if (expander_status) goto out; 165 expander_input_pin_mask,
166 0,
167 };
169# elif (DIODE_DIRECTION == ROW2COL) 168# elif (DIODE_DIRECTION == ROW2COL)
170 expander_status = i2c_write(0); if (expander_status) goto out; 169 uint8_t direction[2] = {
171 expander_status = i2c_write(expander_input_pin_mask); if (expander_status) goto out; 170 0,
171 expander_input_pin_mask,
172 };
172# endif 173# endif
173#elif (EXPANDER_COL_REGISTER == GPIOB) 174#elif (EXPANDER_COL_REGISTER == GPIOB)
174# if (DIODE_DIRECTION == COL2ROW) 175# if (DIODE_DIRECTION == COL2ROW)
175 expander_status = i2c_write(0); if (expander_status) goto out; 176 uint8_t direction[2] = {
176 expander_status = i2c_write(expander_input_pin_mask); if (expander_status) goto out; 177 0,
178 expander_input_pin_mask,
179 };
177# elif (DIODE_DIRECTION == ROW2COL) 180# elif (DIODE_DIRECTION == ROW2COL)
178 expander_status = i2c_write(expander_input_pin_mask); if (expander_status) goto out; 181 uint8_t direction[2] = {
179 expander_status = i2c_write(0); if (expander_status) goto out; 182 expander_input_pin_mask,
183 0,
184 };
180# endif 185# endif
181#endif 186#endif
182 187
183 i2c_stop();
184
185 // set pull-up 188 // set pull-up
186 // - unused : off : 0 189 // - unused : off : 0
187 // - input : on : 1 190 // - input : on : 1
188 // - driving : off : 0 191 // - driving : off : 0
189 expander_status = i2c_start(I2C_ADDR_WRITE); if (expander_status) goto out;
190 expander_status = i2c_write(GPPUA); if (expander_status) goto out;
191#if (EXPANDER_COL_REGISTER == GPIOA) 192#if (EXPANDER_COL_REGISTER == GPIOA)
192# if (DIODE_DIRECTION == COL2ROW) 193# if (DIODE_DIRECTION == COL2ROW)
193 expander_status = i2c_write(expander_input_pin_mask); if (expander_status) goto out; 194 uint8_t pullup[2] = {
194 expander_status = i2c_write(0); if (expander_status) goto out; 195 expander_input_pin_mask,
196 0,
197 };
195# elif (DIODE_DIRECTION == ROW2COL) 198# elif (DIODE_DIRECTION == ROW2COL)
196 expander_status = i2c_write(0); if (expander_status) goto out; 199 uint8_t pullup[2] = {
197 expander_status = i2c_write(expander_input_pin_mask); if (expander_status) goto out; 200 0,
201 expander_input_pin_mask,
202 };
198# endif 203# endif
199#elif (EXPANDER_COL_REGISTER == GPIOB) 204#elif (EXPANDER_COL_REGISTER == GPIOB)
200# if (DIODE_DIRECTION == COL2ROW) 205# if (DIODE_DIRECTION == COL2ROW)
201 expander_status = i2c_write(0); if (expander_status) goto out; 206 uint8_t pullup[2] = {
202 expander_status = i2c_write(expander_input_pin_mask); if (expander_status) goto out; 207 0,
208 expander_input_pin_mask,
209 };
203# elif (DIODE_DIRECTION == ROW2COL) 210# elif (DIODE_DIRECTION == ROW2COL)
204 expander_status = i2c_write(expander_input_pin_mask); if (expander_status) goto out; 211 uint8_t pullup[2] = {
205 expander_status = i2c_write(0); if (expander_status) goto out; 212 expander_input_pin_mask,
213 0,
214 };
206# endif 215# endif
207#endif 216#endif
208 217
209out: 218
210 i2c_stop(); 219 expander_status = i2c_writeReg(I2C_ADDR, IODIRA, direction, 2, I2C_TIMEOUT);
220 if (expander_status) return;
221
222 expander_status = i2c_writeReg(I2C_ADDR, GPPUA, pullup, 2, I2C_TIMEOUT);
211} 223}
212 224
213uint8_t matrix_scan(void) 225uint8_t matrix_scan(void)
@@ -337,14 +349,11 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
337 349
338 // Read columns from expander, unless it's in an error state 350 // Read columns from expander, unless it's in an error state
339 if (! expander_status) { 351 if (! expander_status) {
340 expander_status = i2c_start(I2C_ADDR_WRITE); if (expander_status) goto out; 352 uint8_t state = 0;
341 expander_status = i2c_write(EXPANDER_COL_REGISTER); if (expander_status) goto out; 353 expander_status = i2c_readReg(I2C_ADDR, EXPANDER_COL_REGISTER, &state, 1, I2C_TIMEOUT);
342 expander_status = i2c_start(I2C_ADDR_READ); if (expander_status) goto out; 354 if (! expander_status) {
343 355 current_matrix[current_row] |= (~state) & expander_input_pin_mask;
344 current_matrix[current_row] |= (~i2c_readNak()) & expander_input_pin_mask; 356 }
345
346 out:
347 i2c_stop();
348 } 357 }
349 358
350 // Read columns from onboard pins 359 // Read columns from onboard pins
@@ -366,11 +375,8 @@ static void select_row(uint8_t row) {
366 if (! expander_status) { 375 if (! expander_status) {
367 // set active row low : 0 376 // set active row low : 0
368 // set other rows hi-Z : 1 377 // set other rows hi-Z : 1
369 expander_status = i2c_start(I2C_ADDR_WRITE); if (expander_status) goto out; 378 uint8_t port = 0xFF & ~(1<<row);
370 expander_status = i2c_write(EXPANDER_ROW_REGISTER); if (expander_status) goto out; 379 expander_status = i2c_writeReg(I2C_ADDR, EXPANDER_ROW_REGISTER, &port, 1, I2C_TIMEOUT);
371 expander_status = i2c_write(0xFF & ~(1<<row)); if (expander_status) goto out;
372 out:
373 i2c_stop();
374 } 380 }
375 381
376 // select on teensy 382 // select on teensy
@@ -426,13 +432,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
426 return false; 432 return false;
427 } 433 }
428 434
429 expander_status = i2c_start(I2C_ADDR_WRITE); if (expander_status) goto out; 435 expander_status = i2c_readReg(I2C_ADDR, EXPANDER_ROW_REGISTER, &column_state, 1, I2C_TIMEOUT);
430 expander_status = i2c_write(EXPANDER_ROW_REGISTER); if (expander_status) goto out;
431 expander_status = i2c_start(I2C_ADDR_READ); if (expander_status) goto out;
432 column_state = i2c_readNak();
433
434 out:
435 i2c_stop();
436 436
437 column_state = ~column_state; 437 column_state = ~column_state;
438 } else { 438 } else {
@@ -476,11 +476,8 @@ static void select_col(uint8_t col)
476 } else { 476 } else {
477 // set active col low : 0 477 // set active col low : 0
478 // set other cols hi-Z : 1 478 // set other cols hi-Z : 1
479 expander_status = i2c_start(I2C_ADDR_WRITE); if (expander_status) goto out; 479 uint8_t port = 0xFF & ~(1<<col);
480 expander_status = i2c_write(EXPANDER_COL_REGISTER); if (expander_status) goto out; 480 expander_status = i2c_writeReg(I2C_ADDR, EXPANDER_COL_REGISTER, &port, 1, I2C_TIMEOUT);
481 expander_status = i2c_write(0xFF & ~(1<<col)); if (expander_status) goto out;
482 out:
483 i2c_stop();
484 } 481 }
485 } else { 482 } else {
486 // select on teensy 483 // select on teensy
diff --git a/keyboards/handwired/dactyl/rules.mk b/keyboards/handwired/dactyl/rules.mk
index cb5690ba7..7e97cb845 100644
--- a/keyboards/handwired/dactyl/rules.mk
+++ b/keyboards/handwired/dactyl/rules.mk
@@ -28,5 +28,5 @@ SLEEP_LED_ENABLE = no
28RGBLIGHT_ENABLE = no 28RGBLIGHT_ENABLE = no
29 29
30# project specific files 30# project specific files
31SRC = twimaster.c \ 31QUANTUM_LIB_SRC += i2c_master.c
32 matrix.c 32SRC += matrix.c
diff --git a/keyboards/handwired/dactyl/twimaster.c b/keyboards/handwired/dactyl/twimaster.c
deleted file mode 100644
index 41684d3a6..000000000
--- a/keyboards/handwired/dactyl/twimaster.c
+++ /dev/null
@@ -1,207 +0,0 @@
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*************************************************************************/
26void 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*************************************************************************/
46unsigned 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*************************************************************************/
82void 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 //if( twst != TW_MT_SLA_ACK) return 1;
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*************************************************************************/
133unsigned 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*************************************************************************/
143void 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*************************************************************************/
161unsigned 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*************************************************************************/
185unsigned 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*************************************************************************/
200unsigned char i2c_readNak(void)
201{
202 TWCR = (1<<TWINT) | (1<<TWEN);
203 while(!(TWCR & (1<<TWINT)));
204
205 return TWDR;
206
207}/* i2c_readNak */