Fixed issues with AT1846S I2C bus on MD-UV3x0, which caused it to work only if additional capacitance was added to SDA line by probing wires, oscilloscope probe, ...

This commit is contained in:
Silvano Seva 2021-03-21 22:20:11 +01:00
parent fc65891a29
commit fb295a7aa0
1 changed files with 11 additions and 10 deletions

View File

@ -45,8 +45,6 @@ void i2c_init()
{ {
gpio_setMode(I2C_SDA, INPUT); gpio_setMode(I2C_SDA, INPUT);
gpio_setMode(I2C_SCL, OUTPUT); gpio_setMode(I2C_SCL, OUTPUT);
gpio_setOutputSpeed(I2C_SDA, HIGH);
gpio_setOutputSpeed(I2C_SCL, HIGH);
gpio_clearPin(I2C_SCL); gpio_clearPin(I2C_SCL);
} }
@ -199,25 +197,26 @@ void _i2c_write(uint8_t val)
delayUs(2); delayUs(2);
} }
/* Clock cycle for slave ACK/NACK */ /* Ensure SCL is low before releasing SDA */
gpio_setMode(I2C_SDA, INPUT);
gpio_clearPin(I2C_SCL); gpio_clearPin(I2C_SCL);
/* Clock cycle for slave ACK/NACK */
gpio_setMode(I2C_SDA, INPUT_PULL_UP);
delayUs(2); delayUs(2);
gpio_setPin(I2C_SCL); gpio_setPin(I2C_SCL);
delayUs(2); delayUs(2);
gpio_clearPin(I2C_SCL); gpio_clearPin(I2C_SCL);
delayUs(1);
/* Asserting SDA pin allows to fastly bring the line to idle state */ /* Asserting SDA pin allows to fastly bring the line to idle state */
gpio_setMode(I2C_SDA, OUTPUT);
gpio_setPin(I2C_SDA); gpio_setPin(I2C_SDA);
gpio_setMode(I2C_SDA, OUTPUT);
delayUs(8); delayUs(6);
} }
uint8_t _i2c_read(bool ack) uint8_t _i2c_read(bool ack)
{ {
gpio_setMode(I2C_SDA, INPUT); gpio_setMode(I2C_SDA, INPUT_PULL_UP);
gpio_clearPin(I2C_SCL); gpio_clearPin(I2C_SCL);
uint8_t value = 0; uint8_t value = 0;
@ -237,8 +236,10 @@ uint8_t _i2c_read(bool ack)
* Set ACK/NACK state BEFORE putting SDA gpio to output mode. * Set ACK/NACK state BEFORE putting SDA gpio to output mode.
* This avoids spurious spikes which can be interpreted as NACKs * This avoids spurious spikes which can be interpreted as NACKs
*/ */
ack ? gpio_clearPin(I2C_SDA) : gpio_setPin(I2C_SDA); gpio_clearPin(I2C_SDA);
gpio_setMode(I2C_SDA, OUTPUT); gpio_setMode(I2C_SDA, OUTPUT);
delayUs(2);
if(!ack) gpio_setPin(I2C_SDA);
/* Clock cycle for ACK/NACK */ /* Clock cycle for ACK/NACK */
delayUs(2); delayUs(2);