cancel
Showing results for 
Search instead for 
Did you mean: 

My STM32F3 I2C won't send a start sequence.

davidmodulartech
Associate III

I am using the STM32F30x_DSP_StdPeriph_Lib_V1.2.3 library following instructions given in stm32f30x_12c.c for the initilization:

#define I2C_SHORT_TIMEOUT	((uint32_t)0x1000)
#define I2C_LONG_TIMEOUT	((uint32_t) (10 * I2C_SHORT_TIMEOUT))
#define I2Cx_RCC			RCC_APB1Periph_I2C1
#define I2Cx				I2C1
#define I2C_GPIO_RCC		RCC_AHBPeriph_GPIOB
#define I2C_GPIO			GPIOB
#define I2C_PIN_SDA			GPIO_Pin_7
#define I2C_PIN_SCL			GPIO_Pin_6
#define I2C_AF  	        GPIO_AF_4
 
//#define SLAVE_ADDRESS		0x08
 
static uint32_t i2cTimeout;
 
 
void I2C_LowLevel_Init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
 
  /* Configure the I2C clock source. The clock is derived from the SYSCLK */
  RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
 
  /* I2C_SCL_GPIO_CLK and I2C_SDA_GPIO_CLK Periph clock enable */
  RCC_AHBPeriphClockCmd(I2C_GPIO_RCC, ENABLE);
 
  /* I2C Periph clock enable */
  RCC_APB1PeriphClockCmd(I2Cx_RCC, ENABLE);
 
  GPIO_PinAFConfig(I2C_GPIO, I2C_PIN_SCL, I2C_AF);
 
  /* Connect PXx to I2C_SDA*/
  GPIO_PinAFConfig(I2C_GPIO, I2C_PIN_SDA, I2C_AF);
 
  /* GPIO configuration */
  /* Configure I2C MEMS pins: SCL */
  GPIO_InitStructure.GPIO_Pin = I2C_PIN_SCL | I2C_PIN_SDA;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // External Pull Up
  GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
 
 
}
 
void i2c_init()
{
  I2C_InitTypeDef  I2C_InitStructure;
 
  I2C_LowLevel_Init();
 
  /*!< I2C configuration */
  /* sEE_I2C configuration */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
  I2C_InitStructure.I2C_DigitalFilter = 0x01;
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_Timing = 0x50330309; // 0x50330309 400 KHz, use 0xC062121F for 100KHz
 
  /* MEMS_I2C Peripheral Enable */
  I2C_Cmd(I2Cx, ENABLE);
 
  /* Apply MEMS_I2C configuration after enabling it */
  I2C_Init(I2Cx, &I2C_InitStructure);
 
 
  /* NVIC Configuration */
//  NVIC_Config();
 
  /*!< Select the EEPROM address */
  MEMS_Address = 0x68;
}

I am using I2C1 with PB6 & PB7, AF4 and address 0x68

Later, when I try to read a register using the following code:

uint8_t i2c_read(I2C_TypeDef* i2cx, uint8_t address, uint8_t reg, uint8_t len, uint8_t* buf)
{
 
    address <<= 1;
 
    /* Test on BUSY Flag */
    i2cTimeout = I2C_LONG_TIMEOUT;
    while (I2C_GetFlagStatus(i2cx, I2C_ISR_BUSY) != RESET) {
        if ((i2cTimeout--) == 0) {
            return i2cTimeoutUserCallback();
        }
    }
 
    /* Configure slave address, nbytes, reload, end mode and start or stop generation */
    I2C_TransferHandling(i2cx, address, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
 
    /* Wait until TXIS flag is set */
    i2cTimeout = I2C_LONG_TIMEOUT;
    while (I2C_GetFlagStatus(i2cx, I2C_ISR_TXIS) == RESET) { // was I2C_ISR_TXIS
        if ((i2cTimeout--) == 0) {
            return i2cTimeoutUserCallback();
        }
    }
 
    /* Send Register address */
    I2C_SendData(i2cx, (uint8_t) reg);
 
    /* Wait until TC flag is set */
    i2cTimeout = I2C_LONG_TIMEOUT;
    while (I2C_GetFlagStatus(i2cx, I2C_ISR_TC) == RESET) { // was I2C_ISR_TC
        if ((i2cTimeout--) == 0) {
            return i2cTimeoutUserCallback();
        }
    }
 
    /* Configure slave address, nbytes, reload, end mode and start or stop generation */
    I2C_TransferHandling(i2cx, address, len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
 
    /* Wait until all data are received */
    while (len) {
        /* Wait until RXNE flag is set */
        i2cTimeout = I2C_LONG_TIMEOUT;
        while (I2C_GetFlagStatus(i2cx, I2C_ISR_RXNE) == RESET) {
            if ((i2cTimeout--) == 0) {
                return i2cTimeoutUserCallback();
            }
        }
 
        /* Read data from RXDR */
        *buf = I2C_ReceiveData(i2cx);
        /* Point to the next location where the byte read will be saved */
        buf++;
 
        /* Decrement the read bytes counter */
        len--;
    }
 
    /* Wait until STOPF flag is set */
    i2cTimeout = I2C_LONG_TIMEOUT;
    while (I2C_GetFlagStatus(i2cx, I2C_ISR_STOPF) == RESET) {
        if ((i2cTimeout--) == 0) {
            return i2cTimeoutUserCallback();
        }
    }
 
    /* Clear STOPF flag */
    I2C_ClearFlag(i2cx, I2C_ICR_STOPCF);
 
    /* If all operations OK */
    return 1;
 
}

It times out sfter the asttempt to send a start sequence.

I've tried everything!! I made sure that the bits are actually the ones I'm physically using, Initializing andd setting first PB6 then PB7 to "0". They have pull up resistors so I made sure I could pull them down.

I have a digital analyzer on the I2C buss, and during the sequence to start both line remain high.

Don't know what else to try. On an STM32F10x had no problem... but of course the code and configuration is different.

1 ACCEPTED SOLUTION

Accepted Solutions
davidmodulartech
Associate III

Found the solution myself.

In lines 29 and 32 of the init code, I2C_PIN_SCL & I2C_PIN_SDA are in the wrong format.

GPIO_Pin_6 & GPIO_Pin_7 should be GPIO_PinSource6 & GPIO_PinSource7 One is bit number (64. 128) the other is the actual number (6, 7)

View solution in original post

2 REPLIES 2
davidmodulartech
Associate III

When it gets tp line 15, tje ISR contains just TE flag.

After executing that line, ISR shows busy and TE, so far so good, except the sart sequence isnt initiated and I time out at line 21, with no TXIS flag.

I don't have interrupts enabled. but I think the flag should activate anyway. (and as mentioned there is no start sequence initiated)

davidmodulartech
Associate III

Found the solution myself.

In lines 29 and 32 of the init code, I2C_PIN_SCL & I2C_PIN_SDA are in the wrong format.

GPIO_Pin_6 & GPIO_Pin_7 should be GPIO_PinSource6 & GPIO_PinSource7 One is bit number (64. 128) the other is the actual number (6, 7)