int i2c_bitbang_write_byte(void *v, uint8_t val, int flags, i2c_bitbang_ops_t ops) { uint32_t bit; uint8_t mask; int error; BB_DIR(OUTPUT); for (mask = 0x80; mask != 0; mask >>= 1) { bit = (val & mask) ? SDA : 0; BB_SET(bit ); delay(1); /* data setup time (250 nS) */ BB_SET(bit | SCL); delay(4); /* clock high time (4.0 uS) */ BB_SET(bit ); delay(5); /* clock low time (4.7 uS) */ } BB_DIR(INPUT); BB_SET(SDA ); delay(5); BB_SET(SDA | SCL); delay(4); error = (BB_READ & SDA) ? EIO : 0; BB_SET(SDA ); delay(5); if (flags & I2C_F_STOP) (void) i2c_bitbang_send_stop(v, flags, ops); return (error); }
int i2c_bitbang_read_byte(void *v, uint8_t *valp, int flags, i2c_bitbang_ops_t ops) { int i; uint8_t val = 0; uint32_t bit; BB_DIR(INPUT); BB_SET(SDA ); for (i = 0; i < 8; i++) { val <<= 1; BB_SET(SDA | SCL); if (i2c_wait_for_scl(v, ops) != 0) return (EIO); delay(4); /* clock high time (4.0 uS) */ if (BB_READ & SDA) val |= 1; BB_SET(SDA ); delay(5); /* clock low time (4.7 uS) */ } bit = (flags & I2C_F_LAST) ? SDA : 0; BB_DIR(OUTPUT); BB_SET(bit ); delay(1); /* data setup time (250 nS) */ BB_SET(bit | SCL); if (i2c_wait_for_scl(v, ops) != 0) return (EIO); delay(4); /* clock high time (4.0 uS) */ BB_SET(bit ); delay(5); /* clock low time (4.7 uS) */ BB_DIR(INPUT); BB_SET(SDA ); delay(5); if ((flags & (I2C_F_STOP | I2C_F_LAST)) == (I2C_F_STOP | I2C_F_LAST)) (void) i2c_bitbang_send_stop(v, flags, ops); *valp = val; return (0); }
/*ARGSUSED*/ int i2c_bitbang_send_stop(void *v, int flags, i2c_bitbang_ops_t ops) { BB_DIR(OUTPUT); BB_SET( SCL); delay(4); /* stop setup time (4.0 uS) */ BB_SET(SDA | SCL); return (0); }
/*ARGSUSED*/ int i2c_bitbang_send_start(void *v, int flags, i2c_bitbang_ops_t ops) { BB_DIR(OUTPUT); BB_SET(SDA | SCL); delay(5); /* bus free time (4.7 uS) */ BB_SET( SCL); delay(4); /* start hold time (4.0 uS) */ BB_SET( 0); delay(5); /* clock low time (4.7 uS) */ return (0); }