MAXREFDES117# Code Documentation  V01.00
Heart Rate / SpO2 Monitor
 All Data Structures Files Functions Variables Typedefs Macros Pages
SoftI2CMaster.h
Go to the documentation of this file.
1 /* Arduino SoftI2C library.
2  *
3  * This is a very fast and very light-weight software I2C-master library
4  * written in assembler. It is based on Peter Fleury's I2C software
5  * library: http://homepage.hispeed.ch/peterfleury/avr-software.html
6  *
7  *
8  * This Library is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This Library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with the Arduino I2cMaster Library. If not, see
20  * <http://www.gnu.org/licenses/>.
21  */
22 
23 /* In order to use the library, you need to define SDA_PIN, SCL_PIN,
24  * SDA_PORT and SCL_PORT before including this file. Have a look at
25  * http://www.arduino.cc/en/Reference/PortManipulation for finding out
26  * which values to use. For example, if you use digital pin 3 (corresponding
27  * to PD3) for SDA and digital pin 13 (corresponding to PB5)
28  * for SCL on a standard Arduino,
29  * you have to use the following definitions:
30  * #define SDA_PIN 3
31  * #define SDA_PORT PORTD
32  * #define SCL_PIN 5
33  * #define SCL_PORT PORTB
34  *
35  * You can also define the following constants (see also below):
36  * - I2C_CPUFREQ, when changing CPU clock frequency dynamically
37  * - I2C_FASTMODE = 1 meaning that the I2C bus allows speeds up to 400 kHz
38  * - I2C_SLOWMODE = 1 meaning that the I2C bus will allow only up to 25 kHz
39  * - I2C_NOINTERRUPT = 1 in order to prohibit interrupts while
40  * communicating (see below). This can be useful if you use the library
41  * for communicationg with SMbus devices, which have timeouts.
42  * Note, however, that interrupts are disabled from issuing a start condition
43  * until issuing a stop condition. So use this option with care!
44  * - I2C_TIMEOUT = 0..10000 mssec in order to return from the I2C functions
45  * in case of a I2C bus lockup (i.e., SCL constantly low). 0 means no timeout
46  */
47 
48 /* Changelog:
49  * Version 1.1:
50  * - removed I2C_CLOCK_STRETCHING
51  * - added I2C_TIMEOUT time in msec (0..10000) until timeout or 0 if no timeout
52  * - changed i2c_init to return true iff both SDA and SCL are high
53  * - changed interrupt disabling so that the previous IRQ state is restored
54  * Version 1.0: basic functionality
55  */
56 
57 #ifndef SOFTI2CMASTER_H_
58 
59 #define SOFTI2DMASTER_H_
60 
61 #include <avr/io.h>
62 #include <Arduino.h>
63 
64 #if defined(ARDUINO_AVR_FLORA8) || defined(ARDUINO_AVR_LILYPAD_USB)
65 #define SDA_PORT PORTD
66 #define SDA_PIN 1
67 #define SCL_PORT PORTD
68 #define SCL_PIN 0
69 #endif
70 
71 #ifdef ARDUINO_AVR_UNO
72 #define SDA_PORT PORTC
73 #define SDA_PIN 4
74 #define SCL_PORT PORTC
75 #define SCL_PIN 5
76 #endif
77 
78 #define I2C_TIMEOUT 100
79 #define I2C_NOINTERRUPT 0
80 #define I2C_SLOWMODE 1
81 #define FAC 1
82 #define I2C_CPUFREQ (F_CPU/FAC)
83 
84 #ifndef _SOFTI2C_H
85 #define _SOFTI2C_H 1
86 
87 // Init function. Needs to be called once in the beginning.
88 // Returns false if SDA or SCL are low, which probably means
89 // a I2C bus lockup or that the lines are not pulled up.
90 boolean __attribute__ ((noinline)) i2c_init(void);
91 
92 // Start transfer function: <addr> is the 8-bit I2C address (including the R/W
93 // bit).
94 // Return: true if the slave replies with an "acknowledge", false otherwise
95 bool __attribute__ ((noinline)) i2c_start(uint8_t addr);
96 
97 // Similar to start function, but wait for an ACK! Be careful, this can
98 // result in an infinite loop!
99 void __attribute__ ((noinline)) i2c_start_wait(uint8_t addr);
100 
101 // Repeated start function: After having claimed the bus with a start condition,
102 // you can address another or the same chip again without an intervening
103 // stop condition.
104 // Return: true if the slave replies with an "acknowledge", false otherwise
105 bool __attribute__ ((noinline)) i2c_rep_start(uint8_t addr);
106 
107 // Issue a stop condition, freeing the bus.
108 void __attribute__ ((noinline)) i2c_stop(void) asm("ass_i2c_stop");
109 
110 // Write one byte to the slave chip that had been addressed
111 // by the previous start call. <value> is the byte to be sent.
112 // Return: true if the slave replies with an "acknowledge", false otherwise
113 bool __attribute__ ((noinline)) i2c_write(uint8_t value) asm("ass_i2c_write");
114 
115 // Read one byte. If <last> is true, we send a NAK after having received
116 // the byte in order to terminate the read sequence.
117 uint8_t __attribute__ ((noinline)) i2c_read(bool last);
118 
119 // You can set I2C_CPUFREQ independently of F_CPU if you
120 // change the CPU frequency on the fly. If you do not define it,
121 // it will use the value of F_CPU
122 #ifndef I2C_CPUFREQ
123 #define I2C_CPUFREQ F_CPU
124 #endif
125 
126 // If I2C_FASTMODE is set to 1, then the highest possible frequency below 400kHz
127 // is selected. Be aware that not all slave chips may be able to deal with that!
128 #ifndef I2C_FASTMODE
129 #define I2C_FASTMODE 0
130 #endif
131 
132 // If I2C_FASTMODE is not defined or defined to be 0, then you can set
133 // I2C_SLOWMODE to 1. In this case, the I2C frequency will not be higher
134 // than 25KHz. This could be useful for problematic buses.
135 #ifndef I2C_SLOWMODE
136 #define I2C_SLOWMODE 0
137 #endif
138 
139 // if I2C_NOINTERRUPT is 1, then the I2C routines are not interruptable.
140 // This is most probably only necessary if you are using a 1MHz system clock,
141 // you are communicating with a SMBus device, and you want to avoid timeouts.
142 // Be aware that the interrupt bit is enabled after each call. So the
143 // I2C functions should not be called in interrupt routines or critical regions.
144 #ifndef I2C_NOINTERRUPT
145 #define I2C_NOINTERRUPT 0
146 #endif
147 
148 // I2C_TIMEOUT can be set to a value between 1 and 10000.
149 // If it is defined and nonzero, it leads to a timeout if the
150 // SCL is low longer than I2C_TIMEOUT milliseconds, i.e., max timeout is 10 sec
151 #ifndef I2C_TIMEOUT
152 #define I2C_TIMEOUT 0
153 #else
154 #if I2C_TIMEOUT > 10000
155 #error I2C_TIMEOUT is too large
156 #endif
157 #endif
158 
159 #define I2C_TIMEOUT_DELAY_LOOPS (I2C_CPUFREQ/1000UL)*I2C_TIMEOUT/4000UL
160 #if I2C_TIMEOUT_DELAY_LOOPS < 1
161 #define I2C_MAX_STRETCH 1
162 #else
163 #if I2C_TIMEOUT_DELAY_LOOPS > 60000UL
164 #define I2C_MAX_STRETCH 60000UL
165 #else
166 #define I2C_MAX_STRETCH I2C_TIMEOUT_DELAY_LOOPS
167 #endif
168 #endif
169 
170 #if I2C_FASTMODE
171 #define I2C_DELAY_COUNTER (((I2C_CPUFREQ/400000L)/2-19)/3)
172 #else
173 #if I2C_SLOWMODE
174 #define I2C_DELAY_COUNTER (((I2C_CPUFREQ/25000L)/2-19)/3)
175 #else
176 #define I2C_DELAY_COUNTER (((I2C_CPUFREQ/100000L)/2-19)/3)
177 #endif
178 #endif
179 
180 // Table of I2C bus speed in kbit/sec:
181 // CPU clock: 1MHz 2MHz 4MHz 8MHz 16MHz 20MHz
182 // Fast I2C mode 40 80 150 300 400 400
183 // Standard I2C mode 40 80 100 100 100 100
184 // Slow I2C mode 25 25 25 25 25 25
185 
186 // constants for reading & writing
187 #define I2C_READ 1
188 #define I2C_WRITE 0
189 
190 // map the IO register back into the IO address space
191 #define SDA_DDR (_SFR_IO_ADDR(SDA_PORT) - 1)
192 #define SCL_DDR (_SFR_IO_ADDR(SCL_PORT) - 1)
193 #define SDA_OUT _SFR_IO_ADDR(SDA_PORT)
194 #define SCL_OUT _SFR_IO_ADDR(SCL_PORT)
195 #define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2)
196 #define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2)
197 
198 #ifndef __tmp_reg__
199 #define __tmp_reg__ 0
200 #endif
201 
202 
203 // Internal delay functions.
204 void __attribute__ ((noinline)) i2c_delay_half(void) asm("ass_i2c_delay_half");
205 void __attribute__ ((noinline)) i2c_wait_scl_high(void) asm("ass_i2c_wait_scl_high");
206 
207 void i2c_delay_half(void)
208 { // function call 3 cycles => 3C
209 #if I2C_DELAY_COUNTER < 1
210  __asm__ __volatile__ (" ret");
211  // 7 cycles for call and return
212 #else
213  __asm__ __volatile__
214  (
215  " ldi r25, %[DELAY] ;load delay constant ;; 4C \n\t"
216  "_Lidelay: \n\t"
217  " dec r25 ;decrement counter ;; 4C+xC \n\t"
218  " brne _Lidelay ;;5C+(x-1)2C+xC\n\t"
219  " ret ;; 9C+(x-1)2C+xC = 7C+xC"
220  : : [DELAY] "M" I2C_DELAY_COUNTER : "r25");
221  // 7 cycles + 3 times x cycles
222 #endif
223 }
224 
226 {
227 #if I2C_TIMEOUT <= 0
228  __asm__ __volatile__
229  ("_Li2c_wait_stretch: \n\t"
230  " sbis %[SCLIN],%[SCLPIN] ;wait for SCL high \n\t"
231  " rjmp _Li2c_wait_stretch \n\t"
232  " cln ;signal: no timeout \n\t"
233  " ret "
234  : : [SCLIN] "I" (SCL_IN), [SCLPIN] "I" (SCL_PIN));
235 #else
236  __asm__ __volatile__
237  ( " ldi r27, %[HISTRETCH] ;load delay counter \n\t"
238  " ldi r26, %[LOSTRETCH] \n\t"
239  "_Lwait_stretch: \n\t"
240  " clr __tmp_reg__ ;do next loop 255 times \n\t"
241  "_Lwait_stretch_inner_loop: \n\t"
242  " rcall _Lcheck_scl_level ;call check function ;; 12C \n\t"
243  " brpl _Lstretch_done ;done if N=0 ;; +1 = 13C\n\t"
244  " dec __tmp_reg__ ;dec inner loop counter;; +1 = 14C\n\t"
245  " brne _Lwait_stretch_inner_loop ;; +2 = 16C\n\t"
246  " sbiw r26,1 ;dec outer loop counter \n\t"
247  " brne _Lwait_stretch ;continue with outer loop \n\t"
248  " sen ;timeout -> set N-bit=1 \n\t"
249  " rjmp _Lwait_return ;and return with N=1\n\t"
250  "_Lstretch_done: ;SCL=1 sensed \n\t"
251  " cln ;OK -> clear N-bit \n\t"
252  " rjmp _Lwait_return ; and return with N=0 \n\t"
253 
254  "_Lcheck_scl_level: ;; call = 3C\n\t"
255  " cln ;; +1C = 4C \n\t"
256  " sbic %[SCLIN],%[SCLPIN] ;skip if SCL still low ;; +2C = 6C \n\t"
257  " rjmp _Lscl_high ;; +0C = 6C \n\t"
258  " sen ;; +1 = 7C\n\t "
259  "_Lscl_high: "
260  " nop ;; +1C = 8C \n\t"
261  " ret ;return N-Bit=1 if low ;; +4 = 12C\n\t"
262 
263  "_Lwait_return:"
264  : : [SCLIN] "I" (SCL_IN), [SCLPIN] "I" (SCL_PIN),
265  [HISTRETCH] "M" (I2C_MAX_STRETCH>>8),
266  [LOSTRETCH] "M" (I2C_MAX_STRETCH&0xFF)
267  : "r26", "r27");
268 #endif
269 }
270 
271 
272 boolean i2c_init(void)
273 {
274  __asm__ __volatile__
275  (" cbi %[SDADDR],%[SDAPIN] ;release SDA \n\t"
276  " cbi %[SCLDDR],%[SCLPIN] ;release SCL \n\t"
277  " cbi %[SDAOUT],%[SDAPIN] ;clear SDA output value \n\t"
278  " cbi %[SCLOUT],%[SCLPIN] ;clear SCL output value \n\t"
279  " clr r24 ;set return value to false \n\t"
280  " clr r25 ;set return value to false \n\t"
281  " sbis %[SDAIN],%[SDAPIN] ;check for SDA high\n\t"
282  " ret ;if low return with false \n\t"
283  " sbis %[SCLIN],%[SCLPIN] ;check for SCL high \n\t"
284  " ret ;if low return with false \n\t"
285  " ldi r24,1 ;set return value to true \n\t"
286  " ret "
287  : :
288  [SCLDDR] "I" (SCL_DDR), [SCLPIN] "I" (SCL_PIN),
289  [SCLIN] "I" (SCL_IN), [SCLOUT] "I" (SCL_OUT),
290  [SDADDR] "I" (SDA_DDR), [SDAPIN] "I" (SDA_PIN),
291  [SDAIN] "I" (SDA_IN), [SDAOUT] "I" (SDA_OUT));
292  return true;
293 }
294 
295 bool i2c_start(uint8_t addr)
296 {
297  __asm__ __volatile__
298  (
299 #if I2C_NOINTERRUPT
300  " cli ;clear IRQ bit \n\t"
301 #endif
302  " sbis %[SCLIN],%[SCLPIN] ;check for clock stretching slave\n\t"
303  " rcall ass_i2c_wait_scl_high ;wait until SCL=H\n\t"
304  " sbi %[SDADDR],%[SDAPIN] ;force SDA low \n\t"
305  " rcall ass_i2c_delay_half ;wait T/2 \n\t"
306  " rcall ass_i2c_write ;now write address \n\t"
307  " ret"
308  : : [SDADDR] "I" (SDA_DDR), [SDAPIN] "I" (SDA_PIN),
309  [SCLIN] "I" (SCL_IN),[SCLPIN] "I" (SCL_PIN));
310  return true; // we never return here!
311 }
312 
313 bool i2c_rep_start(uint8_t addr)
314 {
315  __asm__ __volatile__
316 
317  (
318 #if I2C_NOINTERRUPT
319  " cli \n\t"
320 #endif
321  " sbi %[SCLDDR],%[SCLPIN] ;force SCL low \n\t"
322  " rcall ass_i2c_delay_half ;delay T/2 \n\t"
323  " cbi %[SDADDR],%[SDAPIN] ;release SDA \n\t"
324  " rcall ass_i2c_delay_half ;delay T/2 \n\t"
325  " cbi %[SCLDDR],%[SCLPIN] ;release SCL \n\t"
326  " rcall ass_i2c_delay_half ;delay T/2 \n\t"
327  " sbis %[SCLIN],%[SCLPIN] ;check for clock stretching slave\n\t"
328  " rcall ass_i2c_wait_scl_high ;wait until SCL=H\n\t"
329  " sbi %[SDADDR],%[SDAPIN] ;force SDA low \n\t"
330  " rcall ass_i2c_delay_half ;delay T/2 \n\t"
331  " rcall ass_i2c_write \n\t"
332  " ret"
333  : : [SCLDDR] "I" (SCL_DDR), [SCLPIN] "I" (SCL_PIN),[SCLIN] "I" (SCL_IN),
334  [SDADDR] "I" (SDA_DDR), [SDAPIN] "I" (SDA_PIN));
335  return true; // just to fool the compiler
336 }
337 
338 void i2c_start_wait(uint8_t addr)
339 {
340  __asm__ __volatile__
341  (
342  " push r24 ;save original parameter \n\t"
343  "_Li2c_start_wait1: \n\t"
344  " pop r24 ;restore original parameter\n\t"
345  " push r24 ;and save again \n\t"
346 #if I2C_NOINTERRUPT
347  " cli ;disable interrupts \n\t"
348 #endif
349  " sbis %[SCLIN],%[SCLPIN] ;check for clock stretching slave\n\t"
350  " rcall ass_i2c_wait_scl_high ;wait until SCL=H\n\t"
351  " sbi %[SDADDR],%[SDAPIN] ;force SDA low \n\t"
352  " rcall ass_i2c_delay_half ;delay T/2 \n\t"
353  " rcall ass_i2c_write ;write address \n\t"
354  " tst r24 ;if device not busy -> done \n\t"
355  " brne _Li2c_start_wait_done \n\t"
356  " rcall ass_i2c_stop ;terminate write & enable IRQ \n\t"
357  " rjmp _Li2c_start_wait1 ;device busy, poll ack again \n\t"
358  "_Li2c_start_wait_done: \n\t"
359  " pop __tmp_reg__ ;pop off orig argument \n\t"
360  " ret "
361  : : [SDADDR] "I" (SDA_DDR), [SDAPIN] "I" (SDA_PIN),
362  [SCLIN] "I" (SCL_IN),[SCLPIN] "I" (SCL_PIN));
363 }
364 
365 void i2c_stop(void)
366 {
367  __asm__ __volatile__
368  (
369  " sbi %[SCLDDR],%[SCLPIN] ;force SCL low \n\t"
370  " sbi %[SDADDR],%[SDAPIN] ;force SDA low \n\t"
371  " rcall ass_i2c_delay_half ;T/2 delay \n\t"
372  " cbi %[SCLDDR],%[SCLPIN] ;release SCL \n\t"
373  " rcall ass_i2c_delay_half ;T/2 delay \n\t"
374  " sbis %[SCLIN],%[SCLPIN] ;check for clock stretching slave\n\t"
375  " rcall ass_i2c_wait_scl_high ;wait until SCL=H\n\t"
376  " cbi %[SDADDR],%[SDAPIN] ;release SDA \n\t"
377  " rcall ass_i2c_delay_half \n\t"
378 #if I2C_NOINTERRUPT
379  " sei ;enable interrupts again!\n\t"
380 #endif
381  : : [SCLDDR] "I" (SCL_DDR), [SCLPIN] "I" (SCL_PIN), [SCLIN] "I" (SCL_IN),
382  [SDADDR] "I" (SDA_DDR), [SDAPIN] "I" (SDA_PIN));
383 }
384 
385 bool i2c_write(uint8_t value)
386 {
387  __asm__ __volatile__
388  (
389  " sec ;set carry flag \n\t"
390  " rol r24 ;shift in carry and shift out MSB \n\t"
391  " rjmp _Li2c_write_first \n\t"
392  "_Li2c_write_bit:\n\t"
393  " lsl r24 ;left shift into carry ;; 1C\n\t"
394  "_Li2c_write_first:\n\t"
395  " breq _Li2c_get_ack ;jump if TXreg is empty;; +1 = 2C \n\t"
396  " sbi %[SCLDDR],%[SCLPIN] ;force SCL low ;; +2 = 4C \n\t"
397  " nop \n\t"
398  " nop \n\t"
399  " nop \n\t"
400  " brcc _Li2c_write_low ;;+1/+2=5/6C\n\t"
401  " nop ;; +1 = 7C \n\t"
402  " cbi %[SDADDR],%[SDAPIN] ;release SDA ;; +2 = 9C \n\t"
403  " rjmp _Li2c_write_high ;; +2 = 11C \n\t"
404  "_Li2c_write_low: \n\t"
405  " sbi %[SDADDR],%[SDAPIN] ;force SDA low ;; +2 = 9C \n\t"
406  " rjmp _Li2c_write_high ;;+2 = 11C \n\t"
407  "_Li2c_write_high: \n\t"
408 #if I2C_DELAY_COUNTER >= 1
409  " rcall ass_i2c_delay_half ;delay T/2 ;;+X = 11C+X\n\t"
410 #endif
411  " cbi %[SCLDDR],%[SCLPIN] ;release SCL ;;+2 = 13C+X\n\t"
412  " cln ;clear N-bit ;;+1 = 14C+X\n\t"
413  " nop \n\t"
414  " nop \n\t"
415  " nop \n\t"
416  " sbis %[SCLIN],%[SCLPIN] ;check for SCL high ;;+2 = 16C+X\n\t"
417  " rcall ass_i2c_wait_scl_high \n\t"
418  " brpl _Ldelay_scl_high ;;+2 = 18C+X\n\t"
419  "_Li2c_write_return_false: \n\t"
420  " clr r24 ; return false because of timeout \n\t"
421  " rjmp _Li2c_write_return \n\t"
422  "_Ldelay_scl_high: \n\t"
423 #if I2C_DELAY_COUNTER >= 1
424  " rcall ass_i2c_delay_half ;delay T/2 ;;+X= 18C+2X\n\t"
425 #endif
426  " rjmp _Li2c_write_bit \n\t"
427  " ;; +2 = 20C +2X for one bit-loop \n\t"
428  "_Li2c_get_ack: \n\t"
429  " sbi %[SCLDDR],%[SCLPIN] ;force SCL low ;; +2 = 5C \n\t"
430  " nop \n\t"
431  " nop \n\t"
432  " cbi %[SDADDR],%[SDAPIN] ;release SDA ;;+2 = 7C \n\t"
433 #if I2C_DELAY_COUNTER >= 1
434  " rcall ass_i2c_delay_half ;delay T/2 ;; +X = 7C+X \n\t"
435 #endif
436  " clr r25 ;; 17C+2X \n\t"
437  " clr r24 ;return 0 ;; 14C + X \n\t"
438  " cbi %[SCLDDR],%[SCLPIN] ;release SCL ;; +2 = 9C+X\n\t"
439  "_Li2c_ack_wait: \n\t"
440  " cln ; clear N-bit ;; 10C + X\n\t"
441  " nop \n\t"
442  " sbis %[SCLIN],%[SCLPIN] ;wait SCL high ;; 12C + X \n\t"
443  " rcall ass_i2c_wait_scl_high \n\t"
444  " brmi _Li2c_write_return_false ;; 13C + X \n\t "
445  " sbis %[SDAIN],%[SDAPIN] ;if SDA hi -> return 0 ;; 15C + X \n\t"
446  " ldi r24,1 ;return true ;; 16C + X \n\t"
447 #if I2C_DELAY_COUNTER >= 1
448  " rcall ass_i2c_delay_half ;delay T/2 ;; 16C + 2X \n\t"
449 #endif
450  "_Li2c_write_return: \n\t"
451  " nop \n\t "
452  " nop \n\t "
453  " sbi %[SCLDDR],%[SCLPIN] ;force SCL low so SCL=H is short\n\t"
454  " ret \n\t"
455  " ;; + 4 = 17C + 2X for acknowldge bit"
456  ::
457  [SCLDDR] "I" (SCL_DDR), [SCLPIN] "I" (SCL_PIN), [SCLIN] "I" (SCL_IN),
458  [SDADDR] "I" (SDA_DDR), [SDAPIN] "I" (SDA_PIN), [SDAIN] "I" (SDA_IN));
459  return true; // fooling the compiler
460 }
461 
462 uint8_t i2c_read(bool last)
463 {
464  __asm__ __volatile__
465  (
466  " ldi r23,0x01 \n\t"
467  "_Li2c_read_bit: \n\t"
468  " sbi %[SCLDDR],%[SCLPIN] ;force SCL low ;; 2C \n\t"
469  " cbi %[SDADDR],%[SDAPIN] ;release SDA(prev. ACK);; 4C \n\t"
470  " nop \n\t"
471  " nop \n\t"
472  " nop \n\t"
473 #if I2C_DELAY_COUNTER >= 1
474  " rcall ass_i2c_delay_half ;delay T/2 ;; 4C+X \n\t"
475 #endif
476  " cbi %[SCLDDR],%[SCLPIN] ;release SCL ;; 6C + X \n\t"
477 #if I2C_DELAY_COUNTER >= 1
478  " rcall ass_i2c_delay_half ;delay T/2 ;; 6C + 2X \n\t"
479 #endif
480  " cln ; clear N-bit ;; 7C + 2X \n\t"
481  " nop \n\t "
482  " nop \n\t "
483  " nop \n\t "
484  " sbis %[SCLIN], %[SCLPIN] ;check for SCL high ;; 9C +2X \n\t"
485  " rcall ass_i2c_wait_scl_high \n\t"
486  " brmi _Li2c_read_return ;return if timeout ;; 10C + 2X\n\t"
487  " clc ;clear carry flag ;; 11C + 2X\n\t"
488  " sbic %[SDAIN],%[SDAPIN] ;if SDA is high ;; 11C + 2X\n\t"
489  " sec ;set carry flag ;; 12C + 2X\n\t"
490  " rol r23 ;store bit ;; 13C + 2X\n\t"
491  " brcc _Li2c_read_bit ;while receiv reg not full \n\t"
492  " ;; 15C + 2X for one bit loop \n\t"
493 
494  "_Li2c_put_ack: \n\t"
495  " sbi %[SCLDDR],%[SCLPIN] ;force SCL low ;; 2C \n\t"
496  " cpi r24,0 ;; 3C \n\t"
497  " breq _Li2c_put_ack_low ;if (ack=0) ;; 5C \n\t"
498  " cbi %[SDADDR],%[SDAPIN] ;release SDA \n\t"
499  " rjmp _Li2c_put_ack_high \n\t"
500  "_Li2c_put_ack_low: ;else \n\t"
501  " sbi %[SDADDR],%[SDAPIN] ;force SDA low ;; 7C \n\t"
502  "_Li2c_put_ack_high: \n\t"
503  " nop \n\t "
504  " nop \n\t "
505  " nop \n\t "
506 #if I2C_DELAY_COUNTER >= 1
507  " rcall ass_i2c_delay_half ;delay T/2 ;; 7C + X \n\t"
508 #endif
509  " cbi %[SCLDDR],%[SCLPIN] ;release SCL ;; 9C +X \n\t"
510  " cln ;clear N ;; +1 = 10C\n\t"
511  " nop \n\t "
512  " nop \n\t "
513  " sbis %[SCLIN],%[SCLPIN] ;wait SCL high ;; 12C + X\n\t"
514  " rcall ass_i2c_wait_scl_high \n\t"
515 #if I2C_DELAY_COUNTER >= 1
516  " rcall ass_i2c_delay_half ;delay T/2 ;; 11C + 2X\n\t"
517 #endif
518  "_Li2c_read_return: \n\t"
519  " nop \n\t "
520  " nop \n\t "
521  "sbi %[SCLDDR],%[SCLPIN] ;force SCL low so SCL=H is short\n\t"
522  " mov r24,r23 ;; 12C + 2X \n\t"
523  " clr r25 ;; 13 C + 2X\n\t"
524  " ret ;; 17C + X"
525  ::
526  [SCLDDR] "I" (SCL_DDR), [SCLPIN] "I" (SCL_PIN), [SCLIN] "I" (SCL_IN),
527  [SDADDR] "I" (SDA_DDR), [SDAPIN] "I" (SDA_PIN), [SDAIN] "I" (SDA_IN)
528  );
529  return ' '; // fool the compiler!
530 }
531 
532 #endif
533 
534 
535 #endif