AnsweredAssumed Answered

I2C Issues Using STM32F429I Discovery Board.

Question asked by waddelow.maxwell on Feb 13, 2015
Latest reply on Mar 4, 2015 by Amel N
I am attempting to configure the pins on the STM32F429I Discovery Board so that i can connect some I2C sensors and produce some data readings for a project i am working on.
I am using the template file given by ST for this Discoveruy Board using Keil uvision 5.

Using an oscilloscope it appears that during the initialisation of the GPIO pins the SCL pin pb6 attempts to go high and then something pulls it low again meaining that the I2C assumes that the line is busy and wont communicate with the board. I think i am performing the setup corectly.

Any Help would be greatly appreciated. Here is the code i have written so far.

#include "i2c.h"
#include "stm32f4xx_conf.h"
#include "stm32f4xx_i2c.h"
#include "stm32f4xx_gpio.h"
  
  
  
  
  
void i2c_init(void){
   
                    GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as I2C1SDA and I2C1SCL
      
    I2C_InitTypeDef I2C_InitStruct; // this is for the I2C1 initilization
   
    /* Enable Clocks */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins 6(I2C1_SCL) and 7(I2C1_SDA)
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;// this defines the IO speed and has nothing to do with the baudrate!
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;// this defines the output type as open drain
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;// this activates the pullup resistors on the IO pins
      
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); //
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
      
    GPIO_Init(GPIOB, &GPIO_InitStruct);// now all the values are passed to the GPIO_Init() 
      
       /* Set the I2C structure parameters */
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStruct.I2C_OwnAddress1 = 0x00;
    I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStruct.I2C_ClockSpeed = 100000;
   
    I2C_Cmd(I2C1, DISABLE);
    I2C_Init(I2C1,&I2C_InitStruct);
    I2C_Cmd(I2C1, ENABLE);
      
}
  
  
uint8_t SHT21_ADR = 0x40;
uint8_t TCS3472_ADR = 0x29;
  
  
double Read_Sensor(int parameter)
{
    uint32_t timeout = I2C_IT_TIMEOUT;
    uint16_t data = 0;
    uint8_t command = 0;
    uint8_t address = 0;
    double value = 0xFF;
   
 /*Possible Sensor Calculations*/
    switch(parameter){
        case TEMPERATURE:
            command = 227;
            address = SHT21_ADR; 
            break;
      
        case HUMIDITY:
            command = 229;
            address = SHT21_ADR; 
            break;
          
        case RED:
            address = TCS3472_ADR;
            break;
          
        case GREEN:
            address = TCS3472_ADR;
            break;
          
        case BLUE:
            address = TCS3472_ADR;
            break;
              
        default :
            return 0xFF;
              
    }
      
      
  /* Generate the Start Condition */
    while (I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)); 
    I2C_GenerateSTART(I2C1, ENABLE);
   
  /* Test on I2C1 EV5 and clear it */
    
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//  {
//    /* If the timeout delay is exceeded, exit with error code */
//      if ((timeout--) == 0){
//          return 0xFF;
//      }
//  } 
   
    I2C_Send7bitAddress(I2C2, address, I2C_Direction_Transmitter);
   
  /* Test on I2C1 EV6 and clear it */
    timeout = I2C_IT_TIMEOUT; /* Initialize timeout value */
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
    {
    /* If the timeout delay is exeeded, exit with error code */
        if ((timeout--) == 0){
            return 0xFF;
        }
    
  
    I2C_SendData(I2C2,command);
   
        /* Test on I2C1 EV8 and clear it */
        timeout = I2C_IT_TIMEOUT; /* Initialize timeout value */
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
          
        /* If the timeout delay is exeeded, exit with error code */
        if ((timeout--) == 0) return 0xFF;
          
    }       
   
      
   
    /* Generate the Start Condition */
    I2C_GenerateSTART(I2C2, ENABLE);
   
    /* Test on I2C1 EV6 and clear it */
    timeout = I2C_IT_TIMEOUT; /* Initialize timeout value */
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
    {
        /* If the timeout delay is exeeded, exit with error code */
        if ((timeout--) == 0) return 0xFF;
    
   
    I2C_Send7bitAddress(I2C2, SHT21_ADR ,I2C_Direction_Receiver);
   
    /* Test on I2C1 EV6 and clear it */
    timeout = I2C_IT_TIMEOUT; /* Initialize timeout value */
     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
    {
                /* If the timeout delay is exeeded, exit with error code */
        if ((timeout--) == 0) return 0xFF;
    }
      
    I2C_AcknowledgeConfig(I2C2, ENABLE); 
    /* Test on I2C1 EV6 and clear it */
    timeout = I2C_IT_TIMEOUT; /* Initialize timeout value */
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
    {
                /* If the timeout delay is exeeded, exit with error code */
        if ((timeout--) == 0) return 0xFF;
    }  
    
    data = I2C_ReceiveData(I2C2);
    data = data<<8;
  
    /* Prepare an NACK for the next data received */
    I2C_AcknowledgeConfig(I2C2, DISABLE);
    timeout = I2C_IT_TIMEOUT; /* Initialize timeout value */
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED))
    {
        /* If the timeout delay is exeeded, exit with error code */
        if ((timeout--) == 0) return 0xFF;
    }
    I2C_GenerateSTOP(I2C2, ENABLE);
    data |= I2C_ReceiveData(I2C2);
  
    /*Bit mask the LSB bits to Zero based on the type of measurement made */
    if(parameter == TEMPERATURE){
        data = data & (0xFFFC); //Last 2 Bits are set to Zero
        value = convertTemperature(data);
    }
    else if(parameter == HUMIDITY){
        data = data & (0xFFF0);
        value = convertHumidity(data);
    }
    else if(parameter == RED || parameter == GREEN || parameter == BLUE){
        uint16_t buffer = data &0x00FF;
        buffer = buffer<<8;
        data = (data>>8) &0x00FF;
        data = buffer | data;
        value = data;
          
          
    }
   return value;
}
  
double convertTemperature(uint16_t data){
double value;
    value = data * 175.72 / 65536 - 48.65;
    return value;
}
  
double convertHumidity(uint16_t data){
double value;
    value = data * 125 / 65536 - 6;
    return value;
}

Outcomes