cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1 I2C Stops on Slave Pull Down

k3nt00
Associate II
Posted on December 12, 2014 at 02:46

Hello,

I'm having an odd issue with the I2C peripheral. I have a simple routine for writing a value to a slave device register below. It succeeds writing to the slave as seen in Image #1. Following that, I need to wait for the slave device to pull down the SDA line to signal that its ready for the Master to read a value from one of its registers. As you can see in my code below, I am attempting to send the address bit until I receive an ACK from the slave. This is working just fine, you can see in Image #2 the attempts to write the address with a NAK response from the slave because it is not ready yet for the Master to read. When the slave finally pulls the SDA line low for a short period (Image #3) the master isn't able to start a new transmission, at which point it would get an ACK. So the question is, why is the quick pull down on the SDA line by the slave not allowing the master to start a new transmission????? Any comments or suggestions would be greatly appreciated!

http://i.gyazo.com/60f244ed9612d1997017d3696bdadpng

http://i.gyazo.com/2fc04f84bcc900a6a2720d7df9aac0b7.png

http://i.gyazo.com/526954072323bdef9e9d20f30e21e53e.png

Entire I2C Tranmission:

http://i.gyazo.com/61578a187934fc360026adb05dfe75png

void Get_value(void)
{
char c;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* initiate start sequence */
I2C_GenerateSTART(I2C1, ENABLE);
/* check start bit flag */
while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB));
/*send write command to chip*/
I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7<<1, I2C_Direction_Transmitter);
/*check master is now in Tx mode*/
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, 0x00);
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, 0x04);
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
/*stop bit flag*/
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
myDelay(10000);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
myDelay(10000);
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB));
/*send write command to chip*/
I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7<<1, I2C_Direction_Transmitter);
I2C_GenerateSTOP(I2C1, ENABLE);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
}
/**** DOESN'T GET HERE ****/
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB));
/*send write command to chip*/
I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7<<1, I2C_Direction_Transmitter);
/*check master is now in Tx mode*/
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, 0x0f);
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
/*stop bit flag*/
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
}


0 REPLIES 0