This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
I am trying to communicate with two TCA6424A devices via i2c using python smbus2 with Raspberry Pi 4 .
So, smbus2 read and write i2c functions through no exceptions.
But, it looks like read function doesn't read from the input register configured like this
bus = SMBus(1)
Next, I write data to device address 0x23 output port-0
The logic analyer shows that the "i2c_msg.write(0x23, 0x02)" message writes two zero bytes, which makes the following read access the output port.
When calling i2c_msg.write, always give it a list of bytes, or a string containing the bytes: i2c_msg.write(0x23, [0x02]).
(And why are reading the same register three times?)
Thank you for your quick response , I will try i2c_msg.write(0x23, [0x02]) as you are suggesting.
The goal is to read the input Port-2 so, the i2c_msg.write(0x23, 0x02) should write 0x2 to TCA6424 command byte to allow reading from input Port-2. , if I am not mistaken.
I am not sure about reading the same register three times. I just mimic with Python the original MCU STM32 C code Read function which works fine . The only difference is : C code is using 8 bit address and smbus2 python can take only 7bit address. However, using i2c sniffer with 8bit addressing I can see my python read function read = i2c_msg.read(0x23, 3) is reading from address 0x47 (as it should be, correct ?)
void TCA_Read(void)
{
read_state = 0;
I2C2->CR1 |= 0x00000040; //Transfer Complete Interrupt enabled TCIE
I2C2->CR2 &= 0x00000000;
I2C2->CR2 |= 0x00010046; //AUTOEND=0, NBYTES=1,Write Request,SADD[7:1]=Slave Address=0x46
}
switch (read_state)
{
case 0:
I2C2->CR2 |= 0x00002000; //Start condition
read_state = 1;
break;
case 1:
read_state = 2;
I2C2->TXDR = 0x02;
break;
case 2:
I2C2->CR1 &= 0xFFFFFFBF; //Transfer Complete Interrupt disabled TCIE
I2C2->CR2 &= 0x00000000;
I2C2->CR2 |= 0x00010000;
I2C2->CR2 |= 0x02000446; //AUTOEND=1, NBYTES=2 (3bytes),Read Request,SADD[7:0]=Slave write Address=0x46
I2C2->CR2 |= 0x00002000; //Re-start condition
read_state = 3;
break;
case 3:
TCA_Temp_Buff[TCA_Temp_Sample_Count] = I2C2->RXDR;
read_state = 0;
break;
default:
read_error_set();
break;
}
"i2c_msg.read(0x23, 3)" tells it to read three bytes. Because the previously written command byte is 0x02 (and not 0x82), the register index is not autoincremented, so you get the same value three times.
An I²C address always has seven bits. The first byte of an I²C transaction contains the address and the R/W bit. This byte is sometimes called the "address byte", but this does not make the adress eight bits. (And some microcontrollers have a register that also combines the address and the R/W bit, such as in your example.)
Thanks again for your explanations.
I will try to use correct terms in the future but , my question is still standing , why it is not reading from the input port-2 ?
Hi Mike,
I agree with Clemen's comment. Your logic analyzer image is showing that you are writing to the command byte 0x00h prior to the read which sets the read transaction to read from the INPUT PORT 0. You would need to set the write command to send the command byte 0x02h if you want to read from INPUT PORT 2.
-Bobby