Skip to main content
Visitor II
March 18, 2022
Question

MCU restarts after I2C->CR2 |= I2C_CR2_START; during setting I2C_GenerateSTART

  • March 18, 2022
  • 3 replies
  • 2007 views

I am trying to get I2C communication working between two STM8S003F3P6.

From I2c master I am trying to initiate I2C start message using CR2 registers with below code

#define I2C_CR2_START ((uint8_t)0x01) /*!< Start Generation */
 
.....
 
I2C->CR2 |= I2C_CR2_START;
 

But executing I2C->CR2 |= I2C_CR2_START; immediately restart and it keeps crashing at the same line.

Can someone please help what is possible cause of it, and how to get over this issue

    This topic has been closed for replies.

    3 replies

    Visitor II
    March 18, 2022

    STM8 support here is not so good. I have two cases and no response.

    Unless I2C->CR2 address is wrong, the problem is not in that line. You should put here more details, more code, not just one line. Also it seems that you should read RM0016 with more attention.

    My guess is that the problem is in an ISR that is executed after that line is executed.

    SSaro.1Author
    Visitor II
    March 19, 2022

    I see correct address gets generated in asm file below

    ; src/main.c: 173: I2C->CR2 |= I2C_CR2_START;
     
     ld a, 0x5211
     
     or a, #0x01
     
     ld 0x5211, a
     

    Below is the interrupt handler defined , but I do not see that getting invoked as print statement does not get executed below

    INTERRUPT_HANDLER(I2C_IRQHandler, 19)
     
    {
     
     printf("I2C_Interrupt \n");
     
     switch (I2C_GetLastEvent())
     
     {
     
     /* EV5 */
     
     case I2C_EVENT_MASTER_MODE_SELECT :
     
     
     
    #ifdef TEN_BITS_ADDRESS
     
     /* Send Header to Slave for write */
     
     I2C_SendData(HEADER_ADDRESS_Write);
     
     break;
     
     
     
     /* EV9 */
     
     case I2C_EVENT_MASTER_MODE_ADDRESS10:
     
     /* Send slave Address for write */
     
     I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);
     
     break;
     
    #else
     
     /* Send slave Address for write */
     
     I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);
     
     break;
     
    #endif
     
     /* EV6 */
     
     case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
     
     if (NumOfBytes != 0)
     
     {
     
     /* Send the first Data */
     
     I2C_SendData(TxBuffer[Tx_Idx++]);
     
     
     
     /* Decrement number of bytes */
     
     NumOfBytes--;
     
     }
     
     if (NumOfBytes == 0)
     
     {
     
     I2C_ITConfig(I2C_IT_BUF, DISABLE);
     
     }
     
     break;
     
     
     
     /* EV8 */
     
     case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
     
     /* Transmit Data */
     
     I2C_SendData(TxBuffer[Tx_Idx++]);
     
     
     
     /* Decrement number of bytes */
     
     NumOfBytes--;
     
     
     
     if (NumOfBytes == 0)
     
     {
     
     I2C_ITConfig(I2C_IT_BUF, DISABLE);
     
     }
     
     break;
     
     
     
     /* EV8_2 */
     
     case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
     
     /* Send STOP condition */
     
     I2C_GenerateSTOP(ENABLE);
     
     
     
     I2C_ITConfig(I2C_IT_EVT, DISABLE);
     
     break;
     
     
     
     default:
     
     break;
     
     }
     
    }

    I checked in my code at below locations, its master thats failing,

    https://github.com/spsarolkar/stm8s-i2c-master

    https://github.com/spsarolkar/stm8s-i2c-slave

    I am using sample example code for I2c from standard peripheral library STM8S_StdPeriph_Lib/Project/STM8S_StdPeriph_Examples/I2C/I2C_TwoBoards/I2C_DataExchange

    Visitor II
    March 19, 2022

    You should not use printf in an interrupt handler. Maybe this is the problem.

    SSaro.1Author
    Visitor II
    March 19, 2022

    I removed it from interrupt routien now but still same result, below output keeps repeating indicating restarts at I2C_GenerateSTART each time

    checking function state done �I2C_DeInit 

    I2C_ITConfig 

    enableInterrupts 

    TxBuffer 

    I2C_GenerateSTART 

    checking function state 

    checking function state done �I2C_DeInit 

    I2C_ITConfig 

    enableInterrupts 

    TxBuffer 

    I2C_GenerateSTART 

    checking function state 

    checking function state

    Visitor II
    March 19, 2022

    Maybe the problem is stack.

    If not put a while(1) forever loop in interrupt handler in several places to force program to stop. If it stops, means no restart, problem is in next lines.

    Or use a debug build and place breakpoints. But you need to use STVD.