<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="bbPress/1.0.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LeafLabs Garden &#187; Topic: Wire Library Software I2C Implementation Issues</title>
		<link>http://forums.leaflabs.com/topic.php?id=1145</link>
		<description>A place to share, learn, and grow...</description>
		<language>en-US</language>
		<pubDate>Fri, 22 Jan 2016 00:11:18 +0000</pubDate>
		<generator>http://bbpress.org/?v=1.0.2</generator>
		<textInput>
			<title><![CDATA[Search]]></title>
			<description><![CDATA[Search all topics from these forums.]]></description>
			<name>q</name>
			<link>http://forums.leaflabs.com/search.php</link>
		</textInput>
		<atom:link href="http://forums.leaflabs.com/rss.php?topic=1145" rel="self" type="application/rss+xml" />

		<item>
			<title>dfletch on "Wire Library Software I2C Implementation Issues"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1145#post-7077</link>
			<pubDate>Wed, 02 Nov 2011 19:06:52 +0000</pubDate>
			<dc:creator>dfletch</dc:creator>
			<guid isPermaLink="false">7077@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;elstonj,&#60;/p&#62;
&#60;p&#62;This is a really good patch thanks! I still think there are timing issues but the patch is a giant leap forward. The Wire lib from V0.0.12 was giving very odd readings from the last memory address on all three of my sensors the worst being an accelerometer ranging from 0G, 1G and over 2G randomly on the z axis, this has almost gone now, the range is a lot lower! I also read the sensors using an mbed there is no sign of the above issue, thus my comment about further timing issues. Being able to read multiple bytes is also a big step forward or maybe this is what has almost solved my issues. Thanks guys for all your hard work!&#60;/p&#62;
&#60;p&#62;Dave.
&#60;/p&#62;</description>
		</item>
		<item>
			<title>mbolivar on "Wire Library Software I2C Implementation Issues"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1145#post-7073</link>
			<pubDate>Wed, 02 Nov 2011 14:40:38 +0000</pubDate>
			<dc:creator>mbolivar</dc:creator>
			<guid isPermaLink="false">7073@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;Hi elstonj,&#60;/p&#62;
&#60;p&#62;Thanks for the patch!&#60;/p&#62;
&#60;p&#62;However, from the posting guidelines, can you please refrain from posting long code listings/diffs etc. in the forum?&#60;/p&#62;
&#60;p&#62;Also, if you'd like to get this integrated into libmaple, please send us a pull request on GitHub or an email with more details on the patch as explained here:&#60;/p&#62;
&#60;p&#62;&#60;a href=&#34;http://leaflabs.com/docs/libmaple/contributing.html&#34; rel=&#34;nofollow&#34;&#62;http://leaflabs.com/docs/libmaple/contributing.html&#60;/a&#62;
&#60;/p&#62;</description>
		</item>
		<item>
			<title>elstonj on "Wire Library Software I2C Implementation Issues"</title>
			<link>http://forums.leaflabs.com/topic.php?id=1145#post-7057</link>
			<pubDate>Mon, 31 Oct 2011 14:12:41 +0000</pubDate>
			<dc:creator>elstonj</dc:creator>
			<guid isPermaLink="false">7057@http://forums.leaflabs.com/</guid>
			<description>&#60;p&#62;I was having troubles talking to a i2c chip using the current version of libmaple's Wire software I2C implementation (commit as of Oct 20, 2011), and put together this patch that should fix the timing issues I saw, and also implements true multi-byte reads.&#60;/p&#62;
&#60;p&#62;Hopefully this helps someone.&#60;/p&#62;
&#60;p&#62;&#60;code&#62;&#60;br /&#62;
--- Wire/Wire.cpp	2011-10-28 14:25:32.000000000 -0600&#60;br /&#62;
+++ old/Wire/Wire.cpp	2011-10-28 14:12:33.000000000 -0600&#60;br /&#62;
@@ -63,45 +63,48 @@&#60;/p&#62;
&#60;p&#62;     if (!digitalRead(port.sda)) {&#60;br /&#62;
       I2C_DELAY;&#60;br /&#62;
+			digitalWrite(port.sda, LOW);&#60;br /&#62;
       digitalWrite(port.scl,LOW);&#60;br /&#62;
       return true;&#60;br /&#62;
     } else {&#60;br /&#62;
       I2C_DELAY;&#60;br /&#62;
+			digitalWrite(port.sda, LOW);&#60;br /&#62;
       digitalWrite(port.scl,LOW);&#60;br /&#62;
       return false;&#60;br /&#62;
     }&#60;br /&#62;
 }&#60;/p&#62;
&#60;p&#62; void i2c_send_ack(Port port) {&#60;br /&#62;
-    I2C_DELAY;&#60;br /&#62;
     digitalWrite(port.sda,LOW);&#60;br /&#62;
-    I2C_DELAY;&#60;br /&#62;
     digitalWrite(port.scl,HIGH);&#60;br /&#62;
     I2C_DELAY;&#60;br /&#62;
     digitalWrite(port.scl,LOW);&#60;br /&#62;
 }&#60;/p&#62;
&#60;p&#62; void i2c_send_nack(Port port) {&#60;br /&#62;
-    I2C_DELAY;&#60;br /&#62;
     digitalWrite(port.sda,HIGH);&#60;br /&#62;
-    I2C_DELAY;&#60;br /&#62;
     digitalWrite(port.scl,HIGH);&#60;br /&#62;
+    I2C_DELAY;&#60;br /&#62;
+    digitalWrite(port.scl,LOW);&#60;br /&#62;
+    digitalWrite(port.sda,LOW);&#60;br /&#62;
 }&#60;/p&#62;
&#60;p&#62; uint8 i2c_shift_in(Port port) {&#60;br /&#62;
-    uint8 data = 0;&#60;br /&#62;
-&#60;br /&#62;
-    int i;&#60;br /&#62;
-    for (i=0;i&#38;lt;8;i++) {&#60;br /&#62;
-        I2C_DELAY;&#60;br /&#62;
-        digitalWrite(port.scl,HIGH);&#60;br /&#62;
-        I2C_DELAY;&#60;br /&#62;
-        data += digitalRead(port.sda) &#38;lt;&#38;lt; (7-i);&#60;br /&#62;
-        I2C_DELAY;&#60;br /&#62;
-        digitalWrite(port.scl,LOW);&#60;br /&#62;
-    }&#60;br /&#62;
-&#60;br /&#62;
-    return data;&#60;br /&#62;
+	char x = 0;&#60;br /&#62;
+	uint8 data = 0;&#60;br /&#62;
+	digitalWrite(port.sda,HIGH);&#60;br /&#62;
+	for(x=0; x&#38;lt;8; x++) {&#60;br /&#62;
+		data &#38;lt;&#38;lt;= 1;&#60;br /&#62;
+		do {&#60;br /&#62;
+			digitalWrite(port.scl,HIGH);&#60;br /&#62;
+		}&#60;br /&#62;
+		while((digitalRead(port.scl))==0); // wait for any SCL clock stretching&#60;br /&#62;
+		I2C_DELAY;&#60;br /&#62;
+		if((digitalRead(port.sda))) data &#124;= 1;&#60;br /&#62;
+		digitalWrite(port.scl,LOW);&#60;br /&#62;
+		I2C_DELAY;&#60;br /&#62;
+	}&#60;br /&#62;
+	return data;&#60;br /&#62;
 }&#60;/p&#62;
&#60;p&#62; void i2c_shift_out(Port port, uint8 val) {&#60;br /&#62;
@@ -110,9 +113,9 @@&#60;br /&#62;
         I2C_DELAY;&#60;br /&#62;
         digitalWrite(port.sda, !!(val &#38;amp; (1 &#38;lt;&#38;lt; (7 - i))));&#60;br /&#62;
         I2C_DELAY;&#60;br /&#62;
-        digitalWrite(port.scl, HIGH);&#60;br /&#62;
+        digitalWrite(port.scl,HIGH);&#60;br /&#62;
         I2C_DELAY;&#60;br /&#62;
-        digitalWrite(port.scl, LOW);&#60;br /&#62;
+        digitalWrite(port.scl,LOW);&#60;br /&#62;
     }&#60;br /&#62;
 }&#60;/p&#62;
&#60;p&#62;@@ -161,16 +164,18 @@&#60;br /&#62;
 uint8 TwoWire::endTransmission(void) {&#60;br /&#62;
     if (tx_buf_overflow) return EDATA;&#60;/p&#62;
&#60;p&#62;-    i2c_start(port);&#60;br /&#62;
+		if(tx_buf_idx &#38;gt; 0) {&#60;br /&#62;
+			i2c_start(port);&#60;/p&#62;
&#60;p&#62;-    i2c_shift_out(port, (tx_addr &#38;lt;&#38;lt; 1) &#124; I2C_WRITE);&#60;br /&#62;
-    if (!i2c_get_ack(port)) return ENACKADDR;&#60;br /&#62;
+			i2c_shift_out(port, (tx_addr &#38;lt;&#38;lt; 1) &#124; I2C_WRITE);&#60;br /&#62;
+			if (!i2c_get_ack(port)) return ENACKADDR;&#60;/p&#62;
&#60;p&#62;-    // shift out the address we're transmitting to&#60;br /&#62;
-    for (uint8 i = 0; i &#38;lt; tx_buf_idx; i++) {&#60;br /&#62;
-        uint8 ret = writeOneByte(tx_buf[i]);&#60;br /&#62;
-        if (ret) return ret;    // SUCCESS is 0&#60;br /&#62;
-    }&#60;br /&#62;
+			// shift out the address we're transmitting to&#60;br /&#62;
+			for (uint8 i = 0; i &#38;lt; tx_buf_idx; i++) {&#60;br /&#62;
+				uint8 ret = writeOneByte(tx_buf[i]);&#60;br /&#62;
+				if (ret) return ret;    // SUCCESS is 0&#60;br /&#62;
+			}&#60;br /&#62;
+		}&#60;/p&#62;
&#60;p&#62;     i2c_stop(port);&#60;/p&#62;
&#60;p&#62;@@ -179,7 +184,7 @@&#60;br /&#62;
     return SUCCESS;&#60;br /&#62;
 }&#60;/p&#62;
&#60;p&#62;-uint8 TwoWire::requestFrom(uint8 address, int num_bytes) {&#60;br /&#62;
+/*uint8 TwoWire::requestFrom(uint8 address, int num_bytes) {&#60;br /&#62;
     if (num_bytes &#38;gt; WIRE_BUFSIZ) num_bytes = WIRE_BUFSIZ;&#60;/p&#62;
&#60;p&#62;     rx_buf_idx = 0;&#60;br /&#62;
@@ -189,6 +194,33 @@&#60;br /&#62;
         else break;&#60;br /&#62;
     }&#60;br /&#62;
     return rx_buf_len;&#60;br /&#62;
+}*/&#60;br /&#62;
+&#60;br /&#62;
+uint8 TwoWire::requestFrom(uint8 address, int num_bytes) {&#60;br /&#62;
+    if (num_bytes &#38;gt; WIRE_BUFSIZ) num_bytes = WIRE_BUFSIZ;&#60;br /&#62;
+&#60;br /&#62;
+    rx_buf_idx = 0;&#60;br /&#62;
+    rx_buf_len = 0;&#60;br /&#62;
+&#60;br /&#62;
+    i2c_start(port);&#60;br /&#62;
+&#60;br /&#62;
+    i2c_shift_out(port, (address &#38;lt;&#38;lt; 1) &#124; I2C_READ);&#60;br /&#62;
+    if (!i2c_get_ack(port)) return ENACKADDR;&#60;br /&#62;
+&#60;br /&#62;
+		while (rx_buf_len &#38;lt; num_bytes) {&#60;br /&#62;
+			i2c_start(port);&#60;br /&#62;
+&#60;br /&#62;
+			rx_buf[rx_buf_len++] = i2c_shift_in(port);&#60;br /&#62;
+			if(rx_buf_len == num_bytes)&#60;br /&#62;
+				i2c_send_nack(port);&#60;br /&#62;
+			else&#60;br /&#62;
+				i2c_send_ack(port);&#60;br /&#62;
+&#60;br /&#62;
+		}&#60;br /&#62;
+&#60;br /&#62;
+    i2c_stop(port);&#60;br /&#62;
+&#60;br /&#62;
+    return rx_buf_len;&#60;br /&#62;
 }&#60;/p&#62;
&#60;p&#62; uint8 TwoWire::requestFrom(int address, int numBytes) {&#60;br /&#62;
&#60;/code&#62;
&#60;/p&#62;</description>
		</item>

	</channel>
</rss>
