AnsweredAssumed Answered

stm32 100 I2C peripheral not sending address

Question asked by stephen.goodman on Jan 7, 2015
Latest reply on Jan 7, 2015 by stephen.goodman
I am trying to use the I2C peripheral on the STM32100.  I am finding that about half the time the address isn't being sent.  What happens is that the data line is going low (start condition is set) the clock line goes low then high without any clock pulses then the data line is going high (stop condition).  Other times communication works successfully.

Code: (Peripheral clock enable and GPIO configuration is handled elsewhere)
uint8 Address;
uint8 * Data;
uint8 DataNumBytes;
uint8 CurrentDataPosition;
  
void i2cInitialise(void)
{
    /* Set frequency system clock is running at. */
    I2C_MODULE(1)->CR2 &= ~I2C_CR2_FREQ_MSK;
    I2C_MODULE(1)->CR2 |= I2C_CR2_FREQ(24);
      
    /* Set as fast mode */
    I2C_MODULE(1)->CCR |= I2C_CCR_FS;
      
    /* Set duty cycle */
    I2C_MODULE(1)->CCR |= I2C_CCR_DUTY;
      
    /* Configure clock frequency to ~100khz */
    I2C_MODULE(1)->CCR &= ~I2C_CCR_CCR_MSK;
    I2C_MODULE(1)->CCR |= I2C_CCR_CCR(9);
      
    /* Configure maximum rise time to 300ns */
    I2C_MODULE(1)->TRISE = I2C_TRISE_TRISE(8);
      
    /* Enable Interrupts */
    I2C_MODULE(1)->CR2 |= I2C_CR2_ITEVTEN;
    I2C_MODULE(1)->CR2 |= I2C_CR2_ITERREN;
    I2C_MODULE(1)->CR2 |= I2C_CR2_ITBUFEN;
      
    /* Enable peripheral. */
    I2C_MODULE(1)->CR1 |= I2C_CR1_PE;
}
  
  
void i2cSendDataPacket(uint8 address, uint8 * data, uint8 dataNumBytes)
{
    /* Record data to be transmitted */
    Address = address;
    Data = data;
    DataNumBytes = dataNumBytes;
    CurrentDataPosition = 0;
      
    /* Set start condition */
    I2C_MODULE(1)->CR1 |= I2C_CR1_START;
}
  
void I2C2_EV_IRQHandler(void)
{
    int32 statusRegister1 = 0;
    int32 statusRegister2 = 0;
      
    /* Read SR1 register - this is needed to clear event flags */
    statusRegister1 = I2C_MODULE(1)->SR1;
      
    if(statusRegister1 & I2C_SR1_SB) /* Start condition has been set */
    {
        /* Write address to DR */
        I2C_MODULE(1)->DR = Address;
    }
    else if(statusRegister1 & I2C_SR1_ADDR) /* Address has been sent */
    {
        /* Read SR2 register - this is needed to clear address sent flag */
        statusRegister2 = I2C_MODULE(1)->SR2;
          
        /* Send data */
        I2C_MODULE(1)->DR = Data[CurrentDataPosition];
        CurrentDataPosition++;
    }
    else if(statusRegister1 & I2C_SR1_TxE)
    {
        if(CurrentDataPosition < DataNumBytes)
        {
            /* Send data */
            I2C_MODULE(1)->DR = Data[CurrentDataPosition];
            CurrentDataPosition++;
        }
        else
        {
            /* Set stop condition */
            I2C_MODULE(1)->CR1 |= I2C_CR1_STOP;
        }
    }
}

Outcomes