Blackaddr
Well-known member
I've been working on improving my BAGuitar library, and doing additional testing. I had some odd results I didn't expect. Perhaps someone might have some insight.
I'm using teensyduinio 1.40.
FIRST ISSUE:
I use the default I2C configuration to configure my codec. I noticed that on my T3.2, I can send transactions to the I2C and never see a failure. If I switch to my T3.6, I see random failures where Wire.endTransmission() returns errors. The errors on the T3.6 occur even at 10Khz. As a work around, I modified my write command to loop and keep retrying until it succeeds.
It's almost like the library when operating on the T3.6 is not checking a done flag correctly on the peripheral and corrupts a transfer that is in progress. This happens both on the default Wire.h library and the i2c_t3.h library.
SECOND ISSUE:
I was calling Wire.begin() in a class constructor that was being declared as a global, so the class would be constructed before the sketch setup() gets called. With the default Wire.h library, things generally work fine. However, when I switch to the i2c_t3.h, it would hang the system before ever getting to setup(). I had to move the call to Wire.begin() out of the constructor and into a member function I call in setup().
I presume there is something about the i2c_t3 library that when setting up the peripheral, it is not yet ready and a hang occurs. Is calling begin() on the peripherals in a global instance constructor generally a bad idea?
I'm using teensyduinio 1.40.
FIRST ISSUE:
I use the default I2C configuration to configure my codec. I noticed that on my T3.2, I can send transactions to the I2C and never see a failure. If I switch to my T3.6, I see random failures where Wire.endTransmission() returns errors. The errors on the T3.6 occur even at 10Khz. As a work around, I modified my write command to loop and keep retrying until it succeeds.
It's almost like the library when operating on the T3.6 is not checking a done flag correctly on the peripheral and corrupts a transfer that is in progress. This happens both on the default Wire.h library and the i2c_t3.h library.
Code:
// Without this loop, failures occur on T3.6, but never on T3.2
bool BAAudioControlWM8731::write(unsigned int reg, unsigned int val)
{
bool done = false;
while (!done) {
Wire.beginTransmission(WM8731_I2C_ADDR);
Wire.write((reg << 1) | ((val >> 8) & 1));
Wire.write(val & 0xFF);
if (byte error = Wire.endTransmission() ) {
Serial.println(String("Wire::Error: ") + error + String(" retrying..."));
} else {
done = true;
Serial.println("Wire::SUCCESS!");
}
}
return true;
}
SECOND ISSUE:
I was calling Wire.begin() in a class constructor that was being declared as a global, so the class would be constructed before the sketch setup() gets called. With the default Wire.h library, things generally work fine. However, when I switch to the i2c_t3.h, it would hang the system before ever getting to setup(). I had to move the call to Wire.begin() out of the constructor and into a member function I call in setup().
I presume there is something about the i2c_t3 library that when setting up the peripheral, it is not yet ready and a hang occurs. Is calling begin() on the peripherals in a global instance constructor generally a bad idea?
Code:
#include "i2c_t3.h"
MyClass object; // if Wire.begin() is called inside MyClass::MyClass() constructor, this will hang
setup() {
object.begin(); // call Wire.begin() here instead and it works fine
}