Skip to main content
jean_prieur
Associate III
July 30, 2014
Question

I2C problem: random error when I2C1 communicates

  • July 30, 2014
  • 2 replies
  • 552 views
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.
    This topic has been closed for replies.

    2 replies

    jean_prieur
    Associate III
    July 30, 2014
    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
    July 31, 2014
    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!