AnsweredAssumed Answered

STM32F1 I2C Stops on Slave Pull Down

Question asked by Williams.Kent.001 on Dec 12, 2014
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!

Image #1
Image #2
Image #3

Entire I2C Tranmission: Image #4


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));
}


Outcomes