2015-08-25 07:53 AM
I know it's a recurring problem. I could'nt make I2C2 work on my STM32F401VET.
When I use RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);I2C2->SR2 =2No matter what I do.I try many work around proposed on this forum but nothing works.Another weird thing happening is when I set my pin SDA on PB3 to AF, SDA go down.GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // use PB3 and PB10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // set pins to alternate functionGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // set GPIO speedGPIO_InitStructure.GPIO_OType = GPIO_OType_OD; // set output to open drain --> the line has to be only pulled low, not driven highGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // enable pull up resistorsGPIO_Init(GPIOB, &GPIO_InitStructure); // init GPIOBGPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_Init(GPIOB, &GPIO_InitStructure);// SDA =
HIGHGPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_I2C2); // SDA =LOWGPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2); // SCLSomeone has faced the same issues ? #i2c2-sr2-busy-stm32f4012015-08-25 11:21 AM
What's attached to the pins?
If you just configure the pins as GPIO Inputs with Pull-Up, what's the state of the pins then?2015-08-26 07:07 AM
It is an audio codec WM8731, there are also external pull up resitor on SDA and SCL.
At fisrt I thought that it was the codec wich pull low the SDA. But when I put the SDA pin as Input, the line goes HIGH then I set it again to AF it goes LOW.I also tried to reset the I2C2 after setting the clock, or doing a manual clocking on SCL. But nothing worked.2015-08-26 02:19 PM
2015-08-26 03:17 PM
I use standard periph.
I already try inverting the init of SDA and SCL ( I read the thread you mentioned)I try your sample of code, it did'nt work :\I check the state externaly not internaly with a Flag.2015-08-27 02:00 AM
HiGermain,
Did you tried the workaround consisting on enabling the I2C2 clock (RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);) after GPIO configuration? If it doesn't work, try this order:// GPIOB clock enable
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_I2C2); // SDA =LOW
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2); // SCL
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // use PB3 and PB10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // set pins to alternate function
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // set GPIO speed
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; // set output to open drain --> the line has to be only pulled low, not driven high
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // enable pull up resistors
GPIO_Init(GPIOB, &GPIO_InitStructure); // init GPIOB
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOB, &GPIO_InitStructure); // SDA =HIGH
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
Is there another pins combination that you may use for I2C2? If yes, try it.
-Mayla-
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2015-08-27 09:54 AM
This is how I have done it.
GPIO_DeInit(GPIOA);GPIO_DeInit(GPIOB);GPIO_DeInit(GPIOC);GPIO_DeInit(GPIOD);GPIO_DeInit(GPIOE);// GPIO Periph clock enableRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // PORTA clock enableRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // PORTB clock enableRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); // PORTC clock enableRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // PORTD clock enableRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); // PORTE clock enableGPIO_InitTypeDef GPIO_InitStructure;// GPIOB Configuration SCL and SDA pins// SCL on PB10 and SDA on PB3GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // use PB3 and PB10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // set pins to alternate functionGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // set GPIO speedGPIO_InitStructure.GPIO_OType = GPIO_OType_OD; // set output to open drain --> the line has to be only pulled low, not driven highGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // enable pull up resistorsGPIO_Init(GPIOB, &GPIO_InitStructure); // init GPIOBGPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C3); // SCLGPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_Init(GPIOB, &GPIO_InitStructure); // init GPIOBGPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_I2C3); // SDA// Configure I2S2_LRCK as alternate functionGPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2); // Connect I2S2_LRCK pins to AF5// Configure I2S2_SD as alternate functionGPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOC, &GPIO_InitStructure);// Configure I2S2_MCK as alternate functionGPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_SPI2); // Connect I2S2_SD pins to AF5GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_SPI2); // Connect I2S2_MCK pins to AF5// Configure I2S2_SCK as alternate functionGPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_PinAFConfig(GPIOD, GPIO_PinSource3, GPIO_AF_SPI2); // Connect I2S2_SCK pins to AF5I2C_InitTypeDef I2C_InitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);// Enable the I2C clockI2C_DeInit(I2C2);I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; // I2C modeI2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle --> standardI2C_InitStruct.I2C_OwnAddress1 = 0x33; // own address, not relevant in master modeI2C_InitStruct.I2C_Ack = I2C_Ack_Enable; // disable acknowledge when reading (can be changed later on)I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addressesI2C_InitStruct.I2C_ClockSpeed = 100000; // 100kHz// enable I2C2I2C_Init(I2C2, &I2C_InitStruct); // init I2C2I2C_Cmd(I2C2, ENABLE);I2S_InitTypeDef I2S_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);/* CODEC_I2S peripheral configuration for master TX */SPI_I2S_DeInit(SPI2);I2S_InitStructure.I2S_AudioFreq = 48000;I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;//extended;I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;/* Initialize the I2S main channel for TX */I2S_Init(SPI2, &I2S_InitStructure);v_I2C_Write16(I2C2, WM8731ADDRESS ,0x0f, 0);uint8_t i;/* Load default values */for(i=0;i<W8731_NUM_REGS;i++){ v_I2C_Write16(I2C2, WM8731ADDRESS ,i, w8731_init_data[i]);}2015-08-27 01:23 PM
One thing which looks fishy is that you want to use I2C2 but you configure the pins to alternative function I2C3. Also the I2C2 can be AF9. I guess it should be like this:
PB3 (SDA) should be GPIO_AF9_I2C2 PB10 (SCL) should be GPIO_AF_I2C22015-08-28 12:20 AM
Sorry it an artefact I test I2C3 after everything fail on I2C2, I forgot to set it back to I2C2 before the copy and paste on this forum.
So it's not the problem. By the way I2C1 and I2C3 look to work fine. I will change my design but I would like to know if I2C2 is usable.2015-08-28 05:12 AM
Of course I2C2 should be usable.
Did you try setting the I2C2 SDA pin to Alternative Function 9 ?