+ if (I2C_TEST_START(i2c->flags) == I2C_START_W)
+ {
+ ticks_t start = timer_clock();
+ while (true)
+ {
+ i2c_hw_restart(i2c);
+
+ uint8_t status = HWREG(i2c->hw->base + I2C_STAT_OFF);
+
+ /* Start status ok, set addres and the R/W bit */
+ if ((status == I2C_STAT_SEND) || (status == I2C_STAT_RESEND))
+ HWREG(i2c->hw->base + I2C_DAT_OFF) = slave_addr & ~I2C_READBIT;
+
+ /* Clear the start bit and clear the SI bit */
+ HWREG(i2c->hw->base + I2C_CONCLR_OFF) = BV(I2CON_SIC) | BV(I2CON_STAC);
+
+ if (status == I2C_STAT_SLAW_ACK)
+ break;
+
+ if (status == I2C_STAT_ARB_LOST)
+ {
+ LOG_ERR("Arbitration lost\n");
+ i2c->errors |= I2C_ARB_LOST;
+ i2c_hw_stop(i2c);
+ }
+
+ if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
+ {
+ LOG_ERR("Timeout on I2C START\n");
+ i2c->errors |= I2C_NO_ACK;
+ i2c_hw_stop(i2c);
+ break;
+ }
+ }
+ }
+ else if (I2C_TEST_START(i2c->flags) == I2C_START_R)
+ {
+ i2c_hw_restart(i2c);
+
+ uint8_t status = HWREG(i2c->hw->base + I2C_STAT_OFF);
+
+ /* Start status ok, set addres and the R/W bit */
+ if ((status == I2C_STAT_SEND) || (status == I2C_STAT_RESEND))
+ HWREG(i2c->hw->base + I2C_DAT_OFF) = slave_addr | I2C_READBIT;
+
+ /* Clear the start bit and clear the SI bit */
+ HWREG(i2c->hw->base + I2C_CONCLR_OFF) = BV(I2CON_SIC) | BV(I2CON_STAC);
+
+ WAIT_SI(i2c);
+
+ status = HWREG(i2c->hw->base + I2C_STAT_OFF);
+
+ if (status == I2C_STAT_SLAR_NACK)
+ {
+ LOG_ERR("SLAR NACK:%02x\n", status);
+ i2c->errors |= I2C_NO_ACK;
+ i2c_hw_stop(i2c);
+ }
+
+ if (status == I2C_STAT_ARB_LOST)
+ {
+ LOG_ERR("Arbitration lost\n");
+ i2c->errors |= I2C_ARB_LOST;
+ i2c_hw_stop(i2c);
+ }
+ }
+ else
+ {
+ ASSERT(0);
+ }