I am seeing an extra, unexpected, I2C cycle on Teensy 3.1. I expect two cycles:
I've included both a test program below and screen shot from my scope. This test is an access to an accelerometer chip where we continue the cycle, however I also see the same behavior when accessing a temperature chip (tmp102) where we do not continue the cycle.
View attachment 1657
- Write Register Address: 2 bytes [I2C device address + Write] + [device register address]
- Read Register Data: 2 bytes [I2C device address + Read] + [data from device]
I've included both a test program below and screen shot from my scope. This test is an access to an accelerometer chip where we continue the cycle, however I also see the same behavior when accessing a temperature chip (tmp102) where we do not continue the cycle.
Code:
/*
* Teensy I2C Wire Library test program
*
* Execute a very simple I2C operation for verification using an oscilloscope
*
* This test program reads the ID ("Who Am I") register in a MMA8452 accelerometer
* chip. The I2C access of this register consists of writing the ID register
* address to the chip and then performing an I2C read to get the value.
*
*/
#include <Wire.h>
// I2C address of the accelerometer
#define MMA8452_ADDRESS 0x1D
// Accelerometer ID Register address
#define ID_REG_ADDR 0x0D
// Expected ID Register value
#define ACCEL_ID 0x2A
void setup() {
uint8_t regVal;
Serial.begin(115200);
Wire.begin();
delay(5000); // Allow the user to open the serial monitor & trigger the scope
// Execute one access to the acceleromter to read the ID Register
if (ReadAccelReg(MMA8452_ADDRESS, ID_REG_ADDR, ®Val)) {
if (regVal == ACCEL_ID) {
Serial.println("Successfully read ID Register");
} else {
Serial.printf("Got unexpected value from ID register: 0x%x\n", regVal);
}
} else {
Serial.println("Register access failed");
}
}
void loop() {
}
/* *****************************************************************************
* ReadAccelReg - Read a register in a MMA8452 accelerometer
*
* On entry: a contains the I2C address of the accelerometer
* reg contains the address of the register to read
* *d contains a pointer to a uint8_t variable to receive the register value
*
* On exit: *d may be updated with the register value
**************************************************************************** */
boolean ReadAccelReg(uint8_t a, uint8_t reg, uint8_t* d) {
uint8_t n, s;
// Reset the register pointer
Wire.beginTransmission(a);
n = Wire.write(reg);
s = Wire.endTransmission(false); // Do not release the bus for the subsequent read
if (n != 1) {
Wire.endTransmission(true); // Force release of the bus
return false;
} else if (s != 0) {
Wire.endTransmission(true);
return false;
}
// Read the register value
n = Wire.requestFrom(a, (uint8_t) 1);
s = Wire.endTransmission();
if (n != 1) {
return false;
} else if (s != 0) {
return false;
}
// Success: finally get the data
*d = Wire.read();
return true;
}
View attachment 1657