CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

I2C Slave SDA pulled low after writing to SSPBUF

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dtemplar



Joined: 16 Feb 2004
Posts: 5

View user's profile Send private message

I2C Slave SDA pulled low after writing to SSPBUF
PostPosted: Thu Jun 30, 2005 4:43 am     Reply with quote

Hello Guys,

I am trying to make a library that would require me to implement I2C slave on the PIC16F876A without using the CCS-C functions (since these functions will be used on the main program)

However, upon getting an I2C read operation, the SDA line is pulled low after writing the data to SSPBUF. I verified that the program did went through the SSPBUF = data codes, but the SDA just went low during the clock transitions and after.

I tried checking all the errata (my F876A is rev B4) and I cant find anything that explains this.

Here's my code:

Code:

//i2c register
#byte   REG_INTERRUPT_FLAGS1        = 0x0C  //PIR1
#bit    FLAG_I2C_INTERRUPT          = REG_INTERRUPT_FLAGS1.3

#byte   REG_I2C_BUFFER              = 0x13  //SSPBUF
#byte   REG_I2C_ADDRESS             = 0x93  //SSPADD

#byte   REG_I2C_STATUS              = 0x94  //SSPSTAT
#bit    FLAG_I2C_BUFFER_FULL        = REG_I2C_STATUS.0
#bit    FLAG_I2C_UPDATE_ADDR_10BIT  = REG_I2C_STATUS.1
#bit    FLAG_I2C_READ_WRITE         = REG_I2C_STATUS.2
#bit    FLAG_I2C_START              = REG_I2C_STATUS.3
#bit    FLAG_I2C_STOP               = REG_I2C_STATUS.4
#bit    FLAG_I2C_DATA_ADDR          = REG_I2C_STATUS.5
#bit    FLAG_I2C_CKE                = REG_I2C_STATUS.6
#bit    FLAG_I2C_SMP                = REG_I2C_STATUS.7

#byte   REG_I2C_CONTROL             = 0x14  //SSPCON
#bit    FLAG_I2C_MODE_BIT0          = REG_I2C_CONTROL.0
#bit    FLAG_I2C_MODE_BIT1          = REG_I2C_CONTROL.1
#bit    FLAG_I2C_MODE_BIT2          = REG_I2C_CONTROL.2
#bit    FLAG_I2C_MODE_BIT3          = REG_I2C_CONTROL.3
#bit    FLAG_I2C_SCK_RELEASE        = REG_I2C_CONTROL.4
#bit    FLAG_I2C_ENABLE             = REG_I2C_CONTROL.5
#bit    FLAG_I2C_OVERFLOW           = REG_I2C_CONTROL.6
#bit    FLAG_I2C_WRITE_COLLISION    = REG_I2C_CONTROL.7

#byte   REG_I2C_CONTROL2            = 0x91  //SSPCON2
#bit    FLAG_I2C_CLOCK_STRETCH      = REG_I2C_CONTROL2.0
#bit    FLAG_I2C_GEN_CALL_ENABLED   = REG_I2C_CONTROL2.7

//port access
#byte   REG_PORT_C_TRIS             = 0x87  //TRISC
//#bit    FLAG_PINC0_INPUT            = REG_PORT_C_TRIS.0
#bit    FLAG_PINC1_INPUT            = REG_PORT_C_TRIS.1
//#bit    FLAG_PINC2_INPUT            = REG_PORT_C_TRIS.2
#bit    FLAG_BUS_SCL_INPUT          = REG_PORT_C_TRIS.3
#bit    FLAG_BUS_SDA_INPUT          = REG_PORT_C_TRIS.4

void main(void)
{
    int8 i8ReceivedData;
    //enable slave i2c
     //init bus pins
    FLAG_BUS_SCL_INPUT = FALSE;
    FLAG_BUS_SDA_INPUT = FALSE;
    PIN_BUS_SCL = 1;
    PIN_BUS_SDA = 1;
    FLAG_BUS_SCL_INPUT = TRUE;
    FLAG_BUS_SDA_INPUT = TRUE;
    //init registers
    FLAG_I2C_GEN_CALL_ENABLED = FALSE;
    FLAG_I2C_CLOCK_STRETCH = FALSE;
    FLAG_I2C_WRITE_COLLISION = FALSE;
    FLAG_I2C_OVERFLOW = FALSE;
    FLAG_I2C_SCK_RELEASE = TRUE;
    i8ReceivedData= REG_I2C_BUFFER;
    //slave mode 7bit-address
    FLAG_I2C_MODE_BIT0 = 0;
    FLAG_I2C_MODE_BIT1 = 1;
    FLAG_I2C_MODE_BIT2 = 1;
    FLAG_I2C_MODE_BIT3 = 0;
    //enable slave i2c
    REG_I2C_ADDRESS = CONST_I2C_SLAVE_ADDRESS;
    FLAG_I2C_ENABLE = TRUE;
    //wait for commands
    while(TRUE)
    {
        if (FLAG_I2C_INTERRUPT)
        {
            FLAG_I2C_SCK_RELEASE = FALSE;
            //check buffer
            if (FLAG_I2C_BUFFER_FULL)
            {
                // read buffer (SSPBUF)
                i8ReceivedData = REG_I2C_BUFFER;
            }
            //check errors
            if (FLAG_I2C_OVERFLOW || FLAG_I2C_WRITE_COLLISION)
            {
                FLAG_I2C_OVERFLOW = FALSE;
                FLAG_I2C_WRITE_COLLISION = FALSE;
                //reset bus
                FLAG_I2C_ENABLE     = FALSE;
                FLAG_BUS_SCL_INPUT  = TRUE;
                FLAG_BUS_SDA_INPUT  = TRUE;
                FLAG_I2C_ENABLE     = TRUE;
            }
            else
            {
                //check read operation
                if (FLAG_I2C_READ_WRITE)
                {
                    //check if to send first byte
                    if (FLAG_I2C_DATA_ADDR)
                    {
                        //send next byte
                        REG_I2C_BUFFER = 0xAA;
                    }
                    else
                    {
                        //send first byte
                        REG_I2C_BUFFER = 0x55;
                    }
                }
            }
            FLAG_I2C_SCK_RELEASE = TRUE;
            FLAG_I2C_INTERRUPT = FALSE;
        }
    }
}


By the way, I also tried recompiling a CCS-C program used for the PIC16F76 with working I2C slave implementation, for a PIC16F876A, but the I2C slave did not work.

Now I am not sure if its with CCS or with the PIC micro. Crying or Very sad
Ttelmah
Guest







PostPosted: Thu Jun 30, 2005 5:58 am     Reply with quote

You seem to only be handling three of the four normal conditions that can occur on an I2C slave. Your first byte received, will be the address byte.
Look at AN734 from Microchip. This shows the code needed in assembler, and is well documented, so conversion should be easy. Your slave handler needs to be able to handle the possibilities of both a read, and a write, with either data, or address bytes, and also Nack reset condition.
The SDO line being held low, implies that the slave thinks that it has not successfully completed the transaction, and is therefore holding ACK low.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group