cancel
Showing results for 
Search instead for 
Did you mean: 

I2C problem: random error when I2C1 communicates

jean_prieur
Associate III
Posted on July 30, 2014 at 17:17

Hello everybody,

I have a problem when I try to communicate with I2C1 (on STM32F4DISCOVERY) and a touch panel controller (Azoteq IQS550). First I have to say that I use I2C1 on the demoboard DISCOVERY which is reserved forCS43L22 (it uses the pins PB6 and PB9). But I think there is no problem to do that. So my problem appears after an I2C START, I communicate with the controller by using WRITE, READ, REPEATED_START and STOP functions:

I2C1_Start(I2C_Direction_Transmitter);
// Communication started
I2C1_Wr(0x11);
// Send data address
I2C1_Wr(0x64);
// Send data for Prox Threshold
I2C1_Wr(0x05);
// Send data for Touch Threshold
I2C1_Stop(); 
// Close communication window
I2C1_Start(I2C_Direction_Transmitter);
// Communication started
I2C1_Wr(0x11); 
// Send data address
I2C1_Repeated_Start(I2C_Direction_Receiver); 
// Issue repeated start signal
info_tt = I2C1_Read_Ack();
// Read first byte (Prox threshold)
info_tt = I2C1_Read();
// Read second byte (Touch Threshold)
I2C1_Stop();
// Close communication windows

The START function works, but after the program get lost in the function ''I2C_CheckEvent'' with the status = error. This error happens not after a particular function above, it's quite random. But the error always happens.
2 REPLIES 2
jean_prieur
Associate III
Posted on July 30, 2014 at 17:22

Below, my I2C functions:

void
I2C1_Start(uint8_t direction)
{
// wait until I2C1 is not busy anymore
while
(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
// Send I2C1 START condition
I2C_GenerateSTART(I2C1, ENABLE);
// wait for I2C1 EV5 --> Slave has acknowledged start condition
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
// Send slave Address for write
I2C_Send7bitAddress(I2C1, TP_ADRESS<<1, direction);
/* wait for I2C1 EV6, check if
* either Slave has acknowledged Master transmitter or
* Master receiver mode, depending on the transmission
* direction
*/
if
(direction == I2C_Direction_Transmitter)
{
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
}
else
if
(direction == I2C_Direction_Receiver)
{
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
}
}

void
I2C1_Wr(uint8_t data)
{
I2C_SendData(I2C1, data);
// wait for I2C1 EV8_2 --> byte has been transmitted
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}

uint8_t I2C1_Read(
void
)
{
// disable acknowledge of received data
I2C_AcknowledgeConfig(I2C1, DISABLE);
// wait until one byte has been received
while
( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) );
// read data from I2C data register and return data byte
uint8_t data = I2C_ReceiveData(I2C1);
return
data;
}

uint8_t I2C1_Read_Ack(
void
)
{
// enable acknowledge of recieved data
I2C_AcknowledgeConfig(I2C1, ENABLE);
// wait until one byte has been received
while
( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) );
// read data from I2C data register and return data byte
uint8_t data = I2C_ReceiveData(I2C1);
return
data;
}

void
I2C1_Repeated_Start(uint8_t direction)
{
// Send I2C1 START condition
I2C_GenerateSTART(I2C1, ENABLE);
}

void
I2C1_Stop(
void
)
{
// Send I2C1 STOP Condition
I2C_GenerateSTOP(I2C1, ENABLE);
}

jean_prieur
Associate III
Posted on July 31, 2014 at 18:01

Hello,

Is it possible to have a validation of the fact that I can use the I2C1 of the discovery board?

Thanks a lot!