cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to see why I2C3 is not functioning?

Rogers.Gary
Senior II
Posted on May 03, 2015 at 00:30

Hi,

I have been looking at this for hours, but cannot determine why I cannot get the I2C3 operating, even getting a pulse from the SCK line. I am using an STM32F4 device, with an ST LIS3DML sensor.

Both SCK and SDA are physically pulled to Vdd with a  10K resistor.

GPIO and call to I2C init is below:

void init_I2C3(void)

{

    GPIO_InitTypeDef GPIO_InitStruct;

    I2C_InitTypeDef I2C_InitStruct;

    

    // enable APB1 peripheral clock for I2C3

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);

    // enable clock for SCL pin

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    // enable clock for SDA pin

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);    

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;           

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;        

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;    

    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;        

    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;    

    GPIO_Init(GPIOA, &GPIO_InitStruct);                

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;          

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;        

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;    

    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;        

    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;    

    GPIO_Init(GPIOC, &GPIO_InitStruct);                

    

    // Connect I2C3 pins to AF  

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3);    // SCL

    GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_I2C3); // SDA

    

    // configure I2C3

    I2C_InitStruct.I2C_ClockSpeed = 100000;         // 100kHz

    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_Disable;        

    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Init(I2C3, &I2C_InitStruct);                

    

    // enable I2C3

    I2C_Cmd(I2C3, ENABLE);

}

Below is the I2C start, and the I2C send:

void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction)

{

    // wait until I2C1 is not busy anymore

    while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

 

    // Send I2C1 START condition

    I2C_GenerateSTART(I2Cx, ENABLE);

      

    // wait for I2C1 EV5 --> Slave has acknowledged start condition

    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

        

    // Send slave Address for write

    I2C_Send7bitAddress(I2Cx, address, 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(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    }

    else if(direction == I2C_Direction_Receiver){

        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    }

}

void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)

{

    I2C_SendData(I2Cx, data);

    // wait for I2C1 EV8_2 --> byte has been transmitted

    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

}

uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){

    // enable acknowledge of recieved data

    I2C_AcknowledgeConfig(I2Cx, ENABLE);

    // wait until one byte has been received

    while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );

    // read data from I2C data register and return data byte

    uint8_t data = I2C_ReceiveData(I2Cx);

    return data;

}

uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){

    // disabe acknowledge of received data

    // nack also generates stop condition after last byte received

    // see reference manual for more info

    I2C_AcknowledgeConfig(I2Cx, DISABLE);

    I2C_GenerateSTOP(I2Cx, ENABLE);

    // wait until one byte has been received

    while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );

    // read data from I2C data register and return data byte

    uint8_t data = I2C_ReceiveData(I2Cx);

    return data;

}

 

From main, I call:

&sharpdefine LIS3MDL_ADDRESS      0x1C

&sharpdefine LIS3MDL_WHO_AM_I     0x0F  // should return 0x3D

    init_I2C3();

    I2C_start(I2C3, LIS3MDL_ADDRESS<<1, I2C_Direction_Transmitter);

    I2C_write(I2C3, LIS3MDL_WHO_AM_I);

    //I2C_read_nack(I2C3);

    I2C_read_ack(I2C3);

However, when scoping the SCK line, there is never a clock burst from the STM32F4. In fact, it hangs the processor if I try to use either read call above.

Any idea of what the problem might be?

Thank you for any help...

#stm32f4 #i2c3
0 REPLIES 0