We are working on a real soft-i2c implementation compatible with arduino's Wire library. In order to test it, I had to revive some very crufty xl345 breakout board+driver sketch. To make sure the board was still working, I used a very hacked bit banged i2c. I dont recommend using this code, I recommend waiting for the superior i2c implementation on the way. This code is also xl345 specific, and not generic i2c. However, in the event that you are hacking on i2c right now (I know many are!) heres an example sketch that definitely builds and works with the xl345:
#define XL_SCL 6 #define XL_SDA 7 #define XL_READ_ADDR 0xA7 #define XL_WRITE_ADDR 0xA6 #define LED 13 #define BUT 38 void setup() { pinMode(LED,OUTPUT); pinMode(BUT,INPUT); pinMode(XL_SCL,OUTPUT_OPEN_DRAIN); pinMode(XL_SDA,OUTPUT_OPEN_DRAIN); digitalWrite(XL_SCL,HIGH); digitalWrite(XL_SDA,HIGH); /* dont begin until the user hits the button! */ while (digitalRead(BUT) != 1); xl345_init(); } void loop() { digitalWrite(LED,HIGH); delay(100); digitalWrite(LED,LOW); delay(100); SerialUSB.println(xl345_readZ(),DEC); } /******* i2c ********/ static void i2c_delay() { delayMicroseconds(5); } static void i2c_start() { i2c_delay(); digitalWrite(XL_SCL,HIGH); i2c_delay(); digitalWrite(XL_SDA,HIGH); i2c_delay(); digitalWrite(XL_SDA,LOW); i2c_delay(); digitalWrite(XL_SCL,LOW); } static void i2c_stop() { i2c_delay(); digitalWrite(XL_SCL,HIGH); i2c_delay(); digitalWrite(XL_SDA,HIGH); } static void i2c_send_ack() { i2c_delay(); digitalWrite(XL_SDA,LOW); i2c_delay(); digitalWrite(XL_SCL,HIGH); i2c_delay(); digitalWrite(XL_SCL,LOW); } static int i2c_get_ack() { i2c_delay(); digitalWrite(XL_SCL,LOW); i2c_delay(); digitalWrite(XL_SDA,HIGH); i2c_delay(); digitalWrite(XL_SCL,HIGH); for (int i=100;i>0;i--) { if (!digitalRead(XL_SDA)) { i2c_delay(); i2c_delay(); digitalWrite(XL_SCL,LOW); return 1; } } return 0; } static void i2c_send_nack() { i2c_delay(); digitalWrite(XL_SDA,HIGH); i2c_delay(); digitalWrite(XL_SCL,HIGH); } static void i2c_shift_out(uint8 val) { for (int i=0;i<8;i++) { i2c_delay(); digitalWrite(XL_SDA, !!(val & (1 << (7 - i)))); i2c_delay(); digitalWrite(XL_SCL, HIGH); i2c_delay(); digitalWrite(XL_SCL, LOW); } } static uint8 i2c_shift_in() { uint8 data; for (int i=0;i<8;i++) { i2c_delay(); digitalWrite(XL_SCL,HIGH); i2c_delay(); data += digitalRead(XL_SDA) << (7-i); i2c_delay(); digitalWrite(XL_SCL,LOW); } return data; } static void i2c_write(uint8 addr, uint8 val) { /* 1) start 2) dev addr write 3) ack 4) reg addr 5) ack 6) data 7) ack 8) stop */ i2c_start(); i2c_shift_out(XL_WRITE_ADDR); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } i2c_shift_out(addr); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } i2c_shift_out(val); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } i2c_stop(); } static uint8 i2c_read(uint8 addr) { /* 1) start 2) slave addr write 3) ack 4) reg addr 5) ack 6) start 7) slave addr read 8) ack 9) data in 10) nack 11) stop */ uint8 data; i2c_start(); i2c_shift_out(XL_WRITE_ADDR); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } i2c_shift_out(addr); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } i2c_start(); i2c_shift_out(XL_READ_ADDR); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } i2c_delay(); i2c_delay(); i2c_delay(); i2c_delay(); i2c_delay(); data = i2c_shift_in(); i2c_delay(); i2c_delay(); i2c_delay(); i2c_delay(); i2c_delay(); i2c_send_nack(); i2c_stop(); return data; } static uint16 i2c_read16(uint8 addr) { /* 1) start 2) slave addr write 3) ack 4) reg addr 5) ack 6) start 7) slave addr read 8) ack 9) data in 10) ack ... 9) 12) nack 13) stop */ uint16 data; i2c_start(); i2c_shift_out(XL_WRITE_ADDR); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } i2c_shift_out(addr); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } i2c_start(); i2c_shift_out(XL_READ_ADDR); if (!i2c_get_ack()) { SerialUSB.println("Missed i2c ack!"); } data = i2c_shift_in(); i2c_send_ack(); data = i2c_shift_in()<<8; i2c_send_nack(); i2c_stop(); return data; } /******* xl345 ******/ void xl345_init() { i2c_write(0x2C,0x0A); i2c_write(0x2D,0x08); i2c_write(0x31,0x04); } static uint8 xl345_readX() { int8 val = (int8)i2c_read(0x33); val += 128; return (uint8) val; } static uint8 xl345_readY() { int8 val = (int8)i2c_read(0x35); val += 128; return (uint8) val; } static uint8 xl345_readZ() { int8 val = (int8)i2c_read(0x37); val += 128; return (uint8) val; }