cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411 I2C transmission not working

Arno Thiele
Associate III

I am trying to get I2C on the STM32F411 to work with an audio codec. For now I am just trying a simple loopback but I am already running into trouble. I am using the standard lib and my code always hangs after sending the 7bit address. 

I checked everything with a DSO and did step-by-step debugging. Surprisingly the problem is NOT that the code gets stuck in the while loop after the 7bitAddress. The address does get acknowledged by the receiver and the program successfully leaves that loop. But after that no other transmission function has any effect. I2C_SendData won’t send anything and I2C_GenerateStop won’t generate any stop condition even though both get executed in my debugger. All I see is SDA high and the SCL pulled low by the master. The I2C peripheral seems to be stuck in a busy state without being responsive and I don't understand why that is.

Looking at my registers I saw that ADDR gets successfully cleared after sending the address. TXE is set and that’s the only bit I see set in SR1. The code is the same as in many other working examples I’ve found online. 

Below is the full code. Any help is very appreciated.

int main(void)
{
 
	  GPIO_InitTypeDef GPIO_InitStructure;
	  I2C_InitTypeDef  I2C_InitStructure;
 
	  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
	  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);  // loopback receive
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
 
	  I2C_InitStructure.I2C_Mode        = I2C_Mode_I2C;
	  I2C_InitStructure.I2C_DutyCycle   = I2C_DutyCycle_2;
	  I2C_InitStructure.I2C_OwnAddress1 = 0b0001111;
	  I2C_InitStructure.I2C_Ack         = I2C_Ack_Disable;
	  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	  I2C_InitStructure.I2C_ClockSpeed = 100000;
	  I2C_Init(I2C1, &I2C_InitStructure);
 
	  I2C_InitStructure.I2C_Ack         = I2C_Ack_Enable;
	  I2C_InitStructure.I2C_OwnAddress1 = 0b0001110;
	  I2C_Init(I2C3, &I2C_InitStructure);       // loopback receive
 
	  I2C_Cmd(I2C1, ENABLE);
	  I2C_Cmd(I2C3, ENABLE);    // loopback receive
 
	  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
	  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
 
	  GPIO_PinAFConfig(GPIOA, GPIO_PinSource8,  GPIO_AF_I2C3);  // loopback receive
	  GPIO_PinAFConfig(GPIOC, GPIO_PinSource9,  GPIO_AF_I2C3);  // loopback receive
 
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
	  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
	  GPIO_InitStructure.GPIO_Speed = GPIO_Medium_Speed;
 
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;   //SCL
	  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;   //SDA
	  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;    // loopback receive
	  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
	  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;     // loopback receive
	  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
 
 
			  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
 
			  /* Send I2C1 START condition */
			  I2C_GenerateSTART(I2C1, ENABLE);
 
			  /* Test on I2C1 EV5 and clear it */
			  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
 
			  /* Send slave Address for write */
			  I2C_Send7bitAddress(I2C1, 0b0001110, I2C_Direction_Transmitter);
 
			  /* Test on I2C1 EV6 and clear it */
			  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // hängt!
 
			  I2C_SendData(I2C1, 0b10011000);
 
			  /* Test on I2C1 EV8 and clear it */
			  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
			  /* Send I2C1 STOP Condition */
			  I2C_GenerateSTOP(I2C1, ENABLE);
 
			  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
 
}

1 ACCEPTED SOLUTION

Accepted Solutions
Arno Thiele
Associate III

The problem got resolved trying it with my my actual audio codec and exactly the same code. No hang ups anymore. Still I have no idea why the loopback wouldn't work.

View solution in original post

3 REPLIES 3
MDolb
Associate

I am doing the same thing than you. Lucky you are because in my case the slave address does not mean to output on the bus... The busy flag workaround seems though.

Arno Thiele
Associate III

The problem got resolved trying it with my my actual audio codec and exactly the same code. No hang ups anymore. Still I have no idea why the loopback wouldn't work.

T J
Lead

please mark this as answered...