Other Parts Discussed in Thread: BQ3060
I´m using a TCA9548A for multiplexing i2c devices with the same adress.
this i2c devices are bq3060 IC, and the objective is to read the registers from the ICs conected in port 0 and 1.
I managed to read the IC in port 0. Also the other IC in port 1. But when I try to read both ports, first port 0 and after port 1, some times I have reading problems. The problem is when there is a port selection change in the TCA.
I have seen that when I have reading problem is because in the i2c signal sent to select the port in the TAC9548 (in "tcaselect()" , "BP_WriteReg" ) the stop bit is not send correctly. I post below the code of my application and also I attached the i2c signal when I write the port of the TCA.
My question is, why can be that sometimes, when I write in TCA9548 the stop bit is not send correctly and other times yes. When it is not send ok, it seems that the clock signal is going down just when the data is going high for the STOP bit.
i2c signal sent to TCA in order to select the port (the black marked bit is the stop bit):
My code is the next:
tcaselect(0); VoltageArray[0]=BP_ReadReg(0x09); SOCArray[0]=BP_ReadReg(0x0d); tcaselect(1); VoltageArray[1]=BP_ReadReg(0x09); SOCArray[1]=BP_ReadReg(0x0d); void tcaselect(uint8_t i) { if (i > 7) return; tmp=(1<<i); BP_WriteReg(0x01,tmp); } void BP_WriteReg(uint8_t RegName, uint8_t RegValue) { /*-------------------------------- Transmission Phase -----------------------*/ /* Send BP_I2C START condition */ I2C_GenerateSTART(BP_I2C, ENABLE); /* Test on BP_I2C EV5 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_MODE_SELECT)) /* EV5 */ { } /* Send BP slave address for write */ I2C_Send7bitAddress(BP_I2C, i2c_MULT_ADDR, I2C_Direction_Transmitter); /* Test on BP_I2C EV6 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */ { } /* Send the specified register data pointer */ I2C_SendData(BP_I2C, (uint8_t)RegValue); /* Test on BP_I2C EV8 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */ { } /* Send BP_I2C STOP Condition */ I2C_GenerateSTOP(BP_I2C, ENABLE); } uint16_t BP_ReadReg(uint8_t RegName) { __IO uint16_t RegValue = 0; /* Enable BP_I2C acknowledgement if it is already disabled by other function */ I2C_AcknowledgeConfig(BP_I2C, ENABLE); /*--------------------------- Transmission Phase ----------------------------*/ /* Send BP_I2C START condition */ I2C_GenerateSTART(BP_I2C, ENABLE); /* Test on BP_I2C EV5 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_MODE_SELECT)) /* EV5 */ { } /* Send STBP slave address for write */ I2C_Send7bitAddress(BP_I2C, BP_ADDR, I2C_Direction_Transmitter); /* Test on BP_I2C EV6 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* EV6 */ { } /* Send the specified register data pointer */ I2C_SendData(BP_I2C, RegName); /* Test on BP_I2C EV8 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) /* EV8 */ { } /*------------------------------ Reception Phase ----------------------------*/ /* Send Re-STRAT condition */ I2C_GenerateSTART(BP_I2C, ENABLE); /* Test on EV5 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_MODE_SELECT)) /* EV5 */ { } /* Send BP slave address for read */ I2C_Send7bitAddress(BP_I2C, BP_ADDR, I2C_Direction_Receiver); /* Test on EV6 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) /* EV6 */ { } /* Test on EV7 and clear it */ while (!I2C_CheckEvent(BP_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)) /* EV7 */ { } /* Store BP_I2C received data */ RegValue = (uint16_t)(I2C_ReceiveData(BP_I2C)); /* Disable BP_I2C acknowledgement */ I2C_AcknowledgeConfig(BP_I2C, DISABLE); /* Send BP_I2C STOP Condition */ I2C_GenerateSTOP(BP_I2C, ENABLE); /* Test on RXNE flag */ while (I2C_GetFlagStatus(BP_I2C, I2C_FLAG_RXNE) == RESET) {} /* Store BP_I2C received data */ RegValue|=(I2C_ReceiveData(BP_I2C) << 8); /* Return register value */ return (RegValue); }