2010-07-26 02:22 AM
I2C Unable to receive start state (EV5)
#i2c #i2c #i2c-gpio #stm32-i2c-master2011-05-17 04:59 AM
One of the problems with I2C is the initial condition of attached peripherals after a reset. When you see a stuck BUSY it's most likely coming from another device on the I2C bus. The device is in some indeterminate state where it expects to have data clocked out by a bus master.
There are a couple of solutions. The clean way is, if all the devices on the I2C bus have reset lines, is to assert the resets to ensure all devices are in a known state before enabling the I2C bus. Unfortunately the peripheral resets are rarely available. The second solution is to manually clock the I2C bus in GPIO mode. Before initializing for I2C set up the I2C pins as GPIO, open collector. If there's a BUSY asserted, issue clocks manually until the BUSY clears. Jack Peacock2011-05-17 04:59 AM
At the moment I have nothing connected to my bus... SCL and SDA are pulled up to 5V as I wanted to make sure that its not a problem with a slave.
I have checked on the hardware that I can set the pin to Open Drain and toggle the pin high and low. So it doesn't seem like stuck hardware. Thanks for the tip though, thats one thing I will put into the start up once I have this working.2011-05-17 04:59 AM
I have managed to solve the BUSY flag problem.
As I am using software/hardware that was orignal for another purpose I had not removed the code that enables USART3. I had explicitly done USART_DeInit(USART3); USART_Cmd(USART3, DISABLE); But what is required is for the clock to be disabled to the peripheral ie RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, DISABLE); I am not 100% of the way there, I now have I2C realising the start bit being sent, but I am not stuck on the address state. I'll post the solution once I find out what the problem is.2011-05-17 04:59 AM
Hi Paul,
It is most likely linked to the order of setting I2C IOs and Enabling the I2C itself. First try to inverse the order: Configure the I2C and enable it then configure and enable the GPIOs : This way, even if the IO has a default state equal to 0, it won't force the busy state on the I2C cell at the I2C start up. If it doesn't work, try to use the other I2C cell to verify it is not a hardware issue. I hope it helps :)2011-05-17 04:59 AM
hello,
if your problem isn't fixed yet, try to remove the line I2C_Cmd(I2C2, ENABLE); from your init. regards2011-05-17 04:59 AM
Did you enable clock for port B?
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
And try first to enable I2C2 and then to initialize, like this:
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x30;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 50000;/* I2C Peripheral Enable */I2C_Cmd(I2C2, ENABLE);I2C_Init(I2C2, &I2C_InitStructure);BR,
Dragan
2011-05-17 04:59 AM
2011-05-17 04:59 AM
Actually after looking at the oscilloscope for longer, I realise that it seems to be an extra bit on the end (ie after the stop bit has been sent). After debugging the slave end, the slave is performing clock stretching(pulling the clock low) (even when receiving the stop command). After fixing up the slave to only perform clock stretching when required the STM32 works great.
If anyone wants to use the I2C read/write functions go ahead, they seem to be working. Thanks for everyones comments. Regards Paul2011-05-17 04:59 AM
As you said I2C library work fine but you must be careful with stop condition, some more thing and events happen after you send stop, but I'm not sure what :)
Cheers,
Dragan