New LiquidCrystal library: /Users/fmalpartida/Documents/development/mercurial repos/SW/NewliquidCrystal/SoftI2CMaster.h Source File

New LiquidCrystal library 1.3.2 Generic LCD control library

- Main Page
- Related Pages
- Classes
- Files

- File List

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