diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_i2c.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_i2c.c
index 368adf3c4e51db81c1a4760bd4a282a4b909a38d..7748962c3f12530595b6664d64e3a712c9a9993e 100644
--- a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_i2c.c
+++ b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_i2c.c
@@ -1,10 +1,13 @@
 #include "hw_impl_zybo.h"
 #include "iic_utils.h"
+#include "xiicps.h"
 
 #define IO_CLK_CONTROL_REG_ADDR	(0xF800012C)
 
 int XIicPs_MasterSendPolled_ours(XIicPs *InstancePtr, u8 *MsgPtr,
 				 int ByteCount, u16 SlaveAddr);
+int XIicPs_MasterRecvPolled_ours(XIicPs *InstancePtr, u8 *MsgPtr,
+				int ByteCount, u16 SlaveAddr);
 int XIicPs_SetupMaster(XIicPs *InstancePtr, int Role);
 
 int zybo_i2c_reset(struct I2CDriver *self) {
@@ -55,6 +58,7 @@ int zybo_i2c_write(struct I2CDriver *self,
 	  // Put it back to 400kHz
 	  XIicPs_SetSClk(inst, 400000);
   }
+  usleep(5);
   return error;
 }
 
@@ -67,11 +71,12 @@ int zybo_i2c_read(struct I2CDriver *self,
 	  // If we are sending a request to optical flow, drop down to 100kHz
 	  XIicPs_SetSClk(inst, 100000);
   }
-  int error = XIicPs_MasterRecvPolled(inst, buff, length, device_addr);
+  int error = XIicPs_MasterRecvPolled_ours(inst, buff, length, device_addr);
   if (device_addr == PX4FLOW_DEVICE_ADDR) {
 	  // Put it back to 400kHz
 	  XIicPs_SetSClk(inst, 400000);
   }
+  usleep(5);
   return error;
 }
 
@@ -188,6 +193,176 @@ int XIicPs_MasterSendPolled_ours(XIicPs *InstancePtr, u8 *MsgPtr,
 	return XST_SUCCESS;
 }
 
+/*****************************************************************************/
+/**
+* This function initiates a polled mode receive in master mode.
+*
+* It repeatedly sets the transfer size register so the slave can
+* send data to us. It polls the data register for data to come in.
+* If slave fails to send us data, it fails with time out.
+*
+* @param	InstancePtr is a pointer to the XIicPs instance.
+* @param	MsgPtr is the pointer to the receive buffer.
+* @param	ByteCount is the number of bytes to be received.
+* @param	SlaveAddr is the address of the slave we are receiving from.
+*
+* @return
+*		- XST_SUCCESS if everything went well.
+*		- XST_FAILURE if timed out.
+*
+* @note		This receive routine is for polled mode transfer only.
+*
+****************************************************************************/
+int XIicPs_MasterRecvPolled_ours(XIicPs *InstancePtr, u8 *MsgPtr,
+				int ByteCount, u16 SlaveAddr)
+{
+	u32 IntrStatusReg;
+	u32 Intrs;
+	u32 StatusReg;
+	u32 BaseAddr;
+	int BytesToRecv;
+	int BytesToRead;
+	int TransSize;
+	int Tmp;
+
+	/*
+	 * Assert validates the input arguments.
+	 */
+	Xil_AssertNonvoid(InstancePtr != NULL);
+	Xil_AssertNonvoid(MsgPtr != NULL);
+	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
+	Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr);
+
+	BaseAddr = InstancePtr->Config.BaseAddress;
+	InstancePtr->RecvBufferPtr = MsgPtr;
+	InstancePtr->RecvByteCount = ByteCount;
+
+	XIicPs_SetupMaster(InstancePtr, RECVING_ROLE);
+
+	XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr);
+
+	/*
+	 * Intrs keeps all the error-related interrupts.
+	 */
+	Intrs = XIICPS_IXR_ARB_LOST_MASK | XIICPS_IXR_RX_OVR_MASK |
+			XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_TO_MASK |
+			XIICPS_IXR_NACK_MASK;
+
+	/*
+	 * Clear the interrupt status register before use it to monitor.
+	 */
+	IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
+	XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);
+
+	/*
+	 * Set up the transfer size register so the slave knows how much
+	 * to send to us.
+	 */
+	if (ByteCount > XIICPS_FIFO_DEPTH) {
+		XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
+			 XIICPS_FIFO_DEPTH);
+	}else {
+		XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET,
+			 ByteCount);
+	}
+
+	/*
+	 * Pull the interrupt status register to find the errors.
+	 */
+	IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
+	while ((InstancePtr->RecvByteCount > 0) &&
+			((IntrStatusReg & Intrs) == 0) && !(IntrStatusReg & XIICPS_IXR_COMP_MASK)) {
+		StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET);
+
+		/*
+		 * If there is no data in the FIFO, check the interrupt
+		 * status register for error, and continue.
+		 */
+		if ((StatusReg & XIICPS_SR_RXDV_MASK) == 0) {
+			IntrStatusReg = XIicPs_ReadReg(BaseAddr,
+					XIICPS_ISR_OFFSET);
+			continue;
+		}
+
+		/*
+		 * The transfer size register shows how much more data slave
+		 * needs to send to us.
+		 */
+		TransSize = XIicPs_ReadReg(BaseAddr,
+		XIICPS_TRANS_SIZE_OFFSET);
+
+		BytesToRead = InstancePtr->RecvByteCount;
+
+		/*
+		 * If expected number of bytes is greater than FIFO size,
+		 * the master needs to wait for data comes in and set the
+		 * transfer size register for slave to send more.
+		 */
+		if (InstancePtr->RecvByteCount > XIICPS_FIFO_DEPTH) {
+			/* wait slave to send data */
+			while ((TransSize > 2) &&
+				((IntrStatusReg & Intrs) == 0)) {
+				TransSize = XIicPs_ReadReg(BaseAddr,
+						XIICPS_TRANS_SIZE_OFFSET);
+				IntrStatusReg = XIicPs_ReadReg(BaseAddr,
+							XIICPS_ISR_OFFSET);
+			}
+
+			/*
+			 * If timeout happened, it is an error.
+			 */
+			if (IntrStatusReg & XIICPS_IXR_TO_MASK) {
+				return XST_FAILURE;
+			}
+			TransSize = XIicPs_ReadReg(BaseAddr,
+						XIICPS_TRANS_SIZE_OFFSET);
+
+			/*
+			 * Take trans size into account of how many more should
+			 * be received.
+			 */
+			BytesToRecv = InstancePtr->RecvByteCount -
+					XIICPS_FIFO_DEPTH + TransSize;
+
+			/* Tell slave to send more to us */
+			if (BytesToRecv > XIICPS_FIFO_DEPTH) {
+				XIicPs_WriteReg(BaseAddr,
+					XIICPS_TRANS_SIZE_OFFSET,
+					XIICPS_FIFO_DEPTH);
+			} else{
+				XIicPs_WriteReg(BaseAddr,
+					XIICPS_TRANS_SIZE_OFFSET, BytesToRecv);
+			}
+
+			BytesToRead = XIICPS_FIFO_DEPTH - TransSize;
+		}
+
+		Tmp = 0;
+		IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);
+		while ((Tmp < BytesToRead) &&
+				((IntrStatusReg & Intrs) == 0)) {
+			StatusReg = XIicPs_ReadReg(BaseAddr,
+					XIICPS_SR_OFFSET);
+			IntrStatusReg = XIicPs_ReadReg(BaseAddr,
+					XIICPS_ISR_OFFSET);
+
+			if ((StatusReg & XIICPS_SR_RXDV_MASK) == 0) {
+				/* No data in fifo */
+				continue;
+			}
+			XIicPs_RecvByte(InstancePtr);
+			Tmp ++;
+		}
+	}
+
+	if ((IntrStatusReg & Intrs) || InstancePtr->RecvByteCount > 0) {
+		return XST_FAILURE;
+	}
+
+	return XST_SUCCESS;
+}
+
+
 /*****************************************************************************/
 /*
 * NOTE to MicroCART: This function is required by the send polling method above,
diff --git a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_tests.c b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_tests.c
index 0d669fb66a69ed1898314e6a3a31970d40528155..eb0597de8277eb2d2e1bd327c4ac739e8fe9e0fb 100644
--- a/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_tests.c
+++ b/quad/xsdk_workspace/real_quad/src/hw_impl_zybo_tests.c
@@ -119,14 +119,30 @@ int test_zybo_i2c_all() {
   if (iic0_mpu9150_start()) return 0;
   if (iic0_lidarlite_init()) return 0;
 
+  int lidarErrors = 0;
+  int gamErrors = 0;
+  int nLoops = 0;
+  int of_errors = 0;
+
   for(;;) {
     unsigned int delay = 5;
 
     sys.sleep(&sys, delay * 1000);
 
-    iic0_px4flow_update(&of, delay / 1000.);
+    if (iic0_px4flow_update(&of, delay / 1000.)) {
+    	of_errors += 1;
+    }
+
     iic0_mpu9150_read_gam(&gam);
     iic0_lidarlite_read_distance(&lidar);
+
+    if (lidar.distance_cm > 5000) {
+    	lidarErrors += 1;
+    }
+    if (gam.accel_z > -0.8) {
+    	gamErrors += 1;
+    }
+    nLoops += 1;
   }
   return 0;
 }