Fix I2C communication issue with MCP23008, where STOP-condition was failing due to SDA non-LOW possibly because of a late ACK.

pull/55/merge
guido 2021-05-30 18:27:14 +02:00
rodzic a6b36c2a2a
commit 94204bd3bd
1 zmienionych plików z 11 dodań i 2 usunięć

Wyświetl plik

@ -1115,6 +1115,8 @@ ISR(PCINT2_vect){ // Interrupt on rotary encoder turn
enc.event(); enc.event();
}*/ }*/
// I2C communication starts with a START condition, multiple single byte-transfers (MSB first) followed by an ACK/NACK and stops with a STOP condition;
// during data-transfer SDA may only change when SCL is LOW, during a START/STOP condition SCL is HIGH and SDA goes DOWN for a START and UP for a STOP.
class I2C { class I2C {
public: public:
#if(F_MCU > 20900000) #if(F_MCU > 20900000)
@ -1194,10 +1196,11 @@ public:
SendBit(data, 1 << 2); SendBit(data, 1 << 2);
SendBit(data, 1 << 1); SendBit(data, 1 << 1);
SendBit(data, 1 << 0); SendBit(data, 1 << 0);
I2C_SDA_HI(); // recv ACK SendBit( 0, 1 << 0); // ACK/NAK: instead of assuming slave will set SDA is LOW (ACK), force SDA is LOW so that at least STOP condition will succeed (in case ACK is delayed, e.g. with MCP23008).
/*I2C_SDA_HI(); // recv ACK
DELAY(I2C_DELAY); DELAY(I2C_DELAY);
I2C_SCL_HI(); I2C_SCL_HI();
I2C_SCL_LO(); I2C_SCL_LO();*/
} }
inline uint8_t RecvBit(uint8_t mask){ inline uint8_t RecvBit(uint8_t mask){
I2C_SCL_HI(); I2C_SCL_HI();
@ -4368,6 +4371,12 @@ clear; echo ";UA1;UD;" > /tmp/ttyS0; cat /tmp/ttyS0 | while IFS= read -d \; c; d
Use pavumeter to set the correct mixer settings Use pavumeter to set the correct mixer settings
For an Arduino board at 16 MHz, the following simple script will start streaming audio:
cat /dev/ttyACM0 | aplay -c 1 -r 6249 -f U8
stty -F /dev/ttyACM0 raw -echo -echoe -echoctl -echoke 115200;
echo ";UA1;" > /dev/ttyACM0
*/ */
#ifdef CAT_EXT #ifdef CAT_EXT
else if((CATcmd[0] == 'U') && (CATcmd[1] == 'K') && (CATcmd[4] == ';')) // remote key press else if((CATcmd[0] == 'U') && (CATcmd[1] == 'K') && (CATcmd[4] == ';')) // remote key press