From 6c67c97fadd6bcc63f734cd058f091663bcd07f3 Mon Sep 17 00:00:00 2001
From: Jonathan BAUDIN <jonathan.baudin@atmel.com>
Date: Mon, 2 Jun 2014 16:23:26 +0200
Subject: [PATCH]  Fix Wire bug. First bytes not read.

---
 cores/arduino/RingBuffer.cpp               |  2 +-
 cores/arduino/SERCOM.cpp                   |  6 ++---
 cores/validation/validation_chuck/test.cpp | 26 +++++++++++-----------
 libraries/Wire/Wire.cpp                    | 22 +++++++++++++-----
 4 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/cores/arduino/RingBuffer.cpp b/cores/arduino/RingBuffer.cpp
index ba9522ce..92d82098 100644
--- a/cores/arduino/RingBuffer.cpp
+++ b/cores/arduino/RingBuffer.cpp
@@ -51,7 +51,7 @@ int RingBuffer::read_char()
 	if(_iTail == _iHead)
 		return -1;
 
-	int value = _aucBuffer[_iTail];
+	uint8_t value = _aucBuffer[_iTail];
 	_iTail = nextIndex(_iTail);
 
 	return value;
diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp
index f14f8584..31fc51aa 100644
--- a/cores/arduino/SERCOM.cpp
+++ b/cores/arduino/SERCOM.cpp
@@ -448,7 +448,7 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
     }
 
     // Clean the 'Slave on Bus' flag, for further usage.
-    sercom->I2CM.INTFLAG.bit.SB = 0x1ul;
+    //sercom->I2CM.INTFLAG.bit.SB = 0x1ul;
   }
 
 
@@ -550,9 +550,9 @@ uint8_t SERCOM::readDataWIRE( void )
 {
   if(isMasterWIRE())
   {
-    while( sercom->I2CM.INTFLAG.bit.SB == 0 || sercom->I2CM.STATUS.bit.CLKHOLD == 0 )
+    while( sercom->I2CM.INTFLAG.bit.SB == 0 )
     {
-      // Waiting complete receive, Clock holding & synchronization finished
+      // Waiting complete receive
     }
 
     return sercom->I2CM.DATA.bit.DATA ;
diff --git a/cores/validation/validation_chuck/test.cpp b/cores/validation/validation_chuck/test.cpp
index e6e3fd4d..9e5698eb 100644
--- a/cores/validation/validation_chuck/test.cpp
+++ b/cores/validation/validation_chuck/test.cpp
@@ -1,15 +1,12 @@
+#include <Arduino.h>
 #include <Wire.h>
-#include "nunchuck_funcs.h"
 
-int loop_cnt=0 ;
-
-byte accx,accy,zbut,cbut ;
-int ledPin = 13 ;
+uint8_t accx,accy,zbut,cbut ;
 
 void setup()
 {
   Serial5.begin( 115200 ) ;
-  Serial5.println("nunchuck_init");
+  Serial5.println("nunchuk init");
   
   Wire.begin(); // join i2c bus as master
   Wire.beginTransmission(0x52);// transmit to device 0x52
@@ -17,17 +14,16 @@ void setup()
     Wire.write((uint8_t)0x00);// sends sent a zero.
   Wire.endTransmission();// stop transmitting
 
-  Serial5.println( "WiiChuckDemo ready" ) ;
-  delay(3000);
+  Serial5.println( "WiiChukDemo ready" ) ;
+  delay(100);
 }
 
 void loop()
 {
   Wire.requestFrom(0x52, 6);
-
   
-  uint8_t jX = Wire.read();
-  uint8_t jY = Wire.read();
+  uint8_t jX =   Wire.read();
+  uint8_t jY =   Wire.read();
   uint8_t accX = Wire.read();
   uint8_t accY = Wire.read();
   uint8_t accZ = Wire.read();
@@ -46,6 +42,10 @@ void loop()
   Serial5.print(accZ);
   
   Serial5.print("\tBtn : ");
+  Serial5.print(" [");
+  Serial5.print(misc);
+  Serial5.print("] ");
+
   switch(misc & 0x3ul)
   {
     case 0x0ul:
@@ -67,11 +67,11 @@ void loop()
     default:
       break;
   }
-
   
   Wire.beginTransmission(0x52);// transmit to device 0x52
-    Wire.write((uint8_t)0x00);// sends sent a zero.
+  Wire.write((uint8_t)0x00);// sends sent a zero.
   Wire.endTransmission();// stop transmitting
 
   delay(100);
+
 }
diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp
index 9ab0d25a..7b92a534 100644
--- a/libraries/Wire/Wire.cpp
+++ b/libraries/Wire/Wire.cpp
@@ -50,18 +50,28 @@ void TwoWire::begin(uint8_t address) {
 
 uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit)
 { 
-  size_t toRead = quantity + 1;
+  if(quantity == 0)
+  {
+    return 0;
+  }
+
+
+  size_t byteRead = 0;
 
   if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG))
   {
+  
+    // Read first data
+    rxBuffer.store_char(sercom->readDataWIRE());
+
     // Connected to slave
-    while(toRead--)
-    //for(toRead = quantity; toRead >= 0; --toRead)
+    //while(toRead--)
+    for(byteRead = 0; byteRead < quantity; ++byteRead)
     {
-      if( toRead == 0)  // Stop transmission
+      if( byteRead == quantity - 1)  // Stop transmission
       {
         sercom->prepareNackBitWIRE(); // Prepare NACK to stop slave transmission
-        sercom->readDataWIRE(); // Clear data register to send NACK
+        //sercom->readDataWIRE(); // Clear data register to send NACK
         sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); // Send Stop 
       }
       else // Continue transmission
@@ -73,7 +83,7 @@ uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit)
     }
   }
 
-  return quantity - toRead;
+  return byteRead;
 }
 
 uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity)
-- 
GitLab