static int i2c_start(device_t dev, u_char slave, int timeout) { struct i2c_softc *sc; int error; sc = device_get_softc(dev); i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN); DELAY(10); /* Delay for controller to sample bus state. */ if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) { return (i2c_error_handler(sc, IIC_EBUSERR)); } i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX); if ((error = wait_for_busbusy(sc, true)) != IIC_NOERR) return (i2c_error_handler(sc, error)); i2c_write_reg(sc, I2C_STATUS_REG, 0); i2c_write_reg(sc, I2C_DATA_REG, slave); error = wait_for_xfer(sc, true); return (i2c_error_handler(sc, error)); }
static int i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay) { struct i2c_softc *sc; int error, reg; sc = device_get_softc(dev); *read = 0; if (len) { if (len == 1) i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_TXAK); else i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA); /* Dummy read to prime the receiver. */ i2c_write_reg(sc, I2C_STATUS_REG, 0x0); i2c_read_reg(sc, I2C_DATA_REG); } error = 0; *read = 0; while (*read < len) { if ((error = wait_for_xfer(sc, false)) != IIC_NOERR) break; i2c_write_reg(sc, I2C_STATUS_REG, 0x0); if (last) { if (*read == len - 2) { /* NO ACK on last byte */ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_TXAK); } else if (*read == len - 1) { /* Transfer done, signal stop. */ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK); wait_for_busbusy(sc, false); } } reg = i2c_read_reg(sc, I2C_DATA_REG); *buf++ = reg; (*read)++; } return (i2c_error_handler(sc, error)); }
static int i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout) { struct i2c_softc *sc; int error; sc = device_get_softc(dev); error = 0; *sent = 0; while (*sent < len) { i2c_write_reg(sc, I2C_STATUS_REG, 0x0); i2c_write_reg(sc, I2C_DATA_REG, *buf++); if ((error = wait_for_xfer(sc, true)) != IIC_NOERR) break; (*sent)++; } return (i2c_error_handler(sc, error)); }
static int i2c_repeated_start(device_t dev, u_char slave, int timeout) { struct i2c_softc *sc; int error; sc = device_get_softc(dev); if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) { return (IIC_EBUSERR); } /* * Set repeated start condition, delay (per reference manual, min 156nS) * before writing slave address, wait for ack after write. */ i2c_flag_set(sc, I2C_CONTROL_REG, I2CCR_RSTA); DELAY(1); i2c_write_reg(sc, I2C_STATUS_REG, 0x0); i2c_write_reg(sc, I2C_DATA_REG, slave); error = wait_for_xfer(sc, true); return (i2c_error_handler(sc, error)); }
void i2c2_error_interrupt(void) { i2c_error_handler(I2C2); }