Skip to main content
bagrowicz
Associate II
September 23, 2009
Question

I2C Slave Problem

  • September 23, 2009
  • 9 replies
  • 2161 views
Posted on September 23, 2009 at 13:06

I2C Slave Problem

    This topic has been closed for replies.

    9 replies

    bagrowicz
    bagrowiczAuthor
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:24

    Hi!

    I encounter some problem with i2c module on my STM32F102R6.

    I've got board with master i2c device based on Atmel AVR ATmega8 uController. This device works fine with our other products but now we try to comunicate with device based on STM32.

    I try to do i2c based on interrupts. When i connect master to board with STM and send packet through i2c i've got nothing - there is no interrupt event! Master sends Start,correct address but it can't get any ACK. I've attached osciloscope printscreen.

    Of course other parts of my board works fine (uart, USB, exti, timers) only i2c doesn't.

    I paste some code from my project. Maybe some one got any clue.

    void i2c_ini(void)

    {

    // na wszelki wypadek

    I2C_DeInit(I2C1);

    // inicjalizacja RCC

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    // konfiguruje kontroler przerwan

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

    NVIC_Init(&NVIC_InitStructure);

    // konfiguracja pinów I2C

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // uruchomienie modulu

    I2C_Cmd(I2C1, ENABLE);

    // konfiguracja modulu

    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

    I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;

    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_InitStructure.I2C_ClockSpeed = SCL_speed;

    I2C_Init(I2C1, &I2C_InitStructure);

    // Sprawdzanie PEC - Packet Error Checking

    // off because AVR not support this feature

    //I2C_CalculatePEC(I2C1, ENABLE);

    // Uruchomienie przerwan od Eventu i od bufora

    I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, ENABLE);

    }

    In intterups handler, there is no code at this moment - only debug and led flash. because when it's goes to interrupt i think there is no problem for me to write rest of the code... ;)

    void I2C1_EV_IRQHandler(void)

    {

    switch (I2C_GetLastEvent(I2C1))

    {

    GPIO_ResetBits(GPIOB, LED1);

    // Master Events

    case I2C_EVENT_MASTER_MODE_SELECT: // EV5

    {

    sendDebug(''Master mode select'');

    break;

    }

    case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: // EV6

    {

    sendDebug(''Master Rx mode select'');

    break;

    }

    case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: // EV6

    {

    sendDebug(''Master Tx mode select'');

    break;

    }

    case I2C_EVENT_MASTER_BYTE_RECEIVED: // EV7

    {

    sendDebug(''Master byte recv'');

    break;

    }

    case I2C_EVENT_MASTER_BYTE_TRANSMITTED: // EV8

    {

    sendDebug(''Master byte transmitted'');

    break;

    }

    case I2C_EVENT_MASTER_MODE_ADDRESS10: // EV9

    {

    sendDebug(''Master mode address 10'');

    break;

    }

    //Slave Events

    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: // EV1

    {

    sendDebug(''Slave Rx Address'');

    break;

    }

    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: // EV1

    {

    sendDebug(''Slave Tx Address'');

    break;

    }

    case I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: //EV1

    {

    sendDebug(''Slave Rx Second Address'');

    break;

    }

    case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: // EV1

    {

    sendDebug(''Slave Tx Second Address'');

    break;

    }

    case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: // EV1

    {

    sendDebug(''Slave General Call'');

    break;

    }

    case I2C_EVENT_SLAVE_BYTE_RECEIVED: //EV2

    {

    sendDebug(''Slave byte recv'');

    break;

    }

    case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: //EV3

    {

    sendDebug(''Slave byte transmitted'');

    break;

    }

    case I2C_EVENT_SLAVE_ACK_FAILURE: // EV3-1

    {

    sendDebug(''Slave ACK failure'');

    break;

    }

    case I2C_EVENT_SLAVE_STOP_DETECTED: // EV4

    {

    sendDebug(''Slave Stop detect'');

    break;

    }

    default:

    {

    sendDebug(''Unknown I2C event detect!'');

    break;

    }

    }

    }

    /**

    * @brief This function handles I2C error interrupt request.

    * @param None

    * @retval : None

    */

    void I2C1_ER_IRQHandler(void)

    {

    GPIO_ResetBits(GPIOB, LED2);

    /* Check on I2C2 AF flag and clear it */

    if (I2C_GetITStatus(I2C1, I2C_IT_AF))

    {

    sendDebug(''Clearing I2C error flag'');

    I2C_ClearITPendingBit(I2C1, I2C_IT_AF);

    }

    }

    norcio82
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 13:24

    Hi

    Are you sending proper slave adress?

    Why SCL line does not have pull-up resistor?

    For me I2C configuration looks fine.

    Regards

    Tomek

    norcio82
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 13:24

    Hi Maciek,

    If it's still doesn't working with SCL line pulled-up try run examples

    from

    http://www.st.com/stonline/products/support/micro/files/stm32f10x_stdperiph_lib.zip

    . Are you using DMA ?

    Regards

    Tomek

    P.S Yes I'm from Poland ;)

    bagrowicz
    bagrowiczAuthor
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:24

    Address is for 100% correct. I also try use General Call, but without any success. My Slave Address is 0x40 so on scope you can see that is correct.

    SCL line has PullUp through 4,7k, but maybe this is clue. I curious why line is in low state. I don't notice that before...

    Regards

    Maciek

    P.S. @norcio82 are you from Poland?

    zach
    Visitor II
    March 24, 2012
    Posted on March 24, 2012 at 04:20

    I know this is an old post, but I am curious if you ever found a solution.  I am having the exact same issue.

    alok472
    Associate
    March 25, 2012
    Posted on March 25, 2012 at 04:06

    Did you take care of I2C Address and R/nW bit ?

    Normaly, depending on the library and configuration...it can be as follows as well..

    I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS<<1;

    eduardobernardi7
    Associate II
    August 29, 2013
    Posted on August 30, 2013 at 00:11

    I have the exact same problem too. Did you ever find a solution for it? I'm almost giving up and start to code a bitbanging.

    David Littell
    Senior II
    September 10, 2013
    Posted on September 10, 2013 at 23:15

    Do you have a scope trace of the data and clock lines during an attempted read or write?

    Nickname925_O
    Associate III
    January 14, 2014
    Posted on January 14, 2014 at 18:51

    Hi,

    did you solve this issue?

    I get the same problem!!!!!