+ if (!start_and_addr(i2c, slave_addr))
+ return;
+ /*
+ * Due to the hardware receive bytes from slave in automatically mode
+ * we should manage contextually all cases that we want to read one, two or more
+ * than two bytes. To comply this behaviour to our api we shoul bufferd some byte
+ * to hide all special case that needs to use this device.
+ */
+ if (i2c->xfer_size == 1)
+ {
+ i2c->hw->base->CR1 &= CR1_ACK_RESET;
+
+ cpu_flags_t irq;
+
+ IRQ_SAVE_DISABLE(irq);
+ (void)i2c->hw->base->SR2;
+ if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
+ i2c->hw->base->CR1 |= CR1_STOP_SET;
+ IRQ_RESTORE(irq);
+
+ WAIT_RXNE(i2c->hw->base);
+
+ i2c->hw->cache[0] = i2c->hw->base->DR;
+ i2c->hw->cached = true;
+
+ if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
+ while (i2c->hw->base->CR1 & CR1_STOP_SET);
+
+ i2c->hw->base->CR1 |= CR1_ACK_SET;
+ }
+ else if (i2c->xfer_size == 2)
+ {
+ cpu_flags_t irq;
+
+ IRQ_SAVE_DISABLE(irq);
+ (void)i2c->hw->base->SR2;
+ i2c->hw->base->CR1 &= CR1_ACK_RESET;
+ IRQ_RESTORE(irq);
+
+ WAIT_BTF(i2c->hw->base);
+
+ IRQ_SAVE_DISABLE(irq);
+ if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
+ i2c->hw->base->CR1 |= CR1_STOP_SET;
+ /*
+ * We store read bytes like a fifo..
+ */
+ i2c->hw->cache[1] = i2c->hw->base->DR;
+ i2c->hw->cache[0] = i2c->hw->base->DR;
+ i2c->hw->cached = true;
+ IRQ_RESTORE(irq);
+
+ i2c->hw->base->CR1 &= CR1_POS_RESET;
+ i2c->hw->base->CR1 |= CR1_ACK_SET;
+ }