This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Not Getting Proper Status Responses of Repeated Start in I2C Protocol of LPC1343?

Hello!! Everyone i am working on LPC1343 Micro-controller and wants to interface RTCC PCF8523 with LPC1343.

I write code for I2C protocol but its not working.
The problem is found when i send repeated start from master (LPC1343), the status for this must be 0x10 while i am getting 0x28 every time.

The full code can be downloaded from here:-
www.edaboard.com/.../107170d1404924341-pcf8523_rtcc.zip
(Its EDABOARD Link Sorry, i dont know how to attach files here.)

The functions used for I2C Protocol are as follow:-

#include "LPC13xx.h"
#include "I2C.h"
#include "UART.h"

void I2C_Init(unsigned char Mode)
{
        LPC_SYSCON->PRESETCTRL |= (1<<1);                      //De-Asserts Reset Signal to I2C
        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);   //Enable I2C Clock

        LPC_IOCON->PIO0_4 &= ~0x3F;
        LPC_IOCON->PIO0_4 |= 0x01;   //SCL

        LPC_IOCON->PIO0_5 &= ~0x3F;
        LPC_IOCON->PIO0_5 |= 0x01;   //SDA

        if(Mode == I2C_SPEED_400)
        {
                LPC_I2C->SCLH = 90;                  //I2PCLK is 72MHz
                LPC_I2C->SCLL = 90;                  //I2PCLK is 72MHz
        }
        else if(Mode == I2C_SPEED_100)
        {
                LPC_I2C->SCLH = 360;         //I2PCLK is 72MHz
                LPC_I2C->SCLL = 360;         //I2PCLK is 72MHz
        }

        LPC_I2C->CONCLR = 0xFF;              //Clear All Flags
        LPC_I2C->CONSET = (1<<6);      //I2C Interface Enable
}
void I2C_Start(void)
{
        LPC_I2C->CONSET |= 0x20;                     //Set the Start Bit
        while(LPC_I2C->STAT!=0x08);          //Wait for the Status Bit
}
void I2C_Restart(void)
{
        LPC_I2C->CONSET |= 0x20;                     //Set the Start Bit
        while(LPC_I2C->STAT!=0x10);          //Wait for the Status Bit
}
void I2C_Stop(void)
{
        LPC_I2C->CONSET |= 0x14;     //Stop I2C
        LPC_I2C->CONCLR = 0x08;
}
void I2C_Write(unsigned char data,unsigned char status)
{
        LPC_I2C->DAT = data;
  LPC_I2C->CONCLR = 0X28;                                            //Clear Start Flag and SI Interrupt
  while(LPC_I2C->STAT!=status);                //Wait for the Status Byte
}
unsigned char I2C_Read(void)
{
  LPC_I2C->CONCLR = 0X28;
  while (LPC_I2C->STAT!=0x50);                       //Wait for Status Set - 0x50
  return(LPC_I2C->DAT);
}

In function Read from RTCC (given below)

unsigned char PCF8523_Read(unsigned char Address)
{
        unsigned char temp;
        I2C_Start();
        UART_Write('1');
        I2C_Write(PC8523_ADDRESS,0x18);
        UART_Write('2');
        I2C_Write(Address,0x28);
        UART_Write('3');
        I2C_Restart();
        UART_Write('4');
        I2C_Write(PC8523_ADDRESS+1,0x40);
        UART_Write('5');
        temp = I2C_Read();
        UART_Write('6');
        I2C_Stop();
        UART_Write('7');
        return temp;
}[/pre>

As i dont have debugger i checked the content of Status Bytes on UART, i found that for I2c_Start, the status byte contains 0x08 when sending rtcc address i am getting status = 0x18 and then after sending the address from where i have to read i am getting status = 0x28 which is correct.
Upto this point i am getting valid status responses, but after sending Repeated Start i am getting 0x28 each and every time continuously.
Can anyone please help me to solve this issue.


Parents
  • Thanks for your reply, i tried the above code as but it is giving the same result as given previously without any change.
    For Start Condition i am getting Status = 0x08
    For Write Address Condition i am getting Status = 0x18
    For Writing to Address i am getting Status = 0x28
    For Repeated Start condition i am getting Status = 0x28 (which is incorrect it must be 0x10 here)

    I don't know what to do now.

    I will give a try to the Interrupt method but dont think it will work because Interrupt in the second polling based code i had use the SI interrupt.

Reply
  • Thanks for your reply, i tried the above code as but it is giving the same result as given previously without any change.
    For Start Condition i am getting Status = 0x08
    For Write Address Condition i am getting Status = 0x18
    For Writing to Address i am getting Status = 0x28
    For Repeated Start condition i am getting Status = 0x28 (which is incorrect it must be 0x10 here)

    I don't know what to do now.

    I will give a try to the Interrupt method but dont think it will work because Interrupt in the second polling based code i had use the SI interrupt.

Children
  • The below code has been tested OK with my LPC1343 and DS3231 (My I2C-Slave, I don't have PCF8523).
    I assume your I2C_Init() is correct.

    #include <LPC13xx.h>
    
    #define I2C_I2CONSET_AA                         ((0x04))
    #define I2C_I2CONSET_SI                         ((0x08))
    #define I2C_I2CONSET_STO                        ((0x10))
    #define I2C_I2CONSET_STA                        ((0x20))
    #define I2C_I2CONSET_I2EN                       ((0x40))
    
    #define I2C_I2CONCLR_AAC                        ((1<<2))
    #define I2C_I2CONCLR_SIC                        ((1<<3))
    #define I2C_I2CONCLR_STOC                       ((1<<4))
    #define I2C_I2CONCLR_STAC                       ((1<<5))
    #define I2C_I2CONCLR_I2ENC                      ((1<<6))
    
    #define I2C_STAT_CODE_BITMASK                                   ((0xF8))
    
    #define I2C_I2STAT_M_TX_START                                   ((0x08))
    #define I2C_I2STAT_M_TX_RESTART                                 ((0x10))
    #define I2C_I2STAT_M_TX_SLAW_ACK                                ((0x18))
    #define I2C_I2STAT_M_TX_SLAW_NACK                               ((0x20))
    #define I2C_I2STAT_M_TX_DAT_ACK                                 ((0x28))
    #define I2C_I2STAT_M_TX_DAT_NACK                                ((0x30))
    #define I2C_I2STAT_M_TX_ARB_LOST                                ((0x38))
    
    #define I2C_I2STAT_M_RX_START                                   ((0x08))
    #define I2C_I2STAT_M_RX_RESTART                                 ((0x10))
    #define I2C_I2STAT_M_RX_SLAR_ACK                                ((0x40))
    #define I2C_I2STAT_M_RX_SLAR_NACK                               ((0x48))
    #define I2C_I2STAT_M_RX_DAT_ACK                                 ((0x50))
    #define I2C_I2STAT_M_RX_DAT_NACK                                ((0x58))
    
    #define I2C_I2DAT_BITMASK                       ((0xFF))
    
    
    void I2C_Init( LPC_I2C_TypeDef *I2Cx, uint32_t clockrate );
    
    
    uint32_t I2C_Start(void)
    {
        LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
        LPC_I2C->CONSET = I2C_I2CONSET_STA;
        while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
        return (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
    }
    void I2C_Stop(void)
    {
        LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
        LPC_I2C->CONSET = I2C_I2CONSET_STO;
        while (LPC_I2C->CONSET & I2C_I2CONSET_STO);
    }
    uint32_t I2C_Write(unsigned char data)
    {
        LPC_I2C->DAT = data;
        LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
        while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
        return (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
    }
    unsigned char Slave_Read(unsigned char Address)
    {
        uint8_t result;
    
        if ( I2C_Start() == I2C_I2STAT_M_TX_START )
        {
            LPC_I2C->CONCLR = I2C_I2CONCLR_STAC;
            if ( I2C_Write(Address) == I2C_I2STAT_M_TX_SLAW_ACK )
            {
                if ( I2C_Start() == I2C_I2STAT_M_TX_RESTART )
                {
                    if ( I2C_Write( Address | 0x1 ) == I2C_I2STAT_M_RX_SLAR_ACK )
                    {
                        LPC_I2C->CONCLR = I2C_I2CONCLR_AAC;
                        LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
                        while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
    
                        result = (uint8_t)(LPC_I2C->DAT & I2C_I2DAT_BITMASK);
    
                        I2C_Stop();
                        return result;
                    }
                }
            }
        }
    
        I2C_Stop();
        return 0xE8;
    }
    
    
    int main(void)
    {
        volatile uint8_t result;
    
        I2C_Init( LPC_I2C, 100000 );
    
        while(1)
        {
            result = Slave_Read(0xD0);
            /* Check result */
        }
    }
    
    
    

  • Hello!!
    The code is working now, i had not cleared the SI Flag when using Repeated Restart Function.

    Here is the Updated and Working I2C Functions for LPC1343

    
    #include "LPC13xx.h"
    #include "I2C.h"
    
    void I2C_Init(unsigned char Mode)
    {
            LPC_SYSCON->PRESETCTRL |= (1<<1);                      //De-Asserts Reset Signal to I2C
            LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);   //Enable I2C Clock
    
            LPC_IOCON->PIO0_4 &= ~0x3F;
            LPC_IOCON->PIO0_4 |= 0x01;   //SCL
    
            LPC_IOCON->PIO0_5 &= ~0x3F;
            LPC_IOCON->PIO0_5 |= 0x01;   //SDA
    
            if(Mode == I2C_SPEED_400)
            {
                    LPC_I2C->SCLH = 90;                  //I2PCLK is 72MHz
                    LPC_I2C->SCLL = 90;                  //I2PCLK is 72MHz
            }
            else if(Mode == I2C_SPEED_100)
            {
                    LPC_I2C->SCLH = 360;         //I2PCLK is 72MHz
                    LPC_I2C->SCLL = 360;         //I2PCLK is 72MHz
            }
    
            LPC_I2C->CONCLR = 0xFF;              //Clear All Flags
            LPC_I2C->CONSET = (1<<6);      //I2C Interface Enable
    }
    void I2C_Start(void)
    {
            LPC_I2C->CONCLR = 0X28;
            LPC_I2C->CONSET |= 0x20;                     //Set the Start Bit
            while(LPC_I2C->STAT!=0x08);          //Wait for the Status Bit
    }
    void I2C_Restart(void)
    {
            LPC_I2C->CONCLR = 0X28;
            LPC_I2C->CONSET |= 0x20;                     //Set the Start Bit
            while(LPC_I2C->STAT!=0x10);          //Wait for the Status Bit
    }
    void I2C_Stop(void)
    {
            LPC_I2C->CONSET |= 0x14;     //Stop I2C
            LPC_I2C->CONCLR = 0x08;
    }
    void I2C_Write(unsigned char data,unsigned char status)
    {
            LPC_I2C->CONCLR = 0X28;
            LPC_I2C->DAT = data;
      LPC_I2C->CONCLR = 0X28;                                            //Clear Start Flag and SI Interrupt
      while(LPC_I2C->STAT!=status);                //Wait for the Status Byte
    }
    unsigned char I2C_Read(void)
    {
      LPC_I2C->CONCLR = 0X2C;            //Cleat SI and Asset Acknowledgment Flag
      while(LPC_I2C->STAT!=0x58);
      return(LPC_I2C->DAT);
    }
    

  • Hello!!
    The code is working now, i had not cleared the SI Flag when using Repeated Restart Function.

    Here is the Updated and Working I2C Functions for LPC1343

    
    #include "LPC13xx.h"
    #include "I2C.h"
    
    void I2C_Init(unsigned char Mode)
    {
            LPC_SYSCON->PRESETCTRL |= (1<<1);                      //De-Asserts Reset Signal to I2C
            LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);   //Enable I2C Clock
    
            LPC_IOCON->PIO0_4 &= ~0x3F;
            LPC_IOCON->PIO0_4 |= 0x01;   //SCL
    
            LPC_IOCON->PIO0_5 &= ~0x3F;
            LPC_IOCON->PIO0_5 |= 0x01;   //SDA
    
            if(Mode == I2C_SPEED_400)
            {
                    LPC_I2C->SCLH = 90;                  //I2PCLK is 72MHz
                    LPC_I2C->SCLL = 90;                  //I2PCLK is 72MHz
            }
            else if(Mode == I2C_SPEED_100)
            {
                    LPC_I2C->SCLH = 360;         //I2PCLK is 72MHz
                    LPC_I2C->SCLL = 360;         //I2PCLK is 72MHz
            }
    
            LPC_I2C->CONCLR = 0xFF;              //Clear All Flags
            LPC_I2C->CONSET = (1<<6);      //I2C Interface Enable
    }
    void I2C_Start(void)
    {
            LPC_I2C->CONCLR = 0X28;
            LPC_I2C->CONSET |= 0x20;                     //Set the Start Bit
            while(LPC_I2C->STAT!=0x08);          //Wait for the Status Bit
    }
    void I2C_Restart(void)
    {
            LPC_I2C->CONCLR = 0X28;
            LPC_I2C->CONSET |= 0x20;                     //Set the Start Bit
            while(LPC_I2C->STAT!=0x10);          //Wait for the Status Bit
    }
    void I2C_Stop(void)
    {
            LPC_I2C->CONSET |= 0x14;     //Stop I2C
            LPC_I2C->CONCLR = 0x08;
    }
    void I2C_Write(unsigned char data,unsigned char status)
    {
            LPC_I2C->CONCLR = 0X28;
            LPC_I2C->DAT = data;
      LPC_I2C->CONCLR = 0X28;                                            //Clear Start Flag and SI Interrupt
      while(LPC_I2C->STAT!=status);                //Wait for the Status Byte
    }
    unsigned char I2C_Read(void)
    {
      LPC_I2C->CONCLR = 0X2C;            //Cleat SI and Asset Acknowledgment Flag
      while(LPC_I2C->STAT!=0x58);
      return(LPC_I2C->DAT);
    }