1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

I2C slave code in hardware.

Discussion in 'Microcontrollers' started by Pommie, Aug 29, 2017.

  1. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,013
    Likes:
    317
    Location:
    Brisbane Australia
    Has anyone managed to get this to work on a pic? I'm using a 16F1823 and it all works except for sending bytes back to the master. As soon as I release the clock line (CKP=1) the master receives the 8 (wrong) bytes it asks for. It's as though the clock doesn't get stretched on subsequent bytes.

    Here's my main code,
    Code (text):

        SSPADD=0x80;        //Slave address
        SSPSTAT = 0x80;  
        SSPCON = 0x36;    //As a slave device
        SSPCON2 = 0x01;
        SSPCON3=0x10;
        status = WaitID;
     
        while(1){
            if(SSP1IF){             //byte received??
                SSP1IF=0;
                if(!SSPSTATbits.D_nA)   //if Address (0x80) then reset state
                    status=WaitID;
                switch (status){
                    case WaitID:
                        if(R_nW){                   //is it a read operation?
                            status=WriteBytes;      //if master reading, we're writing
                            SSP1BUF=buff[index++&7];//write first byte
                            CKP=1;                  //once this line executes all bytes are read by master
                        }else{
                            status=WaitAdd;
                            dummy=SSP1BUF;          //is ID so discard
                            CKP=1;
                        }
                        break;
                    case WaitAdd:
                        index=SSP1BUF;              //store address
                        status=ReadBytes;
                        CKP=1;
                        break;
                    case WriteBytes:
                        if(ACKSTAT){            //if no ACK
                            status=WaitID;      //start again
                        }else{                  //if master ACKed then more bytes required
                            SSP1BUF=buff[index++&7];
                            CKP=1;                      
                        }
                        break;
                    case ReadBytes:
                        buff[index++&7]=SSPBUF; //store values
                        CKP=1;
                        break;
                }
                //lastly check for errors and deal with them
                if ((SSPCONbits.SSPOV) || (SSPCONbits.WCOL)){
                    dummy = SSPBUF;         // Read the previous value to clear the buffer
                    SSPCONbits.SSPOV = 0;   // Clear the overflow flag
                    SSPCONbits.WCOL = 0;    // Clear the collision bit
                    SSPCONbits.CKP = 1;     //release clock line
                }
            }
        }
     
    The master writes 8 bytes and these end up in the buffer (buff). It then attempts to read them back but get's nonsense.
    I can single step through the above code and it works exactly as it should until the line CKP=1 with remark //once this line executes all bytes are read by master, even though the slave is paused. Anyone managed to do this? Any suggestions?

    Thanks,

    Mike.
    edit, removed superfluous code.
     
  2. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,013
    Likes:
    317
    Location:
    Brisbane Australia
    I'm working my way through AN734 and will report back if I work out what the problem is.

    Mike.
     
  3. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,013
    Likes:
    317
    Location:
    Brisbane Australia
    Worked out the problem. I wasn't ACKing in the master software.

    Mike.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. granddad

    granddad Active Member

    Joined:
    Jan 18, 2015
    Messages:
    750
    Likes:
    75
    Location:
    Worcestershire UK

    Hi Mike When I worked in tec support for a living , we sometimes said , " Leave them for a bit they may sort their own problem out... " :) well done getting slave HW to work ... waiting for the ACK seems to be the difficult thing .
     

Share This Page