2014-08-11 10:24 AM
Hi
First of all, I know there are other threads herein which deals with the I2Cx BUSY flag problem, and I have tried the solutions suggested in them to no relieve. Therefor I now, as a last resort opens a new thread about the same topic. The BUSY flag is set in the same moment as the I2C pheripheral clock is enabled in line 6 (RCC). The BUSY then remains set except for when i tried to do a pheripheral reset. As long as the reset was asserted BUSY was not set, but as soon it was released again BUSY was set again. The SCL and SDA pins are both high and remains high. I am not able to see any glitches using an oscilloscope. I am able to set or clr both pins by either doing it in sw or by shorting pins to ground so there are nothing keeping the bus high by force. I have also tried to generate both stop and start conditions on the bus, but the BUSY flag remains high. I have also tried to enable the I2C block before initlaising it to no use. I am stuck. Then I have also tried to reorder the order things are done, i.e. when to enable clocks and to initialize I2C befor GPIOs and such and many other not so smart variants youdt to have tried it. Its always the same result. As soon as the pheripheral clock for the I2C is turned on the BUSY flag goes on and remains on. I use many other features on the chip like DCIM and SPI and these works like expected, it's only the I2C2 that does not work right now. If you have the time and skill I would be very happy for an helping hand. Thanks in advance (see code below) Vidar (Z) The code I use for initialization is given below, but first the definition I use in the code and which gives you the GPIOs used and such (EDIT: Tagged my error in red, should read GPIO_Mode_AF)
// I2C interface
#define I2C_CHANNEL I2C2
#define I2C_AF GPIO_AF_I2C2
#define I2C_RCC RCC_APB1Periph_I2C2
#define I2C_GPIO_RCC RCC_AHB1Periph_GPIOB
#define I2C_PORT GPIOB
#define I2C_READ 0x01
#define I2C_WRITE 0x00
#define I2C_SCL_PIN GPIO_Pin_10 /* PB.10 - AF */
#define I2C_SCL_PORT GPIOB /* GPIOB */
#define I2C_SCL_RCC RCC_AHB1Periph_GPIOB
#define I2C_SCL_PIN_NR GPIO_PinSource10
#define I2C_SDA_PIN GPIO_Pin_11 /* PB.11 - AF */
#define I2C_SDA_PORT GPIOB /* GPIOB */
#define I2C_SDA_RCC RCC_AHB1Periph_GPIOB
#define I2C_SDA_PIN_NR GPIO_PinSource11
void
I2C_init(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(I2C_RCC, ENABLE);
RCC_AHB1PeriphClockCmd(I2C_GPIO_RCC, ENABLE);
/* Configure port pins used by I2C */
GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_PORT, &GPIO_InitStructure);
I2C_PORT->BSRRL = I2C_SCL_PIN | I2C_SDA_PIN;
// Set high
/* Connect I2C dedicated port pins to use the alternative function */
GPIO_PinAFConfig(I2C_SCL_PORT, I2C_SCL_PIN_NR, I2C_AF);
GPIO_PinAFConfig(I2C_SDA_PORT, I2C_SDA_PIN_NR, I2C_AF);
/* Configure I2C */
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C_CHANNEL, &I2C_InitStructure);
// enable I2C_CHANNEL
I2C_Cmd(I2C_CHANNEL, ENABLE);
}
#i2c-busy-bit-set #stm32f4 #i2c #discovery
2014-08-11 10:29 AM
Wouldn't the pins need to be in AF mode?
2014-08-11 11:10 AM
9.
/* Connect I2C dedicated port pins to use the alternative function */
GPIO_PinAFConfig(I2C_SCL_PORT, I2C_SCL_PIN_NR, I2C_AF);
GPIO_PinAFConfig(I2C_SDA_PORT, I2C_SDA_PIN_NR, I2C_AF);
Do you see any typos here???
EDIT: < a few minutes later>
BAAAH! I see what you mean. the pin mode is wrong. I must be blind, totally and a few other things. I will try with AF mode and update thread when tested. It does not explain why the BUSY flag is set as soon as the clock is enabled though, but I am sure there is an explanation...
2014-08-11 12:11 PM
I'll also observe that ST always Enables the I2C interface before I2C_Init()
The I2C peripheral has always been very sensitive to the pin states when it starts.2014-08-11 12:52 PM
Well, I have also seen that, that the order between init and enable has been done different between projects, but it was not necessary to do so to have it work. (Yes it worked to set mode to AF). Then at the moment the AF muxes where switched to I2C the busy flag was cleared.
One important observation here though. The reason for why the BUSY flag was cleard at this exact moment was because of the order of how I switched in the AF muxes for each pin. Since I first connected SCL to AF , and then SDA after, I actually generated a stop condition, effectly clearing the BUSY flag. When I altered the order, i.e. swapped line 20 and 21 , connecting SDA FIRST and then SCL. The BUSY flag remains even after switching in the AF muxes and would be forever. (I could then manually in HW toggle a stop condition by connecting the pins to GND and release SCL then SDA, that would clear the BUSY flag). This is important to know because else you would need to do a peripheral reset i guess to be able to clear the BUSY flag. Nevertheless, THANK YOU! for pointing out the mode setting error. Now I will go and wash my glasses...