Skip to main content
lorenzo meneghello
Associate III
December 21, 2016
Question

About I2C Bus

  • December 21, 2016
  • 12 replies
  • 2445 views
Posted on December 21, 2016 at 16:03

Hi all,

I'm new on ST device, i'm trying to test the I2C bus but I can't understand how it works.. I do not want to use the HAL library but manage directly the register, but the I2C Interface on ST produce the state of transmission (0x08,0x10,0x28...) like other uC? or it manages all the transmission?

Thanks.

Lorenzo.

    This topic has been closed for replies.

    12 replies

    Nesrine M_O
    Associate
    December 21, 2016
    Posted on December 21, 2016 at 17:13

    Hi

    Meneghello.Lorenzo

    ‌,

    • Could you please precise what are you using as STM32 product?
    • Otherwise I recommend you to read carefully theInter-integrated circuit (I2C) interface section in your related reference manual to have overviewabout STM32 I2C main features and functional description.

    -Nesrine-

    Ifmy suggestanswers your question, please mark it as correct.

    waclawek.jan
    Super User
    December 21, 2016
    Posted on December 21, 2016 at 17:21

    Lorenzo,

    no, the I2C interface does not expose discrete states of the internal state machine as is usual in I2C peripherals following the Philips 'standard' implementation. Rather, you have to infer the internal state from various individual status bits. Read thoroughly the I2C chapter in the RM of the STM32 model of your choice. Beware, there are several evolutionary incarnations of that peripheral in various STM32 models, differing in some of the details.

    JW

    lorenzo meneghello
    Associate III
    December 22, 2016
    Posted on December 22, 2016 at 11:49

    Very hard work.. There's nothing online ? example code? 

    Thanks.

    Nesrine M_O
    Associate
    December 22, 2016
    Posted on December 22, 2016 at 12:03

    Hi

    Meneghello.Lorenzo

    ‌,

    If I suppose that you are using STM32F4 product, Irecommend you to start with the examples available at ST website:

    -Nesrine-

    Nor Sch
    Associate III
    December 22, 2016
    Posted on December 22, 2016 at 13:45

    The I2C itself is really simple. But to get a stable Communication between Slave and Master could take some time. I use the HAL-Driver and for Init the Driver i2c.c/.h generated from Cube. On top I have a Busdriver which is handling the Data and Transmit + Receive. Simplest Solution is to work with a State Machine. For this I have following States:

    typedef enum{
     eI2C_IsErrorOccured = 0,
     eI2C_IsReadyForSend = 1,
     eI2C_IsReadyForReceive = 2,
     eI2C_IsSending = 3, //!< Status while Sending (only Bonus for Debugging, not really needed)
     eI2C_IsReceiving = 4, //!< Status while Receiving (only Bonus for Debugging, not really needed)
     eI2C_SendIsDone = 5, //!< after Tx Complete Interrupt
     eI2C_ReceiveIsDone = 6, //!< after Rx Complete Interrupt
    } TE_I2C_SEND_RECEIVE_STATE;
    �?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    Build your Driver around this. Keep in Mind, that Slave and Master must have a possibility to get synchron after Errors.

    Good luck!

    lorenzo meneghello
    Associate III
    December 22, 2016
    Posted on December 22, 2016 at 17:18

    Thanks all for reply, I'm trying to send a single byte but when I set the START bit on CR2, the STOPF and NACK flag will comes active.. I don't have any device on the bus..

    waclawek.jan
    Super User
    December 23, 2016
    Posted on December 23, 2016 at 00:53

    Which STM32? How did you initialize the related GPIO pins?

    JW

    lorenzo meneghello
    Associate III
    December 23, 2016
    Posted on December 23, 2016 at 10:09

    I'm using the STM32F042K6 and this is the code:

    // I2C Peripheral Disable

    I2C1->CR1 &= ~0x01;

    //Enable the i2c

    RCC->APB1ENR |= (1<<21);

    RCC->CFGR3 |= (1<<4); //SYSCLK 48Mhz

    //Reset the Peripheral

    RCC->APB1RSTR |= (1<<21);

    RCC->APB1RSTR &= ~(1<<21);

    //Configure and initialize the GPIOs

    GPIOA->MODER |= 0x280000;

    GPIOA->OSPEEDR |= 0x280000; 

    GPIOA->PUPDR |= 0x140000;

    //Connect GPIO pins to peripheral

    GPIOA->AFR[1] |= 0x440;

    //Configure and Initialize the I2C

    I2C1->TIMINGR = 0xB0420F13;

    //100kHz

    I2C1->OAR1 = 0;

    I2C1->CR2 &= ~0x01;

    //Addressing mode 7 bit

    I2C1->OAR2 = 0;

    I2C1->CR2 |= 0x80000;

    I2C1->CR1 &= ~(1<<19);

    I2C1->CR1 |= (1<<17);

    // I2C Peripheral Enable

    I2C1->CR1 |= 0x01;

    Mon2
    Senior III
    December 25, 2016
    Posted on December 25, 2016 at 14:48

    Lorenzo - why not just bit-bang out the I2C specification ? Have done this in the past with assorted microcontroller and is very clean and straight forward to understand the interface.

    Have a review of AN4655 (section 2.5.3 I2C master bit-banging sequence).