Open felias-fogg opened 6 years ago
Does the code of the library gets stuck completely, or is just SDA stuck to low and the code runs further?
I added a "being alive" signal in the main loop, which does not show any more, when the the SDA line gets stuck. So I guess, it gets stuck inside the library code. It seems to happen during the execution of an onrequest call-back function. I can send you the code, if you want. However, it usually takes quite some time before the error shows up.
I thought a while about this. For pure slave mode there are only 2 places, where a block can happen:
Can you check, if the start condition is completed correctly by your master in the case of a stuck? Maybe you can capture it with a scope, or you just check the state of the SCL line.
I noticed that the lockup happened during the transfer of 4 bytes from the slave to the master. The first 2 bytes were transfered OK, the second 2 bytes were 0. So, my best guess is that it happens inside the onRequest callback function.
I'm experiencing this issue as well and am not able to resolve it given the info above.
Hardware: Jetson Nano is Master on its I2C bus 1 (pins 3 and 5)
This is the code I'm running on the ATTiny85 (16MHz)
// Simple Sketch for ATtiny85
// Listens to I2C for an 8-bit value
// writes that value to PWM output
#include <TinyWire.h>
#define ADDRESS 0x40
#define PWM_PIN 1 // pin #6 on the ATtiny85
float ease_rate = 0.125;
float value = 0;
int target = 0;
//////////////////////////////////////////////////////////////////////////////
void setup() {
// warning: this contains cryptic register settings for the ATTiny85 timers
cli(); // clear interrupts
// timer0 PWM freqeuncy ~8Khz (16Mhz / 256 / 8)
TCCR0A = 0b00000011; // waveform generation mode (WGM) = fast pwm
TCCR0B = 0b00000010; // bits 0-2 are prescaler /8
// timer1 frequency ~ 60Hz ( 16Mhz / 8192 / 60 ~ 32.5 )
// used for timed smoothing PWM values
TCCR1 = 0b10001110; //CTC - 16Mhz / 8192
OCR1A = 0b00000000; //interrupt when the clock is reset
OCR1C = 0b00010000; //clock is reset when it hits 32
TIMSK = 0b01000000; // attach interrupt to OCR1A
sei(); // set interrupts
pinMode(PWM_PIN, OUTPUT);
value = 0;
target = 0;
// config TinyWire library for I2C slave functionality
TinyWire.begin( ADDRESS );
// sets callback for the event of a slave receive
TinyWire.onReceive( onI2CReceive );
}
//////////////////////////////////////////////////////////////////////////////
void loop() {
analogWrite(PWM_PIN, int(value));
}
//////////////////////////////////////////////////////////////////////////////
ISR(TIM1_COMPA_vect) {
value += ease(value, target, ease_rate);
}
//////////////////////////////////////////////////////////////////////////////
void onI2CReceive(int howMany) {
while( TinyWire.available() > 0 ){
target = TinyWire.read();
}
}
//////////////////////////////////////////////////////////////////////////////
float ease(float _val, int _target, float _ease) {
return ( float(_target) - _val ) * _ease;
}
I noticed that when I use the i2cdetect
tool on the Jetson, the device wasn't showing up and I wasn't able to send data to the ATTiny85. I checked the SDA and SCL pins on a scope and found the SDA pin was driven low on the ATTiny85. Only after resetting the ATTiny85, does the SDA pin return high again.
Out of desperation, I skipped the detection and went straight for sending data to the ATTiny85. Using the smbus python library and can send data that is successfully received by the ATTiny85.
I can use the ATTiny85, but am troubled by the prospect that the SDA pin can get stuck low.
Detection shouldn't cause a device to hang.
Was the source of the problem ever properly identified? Is there a solution?
Using the library as a slave client on an ATtiny85 with 1 MHz clock, I experienced quite often that the SDA line got stuck to zero. Disabling the Timer0 interrupt (responsible for counting millis etc) seems to help. I haven't seen this problem again even running the slave client for quite some time. I am not really sure whether this is problem of the library or of the way Arduino implements the Timer0 IRQ routine. I just wanted to mentioned the problem so that others might be aware of the potential problem.