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

LPC1768 + AT24C08 - Timeout problem

Hello, I am using a AT24C08 for store some datas and I'm having trouble. I am using code sample for I2C. The data is being written and read perfectly, but the function I2CStart() return always "timeout". This "problem" causes a delay in my routines of W/R. I believe it is necessary some modification in I2C0_IRQHandler() function. Someone could review my code?

I implemented a matricial keypad for tests of write and read.

Parents
  • i2c.h

    #define I2C_STARTED           1
    #define I2C_RESTARTED         2
    #define I2C_REPEATED_START    3
    #define DATA_ACK              4
    #define DATA_NACK             5
    #define I2C_BUSY              6
    #define I2C_NO_DATA           7
    #define I2C_NACK_ON_ADDRESS   8
    #define I2C_NACK_ON_DATA      9
    #define I2C_ARBITRATION_LOST  10
    #define I2C_TIME_OUT          11
    #define I2C_OK                12
    
    #define I2CONSET_I2EN       (0x1<<6)  /* I2C Control Set Register */
    #define I2CONSET_AA         (0x1<<2)
    #define I2CONSET_SI         (0x1<<3)
    #define I2CONSET_STO        (0x1<<4)
    #define I2CONSET_STA        (0x1<<5)
    
    #define I2CONCLR_AAC        (0x1<<2)  /* I2C Control clear Register */
    #define I2CONCLR_SIC        (0x1<<3)
    #define I2CONCLR_STAC       (0x1<<5)
    #define I2CONCLR_I2ENC      (0x1<<6)
    
    #define I2DAT_I2C                       0x00000000  /* I2C Data Reg */
    #define I2ADR_I2C                       0x00000000  /* I2C Slave Address Reg */
    #define I2SCLH_SCLH                     0x00000080  /* I2C SCL Duty Cycle High Reg */
    #define I2SCLL_SCLL                     0x00000080  /* I2C SCL Duty Cycle Low Reg */
    #define I2SCLH_HS_SCLH          0x00000008  /* Fast Plus I2C SCL Duty Cycle High Reg */
    #define I2SCLL_HS_SCLL          0x00000008  /* Fast Plus I2C SCL Duty Cycle Low Reg */
    
    extern void I2C0_IRQHandler( void );
    extern uint32_t I2CInit( uint32_t I2cMode );
    extern uint32_t I2CStart( void );
    extern uint32_t I2CStop( void );
    extern uint32_t I2CEngine( void );
    
    #endif /* end __I2C_H */
    

Reply
  • i2c.h

    #define I2C_STARTED           1
    #define I2C_RESTARTED         2
    #define I2C_REPEATED_START    3
    #define DATA_ACK              4
    #define DATA_NACK             5
    #define I2C_BUSY              6
    #define I2C_NO_DATA           7
    #define I2C_NACK_ON_ADDRESS   8
    #define I2C_NACK_ON_DATA      9
    #define I2C_ARBITRATION_LOST  10
    #define I2C_TIME_OUT          11
    #define I2C_OK                12
    
    #define I2CONSET_I2EN       (0x1<<6)  /* I2C Control Set Register */
    #define I2CONSET_AA         (0x1<<2)
    #define I2CONSET_SI         (0x1<<3)
    #define I2CONSET_STO        (0x1<<4)
    #define I2CONSET_STA        (0x1<<5)
    
    #define I2CONCLR_AAC        (0x1<<2)  /* I2C Control clear Register */
    #define I2CONCLR_SIC        (0x1<<3)
    #define I2CONCLR_STAC       (0x1<<5)
    #define I2CONCLR_I2ENC      (0x1<<6)
    
    #define I2DAT_I2C                       0x00000000  /* I2C Data Reg */
    #define I2ADR_I2C                       0x00000000  /* I2C Slave Address Reg */
    #define I2SCLH_SCLH                     0x00000080  /* I2C SCL Duty Cycle High Reg */
    #define I2SCLL_SCLL                     0x00000080  /* I2C SCL Duty Cycle Low Reg */
    #define I2SCLH_HS_SCLH          0x00000008  /* Fast Plus I2C SCL Duty Cycle High Reg */
    #define I2SCLL_HS_SCLL          0x00000008  /* Fast Plus I2C SCL Duty Cycle Low Reg */
    
    extern void I2C0_IRQHandler( void );
    extern uint32_t I2CInit( uint32_t I2cMode );
    extern uint32_t I2CStart( void );
    extern uint32_t I2CStop( void );
    extern uint32_t I2CEngine( void );
    
    #endif /* end __I2C_H */
    

Children
  • => but the function I2CStart() return always "timeout".
    Do you mean that I2CStart() returns FALSE due to timeout?

    uint32_t I2CStart( void )
    {
      uint32_t timeout = 0;
      uint32_t retVal = FALSE;
    
      /*--- Issue a start condition ---*/
      LPC_I2C0->I2CONSET = I2CONSET_STA; /* Set Start flag */
    
    
    
      /*--- Wait until START transmitted ---*/
      while( 1 )
      {
            if ( I2CMasterState == I2C_STARTED )
            {
              retVal = TRUE;
              break;
            }
    

    But it seems you never assign an I2C_STARTED to I2CMasterState.

    Search "I2CMasterState" (10 hits in 1 files)
      new  1 (10 hits)
            Line 6: volatile uint32_t I2CMasterState = I2C_IDLE;
            Line 48:           I2CMasterState = I2C_NO_DATA;
            Line 71:                 I2CMasterState = I2C_OK;
            Line 79:         I2CMasterState = I2C_NACK_ON_DATA;
            Line 112:         I2CMasterState = I2C_OK;
            Line 120:         I2CMasterState = I2C_NACK_ON_ADDRESS;
            Line 127:         I2CMasterState = I2C_ARBITRATION_LOST;
            Line 146:         if ( I2CMasterState == I2C_STARTED )
            Line 201:   I2CMasterState = I2C_IDLE;
            Line 213:         if ( I2CMasterState == DATA_NACK )
    

  • Yes, the I2CStart() returns FALSE. This code is a driver sample of NXP for PCA8581, but don't work with my 24C08. I tried using the code below, but don't work. There is some error in I2C0_IRQHandler() that I can't find.

    void I2C0_IRQHandler(void)
    {
      uint8_t StatValue;
    
      /* this handler deals with master read and master write only */
      StatValue = LPC_I2C0->I2STAT;
    
      switch ( StatValue )
      {
            case 0x08:                      /* A Start condition is issued. */
            LPC_I2C0->I2DAT = I2CMasterBuffer[0];
            LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
            I2CMasterState = I2C_STARTED;
            break;
    
            case 0x10:                      /* A repeated started is issued */
            LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
            I2CMasterState = I2C_RESTARTED;
            break;
    
            case 0x18:                      /* Regardless, it's a ACK */
            if ( I2CMasterState == I2C_STARTED )
            {
              LPC_I2C0->I2DAT = I2CMasterBuffer[1+WrIndex];
              WrIndex++;
              I2CMasterState = DATA_ACK;
            }
            LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
            break;
    
            case 0x28:      /* Data byte has been transmitted, regardless ACK or NACK */
            case 0x30:
            if ( WrIndex != I2CWriteLength )
            {
              LPC_I2C0->I2DAT = I2CMasterBuffer[1+WrIndex]; /* this should be the last one */
              WrIndex++;
              if ( WrIndex != I2CWriteLength )
              {
                    I2CMasterState = DATA_ACK;
              }
              else
              {
                    I2CMasterState = DATA_NACK;
                    if ( I2CReadLength != 0 )
                    {
                      LPC_I2C0->I2CONSET = I2CONSET_STA; /* Set Repeated-start flag */
                      I2CMasterState = I2C_REPEATED_START;
                    }
              }
            }
            else
            {
              if ( I2CReadLength != 0 )
              {
                    LPC_I2C0->I2CONSET = I2CONSET_STA;   /* Set Repeated-start flag */
                    I2CMasterState = I2C_REPEATED_START;
              }
              else
              {
                    I2CMasterState = DATA_NACK;
                    LPC_I2C0->I2CONSET = I2CONSET_STO;      /* Set Stop flag */
              }
            }
            LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
            break;
    
            case 0x40:      /* Master Receive, SLA_R has been sent */
            LPC_I2C0->I2CONSET = I2CONSET_AA;    /* assert ACK after data is received */
            LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
            break;
    
            case 0x50:      /* Data byte has been received, regardless following ACK or NACK */
            case 0x58:
            I2CMasterBuffer[3+RdIndex] = LPC_I2C0->I2DAT;
            RdIndex++;
            if ( RdIndex != I2CReadLength )
            {
              I2CMasterState = DATA_ACK;
            }
            else
            {
              RdIndex = 0;
              I2CMasterState = DATA_NACK;
            }
            LPC_I2C0->I2CONSET = I2CONSET_AA;    /* assert ACK after data is received */
            LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
            break;
    
            case 0x20:              /* regardless, it's a NACK */
    
            case 0x48:
            LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
            I2CMasterState = DATA_NACK;
            break;
    
            case 0x38:              /* Arbitration lost, in this example, we don't
                                            deal with multiple master situation */
            default:
            LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
            break;
      }
    }
    

  • => I tried using the code below, but don't work

    What do you mean by [but don't work] in this case?