add Rf link quality checks
[openXsensor.git] / openXsensor / I2C.cpp
blobf5c8d8dc4f10b8e204d613c2ad009ccdb1e12b1e
1 // Modified for use in the openXsensor code by Mike B.
3 /*
4 I2C.cpp - I2C library
5 Copyright (c) 2011-2012 Wayne Truchsess. All right reserved.
6 Rev 5.0 - January 24th, 2012
7 - Removed the use of interrupts completely from the library
8 so TWI state changes are now polled.
9 - Added calls to lockup() function in most functions
10 to combat arbitration problems
11 - Fixed scan() procedure which left timeouts enabled
12 and set to 80msec after exiting procedure
13 - Changed scan() address range back to 0 - 0x7F
14 - Removed all Wire legacy functions from library
15 - A big thanks to Richard Baldwin for all the testing
16 and feedback with debugging bus lockups!
17 Rev 4.0 - January 14th, 2012
18 - Updated to make compatible with 8MHz clock frequency
19 Rev 3.0 - January 9th, 2012
20 - Modified library to be compatible with Arduino 1.0
21 - Changed argument type from boolean to uint8_t in pullUp(),
22 setSpeed() and receiveByte() functions for 1.0 compatability
23 - Modified return values for timeout feature to report
24 back where in the transmission the timeout occured.
25 - added function scan() to perform a bus scan to find devices
26 attached to the I2C bus. Similar to work done by Todbot
27 and Nick Gammon
28 Rev 2.0 - September 19th, 2011
29 - Added support for timeout function to prevent
30 and recover from bus lockup (thanks to PaulS
31 and CrossRoads on the Arduino forum)
32 - Changed return type for stop() from void to
33 uint8_t to handle timeOut function
34 Rev 1.0 - August 8th, 2011
36 This is a modified version of the Arduino Wire/TWI
37 library. Functions were rewritten to provide more functionality
38 and also the use of Repeated Start. Some I2C devices will not
39 function correctly without the use of a Repeated Start. The
40 initial version of this library only supports the Master.
43 This library is free software; you can redistribute it and/or
44 modify it under the terms of the GNU Lesser General Public
45 License as published by the Free Software Foundation; either
46 version 2.1 of the License, or (at your option) any later version.
48 This library is distributed in the hope that it will be useful,
49 but WITHOUT ANY WARRANTY; without even the implied warranty of
50 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
51 Lesser General Public License for more details.
53 You should have received a copy of the GNU Lesser General Public
54 License along with this library; if not, write to the Free Software
55 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
58 #if(ARDUINO >= 100)
59 #include <Arduino.h>
60 #else
61 #include <WProgram.h>
62 #endif
64 #include <inttypes.h>
65 #include "I2C.h"
69 uint8_t I2C::bytesAvailable = 0;
70 uint8_t I2C::bufferIndex = 0;
71 uint8_t I2C::totalBytes = 0;
72 uint16_t I2C::timeOutDelay = 0;
74 I2C::I2C()
79 ////////////// Public Methods ////////////////////////////////////////
83 void I2C::begin()
85 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
86 // activate internal pull-ups for twi
87 // as per note from atmega8 manual pg167
88 // with modules like GY-63 there is no need for pull-up because the module have already pull-up resistor
89 // it is safier not to activate internal pull-up when Arduino is running 5 volt and external sensors are running 3.3 volt
90 // sbi(PORTC, 4);
91 // sbi(PORTC, 5);
92 #else
93 // activate internal pull-ups for twi
94 // as per note from atmega128 manual pg204
95 // sbi(PORTD, 0);
96 // sbi(PORTD, 1);
97 #endif
98 // initialize twi prescaler and bit rate
99 cbi(TWSR, TWPS0);
100 cbi(TWSR, TWPS1);
101 TWBR = ((F_CPU / 400000) - 16) / 2; //use 100khz ; for 400khz use TWBR = ((F_CPU / 400000) - 16) / 2;
102 // enable twi module and acks
103 TWCR = _BV(TWEN) | _BV(TWEA);
106 void I2C::end()
108 TWCR = 0;
111 void I2C::timeOut(uint16_t _timeOut)
113 timeOutDelay = _timeOut;
116 void I2C::setSpeed(uint8_t _fast)
118 if(!_fast)
120 TWBR = ((F_CPU / 100000) - 16) / 2;
122 else
124 TWBR = ((F_CPU / 400000) - 16) / 2;
128 void I2C::pullup(uint8_t activate)
130 if(activate)
132 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
133 // activate internal pull-ups for twi
134 // as per note from atmega8 manual pg167
135 sbi(PORTC, 4);
136 sbi(PORTC, 5);
137 #else
138 // activate internal pull-ups for twi
139 // as per note from atmega128 manual pg204
140 sbi(PORTD, 0);
141 sbi(PORTD, 1);
142 #endif
144 else
146 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
147 // deactivate internal pull-ups for twi
148 // as per note from atmega8 manual pg167
149 cbi(PORTC, 4);
150 cbi(PORTC, 5);
151 #else
152 // deactivate internal pull-ups for twi
153 // as per note from atmega128 manual pg204
154 cbi(PORTD, 0);
155 cbi(PORTD, 1);
156 #endif
161 void I2C::scan()
163 uint16_t tempTime = timeOutDelay;
164 timeOut(80);
165 uint8_t totalDevicesFound = 0;
166 scanAdr = 0 ;
167 // Serial.println("Scanning for devices...please wait");
168 // Serial.println();
169 for(uint8_t s = 0; s <= 0x7F; s++)
171 returnStatus = 0;
172 returnStatus = start();
173 if(!returnStatus)
175 returnStatus = sendAddress(SLA_W(s));
177 if(returnStatus)
179 if(returnStatus == 1)
181 // Serial.println("There is a problem with the bus, could not complete scan");
182 timeOutDelay = tempTime;
183 return;
186 else
188 // Serial.print("Found device at address - ");
189 // Serial.print(" 0x");
190 // Serial.println(s,HEX);
191 // if( scanAdr == 0)
192 scanAdr = s ;
194 totalDevicesFound++;
196 stop();
198 // if(!totalDevicesFound){Serial.println("No devices found");}
199 timeOutDelay = tempTime;
203 uint8_t I2C::available()
205 return(bytesAvailable);
208 uint8_t I2C::receive()
210 bufferIndex = totalBytes - bytesAvailable;
211 if(!bytesAvailable)
213 bufferIndex = 0;
214 return(0);
216 bytesAvailable--;
217 return(data[bufferIndex]);
221 /*return values for new functions that use the timeOut feature
222 will now return at what point in the transmission the timeout
223 occurred. Looking at a full communication sequence between a
224 master and slave (transmit data and then readback data) there
225 a total of 7 points in the sequence where a timeout can occur.
226 These are listed below and correspond to the returned value:
227 1 - Waiting for successful completion of a Start bit
228 2 - Waiting for ACK/NACK while addressing slave in transmit mode (MT)
229 3 - Waiting for ACK/NACK while sending data to the slave
230 4 - Waiting for successful completion of a Repeated Start
231 5 - Waiting for ACK/NACK while addressing slave in receiver mode (MR)
232 6 - Waiting for ACK/NACK while receiving data from the slave
233 7 - Waiting for successful completion of the Stop bit
235 All possible return values:
236 0 Function executed with no errors
237 1 - 7 Timeout occurred, see above list
238 8 - 0xFF See datasheet for exact meaning */
241 /////////////////////////////////////////////////////
243 uint8_t I2C::write(uint8_t address, uint8_t registerAddress)
245 returnStatus = 0;
246 returnStatus = start();
247 if(returnStatus){
248 return(returnStatus);
250 returnStatus = sendAddress(SLA_W(address));
251 if(returnStatus)
253 if(returnStatus == 1){return(2);}
254 return(returnStatus);
256 returnStatus = sendByte(registerAddress);
257 if(returnStatus)
259 if(returnStatus == 1){return(3);}
260 return(returnStatus);
262 returnStatus = stop();
263 if(returnStatus)
265 if(returnStatus == 1){return(7);}
266 return(returnStatus);
268 return(returnStatus);
271 //uint8_t I2C::write(int address, int registerAddress)
273 // return(write((uint8_t) address, (uint8_t) registerAddress));
276 uint8_t I2C::write(uint8_t address, uint8_t registerAddress, uint8_t data)
278 returnStatus = 0;
279 returnStatus = start();
280 if(returnStatus){
281 return(returnStatus);
283 returnStatus = sendAddress(SLA_W(address));
284 if(returnStatus)
286 if(returnStatus == 1){
287 return(2);
289 return(returnStatus);
291 returnStatus = sendByte(registerAddress);
292 if(returnStatus)
294 if(returnStatus == 1){
295 return(3);
297 return(returnStatus);
299 returnStatus = sendByte(data);
300 if(returnStatus)
302 if(returnStatus == 1){
303 return(3);
305 return(returnStatus);
307 returnStatus = stop();
308 if(returnStatus)
310 if(returnStatus == 1){
311 return(7);
313 return(returnStatus);
315 return(returnStatus);
318 //uint8_t I2C::write(int address, int registerAddress, int data)
320 // return(write((uint8_t) address, (uint8_t) registerAddress, (uint8_t) data));
323 uint8_t I2C::write(uint8_t address, uint8_t registerAddress, char *data)
325 uint8_t bufferLength = strlen(data);
326 returnStatus = 0;
327 returnStatus = write(address, registerAddress, bufferLength ,(uint8_t*)data );
328 return(returnStatus);
331 uint8_t I2C::write(uint8_t address, uint8_t registerAddress, uint8_t numberBytes , uint8_t * data )
333 returnStatus = 0;
334 returnStatus = start();
335 if(returnStatus){
336 return(returnStatus);
338 returnStatus = sendAddress(SLA_W(address));
339 if(returnStatus)
341 if(returnStatus == 1){
342 return(2);
344 return(returnStatus);
346 returnStatus = sendByte(registerAddress);
347 if(returnStatus)
349 if(returnStatus == 1){return(3);}
350 return(returnStatus);
352 for (uint8_t i = 0; i < numberBytes; i++)
354 returnStatus = sendByte(data[i]);
355 if(returnStatus)
357 if(returnStatus == 1){
358 return(3);
360 return(returnStatus);
363 returnStatus = stop();
364 if(returnStatus)
366 if(returnStatus == 1){
367 return(7);
369 return(returnStatus);
371 return(returnStatus);
375 // Read a device whitout sending first the register to be read; code modified in order to allow that number of byte = 0 (needed for sensor 4525DO)
376 // return a status (0 = OK, others see above)
377 uint8_t I2C::read(uint8_t address, uint8_t numberBytes)
379 bytesAvailable = 0;
380 bufferIndex = 0;
381 // if(numberBytes == 0){numberBytes++;}
382 // nack = numberBytes - 1;
383 returnStatus = 0;
384 returnStatus = start();
385 if(returnStatus){
386 return(returnStatus);
388 returnStatus = sendAddress(SLA_R(address));
389 if(returnStatus)
391 if(returnStatus == 1){
392 return(5);
394 return(returnStatus);
396 if(numberBytes > 0){
397 nack = numberBytes - 1;
398 for(uint8_t i = 0; i < numberBytes; i++)
400 if( i == nack )
402 returnStatus = receiveByte(0);
403 if(returnStatus == 1){
404 return(6);
406 if(returnStatus != MR_DATA_NACK){
407 return(returnStatus);
410 else
412 returnStatus = receiveByte(1);
413 if(returnStatus == 1){
414 return(6);
416 if(returnStatus != MR_DATA_ACK){
417 return(returnStatus);
420 data[i] = TWDR;
421 bytesAvailable = i+1;
422 totalBytes = i+1;
425 returnStatus = stop();
426 if(returnStatus)
428 if(returnStatus == 1){
429 return(7);
431 return(returnStatus);
433 return(returnStatus);
436 // read a device after sending a command (= register address)
437 // return a status (0 = OK, others see above)
438 uint8_t I2C::read(uint8_t address, uint8_t registerAddress, uint8_t numberBytes)
440 bytesAvailable = 0;
441 bufferIndex = 0;
442 if(numberBytes == 0){numberBytes++;}
443 nack = numberBytes - 1;
444 returnStatus = 0;
445 returnStatus = start();
446 if(returnStatus){
447 return(returnStatus);
449 returnStatus = sendAddress(SLA_W(address));
450 if(returnStatus)
452 if(returnStatus == 1){
453 return(2);
455 return(returnStatus);
457 returnStatus = sendByte(registerAddress);
458 if(returnStatus)
460 if(returnStatus == 1){
461 return(3);
463 return(returnStatus);
465 returnStatus = start();
466 if(returnStatus)
468 if(returnStatus == 1){
469 return(4);
471 return(returnStatus);
473 returnStatus = sendAddress(SLA_R(address));
474 if(returnStatus)
476 if(returnStatus == 1){return(5);}
477 return(returnStatus);
479 for(uint8_t i = 0; i < numberBytes; i++)
481 if( i == nack )
483 returnStatus = receiveByte(0);
484 if(returnStatus == 1){
485 return(6);
487 if(returnStatus != MR_DATA_NACK){
488 return(returnStatus);
491 else
493 returnStatus = receiveByte(1);
494 if(returnStatus == 1){
495 return(6);
497 if(returnStatus != MR_DATA_ACK){
498 return(returnStatus);
501 data[i] = TWDR;
502 bytesAvailable = i+1;
503 totalBytes = i+1;
505 returnStatus = stop();
506 if(returnStatus)
508 if(returnStatus == 1){
509 return(7);
511 return(returnStatus);
513 return(returnStatus);
516 // Read a number of bytes in a specified buffer without sending first a register address
517 // return a status (0 = OK, others see above)
518 uint8_t I2C::read(uint8_t address, uint8_t numberBytes, uint8_t *dataBuffer)
520 bytesAvailable = 0;
521 bufferIndex = 0;
522 // if(numberBytes == 0){numberBytes++;}
523 // nack = numberBytes - 1;
524 returnStatus = 0;
525 returnStatus = start();
526 if(returnStatus){return(returnStatus);}
527 returnStatus = sendAddress(SLA_R(address));
528 if(returnStatus)
530 if(returnStatus == 1){return(5);}
531 return(returnStatus);
533 if(numberBytes > 0) {
534 nack = numberBytes - 1;
535 for(uint8_t i = 0; i < numberBytes; i++)
537 if( i == nack )
539 returnStatus = receiveByte(0);
540 if(returnStatus == 1){
541 return(6);
543 if(returnStatus != MR_DATA_NACK){
544 return(returnStatus);
547 else
549 returnStatus = receiveByte(1);
550 if(returnStatus == 1){
551 return(6);
553 if(returnStatus != MR_DATA_ACK){
554 return(returnStatus);
557 dataBuffer[i] = TWDR;
558 bytesAvailable = i+1;
559 totalBytes = i+1;
562 returnStatus = stop();
563 if(returnStatus)
565 if(returnStatus == 1){
566 return(7);
568 return(returnStatus);
570 return(returnStatus);
574 // Read a number of bytes in a specified buffer after sending a register address
575 // this version is currently not used in openXsensor so it is in comment
576 uint8_t I2C::read(uint8_t address, uint8_t registerAddress, uint8_t numberBytes, uint8_t *dataBuffer)
578 bytesAvailable = 0;
579 bufferIndex = 0;
580 if(numberBytes == 0){numberBytes++;}
581 nack = numberBytes - 1;
582 returnStatus = 0;
583 returnStatus = start();
584 if(returnStatus){
585 return(returnStatus);
587 returnStatus = sendAddress(SLA_W(address));
588 if(returnStatus)
590 if(returnStatus == 1){
591 return(2);
593 return(returnStatus);
595 returnStatus = sendByte(registerAddress);
596 if(returnStatus)
598 if(returnStatus == 1){
599 return(3);
601 return(returnStatus);
603 returnStatus = start();
604 if(returnStatus)
606 if(returnStatus == 1){
607 return(4);
609 return(returnStatus);
611 returnStatus = sendAddress(SLA_R(address));
612 if(returnStatus)
614 if(returnStatus == 1){
615 return(5);
617 return(returnStatus);
619 for(uint8_t i = 0; i < numberBytes; i++)
621 if( i == nack )
623 returnStatus = receiveByte(0);
624 if(returnStatus == 1){
625 return(6);
627 if(returnStatus != MR_DATA_NACK){
628 return(returnStatus);
631 else
633 returnStatus = receiveByte(1);
634 if(returnStatus == 1){
635 return(6);
637 if(returnStatus != MR_DATA_ACK){
638 return(returnStatus);
641 dataBuffer[i] = TWDR;
642 bytesAvailable = i+1;
643 totalBytes = i+1;
645 returnStatus = stop();
646 if(returnStatus)
648 if(returnStatus == 1){
649 return(7);
651 return(returnStatus);
653 return(returnStatus);
657 /////////////// Private Methods ////////////////////////////////////////
660 uint8_t I2C::start()
662 unsigned long startingTime = millis();
663 TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
664 while (!(TWCR & (1<<TWINT)))
666 if(!timeOutDelay){continue;}
667 if((millis() - startingTime) >= timeOutDelay)
669 lockUp();
670 return(1);
674 if ((TWI_STATUS == START) || (TWI_STATUS == REPEATED_START))
676 return(0);
678 if (TWI_STATUS == LOST_ARBTRTN)
680 uint8_t bufferedStatus = TWI_STATUS;
681 lockUp();
682 return(bufferedStatus);
684 return(TWI_STATUS);
687 uint8_t I2C::sendAddress(uint8_t i2cAddress)
689 TWDR = i2cAddress;
690 unsigned long startingTime = millis();
691 TWCR = (1<<TWINT) | (1<<TWEN);
692 while (!(TWCR & (1<<TWINT)))
694 if(!timeOutDelay){continue;}
695 if((millis() - startingTime) >= timeOutDelay)
697 lockUp();
698 return(1);
702 if ((TWI_STATUS == MT_SLA_ACK) || (TWI_STATUS == MR_SLA_ACK))
704 return(0);
706 uint8_t bufferedStatus = TWI_STATUS;
707 if ((TWI_STATUS == MT_SLA_NACK) || (TWI_STATUS == MR_SLA_NACK))
709 stop();
710 return(bufferedStatus);
712 else
714 lockUp();
715 return(bufferedStatus);
719 uint8_t I2C::sendByte(uint8_t i2cData)
721 TWDR = i2cData;
722 unsigned long startingTime = millis();
723 TWCR = (1<<TWINT) | (1<<TWEN);
724 while (!(TWCR & (1<<TWINT)))
726 if(!timeOutDelay){continue;}
727 if((millis() - startingTime) >= timeOutDelay)
729 lockUp();
730 return(1);
734 if (TWI_STATUS == MT_DATA_ACK)
736 return(0);
738 uint8_t bufferedStatus = TWI_STATUS;
739 if (TWI_STATUS == MT_DATA_NACK)
741 stop();
742 return(bufferedStatus);
744 else
746 lockUp();
747 return(bufferedStatus);
751 uint8_t I2C::receiveByte(uint8_t ack)
753 unsigned long startingTime = millis();
754 if(ack)
756 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
759 else
761 TWCR = (1<<TWINT) | (1<<TWEN);
763 while (!(TWCR & (1<<TWINT)))
765 if(!timeOutDelay){continue;}
766 if((millis() - startingTime) >= timeOutDelay)
768 lockUp();
769 return(1);
772 if (TWI_STATUS == LOST_ARBTRTN)
774 uint8_t bufferedStatus = TWI_STATUS;
775 lockUp();
776 return(bufferedStatus);
778 return(TWI_STATUS);
781 uint8_t I2C::stop()
783 unsigned long startingTime = millis();
784 TWCR = (1<<TWINT)|(1<<TWEN)| (1<<TWSTO);
785 while ((TWCR & (1<<TWSTO)))
787 if(!timeOutDelay){continue;}
788 if((millis() - startingTime) >= timeOutDelay)
790 lockUp();
791 return(1);
795 return(0);
798 void I2C::lockUp()
800 TWCR = 0; //releases SDA and SCL lines to high impedance
801 TWCR = _BV(TWEN) | _BV(TWEA); //reinitialize TWI
804 I2C I2c = I2C();