Skip to content

Make Wire library error safe #2489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<echo message="override ${env.JAVA_HOME}/lib/tools.jar" />
<fail />
-->
<javac target="1.5"
<javac target="1.6"
srcdir="src"
destdir="bin"
excludes="**/tools/format/**"
Expand Down
35 changes: 26 additions & 9 deletions libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,45 +51,57 @@ TwoWire::TwoWire()

// Public Methods //////////////////////////////////////////////////////////////

void TwoWire::begin(void)
void TwoWire::begin_timeout(uint32_t default_timeout)
{
rxBufferIndex = 0;
rxBufferLength = 0;

txBufferIndex = 0;
txBufferLength = 0;

twi_init();
twi_init_timeout(default_timeout);
}

void TwoWire::begin(uint8_t address)
{
void TwoWire::begin_timeout(uint8_t address, uint32_t default_timeout){
twi_setAddress(address);
twi_attachSlaveTxEvent(onRequestService);
twi_attachSlaveRxEvent(onReceiveService);
begin();
begin_timeout(default_timeout);
}

void TwoWire::begin(void){
begin_timeout(0);
}

void TwoWire::begin(uint8_t address)
{
begin_timeout(address, 0);
}

void TwoWire::begin(int address)
{
begin((uint8_t)address);
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
uint8_t TwoWire::requestFrom_timeout(uint8_t address, uint8_t quantity, uint8_t sendStop, uint32_t timeout_us)
{
// clamp to buffer length
if(quantity > BUFFER_LENGTH){
quantity = BUFFER_LENGTH;
}
// perform blocking read into buffer
uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
uint8_t read = twi_readFrom_timeout(address, rxBuffer, quantity, sendStop, timeout_us);
// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = read;

return read;
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop){
return requestFrom_timeout(address, quantity, sendStop, 0);
}

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
Expand Down Expand Up @@ -134,10 +146,11 @@ void TwoWire::beginTransmission(int address)
// no call to endTransmission(true) is made. Some I2C
// devices will behave oddly if they do not see a STOP.
//
uint8_t TwoWire::endTransmission(uint8_t sendStop)

uint8_t TwoWire::endTransmission_timeout(uint8_t sendStop, uint32_t timeout_us)
{
// transmit buffer (blocking)
int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
int8_t ret = twi_writeTo_timeout(txAddress, txBuffer, txBufferLength, 1, sendStop, timeout_us);
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
Expand All @@ -146,6 +159,10 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
return ret;
}

uint8_t TwoWire::endTransmission(uint8_t sendStop){
return endTransmission_timeout(sendStop, 0);
}

// This provides backwards compatibility with the original
// definition, and expected behaviour, of endTransmission
//
Expand Down
4 changes: 4 additions & 0 deletions libraries/Wire/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,16 @@ class TwoWire : public Stream
void begin();
void begin(uint8_t);
void begin(int);
void begin_timeout(uint32_t);
void begin_timeout(uint8_t, uint32_t);
void beginTransmission(uint8_t);
void beginTransmission(int);
uint8_t endTransmission(void);
uint8_t endTransmission(uint8_t);
uint8_t endTransmission_timeout(uint8_t, uint32_t);
uint8_t requestFrom(uint8_t, uint8_t);
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
uint8_t requestFrom_timeout(uint8_t, uint8_t, uint8_t, uint32_t);
uint8_t requestFrom(int, int);
uint8_t requestFrom(int, int, int);
virtual size_t write(uint8_t);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// I2C Digital Potentiometer
// by Nicholas Zambetti <http://www.zambetti.com>
// and Shawn Bonkowski <http://people.interaction-ivrea.it/s.bonkowski/>

// Demonstrates use of the Wire library
// Controls AD5171 digital potentiometer via I2C/TWI

// Created 31 March 2006
// Edited 7 december 2014 by Mauro Mombelli

// This example code is in the public domain.

// This example code is in the public domain.


#include <Wire.h>

const unsigned long default_wire_timeout_us = 1000UL;

void setup()
{
Wire.begin_timeout(default_wire_timeout_us); // join i2c bus (address optional for master)
}

byte val = 0;

void loop()
{
Wire.beginTransmission(44); // transmit to device #44 (0x2c)
// device address is specified in datasheet
Wire.write(byte(0x00)); // sends instruction byte
Wire.write(val); // sends potentiometer value byte
Wire.endTransmission_timeout(true, default_wire_timeout_us); // stop transmitting

val++; // increment value
if(val == 64) // if reached 64th position (max)
{
val = 0; // start over from lowest value
}
delay(500);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this

// Created 29 March 2006
// Edited 7 december 2014 by Mauro Mombelli

// This example code is in the public domain.


#include <Wire.h>

const unsigned long default_timeout_us = 1000UL;

void setup()
{
Wire.begin_timeout(default_timeout_us); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}

void loop()
{
Wire.requestFrom_timeout(2, 6, true, default_timeout_us); // request 6 bytes from slave device #2

while(Wire.available()) // slave may send less than requested
{
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}

delay(500);
}
6 changes: 6 additions & 0 deletions libraries/Wire/examples/timeout_slave_receiver/.directory
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[Dolphin]
Timestamp=2014,12,7,15,37,21
Version=3

[Settings]
HiddenFilesShown=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006
// Edited 7 december 2014 by Mauro Mombelli

// This example code is in the public domain.


#include <Wire.h>

const unsigned long default_timeout_us = 1000UL;

void setup()
{
Wire.begin_timeout(4, default_timeout_us); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}

void loop()
{
delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
Loading