I got stuck in rewriting this in Wire. Following code is for reading data out of the IQS253 chip. I want adapt the code, so it is then implemented against the Wire library. Can somebody please help me?
unsigned char i2c_read_byte(unsigned char ack)
{
unsigned char i, receive_byte = 0;
I2C_DATA_IN_FLOAT; // Set I2C DATA pin as input and floating
wait(2); // Wait two I2C clock cycles
for (i = 8; i > 0; i--) // Loop and read 8 bits from I2C DATA pin
{
wait(2); // Wait two I2C clock cycles
I2C_CLK_IN_FLOAT; // Set I2C CLK pin as input and floating
while(!I2C_CLK_IN); // Wait for I2C CLK line low (clock stretching)
if (I2C_DATA_IN) receive_byte |= (1 << (i - 1)); //Read data from I2C DATA pin
wait(1); // Wait one I2C clock cycle
I2C_CLK_OUT_PP_LOW; // Set I2C CLK pin as output (push-pull) and floating
}
wait(1); // Wait one I2C clock cycle
if (ack == 0) I2C_DATA_IN_FLOAT; //
else I2C_DATA_OUT_PP_LOW; //Send acknowledge if required
wait(2); // Wait two I2C clock cycles
I2C_CLK_IN_FLOAT; // Set I2C CLK pin as input and floating
while(!I2C_CLK_IN); // Wait for I2C CLK pin low (clock stretching)
wait(2); // Wait two I2C clock cycles
I2C_CLK_OUT_PP_LOW; // Set I2C CLK pin as output (push-pull) and floating
wait(2); // Wait two I2C clock cycles
I2C_DATA_IN_FLOAT; // Set I2C DATA pin as input and floating
return receive_byte;
}
This is more or less what Wire.read()'s function is, although the actual code is part of Wire.requestFrom().
This code is a software implementation of the I2C bus if you don't have hardware support for it. The Wire library uses the hardware support the ATmega family offers.
This is a standard I2C behavior. So it's more or less:
#define DEVICE_ADDRESS 0x47 // just an example, has to be changed for actual device
byte get_register(byte memory_address) {
Wire.beginTransmission(DEVICE_ADDRESS);
Wire.write(memory_address);
Wire.endTransmission();
Wire.requestFrom(DEVICE_ADDRESS, 1);
if (Wire.available() > 0) {
return Wire.read();
}
return 0;
}
The low-level stuff is handled by the Wire library and the underlying hardware. As in your example code control byte is device_address << 1 and here DEVICE_ADDRESS is control byte >> 1, you can directly set the device address (which is 7-bit).
Unfortunately the code does not work. There's always a "0" returning.
Where do I have to write the control bytes?
And how can a repeated start be done?
Unfortunately the code does not work. There's always a "0" returning.
Which one? Mine? That wasn't intended to work, it was just an example. For example the address was just a random number. You have to modify or at least provide a link to the datasheet of your device, so we have a chance to get the necessary information.
Where do I have to write the control bytes?
The control bytes are the address plus read/write bit, so they are in the code already.
And how can a repeated start be done?
Does that mean a start condition without a stop condition? Else you have to define it.
Now it works. I didn't know that read/write bits are set by the library. Another problem was the endTransmission. In Arduino v1.0.1 this method can be called with the false flag. So no stop condition is sent.