cancel
Showing results for 
Search instead for 
Did you mean: 

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

SSaro.1
Associate II

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

5 REPLIES 5
AA1
Senior III

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.

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

AA1
Senior III

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

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

AA1
Senior III

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.